Lots, see ChangeLog
authorMatthew Allum <mallum@openedhand.com>
Fri, 22 Apr 2005 18:03:55 +0000 (18:03 +0000)
committerMatthew Allum <mallum@openedhand.com>
Fri, 22 Apr 2005 18:03:55 +0000 (18:03 +0000)
23 files changed:
ChangeLog
Makefile.am
clutter/Makefile.am
clutter/cltr-button.c [new file with mode: 0644]
clutter/cltr-button.h [new file with mode: 0644]
clutter/cltr-core.c
clutter/cltr-overlay.c [new file with mode: 0644]
clutter/cltr-overlay.h [new file with mode: 0644]
clutter/cltr-photo-grid.c
clutter/cltr-photo-grid.h
clutter/cltr-texture.c
clutter/cltr-texture.h
clutter/cltr-window.c
clutter/cltr.h
clutter/pixbuf.c
clutter/pixbuf.h
configure.ac
examples/Makefile.am
examples/photos.c [new file with mode: 0644]
examples/player.c [new file with mode: 0644]
gst/Makefile.am [new file with mode: 0644]
gst/cltrimagesink.c [new file with mode: 0644]
gst/cltrimagesink.h [new file with mode: 0644]

index c6c48bd..d262cf7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,41 @@
+2005-04-22  mallum,,,  <mallum@openedhand.com>
+
+       * clutter/Makefile.am:
+       * clutter/cltr-button.c:
+       * clutter/cltr-button.h:
+       * clutter/cltr-core.c: (cltr_init):
+       * clutter/cltr-overlay.c:
+       * clutter/cltr-overlay.h:
+       * clutter/cltr-photo-grid.c: (cltr_photo_grid_handle_xevent),
+       (cltr_photo_grid_cell_new), (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_update_visual_state),
+       (cltr_photo_grid_paint), (cltr_photo_grid_show),
+       (cltr_photo_grid_set_fps), (cltr_photo_grid_get_fps),
+       (cltr_photo_grid_set_anim_steps), (cltr_photo_grid_get_anim_steps),
+       (cltr_photo_grid_new):
+       Fix up grid so external prog can load images.   
+       * clutter/cltr-photo-grid.h:
+       * clutter/cltr-texture.c: (cltr_texture_realize),
+       (cltr_texture_new):
+       * clutter/cltr-texture.h:
+       * clutter/cltr-window.c: (cltr_window_set_fullscreen):
+       * clutter/cltr.h:
+       * clutter/pixbuf.c: (pixbuf_scale_down), (ConvolveImage),
+       (GaussianBlurImage):
+       * clutter/pixbuf.h:
+       New experimental Methods
+       * configure.ac:
+       * examples/Makefile.am:
+       * examples/photos.c:
+       * examples/player.c:
+       Add new examples
+       * gst/Makefile.am:
+       * gst/cltrimagesink.c:
+       * gst/cltrimagesink.h:
+       Add initial crusty ( broken ) gst stuff
+
 2005-04-13  mallum,,,  <mallum@openedhand.com>
 
        * bootstrap-autotools.sh:
index fed7ad0..5a09d1b 100644 (file)
@@ -1 +1 @@
-SUBDIRS=clutter examples
\ No newline at end of file
+SUBDIRS=clutter gst examples
\ No newline at end of file
index 32ee920..3871a94 100644 (file)
@@ -8,6 +8,8 @@ source_h = pixbuf.h util.h fonts.h \
           cltr-window.h           \
           cltr-photo-grid.h       \
           cltr-list.h             \
+          cltr-overlay.h          \
+          cltr-button.h           \
           cltr-scratch.h
 
 source_c = pixbuf.c util.c fonts.c \
@@ -19,6 +21,8 @@ source_c = pixbuf.c util.c fonts.c \
            cltr-window.c           \
            cltr-photo-grid.c      \
            cltr-list.c                    \
+           cltr-overlay.c          \
+           cltr-button.c           \
            cltr-scratch.c
 
 AM_CFLAGS = @GCC_FLAGS@ @CLTR_CFLAGS@
