GDK introduce
GDK是标准Xlib函数调用的一个基本封装(wrapper). GDK (GIMP Drawing Kit) is a computer graphics library that acts as a wrapper around the low-level drawing and windowing functions provided by the underlying graphics system.
pixmaps and drawables
A pixmap is an off-screen buffer you can draw graphics into. In GDK, the pixmap type is called GdkPixmap. A pixmap with a single bit representing each pixel is called a bitmap; GDK's bitmap type is GdkBitmap. A drawable is anything you can draw graphics on. GDK has a corresponding type, called GdkDrawable(include GdkWindow,GdkPixmap,GdkBitmap).
#include <gdk/gdk> GdkPixmap* gdk_pixmap_new (GdkWindow* window, gint width, gint height, gint depth); /* window is the surface pixmap to display */ void gdk_pixmap_unref (GdkPixmap* pixmap); /* destroy a pixmap. */ void gdk_draw_drawable (GdkDrawable *drawable, GdkGC *gc, GdkDrawable *src, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height);
colormaps and visuals
A bitmap display consists of a rectangular grid of pixels. Each pixel consists of some fixed number of bits. Pixels are mapped to visible colors. In the X Window System, pixels represent entries in a color lookup table. A color is a red, green, blue (RGB) value. Take an eight bit display, for example: eight bits are not enough to encode a color in-place; only a few arbitrary RGB values would be possible. Instead, the bits are interpreted as an integer and used to index an array of RGB color values. This table of colors is called the colormap.
A visual is required to determine how a pixel's bit pattern is converted into a visible color. On an 8-bit display, the X server might interpret each pixel as an index into a single colormap containing the 256 possible colors. 24-bit visuals typically have three colormaps: one for shades of red, one for shades of green, and one for shades of blue. Each colormap is indexed with an eight-bit value; the three eight-bit values are packed into a 24-bit pixel. The visual defines the meaning of the pixel contents. Visuals also define whether the colormap is read-only or modifiable.
GdkVisual
Xlib can report a list of all available visuals and information about each; GDK keeps a client-side copy of this information in a struct called GdkVisual. GDK can report the available visuals, and rank them in different ways. Most of the time you will only use gdk_visual_get_system(), which returns a pointer to the default visual.
Color and GdkColormap
struct GdkColor { gulong pixel; gushort red; gushort green; gushort blue; };
A convenient way to obtain RGB values is the gdk_color_parse() function. This takes an X color specification, and fills in the red, green, and blue fields of a GdkColor. An X color specification can have many forms; one possibility is an RGB string: RGB:FF/FF/FF Another form: #include <gdk/gdk.h> GdkColor color; if (gdk_color_parse("orange", &color)) { if (gdk_colormap_alloc_color(colormap, &color, FALSE, FALSE)) { /* We have orange! */ } }
Obtaining a Colormap
Call gdk_colormap_get_system() to get the default colormap.
GdkPixbuf and GdkPixmap
GdkPixbuf is used to represent images. It contains information about the image's pixel data, its color space, bits per sample, width, height, etc.
A GdkPixbuf is stored on the client, and a Pixmap on the server.
Drawing
Points gdk_draw_point gdk_draw_points Lines gdk_draw_line gdk_draw_lines gdk_draw_segments Rectangles gdk_draw_rectangle Arcs gdk_draw_arc Polygons gdk_draw_polygon Text gdk_draw_layout
RGB Buffers
GDK's GdkRGB module allows you to copy a client-side buffer of image data to a drawable. You can't directly manipulate a GdkPixmap because a pixmap is a server-side object. Internally, GdkRGB uses an object called GdkImage to rapidly copy image data to the server in a single request. Before using any GdkRGB functions, you must initialize the module with gdk_rgb_init() this sets up the visual and colormap GdkRGB will use, and some internal data structures. The drawable you intend to copy the RGB buffer to must use GdkRGB's visual and colormap. If the drawable is a part of a widget, the easiest way to ensure this is to push the GdkRGB visual and colormap when you create the widget:
GtkWidget* widget; gtk_widget_push_colormap (gdk_rgb_get_cmap()); widget = gtk_whatever_new (); gtk_widget_pop_colormap();
GdkRGB understands several kinds of image data. The simplest is 24-bit RGB data; this kind of buffer is rendered with gdk_draw_rgb_image().
A 24-bit RGB buffer is a one-dimensional array of bytes; every byte triplet makes up a pixel (byte 0 is red, byte 1 is green, byte 2 is blue). Three numbers describe the size of the array and the location of bytes within it: The width is the number of pixels (byte triplets) per row of the image. The height is the number of rows in the image. The x,y,width,height arguments to gdk_rgb_draw_image() define a region of the target drawable to copy the RGB buffer to. The RGB buffer must have at least width columns and height rows. Row 0, column 0 of the RGB buffer will be copied to point (x,y) on the drawable.
#include <gdk/gdk.h> void gdk_rgb_init(void); GdkVisual* gdk_rgb_get_visual(void); void gdk_draw_rgb_image (GdkDrawable *drawable, GdkGC *gc, gint x, gint y, gint width, gint height, GdkRgbDither dith, guchar *rgb_buf, gint rowstride);
Events
Events are sent to your application to indicate changes in a GdkWindow or user actions you might be interested in. All events are associated with a GdkWindow. They also come to be associated with a GtkWidget.
Types of Event
There are many kinds of events; the GdkEvent union can represent any of them. A special event type, GdkEventAny, contains the three fields common to all events; any event can be cast to GdkEventAny. The first field in GdkEventAny is a type marker, GdkEventType; GdkEventType is also included in the GdkEvent union. Confused yet? Seeing the code should help. Here is GdkEventAny:
struct _GdkEventAny { GdkEventType type; GdkWindow *window; gint8 send_event; };
and GdkEvent:
union _GdkEvent { GdkEventType type; GdkEventAny any; GdkEventExpose expose; GdkEventNoExpose no_expose; GdkEventVisibility visibility; GdkEventMotion motion; GdkEventButton button; GdkEventKey key; GdkEventCrossing crossing; GdkEventFocus focus_change; GdkEventConfigure configure; GdkEventProperty property; GdkEventSelection selection; GdkEventProximity proximity; GdkEventClient client; GdkEventDND dnd; };
The window field of GdkEventAny is the GdkWindow the event was sent to.
The Event Mask
Each GdkWindow has an associated event mask which determines which events on that window the X server will forward to your application. You specify the event mask when a GdkWindow is created, as part of the GdkWindowAttr struct. You can access and change the event mask later using gdk_window_set_events() and gdk_window_get_events(). If the GdkWindow in question belongs to a widget, you should not change the event mask directly; rather, call gtk_widget_set_events() or gtk_widget_add_events().
Receiving GDK Events in GTK+
In a GTK+ program, you will never receive GDK events directly. Instead, all events are passed to a GtkWidget, which emits a corresponding signal. You handle events by connecting handlers to GtkWidget signals. In general, events go to the widget owning the GdkWindow the event occurred on.
If the emission of an event signal returns TRUE, the GTK+ main loop will stop propagating the current event. If it returns FALSE, the main loop will propagate the event to the widget's parent.
|