Fix segfault setting MenuFace pixmap style for menus.
[fvwm.git] / libs / FImage.c
blob9de16e9450c171327c9ae457dbb9b39122fab811
1 /* -*-c-*- */
2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 /* ---------------------------- included header files ---------------------- */
19 #include "config.h"
21 #include <stdio.h>
23 #include <X11/Xlib.h>
25 #include "libs/fvwmlib.h"
26 #include "libs/PictureBase.h"
27 #include "libs/FImage.h"
29 /* ---------------------------- local definitions -------------------------- */
31 /* ---------------------------- local macros ------------------------------- */
33 /* ---------------------------- imports ------------------------------------ */
35 /* ---------------------------- included code files ------------------------ */
37 /* ---------------------------- local types -------------------------------- */
39 /* ---------------------------- forward declarations ----------------------- */
41 /* ---------------------------- local variables ---------------------------- */
43 int FShmMajorOpCode = -10000;
44 int FShmEventBase = -10000;
45 int FShmErrorBase = -10000;
46 Bool FShmInitialized = False;
47 Bool FShmImagesSupported = False;
49 /* ---------------------------- exported variables (globals) --------------- */
51 /* ---------------------------- local functions ---------------------------- */
53 static int FShmErrorHandler(Display *dpy, XErrorEvent *ev)
55 FShmImagesSupported = False;
56 return 0;
59 static void FShmInit(Display *dpy)
61 if (FShmInitialized)
63 return;
66 FShmInitialized = True;
68 if (!XShmSupport)
70 return;
72 FShmImagesSupported = XQueryExtension(
73 dpy, "MIT-SHM", &FShmMajorOpCode, &FShmEventBase,
74 &FShmErrorBase);
77 static void FShmSafeCreateImage(
78 Display *dpy, FImage *fim, Visual *visual, unsigned int depth,
79 int format, unsigned int width, unsigned int height)
81 Bool error = False;
82 XErrorHandler save_handler;
84 if (!XShmSupport)
86 return;
88 fim->shminfo = (FShmSegmentInfo *)safecalloc(
89 1, sizeof(FShmSegmentInfo));
90 if (!(fim->im = FShmCreateImage(
91 dpy, visual, depth, format, NULL, fim->shminfo,
92 width, height)))
94 error = True;
95 goto bail;
97 fim->shminfo->shmid = Fshmget(
98 IPC_PRIVATE,
99 fim->im->bytes_per_line * fim->im->height,
100 IPC_CREAT|0777);
101 if (fim->shminfo->shmid <= 0)
103 error = True;
104 goto bail;
106 fim->shminfo->shmaddr = fim->im->data = Fshmat(
107 fim->shminfo->shmid, 0, 0);
108 if (fim->shminfo->shmaddr == (char *)(-1))
110 error = True;
111 goto bail;
113 fim->shminfo->readOnly = False;
115 /* use the error handler for a definitive error */
116 save_handler = XSetErrorHandler(FShmErrorHandler);
117 if (!FShmAttach(dpy, fim->shminfo))
119 error = True;
121 else
123 XSync(dpy, False);
126 if (!error && !FShmImagesSupported)
128 /* get an X error: we are a remote client */
129 if (FShmDetach(dpy, fim->shminfo))
131 XSync(dpy, False);
133 error = True;
135 XSetErrorHandler(save_handler);
137 bail:
138 if (error)
141 if (fim->im)
143 XDestroyImage (fim->im);
144 fim->im = NULL;
146 if (fim->shminfo->shmaddr)
148 Fshmdt(fim->shminfo->shmaddr);
150 if (fim->shminfo->shmid > 0)
152 Fshmctl(fim->shminfo->shmid, IPC_RMID, 0);
154 free(fim->shminfo);
155 fim->shminfo = NULL;
159 /* ---------------------------- interface functions ------------------------ */
161 FImage *FCreateFImage (
162 Display *dpy, Visual *visual, unsigned int depth, int format,
163 unsigned int width, unsigned int height)
165 FImage *fim;
167 FShmInit(dpy);
169 fim = (FImage *)safemalloc(sizeof(FImage));
170 fim->im = NULL;
171 fim->shminfo = NULL;
173 if (XShmSupport && FShmImagesSupported)
175 FShmSafeCreateImage(
176 dpy, fim, visual, depth, format, width, height);
179 if(!fim->im )
181 if ((fim->im = XCreateImage(
182 dpy, visual, depth, ZPixmap, 0, 0, width, height,
183 Pdepth > 16 ? 32 : (Pdepth > 8 ? 16 : 8), 0)))
185 fim->im->data = safemalloc(
186 fim->im->bytes_per_line * height);
188 else
190 free(fim);
194 return fim;
197 FImage *FGetFImage(
198 Display *dpy, Drawable d, Visual *visual,
199 unsigned int depth, int x, int y, unsigned int width,
200 unsigned int height, unsigned long plane_mask, int format)
202 FImage *fim;
204 FShmInit(dpy);
206 fim = (FImage *)safemalloc(sizeof(FImage));
207 fim->im = NULL;
208 fim->shminfo = NULL;
210 if (XShmSupport && FShmImagesSupported)
212 FShmSafeCreateImage(
213 dpy, fim, visual, depth, format, width, height);
214 if (fim->im)
216 FShmGetImage(
217 dpy, d, fim->im, x, y, plane_mask);
221 if (!fim->im)
223 fim->im = XGetImage(
224 dpy, d, x, y, width, height, plane_mask, format);
227 return fim;
230 void FPutFImage(
231 Display *dpy, Drawable d, GC gc, FImage *fim, int src_x, int src_y,
232 int dest_x, int dest_y, unsigned int width, unsigned int height)
235 if (fim->shminfo)
237 if (FShmPutImage(
238 dpy, d, gc, fim->im, src_x, src_y, dest_x, dest_y, width,
239 height, False))
243 else
245 XPutImage(
246 dpy, d, gc, fim->im, src_x, src_y, dest_x, dest_y, width,
247 height);
251 void FDestroyFImage(Display *dpy, FImage *fim)
253 if (fim->shminfo)
255 if (FShmDetach(dpy, fim->shminfo))
259 XDestroyImage (fim->im);
260 if (fim->shminfo)
262 Fshmdt(fim->shminfo->shmaddr);
263 Fshmctl(fim->shminfo->shmid, IPC_RMID, 0);
264 free(fim->shminfo);
266 free(fim);