diff --git a/ChangeLog b/ChangeLog index 22744a0a3..9688c036e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +2005-05-16 mallum,,, + + * clutter/cltr-animator.c: (cltr_animator_zoom_new), + (cltr_animator_fullzoom_new), (cltr_animator_new), + (cltr_animator_set_args), (cltr_animator_wrapped_paint): + * clutter/cltr-animator.h: + * clutter/cltr-list.c: (cltr_list_cell_new), + (cltr_list_get_active_cell_co_ords), (cltr_list_show), + (cltr_list_on_activate_cell), (cltr_list_update_layout), + (cltr_list_paint): + * clutter/cltr-list.h: + * clutter/cltr-texture.c: (cltr_texture_realize), + (cltr_texture_unref), (cltr_texture_sync_pixbuf), + (cltr_texture_force_rgb_data): + * clutter/cltr-video.c: (got_stream_length), (got_time_tick), + (got_state_change), (parse_stream_info), (cb_iterate), + (cltr_video_play), (cltr_video_set_volume), + (cltr_video_get_volume), (cltr_video_get_pixbuf), + (cltr_video_idler), (cltr_video_set_source), + (cltr_video_handle_xevent), (cltr_video_paint): + * clutter/cltr-video.h: + * clutter/cltr-widget.c: + * clutter/pixbuf.c: (pixbuf_write_png), (load_png_file), + (pixbuf_copy), (pixbuf_fill_rect), (pixbuf_scale_down), + (pixbuf_clone): + * examples/select.c: (usage), (populate), (cell_to_item), + (handle_xevent), (zoom_out_complete), (zoom_in_complete), + (cell_activated), (main): + * gst/cltrimagesink.c: (gst_cltrimagesink_getcaps), + (gst_cltrimagesink_chain): + Far too much hacking. Fix many endian image issues. + Greatly improve select demo + 2005-05-16 mallum,,, * clutter/Makefile.am: diff --git a/clutter/cltr-animator.c b/clutter/cltr-animator.c index 120770a4e..ce5aa0a3f 100644 --- a/clutter/cltr-animator.c +++ b/clutter/cltr-animator.c @@ -13,13 +13,49 @@ struct CltrAnimator WidgetPaintMethod wrapped_paint_func; - int zoom_init_x1, zoom_init_y1, zoom_init_x2, zoom_init_y2; - int zoom_dest_x1, zoom_dest_y1, zoom_dest_x2, zoom_dest_y2; + int zoom_end_x1, zoom_end_y1, zoom_end_x2, zoom_end_y2; + int zoom_start_x1, zoom_start_y1, zoom_start_x2, zoom_start_y2; }; static void cltr_animator_wrapped_paint(CltrWidget *widget); +CltrAnimator* +cltr_animator_zoom_new(CltrWidget *widget, + int src_x1, + int src_y1, + int src_x2, + int src_y2, + int dst_x1, + int dst_y1, + int dst_x2, + int dst_y2) +{ + CltrAnimator *anim = g_malloc0(sizeof(CltrAnimator)); + + anim->zoom_end_x1 = dst_x1; + anim->zoom_end_x2 = dst_x2; + anim->zoom_end_y1 = dst_y1; + anim->zoom_end_y2 = dst_y2; + + anim->zoom_start_x1 = src_x1; + anim->zoom_start_x2 = src_x2; + anim->zoom_start_y1 = src_y1; + anim->zoom_start_y2 = src_y2; + + anim->wrapped_paint_func = widget->paint; + + anim->widget = widget; + widget->anim = anim; + + anim->n_steps = 10; + anim->step = 0; + anim->fps = 50; + + return anim; +} + + CltrAnimator* cltr_animator_fullzoom_new(CltrWidget *widget, int x1, @@ -29,15 +65,15 @@ cltr_animator_fullzoom_new(CltrWidget *widget, { CltrAnimator *anim = g_malloc0(sizeof(CltrAnimator)); - anim->zoom_init_x1 = x1; - anim->zoom_init_x2 = x2; - anim->zoom_init_y1 = y1; - anim->zoom_init_y2 = y2; + anim->zoom_end_x1 = x1; + anim->zoom_end_x2 = x2; + anim->zoom_end_y1 = y1; + anim->zoom_end_y2 = y2; - anim->zoom_dest_x1 = cltr_widget_abs_x(widget); - anim->zoom_dest_x2 = cltr_widget_abs_x2(widget); - anim->zoom_dest_y1 = cltr_widget_abs_y(widget); - anim->zoom_dest_y2 = cltr_widget_abs_y2(widget); + anim->zoom_start_x1 = cltr_widget_abs_x(widget); + anim->zoom_start_x2 = cltr_widget_abs_x2(widget); + anim->zoom_start_y1 = cltr_widget_abs_y(widget); + anim->zoom_start_y2 = cltr_widget_abs_y2(widget); anim->wrapped_paint_func = widget->paint; @@ -75,16 +111,18 @@ cltr_animator_wrapped_paint(CltrWidget *widget) float f = (float)anim->step/anim->n_steps; - int init_width = anim->zoom_init_x2 - anim->zoom_init_x1; - int dest_width = anim->zoom_dest_x2 - anim->zoom_dest_x1; + int end_width = anim->zoom_end_x2 - anim->zoom_end_x1; + int start_width = anim->zoom_start_x2 - anim->zoom_start_x1; - int init_height = anim->zoom_init_y2 - anim->zoom_init_y1; - int dest_height = anim->zoom_dest_y2 - anim->zoom_dest_y1; + int end_height = anim->zoom_end_y2 - anim->zoom_end_y1; + int start_height = anim->zoom_start_y2 - anim->zoom_start_y1; - float max_zoom_x = (float)dest_width/init_width; - float max_zoom_y = (float)dest_height/init_height; + float max_zoom_x = (float)start_width/end_width; + float max_zoom_y = (float)start_height/end_height; - float trans_y = ((float)anim->zoom_init_y1); + float trans_y = ((float)anim->zoom_end_y1); + + CLTR_MARK(); glPushMatrix(); @@ -93,7 +131,7 @@ cltr_animator_wrapped_paint(CltrWidget *widget) (f * max_zoom_x), (f * max_zoom_y)); #if 0 - glTranslatef (0.0 /* - (float)(anim->zoom_dest_x1) * ( (max_zoom_x * f) )*/, + glTranslatef (0.0 /* - (float)(anim->zoom_start_x1) * ( (max_zoom_x * f) )*/, - trans_y * f * max_zoom_y, 0.0); @@ -112,17 +150,17 @@ cltr_animator_wrapped_paint(CltrWidget *widget) /* 800 -> 80, 800-80 = 720/n_steps = x , cur = 80 + x * (n_steps - steps) */ - x2 = anim->zoom_init_x2 + ( ( ((float)anim->zoom_dest_x2 - anim->zoom_init_x2)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); + x2 = anim->zoom_end_x2 + ( ( ((float)anim->zoom_start_x2 - anim->zoom_end_x2)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); - x1 = anim->zoom_init_x1 + ( ( ((float)anim->zoom_dest_x1 - anim->zoom_init_x1)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); + x1 = anim->zoom_end_x1 + ( ( ((float)anim->zoom_start_x1 - anim->zoom_end_x1)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); - y1 = anim->zoom_init_y1 + ( ( ((float)anim->zoom_dest_y1 - anim->zoom_init_y1)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); + y1 = anim->zoom_end_y1 + ( ( ((float)anim->zoom_start_y1 - anim->zoom_end_y1)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); - y2 = anim->zoom_init_y2 + ( ( ((float)anim->zoom_dest_y2 - anim->zoom_init_y2)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); + y2 = anim->zoom_end_y2 + ( ( ((float)anim->zoom_start_y2 - anim->zoom_end_y2)/ (float)anim->n_steps) * (anim->n_steps - anim->step) ); /* - glOrtho( anim->zoom_init_x1, x2-1, - anim->zoom_init_y2-1, anim->zoom_init_y1, + glOrtho( anim->zoom_end_x1, x2-1, + anim->zoom_end_y2-1, anim->zoom_end_y1, -1, 1); */ @@ -139,16 +177,37 @@ cltr_animator_wrapped_paint(CltrWidget *widget) /* reset here */ } +/* Hack, we need somehow to reset the viewport + * XXX Hook this into anim->widget hide() + * XXX Call this every time for every render ? +*/ +void +cltr_animator_reset(CltrAnimator *anim) +{ + ClutterMainContext *ctx = CLTR_CONTEXT(); + + clrt_window_set_gl_viewport(ctx->window); +} + static gboolean cltr_animator_timeout_cb(gpointer data) { CltrAnimator *anim = (CltrAnimator *)data; + CLTR_MARK(); + anim->step++; if (anim->step > anim->n_steps) - return FALSE; + { + if (anim->anim_finish_cb) + anim->anim_finish_cb(anim, anim->anim_finish_data); + + anim->widget->paint = anim->wrapped_paint_func; + + return FALSE; + } cltr_widget_queue_paint(anim->widget); diff --git a/clutter/cltr-animator.h b/clutter/cltr-animator.h index 8783e764a..c6bbb9db0 100644 --- a/clutter/cltr-animator.h +++ b/clutter/cltr-animator.h @@ -13,6 +13,17 @@ CltrAnimatorType; typedef void (*CltrAnimatorFinishFunc) (CltrAnimator *anim, void *userdata) ; +CltrAnimator* +cltr_animator_zoom_new(CltrWidget *widget, + int src_x1, + int src_y1, + int src_x2, + int src_y2, + int dst_x1, + int dst_y1, + int dst_x2, + int dst_y2); + CltrAnimator* cltr_animator_fullzoom_new(CltrWidget *widget, int x1, @@ -20,6 +31,10 @@ cltr_animator_fullzoom_new(CltrWidget *widget, int x2, int y2); +/* HACK */ +void +cltr_animator_reset(CltrAnimator *anim); + void cltr_animator_run(CltrAnimator *anim, CltrAnimatorFinishFunc finish_callback, diff --git a/clutter/cltr-list.c b/clutter/cltr-list.c index 8d04ff2d9..be517bccd 100644 --- a/clutter/cltr-list.c +++ b/clutter/cltr-list.c @@ -79,6 +79,18 @@ cltr_list_cell_new(CltrList *list, return cell; } +void +cltr_list_cell_set_pixbuf(CltrListCell *cell, + Pixbuf *thumb_pixb) +{ + cltr_texture_unref(cell->thumb_texture); + + cell->thumb_pixb = thumb_pixb; + + cell->thumb_texture = cltr_texture_new(cell->thumb_pixb); + +} + CltrWidget* cltr_list_new(int width, int height, @@ -145,20 +157,16 @@ cltr_list_show(CltrWidget *widget) CltrList *list = CLTR_LIST(widget); CltrListCell *cell = NULL; - list->active_cell_y = (widget->height / 2) - (list->cell_height/2); - - /* - for (i=0; iactive_cell_y == 0) { - list->cells = g_list_append(list->cells, cltr_list_cell_new(list)); + list->active_cell_y = (widget->height / 2) - (list->cell_height/2); + + list->active_cell = g_list_first(list->cells); + + cell = list->active_cell->data; + + cell->rect.y = list->active_cell_y; } - */ - - list->active_cell = g_list_first(list->cells); - - cell = list->active_cell->data; - - cell->rect.y = list->active_cell_y; list->state = CLTR_LIST_STATE_BROWSE; @@ -176,6 +184,14 @@ cltr_list_on_activate_cell(CltrList *list, list->cell_activate_data = userdata; } +CltrListCell* +cltr_list_get_active_cell(CltrList *list) +{ + if (list->active_cell) + return list->active_cell->data; + + return NULL; +} static gboolean cltr_list_handle_xevent (CltrWidget *widget, XEvent *xev) @@ -354,6 +370,8 @@ cltr_list_paint(CltrWidget *widget) int last; + CLTR_MARK(); + cell_item = g_list_first(list->cells); cell = (CltrListCell *)cell_item->data; last = cell->rect.y; diff --git a/clutter/cltr-list.h b/clutter/cltr-list.h index 18df79a24..4ef7f317a 100644 --- a/clutter/cltr-list.h +++ b/clutter/cltr-list.h @@ -28,6 +28,10 @@ cltr_list_cell_new(CltrList *list, Pixbuf *thump_pixb, char *text); +void +cltr_list_cell_set_pixbuf(CltrListCell *cell, + Pixbuf *thump_pixb); + void cltr_list_append_cell(CltrList *list, CltrListCell *cell); @@ -37,6 +41,9 @@ cltr_list_new(int width, int cell_width, int cell_height); +CltrListCell* +cltr_list_get_active_cell(CltrList *list); + void cltr_list_on_activate_cell(CltrList *list, CltrListCellActivate callback, diff --git a/clutter/cltr-texture.c b/clutter/cltr-texture.c index f07d2ce11..1c5177f67 100644 --- a/clutter/cltr-texture.c +++ b/clutter/cltr-texture.c @@ -292,7 +292,7 @@ cltr_texture_realize(CltrTexture *texture) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + /* glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); */ glTexImage2D(GL_TEXTURE_2D, 0, /*GL_COMPRESSED_RGBA_ARB*/ GL_RGBA, texture->width, @@ -360,7 +360,8 @@ cltr_texture_realize(CltrTexture *texture) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - /* glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_); */ +glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + /* glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); */ /* glPixelStorei (GL_UNPACK_ALIGNMENT, 4); */ /* glPixelStorei (GL_UNPACK_ROW_LENGTH, texture->tile_x_size[x]); */ @@ -427,8 +428,9 @@ cltr_texture_unref(CltrTexture *texture) if (texture->refcnt <= 0) { cltr_texture_unrealize(texture); + if (texture->pixb) + pixbuf_unref(texture->pixb); g_free(texture); - pixbuf_unref(texture->pixb); } } @@ -488,6 +490,9 @@ cltr_texture_sync_pixbuf(CltrTexture* texture) } else { + if (!texture->tiles) + cltr_texture_realize(texture); + glBindTexture(GL_TEXTURE_2D, texture->tiles[0]); glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, @@ -524,6 +529,8 @@ cltr_texture_force_rgb_data(CltrTexture *texture, glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height, - GL_RGB, GL_UNSIGNED_BYTE, + GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data); + + CLTR_GLERR(); } diff --git a/clutter/cltr-video.c b/clutter/cltr-video.c index b0c75ebcc..a1fbe9dc7 100644 --- a/clutter/cltr-video.c +++ b/clutter/cltr-video.c @@ -105,9 +105,10 @@ got_stream_length (GstElement *play, { video->stream_length = (gint64) length_nanos / GST_MSECOND; + CLTR_MARK(); /* fire off some callback here ? */ - CLTR_DBG("length: %i", video->stream_length); + CLTR_DBG("length: %li", video->stream_length); } static void @@ -128,6 +129,8 @@ got_time_tick (GstElement *play, video->current_position = (float) video->current_time / video->stream_length; } + CLTR_DBG("current pos is %f\n", video->current_position); + /* fire off callback here */ } @@ -168,6 +171,7 @@ got_state_change (GstElement *play, g_idle_remove_by_data (video); + } else if (new_state == GST_STATE_PLAYING) { @@ -188,6 +192,10 @@ got_state_change (GstElement *play, video->has_video = FALSE; video->has_audio = FALSE; + /* blank the texture */ + + /* while (g_async_queue_try_pop (video->queue)) ; */ + /* if (bvw->priv->tagcache) { @@ -196,7 +204,7 @@ got_state_change (GstElement *play, } */ - video->video_width = 0; + video->video_width = 0; video->video_height = 0; } } @@ -463,6 +471,8 @@ cb_iterate (CltrVideo *video) GstFormat fmt = GST_FORMAT_TIME; gint64 value; + CLTR_MARK(); + /* check length/pos of stream */ if (gst_element_query (GST_ELEMENT (video->play), GST_QUERY_TOTAL, &fmt, &value) @@ -606,6 +616,14 @@ cltr_video_play ( CltrVideo *video, GError ** error) return ret; } +gint64 +cltr_video_get_time (CltrVideo *video) +{ + CLTR_DBG("current pos is %f\n", video->current_position); + + return video->current_time; +} + gboolean cltr_video_seek (CltrVideo *video, float position, GError **gerror) { @@ -692,6 +710,22 @@ cltr_video_get_volume ( CltrVideo *video) return (gint) (vol * 100 + 0.5); } +Pixbuf* +cltr_video_get_pixbuf (CltrVideo *video) +{ + Pixbuf *pixb = NULL; + + if (video->frame_texture) + { + cltr_texture_lock(video->frame_texture); + + pixb = pixbuf_clone(cltr_texture_get_pixbuf(video->frame_texture)); + + cltr_texture_unlock(video->frame_texture); + } + + return pixb; +} static gboolean cltr_video_idler (CltrVideo *video) @@ -714,13 +748,8 @@ cltr_video_idler (CltrVideo *video) cltr_texture_lock(video->frame_texture); - pixb = cltr_texture_get_pixbuf(video->frame_texture); - - if (pixb) - cltr_texture_force_rgb_data(video->frame_texture, - pixb->width, - pixb->height, - pixb->data); + if (cltr_texture_get_pixbuf(video->frame_texture)) + cltr_texture_sync_pixbuf(video->frame_texture); cltr_texture_unlock(video->frame_texture); @@ -791,7 +820,6 @@ cltr_video_set_source(CltrVideo *video, char *mrl) g_object_set (G_OBJECT (video->play), "uri", video->mrl, "suburi", NULL, NULL); - ret = (gst_element_set_state (video->play, GST_STATE_PAUSED) == GST_STATE_SUCCESS); @@ -816,7 +844,6 @@ cltr_video_set_source(CltrVideo *video, char *mrl) */ return ret; - } @@ -863,30 +890,29 @@ cltr_video_paint(CltrWidget *widget) dis_x = 0; } - - // glEnable(GL_BLEND); - - // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glColor4f(1.0, 1.0, 1.0, 1.0); - glEnable(GL_TEXTURE_2D); - // glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + /* + glEnable(GL_BLEND); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + */ + + glColor4f(1.0, 1.0, 1.0, 1.0); cltr_texture_lock(video->frame_texture); cltr_texture_render_to_gl_quad(video->frame_texture, - dis_x, - dis_y, - dis_x + dis_width, - dis_y + dis_height); + widget->x + dis_x, + widget->y + dis_y, + widget->x + dis_x + dis_width, + widget->y + dis_y + dis_height); cltr_texture_unlock(video->frame_texture); glDisable(GL_TEXTURE_2D); - // glDisable(GL_BLEND); + glDisable(GL_BLEND); // glColor4f(1.0, 1.0, 1.0, 0.5); diff --git a/clutter/cltr-video.h b/clutter/cltr-video.h index 165af5256..49754ef04 100644 --- a/clutter/cltr-video.h +++ b/clutter/cltr-video.h @@ -69,6 +69,9 @@ cltr_video_set_source(CltrVideo *video, char *location); gboolean cltr_video_play ( CltrVideo *video, GError ** Error); +gint64 +cltr_video_get_time (CltrVideo *video); + gboolean cltr_video_seek (CltrVideo *video, float position, GError **gerror); @@ -93,5 +96,8 @@ cltr_video_set_volume ( CltrVideo *video, int volume); int cltr_video_get_volume ( CltrVideo *video); +Pixbuf* +cltr_video_get_pixbuf (CltrVideo *video); + #endif diff --git a/clutter/cltr-widget.c b/clutter/cltr-widget.c index fb1349ec4..0cf9cb508 100644 --- a/clutter/cltr-widget.c +++ b/clutter/cltr-widget.c @@ -219,6 +219,9 @@ cltr_widget_queue_paint(CltrWidget *widget) gboolean cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev) { + if (!widget->visible) + return FALSE; + if (widget && widget->xevent_handler) return widget->xevent_handler(widget, xev); diff --git a/clutter/pixbuf.c b/clutter/pixbuf.c index 764958ed7..d23594a21 100644 --- a/clutter/pixbuf.c +++ b/clutter/pixbuf.c @@ -21,6 +21,111 @@ #define CLTR_CLAMP(x, y) ((x) > (y)) ? (y) : (x); +static void +fix_png_write_data (png_structp png, + png_row_infop row_info, + png_bytep data) +{ + int i; + + for (i = 0; i < row_info->rowbytes; i += 4) + { + unsigned char *b = &data[i]; + unsigned int pixel; + + memcpy (&pixel, b, sizeof (unsigned int)); + + b[0] = (pixel >> 24) & 0xff; + b[1] = (pixel >> 16) & 0xff; + b[2] = (pixel >> 8) & 0xff; + b[3] = pixel & 0xff; + } +} + +static void +fix_png_read_data (png_structp png, + png_row_infop row_info, + png_bytep data) +{ + int i; + + for (i = 0; i < row_info->rowbytes; i += 4) + { + unsigned char *b = &data[i]; + unsigned int pixel; + + memcpy (&pixel, b, sizeof (unsigned int)); + + b[0] = (pixel >> 24) & 0xff; + b[1] = (pixel >> 16) & 0xff; + b[2] = (pixel >> 8) & 0xff; + b[3] = pixel & 0xff; + } +} + +int +pixbuf_write_png(Pixbuf *pixb, char *filename) +{ + FILE *f; + int i; + png_struct *png; + png_info *info; + png_byte **rows; + png_color_16 white; + + f = fopen (filename, "w"); + + rows = malloc (pixb->height * sizeof(png_byte*)); + + for (i = 0; i < pixb->height; i++) + { + rows[i] = pixb->data + (i * (pixb->width)); + } + + png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + info = png_create_info_struct (png); + + png_init_io (png, f); + + png_set_IHDR (png, info, + pixb->width, pixb->height, 8, + PNG_COLOR_TYPE_RGB_ALPHA, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + white.red = 0xff; + white.blue = 0xff; + white.green = 0xff; + png_set_bKGD (png, info, &white); + + /* png_set_write_user_transform_fn (png, unpremultiply_data); */ + + /* png_set_bgr (png); */ + + /* png_set_filler(png, 0, PNG_FILLER_BEFORE); */ + + /* + png_set_packswap(png); + + png_set_swap(png); + */ + + png_set_write_user_transform_fn (png, fix_png_write_data); + + png_write_info (png, info); + png_write_image (png, rows); + png_write_end (png, info); + + png_destroy_write_struct (&png, &info); + + free (rows); + fclose (f); + + return 1; +} + static int* load_png_file( const char *file, int *width, @@ -97,12 +202,18 @@ load_png_file( const char *file, if (( color_type == PNG_COLOR_TYPE_GRAY ) || ( color_type == PNG_COLOR_TYPE_RGB )) png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_BEFORE); /* req 1.2.7 */ + else /* */ + { + if (( color_type == PNG_COLOR_TYPE_PALETTE )|| + ( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS ))) + png_set_expand(png_ptr); - if (( color_type == PNG_COLOR_TYPE_PALETTE )|| - ( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS ))) - png_set_expand(png_ptr); + /* Needed to fix endianess */ + png_set_read_user_transform_fn (png_ptr, fix_png_read_data); + } - png_set_packswap(png_ptr); + + /* png_set_packswap(png_ptr); */ png_read_update_info( png_ptr, info_ptr); @@ -686,6 +797,9 @@ pixbuf_clone(Pixbuf *pixb) { Pixbuf *clone; + if (pixb == NULL) + return NULL; + clone = util_malloc0(sizeof(Pixbuf)); clone->width = pixb->width; diff --git a/examples/select.c b/examples/select.c index 6bfa5926e..5201fb2c2 100644 --- a/examples/select.c +++ b/examples/select.c @@ -1,5 +1,29 @@ #include +typedef struct ItemEntry ItemEntry; + +typedef struct DemoApp +{ + CltrAnimator *anim; + CltrWidget *list; + CltrWidget *video; + CltrWidget *win; + + GList *items; + +} DemoApp; + +struct ItemEntry +{ + gchar *nice_name; + gchar *path; + gchar *uri; + CltrListCell *cell; +}; + +static void +zoom_out_complete (CltrAnimator *anim, void *userdata); + int usage(char *progname) { @@ -7,14 +31,15 @@ usage(char *progname) exit(-1); } + gboolean -populate(CltrList *list, char *path) +populate(DemoApp *app, char *path) { GDir *dir; GError *error; const gchar *entry = NULL; int n_pixb = 0, i =0; - + CltrList *list = CLTR_LIST(app->list); Pixbuf *default_thumb_pixb = NULL; default_thumb_pixb = pixbuf_new_from_file("clutter-logo-800x600.png"); @@ -33,33 +58,49 @@ populate(CltrList *list, char *path) while ((entry = g_dir_read_name (dir)) != NULL) { - Pixbuf *pixb = default_thumb_pixb; - CltrListCell *cell; - gchar *nice_name = NULL; + Pixbuf *pixb = NULL; gint i = 0; + ItemEntry *new_item; + char *img_path; if (!(g_str_has_suffix (entry, ".mpg") || g_str_has_suffix (entry, ".MPG") || g_str_has_suffix (entry, ".mpg4") || g_str_has_suffix (entry, ".MPG4") || g_str_has_suffix (entry, ".avi") || + g_str_has_suffix (entry, ".mov") || + g_str_has_suffix (entry, ".MOV") || g_str_has_suffix (entry, ".AVI"))) { continue; } - nice_name = g_strdup(entry); + new_item = g_malloc0(sizeof(ItemEntry)); - i = strlen(nice_name) - 1; - while (i-- && nice_name[i] != '.') ; + new_item->nice_name = g_strdup(entry); + + i = strlen(new_item->nice_name) - 1; + while (i-- && new_item->nice_name[i] != '.') ; if (i > 0) - nice_name[i] = '\0'; + new_item->nice_name[i] = '\0'; - cell = cltr_list_cell_new(list, pixb, nice_name); + img_path = g_strconcat(path, "/", new_item->nice_name, ".png", NULL); - cltr_list_append_cell(list, cell); + pixb = pixbuf_new_from_file(img_path); - g_free(nice_name); + if (!pixb) + pixb = default_thumb_pixb; + + new_item->cell = cltr_list_cell_new(list, pixb, new_item->nice_name); + + cltr_list_append_cell(list, new_item->cell); + + new_item->uri = g_strconcat("file://", path, "/", entry, NULL); + new_item->path = g_strdup(path); + + app->items = g_list_append(app->items, new_item); + + g_free(img_path); g_printf("."); } @@ -71,19 +112,175 @@ populate(CltrList *list, char *path) return TRUE; } +ItemEntry* +cell_to_item(DemoApp *app, CltrListCell *cell) +{ + GList *item = NULL; + + item = g_list_first(app->items); + + while (item) + { + ItemEntry *entry = item->data; + + if (entry->cell == cell) + return entry; + + item = g_list_next(item); + } + + return NULL; +} + + + +void +handle_xevent(CltrWidget *win, XEvent *xev, void *cookie) +{ + KeySym kc; + DemoApp *app = (DemoApp*)cookie; + + if (xev->type == KeyPress) + { + XKeyEvent *xkeyev = &xev->xkey; + + kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0); + + switch (kc) + { + case XK_Return: + { + ItemEntry *item; + char filename[1024]; + Pixbuf *spixb, *dpixb; + int dstx, dsty, dstw, dsth; + PixbufPixel col = { 0, 0, 0, 0xff }; + int x1, y1, x2, y2; + + // cltr_video_pause (CLTR_VIDEO(app->video)); + + item = cell_to_item(app, cltr_list_get_active_cell(app->list)); + + snprintf(filename, 1024, "%s/%s.png", item->path, item->nice_name); + + spixb = cltr_video_get_pixbuf (app->video); + + /* fixup pixbuf so scaled like video + * + */ + + /* XXX wrongly assume width > height */ + + dstw = spixb->width; + + dsth = (spixb->width * cltr_widget_height(win)) + / cltr_widget_width(win) ; + + printf("dsth %i, spixb h %i\n", dsth, spixb->height); + + dsty = (dsth - spixb->height)/2; dstx = 0; + + dpixb = pixbuf_new(dstw, dsth); + pixbuf_fill_rect(dpixb, 0, 0, -1, -1, &col); + pixbuf_copy(spixb, dpixb, 0, 0, + spixb->width, spixb->height, dstx, dsty); + + cltr_list_cell_set_pixbuf(cltr_list_get_active_cell(app->list), + dpixb); + + pixbuf_write_png(dpixb, filename); + + + /* reset the viewing pixbuf */ + + pixbuf_unref(dpixb); + + cltr_list_get_active_cell_co_ords(CLTR_LIST(app->list), + &x1, &y1, &x2, &y2); + + + cltr_video_stop (CLTR_VIDEO(app->video)); + + /* zoom out, XXX old anim needs freeing */ + + app->anim = cltr_animator_zoom_new(app->list, + x1, y1, x1+80, y1+60, + 0,0,800,600); + + printf("got return, seek time %li, %i, %i \n", + cltr_video_get_time (CLTR_VIDEO(app->video)), + x1, y1); + + cltr_widget_show(app->list); + + cltr_animator_run(app->anim, zoom_out_complete, app); + } + break; + } + } + +} + +static void +zoom_out_complete (CltrAnimator *anim, void *userdata) +{ + DemoApp *app = (DemoApp*)userdata; + + cltr_window_on_xevent(CLTR_WINDOW(app->win), NULL, NULL); + + + + cltr_widget_hide(app->video); + + cltr_widget_queue_paint(app->win); +} + +void +zoom_in_complete (CltrAnimator *anim, void *userdata) +{ + DemoApp *app = (DemoApp*)userdata; + ItemEntry *item; + + cltr_widget_hide(CLTR_WIDGET(app->list)); + + /* cltr_animator_reset(anim); */ + + item = cell_to_item(app, cltr_list_get_active_cell(app->list)); + + cltr_video_set_source(CLTR_VIDEO(app->video), item->uri); + + cltr_video_play(CLTR_VIDEO(app->video), NULL); + + cltr_widget_show(app->video); + + cltr_window_on_xevent(CLTR_WINDOW(app->win), handle_xevent, app); +} + void cell_activated (CltrList *list, CltrListCell *cell, void *userdata) { + DemoApp *app = (DemoApp*)userdata; int x1, y1, x2, y2; - CltrAnimator *anim = NULL; + static have_added_child = 0; /* HACK */ cltr_list_get_active_cell_co_ords(CLTR_LIST(list), &x1, &y1, &x2, &y2); - anim = cltr_animator_fullzoom_new(CLTR_LIST(list), x1, y1, x1+80, y1+60); + app->anim = cltr_animator_zoom_new(CLTR_WIDGET(list), + 0,0,800,600, + x1, y1, x1+80, y1+60); - cltr_animator_run(anim, NULL, NULL); + if (!have_added_child) + cltr_widget_add_child(app->win, app->video, x1, y1); + else + { + printf("x1: %i, y1: %i\n", x1, y1); + } + + have_added_child = 1; + + cltr_animator_run(app->anim, zoom_in_complete, app); } int @@ -98,7 +295,7 @@ main(int argc, char **argv) gboolean want_fullscreen = FALSE; gint cols = 3; - CltrAnimator *anim = NULL; + DemoApp *app; cltr_init(&argc, &argv); @@ -135,23 +332,29 @@ main(int argc, char **argv) exit(-1); } - win = cltr_window_new(800, 600); + app = g_malloc0(sizeof(DemoApp)); + + app->win = cltr_window_new(800, 600); if (want_fullscreen) - cltr_window_set_fullscreen(CLTR_WINDOW(win)); + cltr_window_set_fullscreen(CLTR_WINDOW(app->win)); - list = cltr_list_new(800, 600, 800, 600/5); + app->list = cltr_list_new(800, 600, 800, 600/5); - if (!populate(list, movie_path)) + if (!populate(app, movie_path)) exit(-1); - cltr_widget_add_child(win, list, 0, 0); + cltr_widget_add_child(app->win, app->list, 0, 0); - cltr_window_focus_widget(CLTR_WINDOW(win), list); + app->video = cltr_video_new(80, 60); - cltr_widget_show_all(win); + cltr_window_focus_widget(CLTR_WINDOW(app->win), app->list); - cltr_list_on_activate_cell(CLTR_LIST(list), cell_activated, NULL); + cltr_widget_show_all(app->win); + cltr_widget_hide(app->video); + + cltr_list_on_activate_cell(CLTR_LIST(app->list), + cell_activated, (gpointer)app); cltr_main_loop(); } diff --git a/gst/cltrimagesink.c b/gst/cltrimagesink.c index 6fb2b6e25..7643fd417 100644 --- a/gst/cltrimagesink.c +++ b/gst/cltrimagesink.c @@ -162,8 +162,8 @@ gst_cltrimagesink_getcaps (GstPad * pad) "endianness", G_TYPE_INT, G_BIG_ENDIAN, /* "red_mask", G_TYPE_INT, 0xff0000, - "green_mask", G_TYPE_INT, 0x0000ff, - "blue_mask", G_TYPE_INT, 0x00ff00, + "green_mask", G_TYPE_INT, 0x00ff00, + "blue_mask", G_TYPE_INT, 0x0000ff, */ "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, @@ -331,10 +331,24 @@ gst_cltrimagesink_chain (GstPad * pad, GstData * data) if (pixb) { + int i = 0; + guint8 *d = GST_BUFFER_DATA (buf); + for (i = 0; i < pixb->height * pixb->width; i++) + { + int r,g,b, a; + r = *d++; g = *d++; b = *d++; a = 0xff; + pixb->data[i] = ((r << 24) | + (g << 16) | + (b << 8) | + a ); + } + + /* memcpy (pixb->data, GST_BUFFER_DATA (buf), MIN (GST_BUFFER_SIZE (buf), pixb->bytes_per_line * pixb->width)); + */ /* Below faster but threading issues causing DRI to bomb out */