Compare commits
1 Commits
master
...
demo-blur-
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b4dd0797c8 |
@ -420,7 +420,7 @@ static yutani_server_window_t * server_window_create(yutani_globals_t * yg, int
|
||||
win->client_strings = NULL;
|
||||
win->anim_mode = yutani_pick_animation(flags, 0);
|
||||
win->anim_start = yutani_current_time(yg);
|
||||
win->alpha_threshold = 0;
|
||||
win->alpha_threshold = (flags & (1 << 5)) ? 10 : 0;
|
||||
win->show_mouse = 1;
|
||||
win->tiled = 0;
|
||||
win->untiled_width = 0;
|
||||
@ -705,6 +705,56 @@ static inline int matrix_is_translation(gfx_matrix_t m) {
|
||||
return (m[0][0] == 1.0 && m[0][1] == 0.0 && m[1][0] == 0.0 && m[1][1] == 1.0);
|
||||
}
|
||||
|
||||
static inline int clamp(int a, int l, int h) {
|
||||
return a < l ? l : (a > h ? h : a);
|
||||
}
|
||||
static int _is_in_clip(gfx_context_t * ctx, int32_t y) {
|
||||
if (!ctx->clips) return 1;
|
||||
if (y < 0 || y >= ctx->clips_size) return 1;
|
||||
return ctx->clips[y];
|
||||
}
|
||||
|
||||
static void horizontal_selective_blur(yutani_globals_t * yg, yutani_server_window_t * win) {
|
||||
int radius = 2;
|
||||
gfx_context_t * _src = yg->backend_ctx;
|
||||
int w = _src->width;
|
||||
int h = _src->height;
|
||||
if (w < radius) return;
|
||||
uint32_t * out_color = calloc(sizeof(uint32_t), w);
|
||||
|
||||
for (int y = 0; y < h; y++) {
|
||||
if (!_is_in_clip(_src, y)) continue;
|
||||
unsigned short r = 0;
|
||||
unsigned short g = 0;
|
||||
unsigned short b = 0;
|
||||
for (int i = -radius; i < radius; ++i) {
|
||||
int p1 = clamp(i, 0, w - 1);
|
||||
uint32_t col1 = GFX(_src, p1, y);
|
||||
r += (int)_RED(col1);
|
||||
g += (int)_GRE(col1);
|
||||
b += (int)_BLU(col1);
|
||||
}
|
||||
for (int x = 0; x < w; x++) {
|
||||
out_color[x] = rgb(r >> 2, g >> 2, b >> 2);
|
||||
int p1 = clamp(x - radius, 0, w - 1);
|
||||
int p2 = clamp(x + radius, 0, w - 1);
|
||||
uint32_t col1 = GFX(_src, p1, y);
|
||||
uint32_t col2 = GFX(_src, p2, y);
|
||||
r += (int)_RED(col2) - (int)_RED(col1);
|
||||
g += (int)_GRE(col2) - (int)_GRE(col1);
|
||||
b += (int)_BLU(col2) - (int)_BLU(col1);
|
||||
}
|
||||
|
||||
for (int x = 0; x < w; x++) {
|
||||
if (check_top_at(yg,win,x,y)) {
|
||||
GFX(_src,x,y) = out_color[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(out_color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Blit a window to the framebuffer.
|
||||
*
|
||||
@ -727,6 +777,11 @@ static int yutani_blit_window(yutani_globals_t * yg, yutani_server_window_t * wi
|
||||
|
||||
double opacity = (double)(window->opacity) / 255.0;
|
||||
|
||||
if (window->server_flags & (1 << 5)) {
|
||||
/* Blur behind, but restricted to the valid region? */
|
||||
horizontal_selective_blur(yg, window);
|
||||
}
|
||||
|
||||
if (window->rotation || window == yg->resizing_window || window->anim_mode) {
|
||||
double m[2][3];
|
||||
|
||||
|
@ -1532,7 +1532,7 @@ int main (int argc, char ** argv) {
|
||||
height = yctx->display_height;
|
||||
|
||||
/* Create the panel window */
|
||||
panel = yutani_window_create_flags(yctx, width, PANEL_HEIGHT, YUTANI_WINDOW_FLAG_NO_STEAL_FOCUS | YUTANI_WINDOW_FLAG_ALT_ANIMATION);
|
||||
panel = yutani_window_create_flags(yctx, width, PANEL_HEIGHT, YUTANI_WINDOW_FLAG_NO_STEAL_FOCUS | YUTANI_WINDOW_FLAG_ALT_ANIMATION | (1 << 5));
|
||||
|
||||
/* And move it to the top layer */
|
||||
yutani_set_stack(yctx, panel, YUTANI_ZORDER_TOP);
|
||||
|
@ -2296,7 +2296,7 @@ int main(int argc, char ** argv) {
|
||||
init_decorations();
|
||||
struct decor_bounds bounds;
|
||||
decor_get_bounds(NULL, &bounds);
|
||||
window = yutani_window_create(yctx, window_width + bounds.width, window_height + bounds.height + menu_bar_height);
|
||||
window = yutani_window_create_flags(yctx, window_width + bounds.width, window_height + bounds.height + menu_bar_height, (1 << 5));
|
||||
update_bounds();
|
||||
}
|
||||
|
||||
|
108
apps/toastd.c
Normal file
108
apps/toastd.c
Normal file
@ -0,0 +1,108 @@
|
||||
/**
|
||||
* @brief Toast notification daemon.
|
||||
* @file apps/toastd.c
|
||||
*
|
||||
* Provides an endpoint for applications to post notifications
|
||||
* which are displayed in pop-up "toasts" in the upper-right
|
||||
* corner of the screen without stealing focus.
|
||||
*
|
||||
* @copyright 2021 K. Lange
|
||||
* This file is part of ToaruOS and is released under the terms
|
||||
* of the NCSA / University of Illinois License - see LICENSE.md
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
#include <sys/fswait.h>
|
||||
#include <toaru/pex.h>
|
||||
#include <toaru/yutani.h>
|
||||
#include <toaru/markup_text.h>
|
||||
#include <toaru/graphics.h>
|
||||
|
||||
static yutani_t * yctx;
|
||||
static FILE * pex_endpoint = NULL;
|
||||
static sprite_t background_sprite;
|
||||
|
||||
#define PAD_RIGHT 10
|
||||
#define PAD_TOP 48
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
/* Make sure we were actually expecting to be run... */
|
||||
if (argc < 2 || strcmp(argv[1],"--really")) {
|
||||
fprintf(stderr,
|
||||
"%s: Toast notification daemon\n"
|
||||
"\n"
|
||||
" Displays popup notifications from other\n"
|
||||
" applications in the corner of the screen.\n"
|
||||
" You probably don't want to run this directly - it is\n"
|
||||
" started automatically by the session manager.\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
/* Daemonize... */
|
||||
if (!fork()) {
|
||||
/* Connect to display server... */
|
||||
yctx = yutani_init();
|
||||
if (!yctx) {
|
||||
fprintf(stderr, "%s: Failed to connect to compositor.\n", argv[0]);
|
||||
}
|
||||
/* Open pex endpoint to receive notifications... */
|
||||
pex_endpoint = pex_bind("toast");
|
||||
if (!pex_endpoint) {
|
||||
fprintf(stderr, "%s: Failed to establish socket.\n", argv[0]);
|
||||
}
|
||||
/* Set up our text rendering and sprite contexts... */
|
||||
markup_text_init();
|
||||
load_sprite(&background_sprite, "/usr/share/ttk/toast/default.png");
|
||||
/* Make a test window? */
|
||||
yutani_window_t * wina = yutani_window_create_flags(yctx, background_sprite.width, background_sprite.height, YUTANI_WINDOW_FLAG_ALT_ANIMATION);
|
||||
yutani_window_move(yctx, wina, yctx->display_width - background_sprite.width - PAD_RIGHT, PAD_TOP); /* We need to be able to query the panel location... */
|
||||
gfx_context_t * ctx = init_graphics_yutani_double_buffer(wina);
|
||||
draw_fill(ctx, rgba(0,0,0,0));
|
||||
draw_sprite(ctx, &background_sprite, 0, 0);
|
||||
/* Wait for messages from pex, or from compositor... */
|
||||
markup_draw_string(ctx,10,26,"<b><h1>Welcome!</h1></b><br>This is a sample <i>toast</i> notification.",rgb(255,255,255));
|
||||
flip(ctx);
|
||||
yutani_flip(yctx, wina);
|
||||
|
||||
int should_exit = 0;
|
||||
while (!should_exit) {
|
||||
int fds[1] = {fileno(yctx->sock)};
|
||||
int index = fswait2(1,fds,20);
|
||||
if (index == 0) {
|
||||
yutani_msg_t * m = yutani_poll(yctx);
|
||||
while (m) {
|
||||
switch (m->type) {
|
||||
case YUTANI_MSG_KEY_EVENT:
|
||||
{
|
||||
struct yutani_msg_key_event * ke = (void*)m->data;
|
||||
if (ke->event.action == KEY_ACTION_DOWN && ke->event.keycode == 'q') {
|
||||
should_exit = 1;
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case YUTANI_MSG_WINDOW_MOUSE_EVENT:
|
||||
{
|
||||
struct yutani_msg_window_mouse_event * me = (void*)m->data;
|
||||
if (me->command == YUTANI_MOUSE_EVENT_DOWN && me->buttons & YUTANI_MOUSE_BUTTON_LEFT) {
|
||||
yutani_window_drag_start(yctx, wina);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case YUTANI_MSG_WINDOW_CLOSE:
|
||||
case YUTANI_MSG_SESSION_END:
|
||||
should_exit = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
free(m);
|
||||
m = yutani_poll_async(yctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
yutani_close(yctx, wina);
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -320,7 +320,7 @@ int main(int argc, char * argv[]) {
|
||||
|
||||
background = yutani_window_create_flags(yctx, yctx->display_width, yctx->display_height,
|
||||
YUTANI_WINDOW_FLAG_DISALLOW_RESIZE | YUTANI_WINDOW_FLAG_DISALLOW_DRAG |
|
||||
YUTANI_WINDOW_FLAG_ALT_ANIMATION | YUTANI_WINDOW_FLAG_NO_STEAL_FOCUS);
|
||||
YUTANI_WINDOW_FLAG_ALT_ANIMATION | YUTANI_WINDOW_FLAG_NO_STEAL_FOCUS | (1 << 5));
|
||||
yutani_window_move(yctx, background, 0, 0);
|
||||
yutani_window_update_shape(yctx, background, 2);
|
||||
background_ctx = init_graphics_yutani_double_buffer(background);
|
||||
|
Loading…
x
Reference in New Issue
Block a user