/* * $Id$ * * Copyright © 2004 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "lpint.h" Bool create_window_image (light_pipe_window *lpw) { int image_size; XGCValues gcv; lpw->public.image = XCreateImage (lpw->display, lpw->visual, lpw->depth, ZPixmap, 0, 0, lpw->public.geometry.width, lpw->public.geometry.height, 32, 0); if (!lpw->public.image) return False; image_size = (lpw->public.image->bytes_per_line * lpw->public.geometry.height); if (!image_size) { XDestroyImage (lpw->public.image); return False; } lpw->shm_info.shmid = shmget (IPC_PRIVATE, image_size, IPC_CREAT|0600); if (lpw->shm_info.shmid < 0) { XDestroyImage (lpw->public.image); lpw->public.image = 0; return False; } lpw->shm_info.shmaddr = (char *) shmat (lpw->shm_info.shmid, 0, 0); if (lpw->shm_info.shmaddr == ((char *) -1)) { XDestroyImage (lpw->public.image); lpw->public.image = 0; shmctl (lpw->shm_info.shmid, IPC_RMID, 0); return False; } XShmAttach (lpw->display, &lpw->shm_info); lpw->public.image->data = lpw->shm_info.shmaddr; lpw->public.image->obdata = (char *) &lpw->shm_info; lpw->shm_pixmap = XShmCreatePixmap (lpw->display, lpw->window, lpw->public.image->data, &lpw->shm_info, lpw->public.geometry.width, lpw->public.geometry.height, lpw->depth); gcv.graphics_exposures = False; gcv.subwindow_mode = IncludeInferiors; lpw->shm_gc = XCreateGC (lpw->display, lpw->window, GCGraphicsExposures|GCSubwindowMode, &gcv); return True; } void destroy_window_image (light_pipe_window *lpw) { if (lpw->public.image) { XShmDetach (lpw->display, &lpw->shm_info); XSync (lpw->display, False); (void) shmdt (&lpw->shm_info.shmaddr); (void) shmctl (lpw->shm_info.shmid, IPC_RMID, 0); lpw->public.image->data = 0; lpw->public.image->obdata = 0; XDestroyImage (lpw->public.image); XFreePixmap (lpw->display, lpw->shm_pixmap); XFreeGC (lpw->display, lpw->shm_gc); lpw->public.image = 0; } } void update_region (light_pipe_window *lpw, int x, int y, int width, int height) { XCopyArea (lpw->display, lpw->window, lpw->shm_pixmap, lpw->shm_gc, x, y, width, height, x, y); }