Initial revision
[wmaker-crm.git] / wrlib / xutil.c
blob5a6ce952a80c829cc16cfc486a6bef98b2025136
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
42 static int shmError;
44 static int (*oldErrorHandler)();
46 static int
47 errorHandler(Display *dpy, XErrorEvent *err)
49 shmError=1;
50 if(err->error_code!=BadAccess)
51 (*oldErrorHandler)(dpy, err);
53 return 0;
55 #endif
58 RXImage*
59 RCreateXImage(RContext *context, int depth, unsigned width, unsigned height)
61 RXImage *rximg;
63 rximg = malloc(sizeof(RXImage));
64 if (!rximg) {
65 sprintf(RErrorString, "out of memory trying to create XImage");
66 return NULL;
69 #ifndef XSHM
70 rximg->image = XCreateImage(context->dpy, context->visual, depth,
71 ZPixmap, 0, NULL, width, height, 8, 0);
72 if (!rximg->image) {
73 free(rximg);
74 sprintf(RErrorString, "error creating XImage");
75 return NULL;
77 rximg->image->data = malloc(rximg->image->bytes_per_line*height);
78 if (!rximg->image->data) {
79 XDestroyImage(rximg->image);
80 free(rximg);
81 sprintf(RErrorString, "out of memory trying to create XImage");
82 return NULL;
85 #else /* XSHM */
86 if (!context->attribs->use_shared_memory) {
87 retry_without_shm:
88 rximg->is_shared = 0;
89 rximg->image = XCreateImage(context->dpy, context->visual, depth,
90 ZPixmap, 0, NULL, width, height, 8, 0);
91 if (!rximg->image) {
92 free(rximg);
93 sprintf(RErrorString, "error creating XImage");
94 return NULL;
96 rximg->image->data = malloc(rximg->image->bytes_per_line*height);
97 if (!rximg->image->data) {
98 XDestroyImage(rximg->image);
99 free(rximg);
100 sprintf(RErrorString, "out of memory trying to create XImage");
101 return NULL;
103 } else {
104 rximg->is_shared = 1;
106 rximg->image = XShmCreateImage(context->dpy, context->visual, depth,
107 ZPixmap, NULL, &rximg->info, width,
108 height);
110 rximg->info.shmid = shmget(IPC_PRIVATE,
111 rximg->image->bytes_per_line*height,
112 IPC_CREAT|0770);
113 if (rximg->info.shmid < 0) {
114 context->attribs->use_shared_memory = 0;
115 perror("wrlib:could not allocate shared memory segment:");
116 XDestroyImage(rximg->image);
117 goto retry_without_shm;
120 rximg->info.shmaddr = shmat(rximg->info.shmid, 0, 0);
121 if (rximg->info.shmaddr == (void*)-1) {
122 context->attribs->use_shared_memory = 0;
123 if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
124 perror("wrlib:shmctl:");
125 perror("wrlib:could not allocate shared memory");
126 XDestroyImage(rximg->image);
127 goto retry_without_shm;
130 shmError = 0;
131 XSync(context->dpy, False);
132 oldErrorHandler = XSetErrorHandler(errorHandler);
133 XShmAttach(context->dpy, &rximg->info);
134 XSync(context->dpy, False);
135 XSetErrorHandler(oldErrorHandler);
137 rximg->image->data = rximg->info.shmaddr;
138 /* rximg->image->obdata = &(rximg->info);*/
140 if (shmError) {
141 context->attribs->use_shared_memory = 0;
142 XDestroyImage(rximg->image);
143 if (shmdt(rximg->info.shmaddr) < 0)
144 perror("wrlib:shmdt:");
145 if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
146 perror("wrlib:shmctl:");
147 printf("wrlib:error attaching shared memory segment to XImage\n");
148 goto retry_without_shm;
152 #endif /* XSHM */
154 return rximg;
158 void
159 RDestroyXImage(RContext *context, RXImage *rximage)
161 #ifndef XSHM
162 XDestroyImage(rximage->image);
163 #else /* XSHM */
164 if (rximage->is_shared) {
165 XSync(context->dpy, False);
166 XShmDetach(context->dpy, &rximage->info);
167 XDestroyImage(rximage->image);
168 if (shmdt(rximage->info.shmaddr) < 0)
169 perror("wrlib:shmdt:");
170 if (shmctl(rximage->info.shmid, IPC_RMID, 0) < 0)
171 perror("wrlib:shmctl:");
172 } else {
173 XDestroyImage(rximage->image);
175 #endif
176 free(rximage);
180 void
181 RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage, int src_x,
182 int src_y, int dest_x, int dest_y,
183 unsigned int width, unsigned int height)
185 #ifndef XSHM
186 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
187 dest_y, width, height);
188 #else
189 if (ximage->is_shared) {
190 XShmPutImage(context->dpy, d, gc, ximage->image, src_x, src_y,
191 dest_x, dest_y, width, height, False);
192 } else {
193 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x,
194 dest_y, width, height);
196 XFlush(context->dpy);
197 #endif /* XSHM */