1 /* xutil.c - utility functions for X
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.
26 #include <X11/Xutil.h>
44 static int (*oldErrorHandler
)();
47 errorHandler(Display
*dpy
, XErrorEvent
*err
)
50 if(err
->error_code
!=BadAccess
)
51 (*oldErrorHandler
)(dpy
, err
);
59 RCreateXImage(RContext
*context
, int depth
, unsigned width
, unsigned height
)
63 rximg
= malloc(sizeof(RXImage
));
65 sprintf(RErrorString
, "out of memory trying to create XImage");
70 rximg
->image
= XCreateImage(context
->dpy
, context
->visual
, depth
,
71 ZPixmap
, 0, NULL
, width
, height
, 8, 0);
74 sprintf(RErrorString
, "error creating XImage");
77 rximg
->image
->data
= malloc(rximg
->image
->bytes_per_line
*height
);
78 if (!rximg
->image
->data
) {
79 XDestroyImage(rximg
->image
);
81 sprintf(RErrorString
, "out of memory trying to create XImage");
86 if (!context
->attribs
->use_shared_memory
) {
89 rximg
->image
= XCreateImage(context
->dpy
, context
->visual
, depth
,
90 ZPixmap
, 0, NULL
, width
, height
, 8, 0);
93 sprintf(RErrorString
, "error creating XImage");
96 rximg
->image
->data
= malloc(rximg
->image
->bytes_per_line
*height
);
97 if (!rximg
->image
->data
) {
98 XDestroyImage(rximg
->image
);
100 sprintf(RErrorString
, "out of memory trying to create XImage");
104 rximg
->is_shared
= 1;
106 rximg
->image
= XShmCreateImage(context
->dpy
, context
->visual
, depth
,
107 ZPixmap
, NULL
, &rximg
->info
, width
,
110 rximg
->info
.shmid
= shmget(IPC_PRIVATE
,
111 rximg
->image
->bytes_per_line
*height
,
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
;
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 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
;
159 RDestroyXImage(RContext
*context
, RXImage
*rximage
)
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 perror("wrlib:shmdt:");
170 if (shmctl(rximage
->info
.shmid
, IPC_RMID
, 0) < 0)
171 perror("wrlib:shmctl:");
173 XDestroyImage(rximage
->image
);
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
)
186 XPutImage(context
->dpy
, d
, gc
, ximage
->image
, src_x
, src_y
, dest_x
,
187 dest_y
, width
, height
);
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
);
193 XPutImage(context
->dpy
, d
, gc
, ximage
->image
, src_x
, src_y
, dest_x
,
194 dest_y
, width
, height
);
196 XFlush(context
->dpy
);