diff --git a/ChangeLog b/ChangeLog index 49fac1b8ec..d7411d85c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Sat Apr 18 11:37:46 PDT 1998 Manish Singh + + * plug-ins/dbbrowser/dbbrowser_util.c: make text entry for function + name read-only + + * plug-ins/film/film.c + * plug-ins/animationplay/animationplay.c: minor cleanups + Thu Apr 16 19:46:46 MEST 1998 Sven Neumann * plug-ins/script-fu/interp_slib.c: changed the link to diff --git a/Makefile.am b/Makefile.am index 127efe3446..4f66776429 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = libgimp plug-ins app data -EXTRA_DIST = TODO NOTES gtkrc gimp_logo.ppm gimp_splash.ppm rmshm user_install gimp_tips.txt ps-menurc +EXTRA_DIST = TODO NOTES gtkrc gimp_logo.ppm gimp_splash.ppm rmshm user_install gimp_tips.txt ps-menurc gimp.spec gimpdata_DATA = gimprc gimprc_user gtkrc gimp_logo.ppm gimp_splash.ppm gimp_tips.txt ps-menurc diff --git a/libgimp/gimpprocbrowserdialog.c b/libgimp/gimpprocbrowserdialog.c index b51a4ca4fb..ba85d89726 100644 --- a/libgimp/gimpprocbrowserdialog.c +++ b/libgimp/gimpprocbrowserdialog.c @@ -268,6 +268,7 @@ dialog_select (dbbrowser_t *dbbrowser, label = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(label),dbbrowser->selected_scheme_proc_name); + gtk_entry_set_editable(GTK_ENTRY(label), FALSE); gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label, 1, 4, row, row+1, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); diff --git a/libgimp/gimpprocview.c b/libgimp/gimpprocview.c index b51a4ca4fb..ba85d89726 100644 --- a/libgimp/gimpprocview.c +++ b/libgimp/gimpprocview.c @@ -268,6 +268,7 @@ dialog_select (dbbrowser_t *dbbrowser, label = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(label),dbbrowser->selected_scheme_proc_name); + gtk_entry_set_editable(GTK_ENTRY(label), FALSE); gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label, 1, 4, row, row+1, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); diff --git a/plug-ins/animationplay/animationplay.c b/plug-ins/animationplay/animationplay.c index 773398d1ce..245444ff89 100644 --- a/plug-ins/animationplay/animationplay.c +++ b/plug-ins/animationplay/animationplay.c @@ -1,16 +1,30 @@ /* - * Animation Playback plug-in version 0.85.0 + * Animation Playback plug-in version 0.94.0 * - * by Adam D. Moss, 1997-98 - * adam@gimp.org - * adam@foxbox.org + * Adam D. Moss : 1997-98 : adam@gimp.org : adam@foxbox.org * - * This is part of the GIMP package and falls under the GPL. + * + * This is part of the GIMP package and is released under the GNU + * Public License. */ /* * REVISION HISTORY: * + * 98.04.05 : version 0.94.0 + * Improved performance and removed flicker when shaped. + * Shaped mode also works with RGB* images now. + * Fixed some longstanding potential visual debris. + * + * 98.04.04 : version 0.92.0 + * Improved responsiveness and performance for the new + * shaped-animation mode. Still some flicker. + * + * 98.04.02 : version 0.90.0 + * EXPERIMENTAL wackyness - try dragging the animation + * out of the plugin dialog's preview box... + * (only works on non-RGB* images for now) + * * 98.03.16 : version 0.85.0 * Implemented some more rare opaque/alpha combinations. * @@ -44,10 +58,15 @@ /* * BUGS: - * Leaks memory. Not sure why. * Gets understandably upset if the source image is deleted - * while the animation is playing. - * Decent solutions to either of the above are most welcome. + * while the animation is playing. Decent solution welcome. + * + * In shaped mode, the shaped-window's mask and its pixmap contents + * can get way out of sync (specifically, the mask changes but + * the contents are frozen). Starvation of GTK's redrawing thread? + * How do I fix this? + * + * Often segfaults on exit. GTK stuff. Help. * * Any more? Let me know! */ @@ -55,8 +74,11 @@ /* * TODO: * pdb interface - should we bother? + * * speedups (caching? most bottlenecks seem to be in pixelrgns) - * write other half of the user interface + * -> do pixelrgns properly! + * + * write other half of the user interface (default timing, disposal &c) */ #include @@ -64,6 +86,7 @@ #include #include #include "libgimp/gimp.h" +#include "gdk/gdkx.h" #include "gtk/gtk.h" @@ -105,6 +128,7 @@ static void total_alpha_preview (void); static void init_preview_misc (void); + GPlugInInfo PLUG_IN_INFO = { NULL, /* init_proc */ @@ -136,6 +160,20 @@ gint ncolours; +/* for shaping */ +guchar *shape_preview_mask; +GtkWidget *shape_window; +GtkWidget *shape_fixed; +GtkPreview *shape_preview; +GdkPixmap *shape_pixmap; +typedef struct _cursoroffset {gint x,y;} CursorOffset; +gint shaping = 0; +static GdkWindow *root_win = NULL; + + + + + MAIN() @@ -156,7 +194,7 @@ static void query() "", "Adam D. Moss ", "Adam D. Moss ", - "1997", + "1997, 1998...", "/Filters/Animation/Animation Playback", "RGB*, INDEXED*, GRAY*", PROC_PLUG_IN, @@ -255,6 +293,188 @@ parse_disposal_tag (char *str) } +static void +reshape_from_bitmap(guchar* bitmap) +{ + GdkBitmap *shape_mask; + + shape_mask = gdk_bitmap_create_from_data(shape_window->window, + bitmap, + width, height); + gtk_widget_shape_combine_mask (shape_window, shape_mask, 0, 0); + gdk_bitmap_unref (shape_mask); +} + + +static void +shape_pressed (GtkWidget *widget, GdkEventButton *event) +{ + CursorOffset *p; + + /* ignore double and triple click */ + if (event->type != GDK_BUTTON_PRESS) + return; + + p = gtk_object_get_user_data (GTK_OBJECT(widget)); + p->x = (int) event->x; + p->y = (int) event->y; + + gtk_grab_add (widget); + gdk_pointer_grab (widget->window, TRUE, + GDK_BUTTON_RELEASE_MASK | + GDK_BUTTON_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK, + NULL, NULL, 0); + gdk_window_raise (widget->window); +} + + +static void +blocked_expose (GtkWidget *widget, GdkEventExpose *event) +{ + gtk_signal_emit_stop_by_name (GTK_OBJECT(widget), "expose_event"); +} + + +#ifdef I_AM_STUPID +static void +xblocked_expose (GtkWidget *widget, GdkEventExpose *event) +{ + printf("eep!\n");fflush(stdout); + abort(); +} + +static void +unblocked_expose (GtkWidget *widget, GdkEventExpose *event) +{ + gboolean should_block; + + printf("%p: t%d w:%p s:%d c:%d \n",widget, event->type, event->window, + event->send_event, event->count); + fflush(stdout); + + return; + + /* + * If the animation is playing, we only respond to exposures + * which are artificially generated as a result of i.e. + * draw_widget. This is to avoid needlessly redrawing twice + * per frame, because also 'real' exposure events may be generated + * by reshaping the windoow. + * + * If the animation is not playing, then we respond to any type + * of expose event. + */ + + if (playing) + should_block = (!event->send_event) || (event->count != 0); + else + should_block = FALSE; + + if (should_block) + { + /* + * Since a whole load of exposures can come back-to-back, + * starvation can occur for the dialog etc. This alleviates + * the pain. + */ + while (gtk_events_pending()) + gtk_main_iteration_do(TRUE); + + /* + * Block the expose from being acted upon. + */ + blocked_expose(widget, event); + + return; + } +} +#endif + + +static void +shape_released (GtkWidget *widget) +{ + gtk_grab_remove (widget); + gdk_pointer_ungrab (0); + gdk_flush(); +} + + +static void +shape_motion (GtkWidget *widget, + GdkEventMotion *event) +{ + gint xp, yp; + CursorOffset * p; + GdkModifierType mask; + + gdk_window_get_pointer (root_win, &xp, &yp, &mask); + + // printf("%u %d\n", mask, event->state);fflush(stdout); + + /* if a button is still held by the time we process this event... */ + if (mask & (GDK_BUTTON1_MASK| + GDK_BUTTON2_MASK| + GDK_BUTTON3_MASK| + GDK_BUTTON4_MASK| + GDK_BUTTON5_MASK)) + { + p = gtk_object_get_user_data (GTK_OBJECT (widget)); + + gtk_widget_set_uposition (widget, xp - p->x, yp - p->y); + } + else /* the user has released all buttons */ + { + shape_released(widget); + } +} + + +static void +preview_pressed (GtkWidget *widget, GdkEventButton *event) +{ + gint i; + gint xp, yp; + GdkModifierType mask; + + if (shaping) return; + + /* put current preview buf into shaped buf */ + for (i=0;ix, yp - event->y); + + gtk_widget_show (shape_window); + + gdk_window_set_back_pixmap(shape_window->window, NULL, 0); + gdk_window_set_back_pixmap(shape_fixed->window, NULL, 1); + + /* clear nonshaped preview widget */ + total_alpha_preview(); + for (i=0;iwindow, + width, height, + gtk_preview_get_visual()->depth); + + gdk_window_set_back_pixmap(shape_window->window, NULL, 0); + + cursor = gdk_cursor_new (GDK_CENTER_PTR); + gdk_window_set_cursor(shape_window->window, cursor); + gdk_cursor_destroy (cursor); + + gtk_signal_connect (GTK_OBJECT (shape_window), "button_press_event", + GTK_SIGNAL_FUNC (shape_pressed),NULL); + gtk_signal_connect (GTK_OBJECT (shape_window), "button_release_event", + GTK_SIGNAL_FUNC (shape_released),NULL); + gtk_signal_connect (GTK_OBJECT (shape_window), "motion_notify_event", + GTK_SIGNAL_FUNC (shape_motion),NULL); + + icon_pos = g_new (CursorOffset, 1); + gtk_object_set_user_data(GTK_OBJECT(shape_window), icon_pos); + } + + gtk_signal_connect (GTK_OBJECT (eventbox), "button_press_event", + GTK_SIGNAL_FUNC (preview_pressed),NULL); + +#ifdef I_AM_STUPID + gtk_signal_connect (GTK_OBJECT (shape_window), "expose_event", + GTK_SIGNAL_FUNC (unblocked_expose),shape_window); +#endif + gtk_signal_connect (GTK_OBJECT (shape_fixed), "expose_event", + GTK_SIGNAL_FUNC (blocked_expose),shape_fixed); + + root_win = gdk_window_foreign_new (GDK_ROOT_WINDOW ()); } @@ -462,7 +755,7 @@ render_frame(gint32 whichframe) gint rawx=0, rawy=0; guchar* srcptr; guchar* destptr; - gint i,j; + gint i,j,k; /* imaginative loop variables */ DisposeType dispose; @@ -563,6 +856,22 @@ render_frame(gint32 whichframe) *(destptr++) = *(srcptr++); srcptr++; } + + /* calculate the shape mask */ + if (shaping) + { + srcptr = rawframe + 3; + for (j=0;jid)) { /* alpha */ @@ -611,6 +937,25 @@ render_frame(gint32 whichframe) srcptr += 4; } } + + if (shaping) + { + srcptr = rawframe + 3; + for (j=rawy; j=0 && i=0 && j=0 && i=0 && i=0 && iid)) { /* alpha */ @@ -746,6 +1150,25 @@ render_frame(gint32 whichframe) srcptr += 2; } } + + if (shaping) + { + srcptr = rawframe + 1; + for (j=rawy; j=0 && i=0 && j=0 && i=0 && i=0 && iwindow, shape_pixmap, + FALSE); + + reshape_from_bitmap(shape_preview_mask); + + gdk_flush(); + + gtk_widget_queue_draw(shape_window); + } /* update the dialog's progress bar */ gtk_progress_bar_update (progress, @@ -825,6 +1295,7 @@ init_preview_misc(void) int i; preview_data = g_malloc(width*height*3); + shape_preview_mask = g_malloc((width*height)/8 + 1 + height); preview_alpha1_data = g_malloc(width*3); preview_alpha2_data = g_malloc(width*3); @@ -857,12 +1328,19 @@ total_alpha_preview(void) { int i; - for (i=0;i do pixelrgns properly! + * + * write other half of the user interface (default timing, disposal &c) */ #include @@ -64,6 +86,7 @@ #include #include #include "libgimp/gimp.h" +#include "gdk/gdkx.h" #include "gtk/gtk.h" @@ -105,6 +128,7 @@ static void total_alpha_preview (void); static void init_preview_misc (void); + GPlugInInfo PLUG_IN_INFO = { NULL, /* init_proc */ @@ -136,6 +160,20 @@ gint ncolours; +/* for shaping */ +guchar *shape_preview_mask; +GtkWidget *shape_window; +GtkWidget *shape_fixed; +GtkPreview *shape_preview; +GdkPixmap *shape_pixmap; +typedef struct _cursoroffset {gint x,y;} CursorOffset; +gint shaping = 0; +static GdkWindow *root_win = NULL; + + + + + MAIN() @@ -156,7 +194,7 @@ static void query() "", "Adam D. Moss ", "Adam D. Moss ", - "1997", + "1997, 1998...", "/Filters/Animation/Animation Playback", "RGB*, INDEXED*, GRAY*", PROC_PLUG_IN, @@ -255,6 +293,188 @@ parse_disposal_tag (char *str) } +static void +reshape_from_bitmap(guchar* bitmap) +{ + GdkBitmap *shape_mask; + + shape_mask = gdk_bitmap_create_from_data(shape_window->window, + bitmap, + width, height); + gtk_widget_shape_combine_mask (shape_window, shape_mask, 0, 0); + gdk_bitmap_unref (shape_mask); +} + + +static void +shape_pressed (GtkWidget *widget, GdkEventButton *event) +{ + CursorOffset *p; + + /* ignore double and triple click */ + if (event->type != GDK_BUTTON_PRESS) + return; + + p = gtk_object_get_user_data (GTK_OBJECT(widget)); + p->x = (int) event->x; + p->y = (int) event->y; + + gtk_grab_add (widget); + gdk_pointer_grab (widget->window, TRUE, + GDK_BUTTON_RELEASE_MASK | + GDK_BUTTON_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK, + NULL, NULL, 0); + gdk_window_raise (widget->window); +} + + +static void +blocked_expose (GtkWidget *widget, GdkEventExpose *event) +{ + gtk_signal_emit_stop_by_name (GTK_OBJECT(widget), "expose_event"); +} + + +#ifdef I_AM_STUPID +static void +xblocked_expose (GtkWidget *widget, GdkEventExpose *event) +{ + printf("eep!\n");fflush(stdout); + abort(); +} + +static void +unblocked_expose (GtkWidget *widget, GdkEventExpose *event) +{ + gboolean should_block; + + printf("%p: t%d w:%p s:%d c:%d \n",widget, event->type, event->window, + event->send_event, event->count); + fflush(stdout); + + return; + + /* + * If the animation is playing, we only respond to exposures + * which are artificially generated as a result of i.e. + * draw_widget. This is to avoid needlessly redrawing twice + * per frame, because also 'real' exposure events may be generated + * by reshaping the windoow. + * + * If the animation is not playing, then we respond to any type + * of expose event. + */ + + if (playing) + should_block = (!event->send_event) || (event->count != 0); + else + should_block = FALSE; + + if (should_block) + { + /* + * Since a whole load of exposures can come back-to-back, + * starvation can occur for the dialog etc. This alleviates + * the pain. + */ + while (gtk_events_pending()) + gtk_main_iteration_do(TRUE); + + /* + * Block the expose from being acted upon. + */ + blocked_expose(widget, event); + + return; + } +} +#endif + + +static void +shape_released (GtkWidget *widget) +{ + gtk_grab_remove (widget); + gdk_pointer_ungrab (0); + gdk_flush(); +} + + +static void +shape_motion (GtkWidget *widget, + GdkEventMotion *event) +{ + gint xp, yp; + CursorOffset * p; + GdkModifierType mask; + + gdk_window_get_pointer (root_win, &xp, &yp, &mask); + + // printf("%u %d\n", mask, event->state);fflush(stdout); + + /* if a button is still held by the time we process this event... */ + if (mask & (GDK_BUTTON1_MASK| + GDK_BUTTON2_MASK| + GDK_BUTTON3_MASK| + GDK_BUTTON4_MASK| + GDK_BUTTON5_MASK)) + { + p = gtk_object_get_user_data (GTK_OBJECT (widget)); + + gtk_widget_set_uposition (widget, xp - p->x, yp - p->y); + } + else /* the user has released all buttons */ + { + shape_released(widget); + } +} + + +static void +preview_pressed (GtkWidget *widget, GdkEventButton *event) +{ + gint i; + gint xp, yp; + GdkModifierType mask; + + if (shaping) return; + + /* put current preview buf into shaped buf */ + for (i=0;ix, yp - event->y); + + gtk_widget_show (shape_window); + + gdk_window_set_back_pixmap(shape_window->window, NULL, 0); + gdk_window_set_back_pixmap(shape_fixed->window, NULL, 1); + + /* clear nonshaped preview widget */ + total_alpha_preview(); + for (i=0;iwindow, + width, height, + gtk_preview_get_visual()->depth); + + gdk_window_set_back_pixmap(shape_window->window, NULL, 0); + + cursor = gdk_cursor_new (GDK_CENTER_PTR); + gdk_window_set_cursor(shape_window->window, cursor); + gdk_cursor_destroy (cursor); + + gtk_signal_connect (GTK_OBJECT (shape_window), "button_press_event", + GTK_SIGNAL_FUNC (shape_pressed),NULL); + gtk_signal_connect (GTK_OBJECT (shape_window), "button_release_event", + GTK_SIGNAL_FUNC (shape_released),NULL); + gtk_signal_connect (GTK_OBJECT (shape_window), "motion_notify_event", + GTK_SIGNAL_FUNC (shape_motion),NULL); + + icon_pos = g_new (CursorOffset, 1); + gtk_object_set_user_data(GTK_OBJECT(shape_window), icon_pos); + } + + gtk_signal_connect (GTK_OBJECT (eventbox), "button_press_event", + GTK_SIGNAL_FUNC (preview_pressed),NULL); + +#ifdef I_AM_STUPID + gtk_signal_connect (GTK_OBJECT (shape_window), "expose_event", + GTK_SIGNAL_FUNC (unblocked_expose),shape_window); +#endif + gtk_signal_connect (GTK_OBJECT (shape_fixed), "expose_event", + GTK_SIGNAL_FUNC (blocked_expose),shape_fixed); + + root_win = gdk_window_foreign_new (GDK_ROOT_WINDOW ()); } @@ -462,7 +755,7 @@ render_frame(gint32 whichframe) gint rawx=0, rawy=0; guchar* srcptr; guchar* destptr; - gint i,j; + gint i,j,k; /* imaginative loop variables */ DisposeType dispose; @@ -563,6 +856,22 @@ render_frame(gint32 whichframe) *(destptr++) = *(srcptr++); srcptr++; } + + /* calculate the shape mask */ + if (shaping) + { + srcptr = rawframe + 3; + for (j=0;jid)) { /* alpha */ @@ -611,6 +937,25 @@ render_frame(gint32 whichframe) srcptr += 4; } } + + if (shaping) + { + srcptr = rawframe + 3; + for (j=rawy; j=0 && i=0 && j=0 && i=0 && i=0 && iid)) { /* alpha */ @@ -746,6 +1150,25 @@ render_frame(gint32 whichframe) srcptr += 2; } } + + if (shaping) + { + srcptr = rawframe + 1; + for (j=rawy; j=0 && i=0 && j=0 && i=0 && i=0 && iwindow, shape_pixmap, + FALSE); + + reshape_from_bitmap(shape_preview_mask); + + gdk_flush(); + + gtk_widget_queue_draw(shape_window); + } /* update the dialog's progress bar */ gtk_progress_bar_update (progress, @@ -825,6 +1295,7 @@ init_preview_misc(void) int i; preview_data = g_malloc(width*height*3); + shape_preview_mask = g_malloc((width*height)/8 + 1 + height); preview_alpha1_data = g_malloc(width*3); preview_alpha2_data = g_malloc(width*3); @@ -857,12 +1328,19 @@ total_alpha_preview(void) { int i; - for (i=0;iselected_scheme_proc_name); + gtk_entry_set_editable(GTK_ENTRY(label), FALSE); gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label, 1, 4, row, row+1, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); diff --git a/plug-ins/dbbrowser/gimpprocbrowser.c b/plug-ins/dbbrowser/gimpprocbrowser.c index b51a4ca4fb..ba85d89726 100644 --- a/plug-ins/dbbrowser/gimpprocbrowser.c +++ b/plug-ins/dbbrowser/gimpprocbrowser.c @@ -268,6 +268,7 @@ dialog_select (dbbrowser_t *dbbrowser, label = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(label),dbbrowser->selected_scheme_proc_name); + gtk_entry_set_editable(GTK_ENTRY(label), FALSE); gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label, 1, 4, row, row+1, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); diff --git a/plug-ins/dbbrowser/gimpprocview.c b/plug-ins/dbbrowser/gimpprocview.c index b51a4ca4fb..ba85d89726 100644 --- a/plug-ins/dbbrowser/gimpprocview.c +++ b/plug-ins/dbbrowser/gimpprocview.c @@ -268,6 +268,7 @@ dialog_select (dbbrowser_t *dbbrowser, label = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(label),dbbrowser->selected_scheme_proc_name); + gtk_entry_set_editable(GTK_ENTRY(label), FALSE); gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label, 1, 4, row, row+1, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); diff --git a/plug-ins/film/film.c b/plug-ins/film/film.c index 5b191c0090..a032f68f00 100644 --- a/plug-ins/film/film.c +++ b/plug-ins/film/film.c @@ -878,7 +878,7 @@ draw_number (gint32 layer_ID, {char buf[32]; GDrawable *drw; - GParam *params; + GParam *params = NULL; gint nreturn_vals, k, delta, max_delta; gint32 image_ID, descent; char *family = filmvals.number_fontf;