/* ID = gtkhelp.c Some help options for GTK+ Trent Weddington & Maciek Fijalkowski 2001 - 2002 */ #include "tools.h" /* `draw_area' is a pointer to a GtkDrawingArea widget, which we will * use to display the contents of our Allegro bitmap. We will use * `screen' here, but you can use anything you want. */ /* These bank switching functions get called when a line gets selected * for writing. This saves us from redrawing the entire `draw_area' * widget, as in the previous program. */ static int last_line = -1; #ifndef ALLEGRO_NO_ASM unsigned long _screen_write_line_asm (BITMAP *bmp, int line); unsigned long _screen_unwrite_line_asm (BITMAP *bmp, int line); #endif static inline void update_draw_area_line ( BITMAP *bmp, int y) { GtkWidget *draw_area; draw_area = (GtkWidget*)(bmp -> extra); gdk_draw_rgb_32_image (draw_area->window, draw_area->style->black_gc, 0, y, bmp->w, 1, GDK_RGB_DITHER_NONE, bmp->line[y], bmp->w * 4 ); } unsigned long _screen_write_line ( BITMAP *bmp, int line) { int new_line = line + bmp->y_ofs; if ((new_line != last_line) && (last_line >= 0)) update_draw_area_line ( bmp, last_line); last_line = new_line; return (unsigned long) (bmp->line[line]); } void _screen_unwrite_line ( BITMAP *bmp) { if (last_line >= 0) update_draw_area_line ( bmp, last_line); last_line = -1; } /* The "configure" event is sent whenever the widget is resized * (including when it is created). You may decide to resize the * screen bitmap here, for example. */ static gboolean draw_area_configure_event ( GtkWidget *widget , GdkEventConfigure *event , BITMAP *bmp ) { /* Set write bank switching functions. We do this here because if * the bank switching functions were called before `draw_area' was * properly constructed, that would be bad. */ #ifdef ALLEGRO_NO_ASM bmp->write_bank = _screen_write_line; bmp->vtable->unwrite_bank = _screen_unwrite_line; #else bmp->write_bank = _screen_write_line_asm; bmp->vtable->unwrite_bank = _screen_unwrite_line_asm; #endif /* The new width and height of the widget may be found in * widget->allocation.width and widget->allocation.height. */ return TRUE; } /* The "expose" event is sent when some part of the widget on screen * requires redrawing (e.g. it was previously overlapped). */ static gboolean draw_area_expose_event (GtkWidget *widget, GdkEventExpose *event, BITMAP *bmp ) { int x0,y0,xk,yk,sx,sy; /* Look in `/usr/include/gdk/gdkrgb.h' for other functions if * you're not using a 32 bit bitmap. */ gdk_window_get_size ( event -> window , &sx , &sy ); xk = MIN ( event -> area.x + event -> area.width , (bmp -> w + sx) / 2 ); yk = MIN ( event -> area.y + event -> area.height , (bmp -> h + sy) / 2 ); x0 = MAX ( event -> area.x , (sx - bmp -> w) / 2 ); y0 = MAX ( event -> area.y , (sy - bmp -> h) / 2 ); sx = MAX ( event -> area.x - (sx - bmp -> w) / 2 , 0 ); sy = MAX ( event -> area.y - (sy - bmp -> h) / 2 , 0 ); if (( xk - x0 < 0 ) || ( yk - y0 < 0 )) return ( FALSE ); gdk_draw_rgb_32_image (widget->window, widget->style->black_gc, x0 , y0 , xk - x0 , yk - y0 , GDK_RGB_DITHER_NONE, bmp->line[sy] + sx * 4 , bmp -> w * 4 ); return FALSE; } GtkWidget *make_drawing_area ( BITMAP *bitmap ) { GtkWidget *drawing_area; drawing_area = gtk_drawing_area_new (); gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), bitmap -> w , bitmap -> h ); bitmap -> extra = drawing_area; gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event", GTK_SIGNAL_FUNC (draw_area_expose_event), bitmap); gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event", GTK_SIGNAL_FUNC (draw_area_configure_event), bitmap); gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK); return ( drawing_area ); }