Add basic toolkit infrastructure
authorMatthew Allum <mallum@openedhand.com>
Sun, 3 Apr 2005 16:13:08 +0000 (16:13 +0000)
committerMatthew Allum <mallum@openedhand.com>
Sun, 3 Apr 2005 16:13:08 +0000 (16:13 +0000)
17 files changed:
ChangeLog
Makefile
cltr-core.c [new file with mode: 0644]
cltr-core.h [new file with mode: 0644]
cltr-events.c [new file with mode: 0644]
cltr-events.h [new file with mode: 0644]
cltr-photo-grid.c
cltr-photo-grid.h
cltr-private.h [new file with mode: 0644]
cltr-texture.c
cltr-texture.h
cltr-widget.c [new file with mode: 0644]
cltr-widget.h [new file with mode: 0644]
cltr-window.c [new file with mode: 0644]
cltr-window.h [new file with mode: 0644]
cltr.c
cltr.h

index 57178cd..66459f4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2005-04-03  mallum,,,  <mallum@openedhand.com>
+
+       * Makefile:
+       * cltr-core.c:
+       * cltr-core.h:
+       * cltr-events.c:
+       * cltr-events.h:
+       * cltr-photo-grid.c: (cltr_photo_grid_handle_xkeyevent),
+       (cltr_photo_grid_handle_xevent), (cltr_photo_grid_cell_new),
+       (cltr_photo_grid_append_cell), (ctrl_photo_grid_cell_to_coords),
+       (ctrl_photo_grid_get_zoomed_coords), (cell_is_offscreen),
+       (cltr_photo_grid_idle_cb), (cltr_photo_grid_navigate),
+       (cltr_photo_grid_activate_cell), (cltr_photo_grid_populate),
+       (cltr_photo_grid_paint), (cltr_photo_grid_show),
+       (cltr_photo_grid_new):
+       * cltr-photo-grid.h:
+       * cltr-private.h:
+       * cltr-texture.c:
+       * cltr-texture.h:
+       * cltr-widget.c:
+       * cltr-widget.h:
+       * cltr-window.c:
+       * cltr-window.h:
+       * cltr.c:
+       * cltr.h:
+       Add very basic initial toolkit infrastructure
+
 2005-03-31  mallum,,,  <mallum@openedhand.com>
 
        * cltr-photo-grid.c: (cltr_photo_grid_append_cell),
index 3f98c0a..2330ef5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,12 +4,30 @@ CFLAGS=`pkg-config --cflags pangoft2 pango glib-2.0 gthread-2.0`
 .c.o:
        $(CC) -g -Wall $(CFLAGS) $(INCS) -c $*.c
 
-OBJS=cltr.o pixbuf.o util.o fonts.o cltr-photo-grid.o cltr-texture.o
+OBJS=cltr.o pixbuf.o util.o fonts.o \
+     cltr-core.o                    \
+     cltr-texture.o                 \
+     cltr-widget.o                  \
+     cltr-events.o                 \
+     cltr-window.o                  \
+     cltr-photo-grid.o          
+
+# cltr-photo-grid.o
 
 clutter: $(OBJS)
        $(CC) -g -Wall -o $@ $(OBJS) $(LIBS)
 
-$(OBJS): pixbuf.h util.h fonts.h cltr.h cltr-photo-grid.h cltr-texture.h
+$(OBJS): pixbuf.h util.h fonts.h \
+         cltr.h                  \
+         cltr-private.h          \
+        cltr-events.h           \
+         cltr-texture.h          \
+         cltr-widget.h           \
+         cltr-window.h           \
+         cltr-photo-grid.h  
+
+#cltr-photo-grid.h
+
 
 clean:
        rm -fr *.o clutter test
