aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Iezzi <aiezzi@alessandroiezzi.it>2023-05-17 17:23:34 +0200
committerAlessandro Iezzi <aiezzi@alessandroiezzi.it>2023-05-17 17:23:34 +0200
commit09c7778c402e6bc2f07d6582034fa807988a262c (patch)
treec107bedb13b1c88bd7323108bf4bbfd969dc00bf
parent2c08b225c0e3b8b4eea754d1ebd62be7ac06b936 (diff)
downloadcherry-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.c50
-rw-r--r--src/window.c8
-rw-r--r--src/window.h6
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__ */