This update includes the 0.20.3pre3 code
[wmaker-crm.git] / wrlib / xutil.c
blobbc6034f1aa41a142d298d2e7891bd684b33c6bcb
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:
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 free(rximage);
172 #else /* XSHM */
173 if (rximage->is_shared) {
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
187 void
188 RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage, int src_x,
189 int src_y, int dest_x, int dest_y,
190 unsigned int width, unsigned int height)
192 #ifndef XSHM
193 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
194 dest_y, width, height);
195 #else
196 if (ximage->is_shared) {
197 XShmPutImage(context->dpy, d, gc, ximage->image, src_x, src_y,
198 dest_x, dest_y, width, height, False);
199 } else {
200 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
201 dest_y, width, height);
203 XFlush(context->dpy);
204 #endif /* XSHM */
208 #ifdef XSHM
209 Pixmap
210 R_CreateXImageMappedPixmap(RContext *context, RXImage *rximage)
212 Pixmap pix;
214 pix = XShmCreatePixmap(context->dpy, context->drawable,
215 rximage->image->data, &rximage->info,
216 rximage->image->width, rximage->image->height,
217 rximage->image->depth);
219 return pix;
222 #endif /* XSHM */