Lots, see ChangeLog
This commit is contained in:
parent
3b342b81b7
commit
298f878086
38
ChangeLog
38
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:
|
||||
|
@ -1 +1 @@
|
||||
SUBDIRS=clutter examples
|
||||
SUBDIRS=clutter gst examples
|
@ -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@
|
||||
|
54
clutter/cltr-button.c
Normal file
54
clutter/cltr-button.c
Normal file
@ -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)
|
||||
{
|
||||
|
||||
|
||||
}
|
14
clutter/cltr-button.h
Normal file
14
clutter/cltr-button.h
Normal file
@ -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
|
@ -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)
|
||||
|
54
clutter/cltr-overlay.c
Normal file
54
clutter/cltr-overlay.c
Normal file
@ -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)
|
||||
{
|
||||
|
||||
|
||||
}
|
14
clutter/cltr-overlay.h
Normal file
14
clutter/cltr-overlay.h
Normal file
@ -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
|
@ -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;
|
||||
|
||||
|
||||
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 */
|
||||
|
||||
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,
|
||||
glColor4f(0.1, 0.1, 0.1, 0.3);
|
||||
|
||||
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_n_steps = 20; /* value needs to be calced dep on rows */
|
||||
grid->anim_fps = 50;
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
181
clutter/pixbuf.c
181
clutter/pixbuf.c
@ -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
|
||||
|
@ -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
|
||||
|
11
configure.ac
11
configure.ac
@ -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
|
||||
])
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
157
examples/photos.c
Normal file
157
examples/photos.c
Normal file
@ -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;
|
||||
}
|
196
examples/player.c
Normal file
196
examples/player.c
Normal file
@ -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);
|
||||
}
|
20
gst/Makefile.am
Normal file
20
gst/Makefile.am
Normal file
@ -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
|
669
gst/cltrimagesink.c
Normal file
669
gst/cltrimagesink.c
Normal file
@ -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)
|
57
gst/cltrimagesink.h
Normal file
57
gst/cltrimagesink.h
Normal file
@ -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__ */
|
Loading…
Reference in New Issue
Block a user