diff --git a/cltr-core.c b/cltr-core.c
new file mode 100644 (file)
index 0000000..745f6ef
--- /dev/null
@@ -0,0 +1,44 @@
+#include "cltr-core.h"
+#include "cltr-private.h"
+
+int
+cltr_init(int *argc, char ***argv)
+{
+  int  gl_attributes[] =
+    {
+      GLX_RGBA, 
+      GLX_DOUBLEBUFFER,
+      GLX_RED_SIZE, 1,
+      GLX_GREEN_SIZE, 1,
+      GLX_BLUE_SIZE, 1,
+      0
+    };
+
+  XVisualInfo         *vinfo;  
+
+
+  g_thread_init (NULL);
+  // XInitThreads ();
+
+  if ((CltrCntx.xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
+    {
+      return 0;
+    }
+
+  CltrCntx.xscreen   = DefaultScreen(CltrCntx.xdpy);
+  CltrCntx.xwin_root = RootWindow(CltrCntx.xdpy, CltrCntx.xscreen);
+
+  if ((vinfo = glXChooseVisual(CltrCntx.xdpy, 
+                              CltrCntx.xscreen,
+                              gl_attributes)) == NULL)
+    {
+      fprintf(stderr, "Unable to find visual\n");
+      return 0;
+    }
+
+  CltrCntx.gl_context = glXCreateContext(CltrCntx.xdpy, vinfo, 0, True);
+
+  cltr_events_init();
+
+  return 1;
+}
diff --git a/cltr-core.h b/cltr-core.h
new file mode 100644 (file)
index 0000000..76e2a5c
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _HAVE_CLTR_CORE_H
+#define _HAVE_CLTR_CORE_H
+
+#include "cltr.h"
+
+int
+cltr_init(int *argc, char ***argv);
+
+#endif
diff --git a/cltr-events.c b/cltr-events.c
new file mode 100644 (file)
index 0000000..15425ac
--- /dev/null
@@ -0,0 +1,176 @@
+#include <X11/keysym.h>
+
+#include "cltr-events.h"
+#include "cltr-private.h"
+
+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
+};
+
+void
+cltr_dispatch_expose(XExposeEvent *xexpev)
+{
+  // cltr_photo_grid_redraw(Grid);
+}
+
+void
+cltr_dispatch_x_event (XEvent  *xevent,
+                      gpointer data)
+{
+  /* Should actually forward on to focussed widget */
+
+  ClutterMainContext *ctx = CLTR_CONTEXT();
+
+  cltr_widget_handle_xevent(ctx->window, xevent);
+  
+#if 0
+  switch (xevent->type)
+    {
+    case MapNotify:
+      CLTR_DBG("Map Notify Event");
+      break;
+    case Expose:
+      CLTR_DBG("Expose");      /* TODO COMPRESS */
+      cltr_dispatch_expose(&xevent->xexpose);
+      break;
+    case KeyPress:
+      CLTR_DBG("KeyPress");
+      cltr_dispatch_keypress(&xevent->xkey);
+      break;
+    }
+#endif 
+}
+
+void
+cltr_events_init()
+{
+  GMainContext         *gmain_context;
+  int                   connection_number;
+  GSource              *source;
+  CltrXEventSource     *display_source;
+
+  ClutterMainContext   *ctx = CLTR_CONTEXT();
+
+  /* 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);
+
+  ctx->internal_event_q = g_queue_new();  
+}
+
+void
+cltr_main_loop()
+{
+  ClutterMainContext *ctx = CLTR_CONTEXT();
+
+  /*
+  GMainLoop          *loop;
+
+  loop = g_main_loop_new (g_main_context_default (), FALSE);
+
+  g_main_loop_run (loop);
+  */
+
+  while (TRUE)
+    {
+      if (!g_queue_is_empty (ctx->internal_event_q))
+       {
+         CltrWidget *widget = NULL;
+         CltrWindow *win    = CLTR_WINDOW(ctx->window);
+
+         while ((widget = g_queue_pop_head(ctx->internal_event_q)) != NULL)
+           {
+             cltr_widget_paint(widget);
+           }
+
+         /* Swap Buffers */
+         glXSwapBuffers(ctx->xdpy, cltr_window_xwin(win));  
+       }
+
+      /* while (g_main_context_pending(g_main_context_default ())) */
+      g_main_context_iteration (g_main_context_default (), TRUE);
+
+    }
+}
diff --git a/cltr-events.h b/cltr-events.h
new file mode 100644 (file)
index 0000000..48180e9
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _HAVE_CLTR_EVENT_H
+#define _HAVE_CLTR_EVENT_H
+
+#include "cltr.h"
+
+
+
+void
+cltr_main_loop();
+
+void
+cltr_dispatch_x_event (XEvent  *xevent,
+                      gpointer data);
+
+void
+cltr_events_init();
+
+#endif
index 183bee2..b2676b8 100644 (file)
 #include "cltr-photo-grid.h"
+#include "cltr-private.h"
+
+/* 
+   TODO
+
+   - image cache !!
+
+   - change idle_cb to timeouts, reduce tearing + inc interactivity on
+     image load
+
+   - Split events into seperate file ( break up ctrl.c )
+   
+   - offset zoom a little to give border around picture grid
+
+   - figure out highlighting selected cell
+
+   - tape on pictures ?
+
+   - tidy this code here + document !
+     - fix threads, lower priority ?
+
+ */
+
+#define ANIM_FPS 60 
+#define FPS_TO_TIMEOUT(t) (1000/(t))
+
+struct CltrPhotoGridCell
+{
+  Pixbuf      *pixb;
+  float        angle;
+  CltrTexture *texture;
+  gint         anim_step;
+
+  CltrPhotoGridCellState state;
+};
+
+struct CltrPhotoGrid
+{
+  CltrWidget     widget;
+
+  gchar         *img_path;
+
+  int            n_rows;
+  int            n_cols;
+  int            row_offset;   /* for scrolling */
+
+  int            cell_width;
+  int            cell_height;
+
+  GList         *cells_tail;
+  GList         *cell_active;
+
+  /* animation / zoom etc stuff  */
+
+  int            anim_n_steps, anim_step;
+
+  float          zoom_min, zoom_max, zoom_step;
+
+  float          view_min_x, view_max_x, view_min_y, view_max_y; 
+
+  float          scroll_dist;
+
+  CltrPhotoGridState  state;
+
+  int                    scroll_state, scroll_step; /* urg */
+
+};
+
+static void
+cltr_photo_grid_paint(CltrWidget *widget);
+
+static gboolean 
+cltr_photo_grid_handle_xevent (CltrWidget *widget, XEvent *xev);
+
+static void
+cltr_photo_grid_show(CltrWidget *widget);
+
 
 /* this likely shouldn'y go here */
 static GMutex *Mutex_GRID = NULL;
 
-ClutterPhotoGridCell*
-cltr_photo_grid_cell_new(ClutterPhotoGrid *grid,
-                        Pixbuf           *pixb,
-                        const gchar      *filename)
+
+static void
+cltr_photo_grid_handle_xkeyevent(CltrPhotoGrid *grid, XKeyEvent *xkeyev)
 {
-  ClutterPhotoGridCell *cell = NULL;
-  int                   maxw = grid->width, maxh = grid->height;
+  KeySym kc;
+
+  kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0);
+
+  switch (kc)
+    {
+    case XK_Left:
+    case XK_KP_Left:
+      cltr_photo_grid_navigate(grid, CLTR_WEST);
+      break;
+    case XK_Up:
+    case XK_KP_Up:
+      cltr_photo_grid_navigate(grid, CLTR_NORTH);
+      break;
+    case XK_Right:
+    case XK_KP_Right:
+      cltr_photo_grid_navigate(grid, CLTR_EAST);
+      break;
+    case XK_Down:      
+    case XK_KP_Down:   
+      cltr_photo_grid_navigate(grid, CLTR_SOUTH);
+      break;
+    case XK_Return:
+      cltr_photo_grid_activate_cell(grid);
+      break;
+    default:
+      CLTR_DBG("unhandled keysym");
+    }
+}
+
+static gboolean 
+cltr_photo_grid_handle_xevent (CltrWidget *widget, XEvent *xev) 
+{
+  CltrPhotoGrid* grid = CLTR_PHOTO_GRID(widget);
+
+  switch (xev->type)
+    {
+    case KeyPress:
+      CLTR_DBG("KeyPress");
+      cltr_photo_grid_handle_xkeyevent(grid, &xev->xkey);
+      break;
+    }
+  
+  return TRUE;
+}
+
+
+CltrPhotoGridCell*
+cltr_photo_grid_cell_new(CltrPhotoGrid *grid,
+                        Pixbuf        *pixb,
+                        const gchar   *filename)
+{
+  CltrPhotoGridCell *cell = NULL;
+  int                   maxw = grid->widget.width, maxh = grid->widget.height;
   int                   neww = 0, newh = 0;
 
-  cell = g_malloc0(sizeof(ClutterPhotoGridCell));
+  cell = g_malloc0(sizeof(CltrPhotoGridCell));
 
   if (pixb->width > pixb->height) /* landscape */
     {
@@ -49,8 +177,8 @@ cltr_photo_grid_cell_new(ClutterPhotoGrid *grid,
 }
 
 void
-cltr_photo_grid_append_cell(ClutterPhotoGrid     *grid,
-                           ClutterPhotoGridCell *cell)
+cltr_photo_grid_append_cell(CltrPhotoGrid     *grid,
+                           CltrPhotoGridCell *cell)
 {
   grid->cells_tail = g_list_append(grid->cells_tail, cell);
 
@@ -59,7 +187,7 @@ cltr_photo_grid_append_cell(ClutterPhotoGrid     *grid,
 
 /* relative */
 static void
-ctrl_photo_grid_cell_to_coords(ClutterPhotoGrid *grid,
+ctrl_photo_grid_cell_to_coords(CltrPhotoGrid *grid,
                               GList            *cell,
                               int              *x,
                               int              *y)
@@ -77,7 +205,7 @@ ctrl_photo_grid_cell_to_coords(ClutterPhotoGrid *grid,
 }
 
 static void
-ctrl_photo_grid_get_zoomed_coords(ClutterPhotoGrid *grid,
+ctrl_photo_grid_get_zoomed_coords(CltrPhotoGrid *grid,
                                  int              x,
                                  int              y,
                                  float           *tx,
@@ -94,7 +222,7 @@ ctrl_photo_grid_get_zoomed_coords(ClutterPhotoGrid *grid,
 }
 
 static gboolean
-cell_is_offscreen(ClutterPhotoGrid *grid,
+cell_is_offscreen(CltrPhotoGrid *grid,
                  GList            *cell,
                  CltrDirection    *where)
 {
@@ -122,9 +250,9 @@ cell_is_offscreen(ClutterPhotoGrid *grid,
 gboolean
 cltr_photo_grid_idle_cb(gpointer data)
 {
-  ClutterPhotoGrid *grid = (ClutterPhotoGrid *)data;
+  CltrPhotoGrid *grid = (CltrPhotoGrid *)data;
 
-  cltr_photo_grid_redraw(grid);
+  cltr_widget_queue_paint(CLTR_WIDGET(grid));
 
   switch(grid->state)
     {
@@ -144,7 +272,7 @@ cltr_photo_grid_idle_cb(gpointer data)
 
 
 void
-cltr_photo_grid_navigate(ClutterPhotoGrid *grid,
+cltr_photo_grid_navigate(CltrPhotoGrid *grid,
                         CltrDirection     direction) 
 {
   GList *cell_orig = grid->cell_active;
@@ -198,7 +326,8 @@ cltr_photo_grid_navigate(ClutterPhotoGrid *grid,
            }
          
          if (grid->state != CLTR_PHOTO_GRID_STATE_ZOOMED)            
-           g_idle_add(cltr_photo_grid_idle_cb, grid);
+           g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS), 
+                         cltr_photo_grid_idle_cb, grid);
        }
 
       if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED)
@@ -215,7 +344,8 @@ cltr_photo_grid_navigate(ClutterPhotoGrid *grid,
          grid->anim_step  = 0;
          zoom             = grid->zoom_max;
 
-         g_idle_add(cltr_photo_grid_idle_cb, grid);
+         g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS), 
+                       cltr_photo_grid_idle_cb, grid);
        }
          
       ctrl_photo_grid_cell_to_coords(grid, grid->cell_active, &x, &y);
@@ -226,19 +356,20 @@ cltr_photo_grid_navigate(ClutterPhotoGrid *grid,
                                       
       CLTR_DBG("x: %f, y: %f", grid->view_max_x , grid->view_max_y);
 
-      cltr_photo_grid_redraw(grid);
+      cltr_widget_queue_paint(CLTR_WIDGET(grid));
     }
 }
 
 void                           /* bleh badly named */
-cltr_photo_grid_activate_cell(ClutterPhotoGrid *grid)
+cltr_photo_grid_activate_cell(CltrPhotoGrid *grid)
 {
   if (grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
     {
       grid->state = CLTR_PHOTO_GRID_STATE_ZOOM_IN;
 
 
-      g_idle_add(cltr_photo_grid_idle_cb, grid);
+      g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS), 
+                   cltr_photo_grid_idle_cb, grid);
     }
   else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED)
     {
@@ -248,7 +379,8 @@ cltr_photo_grid_activate_cell(ClutterPhotoGrid *grid)
       grid->view_min_x = 0.0; 
       grid->view_min_y = 0.0; /*- (grid->row_offset * grid->cell_height);*/
 
-      g_idle_add(cltr_photo_grid_idle_cb, grid);
+      g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS), 
+                   cltr_photo_grid_idle_cb, grid);
     }
 
   /* que a draw ? */
@@ -258,7 +390,7 @@ cltr_photo_grid_activate_cell(ClutterPhotoGrid *grid)
 gpointer
 cltr_photo_grid_populate(gpointer data) 
 {
-  ClutterPhotoGrid *grid = (ClutterPhotoGrid *)data;
+  CltrPhotoGrid *grid = (CltrPhotoGrid *)data;
   GDir             *dir;
   GError           *error;
   const gchar      *entry = NULL;
@@ -296,7 +428,7 @@ cltr_photo_grid_populate(gpointer data)
 
       if (pixb)
        {
-         ClutterPhotoGridCell *cell;
+         CltrPhotoGridCell *cell;
          gchar                 buf[24];
 
          cell = cltr_photo_grid_cell_new(grid, pixb, entry);
@@ -328,17 +460,22 @@ cltr_photo_grid_populate(gpointer data)
 
   g_mutex_unlock(Mutex_GRID);
 
-  cltr_photo_grid_redraw(grid);
+  cltr_widget_queue_paint(CLTR_WIDGET(grid));
 
   return NULL;
 }
 
-void
-cltr_photo_grid_redraw(ClutterPhotoGrid *grid)
+static void
+cltr_photo_grid_paint(CltrWidget *widget)
 {
-  int x = 0, y = 0, rows = grid->n_rows+1, cols = 0, i =0;
+  int x = 0, y = 0, rows = 0, cols = 0, i =0;
   GList *cell_item;
   float zoom, trans_x, trans_y;
+  CltrWindow *win = CLTR_WINDOW(widget->parent);
+
+  CltrPhotoGrid *grid = (CltrPhotoGrid *)widget;
+
+  rows = grid->n_rows+1;
 
   /* CLTR_MARK();*/
 
@@ -349,11 +486,12 @@ cltr_photo_grid_redraw(ClutterPhotoGrid *grid)
   if (grid->cells_tail == NULL)
     {
       /* No pictures to paint yet */
+      CltrWindow *win = CLTR_WINDOW(grid->widget.parent);
+
       glColor3f(0.6, 0.6, 0.62);
-      glRecti(0, 0, 640, 480);
+      glRecti(0, 0, widget->width, widget->height);
 
       glPopMatrix();
-      glXSwapBuffers(CltrCntx.xdpy, grid->parent->xwin);  
       return;
     }
 
@@ -448,8 +586,6 @@ cltr_photo_grid_redraw(ClutterPhotoGrid *grid)
              trans_y = ((grid->view_max_y - grid->view_min_y +  scroll_min_y_offset) * f)   ;
              y = 0;
 
-             printf("%f,%f, %f\n", grid->view_max_y, grid->view_min_y, scroll_min_y_offset);
-            
            }
        }
       else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE)
@@ -478,20 +614,20 @@ cltr_photo_grid_redraw(ClutterPhotoGrid *grid)
 
          grid->anim_step++;
 
-         if (grid->anim_step >= grid->anim_n_steps)
+          if (grid->anim_step >= (grid->anim_n_steps/4))
            {
              grid->state = CLTR_PHOTO_GRID_STATE_BROWSE;
              grid->anim_step = 0;
+             zoom = grid->zoom_min;
            }
          else
            {
-             float f = (float)grid->anim_step / grid->anim_n_steps;
+             float f = (float)grid->anim_step / (grid->anim_n_steps/4);
              trans_y += (grid->scroll_dist * f);
 
              if (grid->scroll_dist > 0) /* up */
                {
                  y = (grid->row_offset-1) * grid->cell_height;
-                 /* cell_item = g_list_nth(grid->cells_tail, grid->n_cols * (grid->row_offset+1));*/
                }
              else              /* down */
                {
@@ -511,7 +647,7 @@ cltr_photo_grid_redraw(ClutterPhotoGrid *grid)
       x = 0; 
       while (cols--)
        {
-         ClutterPhotoGridCell *cell = (ClutterPhotoGridCell *)cell_item->data;
+         CltrPhotoGridCell *cell = (CltrPhotoGridCell *)cell_item->data;
          Pixbuf *pixb = NULL;
          int     x1, x2, y1, y2, thumb_w, thumb_h;
          int     ns_border, ew_border;
@@ -607,9 +743,7 @@ cltr_photo_grid_redraw(ClutterPhotoGrid *grid)
   /* finally paint background  */
   glDisable(GL_TEXTURE_2D);
   glColor3f(0.6, 0.6, 0.62);
-  glRecti(0, 0, 640, 480);
-
-  glXSwapBuffers(CltrCntx.xdpy, grid->parent->xwin);  
+  glRecti(0, 0, widget->width, widget->height);
 
   g_mutex_lock(Mutex_GRID);
 
@@ -621,42 +755,50 @@ cltr_photo_grid_redraw(ClutterPhotoGrid *grid)
 
 }
 
-ClutterPhotoGrid*
-cltr_photo_grid_new(ClutterWindow *win, 
+static void
+cltr_photo_grid_show(CltrWidget *widget)
+{
+  CltrPhotoGrid* grid = CLTR_PHOTO_GRID(widget);
+
+  cltr_widget_queue_paint(widget);
+}
+
+CltrWidget*
+cltr_photo_grid_new(int            width, 
+                   int            height,
                    int            n_cols,
                    int            n_rows,
                    const gchar   *img_path)
 {
-  ClutterPhotoGrid *grid = NULL;
+  CltrPhotoGrid *grid = NULL;
   GThread          *loader_thread; 
 
-  grid = util_malloc0(sizeof(ClutterPhotoGrid));
+  grid = g_malloc0(sizeof(CltrPhotoGrid));
 
-  grid->img_path = strdup(img_path);
+  grid->widget.width  = width;
+  grid->widget.height = height;
+
+  grid->widget.show   = cltr_photo_grid_show;
+  grid->widget.paint  = cltr_photo_grid_paint;
+
+  grid->widget.xevent_handler = cltr_photo_grid_handle_xevent;
 
-  grid->width  = win->width;
-  grid->height = win->height;
+  grid->img_path = strdup(img_path);
   grid->n_cols = n_cols;
   grid->n_rows = n_rows;
-  grid->parent = win;
 
-  grid->cell_width  = grid->width  / n_cols;
-  grid->cell_height = grid->height / n_rows;
+  grid->cell_width  = grid->widget.width  / n_cols;
+  grid->cell_height = grid->widget.height / n_rows;
 
   grid->state = CLTR_PHOTO_GRID_STATE_LOADING;
 
-  grid->anim_n_steps = 40; /* value needs to be calced dep on rows */
+  grid->anim_n_steps = 20; /* value needs to be calced dep on rows */
   grid->anim_step    = 0;
 
-  /* 
-     grid->zoom_step = 0.05;
-     grid->zoom      = 1.0;
-  */
   grid->zoom_min  = 1.0;                     
-  grid->view_min_x = (grid->width - (grid->zoom_min * grid->width))/2.0;
+  grid->view_min_x = (grid->widget.width - (grid->zoom_min * grid->widget.width))/2.0;
   grid->view_min_y = 0.0;
 
-
   /* Assmes cols == rows */
   grid->zoom_max  = /* 1.0 + */  (float) (n_rows * 1.0); //  - 0.3;
 
@@ -673,17 +815,8 @@ cltr_photo_grid_new(ClutterWindow *win,
                                   TRUE,
                                   NULL);
 
-  /*
-  ctrl_photo_grid_cell_to_coords(grid, grid->cell_active, &x, &y);
-
-
-  ctrl_photo_grid_get_zoomed_coords(grid, grid->zoom_max,
-                                   x, y, 
-                                   &grid->view_max_x,
-                                   &grid->view_max_y);
-  */
-
-  g_idle_add(cltr_photo_grid_idle_cb, grid);
+  g_timeout_add(FPS_TO_TIMEOUT(20), 
+               cltr_photo_grid_idle_cb, grid);
 
-  return grid;
+  return CLTR_WIDGET(grid);
 }
index 2004ff4..69c90de 100644 (file)
@@ -3,11 +3,13 @@
 
 #include "cltr.h"
 
-typedef struct ClutterPhotoGrid ClutterPhotoGrid;
+typedef struct CltrPhotoGrid CltrPhotoGrid;
 
-typedef struct ClutterPhotoGridCell ClutterPhotoGridCell;
+typedef struct CltrPhotoGridCell CltrPhotoGridCell;
 
-typedef enum ClutterPhotoGridState
+#define CLTR_PHOTO_GRID(w) (CltrPhotoGrid*)(w)
+
+typedef enum CltrPhotoGridState
 {
   CLTR_PHOTO_GRID_STATE_LOADING       ,
   CLTR_PHOTO_GRID_STATE_LOAD_COMPLETE ,
@@ -18,90 +20,44 @@ typedef enum ClutterPhotoGridState
   CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE   ,
   CLTR_PHOTO_GRID_STATE_SCROLLED_MOVE ,
 } 
-ClutterPhotoGridState;
+CltrPhotoGridState;
 
-typedef enum ClutterPhotoGridCellState
+typedef enum CltrPhotoGridCellState
 {
   CLTR_PHOTO_GRID_CELL_STATE_APPEARING,
   CLTR_PHOTO_GRID_CELL_STATE_STATIC,
 } 
-ClutterPhotoGridCellState;
-
-
-struct ClutterPhotoGridCell
-{
-  Pixbuf      *pixb;
-  float        angle;
-  CltrTexture *texture;
-  gint         anim_step;
-
-  ClutterPhotoGridCellState state;
-};
-
-struct ClutterPhotoGrid
-{
-  /* XXX should be base widget stuff  */
-  int            x,y;
-  int            width;
-  int            height;
-  ClutterWindow *parent;
-
-  /* ****** */
-
-  gchar         *img_path;
-
-  int            n_rows;
-  int            n_cols;
-  int            row_offset;   /* for scrolling */
+CltrPhotoGridCellState;
 
-  int            cell_width;
-  int            cell_height;
 
-  GList         *cells_tail;
-  GList         *cell_active;
-
-  /* animation / zoom etc stuff  */
-
-  int            anim_n_steps, anim_step;
-
-  float          zoom_min, zoom_max, zoom_step;
-
-  float          view_min_x, view_max_x, view_min_y, view_max_y; 
-
-  float          scroll_dist;
-
-  ClutterPhotoGridState  state;
-
-  int                    scroll_state, scroll_step; /* urg */
-
-};
-
-ClutterPhotoGridCell*
-cltr_photo_grid_cell_new(ClutterPhotoGrid *grid,
+CltrPhotoGridCell*
+cltr_photo_grid_cell_new(CltrPhotoGrid *grid,
                         Pixbuf           *pixb,
                         const gchar      *filename);
 
 void
-cltr_photo_grid_append_cell(ClutterPhotoGrid     *grid,
-                           ClutterPhotoGridCell *cell);
+cltr_photo_grid_append_cell(CltrPhotoGrid     *grid,
+                           CltrPhotoGridCell *cell);
 
 void
-cltr_photo_grid_navigate(ClutterPhotoGrid *grid,
+cltr_photo_grid_navigate(CltrPhotoGrid *grid,
                         CltrDirection     direction) ;
 
 void                           /* bleh badly named */
-cltr_photo_grid_activate_cell(ClutterPhotoGrid *grid);
+cltr_photo_grid_activate_cell(CltrPhotoGrid *grid);
 
 gpointer
 cltr_photo_grid_populate(gpointer data) ;
 
 void
-cltr_photo_grid_redraw(ClutterPhotoGrid *grid);
+cltr_photo_grid_redraw(CltrPhotoGrid *grid);
 
-ClutterPhotoGrid*
-cltr_photo_grid_new(ClutterWindow *win, 
+CltrWidget*
+cltr_photo_grid_new(int            width, 
+                   int            height,
                    int            n_cols,
                    int            n_rows,
-                   const gchar   *imgs_path);
+                   const gchar   *img_path);
+
 
 #endif
diff --git a/cltr-private.h b/cltr-private.h
new file mode 100644 (file)
index 0000000..bc6ae40
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef _HAVE_CLTR_PRIVATE_H
+#define _HAVE_CLTR_PRIVATE_H
+
+#include "cltr.h"
+
+#define CLTR_WANT_DEBUG 1
+
+#if (CLTR_WANT_DEBUG)
+
+#define CLTR_DBG(x, a...) \
+ g_printerr ( __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a)
+
+#define CLTR_GLERR()                                           \
+ {                                                             \
+  GLenum err = glGetError ();  /* Roundtrip */                \
+  if (err != GL_NO_ERROR)                                      \
+    {                                                          \
+      g_printerr (__FILE__ ": GL Error: %x [at %s:%d]\n",      \
+                 err, __func__, __LINE__);                    \
+    }                                                          \
+ }
+
+#else
+
+#define CLTR_DBG(x, a...) do {} while (0)
+#define CLTR_GLERR()      do {} while (0)
+
+#endif
+
+#define CLTR_MARK() CLTR_DBG("mark")
+
+typedef void     (*WidgetPaintMethod)   (CltrWidget *widget ) ;
+typedef void     (*WidgetShowMethod)    (CltrWidget *widget ) ;
+typedef void     (*WidgetDestroyMethod) (CltrWidget *widget) ;
+
+typedef gboolean (*WidgetXEventHandler) (CltrWidget *widget, XEvent *xev) ;
+
+struct CltrWidget
+{
+  int         x,y,width,height;
+  CltrWidget *parent;
+
+  gboolean    visible;
+
+  GList      *children;
+
+  /* methods */
+
+  WidgetPaintMethod   paint;
+  WidgetShowMethod    show;
+  WidgetDestroyMethod destroy;
+
+  WidgetXEventHandler xevent_handler;
+};
+
+typedef struct ClutterMainContext ClutterMainContext;
+
+struct ClutterMainContext
+{
+  Display        *xdpy;
+  Window          xwin_root;
+  int             xscreen;
+  GC              xgc;
+
+  GLXContext      gl_context;
+  
+  CltrWidget     *window;
+  GQueue         *internal_event_q;
+};
+
+ClutterMainContext CltrCntx;
+
+#define CLTR_CONTEXT() &CltrCntx
+
+#endif
index 09ce187..25bcf50 100644 (file)
@@ -1,4 +1,5 @@
 #include "cltr-texture.h"
+#include "cltr-private.h"
 
 /* 
    IDEAS or less memory
index b78cbd3..8338228 100644 (file)
@@ -3,6 +3,24 @@
 
 #include "cltr.h"
 
+typedef struct CltrTexture CltrTexture;
+
+struct CltrTexture
+{
+  Pixbuf *pixb;
+
+  int    width, height;
+
+  int     n_x_tiles, n_y_tiles;
+  int    *tile_x_position, *tile_x_size, *tile_x_waste;
+  int    *tile_y_position, *tile_y_size, *tile_y_waste;
+
+  GLuint *tiles;
+
+  gint    refcnt; 
+};
+
+
 CltrTexture*
 cltr_texture_new(Pixbuf *pixb);
 
diff --git a/cltr-widget.c b/cltr-widget.c
new file mode 100644 (file)
index 0000000..5f1c997
--- /dev/null
@@ -0,0 +1,82 @@
+#include "cltr-widget.h"
+#include "cltr-private.h"
+
+CltrWidget*
+cltr_widget_new(void)
+{
+  CltrWidget *w = NULL;
+
+  w = g_malloc0(sizeof(CltrWidget));
+
+  return w;
+}
+
+void
+cltr_widget_show(CltrWidget *widget)
+{
+  if (widget->show)
+    {
+      widget->visible = TRUE;
+      widget->show(widget);
+    }
+}
+
+void
+cltr_widget_show_all(CltrWidget *widget)
+{
+  GList *widget_item =  widget->children;;
+
+  if (widget_item)
+    {
+      do 
+       {
+         CltrWidget *child = CLTR_WIDGET(widget_item->data);
+
+         cltr_widget_show(child);
+       }
+      while ((widget_item = g_list_next(widget_item)) != NULL);
+    }
+
+  cltr_widget_show(widget);
+}
+
+void
+cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y)
+{
+  widget->children = g_list_append(widget->children, child);
+
+  child->parent = widget;
+  child->x      = x;
+  child->y      = y;
+}
+
+
+void
+cltr_widget_hide(CltrWidget *widget)
+{
+  widget->visible = FALSE;
+}
+
+void
+cltr_widget_paint(CltrWidget *widget)
+{
+  if (widget->paint && widget->visible)
+    widget->paint(widget);
+}
+
+void
+cltr_widget_queue_paint(CltrWidget *widget)
+{
+  ClutterMainContext *ctx = CLTR_CONTEXT();
+
+  g_queue_push_head (ctx->internal_event_q, (gpointer)widget);
+}
+
+gboolean
+cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev)
+{
+  if (widget && widget->xevent_handler)
+    return widget->xevent_handler(widget, xev);
+
+  return FALSE;
+}
diff --git a/cltr-widget.h b/cltr-widget.h
new file mode 100644 (file)
index 0000000..75618ce
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _HAVE_CLTR_WIDGET_H
+#define _HAVE_CLTR_WIDGET_H
+
+typedef struct CltrWidget CltrWidget;
+
+#include "cltr.h"
+
+#define CLTR_WIDGET(w) ((CltrWidget*)(w))
+
+
+CltrWidget*
+cltr_widget_new(void);
+
+void
+cltr_widget_show(CltrWidget *widget);
+
+void
+cltr_widget_paint(CltrWidget *widget);
+
+
+gboolean
+cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev);
+
+
+
+void
+cltr_widget_show_all(CltrWidget *widget);
+
+void
+cltr_widget_queue_paint(CltrWidget *widget);
+
+void
+cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y);
+
+
+#endif
diff --git a/cltr-window.c b/cltr-window.c
new file mode 100644 (file)
index 0000000..337c579
--- /dev/null
@@ -0,0 +1,101 @@
+#include "cltr-window.h"
+#include "cltr-private.h"
+
+static gboolean 
+cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev);
+
+static void
+cltr_window_show(CltrWidget *widget);
+
+struct CltrWindow
+{
+  CltrWidget  widget;  
+  Window      xwin;
+  CltrWidget *focused_child;
+};
+
+CltrWidget*
+cltr_window_new(int width, int height)
+{
+  ClutterMainContext *ctx = CLTR_CONTEXT();
+  CltrWindow *win;
+
+  win = util_malloc0(sizeof(CltrWindow));
+
+  win->widget.width          = width;
+  win->widget.height         = height;
+  win->widget.show           = cltr_window_show;
+  win->widget.xevent_handler = cltr_window_handle_xevent;
+
+  win->xwin = XCreateSimpleWindow(CltrCntx.xdpy,
+                                 CltrCntx.xwin_root,
+                                 0, 0,
+                                 width, height,
+                                 0, 0, WhitePixel(CltrCntx.xdpy, 
+                                                  CltrCntx.xscreen));
+
+  XSelectInput(CltrCntx.xdpy, win->xwin, 
+              StructureNotifyMask|ExposureMask|
+              KeyPressMask|PropertyChangeMask);
+
+  glXMakeCurrent(CltrCntx.xdpy, win->xwin, CltrCntx.gl_context);
+
+  /* All likely better somewhere else */
+
+  /* view port */
+  glViewport (0, 0, width, height);
+  glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+  glOrtho (0, width, height, 0, -1, 1); /* 2d */
+  glMatrixMode (GL_MODELVIEW);
+  glLoadIdentity ();
+
+  ctx->window = CLTR_WIDGET(win);
+
+  return CLTR_WIDGET(win);
+}
+
+Window
+cltr_window_xwin(CltrWindow *win)
+{
+  return win->xwin;
+}
+
+static void
+cltr_window_show(CltrWidget *widget)
+{
+  ClutterMainContext *ctx = CLTR_CONTEXT();
+  CltrWindow         *win = CLTR_WINDOW(widget);
+
+  /* XXX set focused call */
+  if (widget->children)
+    {
+      win->focused_child = g_list_nth_data(widget->children, 0);
+    }
+
+  XMapWindow(ctx->xdpy, win->xwin);
+}
+
+static gboolean 
+cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev) 
+{
+  CltrWindow *win = CLTR_WINDOW(widget);
+
+  /* XXX handle exposes here too */
+
+  if (xev->type == Expose)
+    {
+      ;
+    }
+
+  /* XXX Very basic - assumes we are only interested in mouse clicks */
+  if (win->focused_child)
+    return cltr_widget_handle_xevent(win->focused_child, xev);
+
+  return FALSE;
+}
+
+/* window only */
+
+
+
diff --git a/cltr-window.h b/cltr-window.h
new file mode 100644 (file)
index 0000000..237bec7
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _HAVE_CLTR_WINDOW_H
+#define _HAVE_CLTR_WINDOW_H
+
+#include "cltr.h"
+
+typedef struct CltrWindow CltrWindow;
+
+#define CLTR_WINDOW(w) ((CltrWindow*)(w))
+
+CltrWidget*
+cltr_window_new(int width, int height);
+
+Window
+cltr_window_xwin(CltrWindow *win);
+
+void
+cltr_window_paint(CltrWidget *widget);
+
+void
+cltr_window_add_widget(CltrWindow *win, CltrWidget *widget, int x, int y);
+
+
+#endif
diff --git a/cltr.c b/cltr.c
index b42b0a5..addfdd2 100644 (file)
--- a/cltr.c
+++ b/cltr.c
 #include "cltr.h"
 
-#include <X11/keysym.h>
-
-/* temp temp temp */
-
-float Zoom = 1.0;
-ClutterPhotoGrid *Grid = NULL;
-
-/* ************* */
-
-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
-};
-
-void
-cltr_dispatch_expose(XExposeEvent *xexpev)
-{
-  cltr_photo_grid_redraw(Grid);
-}
-
-void
-cltr_dispatch_keypress(XKeyEvent *xkeyev)
-{
-  KeySym kc;
-
-  kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0);
-
-  switch (kc)
-    {
-    case XK_Left:
-    case XK_KP_Left:
-      cltr_photo_grid_navigate(Grid, CLTR_WEST);
-      break;
-    case XK_Up:
-    case XK_KP_Up:
-      cltr_photo_grid_navigate(Grid, CLTR_NORTH);
-      break;
-    case XK_Right:
-    case XK_KP_Right:
-      cltr_photo_grid_navigate(Grid, CLTR_EAST);
-      break;
-    case XK_Down:      
-    case XK_KP_Down:   
-      cltr_photo_grid_navigate(Grid, CLTR_SOUTH);
-      break;
-    case XK_Return:
-      cltr_photo_grid_activate_cell(Grid);
-      break;
-    default:
-      CLTR_DBG("unhandled keysym");
-    }
-}
-
-static void
-cltr_dispatch_x_event (XEvent  *xevent,
-                      gpointer data)
-{
-  /* Should actually forward on to focussed widget */
-
-  switch (xevent->type)
-    {
-    case MapNotify:
-      CLTR_DBG("Map Notify Event");
-      break;
-    case Expose:
-      CLTR_DBG("Expose");      /* TODO COMPRESS */
-      cltr_dispatch_expose(&xevent->xexpose);
-      break;
-    case KeyPress:
-      CLTR_DBG("KeyPress");
-      cltr_dispatch_keypress(&xevent->xkey);
-      break;
-    }
-}
-
-int
-cltr_init(int *argc, char ***argv)
-{
-  int  gl_attributes[] =
-    {
-      GLX_RGBA, 
-      GLX_DOUBLEBUFFER,
-      GLX_RED_SIZE, 1,
-      GLX_GREEN_SIZE, 1,
-      GLX_BLUE_SIZE, 1,
-      0
-    };
-
-  XVisualInfo         *vinfo;  
-
-  GMainContext         *gmain_context;
-  int                   connection_number;
-  GSource              *source;
-  CltrXEventSource     *display_source;
-
-  g_thread_init (NULL);
-  // XInitThreads ();
-
-  if ((CltrCntx.xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
-    {
-      return 0;
-    }
-
-  CltrCntx.xscreen   = DefaultScreen(CltrCntx.xdpy);
-  CltrCntx.xwin_root = RootWindow(CltrCntx.xdpy, CltrCntx.xscreen);
-
-  if ((vinfo = glXChooseVisual(CltrCntx.xdpy, 
-                              CltrCntx.xscreen,
-                              gl_attributes)) == NULL)
-    {
-      fprintf(stderr, "Unable to find visual\n");
-      return 0;
-    }
-
-  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;
-}
-
-
-ClutterWindow*
-cltr_window_new(int width, int height)
-{
-  ClutterWindow *win;
-
-  win = util_malloc0(sizeof(ClutterWindow));
-
-  win->width  = width;
-  win->height = height;
-
-  win->xwin = XCreateSimpleWindow(CltrCntx.xdpy,
-                                 CltrCntx.xwin_root,
-                                 0, 0,
-                                 width, height,
-                                 0, 0, WhitePixel(CltrCntx.xdpy, 
-                                                  CltrCntx.xscreen));
-
-  XSelectInput(CltrCntx.xdpy, win->xwin, 
-              StructureNotifyMask|ExposureMask|
-              KeyPressMask|PropertyChangeMask);
-
-  glXMakeCurrent(CltrCntx.xdpy, win->xwin, CltrCntx.gl_context);
-
-  /* All likely better somewhere else */
-
-  /* view port */
-  glViewport (0, 0, width, height);
-  glMatrixMode (GL_PROJECTION);
-  glLoadIdentity ();
-  glOrtho (0, width, height, 0, -1, 1); /* 2d */
-  glMatrixMode (GL_MODELVIEW);
-  glLoadIdentity ();
-
-  glEnable        (GL_TEXTURE_2D);
-  glTexParameteri (GL_TEXTURE_2D,  GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-  glTexParameteri (GL_TEXTURE_2D,  GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-  glTexEnvi       (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,   GL_REPLACE);
-
-  return win;
-}
-
-void
-cltr_main_loop()
-{
-  GMainLoop *loop;
-
-  loop = g_main_loop_new (g_main_context_default (), FALSE);
-
-  CLTR_MARK();
-
-  g_main_loop_run (loop);
-
-}
-
-gboolean
-test_idle_cb(gpointer data)
-{
-  static float angle = 0.0;
-
-  glClear(GL_COLOR_BUFFER_BIT);
-  glClearColor( 0.6, 0.6, 0.62, 1.0);
-
-  glColor3f(0.0, 0.0, 0.0);
-
-  glTranslatef( 0.0, 0.0, 0.0);
-
-  /* get a copy of our untranformed matrix */
-  glPushMatrix();
-
-  /* Translate origin to rotation point */
-  glTranslatef( 320.0, 240.0, 0.0);
-
-  /* Rotate around Z axis */
-  glRotatef ( angle, 0.0, 0.0, 1.0);
-
-  /* Draw tranformed rect with origin at center */
-  glRecti(-50, -50, 50, 50);
-
-  /* Reset our un transformed matrix */
-  glPopMatrix();
-
-  glRecti(-50, -50, 50, 50);
-
-  angle += 0.1;
-
-  glXSwapBuffers(CltrCntx.xdpy, (Window)data);  
-
-  return TRUE;
-}
-
-
-
 int
 main(int argc, char **argv)
 {
-  ClutterPhotoGrid *grid = NULL;
-  ClutterWindow    *win = NULL;
-  /*
-  Pixbuf *p1, *p2, *p3;
-
-  p1 = pixbuf_new(2000,2000);
-  p2 = pixbuf_new(640,480);
-  p3 = pixbuf_scale_down(p1, 512, 512);
-
-  pixbuf_copy(p3, p2, 0,0, 1000, 1000,0,0);
+  CltrWidget    *win = NULL, *grid = NULL;
 
-  exit(1);
-  */
   if (argc < 2)
     {
       g_printerr("usage: '%s' <path to not too heavily populated image dir>\n"
@@ -314,23 +16,11 @@ main(int argc, char **argv)
 
   win = cltr_window_new(640, 480);
 
-  grid = cltr_photo_grid_new(win, 3, 3, argv[1]);
-
-  Grid = grid;                         /* laaaaaazy globals */
-
-  // cltr_photo_grid_redraw(grid);
-
-  // g_idle_add(idle_cb, grid);
-
-  // g_timeout_add (10, idle_cb, grid);
-
-  // g_idle_add(test_idle_cb, (gpointer)win->xwin);
-
-  XFlush(CltrCntx.xdpy);
+  grid = cltr_photo_grid_new(640, 480, 3, 3, argv[1]);
 
-  XMapWindow(CltrCntx.xdpy, win->xwin);
+  cltr_widget_add_child(win, grid, 0, 0);
 
-  XFlush(CltrCntx.xdpy);
+  cltr_widget_show_all(win);
 
   cltr_main_loop();
 
diff --git a/cltr.h b/cltr.h
index 86bdd5f..d7029e3 100644 (file)
--- a/cltr.h
+++ b/cltr.h
@@ -8,6 +8,7 @@
 #include <math.h>
 
 #include <X11/Xlib.h>
+#include <X11/keysym.h>
 
 #include <GL/glx.h>
 #include <GL/gl.h>
 #include "pixbuf.h"
 #include "fonts.h"
 
-#define CLTR_WANT_DEBUG 1
-
-#if (CLTR_WANT_DEBUG)
-
-#define CLTR_DBG(x, a...) \
- g_printerr ( __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a)
-
-#define CLTR_GLERR()                                           \
- {                                                             \
-  GLenum err = glGetError ();  /* Roundtrip */                \
-  if (err != GL_NO_ERROR)                                      \
-    {                                                          \
-      g_printerr (__FILE__ ": GL Error: %x [at %s:%d]\n",      \
-                 err, __func__, __LINE__);                    \
-    }                                                          \
- }
-
-#else
-
-#define CLTR_DBG(x, a...) do {} while (0)
-#define CLTR_GLERR()      do {} while (0)
-
-#endif
-
-#define CLTR_MARK() CLTR_DBG("mark")
-
-typedef struct CltrTexturePool CltrTexturePool;
-
-struct CltrTexturePool
-{
-  GList  *texture_items;
-  gint    n_texture_items;
-  GLuint *gl_textures;
-};
-
-typedef struct ClutterMainContext ClutterMainContext;
-
-struct ClutterMainContext
-{
-  Display        *xdpy;
-  Window          xwin_root;
-  int             xscreen;
-  GC              xgc;
-  GLXContext      gl_context;
-  CltrTexturePool texture_pool;
-};
-
 typedef enum CltrDirection
 {
   CLTR_NORTH,
@@ -73,51 +27,16 @@ typedef enum CltrDirection
 } 
 CltrDirection;
 
-typedef struct ClutterWindow ClutterWindow;
-
-struct ClutterWindow
-{
-  Window xwin;
-  int    width;
-  int    height;
-};
-
-ClutterMainContext CltrCntx;
-
-/* Event Loop Integration */
-
-typedef void (*CltrXEventFunc) (XEvent *xev, gpointer user_data);
-
-typedef struct 
-{
-  GSource  source;
-  Display *display;
-  GPollFD  event_poll_fd;
-} 
-CltrXEventSource;
-
 /* texture stuff */
 
-typedef struct CltrTexture CltrTexture;
-
-struct CltrTexture
-{
-  Pixbuf *pixb;
-
-  int    width, height;
-
-  int     n_x_tiles, n_y_tiles;
-  int    *tile_x_position, *tile_x_size, *tile_x_waste;
-  int    *tile_y_position, *tile_y_size, *tile_y_waste;
-
-  GLuint *tiles;
-
-  gint    refcnt; 
-};
-
 /* ******************* */
 
+#include "cltr-core.h"
 #include "cltr-texture.h"
+#include "cltr-events.h"
+#include "cltr-widget.h"
+#include "cltr-window.h"
+
 #include "cltr-photo-grid.h"
 
 #endif