From 0809a5eb5c659125fe081b76be15d226ed6a5792 Mon Sep 17 00:00:00 2001 From: Matthew Allum Date: Tue, 22 Mar 2005 17:25:52 +0000 Subject: [PATCH] Add glib event loop --- ChangeLog | 9 +++ cltr.c | 201 +++++++++++++++++++++++++++++++++++++++++------------- cltr.h | 2 + 3 files changed, 165 insertions(+), 47 deletions(-) create mode 100644 ChangeLog diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..b5b220052 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,9 @@ +2005-03-22 mallum,,, + + * cltr.c: (x_event_prepare), (x_event_check), (x_event_dispatch), + (cltr_dispatch_x_event), (cltr_init), (cltr_window_new), + (cltr_photo_grid_append_cell), (cltr_photo_grid_populate), + (cltr_photo_grid_redraw), (cltr_photo_grid_new), + (idle_cb), (main): + * cltr.h: + Add glib event loop diff --git a/cltr.c b/cltr.c index b698ecb9f..cb7889084 100644 --- a/cltr.c +++ b/cltr.c @@ -24,6 +24,89 @@ struct ClutterWindow ClutterMainContext CltrCntx; +/* Event Loop Integration */ + +typedef void (*CltrXEventFunc) (XEvent *xev, gpointer user_data); + +typedef struct +{ + GSource source; + Display *display; + GPollFD event_poll_fd; +} +CltrXEventSource; + + +static gboolean +x_event_prepare (GSource *source, + gint *timeout) +{ + Display *display = ((CltrXEventSource*)source)->display; + + *timeout = -1; + + return XPending (display); +} + +static gboolean +x_event_check (GSource *source) +{ + CltrXEventSource *display_source = (CltrXEventSource*)source; + gboolean retval; + + if (display_source->event_poll_fd.revents & G_IO_IN) + retval = XPending (display_source->display); + else + retval = FALSE; + + return retval; +} + +static gboolean +x_event_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + Display *display = ((CltrXEventSource*)source)->display; + CltrXEventFunc event_func = (CltrXEventFunc) callback; + + XEvent xev; + + if (XPending (display)) + { + XNextEvent (display, &xev); + + if (event_func) + (*event_func) (&xev, user_data); + } + + return TRUE; +} + +static const GSourceFuncs x_event_funcs = { + x_event_prepare, + x_event_check, + x_event_dispatch, + NULL +}; + +static void +cltr_dispatch_x_event (XEvent *xevent, + gpointer data) +{ + + + switch (xevent->type) + { + case MapNotify: + CLTR_DBG("Map Notify Event"); + break; + case Expose: + CLTR_DBG("Expose"); + break; + } +} + int cltr_init(int *argc, char ***argv) { @@ -39,6 +122,16 @@ cltr_init(int *argc, char ***argv) XVisualInfo *vinfo; + GMainContext *gmain_context; + int connection_number; + GSource *source; + CltrXEventSource *display_source; + + /* Not just yet .. + g_thread_init (NULL); + XInitThreads (); + */ + if ((CltrCntx.xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL) { return 0; @@ -57,6 +150,33 @@ cltr_init(int *argc, char ***argv) CltrCntx.gl_context = glXCreateContext(CltrCntx.xdpy, vinfo, 0, True); + /* g_main loop stuff */ + + gmain_context = g_main_context_default (); + + g_main_context_ref (gmain_context); + + connection_number = ConnectionNumber (CltrCntx.xdpy); + + source = g_source_new ((GSourceFuncs *)&x_event_funcs, + sizeof (CltrXEventSource)); + + display_source = (CltrXEventSource *)source; + + display_source->event_poll_fd.fd = connection_number; + display_source->event_poll_fd.events = G_IO_IN; + display_source->display = CltrCntx.xdpy; + + g_source_add_poll (source, &display_source->event_poll_fd); + g_source_set_can_recurse (source, TRUE); + + g_source_set_callback (source, + (GSourceFunc) cltr_dispatch_x_event, + NULL /* no userdata */, NULL); + + g_source_attach (source, gmain_context); + g_source_unref (source); + return 1; } @@ -78,6 +198,11 @@ cltr_window_new(int width, int height) 0, 0, WhitePixel(CltrCntx.xdpy, CltrCntx.xscreen)); + XSelectInput(CltrCntx.xdpy, win->xwin, + StructureNotifyMask|ExposureMask| + ButtonPressMask|ButtonReleaseMask|PointerMotionMask| + PropertyChangeMask); + glXMakeCurrent(CltrCntx.xdpy, win->xwin, CltrCntx.gl_context); glViewport (0, 0, width, height); @@ -95,7 +220,6 @@ cltr_window_new(int width, int height) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); - glLoadIdentity (); glOrtho (0, width, height, 0, -1, 1); @@ -114,12 +238,14 @@ cltr_window_new(int width, int height) void cltr_main_loop() { - XEvent xev; + GMainLoop *loop; + + loop = g_main_loop_new (g_main_context_default (), FALSE); + + CLTR_MARK(); + + g_main_loop_run (loop); - for (;;) - { - XNextEvent(CltrCntx.xdpy, &xev); - } } /* xxxxxxxxxxxxx */ @@ -296,10 +422,13 @@ cltr_photo_grid_redraw(ClutterPhotoGrid *grid) */ glLoadIdentity (); + // glTranslatef( -2.5, 2.0, 0.0); glScalef( Zoom, Zoom, Zoom); Zoom += 0.01; + if (Zoom > 4.0) Zoom = 0.0; + cell = g_list_first(grid->cells_tail); while (rows--) @@ -318,8 +447,8 @@ cltr_photo_grid_redraw(ClutterPhotoGrid *grid) thumb_w = (pixb->width / grid->n_cols); thumb_h = (pixb->height / grid->n_rows); - ew_border = thumb_w/4; - ns_border = thumb_h/4; + ew_border = thumb_w/8; + ns_border = thumb_h/8; thumb_w -= (2 * ew_border); thumb_h -= (2 * ns_border); @@ -330,18 +459,11 @@ cltr_photo_grid_redraw(ClutterPhotoGrid *grid) x2 = x1 + thumb_w; y2 = y1 + thumb_h; - glBindTexture(GL_TEXTURE_2D, grid->texs[i]); - - /* - glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, - (GLsizei)pixb->width, - (GLsizei)pixb->height, - GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, - pixb->data); - */ tx = (float) pixb->width / grid->tex_w; ty = (float) pixb->height / grid->tex_h; + glBindTexture(GL_TEXTURE_2D, grid->texs[i]); + glBegin (GL_QUADS); glTexCoord2f (tx, ty); glVertex2i (x2, y2); glTexCoord2f (0, ty); glVertex2i (x1, y2); @@ -405,58 +527,42 @@ cltr_photo_grid_new(ClutterWindow *win, return grid; } -static Bool -get_xevent_timed(Display *dpy, - XEvent *event_return, - struct timeval *tv) +gboolean +idle_cb(gpointer data) { - if (tv->tv_usec == 0 && tv->tv_sec == 0) - { - XNextEvent(dpy, event_return); - return True; - } + ClutterPhotoGrid *grid = (ClutterPhotoGrid *)data; - XFlush(dpy); + cltr_photo_grid_redraw(grid); - if (XPending(dpy) == 0) - { - int fd = ConnectionNumber(dpy); - fd_set readset; - FD_ZERO(&readset); - FD_SET(fd, &readset); - - if (select(fd+1, &readset, NULL, NULL, tv) == 0) - return False; - else { - XNextEvent(dpy, event_return); - return True; - } - - } else { - XNextEvent(dpy, event_return); - return True; - } + return TRUE; } - int main(int argc, char **argv) { ClutterPhotoGrid *grid = NULL; ClutterWindow *win = NULL; + cltr_init(&argc, &argv); win = cltr_window_new(640, 480); - grid = cltr_photo_grid_new(win, 3, 3, argv[1]); + grid = cltr_photo_grid_new(win, 4, 4, argv[1]); cltr_photo_grid_redraw(grid); + g_idle_add(idle_cb, grid); + XFlush(CltrCntx.xdpy); XMapWindow(CltrCntx.xdpy, grid->parent->xwin); + XFlush(CltrCntx.xdpy); + + cltr_main_loop(); + + /* { for (;;) { @@ -464,6 +570,7 @@ main(int argc, char **argv) XFlush(CltrCntx.xdpy); } } + */ return 0; } diff --git a/cltr.h b/cltr.h index 4b4c23570..92dc57f64 100644 --- a/cltr.h +++ b/cltr.h @@ -42,4 +42,6 @@ #endif +#define CLTR_MARK() CLTR_DBG("mark") + #endif