Change to the linux kernel coding style
[wmaker-crm.git] / wrlib / xutil.c
Commit [+]AuthorDateLineData
9d2e6ef9 scottc1998-09-29 22:36:29 +00001/* xutil.c - utility functions for X
6830b057 dan2004-10-12 21:28:27 +00002 *
4153e2fd dan2003-01-16 23:30:45 +00003 * Raster graphics library
9d2e6ef9 scottc1998-09-29 22:36:29 +00004 *
4153e2fd dan2003-01-16 23:30:45 +00005 * Copyright (c) 1997-2003 Alfredo K. Kojima
9d2e6ef9 scottc1998-09-29 22:36:29 +00006 *
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.
6830b057 dan2004-10-12 21:28:27 +000011 *
9d2e6ef9 scottc1998-09-29 22:36:29 +000012 * 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.
6830b057 dan2004-10-12 21:28:27 +000016 *
9d2e6ef9 scottc1998-09-29 22:36:29 +000017 * 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.
20 */
21
22#include <config.h>
23
9d2e6ef9 scottc1998-09-29 22:36:29 +000024#include <X11/Xlib.h>
25#include <X11/Xutil.h>
26#include <stdlib.h>
27#include <stdio.h>
28#include <string.h>
29
30#include <assert.h>
31
32#ifdef XSHM
33#include <sys/ipc.h>
34#include <sys/shm.h>
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020035#endif /* XSHM */
9d2e6ef9 scottc1998-09-29 22:36:29 +000036
37#include "wraster.h"
38
9d2e6ef9 scottc1998-09-29 22:36:29 +000039#ifdef XSHM
9af1c6c4 dan1998-10-21 14:43:47 +000040
9d2e6ef9 scottc1998-09-29 22:36:29 +000041static int shmError;
42
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020043static int (*oldErrorHandler) ();
9d2e6ef9 scottc1998-09-29 22:36:29 +000044
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020045static int errorHandler(Display * dpy, XErrorEvent * err)
9d2e6ef9 scottc1998-09-29 22:36:29 +000046{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020047 shmError = 1;
48 if (err->error_code != BadAccess)
49 (*oldErrorHandler) (dpy, err);
9d2e6ef9 scottc1998-09-29 22:36:29 +000050
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020051 return 0;
9d2e6ef9 scottc1998-09-29 22:36:29 +000052}
9af1c6c4 dan1998-10-21 14:43:47 +000053
9d2e6ef9 scottc1998-09-29 22:36:29 +000054#endif
55
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020056RXImage *RCreateXImage(RContext * context, int depth, unsigned width, unsigned height)
9d2e6ef9 scottc1998-09-29 22:36:29 +000057{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020058 RXImage *rximg;
59 Visual *visual = context->visual;
60
61 rximg = malloc(sizeof(RXImage));
62 if (!rximg) {
63 RErrorCode = RERR_NOMEMORY;
64 return NULL;
65 }
9d2e6ef9 scottc1998-09-29 22:36:29 +000066#ifndef XSHM
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020067 rximg->image = XCreateImage(context->dpy, visual, depth, ZPixmap, 0, NULL, width, height, 8, 0);
68 if (!rximg->image) {
69 free(rximg);
70 RErrorCode = RERR_XERROR;
71 return NULL;
72 }
73 rximg->image->data = malloc(rximg->image->bytes_per_line * height);
74 if (!rximg->image->data) {
75 XDestroyImage(rximg->image);
76 free(rximg);
77 RErrorCode = RERR_NOMEMORY;
78 return NULL;
79 }
80#else /* XSHM */
81 if (!context->attribs->use_shared_memory) {
82 retry_without_shm:
83
84 context->attribs->use_shared_memory = 0;
85 rximg->is_shared = 0;
86 rximg->image = XCreateImage(context->dpy, visual, depth, ZPixmap, 0, NULL, width, height, 8, 0);
87 if (!rximg->image) {
88 free(rximg);
89 RErrorCode = RERR_XERROR;
90 return NULL;
91 }
92 rximg->image->data = malloc(rximg->image->bytes_per_line * height);
93 if (!rximg->image->data) {
94 XDestroyImage(rximg->image);
95 free(rximg);
96 RErrorCode = RERR_NOMEMORY;
97 return NULL;
98 }
99 } else {
100 rximg->is_shared = 1;
101
102 rximg->info.readOnly = False;
103
104 rximg->image = XShmCreateImage(context->dpy, visual, depth,
105 ZPixmap, NULL, &rximg->info, width, height);
106
107 rximg->info.shmid = shmget(IPC_PRIVATE, rximg->image->bytes_per_line * height, IPC_CREAT | 0777);
108 if (rximg->info.shmid < 0) {
109 context->attribs->use_shared_memory = 0;
110 perror("wrlib: could not allocate shared memory segment");
111 XDestroyImage(rximg->image);
112 goto retry_without_shm;
113 }
114
115 rximg->info.shmaddr = shmat(rximg->info.shmid, 0, 0);
116 if (rximg->info.shmaddr == (void *)-1) {
117 context->attribs->use_shared_memory = 0;
118 if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
119 perror("wrlib: shmctl");
120 perror("wrlib: could not allocate shared memory");
121 XDestroyImage(rximg->image);
122 goto retry_without_shm;
123 }
124
125 shmError = 0;
126 XSync(context->dpy, False);
127 oldErrorHandler = XSetErrorHandler(errorHandler);
128 XShmAttach(context->dpy, &rximg->info);
129 XSync(context->dpy, False);
130 XSetErrorHandler(oldErrorHandler);
131
132 rximg->image->data = rximg->info.shmaddr;
133 /* rximg->image->obdata = &(rximg->info); */
134
135 if (shmError) {
136 context->attribs->use_shared_memory = 0;
137 XDestroyImage(rximg->image);
138 if (shmdt(rximg->info.shmaddr) < 0)
139 perror("wrlib: shmdt");
140 if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
141 perror("wrlib: shmctl");
142 /* printf("wrlib:error attaching shared memory segment to XImage\n");
143 */
144 goto retry_without_shm;
145 }
146 }
147#endif /* XSHM */
148
149 return rximg;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000150}
151
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200152void RDestroyXImage(RContext * context, RXImage * rximage)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000153{
154#ifndef XSHM
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200155 XDestroyImage(rximage->image);
156#else /* XSHM */
157 if (rximage->is_shared) {
158 XSync(context->dpy, False);
159 XShmDetach(context->dpy, &rximage->info);
160 XDestroyImage(rximage->image);
161 if (shmdt(rximage->info.shmaddr) < 0)
162 perror("wrlib: shmdt");
163 if (shmctl(rximage->info.shmid, IPC_RMID, 0) < 0)
164 perror("wrlib: shmctl");
165 } else {
166 XDestroyImage(rximage->image);
167 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000168#endif
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200169 free(rximage);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000170}
171
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200172static unsigned getDepth(Display * dpy, Drawable d)
7f9f8894 kojima1999-03-15 23:41:22 +0000173{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200174 Window w;
175 int foo;
176 unsigned bar;
177 unsigned depth;
6830b057 dan2004-10-12 21:28:27 +0000178
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200179 XGetGeometry(dpy, d, &w, &foo, &foo, &bar, &bar, &bar, &depth);
6830b057 dan2004-10-12 21:28:27 +0000180
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200181 return depth;
7f9f8894 kojima1999-03-15 23:41:22 +0000182}
183
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200184RXImage *RGetXImage(RContext * context, Drawable d, int x, int y, unsigned width, unsigned height)
7f9f8894 kojima1999-03-15 23:41:22 +0000185{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200186 RXImage *ximg = NULL;
7f9f8894 kojima1999-03-15 23:41:22 +0000187
188#ifdef XSHM
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200189 if (context->attribs->use_shared_memory && 0) {
190 ximg = RCreateXImage(context, getDepth(context->dpy, d), width, height);
191
192 if (ximg && !ximg->is_shared) {
193 RDestroyXImage(context, ximg);
194 ximg = NULL;
195 }
196 if (ximg) {
197 XShmGetImage(context->dpy, d, ximg->image, x, y, AllPlanes);
198 }
199 }
200 if (!ximg) {
201 ximg = malloc(sizeof(RXImage));
202 if (!ximg) {
203 RErrorCode = RERR_NOMEMORY;
204 return NULL;
205 }
206 ximg->is_shared = 0;
207 ximg->image = XGetImage(context->dpy, d, x, y, width, height, AllPlanes, ZPixmap);
208 }
209 return ximg;
210#else /* !XSHM */
211 ximg = malloc(sizeof(RXImage));
212 if (!ximg) {
213 RErrorCode = RERR_NOMEMORY;
214 return NULL;
215 }
216
217 ximg->image = XGetImage(context->dpy, d, x, y, width, height, AllPlanes, ZPixmap);
218
219 return ximg;
220#endif /* !XSHM */
7f9f8894 kojima1999-03-15 23:41:22 +0000221}
222
9d2e6ef9 scottc1998-09-29 22:36:29 +0000223void
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200224RPutXImage(RContext * context, Drawable d, GC gc, RXImage * ximage, int src_x,
225 int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000226{
227#ifndef XSHM
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200228 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x, dest_y, width, height);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000229#else
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200230 if (ximage->is_shared) {
231 XShmPutImage(context->dpy, d, gc, ximage->image, src_x, src_y,
232 dest_x, dest_y, width, height, False);
233 } else {
234 XPutImage(context->dpy, d, gc, ximage->image, src_x, src_y, dest_x, dest_y, width, height);
235 }
236 XFlush(context->dpy);
237#endif /* XSHM */
9d2e6ef9 scottc1998-09-29 22:36:29 +0000238}
239
9af1c6c4 dan1998-10-21 14:43:47 +0000240#ifdef XSHM
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200241Pixmap R_CreateXImageMappedPixmap(RContext * context, RXImage * rximage)
9af1c6c4 dan1998-10-21 14:43:47 +0000242{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200243 Pixmap pix;
9af1c6c4 dan1998-10-21 14:43:47 +0000244
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200245 pix = XShmCreatePixmap(context->dpy, context->drawable,
246 rximage->image->data, &rximage->info,
247 rximage->image->width, rximage->image->height, rximage->image->depth);
9af1c6c4 dan1998-10-21 14:43:47 +0000248
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200249 return pix;
9af1c6c4 dan1998-10-21 14:43:47 +0000250}
251
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200252#endif /* XSHM */