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,
26 #include <X11/Xutil.h>
45 static int (*oldErrorHandler
)(Display
*dpy
, XErrorEvent
*err
);
47 static int errorHandler(Display
* dpy
, XErrorEvent
* err
)
50 if (err
->error_code
!= BadAccess
)
51 (*oldErrorHandler
) (dpy
, err
);
58 RXImage
*RCreateXImage(RContext
* context
, int depth
, unsigned width
, unsigned height
)
61 Visual
*visual
= context
->visual
;
63 rximg
= malloc(sizeof(RXImage
));
65 RErrorCode
= RERR_NOMEMORY
;
69 rximg
->image
= XCreateImage(context
->dpy
, visual
, depth
, ZPixmap
, 0, NULL
, width
, height
, 8, 0);
72 RErrorCode
= RERR_XERROR
;
75 rximg
->image
->data
= malloc(rximg
->image
->bytes_per_line
* height
);
76 if (!rximg
->image
->data
) {
77 XDestroyImage(rximg
->image
);
79 RErrorCode
= RERR_NOMEMORY
;
83 if (!context
->attribs
->use_shared_memory
) {
86 context
->attribs
->use_shared_memory
= 0;
88 rximg
->image
= XCreateImage(context
->dpy
, visual
, depth
, ZPixmap
, 0, NULL
, width
, height
, 8, 0);
91 RErrorCode
= RERR_XERROR
;
94 rximg
->image
->data
= malloc(rximg
->image
->bytes_per_line
* height
);
95 if (!rximg
->image
->data
) {
96 XDestroyImage(rximg
->image
);
98 RErrorCode
= RERR_NOMEMORY
;
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
;
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); */
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 */
154 void RDestroyXImage(RContext
* context
, RXImage
* rximage
)
157 /* Argument is not used in this case, tell the compiler it is ok */
160 XDestroyImage(rximage
->image
);
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");
171 XDestroyImage(rximage
->image
);
177 static unsigned getDepth(Display
* dpy
, Drawable d
)
184 XGetGeometry(dpy
, d
, &w
, &foo
, &foo
, &bar
, &bar
, &bar
, &depth
);
189 RXImage
*RGetXImage(RContext
* context
, Drawable d
, int x
, int y
, unsigned width
, unsigned height
)
191 RXImage
*ximg
= NULL
;
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
);
202 XShmGetImage(context
->dpy
, d
, ximg
->image
, x
, y
, AllPlanes
);
206 ximg
= malloc(sizeof(RXImage
));
208 RErrorCode
= RERR_NOMEMORY
;
212 ximg
->image
= XGetImage(context
->dpy
, d
, x
, y
, width
, height
, AllPlanes
, ZPixmap
);
214 #else /* !USE_XSHM */
215 ximg
= malloc(sizeof(RXImage
));
217 RErrorCode
= RERR_NOMEMORY
;
221 ximg
->image
= XGetImage(context
->dpy
, d
, x
, y
, width
, height
, AllPlanes
, ZPixmap
);
222 #endif /* !USE_XSHM */
224 if (ximg
->image
== NULL
) {
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
)
237 XPutImage(context
->dpy
, d
, gc
, ximage
->image
, src_x
, src_y
, dest_x
, dest_y
, width
, height
);
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
);
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 */
250 Pixmap
R_CreateXImageMappedPixmap(RContext
* context
, RXImage
* rximage
)
254 pix
= XShmCreatePixmap(context
->dpy
, context
->drawable
,
255 rximage
->image
->data
, &rximage
->info
,
256 rximage
->image
->width
, rximage
->image
->height
, rximage
->image
->depth
);
261 #endif /* USE_XSHM */