From 6db3fe2ec24096b8e28e1159399e45b9bba75b53 Mon Sep 17 00:00:00 2001 From: Kevin Lange Date: Sun, 13 Apr 2014 18:28:42 -0700 Subject: [PATCH] Focus change events --- userspace/build.py | 2 +- userspace/gui/compositor/compositor-beta.c | 7 ++++ userspace/gui/compositor/yutani_int.h | 1 + userspace/gui/terminal/terminal-beta.c | 25 +++++++++++--- userspace/lib/yutani.c | 21 ++++++++++++ userspace/lib/yutani.h | 38 ++++++++++++++-------- 6 files changed, 75 insertions(+), 19 deletions(-) diff --git a/userspace/build.py b/userspace/build.py index a6daaa5e..4339c868 100644 --- a/userspace/build.py +++ b/userspace/build.py @@ -52,7 +52,7 @@ class CCompiler(object): '"lib/shmemfonts.h"': (None, 'lib/shmemfonts.o', ['"lib/graphics.h"', '']), '"lib/wcwidth.h"': (None, 'lib/wcwidth.o', []), '"lib/window.h"': (None, 'lib/window.o', ['"lib/pthread.h"', '"lib/list.h"']), - '"lib/yutani.h"': (None, 'lib/yutani.o', ['"lib/pthread.h"', '"lib/list.h"', '"lib/pex.h"', '"lib/graphics.h"']), + '"lib/yutani.h"': (None, 'lib/yutani.o', ['"lib/pthread.h"', '"lib/list.h"', '"lib/pex.h"', '"lib/graphics.h"', '"lib/hashmap.h"']), '"gui/ttk/ttk.h"': (None, 'gui/ttk/lib/ttk-core.o', ['"lib/decorations.h"', '', '']), '"gui/terminal/lib/termemu.h"': (None, 'gui/terminal/lib/termemu.o', []), diff --git a/userspace/gui/compositor/compositor-beta.c b/userspace/gui/compositor/compositor-beta.c index 44a4354d..577da4db 100644 --- a/userspace/gui/compositor/compositor-beta.c +++ b/userspace/gui/compositor/compositor-beta.c @@ -197,10 +197,16 @@ static void set_focused_window(yutani_globals_t * yg, yutani_server_window_t * w if (yg->focused_window) { /* XXX Send focus change to old focused window */ + yutani_msg_t * response = yutani_msg_build_window_focus_change(yg->focused_window->wid, 0); + pex_send(yg->server, yg->focused_window->owner, response->size, (char *)response); + free(response); } yg->focused_window = w; if (w) { /* XXX Send focus change to new focused window */ + yutani_msg_t * response = yutani_msg_build_window_focus_change(w->wid, 1); + pex_send(yg->server, w->owner, response->size, (char *)response); + free(response); make_top(yg, w); } else { /* XXX */ @@ -604,6 +610,7 @@ int main(int argc, char * argv[]) { setenv("DISPLAY", yg->pex_endpoint, 1); FILE * server = pex_bind(yg->pex_endpoint); + yg->server = server; fprintf(stderr, "[yutani] Loading fonts...\n"); load_fonts(); diff --git a/userspace/gui/compositor/yutani_int.h b/userspace/gui/compositor/yutani_int.h index 9d35ccf5..4ded6cd7 100644 --- a/userspace/gui/compositor/yutani_int.h +++ b/userspace/gui/compositor/yutani_int.h @@ -70,6 +70,7 @@ typedef struct { char * pex_endpoint; yutani_server_window_t * focused_window; + FILE * server; } yutani_globals_t; diff --git a/userspace/gui/terminal/terminal-beta.c b/userspace/gui/terminal/terminal-beta.c index f1a1ad3d..27b75941 100644 --- a/userspace/gui/terminal/terminal-beta.c +++ b/userspace/gui/terminal/terminal-beta.c @@ -144,6 +144,7 @@ static void render_decors() { } else { render_decorations(&w, ctx, "Terminal"); } + yutani_flip(yctx, window); } } @@ -972,10 +973,26 @@ void * handle_incoming(void * garbage) { while (!exit_application) { yutani_msg_t * m = yutani_poll(yctx); if (m) { - if (m->type == YUTANI_MSG_KEY_EVENT) { - struct yutani_msg_key_event * ke = (void*)m->data; - int ret = (ke->event.action == KEY_ACTION_DOWN) && (ke->event.key); - key_event(ret, &ke->event); + switch (m->type) { + case YUTANI_MSG_KEY_EVENT: + { + struct yutani_msg_key_event * ke = (void*)m->data; + int ret = (ke->event.action == KEY_ACTION_DOWN) && (ke->event.key); + key_event(ret, &ke->event); + } + break; + case YUTANI_MSG_WINDOW_FOCUS_CHANGE: + { + struct yutani_msg_window_focus_change * wf = (void*)m->data; + yutani_window_t * win = hashmap_get(yctx->windows, (void*)wf->wid); + if (win) { + win->focused = wf->focused; + render_decors(); + } + } + break; + default: + break; } free(m); } diff --git a/userspace/lib/yutani.c b/userspace/lib/yutani.c index 62a94ed1..f08da675 100644 --- a/userspace/lib/yutani.c +++ b/userspace/lib/yutani.c @@ -7,6 +7,7 @@ #include "graphics.h" #include "kbd.h" #include "mouse.h" +#include "hashmap.h" yutani_msg_t * yutani_wait_for(yutani_t * y, uint32_t type) { do { @@ -197,6 +198,22 @@ yutani_msg_t * yutani_msg_build_window_stack(yutani_wid_t wid, int z) { return msg; } +yutani_msg_t * yutani_msg_build_window_focus_change(yutani_wid_t wid, int focused) { + size_t s = sizeof(struct yutani_message) + sizeof(struct yutani_msg_window_focus_change); + yutani_msg_t * msg = malloc(s); + + msg->magic = YUTANI_MSG__MAGIC; + msg->type = YUTANI_MSG_WINDOW_FOCUS_CHANGE; + msg->size = s; + + struct yutani_msg_window_focus_change * mw = (void *)msg->data; + + mw->wid = wid; + mw->focused = focused; + + return msg; +} + int yutani_msg_send(yutani_t * y, yutani_msg_t * msg) { return pex_reply(y->sock, msg->size, (char *)msg); } @@ -207,6 +224,7 @@ yutani_t * yutani_context_create(FILE * socket) { out->sock = socket; out->display_width = 0; out->display_height = 0; + out->windows = hashmap_create_int(10); return out; } @@ -253,6 +271,9 @@ yutani_window_t * yutani_window_create(yutani_t * y, int width, int height) { win->height = mw->height; win->bufid = mw->bufid; win->wid = mw->wid; + win->focused = 0; + + hashmap_set(y->windows, (void*)win->wid, win); char key[1024]; YUTANI_SHMKEY(key, 1024, win); diff --git a/userspace/lib/yutani.h b/userspace/lib/yutani.h index 79244c22..9e798ebe 100644 --- a/userspace/lib/yutani.h +++ b/userspace/lib/yutani.h @@ -4,6 +4,7 @@ #include #include +#include "hashmap.h" #include "graphics.h" #include "kbd.h" #include "mouse.h" @@ -20,6 +21,8 @@ typedef struct yutani_context { /* XXX display struct with more information? */ size_t display_width; size_t display_height; + + hashmap_t * windows; } yutani_t; typedef struct yutani_message { @@ -70,6 +73,11 @@ struct yutani_msg_window_stack { int z; }; +struct yutani_msg_window_focus_change { + yutani_wid_t wid; + int focused; +}; + struct yutani_msg_mouse_event { yutani_wid_t wid; mouse_device_packet_t event; @@ -88,24 +96,25 @@ typedef struct yutani_window { } yutani_window_t; /* Magic value */ -#define YUTANI_MSG__MAGIC 0xABAD1DEA +#define YUTANI_MSG__MAGIC 0xABAD1DEA /* Client messages */ -#define YUTANI_MSG_HELLO 0x00000001 -#define YUTANI_MSG_WINDOW_NEW 0x00000002 -#define YUTANI_MSG_FLIP 0x00000003 -#define YUTANI_MSG_KEY_EVENT 0x00000004 -#define YUTANI_MSG_MOUSE_EVENT 0x00000005 -#define YUTANI_MSG_WINDOW_MOVE 0x00000006 -#define YUTANI_MSG_WINDOW_CLOSE 0x00000007 -#define YUTANI_MSG_WINDOW_SHOW 0x00000008 -#define YUTANI_MSG_WINDOW_HIDE 0x00000009 -#define YUTANI_MSG_WINDOW_STACK 0x0000000A -#define YUTANI_MSG_GOODBYE 0x000000F0 +#define YUTANI_MSG_HELLO 0x00000001 +#define YUTANI_MSG_WINDOW_NEW 0x00000002 +#define YUTANI_MSG_FLIP 0x00000003 +#define YUTANI_MSG_KEY_EVENT 0x00000004 +#define YUTANI_MSG_MOUSE_EVENT 0x00000005 +#define YUTANI_MSG_WINDOW_MOVE 0x00000006 +#define YUTANI_MSG_WINDOW_CLOSE 0x00000007 +#define YUTANI_MSG_WINDOW_SHOW 0x00000008 +#define YUTANI_MSG_WINDOW_HIDE 0x00000009 +#define YUTANI_MSG_WINDOW_STACK 0x0000000A +#define YUTANI_MSG_WINDOW_FOCUS_CHANGE 0x0000000B +#define YUTANI_MSG_GOODBYE 0x000000F0 /* Server responses */ -#define YUTANI_MSG_WELCOME 0x00010001 -#define YUTANI_MSG_WINDOW_INIT 0x00010002 +#define YUTANI_MSG_WELCOME 0x00010001 +#define YUTANI_MSG_WINDOW_INIT 0x00010002 #define YUTANI_ZORDER_MAX 0xFFFF #define YUTANI_ZORDER_TOP 0xFFFF @@ -123,6 +132,7 @@ yutani_msg_t * yutani_msg_build_key_event(yutani_wid_t wid, key_event_t * event) yutani_msg_t * yutani_msg_build_mouse_event(yutani_wid_t wid, mouse_device_packet_t * event); yutani_msg_t * yutani_msg_build_window_close(yutani_wid_t wid); yutani_msg_t * yutani_msg_build_window_stack(yutani_wid_t wid, int z); +yutani_msg_t * yutani_msg_build_window_focus_change(yutani_wid_t wid, int focused); int yutani_msg_send(yutani_t * y, yutani_msg_t * msg); yutani_t * yutani_context_create(FILE * socket);