diff options
author | 2023-05-17 17:23:34 +0200 | |
---|---|---|
committer | 2023-05-17 17:23:34 +0200 | |
commit | 09c7778c402e6bc2f07d6582034fa807988a262c (patch) | |
tree | c107bedb13b1c88bd7323108bf4bbfd969dc00bf | |
parent | 2c08b225c0e3b8b4eea754d1ebd62be7ac06b936 (diff) | |
download | cherry-09c7778c402e6bc2f07d6582034fa807988a262c.tar.gz cherry-09c7778c402e6bc2f07d6582034fa807988a262c.zip |
Add cherry_window_set_listener() function
With this function, a CherryWindow can listen events. At the moment, just this
listener is available.
-rw-r--r-- | src/application.c | 50 | ||||
-rw-r--r-- | src/window.c | 8 | ||||
-rw-r--r-- | src/window.h | 6 |
3 files changed, 63 insertions, 1 deletions
diff --git a/src/application.c b/src/application.c index 4f48110..444dfc7 100644 --- a/src/application.c +++ b/src/application.c @@ -32,6 +32,53 @@ cherry_application_new(const char *name) return app; } +static void +dispatch_event(CherryApplication *app, Window wnd, int event_id) { + iterator_t it = clist_iterator(&app->windows); + while (clist_iterator_has_next(it)) { + CherryWindow *w = clist_iterator_next(&it); + if (w->window_handler == wnd) { + if (w->listener != NULL) { + w->listener(w, event_id); + } else { + return; + } + } + } +} + +static void +cherry_application_main_loop(CherryApplication *app) +{ + XEvent event; + int finish = 0; + char *atom_name; + + while (finish == 0) { + XNextEvent(app->display, &event); + + switch (event.type) { + case ClientMessage: + atom_name = XGetAtomName(app->display, (Atom) event.xclient.data.l[0]); + + if (strcmp("WM_DELETE_WINDOW", atom_name) == 0) { + dispatch_event(app, event.xclient.window, DELETE_WINDOW); + } + + XFree(atom_name); + break; + case Expose: + break; + case MappingNotify: + break; + case ButtonPress: + break; + case KeyPress: + break; + } + } +} + int cherry_application_run(CherryApplication *app, int argc, char **argv) { @@ -46,10 +93,13 @@ cherry_application_run(CherryApplication *app, int argc, char **argv) if (app->listener_activate != NULL) app->listener_activate(app, app->listener_activate_data); + cherry_application_main_loop(app); + /* finalization */ iterator_t it = clist_iterator(&app->windows); while (clist_iterator_has_next(it)) { CherryWindow *w = clist_iterator_next(&it); + char *wnd_name = cherry_window_get_title(w); printf("Destroying window: %s\n", wnd_name); XFree(wnd_name); diff --git a/src/window.c b/src/window.c index b7cbe14..c6eb5fd 100644 --- a/src/window.c +++ b/src/window.c @@ -16,6 +16,7 @@ cherry_window_new(void) w->dimension = cherry_dimension_new(); w->x = 0; w->y = 0; + w->listener = NULL; CherryApplication *app = cherry_application_get_running_app(); @@ -107,3 +108,10 @@ cherry_window_set_visible(CherryWindow *w, int visible) XMapRaised(app->display, w->window_handler); } } + +void +cherry_window_set_listener(CherryWindow *w, + int (*listener)(struct CherryWindow *, int)) +{ + w->listener = listener; +} diff --git a/src/window.h b/src/window.h index e22badc..f024feb 100644 --- a/src/window.h +++ b/src/window.h @@ -5,7 +5,7 @@ #include "dimension.h" -typedef struct { +typedef struct CherryWindow { char *title; CherryDimension *dimension; int x, y; @@ -13,6 +13,9 @@ typedef struct { /* Xlib stuff */ Window window_handler; + GC gc; + + int (*listener)(struct CherryWindow *, int); } CherryWindow; CherryWindow *cherry_window_new(void); @@ -21,5 +24,6 @@ void cherry_window_set_title(CherryWindow *, char *); void cherry_window_set_dimension(CherryWindow *, int, int); void cherry_window_set_position(CherryWindow *, int, int); void cherry_window_set_visible(CherryWindow *, int); +void cherry_window_set_listener(CherryWindow *, int (*listener)(struct CherryWindow *, int)); #endif /* __CHERRY_WINDOW_H__ */ |