diff --git a/clutter/cltr-button.c b/clutter/cltr-button.c
new file mode 100644 (file)
index 0000000..784b43b
--- /dev/null
@@ -0,0 +1,54 @@
+#include "cltr-button.h"
+#include "cltr-private.h"
+
+struct CltrButton
+{
+  CltrWidget  widget;  
+};
+
+static void
+cltr_button_show(CltrWidget *widget);
+
+static gboolean 
+cltr_button_handle_xevent (CltrWidget *widget, XEvent *xev);
+
+static void
+cltr_button_paint(CltrWidget *widget);
+
+
+CltrWidget*
+cltr_button_new(int width, int height)
+{
+  CltrButton *button;
+
+  button = g_malloc0(sizeof(CltrButton));
+  
+  button->widget.width          = width;
+  button->widget.height         = height;
+  
+  button->widget.show           = cltr_button_show;
+  button->widget.paint          = cltr_button_paint;
+  
+  button->widget.xevent_handler = cltr_button_handle_xevent;
+
+  return CLTR_WIDGET(button);
+}
+
+static void
+cltr_button_show(CltrWidget *widget)
+{
+
+}
+
+static gboolean 
+cltr_button_handle_xevent (CltrWidget *widget, XEvent *xev) 
+{
+
+}
+
+static void
+cltr_button_paint(CltrWidget *widget)
+{
+
+
+}
diff --git a/clutter/cltr-button.h b/clutter/cltr-button.h
new file mode 100644 (file)
index 0000000..8e4966f
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _HAVE_CLTR_BUTTON_H
+#define _HAVE_CLTR_BUTTON_H
+
+#include "cltr.h"
+
+typedef struct CltrButton CltrButton;
+
+#define CLTR_BUTTON(w) ((CltrButton*)(w))
+
+CltrWidget*
+cltr_button_new(int width, int height);
+
+
+#endif
index 034c9ac..cfcbcbd 100644 (file)
@@ -4,20 +4,38 @@
 int
 cltr_init(int *argc, char ***argv)
 {
+
+#define GLX_SAMPLE_BUFFERS_ARB             100000
+#define GLX_SAMPLES_ARB                    100001
+
+
   int  gl_attributes[] =
     {
       GLX_RGBA, 
       GLX_DOUBLEBUFFER,
+      GLX_STENCIL_SIZE, 1, 
+      GLX_DEPTH_SIZE, 24,
+
+      /*
+      GLX_SAMPLE_BUFFERS_ARB, 1, 
+      GLX_SAMPLES_ARB, 0,
+
+      */
+      /*
       GLX_RED_SIZE, 1,
       GLX_GREEN_SIZE, 1,
       GLX_BLUE_SIZE, 1,
+
+
+
+      */
       0
     };
 
   XVisualInfo         *vinfo;  
 
-
-  g_thread_init (NULL);
+  if (!g_thread_supported ())
+    g_thread_init (NULL);
   // XInitThreads ();
 
   if ((CltrCntx.xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
@@ -28,6 +46,10 @@ cltr_init(int *argc, char ***argv)
   CltrCntx.xscreen   = DefaultScreen(CltrCntx.xdpy);
   CltrCntx.xwin_root = RootWindow(CltrCntx.xdpy, CltrCntx.xscreen);
 
+  CLTR_DBG("EXT : %s", glXQueryExtensionsString( CltrCntx.xdpy, 
+                                             CltrCntx.xscreen));
+
+
   if ((vinfo = glXChooseVisual(CltrCntx.xdpy, 
                               CltrCntx.xscreen,
                               gl_attributes)) == NULL)
diff --git a/clutter/cltr-overlay.c b/clutter/cltr-overlay.c
new file mode 100644 (file)
index 0000000..077a7bd
--- /dev/null
@@ -0,0 +1,54 @@
+#include "cltr-overlay.h"
+#include "cltr-private.h"
+
+struct CltrOverlay
+{
+  CltrWidget  widget;  
+};
+
+static void
+cltr_overlay_show(CltrWidget *widget);
+
+static gboolean 
+cltr_overlay_handle_xevent (CltrWidget *widget, XEvent *xev);
+
+static void
+cltr_overlay_paint(CltrWidget *widget);
+
+
+CltrWidget*
+cltr_overlay_new(int width, int height)
+{
+  CltrOverlay *overlay;
+
+  overlay = g_malloc0(sizeof(CltrOverlay));
+  
+  overlay->widget.width          = width;
+  overlay->widget.height         = height;
+  
+  overlay->widget.show           = cltr_overlay_show;
+  overlay->widget.paint          = cltr_overlay_paint;
+  
+  overlay->widget.xevent_handler = cltr_overlay_handle_xevent;
+
+  return CLTR_WIDGET(overlay);
+}
+
+static void
+cltr_overlay_show(CltrWidget *widget)
+{
+
+}
+
+static gboolean 
+cltr_overlay_handle_xevent (CltrWidget *widget, XEvent *xev) 
+{
+
+}
+
+static void
+cltr_overlay_paint(CltrWidget *widget)
+{
+
+
+}
diff --git a/clutter/cltr-overlay.h b/clutter/cltr-overlay.h
new file mode 100644 (file)
index 0000000..2d6d1a3
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _HAVE_CLTR_OVERLAY_H
+#define _HAVE_CLTR_OVERLAY_H
+
+#include "cltr.h"
+
+typedef struct CltrOverlay CltrOverlay;
+
+#define CLTR_OVERLAY(w) ((CltrOverlay*)(w))
+
+CltrWidget*
+cltr_overlay_new(int width, int height);
+
+
+#endif
index 47650c3..0f25698 100644 (file)
@@ -22,7 +22,6 @@
 
  */
 
-#define ANIM_FPS 60 
 #define FPS_TO_TIMEOUT(t) (1000/(t))
 
 struct CltrPhotoGridCell
@@ -51,10 +50,12 @@ struct CltrPhotoGrid
   GList         *cells_tail;
   GList         *cell_active;
 
+  gboolean       is_populated;
+
   /* animation / zoom etc stuff  */
 
   /* current anim frame position */
-  int                 anim_n_steps, anim_step;
+  int                 anim_fps, anim_n_steps, anim_step;
 
   /* start / end points for animations */
   float               zoom_min, zoom_max, zoom_step;
@@ -64,9 +65,10 @@ struct CltrPhotoGrid
   /* Values calucated from above for setting up the GL tranforms and 'view' */
   float               paint_trans_x, paint_trans_y, paint_zoom; 
   int                 paint_start_y;
-  GList              *paint_cell_item;
 
+  GList              *paint_cell_item;
 
+  GMutex             *mutex;
 
   CltrPhotoGridState  state;
 };
@@ -84,9 +86,17 @@ static void
 cltr_photo_grid_update_visual_state(CltrPhotoGrid *grid);
 
 
-/* this likely shouldn'y go here */
-static GMutex *Mutex_GRID = NULL;
+GMutex*
+cltr_photo_grid_mutex(CltrPhotoGrid *grid)
+{
+  return grid->mutex;
+}
 
+void
+cltr_photo_grid_set_populated(CltrPhotoGrid *grid, gboolean populated)
+{
+  grid->is_populated = populated;
+}
 
 static void
 cltr_photo_grid_handle_xkeyevent(CltrPhotoGrid *grid, XKeyEvent *xkeyev)
@@ -140,12 +150,12 @@ cltr_photo_grid_handle_xevent (CltrWidget *widget, XEvent *xev)
 
 CltrPhotoGridCell*
 cltr_photo_grid_cell_new(CltrPhotoGrid *grid,
-                        Pixbuf        *pixb,
-                        const gchar   *filename)
+                        Pixbuf        *pixb)
 {
   CltrPhotoGridCell *cell = NULL;
   int                   maxw = grid->widget.width, maxh = grid->widget.height;
   int                   neww = 0, newh = 0;
+  Pixbuf               *tmp_pixb = NULL;
 
   cell = g_malloc0(sizeof(CltrPhotoGridCell));
 
@@ -173,7 +183,7 @@ cltr_photo_grid_cell_new(CltrPhotoGrid *grid,
     }
   else cell->pixb = pixb;
 
-  CLTR_DBG ("loaded %s at %ix%i", filename, neww, newh);
+  cell->texture = cltr_texture_new(cell->pixb);
 
   cell->angle = 6.0 - (rand()%12);
 
@@ -183,6 +193,44 @@ cltr_photo_grid_cell_new(CltrPhotoGrid *grid,
   return cell;
 }
 
+Pixbuf*
+cltr_photo_grid_cell_pixbuf(CltrPhotoGridCell *cell)
+{
+  return cell->pixb;
+}
+
+CltrPhotoGridCell*
+cltr_photo_grid_get_active_cell(CltrPhotoGrid     *grid)
+{
+  if (grid->cell_active)
+    return grid->cell_active->data;
+  else
+    return NULL;
+}
+
+void
+cltr_photo_grid_set_active_cell(CltrPhotoGrid *grid, CltrPhotoGridCell *cell)
+{
+  GList *cell_item = NULL;
+
+  cell_item = g_list_find(g_list_first(grid->cells_tail), (gconstpointer)cell);
+
+  if (cell_item)
+    grid->cell_active = cell_item;
+}
+
+CltrPhotoGridCell*
+cltr_photo_grid_get_first_cell(CltrPhotoGrid     *grid)
+{
+  GList *cell_item = NULL;
+
+  cell_item = g_list_first(grid->cells_tail);
+
+  if (cell_item)
+    return cell_item->data;
+  return NULL;
+}
+
 void
 cltr_photo_grid_append_cell(CltrPhotoGrid     *grid,
                            CltrPhotoGridCell *cell)
@@ -258,10 +306,11 @@ cltr_photo_grid_idle_cb(gpointer data)
 
   cltr_widget_queue_paint(CLTR_WIDGET(grid));
 
+  if (!grid->is_populated)
+    return TRUE;
+
   switch(grid->state)
     {
-    case CLTR_PHOTO_GRID_STATE_LOADING:
-    case CLTR_PHOTO_GRID_STATE_LOAD_COMPLETE:
     case CLTR_PHOTO_GRID_STATE_ZOOM_IN:
     case CLTR_PHOTO_GRID_STATE_ZOOM_OUT:
     case CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE:
@@ -330,7 +379,7 @@ cltr_photo_grid_navigate(CltrPhotoGrid *grid,
            }
          
          if (grid->state != CLTR_PHOTO_GRID_STATE_ZOOMED)            
-           g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS), 
+           g_timeout_add(FPS_TO_TIMEOUT(grid->anim_fps), 
                          cltr_photo_grid_idle_cb, grid);
        }
 
@@ -343,7 +392,7 @@ cltr_photo_grid_navigate(CltrPhotoGrid *grid,
          grid->anim_step  = 0;
          zoom             = grid->zoom_max;
 
-         g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS), 
+         g_timeout_add(FPS_TO_TIMEOUT(grid->anim_fps), 
                        cltr_photo_grid_idle_cb, grid);
        }
          
@@ -367,7 +416,7 @@ cltr_photo_grid_activate_cell(CltrPhotoGrid *grid)
       grid->state = CLTR_PHOTO_GRID_STATE_ZOOM_IN;
 
 
-      g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS), 
+      g_timeout_add(FPS_TO_TIMEOUT(grid->anim_fps), 
                    cltr_photo_grid_idle_cb, grid);
     }
   else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED)
@@ -378,11 +427,12 @@ cltr_photo_grid_activate_cell(CltrPhotoGrid *grid)
       grid->view_min_x = 0.0; 
       grid->view_min_y = 0.0; /*- (grid->row_offset * grid->cell_height);*/
 
-      g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS), 
+      g_timeout_add(FPS_TO_TIMEOUT(grid->anim_fps), 
                    cltr_photo_grid_idle_cb, grid);
     }
 }                            
 
+#if 0
 gpointer
 cltr_photo_grid_populate(gpointer data) 
 {
@@ -426,9 +476,10 @@ cltr_photo_grid_populate(gpointer data)
       if (pixb)
        {
          CltrPhotoGridCell *cell;
-         gchar                 buf[24];
+         gchar              buf[24];
+         Pixbuf            *tmp_pixb;
 
-         cell = cltr_photo_grid_cell_new(grid, pixb, entry);
+         cell = cltr_photo_grid_cell_new(grid, pixb);
 
          g_snprintf(&buf[0], 24, "%i", i);
          font_draw(font, cell->pixb, buf, 10, 10, &font_col);
@@ -437,10 +488,13 @@ cltr_photo_grid_populate(gpointer data)
 
          cell->texture = cltr_texture_new(cell->pixb);
 
-         g_mutex_unlock(Mutex_GRID);
+         if (!grid->cell_active)
+           grid->cell_active = g_list_first(grid->cells_tail);
 
          cltr_photo_grid_append_cell(grid, cell);
 
+         g_mutex_unlock(Mutex_GRID);
+
          i++;
        }
 
@@ -451,9 +505,7 @@ cltr_photo_grid_populate(gpointer data)
 
   g_mutex_lock(Mutex_GRID);
 
-  grid->cell_active = g_list_first(grid->cells_tail);
-
-  grid->state = CLTR_PHOTO_GRID_STATE_LOAD_COMPLETE;
+  grid->is_populated = TRUE;
 
   g_mutex_unlock(Mutex_GRID);
 
@@ -461,6 +513,7 @@ cltr_photo_grid_populate(gpointer data)
 
   return NULL;
 }
+#endif
 
 static void
 cltr_photo_grid_update_visual_state(CltrPhotoGrid *grid)
@@ -478,9 +531,7 @@ cltr_photo_grid_update_visual_state(CltrPhotoGrid *grid)
   grid->paint_cell_item = g_list_nth(grid->cells_tail, 
                                     grid->n_cols * grid->row_offset);
 
