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>
48 static int (*oldErrorHandler
)(Display
*dpy
, XErrorEvent
*err
);
50 static int errorHandler(Display
* dpy
, XErrorEvent
* err
)
53 if (err
->error_code
!= BadAccess
)
54 (*oldErrorHandler
) (dpy
, err
);
61 RXImage
*RCreateXImage(RContext
* context
, int depth
, unsigned width
, unsigned height
)
64 Visual
*visual
= context
->visual
;
66 rximg
= malloc(sizeof(RXImage
));
68 RErrorCode
= RERR_NOMEMORY
;
72 rximg
->image
= XCreateImage(context
->dpy
, visual
, depth
, ZPixmap
, 0, NULL
, width
, height
, 8, 0);
75 RErrorCode
= RERR_XERROR
;
78 rximg
->image
->data
= malloc(rximg
->image
->bytes_per_line
* height
);
79 if (!rximg
->image
->data
) {
80 XDestroyImage(rximg
->image
);
82 RErrorCode
= RERR_NOMEMORY
;
86 if (!context
->attribs
->use_shared_memory
) {
89 context
->attribs
->use_shared_memory
= 0;
91 rximg
->image
= XCreateImage(context
->dpy
, visual
, depth
, ZPixmap
, 0, NULL
, width
, height
, 8, 0);
94 RErrorCode
= RERR_XERROR
;
97 rximg
->image
->data
= malloc(rximg
->image
->bytes_per_line
* height
);
98 if (!rximg
->image
->data
) {
99 XDestroyImage(rximg
->image
);
101 RErrorCode
= RERR_NOMEMORY
;
105 rximg
->is_shared
= 1;
107 rximg
->info
.readOnly
= False
;
109 rximg
->image
= XShmCreateImage(context
->dpy
, visual
, depth
,
110 ZPixmap
, NULL
, &rximg
->info
, width
, height
);
112 rximg
->info
.shmid
= shmget(IPC_PRIVATE
, rximg
->image
->bytes_per_line
* height
, IPC_CREAT
| 0777);
113 if (rximg
->info
.shmid
< 0) {
114 context
->attribs
->use_shared_memory
= 0;
115 fprintf(stderr
, _("wrlib: could not allocate shared memory segment, %s: %s\n"), "shmget", strerror(errno
));
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 fprintf(stderr
, _("wrlib: could not allocate shared memory segment, %s: %s\n"), "shmat", strerror(errno
));
123 context
->attribs
->use_shared_memory
= 0;
124 if (shmctl(rximg
->info
.shmid
, IPC_RMID
, 0) < 0)
125 fprintf(stderr
, _("wrlib: error occured while aborting %s, %s\n"), "shmctl", strerror(errno
));
126 XDestroyImage(rximg
->image
);
127 goto retry_without_shm
;
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); */
141 fprintf(stderr
, _("wrlib: could not attach shared memory segment to XImage\n"));
142 context
->attribs
->use_shared_memory
= 0;
143 XDestroyImage(rximg
->image
);
144 if (shmdt(rximg
->info
.shmaddr
) < 0)
145 fprintf(stderr
, _("wrlib: error occured while aborting %s, %s\n"), "shmdt", strerror(errno
));
146 if (shmctl(rximg
->info
.shmid
, IPC_RMID
, 0) < 0)
147 fprintf(stderr
, _("wrlib: error occured while aborting %s, %s\n"), "shmctl", strerror(errno
));
148 goto retry_without_shm
;
151 #endif /* USE_XSHM */
156 void RDestroyXImage(RContext
* context
, RXImage
* rximage
)
159 /* Argument is not used in this case, tell the compiler it is ok */
162 XDestroyImage(rximage
->image
);
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 fprintf(stderr
, _("wrlib: error occured while releasing XImage, %s: %s\n"), "shmdt", strerror(errno
));
170 if (shmctl(rximage
->info
.shmid
, IPC_RMID
, 0) < 0)
171 fprintf(stderr
, _("wrlib: error occured while releasing XImage, %s: %s\n"), "shmctl", strerror(errno
));
173 XDestroyImage(rximage
->image
);
179 static unsigned getDepth(Display
* dpy
, Drawable d
)
186 XGetGeometry(dpy
, d
, &w
, &foo
, &foo
, &bar
, &bar
, &bar
, &depth
);
191 RXImage
*RGetXImage(RContext
* context
, Drawable d
, int x
, int y
, unsigned width
, unsigned height
)
193 RXImage
*ximg
= NULL
;
196 if (context
->attribs
->use_shared_memory
&& 0) {
197 ximg
= RCreateXImage(context
, getDepth(context
->dpy
, d
), width
, height
);
199 if (ximg
&& !ximg
->is_shared
) {
200 RDestroyXImage(context
, ximg
);
204 XShmGetImage(context
->dpy
, d
, ximg
->image
, x
, y
, AllPlanes
);
208 ximg
= malloc(sizeof(RXImage
));
210 RErrorCode
= RERR_NOMEMORY
;
214 ximg
->image
= XGetImage(context
->dpy
, d
, x
, y
, width
, height
, AllPlanes
, ZPixmap
);
216 #else /* !USE_XSHM */
217 ximg
= malloc(sizeof(RXImage
));
219 RErrorCode
= RERR_NOMEMORY
;
223 ximg
->image
= XGetImage(context
->dpy
, d
, x
, y
, width
, height
, AllPlanes
, ZPixmap
);
224 #endif /* !USE_XSHM */
226 if (ximg
->image
== NULL
) {
235 RPutXImage(RContext
* context
, Drawable d
, GC gc
, RXImage
* ximage
, int src_x
,
236 int src_y
, int dest_x
, int dest_y
, unsigned int width
, unsigned int height
)
239 XPutImage(context
->dpy
, d
, gc
, ximage
->image
, src_x
, src_y
, dest_x
, dest_y
, width
, height
);
241 if (ximage
->is_shared
) {
242 XShmPutImage(context
->dpy
, d
, gc
, ximage
->image
, src_x
, src_y
,
243 dest_x
, dest_y
, width
, height
, False
);
245 XPutImage(context
->dpy
, d
, gc
, ximage
->image
, src_x
, src_y
, dest_x
, dest_y
, width
, height
);
247 XFlush(context
->dpy
);
248 #endif /* USE_XSHM */
252 Pixmap
R_CreateXImageMappedPixmap(RContext
* context
, RXImage
* rximage
)
256 pix
= XShmCreatePixmap(context
->dpy
, context
->drawable
,
257 rximage
->image
->data
, &rximage
->info
,
258 rximage
->image
->width
, rximage
->image
->height
, rximage
->image
->depth
);
263 #endif /* USE_XSHM */