util: clarify a bit of the code for parsing commands in wmgenmenu
[wmaker-crm.git] / wrlib / xutil.c
blob1c3f86dcb848fddfa4d4eec1e57ca64a16d1a013
1 /* xutil.c - utility functions for X
3 * Raster graphics library
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
20 * MA 02110-1301, USA.
23 #include <config.h>
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
31 #include <assert.h>
33 #ifdef USE_XSHM
34 #include <sys/ipc.h>
35 #include <sys/shm.h>
36 #endif /* USE_XSHM */
38 #include "wraster.h"
39 #include "xutil.h"
41 #ifdef USE_XSHM
43 static int shmError;
45 static int (*oldErrorHandler)(Display *dpy, XErrorEvent *err);
47 static int errorHandler(Display * dpy, XErrorEvent * err)
49 shmError = 1;
50 if (err->error_code != BadAccess)
51 (*oldErrorHandler) (dpy, err);
53 return 0;
56 #endif
58 RXImage *RCreateXImage(RContext * context, int depth, unsigned width, unsigned height)
60 RXImage *rximg;
61 Visual *visual = context->visual;
63 rximg = malloc(sizeof(RXImage));
64 if (!rximg) {
65 RErrorCode = RERR_NOMEMORY;
66 return NULL;
68 #ifndef USE_XSHM
69 rximg->image = XCreateImage(context->dpy, visual, depth, ZPixmap, 0, NULL, width, height, 8, 0);
70 if (!rximg->image) {
71 free(rximg);
72 RErrorCode = RERR_XERROR;
73 return NULL;
75 rximg->image->data = malloc(rximg->image->bytes_per_line * height);
76 if (!rximg->image->data) {
77 XDestroyImage(rximg->image);
78 free(rximg);
79 RErrorCode = RERR_NOMEMORY;
80 return NULL;
82 #else /* USE_XSHM */
83 if (!context->attribs->use_shared_memory) {
84 retry_without_shm:
86 context->attribs->use_shared_memory = 0;
87 rximg->is_shared = 0;
88 rximg->image = XCreateImage(context->dpy, visual, depth, ZPixmap, 0, NULL, width, height, 8, 0);
89 if (!rximg->image) {
90 free(rximg);
91 RErrorCode = RERR_XERROR;
92 return NULL;
94 rximg->image->data = malloc(rximg->image->bytes_per_line * height);
95 if (!rximg->image->data) {
96 XDestroyImage(rximg->image);
97 free(rximg);
98 RErrorCode = RERR_NOMEMORY;
99 return NULL;
101 } else {
102 rximg->is_shared = 1;
104 rximg->info.readOnly = False;
106 rximg->image = XShmCreateImage(context->dpy, visual, depth,
107 ZPixmap, NULL, &rximg->info, width, height);
109 rximg->info.shmid = shmget(IPC_PRIVATE, rximg->image->bytes_per_line * height, IPC_CREAT | 0777);
110 if (rximg->info.shmid < 0) {
111 context->attribs->use_shared_memory = 0;
112 perror("wrlib: could not allocate shared memory segment");
113 XDestroyImage(rximg->image);
114 goto retry_without_shm;
117 rximg->info.shmaddr = shmat(rximg->info.shmid, 0, 0);
118 if (rximg->info.shmaddr == (void *)-1) {
119 context->attribs->use_shared_memory = 0;
120 if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
121 perror("wrlib: shmctl");
122 perror("wrlib: could not allocate shared memory");
123 XDestroyImage(rximg->image);
124 goto retry_without_shm;
127 shmError = 0;
128 XSync(context->dpy, False);
129 oldErrorHandler = XSetErrorHandler(errorHandler);
130 XShmAttach(context->dpy, &rximg->info);
131 XSync(context->dpy, False);
132 XSetErrorHandler(oldErrorHandler);
134 rximg->image->data = rximg->info.shmaddr;
135 /* rximg->image->obdata = &(rximg->info); */
137 if (shmError) {
138 context->attribs->use_shared_memory = 0;
139 XDestroyImage(rximg->image);
140 if (shmdt(rximg->info.shmaddr) < 0)
141 perror("wrlib: shmdt");
142 if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
143 perror("wrlib: shmctl");
144 /* printf("wrlib:error attaching shared memory segment to XImage\n");
146 goto retry_without_shm;
149 #endif /* USE_XSHM */
151 return rximg;
154 void RDestroyXImage(RContext * context, RXImage * rximage)
156 #ifndef USE_XSHM
157 XDestroyImage(rximage->image);
158 #else /* USE_XSHM */
159 if (rximage->is_shared) {
160 XSync(context->dpy, False);
161 XShmDetach(context->dpy, &rximage->info);
162 XDestroyImage(rximage->image);
163 if (shmdt(rximage->info.shmaddr) < 0)
164 perror("wrlib: shmdt");
165 if (shmctl(rximage->info.shmid, IPC_RMID, 0) < 0)
166 perror("wrlib: shmctl");
167 } else {
168 XDestroyImage(rximage->image);
170 #endif
171 free(rximage);
174 static unsigned getDepth(Display * dpy, Drawable d)
176 Window w;
177 int foo;
178 unsigned bar;
179 unsigned depth;
181 XGetGeometry(dpy, d, &w, &foo, &foo, &bar, &bar, &bar, &depth);
183 return depth;
186 RXImage *RGetXImage(RContext * context, Drawable d, int x, int y, unsigned width, unsigned height)
188 RXImage *ximg = NULL;
190 #ifdef USE_XSHM
191 if (context->attribs->use_shared_memory && 0) {
192 ximg = RCreateXImage(context, getDepth(context->dpy, d), width, height);
194 if (ximg && !ximg->is_shared) {
195 RDestroyXImage(context, ximg);
196 ximg = NULL;
198 if (ximg) {
199 XShmGetImage(context->dpy, d, ximg->image, x, y, AllPlanes);
202 if (!ximg) {
203 ximg = malloc(sizeof(RXImage));
204 if (!ximg) {
205 RErrorCode = RERR_NOMEMORY;
206 return NULL;
208 ximg->is_shared = 0;
209 ximg->image = XGetImage(context->dpy, d, x, y, width, height, AllPlanes, ZPixmap);
211 #else /* !USE_XSHM */
212 ximg = malloc(sizeof(RXImage));
213 if (!ximg) {
214 RErrorCode = RERR_NOMEMORY;
215 return NULL;
218 ximg->image = XGetImage(context->dpy, d, x, y, width, height, AllPlanes, ZPixmap);
219 #endif /* !USE_XSHM */
221 if (ximg->image == NULL) {
222 free(ximg);
223 return NULL;
226 return ximg;
229 void
230 RPutXImage(RContext * context, Drawable d, GC gc, RXImage * ximage, int src_x,
231 int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height)
233 #ifndef USE_XSHM
234 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x, dest_y, width, height);
235 #else
236 if (ximage->is_shared) {
237 XShmPutImage(context->dpy, d, gc, ximage->image, src_x, src_y,
238 dest_x, dest_y, width, height, False);
239 } else {
240 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x, dest_y, width, height);
242 XFlush(context->dpy);
243 #endif /* USE_XSHM */
246 #ifdef USE_XSHM
247 Pixmap R_CreateXImageMappedPixmap(RContext * context, RXImage * rximage)
249 Pixmap pix;
251 pix = XShmCreatePixmap(context->dpy, context->drawable,
252 rximage->image->data, &rximage->info,
253 rximage->image->width, rximage->image->height, rximage->image->depth);
255 return pix;
258 #endif /* USE_XSHM */