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., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <X11/Xutil.h>
45 static int (*oldErrorHandler
)();
48 errorHandler(Display
*dpy
, XErrorEvent
*err
)
51 if(err
->error_code
!=BadAccess
)
52 (*oldErrorHandler
)(dpy
, err
);
62 RCreateXImage(RContext
*context
, int depth
, unsigned width
, unsigned height
)
65 Visual
*visual
= context
->visual
;
67 rximg
= malloc(sizeof(RXImage
));
69 RErrorCode
= RERR_NOMEMORY
;
74 rximg
->image
= XCreateImage(context
->dpy
, visual
, depth
,
75 ZPixmap
, 0, NULL
, width
, height
, 8, 0);
78 RErrorCode
= RERR_XERROR
;
81 rximg
->image
->data
= malloc(rximg
->image
->bytes_per_line
*height
);
82 if (!rximg
->image
->data
) {
83 XDestroyImage(rximg
->image
);
85 RErrorCode
= RERR_NOMEMORY
;
90 if (!context
->attribs
->use_shared_memory
) {
93 context
->attribs
->use_shared_memory
= 0;
95 rximg
->image
= XCreateImage(context
->dpy
, visual
, depth
,
96 ZPixmap
, 0, NULL
, width
, height
, 8, 0);
99 RErrorCode
= RERR_XERROR
;
102 rximg
->image
->data
= malloc(rximg
->image
->bytes_per_line
*height
);
103 if (!rximg
->image
->data
) {
104 XDestroyImage(rximg
->image
);
106 RErrorCode
= RERR_NOMEMORY
;
110 rximg
->is_shared
= 1;
112 rximg
->info
.readOnly
= False
;
114 rximg
->image
= XShmCreateImage(context
->dpy
, visual
, depth
,
115 ZPixmap
, NULL
, &rximg
->info
, width
,
118 rximg
->info
.shmid
= shmget(IPC_PRIVATE
,
119 rximg
->image
->bytes_per_line
*height
,
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
;
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);*/
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
;
167 RDestroyXImage(RContext
*context
, RXImage
*rximage
)
170 XDestroyImage(rximage
->image
);
172 if (rximage
->is_shared
) {
173 XSync(context
->dpy
, False
);
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");
181 XDestroyImage(rximage
->image
);
189 getDepth(Display
*dpy
, Drawable d
)
196 XGetGeometry(dpy
, d
, &w
, &foo
, &foo
, &bar
, &bar
, &bar
, &depth
);
204 RGetXImage(RContext
*context
, Drawable d
, int x
, int y
,
205 unsigned width
, unsigned height
)
207 RXImage
*ximg
= NULL
;
210 if (context
->attribs
->use_shared_memory
&& 0) {
211 ximg
= RCreateXImage(context
, getDepth(context
->dpy
, d
),
214 if (ximg
&& !ximg
->is_shared
) {
215 RDestroyXImage(context
, ximg
);
219 XShmGetImage(context
->dpy
, d
, ximg
->image
, x
, y
, AllPlanes
);
223 ximg
= malloc(sizeof(RXImage
));
225 RErrorCode
= RERR_NOMEMORY
;
229 ximg
->image
= XGetImage(context
->dpy
, d
, x
, y
, width
, height
,
234 ximg
= malloc(sizeof(RXImage
));
236 RErrorCode
= RERR_NOMEMORY
;
240 ximg
->image
= XGetImage(context
->dpy
, d
, x
, y
, width
, height
,
249 RPutXImage(RContext
*context
, Drawable d
, GC gc
, RXImage
*ximage
, int src_x
,
250 int src_y
, int dest_x
, int dest_y
,
251 unsigned int width
, unsigned int height
)
254 XPutImage(context
->dpy
, d
, gc
, ximage
->image
, src_x
, src_y
, dest_x
,
255 dest_y
, width
, height
);
257 if (ximage
->is_shared
) {
258 XShmPutImage(context
->dpy
, d
, gc
, ximage
->image
, src_x
, src_y
,
259 dest_x
, dest_y
, width
, height
, False
);
261 XPutImage(context
->dpy
, d
, gc
, ximage
->image
, src_x
, src_y
, dest_x
,
262 dest_y
, width
, height
);
264 XFlush(context
->dpy
);
271 R_CreateXImageMappedPixmap(RContext
*context
, RXImage
*rximage
)
275 pix
= XShmCreatePixmap(context
->dpy
, context
->drawable
,
276 rximage
->image
->data
, &rximage
->info
,
277 rximage
->image
->width
, rximage
->image
->height
,
278 rximage
->image
->depth
);