mirror of
https://github.com/brl/mutter.git
synced 2024-12-22 19:12:04 +00:00
Video widget updates
This commit is contained in:
parent
246e6bdd5d
commit
f085407d41
29
ChangeLog
29
ChangeLog
@ -1,3 +1,32 @@
|
|||||||
|
2005-05-06 mallum,,, <mallum@openedhand.com>
|
||||||
|
|
||||||
|
* clutter/cltr-button.c: (cltr_button_new_with_label):
|
||||||
|
* clutter/cltr-overlay.c:
|
||||||
|
* clutter/cltr-photo-grid.c: (cltr_photo_grid_cell_new),
|
||||||
|
(cltr_photo_grid_paint), (cltr_photo_grid_new):
|
||||||
|
* clutter/cltr-video.c: (cltr_video_print_tag), (got_buffering),
|
||||||
|
(got_error), (caps_set), (parse_stream_info), (cb_iterate),
|
||||||
|
(cltr_video_new), (cltr_video_play), (cltr_video_seek),
|
||||||
|
(cltr_video_seek_time), (cltr_video_stop), (cltr_video_close),
|
||||||
|
(cltr_video_pause), (cltr_video_can_set_volume),
|
||||||
|
(cltr_video_set_volume), (cltr_video_get_volume),
|
||||||
|
(cltr_video_idler), (cltr_video_set_source), (cltr_video_show),
|
||||||
|
(cltr_video_hide), (cltr_video_handle_xevent), (cltr_video_paint):
|
||||||
|
* clutter/cltr-video.h:
|
||||||
|
* clutter/cltr-widget.h:
|
||||||
|
* clutter/cltr-window.c: (cltr_window_show), (cltr_window_paint),
|
||||||
|
(cltr_window_handle_xevent), (cltr_window_set_fullscreen),
|
||||||
|
(cltr_window_focus_widget):
|
||||||
|
* clutter/cltr-window.h:
|
||||||
|
* clutter/cltr.h:
|
||||||
|
* clutter/fonts.c: (get_layout_bitmap), (font_draw),
|
||||||
|
(font_get_pixel_size):
|
||||||
|
* configure.ac:
|
||||||
|
* examples/photos.c: (photo_grid_populate):
|
||||||
|
* examples/player.c: (handle_xevent), (main):
|
||||||
|
* examples/scratch.c: (main):
|
||||||
|
Lots more tweaks, mainly updating video widget.
|
||||||
|
|
||||||
2005-04-29 mallum,,, <mallum@openedhand.com>
|
2005-04-29 mallum,,, <mallum@openedhand.com>
|
||||||
|
|
||||||
* clutter/cltr-button.c: (cltr_button_new),
|
* clutter/cltr-button.c: (cltr_button_new),
|
||||||
|
@ -5,10 +5,13 @@ struct CltrButton
|
|||||||
{
|
{
|
||||||
CltrWidget widget;
|
CltrWidget widget;
|
||||||
CltrLabel *label;
|
CltrLabel *label;
|
||||||
|
Pixmap *pixb;
|
||||||
|
CltrTexture *texture;
|
||||||
|
|
||||||
CltrButtonActivate activate_cb;
|
CltrButtonActivate activate_cb;
|
||||||
void *activate_cb_data;
|
void *activate_cb_data;
|
||||||
|
|
||||||
|
|
||||||
CltrButtonState state; /* may be better in widget ? */
|
CltrButtonState state; /* may be better in widget ? */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -85,6 +88,15 @@ cltr_button_new_with_label(const char *label,
|
|||||||
return CLTR_WIDGET(button);
|
return CLTR_WIDGET(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CltrWidget*
|
||||||
|
cltr_button_new_with_pixbuf(Pixbuf *pixb)
|
||||||
|
{
|
||||||
|
CltrButton *button = NULL;
|
||||||
|
|
||||||
|
button = CLTR_BUTTON(cltr_button_new(-1, -1));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cltr_button_show(CltrWidget *widget)
|
cltr_button_show(CltrWidget *widget)
|
||||||
{
|
{
|
||||||
|
@ -49,6 +49,17 @@ cltr_overlay_handle_xevent (CltrWidget *widget, XEvent *xev)
|
|||||||
static void
|
static void
|
||||||
cltr_overlay_paint(CltrWidget *widget)
|
cltr_overlay_paint(CltrWidget *widget)
|
||||||
{
|
{
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
|
glColor4f(0.5, 0.5, 0.5, 1.0);
|
||||||
|
|
||||||
|
cltr_glu_rounded_rect(widget->x,
|
||||||
|
widget->y,
|
||||||
|
widget->x + widget->width,
|
||||||
|
widget->y + widget->height,
|
||||||
|
widget->width/30,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,6 @@ cltr_photo_grid_cell_new(CltrPhotoGrid *grid,
|
|||||||
CltrPhotoGridCell *cell = NULL;
|
CltrPhotoGridCell *cell = NULL;
|
||||||
int maxw = grid->widget.width, maxh = grid->widget.height;
|
int maxw = grid->widget.width, maxh = grid->widget.height;
|
||||||
int neww = 0, newh = 0;
|
int neww = 0, newh = 0;
|
||||||
Pixbuf *tmp_pixb = NULL;
|
|
||||||
|
|
||||||
cell = g_malloc0(sizeof(CltrPhotoGridCell));
|
cell = g_malloc0(sizeof(CltrPhotoGridCell));
|
||||||
|
|
||||||
@ -540,7 +539,6 @@ cltr_photo_grid_paint(CltrWidget *widget)
|
|||||||
int x = 0, y = 0, rows = 0, cols = 0, i =0;
|
int x = 0, y = 0, rows = 0, cols = 0, i =0;
|
||||||
GList *cell_item;
|
GList *cell_item;
|
||||||
|
|
||||||
CltrWindow *win = CLTR_WINDOW(widget->parent);
|
|
||||||
CltrPhotoGrid *grid = (CltrPhotoGrid *)widget;
|
CltrPhotoGrid *grid = (CltrPhotoGrid *)widget;
|
||||||
|
|
||||||
rows = grid->n_rows+1;
|
rows = grid->n_rows+1;
|
||||||
@ -551,10 +549,7 @@ cltr_photo_grid_paint(CltrWidget *widget)
|
|||||||
|
|
||||||
if (grid->cells_tail == NULL)
|
if (grid->cells_tail == NULL)
|
||||||
{
|
{
|
||||||
/* No pictures to paint yet */
|
glColor3ub(0xc2, 0xc3, 0xc1);
|
||||||
CltrWindow *win = CLTR_WINDOW(grid->widget.parent);
|
|
||||||
|
|
||||||
glColor3f(0.6, 0.6, 0.62);
|
|
||||||
glRecti(0, 0, widget->width, widget->height);
|
glRecti(0, 0, widget->width, widget->height);
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
@ -607,7 +602,7 @@ cltr_photo_grid_paint(CltrWidget *widget)
|
|||||||
CltrPhotoGridCell *cell = (CltrPhotoGridCell *)cell_item->data;
|
CltrPhotoGridCell *cell = (CltrPhotoGridCell *)cell_item->data;
|
||||||
Pixbuf *pixb = NULL;
|
Pixbuf *pixb = NULL;
|
||||||
int x1, x2, y1, y2, thumb_w, thumb_h;
|
int x1, x2, y1, y2, thumb_w, thumb_h;
|
||||||
int ns_border, ew_border;
|
int ns_border, ew_border, selected_offset = 0;
|
||||||
|
|
||||||
pixb = cell->pixb;
|
pixb = cell->pixb;
|
||||||
|
|
||||||
@ -636,8 +631,12 @@ cltr_photo_grid_paint(CltrWidget *widget)
|
|||||||
cell->anim_step = 0;
|
cell->anim_step = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cell_item == grid->cell_active
|
||||||
|
&& grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
|
||||||
|
selected_offset = 2;
|
||||||
|
|
||||||
ew_border = thumb_w/8;
|
ew_border = thumb_w/8;
|
||||||
ns_border = thumb_h/8;
|
ns_border = (thumb_h/8) + 4;
|
||||||
|
|
||||||
thumb_w -= (2 * ew_border);
|
thumb_w -= (2 * ew_border);
|
||||||
thumb_h -= (2 * ns_border);
|
thumb_h -= (2 * ns_border);
|
||||||
@ -662,10 +661,10 @@ cltr_photo_grid_paint(CltrWidget *widget)
|
|||||||
g_mutex_lock(grid->mutex);
|
g_mutex_lock(grid->mutex);
|
||||||
|
|
||||||
cltr_texture_render_to_gl_quad(cell->texture,
|
cltr_texture_render_to_gl_quad(cell->texture,
|
||||||
-(thumb_w/2),
|
-(thumb_w/2) - selected_offset,
|
||||||
-(thumb_h/2),
|
-(thumb_h/2) - selected_offset,
|
||||||
(thumb_w/2),
|
(thumb_w/2) - selected_offset,
|
||||||
(thumb_h/2));
|
(thumb_h/2) - selected_offset);
|
||||||
|
|
||||||
g_mutex_unlock(grid->mutex);
|
g_mutex_unlock(grid->mutex);
|
||||||
|
|
||||||
@ -678,26 +677,46 @@ cltr_photo_grid_paint(CltrWidget *widget)
|
|||||||
else
|
else
|
||||||
glColor4f(0.9, 0.95, 0.95, 1.0);
|
glColor4f(0.9, 0.95, 0.95, 1.0);
|
||||||
|
|
||||||
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||||
|
|
||||||
/* Draw with origin in center of photo */
|
/* Draw with origin in center of photo */
|
||||||
|
|
||||||
/*
|
|
||||||
glRecti(-(thumb_w/2)-4, -(thumb_h/2)-4,
|
|
||||||
(thumb_w/2)+4, (thumb_h/2)+ns_border);
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
glRecti(-(thumb_w/2)-6 - selected_offset,
|
||||||
|
-(thumb_h/2)-6 - selected_offset,
|
||||||
|
(thumb_w/2)+6 - selected_offset,
|
||||||
|
(thumb_h/2)+ns_border - selected_offset);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
cltr_glu_rounded_rect(-(thumb_w/2)-4, -(thumb_h/2)-4,
|
cltr_glu_rounded_rect(-(thumb_w/2)-4, -(thumb_h/2)-4,
|
||||||
(thumb_w/2)+4, (thumb_h/2)+ns_border,
|
(thumb_w/2)+4, (thumb_h/2)+ns_border,
|
||||||
thumb_w/30,
|
thumb_w/30,
|
||||||
NULL);
|
NULL);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Nice colors */
|
||||||
|
/* glColor4ub(0x3c, 0xbb, 0x15, 0xff); */
|
||||||
|
/* glColor4ub(0x99, 0x99, 0xff, 0xff); */
|
||||||
|
/* glColor4ub(0x99, 0x99, 0x99, 0xff); */
|
||||||
|
|
||||||
/* shadow */
|
/* shadow */
|
||||||
|
|
||||||
|
glColor4ub(0x99, 0x99, 0x99, 0xff);
|
||||||
|
glRecti(-(thumb_w/2)-6+2, -(thumb_h/2)-6+2,
|
||||||
|
(thumb_w/2)+6+2, (thumb_h/2)+ns_border+2);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
glColor4f(0.1, 0.1, 0.1, 0.3);
|
glColor4f(0.1, 0.1, 0.1, 0.3);
|
||||||
|
|
||||||
|
|
||||||
cltr_glu_rounded_rect(-(thumb_w/2)-4 + 1, -(thumb_h/2)-4 + 1,
|
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/2)+4 + 1, (thumb_h/2)+ns_border +1,
|
||||||
thumb_w/30,
|
thumb_w/30,
|
||||||
NULL);
|
NULL);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||||
@ -725,7 +744,9 @@ cltr_photo_grid_paint(CltrWidget *widget)
|
|||||||
/* finally paint background */
|
/* finally paint background */
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
glColor3f(0.6, 0.6, 0.62);
|
|
||||||
|
glColor3ub(0xc2, 0xc3, 0xc1);
|
||||||
|
|
||||||
glRecti(0, 0, widget->width, widget->height);
|
glRecti(0, 0, widget->width, widget->height);
|
||||||
|
|
||||||
/* reset */
|
/* reset */
|
||||||
@ -824,7 +845,7 @@ cltr_photo_grid_new(int width,
|
|||||||
grid->view_min_y = 0.0;
|
grid->view_min_y = 0.0;
|
||||||
|
|
||||||
/* Assmes cols == rows */
|
/* Assmes cols == rows */
|
||||||
grid->zoom_max = /* 1.0 + */ (float) (n_rows * 1.0); // - 0.3;
|
grid->zoom_max = (float) (n_rows * 1.0);
|
||||||
|
|
||||||
grid->row_offset = 0;
|
grid->row_offset = 0;
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "cltr-video.h"
|
#include "cltr-video.h"
|
||||||
#include "cltr-private.h"
|
#include "cltr-private.h"
|
||||||
|
|
||||||
|
/* This is all very much based on the totem gst bacon video widget */
|
||||||
|
|
||||||
struct CltrVideo
|
struct CltrVideo
|
||||||
{
|
{
|
||||||
CltrWidget widget;
|
CltrWidget widget;
|
||||||
@ -9,10 +11,20 @@ struct CltrVideo
|
|||||||
|
|
||||||
GAsyncQueue *queue;
|
GAsyncQueue *queue;
|
||||||
|
|
||||||
int video_width, video_height;
|
gint video_width, video_height;
|
||||||
|
gdouble video_fps;
|
||||||
CltrTexture *frame_texture;
|
CltrTexture *frame_texture;
|
||||||
};
|
|
||||||
|
|
||||||
|
gboolean has_video, has_audio;
|
||||||
|
|
||||||
|
gint64 stream_length;
|
||||||
|
gint64 current_time_nanos;
|
||||||
|
gint64 current_time;
|
||||||
|
float current_position;
|
||||||
|
|
||||||
|
guint update_id;
|
||||||
|
char *last_error_message;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -24,6 +36,14 @@ cltr_video_handle_xevent (CltrWidget *widget, XEvent *xev);
|
|||||||
static void
|
static void
|
||||||
cltr_video_paint(CltrWidget *widget);
|
cltr_video_paint(CltrWidget *widget);
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_stream_info (CltrVideo *video);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
cb_iterate (CltrVideo *video);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
cltr_video_idler (CltrVideo *video);
|
||||||
|
|
||||||
|
|
||||||
static gint64 length = 0; /* to go */
|
static gint64 length = 0; /* to go */
|
||||||
@ -59,83 +79,7 @@ cltr_video_print_tag (const GstTagList *list,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cltr_video_got_found_tag (GstPlay *play,
|
got_eos (GstPlay* play, CltrVideo *video)
|
||||||
GstElement *source,
|
|
||||||
GstTagList *tag_list,
|
|
||||||
CltrVideo *video)
|
|
||||||
{
|
|
||||||
CltrVideoSignal *signal;
|
|
||||||
|
|
||||||
signal = g_new0 (CltrVideoSignal, 1);
|
|
||||||
signal->signal_id = CLTR_VIDEO_ASYNC_FOUND_TAG;
|
|
||||||
signal->signal_data.found_tag.source = source;
|
|
||||||
signal->signal_data.found_tag.tag_list = gst_tag_list_copy (tag_list);
|
|
||||||
|
|
||||||
g_async_queue_push (video->queue, signal);
|
|
||||||
|
|
||||||
/* gst_tag_list_foreach (tag_list, cltr_video_print_tag, NULL); */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cltr_video_got_time_tick (GstPlay *play,
|
|
||||||
gint64 time_nanos,
|
|
||||||
CltrVideo *video)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
CltrVideoSignal *signal;
|
|
||||||
|
|
||||||
signal = g_new0 (CltrVideoSignal, 1);
|
|
||||||
signal->signal_id = CLTR_VIDEO_ASYNC_FOUND_TAG;
|
|
||||||
signal->signal_data.found_tag.source = source;
|
|
||||||
signal->signal_data.found_tag.tag_list = gst_tag_list_copy (tag_list);
|
|
||||||
|
|
||||||
g_async_queue_push (video->queue, signal);
|
|
||||||
*/
|
|
||||||
|
|
||||||
g_print ("time tick %f\n", time_nanos / (float) GST_SECOND);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cltr_video_got_stream_length (GstPlay *play,
|
|
||||||
gint64 length_nanos,
|
|
||||||
CltrVideo *video)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
CltrVideoSignal *signal;
|
|
||||||
|
|
||||||
signal = g_new0 (CltrVideoSignal, 1);
|
|
||||||
|
|
||||||
signal->signal_id = CLTR_VIDEO_ASYNC_VIDEO_SIZE;
|
|
||||||
signal->signal_data.video_size.width = width;
|
|
||||||
signal->signal_data.video_size.height = height;
|
|
||||||
|
|
||||||
g_async_queue_push (video->queue, signal);
|
|
||||||
*/
|
|
||||||
CLTR_DBG ("got length %" G_GUINT64_FORMAT "\n", length_nanos);
|
|
||||||
length = length_nanos;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cltr_video_got_video_size (GstPlay *play,
|
|
||||||
gint width,
|
|
||||||
gint height,
|
|
||||||
CltrVideo *video)
|
|
||||||
{
|
|
||||||
CltrVideoSignal *signal;
|
|
||||||
|
|
||||||
signal = g_new0 (CltrVideoSignal, 1);
|
|
||||||
|
|
||||||
signal->signal_id = CLTR_VIDEO_ASYNC_VIDEO_SIZE;
|
|
||||||
signal->signal_data.video_size.width = width;
|
|
||||||
signal->signal_data.video_size.height = height;
|
|
||||||
|
|
||||||
g_async_queue_push (video->queue, signal);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cltr_video_got_eos (GstPlay* play, CltrVideo *video)
|
|
||||||
{
|
{
|
||||||
CLTR_DBG ("End Of Stream\n");
|
CLTR_DBG ("End Of Stream\n");
|
||||||
|
|
||||||
@ -150,40 +94,269 @@ cltr_video_got_eos (GstPlay* play, CltrVideo *video)
|
|||||||
gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
|
gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
cltr_video_seek_timer (GstPlay * play)
|
got_stream_length (GstElement *play,
|
||||||
|
gint64 length_nanos,
|
||||||
|
CltrVideo *video)
|
||||||
{
|
{
|
||||||
gst_play_seek_to_time (play, length / 2);
|
video->stream_length = (gint64) length_nanos / GST_MSECOND;
|
||||||
return FALSE;
|
|
||||||
|
/* fire off some callback here ? */
|
||||||
|
|
||||||
|
CLTR_DBG("length: %i", video->stream_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
got_time_tick (GstElement *play,
|
||||||
|
gint64 time_nanos,
|
||||||
|
CltrVideo *video)
|
||||||
|
{
|
||||||
|
CLTR_MARK();
|
||||||
|
|
||||||
|
video->current_time_nanos = time_nanos;
|
||||||
|
|
||||||
|
video->current_time = (gint64) time_nanos / GST_MSECOND;
|
||||||
|
|
||||||
|
if (video->stream_length == 0)
|
||||||
|
video->current_position = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
video->current_position = (float) video->current_time / video->stream_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fire off callback here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
got_found_tag (GstPlay *play,
|
||||||
|
GstElement *source,
|
||||||
|
GstTagList *tag_list,
|
||||||
|
CltrVideo *video)
|
||||||
|
{
|
||||||
|
CltrVideoSignal *signal;
|
||||||
|
|
||||||
|
CLTR_MARK();
|
||||||
|
|
||||||
|
signal = g_new0 (CltrVideoSignal, 1);
|
||||||
|
signal->signal_id = CLTR_VIDEO_ASYNC_FOUND_TAG;
|
||||||
|
signal->signal_data.found_tag.source = source;
|
||||||
|
signal->signal_data.found_tag.tag_list = gst_tag_list_copy (tag_list);
|
||||||
|
|
||||||
|
g_async_queue_push (video->queue, signal);
|
||||||
|
|
||||||
|
/* gst_tag_list_foreach (tag_list, cltr_video_print_tag, NULL); */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
got_state_change (GstElement *play,
|
||||||
|
GstElementState old_state,
|
||||||
|
GstElementState new_state,
|
||||||
|
CltrVideo *video)
|
||||||
|
{
|
||||||
|
if (old_state == GST_STATE_PLAYING)
|
||||||
|
{
|
||||||
|
if (video->update_id != 0)
|
||||||
|
{
|
||||||
|
g_source_remove (video->update_id);
|
||||||
|
video->update_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_idle_remove_by_data (video);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (new_state == GST_STATE_PLAYING)
|
||||||
|
{
|
||||||
|
if (video->update_id != 0)
|
||||||
|
g_source_remove (video->update_id);
|
||||||
|
|
||||||
|
video->update_id = g_timeout_add (200, (GSourceFunc) cb_iterate, video);
|
||||||
|
|
||||||
|
g_idle_add((GSourceFunc) cltr_video_idler, video);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_state <= GST_STATE_READY && new_state >= GST_STATE_PAUSED)
|
||||||
|
{
|
||||||
|
parse_stream_info (video);
|
||||||
|
}
|
||||||
|
else if (new_state <= GST_STATE_READY && old_state >= GST_STATE_PAUSED)
|
||||||
|
{
|
||||||
|
video->has_video = FALSE;
|
||||||
|
video->has_audio = FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (bvw->priv->tagcache)
|
||||||
|
{
|
||||||
|
gst_tag_list_free (bvw->priv->tagcache);
|
||||||
|
bvw->priv->tagcache = NULL;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
video->video_width = 0;
|
||||||
|
video->video_height = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
got_redirect (GstElement *play,
|
||||||
|
const gchar *new_location,
|
||||||
|
CltrVideo *bvw)
|
||||||
|
{
|
||||||
|
CLTR_MARK();
|
||||||
|
|
||||||
|
/*
|
||||||
|
bvw->priv->got_redirect = TRUE;
|
||||||
|
|
||||||
|
signal = g_new0 (BVWSignal, 1);
|
||||||
|
signal->signal_id = ASYNC_REDIRECT;
|
||||||
|
signal->signal_data.redirect.new_location = g_strdup (new_location);
|
||||||
|
|
||||||
|
g_async_queue_push (bvw->priv->queue, signal);
|
||||||
|
|
||||||
|
g_idle_add ((GSourceFunc) bacon_video_widget_signal_idler, bvw);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
stream_info_set (GObject *obj,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
CltrVideo *video)
|
||||||
|
{
|
||||||
|
|
||||||
|
parse_stream_info (video);
|
||||||
|
|
||||||
|
/*
|
||||||
|
signal = g_new0 (BVWSignal, 1);
|
||||||
|
signal->signal_id = ASYNC_NOTIFY_STREAMINFO;
|
||||||
|
|
||||||
|
g_async_queue_push (bvw->priv->queue, signal);
|
||||||
|
|
||||||
|
g_idle_add ((GSourceFunc) bacon_video_widget_signal_idler, bvw);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
got_source (GObject *play,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
CltrVideo *video)
|
||||||
|
{
|
||||||
|
GObject *source = NULL;
|
||||||
|
GObjectClass *klass;
|
||||||
|
|
||||||
|
CLTR_MARK();
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (bvw->priv->tagcache) {
|
||||||
|
gst_tag_list_free (bvw->priv->tagcache);
|
||||||
|
bvw->priv->tagcache = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bvw->priv->media_device)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_object_get (play, "source", &source, NULL);
|
||||||
|
if (!source)
|
||||||
|
return;
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (source);
|
||||||
|
if (!g_object_class_find_property (klass, "device"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_object_set (source, "device", bvw->priv->media_device, NULL);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
got_buffering (GstElement *play,
|
||||||
|
gint percentage,
|
||||||
|
CltrVideo *video)
|
||||||
|
{
|
||||||
|
CLTR_DBG("Buffering with %i", percentage);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
BVWSignal *signal;
|
||||||
|
|
||||||
|
g_return_if_fail (bvw != NULL);
|
||||||
|
g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
|
||||||
|
|
||||||
|
signal = g_new0 (BVWSignal, 1);
|
||||||
|
signal->signal_id = ASYNC_BUFFERING;
|
||||||
|
signal->signal_data.buffering.percent = percentage;
|
||||||
|
|
||||||
|
g_async_queue_push (bvw->priv->queue, signal);
|
||||||
|
|
||||||
|
g_idle_add ((GSourceFunc) bacon_video_widget_signal_idler, bvw);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
got_error (GstElement *play,
|
||||||
|
GstElement *orig,
|
||||||
|
GError *error,
|
||||||
|
gchar *debug,
|
||||||
|
CltrVideo *video)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
XXX TODO cpy the error message to asyc queueu
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
CLTR_MARK();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* since we're opening, we will never enter the mainloop
|
||||||
|
* until we return, so setting an idle handler doesn't
|
||||||
|
* help... Anyway, let's prepare a message. */
|
||||||
|
if (GST_STATE (play) != GST_STATE_PLAYING) {
|
||||||
|
g_free (bvw->priv->last_error_message);
|
||||||
|
bvw->priv->last_error_message = g_strdup (error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal = g_new0 (BVWSignal, 1);
|
||||||
|
signal->signal_id = ASYNC_ERROR;
|
||||||
|
signal->signal_data.error.element = orig;
|
||||||
|
signal->signal_data.error.error = g_error_copy (error);
|
||||||
|
if (debug)
|
||||||
|
signal->signal_data.error.debug_message = g_strdup (debug);
|
||||||
|
|
||||||
|
g_async_queue_push (bvw->priv->queue, signal);
|
||||||
|
|
||||||
|
g_idle_add ((GSourceFunc) bacon_video_widget_signal_idler, bvw);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
caps_set (GObject *obj,
|
caps_set (GObject *obj,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
CltrVideo *video)
|
CltrVideo *video)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
GstPad *pad = GST_PAD (obj);
|
GstPad *pad = GST_PAD (obj);
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
|
|
||||||
if (!GST_PAD_CAPS (pad))
|
if (!GST_PAD_CAPS (pad))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
s = gst_caps_get_structure (GST_PAD_CAPS (pad), 0);
|
s = gst_caps_get_structure (GST_PAD_CAPS (pad), 0);
|
||||||
|
|
||||||
if (s) {
|
if (s)
|
||||||
|
{
|
||||||
|
/* const GValue *par; */
|
||||||
|
|
||||||
|
if (!(gst_structure_get_double (s, "framerate", &video->video_fps) &&
|
||||||
const GValue *par;
|
gst_structure_get_int (s, "width", &video->video_width) &&
|
||||||
|
gst_structure_get_int (s, "height", &video->video_height)))
|
||||||
if (!(gst_structure_get_double (s, "framerate", &bvw->priv->video_fps) &&
|
|
||||||
gst_structure_get_int (s, "width", &bvw->priv->video_width) &&
|
|
||||||
gst_structure_get_int (s, "height", &bvw->priv->video_height)))
|
|
||||||
return;
|
return;
|
||||||
if ((par = gst_structure_get_value (s,
|
|
||||||
"pixel-aspect-ratio"))) {
|
/*
|
||||||
|
if ((par = gst_structure_get_value (s, "pixel-aspect-ratio")))
|
||||||
|
{
|
||||||
gint num = gst_value_get_fraction_numerator (par),
|
gint num = gst_value_get_fraction_numerator (par),
|
||||||
den = gst_value_get_fraction_denominator (par);
|
den = gst_value_get_fraction_denominator (par);
|
||||||
|
|
||||||
@ -196,14 +369,104 @@ caps_set (GObject *obj,
|
|||||||
got_video_size (bvw->priv->play, bvw->priv->video_width,
|
got_video_size (bvw->priv->play, bvw->priv->video_width,
|
||||||
bvw->priv->video_height, bvw);
|
bvw->priv->video_height, bvw);
|
||||||
|
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* and disable ourselves */
|
|
||||||
//g_signal_handlers_disconnect_by_func (pad, caps_set, bvw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_stream_info (CltrVideo *video)
|
||||||
|
{
|
||||||
|
GList *streaminfo = NULL;
|
||||||
|
GstPad *videopad = NULL;
|
||||||
|
|
||||||
|
g_object_get (G_OBJECT (video->play), "stream-info", &streaminfo, NULL);
|
||||||
|
|
||||||
|
streaminfo = g_list_copy (streaminfo);
|
||||||
|
|
||||||
|
g_list_foreach (streaminfo, (GFunc) g_object_ref, NULL);
|
||||||
|
|
||||||
|
for ( ; streaminfo != NULL; streaminfo = streaminfo->next)
|
||||||
|
{
|
||||||
|
GObject *info = streaminfo->data;
|
||||||
|
gint type;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
GEnumValue *val;
|
||||||
|
|
||||||
|
if (!info)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
g_object_get (info, "type", &type, NULL);
|
||||||
|
|
||||||
|
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (info), "type");
|
||||||
|
|
||||||
|
val = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type);
|
||||||
|
|
||||||
|
if (strstr (val->value_name, "AUDIO"))
|
||||||
|
{
|
||||||
|
if (!video->has_audio) {
|
||||||
|
video->has_audio = TRUE;
|
||||||
|
/*if (!bvw->priv->media_has_video &&
|
||||||
|
bvw->priv->show_vfx && bvw->priv->vis_element) {
|
||||||
|
videopad = gst_element_get_pad (bvw->priv->vis_element, "src");
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strstr (val->value_name, "VIDEO"))
|
||||||
|
{
|
||||||
|
video->has_video = TRUE;
|
||||||
|
if (!videopad)
|
||||||
|
g_object_get (info, "object", &videopad, NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (videopad)
|
||||||
|
{
|
||||||
|
GstPad *real = (GstPad *) GST_PAD_REALIZE (videopad);
|
||||||
|
|
||||||
|
/* handle explicit caps as well - they're set later */
|
||||||
|
if (((GstRealPad *) real)->link != NULL && GST_PAD_CAPS (real))
|
||||||
|
caps_set (G_OBJECT (real), NULL, video);
|
||||||
|
|
||||||
|
g_signal_connect (real, "notify::caps", G_CALLBACK (caps_set), video);
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
else if (bvw->priv->show_vfx && bvw->priv->vis_element)
|
||||||
|
{
|
||||||
|
fixate_visualization (NULL, NULL, bvw);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_list_foreach (streaminfo, (GFunc) g_object_unref, NULL);
|
||||||
|
g_list_free (streaminfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
cb_iterate (CltrVideo *video)
|
||||||
|
{
|
||||||
|
GstFormat fmt = GST_FORMAT_TIME;
|
||||||
|
gint64 value;
|
||||||
|
|
||||||
|
/* check length/pos of stream */
|
||||||
|
if (gst_element_query (GST_ELEMENT (video->play),
|
||||||
|
GST_QUERY_TOTAL, &fmt, &value)
|
||||||
|
&& GST_CLOCK_TIME_IS_VALID (value)
|
||||||
|
&& value / GST_MSECOND != video->stream_length)
|
||||||
|
{
|
||||||
|
got_stream_length (GST_ELEMENT (video->play), value, video);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_element_query (GST_ELEMENT (video->play),
|
||||||
|
GST_QUERY_POSITION, &fmt, &value))
|
||||||
|
{
|
||||||
|
got_time_tick (GST_ELEMENT (video->play), value, video);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
CltrWidget*
|
CltrWidget*
|
||||||
cltr_video_new(int width, int height)
|
cltr_video_new(int width, int height)
|
||||||
{
|
{
|
||||||
@ -274,15 +537,14 @@ cltr_video_new(int width, int height)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (video->play), "eos",
|
g_signal_connect (G_OBJECT (video->play), "eos",
|
||||||
G_CALLBACK (cltr_video_got_eos), (gpointer) video);
|
G_CALLBACK (got_eos), (gpointer) video);
|
||||||
/*
|
|
||||||
g_signal_connect (G_OBJECT (video->play), "state-change",
|
g_signal_connect (G_OBJECT (video->play), "state-change",
|
||||||
G_CALLBACK (state_change), (gpointer) video);
|
G_CALLBACK (got_state_change), (gpointer) video);
|
||||||
*/
|
|
||||||
g_signal_connect (G_OBJECT (video->play), "found_tag",
|
g_signal_connect (G_OBJECT (video->play), "found_tag",
|
||||||
G_CALLBACK (cltr_video_got_found_tag), (gpointer) video);
|
G_CALLBACK (got_found_tag), (gpointer) video);
|
||||||
|
|
||||||
/*
|
|
||||||
g_signal_connect (G_OBJECT (video->play), "error",
|
g_signal_connect (G_OBJECT (video->play), "error",
|
||||||
G_CALLBACK (got_error), (gpointer) video);
|
G_CALLBACK (got_error), (gpointer) video);
|
||||||
|
|
||||||
@ -291,13 +553,18 @@ cltr_video_new(int width, int height)
|
|||||||
|
|
||||||
g_signal_connect (G_OBJECT (video->play), "notify::source",
|
g_signal_connect (G_OBJECT (video->play), "notify::source",
|
||||||
G_CALLBACK (got_source), (gpointer) video);
|
G_CALLBACK (got_source), (gpointer) video);
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (video->play), "notify::stream-info",
|
g_signal_connect (G_OBJECT (video->play), "notify::stream-info",
|
||||||
G_CALLBACK (stream_info_set), (gpointer) video);
|
G_CALLBACK (stream_info_set), (gpointer) video);
|
||||||
|
|
||||||
|
/* what does this do ?
|
||||||
g_signal_connect (G_OBJECT (video->play), "group-switch",
|
g_signal_connect (G_OBJECT (video->play), "group-switch",
|
||||||
G_CALLBACK (group_switch), (gpointer) video);
|
G_CALLBACK (group_switch), (gpointer) video);
|
||||||
|
*/
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (video->play), "got-redirect",
|
g_signal_connect (G_OBJECT (video->play), "got-redirect",
|
||||||
G_CALLBACK (got_redirect), (gpointer) video);
|
G_CALLBACK (got_redirect), (gpointer) video);
|
||||||
*/
|
|
||||||
|
|
||||||
video->queue = g_async_queue_new ();
|
video->queue = g_async_queue_new ();
|
||||||
|
|
||||||
@ -305,76 +572,114 @@ cltr_video_new(int width, int height)
|
|||||||
|
|
||||||
|
|
||||||
return CLTR_WIDGET(video);
|
return CLTR_WIDGET(video);
|
||||||
|
|
||||||
#if 0
|
|
||||||
video->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 NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Getting default audio and video plugins from GConf */
|
gboolean
|
||||||
video->vis_element = gst_element_factory_make ("goom", "vis_element");
|
cltr_video_play ( CltrVideo *video, GError ** error)
|
||||||
video->data_src = gst_element_factory_make ("gnomevfssrc", "source");
|
{
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
video->audio_sink = gst_gconf_get_default_audio_sink ();
|
if (video->last_error_message)
|
||||||
|
{
|
||||||
|
g_free (video->last_error_message);
|
||||||
|
video->last_error_message = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!GST_IS_ELEMENT (video->audio_sink))
|
ret = (gst_element_set_state (GST_ELEMENT (video->play),
|
||||||
g_error ("Could not get default audio sink from GConf");
|
GST_STATE_PLAYING) == GST_STATE_SUCCESS);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
g_set_error (error, 0, 0, "%s", video->last_error_message ?
|
||||||
|
video->last_error_message : "Failed to play; reason unknown");
|
||||||
|
}
|
||||||
|
|
||||||
video->video_sink = gst_element_factory_make ("cltrimagesink", "cltr-output");
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (!GST_IS_ELEMENT (video->video_sink))
|
gboolean
|
||||||
g_error ("Could not get clutter video sink");
|
cltr_video_seek (CltrVideo *video, float position, GError **gerror)
|
||||||
|
{
|
||||||
|
gint64 seek_time, length_nanos;
|
||||||
|
|
||||||
video->queue = g_async_queue_new ();
|
/* Resetting last_error_message to NULL */
|
||||||
|
if (video->last_error_message)
|
||||||
|
{
|
||||||
|
g_free (video->last_error_message);
|
||||||
|
video->last_error_message = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
gst_element_set(video->video_sink, "queue", video->queue, NULL);
|
length_nanos = (gint64) (video->stream_length * GST_MSECOND);
|
||||||
|
seek_time = (gint64) (length_nanos * position);
|
||||||
|
|
||||||
/* Let's send them to GstPlay object */
|
gst_element_seek (video->play, GST_SEEK_METHOD_SET |
|
||||||
|
GST_SEEK_FLAG_FLUSH | GST_FORMAT_TIME,
|
||||||
|
seek_time);
|
||||||
|
|
||||||
if (!gst_play_set_audio_sink (video->play, video->audio_sink))
|
return TRUE;
|
||||||
g_warning ("Could not set audio sink");
|
}
|
||||||
if (!gst_play_set_video_sink (video->play, video->video_sink))
|
|
||||||
g_warning ("Could not set video sink");
|
|
||||||
if (!gst_play_set_data_src (video->play, video->data_src))
|
|
||||||
g_warning ("Could not set data src");
|
|
||||||
if (!gst_play_set_visualization (video->play, video->vis_element))
|
|
||||||
g_warning ("Could not set visualisation");
|
|
||||||
|
|
||||||
/* Setting location we want to play */
|
gboolean
|
||||||
|
cltr_video_seek_time (CltrVideo *video, gint64 time, GError **gerror)
|
||||||
|
{
|
||||||
|
if (video->last_error_message)
|
||||||
|
{
|
||||||
|
g_free (video->last_error_message);
|
||||||
|
video->last_error_message = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Uncomment that line to get an XML dump of the pipeline */
|
gst_element_seek (video->play, GST_SEEK_METHOD_SET |
|
||||||
/* gst_xml_write_file (GST_ELEMENT (play), stdout); */
|
GST_SEEK_FLAG_FLUSH | GST_FORMAT_TIME,
|
||||||
|
time * GST_MSECOND);
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (video->play), "time_tick",
|
return TRUE;
|
||||||
G_CALLBACK (cltr_video_got_time_tick), video);
|
}
|
||||||
g_signal_connect (G_OBJECT (video->play), "stream_length",
|
|
||||||
G_CALLBACK (cltr_video_got_stream_length), video);
|
|
||||||
g_signal_connect (G_OBJECT (video->play), "have_video_size",
|
|
||||||
G_CALLBACK (cltr_video_got_video_size), video);
|
|
||||||
g_signal_connect (G_OBJECT (video->play), "found_tag",
|
|
||||||
G_CALLBACK (cltr_video_got_found_tag), video);
|
|
||||||
g_signal_connect (G_OBJECT (video->play), "error",
|
|
||||||
G_CALLBACK (gst_element_default_error), NULL);
|
|
||||||
g_signal_connect (G_OBJECT (video->play),
|
|
||||||
"eos", G_CALLBACK (cltr_video_got_eos), video);
|
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (video->video_sink), "notify::caps",
|
void
|
||||||
G_CALLBACK (caps_set), video);
|
cltr_video_stop ( CltrVideo *video)
|
||||||
|
{
|
||||||
|
gst_element_set_state (GST_ELEMENT (video->play), GST_STATE_READY);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
void
|
||||||
/*
|
cltr_video_close ( CltrVideo *video)
|
||||||
|
{
|
||||||
|
gst_element_set_state (GST_ELEMENT (video->play), GST_STATE_READY);
|
||||||
|
|
||||||
|
/* XX close callback here */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_video_pause ( CltrVideo *video)
|
||||||
|
{
|
||||||
|
gst_element_set_state (GST_ELEMENT (video->play), GST_STATE_PAUSED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
cltr_video_can_set_volume ( CltrVideo *video )
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_video_set_volume ( CltrVideo *video, int volume)
|
||||||
|
{
|
||||||
|
if (cltr_video_can_set_volume (video) != FALSE)
|
||||||
|
{
|
||||||
|
volume = CLAMP (volume, 0, 100);
|
||||||
g_object_set (G_OBJECT (video->play), "volume",
|
g_object_set (G_OBJECT (video->play), "volume",
|
||||||
(gdouble) (1. * 0 / 100), NULL);
|
(gdouble) (1. * volume / 100), NULL);
|
||||||
*/
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY); */
|
int
|
||||||
|
cltr_video_get_volume ( CltrVideo *video)
|
||||||
|
{
|
||||||
|
gdouble vol;
|
||||||
|
|
||||||
return CLTR_WIDGET(video);
|
g_object_get (G_OBJECT (video->play), "volume", &vol, NULL);
|
||||||
|
|
||||||
|
return (gint) (vol * 100 + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -434,24 +739,6 @@ cltr_video_set_source(CltrVideo *video, char *location)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
cltr_video_play(CltrVideo *video)
|
|
||||||
{
|
|
||||||
/* Change state to PLAYING */
|
|
||||||
if (gst_element_set_state (GST_ELEMENT (video->play),
|
|
||||||
GST_STATE_PLAYING) == GST_STATE_FAILURE)
|
|
||||||
g_error ("Could not set state to PLAYING");
|
|
||||||
|
|
||||||
g_timeout_add(FPS_TO_TIMEOUT(30), (GSourceFunc) cltr_video_idler, video);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cltr_video_pause(CltrVideo *video)
|
|
||||||
{
|
|
||||||
if (gst_element_set_state (GST_ELEMENT (video->play),
|
|
||||||
GST_STATE_PAUSED) == GST_STATE_FAILURE)
|
|
||||||
g_error ("Could not set state to PAUSED");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -482,23 +769,10 @@ cltr_video_paint(CltrWidget *widget)
|
|||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
if (video->frame_texture
|
if (video->frame_texture
|
||||||
/*
|
|
||||||
&& video->video_height
|
&& video->video_height
|
||||||
&& video->video_width
|
&& video->video_width)
|
||||||
*/)
|
|
||||||
{
|
{
|
||||||
int dis_x, dis_y, dis_height, dis_width;
|
int dis_x = 0, dis_y = 0, dis_height = 0, dis_width = 0;
|
||||||
|
|
||||||
/* Hack */
|
|
||||||
|
|
||||||
if (!video->video_height || !video->video_width )
|
|
||||||
{
|
|
||||||
Pixbuf *pixb = cltr_texture_get_pixbuf(video->frame_texture);
|
|
||||||
|
|
||||||
video->video_height = pixb->height;
|
|
||||||
video->video_width = pixb->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (video->video_width > video->video_height)
|
if (video->video_width > video->video_height)
|
||||||
{
|
{
|
||||||
@ -509,12 +783,13 @@ cltr_video_paint(CltrWidget *widget)
|
|||||||
dis_x = 0;
|
dis_x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
|
|
||||||
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
|
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
|
||||||
|
|
||||||
cltr_texture_lock(video->frame_texture);
|
cltr_texture_lock(video->frame_texture);
|
||||||
@ -528,6 +803,10 @@ cltr_video_paint(CltrWidget *widget)
|
|||||||
cltr_texture_unlock(video->frame_texture);
|
cltr_texture_unlock(video->frame_texture);
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glColor4f(1.0, 1.0, 1.0, 0.5);
|
||||||
|
|
||||||
|
// glRecti(100, 100, 600, 600);
|
||||||
}
|
}
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
@ -66,8 +66,32 @@ cltr_video_new(int width, int height);
|
|||||||
gboolean
|
gboolean
|
||||||
cltr_video_set_source(CltrVideo *video, char *location);
|
cltr_video_set_source(CltrVideo *video, char *location);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
cltr_video_play ( CltrVideo *video, GError ** Error);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
cltr_video_seek (CltrVideo *video, float position, GError **gerror);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
cltr_video_seek_time (CltrVideo *video, gint64 time, GError **gerror);
|
||||||
|
|
||||||
void
|
void
|
||||||
cltr_video_play(CltrVideo *video);
|
cltr_video_stop ( CltrVideo *video);
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_video_close ( CltrVideo *video);
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_video_pause ( CltrVideo *video);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
cltr_video_can_set_volume ( CltrVideo *video );
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_video_set_volume ( CltrVideo *video, int volume);
|
||||||
|
|
||||||
|
int
|
||||||
|
cltr_video_get_volume ( CltrVideo *video);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#ifndef _HAVE_CLTR_WIDGET_H
|
#ifndef _HAVE_CLTR_WIDGET_H
|
||||||
#define _HAVE_CLTR_WIDGET_H
|
#define _HAVE_CLTR_WIDGET_H
|
||||||
|
|
||||||
typedef struct CltrWidget CltrWidget;
|
|
||||||
|
|
||||||
#include "cltr.h"
|
#include "cltr.h"
|
||||||
|
|
||||||
#define CLTR_WIDGET(w) ((CltrWidget*)(w))
|
#define CLTR_WIDGET(w) ((CltrWidget*)(w))
|
||||||
|
@ -15,6 +15,12 @@ struct CltrWindow
|
|||||||
CltrWidget widget;
|
CltrWidget widget;
|
||||||
Window xwin;
|
Window xwin;
|
||||||
CltrWidget *focused_child;
|
CltrWidget *focused_child;
|
||||||
|
|
||||||
|
CltrCallback *pre_paint_hook, *post_paint_hook;
|
||||||
|
|
||||||
|
CltrXEventCallback xevent_cb;
|
||||||
|
void *xevent_cb_data;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -86,6 +92,10 @@ static void
|
|||||||
cltr_window_paint(CltrWidget *widget)
|
cltr_window_paint(CltrWidget *widget)
|
||||||
{
|
{
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
glClearColor( 0.0, 0.0, 0.0, 0.0 ); /* needed for saturate to work */
|
glClearColor( 0.0, 0.0, 0.0, 0.0 ); /* needed for saturate to work */
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -93,7 +103,6 @@ cltr_window_paint(CltrWidget *widget)
|
|||||||
static void
|
static void
|
||||||
cltr_window_handle_xconfigure(CltrWindow *win, XConfigureEvent *cxev)
|
cltr_window_handle_xconfigure(CltrWindow *win, XConfigureEvent *cxev)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
widget.width = cxev->width;
|
widget.width = cxev->width;
|
||||||
widget.height = cxev->height;
|
widget.height = cxev->height;
|
||||||
@ -120,7 +129,10 @@ cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev)
|
|||||||
|
|
||||||
/* XXX Very basic - assumes we are only interested in mouse clicks */
|
/* XXX Very basic - assumes we are only interested in mouse clicks */
|
||||||
if (win->focused_child)
|
if (win->focused_child)
|
||||||
return cltr_widget_handle_xevent(win->focused_child, xev);
|
cltr_widget_handle_xevent(win->focused_child, xev);
|
||||||
|
|
||||||
|
if (win->xevent_cb)
|
||||||
|
(win->xevent_cb)(widget, xev, win->xevent_cb_data);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -157,12 +169,12 @@ cltr_window_set_fullscreen(CltrWindow *win)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Window
|
void
|
||||||
cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget)
|
cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget)
|
||||||
{
|
{
|
||||||
/* XXX Should check widget is an actual child of the window */
|
/* XXX Should check widget is an actual child of the window */
|
||||||
|
|
||||||
ClutterMainContext *ctx = CLTR_CONTEXT();
|
/* ClutterMainContext *ctx = CLTR_CONTEXT(); */
|
||||||
|
|
||||||
if (win->focused_child)
|
if (win->focused_child)
|
||||||
cltr_widget_unfocus(win->focused_child);
|
cltr_widget_unfocus(win->focused_child);
|
||||||
@ -172,4 +184,13 @@ cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget)
|
|||||||
win->focused_child = widget;
|
win->focused_child = widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_window_on_xevent(CltrWindow *win,
|
||||||
|
CltrXEventCallback callback,
|
||||||
|
void *userdata)
|
||||||
|
{
|
||||||
|
win->xevent_cb = callback;
|
||||||
|
win->xevent_cb_data = userdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,9 +10,6 @@ typedef struct CltrWindow CltrWindow;
|
|||||||
CltrWidget*
|
CltrWidget*
|
||||||
cltr_window_new(int width, int height);
|
cltr_window_new(int width, int height);
|
||||||
|
|
||||||
void
|
|
||||||
cltr_window_paint(CltrWidget *widget);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cltr_window_add_widget(CltrWindow *win, CltrWidget *widget, int x, int y);
|
cltr_window_add_widget(CltrWindow *win, CltrWidget *widget, int x, int y);
|
||||||
|
|
||||||
@ -24,8 +21,13 @@ cltr_window_xwin(CltrWindow *win);
|
|||||||
void
|
void
|
||||||
cltr_window_set_fullscreen(CltrWindow *win);
|
cltr_window_set_fullscreen(CltrWindow *win);
|
||||||
|
|
||||||
Window
|
void
|
||||||
cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget);
|
cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget);
|
||||||
|
|
||||||
|
void
|
||||||
|
cltr_window_on_xevent(CltrWindow *win,
|
||||||
|
CltrXEventCallback callback,
|
||||||
|
void *userdata);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include "pixbuf.h"
|
#include "pixbuf.h"
|
||||||
#include "fonts.h"
|
#include "fonts.h"
|
||||||
|
|
||||||
|
|
||||||
typedef enum CltrDirection
|
typedef enum CltrDirection
|
||||||
{
|
{
|
||||||
CLTR_NORTH,
|
CLTR_NORTH,
|
||||||
@ -44,6 +43,17 @@ typedef struct CltrTexture CltrTexture;
|
|||||||
#define cltr_rect_x2(r) ((r).x + (r).width)
|
#define cltr_rect_x2(r) ((r).x + (r).width)
|
||||||
#define cltr_rect_y2(r) ((r).y + (r).height)
|
#define cltr_rect_y2(r) ((r).y + (r).height)
|
||||||
|
|
||||||
|
typedef struct CltrWidget CltrWidget;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (*CltrCallback) (CltrWidget *widget, void *userdata) ;
|
||||||
|
|
||||||
|
typedef void (*CltrXEventCallback) (CltrWidget *widget,
|
||||||
|
XEvent *xev,
|
||||||
|
void *userdata) ;
|
||||||
|
|
||||||
|
|
||||||
/* texture stuff */
|
/* texture stuff */
|
||||||
|
|
||||||
/* ******************* */
|
/* ******************* */
|
||||||
|
@ -56,6 +56,8 @@ get_layout_bitmap (PangoLayout *layout,
|
|||||||
|
|
||||||
pango_layout_get_extents (layout, &ink_rect, NULL);
|
pango_layout_get_extents (layout, &ink_rect, NULL);
|
||||||
|
|
||||||
|
printf("%s() gave width:%i, height %i\n", __func__, ink->width, ink->height);
|
||||||
|
|
||||||
/* XXX why the >> 10 */
|
/* XXX why the >> 10 */
|
||||||
ink->x = ink_rect.x >> 10;
|
ink->x = ink_rect.x >> 10;
|
||||||
ink->width = ((ink_rect.x + ink_rect.width + 1023) >> 10) - ink->x;
|
ink->width = ((ink_rect.x + ink_rect.width + 1023) >> 10) - ink->x;
|
||||||
@ -170,14 +172,10 @@ font_draw(ClutterFont *font,
|
|||||||
|
|
||||||
layout = pango_layout_new (font->context);
|
layout = pango_layout_new (font->context);
|
||||||
|
|
||||||
pango_layout_set_width(layout, pixb->width - x );
|
|
||||||
|
|
||||||
pango_layout_set_text (layout, text, -1);
|
pango_layout_set_text (layout, text, -1);
|
||||||
|
|
||||||
pango_layout_get_pixel_size (layout,
|
/* cant rely on just clip - need to set layout width too ? */
|
||||||
&layout_width, &layout_height);
|
/* pango_layout_set_width(layout, (pixb->width - x) << 10); */
|
||||||
|
|
||||||
/* cant rely on just clip - need to set layout width too */
|
|
||||||
|
|
||||||
draw_layout_on_pixbuf (layout, pixb, p, x, y,
|
draw_layout_on_pixbuf (layout, pixb, p, x, y,
|
||||||
x,
|
x,
|
||||||
@ -202,7 +200,7 @@ font_get_pixel_size (ClutterFont *font,
|
|||||||
|
|
||||||
pango_layout_get_pixel_size (layout, width, height);
|
pango_layout_get_pixel_size (layout, width, height);
|
||||||
|
|
||||||
printf("gave width:%i, height %i\n", *width, *height);
|
printf("%s() gave width:%i, height %i\n", __func__, *width, *height);
|
||||||
|
|
||||||
g_object_unref(G_OBJECT(layout));
|
g_object_unref(G_OBJECT(layout));
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,8 @@ fi
|
|||||||
|
|
||||||
dnl ----- Pango, glib etc ---------------------------------------------------
|
dnl ----- Pango, glib etc ---------------------------------------------------
|
||||||
|
|
||||||
pkg_modules="pangoft2 pango glib-2.0 gthread-2.0"
|
pkg_modules="pangoft2 glib-2.0 gthread-2.0"
|
||||||
PKG_CHECK_MODULES(CLTR, pangoft2 pango glib-2.0 gthread-2.0)
|
PKG_CHECK_MODULES(CLTR, pangoft2 glib-2.0 gthread-2.0)
|
||||||
|
|
||||||
dnl ----- Gstreamer ---------------------------------------------------------
|
dnl ----- Gstreamer ---------------------------------------------------------
|
||||||
|
|
||||||
|
@ -55,10 +55,11 @@ photo_grid_populate(gpointer data)
|
|||||||
|
|
||||||
cell = cltr_photo_grid_cell_new(grid, pixb);
|
cell = cltr_photo_grid_cell_new(grid, pixb);
|
||||||
|
|
||||||
|
/*
|
||||||
g_snprintf(&buf[0], 24, "%i", i);
|
g_snprintf(&buf[0], 24, "%i", i);
|
||||||
font_draw(font, cltr_photo_grid_cell_pixbuf(cell),
|
font_draw(font, cltr_photo_grid_cell_pixbuf(cell),
|
||||||
buf, 10, 10, &font_col);
|
buf, 10, 10, &font_col);
|
||||||
|
*/
|
||||||
g_mutex_lock(cltr_photo_grid_mutex(grid));
|
g_mutex_lock(cltr_photo_grid_mutex(grid));
|
||||||
|
|
||||||
if (!cltr_photo_grid_get_active_cell(grid))
|
if (!cltr_photo_grid_get_active_cell(grid))
|
||||||
|
@ -19,6 +19,34 @@
|
|||||||
|
|
||||||
#include <clutter/cltr.h>
|
#include <clutter/cltr.h>
|
||||||
|
|
||||||
|
int Paused = 0;
|
||||||
|
|
||||||
|
void
|
||||||
|
handle_xevent(CltrWidget *win, XEvent *xev, void *cookie)
|
||||||
|
{
|
||||||
|
KeySym kc;
|
||||||
|
CltrVideo *video = CLTR_VIDEO(cookie);
|
||||||
|
|
||||||
|
if (xev->type == KeyPress)
|
||||||
|
{
|
||||||
|
XKeyEvent *xkeyev = &xev->xkey;
|
||||||
|
|
||||||
|
kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0);
|
||||||
|
|
||||||
|
switch (kc)
|
||||||
|
{
|
||||||
|
case XK_Return:
|
||||||
|
if (Paused)
|
||||||
|
cltr_video_play (video, NULL);
|
||||||
|
else
|
||||||
|
cltr_video_pause (video);
|
||||||
|
Paused ^= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -26,7 +54,7 @@ main (int argc, char *argv[])
|
|||||||
CltrFont *font;
|
CltrFont *font;
|
||||||
PixbufPixel col = { 0xff, 0xff, 0xff, 0x66 };
|
PixbufPixel col = { 0xff, 0xff, 0xff, 0x66 };
|
||||||
|
|
||||||
pixel_set_vals(&col, 0xff, 0x00, 0x00, 0xff);
|
pixel_set_vals(&col, 0x00, 0x00, 0x00, 0x99);
|
||||||
|
|
||||||
cltr_init (&argc, &argv);
|
cltr_init (&argc, &argv);
|
||||||
|
|
||||||
@ -45,13 +73,15 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
cltr_widget_add_child(win, video, 0, 0);
|
cltr_widget_add_child(win, video, 0, 0);
|
||||||
|
|
||||||
label = cltr_label_new("hello world", font, &col);
|
// label = cltr_label_new("hello world", font, &col);
|
||||||
|
|
||||||
cltr_widget_add_child(win, label, 100, 100);
|
// cltr_widget_add_child(win, label, 100, 300);
|
||||||
|
|
||||||
|
cltr_window_on_xevent(CLTR_WINDOW(win), handle_xevent, video);
|
||||||
|
|
||||||
cltr_widget_show_all(win);
|
cltr_widget_show_all(win);
|
||||||
|
|
||||||
cltr_video_play(CLTR_VIDEO(video));
|
cltr_video_play(CLTR_VIDEO(video), NULL);
|
||||||
|
|
||||||
cltr_main_loop();
|
cltr_main_loop();
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ int
|
|||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
CltrWidget *win = NULL, *grid = NULL, *test = NULL, *test2 = NULL;
|
CltrWidget *win = NULL, *grid = NULL, *test = NULL, *test2 = NULL, *list;
|
||||||
CltrFont *font = NULL;
|
CltrFont *font = NULL;
|
||||||
PixbufPixel col = { 0xff, 0, 0, 0xff };
|
PixbufPixel col = { 0xff, 0, 0, 0xff };
|
||||||
|
|
||||||
@ -53,24 +53,23 @@ main(int argc, char **argv)
|
|||||||
if (want_fullscreen)
|
if (want_fullscreen)
|
||||||
cltr_window_set_fullscreen(CLTR_WINDOW(win));
|
cltr_window_set_fullscreen(CLTR_WINDOW(win));
|
||||||
|
|
||||||
font = font_new("Sans 20");
|
font = font_new("Sans Bold 11");
|
||||||
|
|
||||||
test = cltr_button_new_with_label("ButtonBoooo\nd sfdsfdsfsss\nsjhsjhsjhs", font, &col);
|
test = cltr_button_new_with_label("ButtonBoooo\nd sfdsfdsfsss\nsjhsjhsjhs", font, &col);
|
||||||
|
|
||||||
test2 = cltr_button_new_with_label("Button", font, &col);
|
test2 = cltr_button_new_with_label("One Two", font, &col);
|
||||||
|
|
||||||
cltr_widget_add_child(win, test, 300, 100);
|
cltr_widget_add_child(win, test, 300, 100);
|
||||||
|
|
||||||
cltr_widget_add_child(win, test2, 100, 100);
|
cltr_widget_add_child(win, test2, 100, 100);
|
||||||
|
|
||||||
cltr_window_focus_widget(CLTR_WINDOW(win), test);
|
cltr_window_focus_widget(CLTR_WINDOW(win), test2);
|
||||||
|
|
||||||
cltr_widget_set_focus_next(test, test2, CLTR_EAST);
|
cltr_widget_set_focus_next(test, test2, CLTR_EAST);
|
||||||
cltr_widget_set_focus_next(test, test2, CLTR_WEST);
|
cltr_widget_set_focus_next(test, test2, CLTR_WEST);
|
||||||
cltr_widget_set_focus_next(test2, test, CLTR_EAST);
|
cltr_widget_set_focus_next(test2, test, CLTR_EAST);
|
||||||
cltr_widget_set_focus_next(test2, test, CLTR_WEST);
|
cltr_widget_set_focus_next(test2, test, CLTR_WEST);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
test = cltr_scratch_new(300, 100);
|
test = cltr_scratch_new(300, 100);
|
||||||
test2 = cltr_scratch_new(150, 150);
|
test2 = cltr_scratch_new(150, 150);
|
||||||
@ -83,12 +82,13 @@ main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
cltr_widget_add_child(win, test, 320, 240);
|
cltr_widget_add_child(win, test, 320, 240);
|
||||||
cltr_widget_add_child(win, test2, 400, 300);
|
cltr_widget_add_child(win, test2, 400, 300);
|
||||||
|
*/
|
||||||
|
|
||||||
list = cltr_list_new(640,480,640, 160);
|
list = cltr_list_new(640,480,640, 160);
|
||||||
|
|
||||||
cltr_widget_add_child(win, list, 0, 0);
|
cltr_widget_add_child(win, list, 0, 0);
|
||||||
|
|
||||||
*/
|
cltr_window_focus_widget(CLTR_WINDOW(win), list);
|
||||||
|
|
||||||
|
|
||||||
cltr_widget_show_all(win);
|
cltr_widget_show_all(win);
|
||||||
|
Loading…
Reference in New Issue
Block a user