changed indentation to use spaces only
[wmaker-crm.git] / wrlib / xutil.c
blob9b5008b71336ae5c03aab69dd8267c9751cdafcb
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #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 XSHM
34 #include <sys/ipc.h>
35 #include <sys/shm.h>
36 #endif /* XSHM */
38 #include "wraster.h"
41 #ifdef XSHM
43 static int shmError;
45 static int (*oldErrorHandler)();
47 static int
48 errorHandler(Display *dpy, XErrorEvent *err)
50 shmError=1;
51 if(err->error_code!=BadAccess)
52 (*oldErrorHandler)(dpy, err);
54 return 0;
58 #endif
61 RXImage*
62 RCreateXImage(RContext *context, int depth, unsigned width, unsigned height)
64 RXImage *rximg;
65 Visual *visual = context->visual;
67 rximg = malloc(sizeof(RXImage));
68 if (!rximg) {
69 RErrorCode = RERR_NOMEMORY;
70 return NULL;
73 #ifndef XSHM
74 rximg->image = XCreateImage(context->dpy, visual, depth,
75 ZPixmap, 0, NULL, width, height, 8, 0);
76 if (!rximg->image) {
77 free(rximg);
78 RErrorCode = RERR_XERROR;
79 return NULL;
81 rximg->image->data = malloc(rximg->image->bytes_per_line*height);
82 if (!rximg->image->data) {
83 XDestroyImage(rximg->image);
84 free(rximg);
85 RErrorCode = RERR_NOMEMORY;
86 return NULL;
89 #else /* XSHM */
90 if (!context->attribs->use_shared_memory) {
91 retry_without_shm:
93 context->attribs->use_shared_memory = 0;
94 rximg->is_shared = 0;
95 rximg->image = XCreateImage(context->dpy, visual, depth,
96 ZPixmap, 0, NULL, width, height, 8, 0);
97 if (!rximg->image) {
98 free(rximg);
99 RErrorCode = RERR_XERROR;
100 return NULL;
102 rximg->image->data = malloc(rximg->image->bytes_per_line*height);
103 if (!rximg->image->data) {
104 XDestroyImage(rximg->image);
105 free(rximg);
106 RErrorCode = RERR_NOMEMORY;
107 return NULL;
109 } else {
110 rximg->is_shared = 1;
112 rximg->info.readOnly = False;
114 rximg->image = XShmCreateImage(context->dpy, visual, depth,
115 ZPixmap, NULL, &rximg->info, width,
116 height);
118 rximg->info.shmid = shmget(IPC_PRIVATE,
119 rximg->image->bytes_per_line*height,
120 IPC_CREAT|0777);
121 if (rximg->info.shmid < 0) {
122 context->attribs->use_shared_memory = 0;
123 perror("wrlib: could not allocate shared memory segment");
124 XDestroyImage(rximg->image);
125 goto retry_without_shm;
128 rximg->info.shmaddr = shmat(rximg->info.shmid, 0, 0);
129 if (rximg->info.shmaddr == (void*)-1) {
130 context->attribs->use_shared_memory = 0;
131 if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
132 perror("wrlib: shmctl");
133 perror("wrlib: could not allocate shared memory");
134 XDestroyImage(rximg->image);
135 goto retry_without_shm;
138 shmError = 0;
139 XSync(context->dpy, False);
140 oldErrorHandler = XSetErrorHandler(errorHandler);
141 XShmAttach(context->dpy, &rximg->info);
142 XSync(context->dpy, False);
143 XSetErrorHandler(oldErrorHandler);
145 rximg->image->data = rximg->info.shmaddr;
146 /* rximg->image->obdata = &(rximg->info);*/
148 if (shmError) {
149 context->attribs->use_shared_memory = 0;
150 XDestroyImage(rximg->image);
151 if (shmdt(rximg->info.shmaddr) < 0)
152 perror("wrlib: shmdt");
153 if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
154 perror("wrlib: shmctl");
155 /* printf("wrlib:error attaching shared memory segment to XImage\n");
157 goto retry_without_shm;
160 #endif /* XSHM */
162 return rximg;
166 void
167 RDestroyXImage(RContext *context, RXImage *rximage)
169 #ifndef XSHM
170 XDestroyImage(rximage->image);
171 #else /* XSHM */
172 if (rximage->is_shared) {
173 XSync(context->dpy, False);
174 XShmDetach(context->dpy, &rximage->info);
175 XDestroyImage(rximage->image);
176 if (shmdt(rximage->info.shmaddr) < 0)
177 perror("wrlib: shmdt");
178 if (shmctl(rximage->info.shmid, IPC_RMID, 0) < 0)
179 perror("wrlib: shmctl");
180 } else {
181 XDestroyImage(rximage->image);
183 #endif
184 free(rximage);
188 static unsigned
189 getDepth(Display *dpy, Drawable d)
191 Window w;
192 int foo;
193 unsigned bar;
194 unsigned depth;
196 XGetGeometry(dpy, d, &w, &foo, &foo, &bar, &bar, &bar, &depth);
198 return depth;
203 RXImage*
204 RGetXImage(RContext *context, Drawable d, int x, int y,
205 unsigned width, unsigned height)
207 RXImage *ximg = NULL;
209 #ifdef XSHM
210 if (context->attribs->use_shared_memory && 0) {
211 ximg = RCreateXImage(context, getDepth(context->dpy, d),
212 width, height);
214 if (ximg && !ximg->is_shared) {
215 RDestroyXImage(context, ximg);
216 ximg = NULL;
218 if (ximg) {
219 XShmGetImage(context->dpy, d, ximg->image, x, y, AllPlanes);
222 if (!ximg) {
223 ximg = malloc(sizeof(RXImage));
224 if (!ximg) {
225 RErrorCode = RERR_NOMEMORY;
226 return NULL;
228 ximg->is_shared = 0;
229 ximg->image = XGetImage(context->dpy, d, x, y, width, height,
230 AllPlanes, ZPixmap);
232 return ximg;
233 #else /* !XSHM */
234 ximg = malloc(sizeof(RXImage));
235 if (!ximg) {
236 RErrorCode = RERR_NOMEMORY;
237 return NULL;
240 ximg->image = XGetImage(context->dpy, d, x, y, width, height,
241 AllPlanes, ZPixmap);
243 return ximg;
244 #endif /* !XSHM */
248 void
249 RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage, int src_x,
250 int src_y, int dest_x, int dest_y,
251 unsigned int width, unsigned int height)
253 #ifndef XSHM
254 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
255 dest_y, width, height);
256 #else
257 if (ximage->is_shared) {
258 XShmPutImage(context->dpy, d, gc, ximage->image, src_x, src_y,
259 dest_x, dest_y, width, height, False);
260 } else {
261 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
262 dest_y, width, height);
264 XFlush(context->dpy);
265 #endif /* XSHM */
269 #ifdef XSHM
270 Pixmap
271 R_CreateXImageMappedPixmap(RContext *context, RXImage *rximage)
273 Pixmap pix;
275 pix = XShmCreatePixmap(context->dpy, context->drawable,
276 rximage->image->data, &rximage->info,
277 rximage->image->width, rximage->image->height,
278 rximage->image->depth);
280 return pix;
283 #endif /* XSHM */