Updating to version 0.20.2
[wmaker-crm.git] / wrlib / xutil.c
blob8cc31a3fb6be4c2fc147f8f9c0fe2ed0ff9c69f8
1 /* xutil.c - utility functions for X
2 *
3 * Raster graphics library
5 * Copyright (c) 1997 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:
92 rximg->is_shared = 0;
93 rximg->image = XCreateImage(context->dpy, visual, depth,
94 ZPixmap, 0, NULL, width, height, 8, 0);
95 if (!rximg->image) {
96 free(rximg);
97 RErrorCode = RERR_XERROR;
98 return NULL;
100 rximg->image->data = malloc(rximg->image->bytes_per_line*height);
101 if (!rximg->image->data) {
102 XDestroyImage(rximg->image);
103 free(rximg);
104 RErrorCode = RERR_NOMEMORY;
105 return NULL;
107 } else {
108 rximg->is_shared = 1;
110 rximg->info.readOnly = False;
112 rximg->image = XShmCreateImage(context->dpy, visual, depth,
113 ZPixmap, NULL, &rximg->info, width,
114 height);
116 rximg->info.shmid = shmget(IPC_PRIVATE,
117 rximg->image->bytes_per_line*height,
118 IPC_CREAT|0666);
119 if (rximg->info.shmid < 0) {
120 context->attribs->use_shared_memory = 0;
121 perror("wrlib:could not allocate shared memory segment");
122 XDestroyImage(rximg->image);
123 goto retry_without_shm;
126 rximg->info.shmaddr = shmat(rximg->info.shmid, 0, 0);
127 if ((int)rximg->info.shmaddr < 0) {
128 context->attribs->use_shared_memory = 0;
129 if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
130 perror("wrlib:shmctl");
131 perror("wrlib:could not allocate shared memory");
132 XDestroyImage(rximg->image);
133 goto retry_without_shm;
136 shmError = 0;
137 XSync(context->dpy, False);
138 oldErrorHandler = XSetErrorHandler(errorHandler);
139 XShmAttach(context->dpy, &rximg->info);
140 XSync(context->dpy, False);
141 XSetErrorHandler(oldErrorHandler);
143 rximg->image->data = rximg->info.shmaddr;
144 /* rximg->image->obdata = &(rximg->info);*/
146 if (shmError) {
147 context->attribs->use_shared_memory = 0;
148 XDestroyImage(rximg->image);
149 if (shmdt(rximg->info.shmaddr) < 0)
150 perror("wrlib:shmdt");
151 if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
152 perror("wrlib:shmctl");
153 printf("wrlib:error attaching shared memory segment to XImage\n");
154 goto retry_without_shm;
157 #endif /* XSHM */
159 return rximg;
163 void
164 RDestroyXImage(RContext *context, RXImage *rximage)
166 #ifndef XSHM
167 XDestroyImage(rximage->image);
168 free(rximage);
169 #else /* XSHM */
170 if (rximage->is_shared) {
171 XShmDetach(context->dpy, &rximage->info);
172 XDestroyImage(rximage->image);
173 if (shmdt(rximage->info.shmaddr) < 0)
174 perror("wrlib:shmdt");
175 if (shmctl(rximage->info.shmid, IPC_RMID, 0) < 0)
176 perror("wrlib:shmctl");
177 } else {
178 XDestroyImage(rximage->image);
180 #endif
184 void
185 RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage, int src_x,
186 int src_y, int dest_x, int dest_y,
187 unsigned int width, unsigned int height)
189 #ifndef XSHM
190 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
191 dest_y, width, height);
192 #else
193 if (ximage->is_shared) {
194 XShmPutImage(context->dpy, d, gc, ximage->image, src_x, src_y,
195 dest_x, dest_y, width, height, False);
196 } else {
197 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
198 dest_y, width, height);
200 XFlush(context->dpy);
201 #endif /* XSHM */
205 #ifdef XSHM
206 Pixmap
207 R_CreateXImageMappedPixmap(RContext *context, RXImage *rximage)
209 Pixmap pix;
211 pix = XShmCreatePixmap(context->dpy, context->drawable,
212 rximage->image->data, &rximage->info,
213 rximage->image->width, rximage->image->height,
214 rximage->image->depth);
216 return pix;
219 #endif /* XSHM */