?? gdkimage-x11.c
字號:
#ifdef USE_SHM /* Future: do we need one of these per-screen per-image? ShmPixmaps * are the same for every screen, but can they be shared? Not a concern * right now since we tie images to a particular screen. */ if (!private->shm_pixmap && image->type == GDK_IMAGE_SHARED && GDK_DISPLAY_X11 (display)->have_shm_pixmaps) private->shm_pixmap = XShmCreatePixmap (GDK_SCREEN_XDISPLAY (private->screen), GDK_SCREEN_XROOTWIN (private->screen), image->mem, private->x_shm_info, image->width, image->height, image->depth); return private->shm_pixmap;#else return None;#endif }static GdkImage*get_full_image (GdkDrawable *drawable, gint src_x, gint src_y, gint width, gint height){ GdkImage *image; GdkImagePrivateX11 *private; GdkDrawableImplX11 *impl; XImage *ximage; impl = GDK_DRAWABLE_IMPL_X11 (drawable); ximage = XGetImage (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, src_x, src_y, width, height, AllPlanes, ZPixmap); if (!ximage) return NULL; image = g_object_new (gdk_image_get_type (), NULL); private = PRIVATE_DATA (image); private->screen = impl->screen; private->ximage = ximage; image->type = GDK_IMAGE_NORMAL; image->visual = gdk_drawable_get_visual (drawable); /* could be NULL */ image->width = width; image->height = height; image->depth = gdk_drawable_get_depth (drawable); image->mem = private->ximage->data; image->bpl = private->ximage->bytes_per_line; image->bits_per_pixel = private->ximage->bits_per_pixel; image->bpp = (private->ximage->bits_per_pixel + 7) / 8; image->byte_order = (private->ximage->byte_order == LSBFirst) ? GDK_LSB_FIRST : GDK_MSB_FIRST; return image;}GdkImage*_gdk_x11_copy_to_image (GdkDrawable *drawable, GdkImage *image, gint src_x, gint src_y, gint dest_x, gint dest_y, gint width, gint height){ GdkImagePrivateX11 *private; GdkDrawableImplX11 *impl; GdkVisual *visual; GdkDisplay *display; Display *xdisplay; gboolean have_grab; GdkRectangle req; GdkRectangle window_rect; Pixmap shm_pixmap = None; gboolean success = TRUE; g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_X11 (drawable), NULL); g_return_val_if_fail (image != NULL || (dest_x == 0 && dest_y == 0), NULL); visual = gdk_drawable_get_visual (drawable); impl = GDK_DRAWABLE_IMPL_X11 (drawable); display = gdk_drawable_get_display (drawable); xdisplay = gdk_x11_display_get_xdisplay (display); if (display->closed) return NULL; have_grab = FALSE;#define UNGRAB() G_STMT_START { \ if (have_grab) { \ gdk_x11_display_ungrab (display); \ have_grab = FALSE; } \ } G_STMT_END if (!image && !GDK_IS_WINDOW_IMPL_X11 (drawable)) return get_full_image (drawable, src_x, src_y, width, height); if (image && image->type == GDK_IMAGE_SHARED) { shm_pixmap = _gdk_x11_image_get_shm_pixmap (image); if (shm_pixmap) { GC xgc; XGCValues values; /* Again easy, we can just XCopyArea, and don't have to worry about clipping */ values.subwindow_mode = IncludeInferiors; xgc = XCreateGC (xdisplay, impl->xid, GCSubwindowMode, &values); XCopyArea (xdisplay, impl->xid, shm_pixmap, xgc, src_x, src_y, width, height, dest_x, dest_y); XSync (xdisplay, FALSE); XFreeGC (xdisplay, xgc); return image; } } /* Now the general case - we may have to worry about clipping to the screen * bounds, in which case we'll have to grab the server and only get a piece * of the window. */ if (GDK_IS_WINDOW_IMPL_X11 (drawable)) { GdkRectangle screen_rect; Window child; have_grab = TRUE; gdk_x11_display_grab (display); /* Translate screen area into window coordinates */ XTranslateCoordinates (xdisplay, GDK_SCREEN_XROOTWIN (impl->screen), impl->xid, 0, 0, &screen_rect.x, &screen_rect.y, &child); screen_rect.width = gdk_screen_get_width (impl->screen); screen_rect.height = gdk_screen_get_height (impl->screen); gdk_error_trap_push (); window_rect.x = 0; window_rect.y = 0; gdk_window_get_geometry (GDK_WINDOW (impl->wrapper), NULL, NULL, &window_rect.width, &window_rect.height, NULL); /* compute intersection of screen and window, in window * coordinates */ if (gdk_error_trap_pop () || !gdk_rectangle_intersect (&window_rect, &screen_rect, &window_rect)) goto out; } else { window_rect.x = 0; window_rect.y = 0; gdk_drawable_get_size (drawable, &window_rect.width, &window_rect.height); } req.x = src_x; req.y = src_y; req.width = width; req.height = height; /* window_rect specifies the part of drawable which we can get from * the server in window coordinates. * For pixmaps this is all of the pixmap, for windows it is just * the onscreen part. */ if (!gdk_rectangle_intersect (&req, &window_rect, &req)) goto out; gdk_error_trap_push (); if (!image && req.x == src_x && req.y == src_y && req.width == width && req.height == height) { image = get_full_image (drawable, src_x, src_y, width, height); if (!image) success = FALSE; } else { gboolean created_image = FALSE; if (!image) { image = _gdk_image_new_for_depth (impl->screen, GDK_IMAGE_NORMAL, visual, width, height, gdk_drawable_get_depth (drawable)); created_image = TRUE; } private = PRIVATE_DATA (image); /* In the ShmImage but no ShmPixmap case, we could use XShmGetImage when * we are getting the entire image. */ if (XGetSubImage (xdisplay, impl->xid, req.x, req.y, req.width, req.height, AllPlanes, ZPixmap, private->ximage, dest_x + req.x - src_x, dest_y + req.y - src_y) == None) { if (created_image) g_object_unref (image); image = NULL; success = FALSE; } } gdk_error_trap_pop (); out: if (have_grab) { gdk_x11_display_ungrab (display); have_grab = FALSE; } if (success && !image) { /* We "succeeded", but could get no content for the image so return junk */ image = _gdk_image_new_for_depth (impl->screen, GDK_IMAGE_NORMAL, visual, width, height, gdk_drawable_get_depth (drawable)); } return image;}guint32gdk_image_get_pixel (GdkImage *image, gint x, gint y){ guint32 pixel; GdkImagePrivateX11 *private; g_return_val_if_fail (GDK_IS_IMAGE (image), 0); g_return_val_if_fail (x >= 0 && x < image->width, 0); g_return_val_if_fail (y >= 0 && y < image->height, 0); private = PRIVATE_DATA (image); if (!private->screen->closed) pixel = XGetPixel (private->ximage, x, y); else pixel = 0; return pixel;}voidgdk_image_put_pixel (GdkImage *image, gint x, gint y, guint32 pixel){ GdkImagePrivateX11 *private; g_return_if_fail (GDK_IS_IMAGE (image)); g_return_if_fail (x >= 0 && x < image->width); g_return_if_fail (y >= 0 && y < image->height); private = PRIVATE_DATA (image); if (!private->screen->closed) pixel = XPutPixel (private->ximage, x, y, pixel);}static voidgdk_x11_image_destroy (GdkImage *image){ GdkImagePrivateX11 *private;#ifdef USE_SHM XShmSegmentInfo *x_shm_info;#endif /* USE_SHM */ g_return_if_fail (GDK_IS_IMAGE (image)); private = PRIVATE_DATA (image); if (private == NULL) /* This means that _gdk_image_exit() destroyed the * image already, and now we're called a second * time from _finalize() */ return; if (private->ximage) /* Deal with failure of creation */ { switch (image->type) { case GDK_IMAGE_NORMAL: if (!private->screen->closed) XDestroyImage (private->ximage); break; case GDK_IMAGE_SHARED:#ifdef USE_SHM if (!private->screen->closed) { gdk_display_sync (GDK_SCREEN_DISPLAY (private->screen)); if (private->shm_pixmap) XFreePixmap (GDK_SCREEN_XDISPLAY (private->screen), private->shm_pixmap); XShmDetach (GDK_SCREEN_XDISPLAY (private->screen), private->x_shm_info); XDestroyImage (private->ximage); } image_list = g_list_remove (image_list, image); x_shm_info = private->x_shm_info; shmdt (x_shm_info->shmaddr); g_free (private->x_shm_info); private->x_shm_info = NULL;#else /* USE_SHM */ g_error ("trying to destroy shared memory image when gdk was compiled without shared memory support");#endif /* USE_SHM */ break; case GDK_IMAGE_FASTEST: g_assert_not_reached (); } } g_free (private); image->windowing_data = NULL;}/** * gdk_x11_image_get_xdisplay: * @image: a #GdkImage. * * Returns the display of a #GdkImage. * * Return value: an Xlib <type>Display*</type>. **/Display *gdk_x11_image_get_xdisplay (GdkImage *image){ GdkImagePrivateX11 *private; g_return_val_if_fail (GDK_IS_IMAGE (image), NULL); private = PRIVATE_DATA (image); return GDK_SCREEN_XDISPLAY (private->screen);}/** * gdk_x11_image_get_ximage: * @image: a #GdkImage. * * Returns the X image belonging to a #GdkImage. * * Return value: an <type>XImage*</type>. **/XImage *gdk_x11_image_get_ximage (GdkImage *image){ GdkImagePrivateX11 *private; g_return_val_if_fail (GDK_IS_IMAGE (image), NULL); private = PRIVATE_DATA (image); if (private->screen->closed) return NULL; else return private->ximage;}gint_gdk_windowing_get_bits_for_depth (GdkDisplay *display, gint depth){ XPixmapFormatValues *formats; gint count, i; formats = XListPixmapFormats (GDK_DISPLAY_XDISPLAY (display), &count); for (i = 0; i < count; i++) if (formats[i].depth == depth) { gint result = formats[i].bits_per_pixel; XFree (formats); return result; } g_assert_not_reached (); return -1;}#define __GDK_IMAGE_X11_C__#include "gdkaliasdef.c"
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -