diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 124 |
1 files changed, 124 insertions, 0 deletions
@@ -0,0 +1,124 @@ +#include <pthread.h> +#include <unistd.h> + +#include "glitch.h" + +WindowManager wm = {0}; + +static void* expose_timer_thread(void* arg) { + (void)arg; + + for(;;) { + sleep(1); + + if (wm.dpy != NULL) { + XEvent event = {0}; + event.type = Expose; + event.xexpose.window = wm.root; + event.xexpose.x = 0; + event.xexpose.y = 0; + event.xexpose.width = 1; + event.xexpose.height = 1; + event.xexpose.count = 0; + + // This is thread-safe - XSendEvent is designed for this. + XSendEvent(wm.dpy, wm.root, False, ExposureMask, &event); + XFlush(wm.dpy); + } + } + return NULL; +} + +int main(int argc, char *argv[]) { + (void)argc; + set_log_level(get_log_level_from_env()); + + // Initialize X11 threading support. + if (!XInitThreads()) { + log_message(stderr, LOG_ERROR, "XInitThreads failed"); + return 1; + } + + init_window_manager(); + + // Starts Expose ticker for updating widgets. + pthread_t timer_tid; + if (pthread_create(&timer_tid, NULL, expose_timer_thread, NULL) != 0) { + log_message(stderr, LOG_ERROR, "failed to create timer thread"); + } else { + pthread_detach(timer_tid); + } + + wm.running = 1; + while(wm.running) { + XNextEvent(wm.dpy, &wm.ev); + + switch (wm.ev.type) { + case MapRequest: + handle_map_request(); + break; + case UnmapNotify: + handle_unmap_notify(); + break; + case DestroyNotify: + handle_destroy_notify(); + break; + case PropertyNotify: + handle_property_notify(); + break; + case MotionNotify: + // Compress MotionNotify events. + while (XCheckTypedEvent(wm.dpy, MotionNotify, &wm.ev)); + handle_motion_notify(); + break; + case ClientMessage: + { + static Atom redraw_atom = None; + if (redraw_atom == None) redraw_atom = XInternAtom(wm.dpy, "GLITCH_WIDGET_REDRAW", False); + + if (wm.ev.xclient.message_type == redraw_atom) { + redraw_widgets(); + } else { + handle_client_message(); + } + } + break; + case ButtonPress: + handle_button_press(); + break; + case ButtonRelease: + handle_button_release(); + break; + case KeyPress: + handle_key_press(); + break; + case KeyRelease: + handle_key_release(); + break; + case FocusIn: + handle_focus_in(); + break; + case FocusOut: + handle_focus_out(); + break; + case EnterNotify: + handle_enter_notify(); + break; + case Expose: + handle_expose(); + break; + case ConfigureRequest: + handle_configure_request(); + break; + } + } + + deinit_window_manager(); + + if (wm.restart) { + execvp(argv[0], argv); + perror("execvp"); + } + + return 0; +} |