-  if (grid->state != CLTR_PHOTO_GRID_STATE_BROWSE
-      && grid->state != CLTR_PHOTO_GRID_STATE_LOADING
-      && grid->state != CLTR_PHOTO_GRID_STATE_LOAD_COMPLETE)
+  if (grid->state != CLTR_PHOTO_GRID_STATE_BROWSE)
     {
       float scroll_min_y_offset = (float)(row_offset_h);
 
@@ -710,7 +761,7 @@ cltr_photo_grid_paint(CltrWidget *widget)
 
          glEnable(GL_TEXTURE_2D);
 
-         g_mutex_lock(Mutex_GRID);
+         g_mutex_lock(grid->mutex);
 
          cltr_texture_render_to_gl_quad(cell->texture,
                                         -(thumb_w/2),
@@ -718,7 +769,7 @@ cltr_photo_grid_paint(CltrWidget *widget)
                                         (thumb_w/2),
                                         (thumb_h/2));
 
-         g_mutex_unlock(Mutex_GRID);
+         g_mutex_unlock(grid->mutex);
 
          glDisable(GL_TEXTURE_2D);
 
@@ -738,16 +789,19 @@ cltr_photo_grid_paint(CltrWidget *widget)
 
          cltr_glu_rounded_rect(-(thumb_w/2)-4, -(thumb_h/2)-4, 
                                (thumb_w/2)+4, (thumb_h/2)+ns_border,
-                               thumb_w/40,
+                               thumb_w/30,
                                NULL);
 
-         glColor4f(0.1, 0.1, 0.1, 0.5);
+         /* shadow */
+
+         glColor4f(0.1, 0.1, 0.1, 0.3);
 
-         cltr_glu_rounded_rect(-(thumb_w/2)-4, -(thumb_h/2)-4+1, 
-                               (thumb_w/2)+4, (thumb_h/2)+ns_border+1,
-                               thumb_w/40,
+         cltr_glu_rounded_rect(-(thumb_w/2)-4 + 1, -(thumb_h/2)-4 + 1, 
+                               (thumb_w/2)+4 + 1, (thumb_h/2)+ns_border +1,
+                               thumb_w/30,
                                NULL);
 
+
          glColor4f(1.0, 1.0, 1.0, 1.0);
 
          glEnable(GL_TEXTURE_2D);
@@ -776,14 +830,6 @@ cltr_photo_grid_paint(CltrWidget *widget)
   glColor3f(0.6, 0.6, 0.62);
   glRecti(0, 0, widget->width, widget->height);
 
-  g_mutex_lock(Mutex_GRID);
-
-  /* Hack, so final item get painted via threaded load */
-  if (grid->state == CLTR_PHOTO_GRID_STATE_LOAD_COMPLETE)
-    grid->state = CLTR_PHOTO_GRID_STATE_BROWSE;
-
-  g_mutex_unlock(Mutex_GRID);
-
   /* reset */
 
   glDisable(GL_POLYGON_SMOOTH);
@@ -795,21 +841,51 @@ static void
 cltr_photo_grid_show(CltrWidget *widget)
 {
   CltrPhotoGrid *grid = CLTR_PHOTO_GRID(widget);
-  GThread       *loader_thread; 
 
-  grid->state = CLTR_PHOTO_GRID_STATE_LOADING;
+  /*
+  GThread       *loader_thread; 
 
   loader_thread = g_thread_create (cltr_photo_grid_populate,
                                   (gpointer)grid,
                                   TRUE,
                                   NULL);
+  */
 
-  g_timeout_add(FPS_TO_TIMEOUT(20), 
-               cltr_photo_grid_idle_cb, grid);
+  grid->state = CLTR_PHOTO_GRID_STATE_BROWSE;
+
+  if (!grid->is_populated)
+    g_timeout_add(FPS_TO_TIMEOUT(20), 
+                 cltr_photo_grid_idle_cb, grid);
 
   cltr_widget_queue_paint(widget);
 }
 
+void
+cltr_photo_grid_set_fps(CltrPhotoGrid *grid, int fps)
+{
+  grid->anim_fps = fps;
+}
+
+int
+cltr_photo_grid_get_fps(CltrPhotoGrid *grid)
+{
+  return grid->anim_fps;
+}
+
+void
+cltr_photo_grid_set_anim_steps(CltrPhotoGrid *grid, int steps)
+{
+  grid->anim_n_steps = steps;
+}
+
+int
+cltr_photo_grid_get_anim_steps(CltrPhotoGrid *grid)
+{
+  return grid->anim_n_steps;
+}
+
+
+
 CltrWidget*
 cltr_photo_grid_new(int            width, 
                    int            height,
@@ -836,9 +912,12 @@ cltr_photo_grid_new(int            width,
   grid->cell_width  = grid->widget.width  / n_cols;
   grid->cell_height = grid->widget.height / n_rows;
 
-  grid->state = CLTR_PHOTO_GRID_STATE_LOADING;
+  grid->state        = CLTR_PHOTO_GRID_STATE_BROWSE;
+  grid->is_populated = FALSE;
+
+  grid->anim_fps     = 50;
 
-  grid->anim_n_steps = 20; /* value needs to be calced dep on rows */
+  grid->anim_n_steps = 10; /* value needs to be calced dep on rows */
   grid->anim_step    = 0;
 
   /* Default 'browse view' */
@@ -851,7 +930,7 @@ cltr_photo_grid_new(int            width,
 
   grid->row_offset = 0;
 
-  Mutex_GRID = g_mutex_new();
+  grid->mutex = g_mutex_new();
 
   return CLTR_WIDGET(grid);
 }
index 69c90de..e26498f 100644 (file)
@@ -11,8 +11,6 @@ typedef struct CltrPhotoGridCell CltrPhotoGridCell;
 
 typedef enum CltrPhotoGridState
 {
-  CLTR_PHOTO_GRID_STATE_LOADING       ,
-  CLTR_PHOTO_GRID_STATE_LOAD_COMPLETE ,
   CLTR_PHOTO_GRID_STATE_BROWSE        ,
   CLTR_PHOTO_GRID_STATE_ZOOM_IN       ,
   CLTR_PHOTO_GRID_STATE_ZOOMED        ,
@@ -29,11 +27,28 @@ typedef enum CltrPhotoGridCellState
 } 
 CltrPhotoGridCellState;
 
+GMutex*
+cltr_photo_grid_mutex(CltrPhotoGrid *grid);
+
+void
+cltr_photo_grid_set_populated(CltrPhotoGrid *grid, gboolean populated);
 
 CltrPhotoGridCell*
 cltr_photo_grid_cell_new(CltrPhotoGrid *grid,
-                        Pixbuf           *pixb,
-                        const gchar      *filename);
+                        Pixbuf           *pixb);
+
+Pixbuf*
+cltr_photo_grid_cell_pixbuf(CltrPhotoGridCell *cell);
+
+CltrPhotoGridCell*
+cltr_photo_grid_get_active_cell(CltrPhotoGrid *grid);
+
+void
+cltr_photo_grid_set_active_cell(CltrPhotoGrid *grid, CltrPhotoGridCell *cell);
+
+CltrPhotoGridCell*
+cltr_photo_grid_get_first_cell(CltrPhotoGrid *grid);
+
 
 void
 cltr_photo_grid_append_cell(CltrPhotoGrid     *grid,
index 6ff32cb..3b5525c 100644 (file)
@@ -259,7 +259,7 @@ cltr_texture_realize(CltrTexture *texture)
        Pixbuf *pixtmp;
        int src_h, src_w;
        
-       pixtmp = pixbuf_new(texture->tile_x_size[x], texture->tile_y_size[y]);
+
 
        src_w = texture->tile_x_size[x];
        src_h = texture->tile_y_size[y];
@@ -276,13 +276,21 @@ cltr_texture_realize(CltrTexture *texture)
                 texture->tile_y_waste[y]);
        */
 
-       pixbuf_copy(texture->pixb, 
-                   pixtmp,
-                   texture->tile_x_position[x],
-                   texture->tile_y_position[y],
-                   texture->tile_x_size[x], 
-                   texture->tile_y_size[y],
-                   0,0);
+       /* Only break the pixbuf up if we have multiple tiles */
+       if (texture->n_x_tiles > 1 && texture->n_y_tiles >1)
+         {
+           pixtmp = pixbuf_new(texture->tile_x_size[x], 
+                               texture->tile_y_size[y]);
+
+           pixbuf_copy(texture->pixb, 
+                       pixtmp,
+                       texture->tile_x_position[x],
+                       texture->tile_y_position[y],
+                       texture->tile_x_size[x], 
+                       texture->tile_y_size[y],
+                       0,0);
+         }
+       else pixtmp = texture->pixb;
 
        glBindTexture(GL_TEXTURE_2D, texture->tiles[i]);
 
@@ -303,7 +311,8 @@ cltr_texture_realize(CltrTexture *texture)
 
        CLTR_GLERR();
 
-       pixbuf_unref(pixtmp);
+       if (pixtmp != texture->pixb)
+         pixbuf_unref(pixtmp);
        
        i++;
 
@@ -332,3 +341,15 @@ cltr_texture_new(Pixbuf *pixb)
 
   return texture;
 }
+
+Pixbuf*
+cltr_texture_get_pixbuf(CltrTexture* texture)
+{
+  return texture->pixb;
+}
+
+void
+cltr_texture_resync_pixbuf(CltrTexture* texture)
+{
+  cltr_texture_unrealize(texture);
+}
index 8338228..8a8b084 100644 (file)
@@ -37,4 +37,11 @@ cltr_texture_render_to_gl_quad(CltrTexture *texture,
                               int          x2, 
                               int          y2);
 
+Pixbuf*
+cltr_texture_get_pixbuf(CltrTexture* texture);
+
+void
+cltr_texture_resync_pixbuf(CltrTexture* texture);
+
+
 #endif
index 097f2dd..a7c8418 100644 (file)
@@ -149,6 +149,11 @@ cltr_window_set_fullscreen(CltrWindow *win)
                  atom_WINDOW_STATE, XA_ATOM, 32,
                  PropModeReplace,
                  (unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1);
+
+  /* 
+    XF86VidModeSwitchToMode (GLWin.dpy, GLWin.screen, &GLWin.deskMode);
+    XF86VidModeSetViewPort (GLWin.dpy, GLWin.screen, 0, 0);
+  */
 }
 
 
index 28cb84b..601fd04 100644 (file)
@@ -49,7 +49,8 @@ CltrRect;
 #include "cltr-events.h"
 #include "cltr-widget.h"
 #include "cltr-window.h"
-
+#include "cltr-overlay.h"
+#include "cltr-button.h"
 #include "cltr-photo-grid.h"
 
 #endif
index c5b8253..e825e77 100644 (file)
@@ -19,6 +19,8 @@
 #include "pixbuf.h"
 #include "util.h"
 
+#define CLTR_CLAMP(x, y)  ((x) > (y)) ? (y) : (x);
+
 static int*
 load_png_file( const char *file, 
               int        *width, 
@@ -672,6 +674,100 @@ pixbuf_scale_down(Pixbuf *pixb,
   return pixb_scaled;
 }
 
+Pixbuf*
+pixbuf_clone(Pixbuf *pixb)
+{
+  Pixbuf *clone;
+
+  clone = util_malloc0(sizeof(Pixbuf));
+
+  clone->width           = pixb->width;
+  clone->height          = pixb->height;
+  clone->bytes_per_pixel = pixb->bytes_per_pixel; 
+  clone->channels       = pixb->channels;
+  clone->bytes_per_line  = pixb->bytes_per_line;
+  clone->data            = malloc(pixb->bytes_per_line * pixb->height);
+
+  memcpy(clone->data, pixb->data, pixb->bytes_per_line * pixb->height);
+  
+  return clone;
+}
+
+Pixbuf*
+pixbuf_convolve(Pixbuf *pixb, 
+               int    *kernel, 
+               int     kernel_size, 
+               int     kernel_divisor) 
+{
+  int         padding, x, y, r, g, b, a, l, k;
+  PixbufPixel pixel;
+  Pixbuf     *clone_pixb;
+    
+  padding = ( kernel_size - 1 ) / 2; 
+  clone_pixb = pixbuf_clone(pixb);
+
+  for( y = padding; y < pixb->height - padding; y++ ) 
+    {
+      for( x = padding; x < pixb->width - padding; x++ ) 
+       {
+         r = b = g = a = 0;
+
+         for( l = 0; l < kernel_size; l++ ) 
+           {
+             for( k = 0; k < kernel_size; k++ ) 
+               {
+                 pixbuf_get_pixel(pixb, (x+k-padding), (y+l-padding), &pixel);
+                 
+                 r += pixel.r * kernel[k + l * kernel_size];
+                 g += pixel.g * kernel[k + l * kernel_size];
+                 b += pixel.b * kernel[k + l * kernel_size];
+                 a += pixel.a * kernel[k + l * kernel_size];
+               }
+           }
+
+         r = CLTR_CLAMP( r / kernel_divisor, 0xff);
+         g = CLTR_CLAMP( g / kernel_divisor, 0xff);
+         b = CLTR_CLAMP( b / kernel_divisor, 0xff);
+         a = CLTR_CLAMP( a / kernel_divisor, 0xff); 
+         
+         pixel_set_vals(&pixel, r, g, b, a); 
+         
+         pixbuf_set_pixel(clone_pixb, x, y, &pixel);
+         
+       }
+    }
+  
+  return clone_pixb;
+}
+
+Pixbuf*
+pixbuf_blur(Pixbuf *pixb)
+{ 
+  /*
+  int kernel[] = { 1, 1, 1,
+                  1, 0, 1, 
+                  1, 1, 1 };
+  */
+
+  int kernel[] = { 1, 1, 1,
+                  1, 1, 1,
+                  1, 1, 1 };
+
+
+  return pixbuf_convolve( pixb, kernel, 3, 9 );
+}
+
+Pixbuf*
+pixbuf_sharpen(Pixbuf *pixb)
+{ 
+  int kernel[] = {-1, -1, -1,
+                 -1, 9, -1, 
+                 -1, -1, -1 };
+
+  return pixbuf_convolve( pixb, kernel, 3, 1 );
+}
+
+
 #if 0
 
 /*
@@ -927,4 +1023,89 @@ MagickExport Image *GaussianBlurImage(Image *image,const double radius,
   return(blur_image);
 }
 
+/* GPE-gallery convolve code */
+
+static void 
+image_convolve( GdkPixbuf *pixbuf, 
+               int       *mask, 
+               int        mask_size, 
+               int        mask_divisor ) {
+
+  int x, y, k, l, b, rowstride, width, height, channels, padding, new_value;
+  int* temp_pixel;
+  guchar *temp_image, *image;
+
+  rowstride = gdk_pixbuf_get_rowstride( GDK_PIXBUF( pixbuf ) );
+  channels = gdk_pixbuf_get_n_channels( GDK_PIXBUF( pixbuf ) );
+
+  width = gdk_pixbuf_get_width( GDK_PIXBUF( pixbuf ) );
+  height = gdk_pixbuf_get_height( GDK_PIXBUF( pixbuf ) );
+
+  //    fprintf( stderr, "Rowstride: %d, width: %d, height: %d, channels: %d\n", rowstride, width, height, channels );
+
+    
+  padding = ( mask_size - 1 ) / 2; 
+
+  image = gdk_pixbuf_get_pixels( GDK_PIXBUF( pixbuf ) );
+  temp_image = (guchar*) malloc( width * height * channels * sizeof( guchar ) );
+  memcpy( temp_image, image, width * height * channels * sizeof( guchar ) ); 
+  temp_pixel =(int*)  malloc( channels * sizeof( int ) );
+  for( y = padding; y < height - padding; y++ ) {
+
+    for( x = padding; x < width - padding; x++ ) {
+        
+      for( b = 0; b < channels; b++ ) 
+       temp_pixel[b] = 0;
+
+      for( l = 0; l < mask_size; l++ ) {
+
+       for( k = 0; k < mask_size; k++ ) {
+
+         for( b = 0; b < channels; b++ ) 
+           temp_pixel[b] += temp_image[ ( y + l - padding ) * rowstride
+                                        + ( x + k - padding ) * channels + b ] * mask[ k + l *
+                                                                                       mask_size ];
+
+       }
+
+       }
+
+      for( b = 0; b < channels; b++ ) {
+
+       new_value = temp_pixel[b] / mask_divisor; 
+       image[ y * rowstride + x * channels +  b ] = ( new_value > 255 ? 255
+                                                      : new_value < 0 ? 0 : new_value ); 
+
+      }
+
+    }
+
+  }
+
+
+  free( temp_image );
+  free( temp_pixel );
+
+}
+
+void image_tools_blur( GdkPixbuf* pixbuf ) {
+
+  int mask[] = { 1, 1, 1,
+                1, 1, 1, 
+                1, 1, 1 };
+
+  image_convolve( pixbuf, mask, 3, 9 );
+
+}
+
+void image_tools_sharpen( GdkPixbuf* pixbuf ) {
+
+  int mask[] = {-1, -1, -1,
+               -1, 9, -1, 
+               -1, -1, -1 };
+
+  image_convolve( pixbuf, mask, 3, 1 );
+
+}
+
 #endif
index 85069ed..155d0b9 100644 (file)
@@ -86,4 +86,20 @@ pixbuf_scale_down(Pixbuf *pixb,
                  int     new_width, 
                  int     new_height);
 
+Pixbuf*
+pixbuf_clone(Pixbuf *pixb);
+
+Pixbuf*
+pixbuf_convolve(Pixbuf *pixb, 
+               int    *kernel, 
+               int     kernel_size, 
+               int     kernel_divisor) ;
+
+Pixbuf*
+pixbuf_blur(Pixbuf *pixb);
+
+Pixbuf*
+pixbuf_sharpen(Pixbuf *pixb);
+
+
 #endif
index 756e827..e1e6742 100644 (file)
@@ -66,9 +66,13 @@ PKG_CHECK_MODULES(CLTR, pangoft2 pango glib-2.0 gthread-2.0)
 
 dnl ----- Gstreamer ---------------------------------------------------------
 
-pkg_modules="gstreamer-0.8 gstreamer-interfaces-0.8 gthread-2.0"
+pkg_modules="gstreamer-0.8 gstreamer-interfaces-0.8 gthread-2.0 gstreamer-play-0.8 gstreamer-gconf-0.8"
 PKG_CHECK_MODULES(GST, [$pkg_modules])
 
+dnl ----- Gconf -------------------------------------------------------------
+
+PKG_CHECK_MODULES(GCONF, gconf-2.0, HAVE_GCONF="yes", HAVE_GCONF="no")
+
 dnl ------ Check for PNG ---------------------------------------------------
 
 AC_MSG_CHECKING(for libpng12)
@@ -110,14 +114,17 @@ AC_SUBST(GCC_FLAGS)
 AC_SUBST(GST_CFLAGS)
 AC_SUBST(GST_LIBS)
 
+AC_SUBST(GCONF_CFLAGS)
+AC_SUBST(GCONF_LIBS)
+
 CLTR_CFLAGS="$GLX_CLAGS $CLTR_CFLAGS"
 CLTR_LIBS="$GLX_LIBS $PNG_LIBS $JPEG_LIBS $CLTR_LIBS"
 
 AC_SUBST(CLTR_CFLAGS)
 AC_SUBST(CLTR_LIBS)
 
-
 AC_OUTPUT([Makefile
 clutter/Makefile
 examples/Makefile
+gst/Makefile
 ])
index 1f22909..1002718 100644 (file)
@@ -1,7 +1,23 @@
-noinst_PROGRAMS = scratch
+noinst_PROGRAMS = scratch photos player
 
 scratch_SOURCES = scratch.c
 scratch_CFLAGS = $(CLTR_CFLAGS)
 scratch_LDFLAGS = \
     $(CLTR_LIBS) \
     $(top_builddir)/clutter/libclutter.la 
+
+photos_SOURCES = photos.c
+photos_CFLAGS = $(CLTR_CFLAGS)
+photos_LDFLAGS = \
+    $(CLTR_LIBS) \
+    $(top_builddir)/clutter/libclutter.la 
+
+player_SOURCES = player.c
+player_CFLAGS = $(CLTR_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
+player_LDFLAGS =    \
+    $(CLTR_LIBS)    \
+    $(GST_LIBS)   \
+    $(GCONF_LIBS) \
+    $(top_builddir)/clutter/libclutter.la 
+
+
diff --git a/examples/photos.c b/examples/photos.c
new file mode 100644 (file)
index 0000000..d8615dc
--- /dev/null
@@ -0,0 +1,157 @@
+#include <clutter/cltr.h>
+
+gchar *ImgPath = NULL;
+
+int 
+usage(char *progname)
+{
+  fprintf(stderr, "Usage ... check source for now\n");
+  exit(-1);
+}
+
+gpointer
+photo_grid_populate(gpointer data) 
+{
+  CltrPhotoGrid    *grid = (CltrPhotoGrid *)data;
+  GDir             *dir;
+  GError           *error;
+  const gchar      *entry = NULL;
+  gchar            *fullpath = NULL;
+  int               n_pixb = 0, i =0;
+  ClutterFont      *font = NULL;
+  PixbufPixel       font_col = { 255, 255, 255, 255 };
+
+  font = font_new("Sans Bold 96");
+
+  if ((dir = g_dir_open (ImgPath, 0, &error)) == NULL)
+    {
+      /* handle this much better */
+      fprintf(stderr, "failed to open '%s'\n", ImgPath);
+      return NULL;
+    }
+
+  while ((entry = g_dir_read_name (dir)) != NULL)
+    {
+      if (!strcasecmp(&entry[strlen(entry)-4], ".png")
+         || !strcasecmp(&entry[strlen(entry)-4], ".jpg")
+         || !strcasecmp(&entry[strlen(entry)-5], ".jpeg"))
+       n_pixb++;
+    }
+
+  g_dir_rewind (dir);
+
+  while ((entry = g_dir_read_name (dir)) != NULL)
+    {
+      Pixbuf *pixb = NULL; 
+      fullpath = g_strconcat(ImgPath, "/", entry, NULL);
+      pixb = pixbuf_new_from_file(fullpath);
+
+      if (pixb)
+       {
+         CltrPhotoGridCell *cell;
+         gchar              buf[24];
+         Pixbuf            *tmp_pixb;
+
+         cell = cltr_photo_grid_cell_new(grid, pixb);
+
+         g_snprintf(&buf[0], 24, "%i", i);
+         font_draw(font, cltr_photo_grid_cell_pixbuf(cell), 
+                   buf, 10, 10, &font_col);
+
+         g_mutex_lock(cltr_photo_grid_mutex(grid));
+
+         if (!cltr_photo_grid_get_active_cell(grid))
+           cltr_photo_grid_set_active_cell(grid,
+                                           cltr_photo_grid_get_first_cell(grid));
+
+         cltr_photo_grid_append_cell(grid, cell);
+
+         g_mutex_unlock(cltr_photo_grid_mutex(grid));
+
+         i++;
+       }
+
+      g_free(fullpath);
+    }
+
+  g_dir_close (dir);
+
+  g_mutex_lock(cltr_photo_grid_mutex(grid));
+
+  cltr_photo_grid_set_populated(grid, TRUE);
+
+  g_mutex_unlock(cltr_photo_grid_mutex(grid));
+
+  cltr_widget_queue_paint(CLTR_WIDGET(grid));
+
+  return NULL;
+}
+
+int
+main(int argc, char **argv)
+{
+  CltrWidget *win = NULL, *grid = NULL;
+  gchar      *img_path = NULL;
+  gboolean    want_fullscreen = FALSE;
+  gint        i, cols = 3;
+
+  GThread    *loader_thread; 
+
+  cltr_init(&argc, &argv);
+
+  if (argc < 2)
+    usage(argv[0]);
+
+  for (i = 1; i < argc; i++) 
+    {
+      if (!strcmp ("--image-path", argv[i]) || !strcmp ("-i", argv[i])) 
+       {
+         if (++i>=argc) usage (argv[0]);
+         ImgPath = argv[i];
+         continue;
+       }
+      if (!strcmp ("--cols", argv[i]) || !strcmp ("-c", argv[i])) 
+       {
+         if (++i>=argc) usage (argv[0]);
+         cols = atoi(argv[i]);
+         continue;
+       }
+      if (!strcmp ("-fs", argv[i]) || !strcmp ("--fullscreen", argv[i])) 
+       {
+         want_fullscreen = TRUE;
+         continue;
+       }
+      if (!strcmp("--help", argv[i]) || !strcmp("-h", argv[i])) 
+       {
+         usage(argv[0]);
+       }
+
+      usage(argv[0]);
+    }
+
+  win = cltr_window_new(800, 600);
+
+  if (want_fullscreen)
+    cltr_window_set_fullscreen(CLTR_WINDOW(win));
+
+  grid = cltr_photo_grid_new(800, 600, cols, cols, ImgPath);
+
+  cltr_window_focus_widget(CLTR_WINDOW(win), grid);
+
+  cltr_widget_add_child(win, grid, 0, 0);
+
+  cltr_widget_show_all(win);
+
+  /* grid->state = CLTR_PHOTO_GRID_STATE_BROWSE; */
+
+  loader_thread = g_thread_create (photo_grid_populate,
+                                  (gpointer)grid,
+                                  TRUE,
+                                  NULL);
+
+
+  cltr_main_loop();
+
+  return 0;
+}
diff --git a/examples/player.c b/examples/player.c
new file mode 100644 (file)
index 0000000..9cdd967
--- /dev/null
@@ -0,0 +1,196 @@
+/* GStreamer
+ * Copyright (C) 2003 Julien Moutte <julien@moutte.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <clutter/cltr.h>
+
+#include <gst/play/play.h>
+#include <gst/gconf/gconf.h>
+
+static GMainLoop *loop = NULL;
+static gint64 length = 0;
+
+static void
+print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
+{
+  gint i, count;
+
+  count = gst_tag_list_get_tag_size (list, tag);
+
+  for (i = 0; i < count; i++) {
+    gchar *str;
+
+    if (gst_tag_get_type (tag) == G_TYPE_STRING) {
+      if (!gst_tag_list_get_string_index (list, tag, i, &str))
+        g_assert_not_reached ();
+    } else {
+      str =
+          g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
+    }
+
+    if (i == 0) {
+      g_print ("%15s: %s\n", gst_tag_get_nick (tag), str);
+    } else {
+      g_print ("               : %s\n", str);
+    }
+
+    g_free (str);
+  }
+}
+
+static void
+got_found_tag (GstPlay * play, GstElement * source, GstTagList * tag_list)
+{
+  gst_tag_list_foreach (tag_list, print_tag, NULL);
+}
+
+static void
+got_time_tick (GstPlay * play, gint64 time_nanos)
+{
+  g_print ("time tick %f\n", time_nanos / (float) GST_SECOND);
+}
+
+static void
+got_stream_length (GstPlay * play, gint64 length_nanos)
+{
+  g_print ("got length %" G_GUINT64_FORMAT "\n", length_nanos);
+  length = length_nanos;
+}
+
+static void
+got_video_size (GstPlay * play, gint width, gint height)
+{
+  g_print ("got video size %d, %d\n", width, height);
+}
+
+static void
+got_eos (GstPlay * play)
+{
+  g_print ("End Of Stream\n");
+  g_main_loop_quit (loop);
+}
+
+static gboolean
+seek_timer (GstPlay * play)
+{
+  gst_play_seek_to_time (play, length / 2);
+  return FALSE;
+}
+
+int
+main (int argc, char *argv[])
+{
+  GstPlay *play;
+  GstElement *data_src, *video_sink, *audio_sink, *vis_element;
+  GError *error = NULL;
+
+  CltrWidget *win;
+
+  /* Initing GStreamer library */
+  gst_init (&argc, &argv);
+  cltr_init (&argc, &argv);
+
+  if (argc != 2) {
+    g_print ("usage: %s <video filename>\n", argv[0]);
+    exit (-1);
+  }
+
+  win = cltr_window_new(800, 600);
+  cltr_widget_show_all(win);
+
+  loop = g_main_loop_new (NULL, FALSE);
+
+  /* Creating the GstPlay object */
+  play = gst_play_new (&error);
+  if (error) {
+    g_print ("Error: could not create play object:\n%s\n", error->message);
+    g_error_free (error);
+    return 1;
+  }
+
+  /* Getting default audio and video plugins from GConf */
+  vis_element = gst_element_factory_make ("goom", "vis_element");
+  data_src = gst_element_factory_make ("gnomevfssrc", "source");
+
+  audio_sink = gst_gconf_get_default_audio_sink ();
+  if (!GST_IS_ELEMENT (audio_sink))
+    g_error ("Could not get default audio sink from GConf");
+
+  /*
+  video_sink = gst_gconf_get_default_video_sink ();
+  if (!GST_IS_ELEMENT (video_sink))
+    g_error ("Could not get default video sink from GConf");
+  */
+
+  video_sink = gst_element_factory_make ("cltrimagesink", "cltr-output");
+
+  gst_element_set(video_sink, "widget", win, NULL);
+
+  if (video_sink == NULL)
+    g_printf("sink NULL\n");
+
+  /* Let's send them to GstPlay object */
+  if (!gst_play_set_audio_sink (play, audio_sink))
+    g_warning ("Could not set audio sink");
+  if (!gst_play_set_video_sink (play, video_sink))
+    g_warning ("Could not set video sink");
+  if (!gst_play_set_data_src (play, data_src))
+    g_warning ("Could not set data src");
+  if (!gst_play_set_visualization (play, vis_element))
+    g_warning ("Could not set visualisation");
+
+  /* Setting location we want to play */
+  if (!gst_play_set_location (play, argv[1]))
+    g_warning ("Could not set location");
+
+  /* Uncomment that line to get an XML dump of the pipeline */
+  gst_xml_write_file (GST_ELEMENT (play), stdout); 
+
+  g_signal_connect (G_OBJECT (play), "time_tick",
+      G_CALLBACK (got_time_tick), NULL);
+  g_signal_connect (G_OBJECT (play), "stream_length",
+      G_CALLBACK (got_stream_length), NULL);
+  g_signal_connect (G_OBJECT (play), "have_video_size",
+      G_CALLBACK (got_video_size), NULL);
+  g_signal_connect (G_OBJECT (play), "found_tag",
+      G_CALLBACK (got_found_tag), NULL);
+  g_signal_connect (G_OBJECT (play), "error",
+      G_CALLBACK (gst_element_default_error), NULL);
+  g_signal_connect (G_OBJECT (play), "eos", G_CALLBACK (got_eos), NULL);
+
+  /* Change state to PLAYING */
+  if (gst_element_set_state (GST_ELEMENT (play),
+          GST_STATE_PLAYING) == GST_STATE_FAILURE)
+    g_error ("Could not set state to PLAYING");
+
+  g_timeout_add (20000, (GSourceFunc) seek_timer, play);
+
+
+
+  cltr_main_loop();
+  // g_main_loop_run (loop);
+
+  g_print ("setting pipeline to ready\n");
+
+  gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
+
+  /* unref 
+     gst_object_unref (GST_OBJECT (play)); */
+
+  exit (0);
+}
diff --git a/gst/Makefile.am b/gst/Makefile.am
new file mode 100644 (file)
index 0000000..f8cea26
--- /dev/null
@@ -0,0 +1,20 @@
+# see http://cvs.sourceforge.net/viewcvs.py/wechselspieler/wechselspieler/plugins/Makefile.am?rev=1.6&view=auto
+
+lib_LTLIBRARIES = libcltrimagesink.la
+
+# HACK HACK HACK HACK for now
+libdir= /usr/lib/gstreamer-0.8/
+
+INCLUDES=@GST_CFLAGS@ $(CLTR_CFLAGS)
+
+LIBS=@GST_LIBS@
+
+
+libcltrimagesink_la_SOURCES = cltrimagesink.c 
+libcltrimagesink_la_INCLUDES = $(CLTR_CFLAGS)
+libcltrimagesink_LIBDIR = ${libdir}/gst
+libcltrimagesink_la_LIBADD = @CLTR_LIBS@
+libcltrimagesink_la_LDFLAGS = -module -avoid-version
+
+noinst_HEADERS = \
+    cltrimagesink.h
\ No newline at end of file
diff --git a/gst/cltrimagesink.c b/gst/cltrimagesink.c
new file mode 100644 (file)
index 0000000..9d93d5e
--- /dev/null
@@ -0,0 +1,669 @@
+/* GStreamer
+ * Copyright (C) <2003> Julien Moutte <julien@moutte.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define DBG(x, a...) \
+ g_printerr ( __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a)
+
+/* Object header */
+#include "cltrimagesink.h"
+
+/* Debugging category */
+#include <gst/gstinfo.h>
+
+GST_DEBUG_CATEGORY_STATIC (gst_debug_cltrimagesink);
+
+#define GST_CAT_DEFAULT gst_debug_cltrimagesink
+
+/* ElementFactory information */
+static GstElementDetails gst_cltrimagesink_details =
+GST_ELEMENT_DETAILS ("Video sink",
+                    "Sink/Video",
+                    "An Clutter based videosink",
+                    "Matthew Allum <mallum@o-hand.com>");
+
+/* Default template - initiated with class struct to allow gst-register to work
+   without X running */
+static GstStaticPadTemplate gst_cltrimagesink_sink_template_factory =
+GST_STATIC_PAD_TEMPLATE ("sink",
+                        GST_PAD_SINK,
+                        GST_PAD_ALWAYS,
+                        GST_STATIC_CAPS ("video/x-raw-rgb, "
+                                         "framerate = (double) [ 1.0, 100.0 ], "
+                                         "width = (int) [ 1, MAX ], "
+                                         "height = (int) [ 1, MAX ]; "
+                                         "video/x-raw-yuv, "
+                                         "framerate = (double) [ 1.0, 100.0 ], "
+                                         "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ]")
+                        );
+
+/* CltrimageSink signals and args */
+enum
+{
+    SIGNAL_HANDOFF,
+    SIGNAL_BUFALLOC,
+    LAST_SIGNAL
+    /* FILL ME */
+ };
+
+static guint gst_cltrimagesink_signals[LAST_SIGNAL] = { 0 };
+
+enum
+{
+  ARG_0,
+  ARG_WIDGET,
+  ARG_SYNCHRONOUS,
+  ARG_SIGNAL_HANDOFFS
+      /* FILL ME */
+};
+
+static GstVideoSinkClass *parent_class = NULL;
+
+#define GLERR()                                           \
+ {                                                             \
+  GLenum err = glGetError ();  /* Roundtrip */                \
+  if (err != GL_NO_ERROR)                                      \
+    {                                                          \
+      g_printerr (__FILE__ ": GL Error: %x [at %s:%d]\n",      \
+                 err, __func__, __LINE__);                    \
+    }                                                          \
+ }
+
+
+/* ============================================================= */
+/*                                                               */
+/*                       Private Methods                         */
+/*                                                               */
+/* ============================================================= */
+
+
+
+/* 
+=================
+Element stuff 
+=================
+*/
+
+static GstCaps *
+gst_cltrimagesink_fixate (GstPad        *pad, 
+                         const GstCaps *caps)
+{
+  GstStructure *structure;
+  GstCaps *newcaps;
+
+  DBG("mark");
+
+  if (gst_caps_get_size (caps) > 1)
+    return NULL;
+
+  newcaps = gst_caps_copy (caps);
+  structure = gst_caps_get_structure (newcaps, 0);
+
+  if (gst_caps_structure_fixate_field_nearest_int (structure, "width", 320)) 
+    {
+      return newcaps;
+    }
+
+  if (gst_caps_structure_fixate_field_nearest_int (structure, "height", 240)) 
+    {
+      return newcaps;
+    }
+
+  if (gst_caps_structure_fixate_field_nearest_double (structure, 
+                                                     "framerate",
+                                                     30.0)) 
+    {
+      return newcaps;
+    }
+
+  gst_caps_free (newcaps);
+  return NULL;
+}
+
+static GstCaps *
+gst_cltrimagesink_getcaps (GstPad * pad)
+{
+  GstCltrimageSink *cltrimagesink;
+
+  cltrimagesink = GST_CLTRIMAGESINK (gst_pad_get_parent (pad));
+
+  if (!cltrimagesink->caps)
+    cltrimagesink->caps 
+      = gst_caps_new_simple (
+                            "video/x-raw-rgb",
+                            "bpp",        G_TYPE_INT, 24,
+                            "depth",      G_TYPE_INT, 24,
+                            "endianness", G_TYPE_INT, G_BIG_ENDIAN,
+                            "red_mask",   G_TYPE_INT,   0xff0000,
+                            "green_mask", G_TYPE_INT, 0x00ff00,
+                            "blue_mask",  G_TYPE_INT,  0xff,
+                            "width",      GST_TYPE_INT_RANGE, 1, G_MAXINT,
+                            "height",     GST_TYPE_INT_RANGE, 1, G_MAXINT,
+                            "framerate",  GST_TYPE_DOUBLE_RANGE, 1.0, 100.0, NULL);
+
+  return gst_caps_copy (cltrimagesink->caps);
+
+}
+
+static GstPadLinkReturn
+gst_cltrimagesink_sink_link (GstPad * pad, const GstCaps * caps)
+{
+  GstCltrimageSink *cltrimagesink;
+  gboolean ret;
+  GstStructure *structure;
+  Pixbuf *pixb = NULL;
+
+  DBG("mark");
+
+  cltrimagesink = GST_CLTRIMAGESINK (gst_pad_get_parent (pad));
+
+  /*
+  if (!cltrimagesink->texture)
+    return GST_PAD_LINK_DELAYED;
+  */
+
+  structure = gst_caps_get_structure (caps, 0);
+
+  ret = gst_structure_get_int (structure, "width",
+                              &(GST_VIDEOSINK_WIDTH (cltrimagesink)));
+
+  ret &= gst_structure_get_int (structure, "height",
+                               &(GST_VIDEOSINK_HEIGHT (cltrimagesink)));
+
+  ret &= gst_structure_get_double (structure,
+                                  "framerate", &cltrimagesink->framerate);
+  if (!ret)
+    {
+      DBG("!ret returning GST_PAD_LINK_REFUSED");
+      return GST_PAD_LINK_REFUSED;
+    }
+
+  cltrimagesink->pixel_width = 1;
+
+  gst_structure_get_int (structure, "pixel_width", 
+                        &cltrimagesink->pixel_width);
+
+  cltrimagesink->pixel_height = 1;
+
+  gst_structure_get_int (structure, "pixel_height", 
+                        &cltrimagesink->pixel_height);
+
+  DBG("returning GST_PAD_LINK_OK, with %ix%i or %ix%i", 
+      cltrimagesink->pixel_width,
+      cltrimagesink->pixel_height,
+      GST_VIDEOSINK_WIDTH (cltrimagesink),
+      GST_VIDEOSINK_HEIGHT (cltrimagesink));
+
+  pixb = pixbuf_new(GST_VIDEOSINK_WIDTH (cltrimagesink), 
+                   GST_VIDEOSINK_HEIGHT (cltrimagesink));
+
+  DBG("pixbuf new at %ix%i", GST_VIDEOSINK_WIDTH (cltrimagesink), 
+      GST_VIDEOSINK_HEIGHT (cltrimagesink));
+
+  /* Is this the right place ? */
+  cltrimagesink->texture = cltr_texture_new(pixb);
+
+  pixbuf_unref(pixb);
+
+  return GST_PAD_LINK_OK;
+}
+
+static GstElementStateReturn
+gst_cltrimagesink_change_state (GstElement * element)
+{
+  GstCltrimageSink *cltrimagesink;
+
+  DBG("mark");
+
+  cltrimagesink = GST_CLTRIMAGESINK (element);
+
+  switch (GST_STATE_TRANSITION (element)) 
+    {
+    case GST_STATE_NULL_TO_READY:
+      /* Initializing the Context */
+      /*
+      if (!cltrimagesink->texture) 
+       {
+         DBG("setting state to failure");
+         return GST_STATE_FAILURE;
+       }
+      */
+      break;
+    case GST_STATE_READY_TO_PAUSED:
+      printf ("ready to paused\n");
+      cltrimagesink->time = 0;
+      break;
+    case GST_STATE_PAUSED_TO_PLAYING:
+      break;
+    case GST_STATE_PLAYING_TO_PAUSED:
+      break;
+    case GST_STATE_PAUSED_TO_READY:
+      cltrimagesink->framerate = 0;
+      GST_VIDEOSINK_WIDTH (cltrimagesink) = 0;
+      GST_VIDEOSINK_HEIGHT (cltrimagesink) = 0;
+      break;
+    case GST_STATE_READY_TO_NULL:
+      if (cltrimagesink->texture)
+       cltr_texture_unref(cltrimagesink->texture);
+
+      break;
+    }
+
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  return GST_STATE_SUCCESS;
+}
+
+static void
+gst_cltrimagesink_chain (GstPad * pad, GstData * data)
+{
+  GstBuffer *buf = GST_BUFFER (data);
+  GstCltrimageSink *cltrimagesink;
+
+  g_return_if_fail (GST_IS_PAD (pad));
+  g_return_if_fail (buf != NULL);
+
+  DBG("mark");
+
+  cltrimagesink = GST_CLTRIMAGESINK (gst_pad_get_parent (pad));
+ if (GST_IS_EVENT (data)) 
+   {
+     gst_pad_event_default (pad, GST_EVENT (data));
+     DBG("GST_IS_EVENT, returning");
+     return;
+   }
+
+ buf = GST_BUFFER (data);
+ /* update time */
+ if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) 
+   cltrimagesink->time = GST_BUFFER_TIMESTAMP (buf);
+
+ /* If this buffer has been allocated using our buffer management we 
+  * simply put the ximage which is in the PRIVATE pointer */
+
+ DBG("time is is %li", cltrimagesink->time);
+
+#if 0
+ if (GST_BUFFER_FREE_DATA_FUNC (buf) == gst_cltrimagesink_buffer_free)
+   {
+       /*
+         gst_cltrimagesink_ximage_put (cltrimagesink, GST_BUFFER_PRIVATE (buf));
+       */
+   }
+ else
+#endif 
+   {   /* Else we have to copy the data into our private image, */
+     /* if we have one... */
+
+
+     if (cltrimagesink->texture) 
+       {
+        /* need to copy the data into out pixbuf here */
+        Pixbuf *pixb = NULL;
+
+        pixb = cltr_texture_get_pixbuf(cltrimagesink->texture);
+
+        if (pixb)
+          memcpy (pixb->data,
+                  GST_BUFFER_DATA (buf),
+                  MIN (GST_BUFFER_SIZE (buf), 
+                       pixb->bytes_per_line * pixb->width));
+
+        cltr_texture_resync_pixbuf(cltrimagesink->texture);
+
+        /*
+        cltr_texture_render_to_gl_quad(cltrimagesink->texture, 
+                                       0, 0, 320, 240); 
+        */
+        
+
+#if 0
+        memcpy (cltrimagesink->cltrimage->data,
+                GST_BUFFER_DATA (buf),
+                MIN (GST_BUFFER_SIZE (buf), 
+                     cltrimagesink->cltrimage->size));
+        
+        gst_cltrimagesink_ximage_put (cltrimagesink, 
+                                      cltrimagesink->cltrimage);
+#endif
+       } 
+     else 
+       {                  
+           /* No image available. Something went wrong during capsnego ! */
+
+        DBG("MARK, texture == NULL");
+
+        gst_buffer_unref (buf);
+        GST_ELEMENT_ERROR (cltrimagesink, CORE, NEGOTIATION, (NULL),
+                           ("no format defined before chain function"));
+        return;
+       }
+   }
+  
+  /* swap buffer here ? */
+
+  GST_DEBUG ("clock wait: %" GST_TIME_FORMAT, 
+            GST_TIME_ARGS (cltrimagesink->time));
+
+  /* ah, BTW, I think the gst_element_wait should happen _before_ 
+     the ximage is shown */
+
+  if (GST_VIDEOSINK_CLOCK (cltrimagesink))
+    gst_element_wait (GST_ELEMENT (cltrimagesink), cltrimagesink->time);
+
+  /* set correct time for next buffer */
+  if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) && cltrimagesink->framerate > 0)
+    cltrimagesink->time += GST_SECOND / cltrimagesink->framerate;
+
+  gst_buffer_unref (buf);
+
+  /*
+  if (!cltrimagesink->signal_handoffs)
+    gst_cltrimagesink_handle_xevents (cltrimagesink, pad);
+  */
+}
+
+
+/* =========================================== */
+/*                                             */
+/*              Init & Class init              */
+/*                                             */
+/* =========================================== */
+
+static void
+gst_cltrimagesink_set_property (GObject      *object, 
+                               guint         prop_id,
+                               const GValue *value, 
+                               GParamSpec   *pspec)
+{
+  GstCltrimageSink *cltrimagesink;
+
+  g_return_if_fail (GST_IS_CLTRIMAGESINK (object));
+
+  cltrimagesink = GST_CLTRIMAGESINK (object);
+
+  switch (prop_id) 
+    {
+    case ARG_WIDGET:
+      cltrimagesink->widget = g_value_get_pointer (value);
+      break;
+      /*
+    case ARG_SIGNAL_HANDOFFS:
+      cltrimagesink->signal_handoffs = g_value_get_boolean (value);
+      */
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_cltrimagesink_get_property (GObject    *object, 
+                               guint       prop_id,
+                               GValue     *value, 
+                               GParamSpec *pspec)
+{
+  GstCltrimageSink *cltrimagesink;
+
+  g_return_if_fail (GST_IS_CLTRIMAGESINK (object));
+
+  cltrimagesink = GST_CLTRIMAGESINK (object);
+
+  switch (prop_id) 
+    {
+    case ARG_WIDGET:
+      g_value_set_pointer (value, cltrimagesink->widget);
+      break;
+      /*
+    case ARG_SIGNAL_HANDOFFS:
+      g_value_set_boolean (value, cltrimagesink->signal_handoffs);
+      break;
+      */
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    } 
+}
+
+static void
+gst_cltrimagesink_finalize (GObject *object)
+{
+  GstCltrimageSink *cltrimagesink;
+
+  cltrimagesink = GST_CLTRIMAGESINK (object);
+
+  /*
+  if (cltrimagesink->display_name) 
+    {
+      g_free (cltrimagesink->display_name);
+      cltrimagesink->display_name = NULL;
+    }
+  */
+
+  g_mutex_free (cltrimagesink->x_lock);
+  g_mutex_free (cltrimagesink->pool_lock);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_cltrimagesink_init (GstCltrimageSink * cltrimagesink)
+{
+  DBG("mark");
+
+  GST_VIDEOSINK_PAD (cltrimagesink) 
+    = gst_pad_new_from_template ( gst_static_pad_template_get(&gst_cltrimagesink_sink_template_factory), "sink");
+
+  gst_element_add_pad (GST_ELEMENT (cltrimagesink),
+                      GST_VIDEOSINK_PAD (cltrimagesink));
+  
+  gst_pad_set_chain_function (GST_VIDEOSINK_PAD (cltrimagesink),
+                             gst_cltrimagesink_chain);
+
+  gst_pad_set_link_function (GST_VIDEOSINK_PAD (cltrimagesink),
+                            gst_cltrimagesink_sink_link);
+
+  gst_pad_set_getcaps_function (GST_VIDEOSINK_PAD (cltrimagesink),
+                               gst_cltrimagesink_getcaps);
+
+  gst_pad_set_fixate_function (GST_VIDEOSINK_PAD (cltrimagesink),
+                              gst_cltrimagesink_fixate);
+
+  /*
+  gst_pad_set_bufferalloc_function (GST_VIDEOSINK_PAD (cltrimagesink),
+                                   gst_cltrimagesink_buffer_alloc);
+  */
+
+  cltrimagesink->framerate    = 0;
+
+  cltrimagesink->x_lock       = g_mutex_new ();
+
+  cltrimagesink->pixel_width  = cltrimagesink->pixel_height = 1;
+
+  cltrimagesink->image_pool   = NULL;
+  cltrimagesink->pool_lock    = g_mutex_new ();
+
+  cltrimagesink->texture = NULL;
+
+  GST_FLAG_SET (cltrimagesink, GST_ELEMENT_THREAD_SUGGESTED);
+  GST_FLAG_SET (cltrimagesink, GST_ELEMENT_EVENT_AWARE);
+}
+
+static void
+gst_cltrimagesink_base_init (gpointer g_class)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+  gst_element_class_set_details (element_class, &gst_cltrimagesink_details);
+
+  gst_element_class_add_pad_template (element_class,
+                                     gst_static_pad_template_get (&gst_cltrimagesink_sink_template_factory));
+}
+
+static void
+gst_cltrimagesink_class_init (GstCltrimageSinkClass * klass)
+{
+  GObjectClass    *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class    = (GObjectClass*) klass;
+  gstelement_class = (GstElementClass*) klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_VIDEOSINK);
+
+  /* TOGO */
+  g_object_class_install_property (gobject_class, 
+                                  ARG_WIDGET,
+                                  g_param_spec_pointer ("widget", 
+                                                       "Widget", 
+                                                       "Cltr drawable widget",
+                                                        G_PARAM_READWRITE));
+
+  /* TOGO */
+  g_object_class_install_property (gobject_class, 
+                                  ARG_SYNCHRONOUS,
+                                  g_param_spec_boolean ("synchronous", 
+                                                        "Synchronous", 
+                                                        "When enabled, runs "
+                                                        "the X display in synchronous mode. (used only for debugging)", 
+                                                        FALSE,
+                                                        G_PARAM_READWRITE));
+  /* TOGO */
+  g_object_class_install_property (gobject_class, 
+                                  ARG_SIGNAL_HANDOFFS,
+                                  g_param_spec_boolean ("signal-handoffs", 
+                                                        "Signal handoffs",
+                                                        "Send a signal before unreffing the buffer, forces YUV, no GL output",
+                                                        FALSE, 
+                                                        G_PARAM_READWRITE));
+
+  gst_cltrimagesink_signals[SIGNAL_HANDOFF] 
+    = g_signal_new ("handoff", 
+                   G_TYPE_FROM_CLASS (klass), 
+                   G_SIGNAL_RUN_LAST,
+                   G_STRUCT_OFFSET (GstCltrimageSinkClass, handoff), 
+                   NULL, 
+                   NULL,
+                   gst_marshal_VOID__POINTER_OBJECT, 
+                   G_TYPE_NONE, 
+                   2,
+                   GST_TYPE_BUFFER, 
+                   GST_TYPE_PAD);
+
+  gst_cltrimagesink_signals[SIGNAL_BUFALLOC] =
+      g_signal_new ("bufferalloc", 
+                   G_TYPE_FROM_CLASS (klass), 
+                   G_SIGNAL_RUN_LAST,
+                   G_STRUCT_OFFSET (GstCltrimageSinkClass, bufferalloc), 
+                   NULL, 
+                   NULL,
+                   gst_marshal_VOID__POINTER_OBJECT, 
+                   G_TYPE_NONE, 2,
+                   GST_TYPE_BUFFER, GST_TYPE_PAD);
+
+  gobject_class->finalize     = gst_cltrimagesink_finalize;
+  gobject_class->set_property = gst_cltrimagesink_set_property;
+  gobject_class->get_property = gst_cltrimagesink_get_property;
+
+  gstelement_class->change_state = gst_cltrimagesink_change_state;
+}
+
+/* ============================================================= */
+/*                                                               */
+/*                       Public Methods                          */
+/*                                                               */
+/* ============================================================= */
+
+/* =========================================== */
+/*                                             */
+/*          Object typing & Creation           */
+/*                                             */
+/* =========================================== */
+
+GType
+gst_cltrimagesink_get_type (void)
+{
+  static GType cltrimagesink_type = 0;
+
+  if (!cltrimagesink_type) 
+    {
+      static const GTypeInfo cltrimagesink_info = 
+       {
+         sizeof (GstCltrimageSinkClass),
+         gst_cltrimagesink_base_init,
+         NULL,
+         (GClassInitFunc) gst_cltrimagesink_class_init,
+         NULL,
+         NULL,
+         sizeof (GstCltrimageSink),
+         0,
+         (GInstanceInitFunc) gst_cltrimagesink_init,
+       };
+
+
+    cltrimagesink_type 
+      = g_type_register_static (GST_TYPE_VIDEOSINK,
+                               "GstCltrimageSink", 
+                               &cltrimagesink_info, 
+                               0);
+    }
+  
+  return cltrimagesink_type;
+}
+
+static gboolean
+plugin_init (GstPlugin *plugin)
+{
+  /* Loading the library containing GstVideoSink, our parent object */
+  if (!gst_library_load ("gstvideo"))
+    return FALSE;
+
+  if (!gst_element_register (plugin, 
+                            "cltrimagesink",
+                            GST_RANK_SECONDARY, 
+                            GST_TYPE_CLTRIMAGESINK))
+    return FALSE;
+
+  GST_DEBUG_CATEGORY_INIT (gst_debug_cltrimagesink, 
+                          "cltrimagesink", 
+                          0,
+                          "cltrimagesink element");
+  return TRUE;
+}
+
+#define GST_LICENSE "LGPL"
+#define GST_PACKAGE "GStreamer"
+#define GST_ORIGIN  "http://o-hand.com"
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+                  GST_VERSION_MINOR,
+                  "cltrimagesink",
+                  "Clutter video output plugin based on OpenGL 1.2 calls",
+                  plugin_init, 
+                  VERSION, 
+                  GST_LICENSE, 
+                  GST_PACKAGE, 
+                  GST_ORIGIN)
diff --git a/gst/cltrimagesink.h b/gst/cltrimagesink.h
new file mode 100644 (file)
index 0000000..1c724c1
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef __GST_CLTRIMAGESINK_H__
+#define __GST_CLTRIMAGESINK_H__
+
+#include <gst/video/videosink.h>
+#include <clutter/cltr.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_CLTRIMAGESINK \
+  (gst_cltrimagesink_get_type())
+#define GST_CLTRIMAGESINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_CLTRIMAGESINK, GstCltrimageSink))
+#define GST_CLTRIMAGESINK_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_CLTRIMAGESINK, GstCltrimageSink))
+#define GST_IS_CLTRIMAGESINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_CLTRIMAGESINK))
+#define GST_IS_CLTRIMAGESINK_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_CLTRIMAGESINK))
+
+typedef struct _GstCltrimageSink GstCltrimageSink;
+typedef struct _GstCltrimageSinkClass GstCltrimageSinkClass;
+
+struct _GstCltrimageSink 
+{
+  /* Our element stuff */
+  GstVideoSink videosink;
+  
+  CltrTexture *texture;
+  
+  int pixel_width, pixel_height;
+
+  gdouble framerate;
+  GMutex *x_lock;
+  
+  GstClockTime time;
+  
+  GMutex *pool_lock;
+  GSList *image_pool;
+
+  GstCaps *caps;
+
+  CltrWidget *widget;
+};
+
+struct _GstCltrimageSinkClass {
+  GstVideoSinkClass parent_class;
+
+  /* signals */
+  void (*handoff)     (GstElement *element, GstBuffer *buf, GstPad *pad);
+  void (*bufferalloc) (GstElement *element, GstBuffer *buf, GstPad *pad);
+};
+
+GType gst_cltrimagesink_get_type(void); /* XXX needed ? */
+
+G_END_DECLS
+
+#endif /* __GST_CLTRIMAGESINK_H__ */