wmaker: Adding copyright year 2017
[wmaker-crm.git] / wrlib / xutil.c
blob8e90333ad431b1cfea918d0ec401af09bb0393f2
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 /* Argument is not used in this case, tell the compiler it is ok */
158 (void) context;
160 XDestroyImage(rximage->image);
161 #else /* USE_XSHM */
162 if (rximage->is_shared) {
163 XSync(context->dpy, False);
164 XShmDetach(context->dpy, &rximage->info);
165 XDestroyImage(rximage->image);
166 if (shmdt(rximage->info.shmaddr) < 0)
167 perror("wrlib: shmdt");
168 if (shmctl(rximage->info.shmid, IPC_RMID, 0) < 0)
169 perror("wrlib: shmctl");
170 } else {
171 XDestroyImage(rximage->image);
173 #endif
174 free(rximage);
177 static unsigned getDepth(Display * dpy, Drawable d)
179 Window w;
180 int foo;
181 unsigned bar;
182 unsigned depth;
184 XGetGeometry(dpy, d, &w, &foo, &foo, &bar, &bar, &bar, &depth);
186 return depth;
189 RXImage *RGetXImage(RContext * context, Drawable d, int x, int y, unsigned width, unsigned height)
191 RXImage *ximg = NULL;
193 #ifdef USE_XSHM
194 if (context->attribs->use_shared_memory && 0) {
195 ximg = RCreateXImage(context, getDepth(context->dpy, d), width, height);
197 if (ximg && !ximg->is_shared) {
198 RDestroyXImage(context, ximg);
199 ximg = NULL;
201 if (ximg) {
202 XShmGetImage(context->dpy, d, ximg->image, x, y, AllPlanes);
205 if (!ximg) {
206 ximg = malloc(sizeof(RXImage));
207 if (!ximg) {
208 RErrorCode = RERR_NOMEMORY;
209 return NULL;
211 ximg->is_shared = 0;
212 ximg->image = XGetImage(context->dpy, d, x, y, width, height, AllPlanes, ZPixmap);
214 #else /* !USE_XSHM */
215 ximg = malloc(sizeof(RXImage));
216 if (!ximg) {
217 RErrorCode = RERR_NOMEMORY;
218 return NULL;
221 ximg->image = XGetImage(context->dpy, d, x, y, width, height, AllPlanes, ZPixmap);
222 #endif /* !USE_XSHM */
224 if (ximg->image == NULL) {
225 free(ximg);
226 return NULL;
229 return ximg;
232 void
233 RPutXImage(RContext * context, Drawable d, GC gc, RXImage * ximage, int src_x,
234 int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height)
236 #ifndef USE_XSHM
237 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x, dest_y, width, height);
238 #else
239 if (ximage->is_shared) {
240 XShmPutImage(context->dpy, d, gc, ximage->image, src_x, src_y,
241 dest_x, dest_y, width, height, False);
242 } else {
243 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x, dest_y, width, height);
245 XFlush(context->dpy);
246 #endif /* USE_XSHM */
249 #ifdef USE_XSHM
250 Pixmap R_CreateXImageMappedPixmap(RContext * context, RXImage * rximage)
252 Pixmap pix;
254 pix = XShmCreatePixmap(context->dpy, context->drawable,
255 rximage->image->data, &rximage->info,
256 rximage->image->width, rximage->image->height, rximage->image->depth);
258 return pix;
261 #endif /* USE_XSHM */