diff options
Diffstat (limited to 'lpimage.c')
-rw-r--r-- | lpimage.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/lpimage.c b/lpimage.c new file mode 100644 index 0000000..f797b6c --- /dev/null +++ b/lpimage.c @@ -0,0 +1,112 @@ +/* + * $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); +} |