Fix segfault setting MenuFace pixmap style for menus.
[fvwm.git] / modules / FvwmBanner / FvwmBanner.c
blob294eda00680740511425b7e0d9eeaf8d7d8c5421
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., 675 Mass Ave, Cambridge, MA 02139, USA.
18 * FvwmBanner
20 * Show Fvwm Banner
24 #include "config.h"
26 #ifdef HAVE_SYS_BSDTYPES_H
27 #include <sys/bsdtypes.h> /* Saul */
28 #endif
30 #include <stdio.h>
31 #include <signal.h>
32 #include <fcntl.h>
33 #include <sys/wait.h>
34 #include "libs/ftime.h"
36 #if HAVE_SYS_SELECT_H
37 #include <sys/select.h>
38 #endif
40 #include <ctype.h>
42 #include <X11/Xlib.h>
43 #include <X11/StringDefs.h>
44 #include <X11/Intrinsic.h>
45 #include <X11/Shell.h>
47 #include "libs/fvwmlib.h"
48 #include "libs/Picture.h"
49 #include "libs/Module.h"
50 #include "libs/FScreen.h"
51 #include "libs/FShape.h"
52 #include "libs/FRenderInit.h"
53 #include "libs/Graphics.h"
54 #include "libs/Parse.h"
55 #include "libs/Strings.h"
57 /* migo (16-Sep-1999): How about to do this configurable? */
58 /*#include "fvwm-logo-old.xpm"*/
59 /*#include "fvwm-logo-colorful.xpm"*/
60 #include "fvwm-logo-current.xpm"
61 #include "fvwm-logo-current.xbm"
63 typedef struct _PImageIcon {
64 Pixmap pixmap;
65 Pixmap mask;
66 int width;
67 int height;
68 int depth;
69 } PImageIcon;
72 * A few function prototypes
74 void RedrawWindow(void);
75 void GetXPMData(char **);
76 void GetXBMData(void);
77 void GetImageFile(char *,char *);
78 void change_window_name(char *str);
79 static void parseOptions (int fd[2]);
81 PImageIcon view;
82 Window win;
84 char *imagePath = NULL;
85 char *imageName = NULL;
86 static char *MyName = NULL;
87 static int MyNameLen;
89 int timeout = 3000000; /* default time of 3 seconds */
91 Display *dpy; /* which display are we talking to */
92 Window Root;
93 int screen;
94 int x_fd;
95 XSizeHints mysizehints;
96 Pixel back_pix, fore_pix;
97 GC NormalGC,FGC;
98 static Atom wm_del_win;
99 Bool no_wm = False;
101 #define MW_EVENTS (ExposureMask | ButtonReleaseMask)
105 * Creates an icon window as needed
108 int main(int argc, char **argv)
110 char *display_name = NULL, *string = NULL;
111 int retval = 0;
112 XEvent Event;
113 fd_set in_fdset;
114 struct timeval value;
115 int fd[2];
116 XSetWindowAttributes attr;
117 int wx;
118 int wy;
120 /* Save our program name - for error messages */
121 string = strrchr (argv[0], '/');
122 if (string != (char *) 0) string++;
124 MyNameLen=strlen(string)+1; /* account for '*' */
125 MyName = safemalloc(MyNameLen+1); /* account for \0 */
126 *MyName='*';
127 strcpy (MyName+1, string);
129 if(argc>=3)
131 /* sever our connection with fvwm, if we have one. */
132 fd[0] = atoi(argv[1]);
133 fd[1] = atoi(argv[2]);
135 else
137 fprintf (stderr,
138 "%s: Version "VERSION" should only be executed by fvwm!\n",
139 MyName+1);
140 exit(1);
143 if (argc > 6) {
144 imageName = safemalloc (strlen (argv[6]) + 1);
145 strcpy (imageName, argv[6]);
148 /* Open the display */
149 if (!(dpy = XOpenDisplay(display_name)))
151 fprintf(stderr,"FvwmBanner: can't open display %s",
152 XDisplayName(display_name));
153 exit (1);
155 screen= DefaultScreen(dpy);
156 Root = RootWindow(dpy, screen);
157 x_fd = XConnectionNumber(dpy);
159 flib_init_graphics(dpy);
160 /* SetMessageMask(fd, M_CONFIG_INFO | M_END_CONFIG_INFO | M_SENDCONFIG); */
161 SetMessageMask(fd, M_CONFIG_INFO | M_END_CONFIG_INFO);
162 parseOptions(fd);
164 /* chick in the neck situation:
165 * can't load pixmaps into non-default visual without a window
166 * don't know what size the window should be until pixmap is loaded
168 attr.background_pixmap = None;
169 attr.border_pixel = 0;
170 attr.colormap = Pcmap;
171 attr.override_redirect = no_wm;
172 win = XCreateWindow(dpy, Root, -20, -20, 10, 10, 0, Pdepth, InputOutput,
173 Pvisual,
174 CWColormap|CWBackPixmap|CWBorderPixel|CWOverrideRedirect,
175 &attr);
177 /* Get the xpm banner */
178 if (imageName)
179 GetImageFile(imageName,imagePath);
180 else
181 GetXPMData(fvwm_logo_xpm);
183 if (view.depth != Pdepth)
185 XGCValues gcv;
186 GC gc;
187 Pixmap temp;
189 gcv.background= PictureWhitePixel();
190 gcv.foreground= PictureBlackPixel();
191 gc = fvwmlib_XCreateGC(dpy, win,
192 GCForeground | GCBackground, &gcv);
193 temp = XCreatePixmap(dpy, win, view.width, view.height, Pdepth);
194 XCopyPlane(dpy, view.pixmap, temp, gc,
195 0,0,view.width,view.height, 0,0,1);
196 XFreePixmap(dpy, view.pixmap);
197 XFreeGC(dpy,gc);
198 view.pixmap = temp;
200 XSetWindowBackgroundPixmap(dpy, win, view.pixmap);
202 /* Create a window to hold the banner */
203 mysizehints.flags = USSize | USPosition | PWinGravity | PResizeInc
204 | PBaseSize | PMinSize | PMaxSize;
205 mysizehints.width = view.width;
206 mysizehints.height = view.height;
207 mysizehints.width_inc = 1;
208 mysizehints.height_inc = 1;
209 mysizehints.base_height = mysizehints.height;
210 mysizehints.base_width = mysizehints.width;
211 mysizehints.min_height = mysizehints.height;
212 mysizehints.min_width = mysizehints.width;
213 mysizehints.max_height = mysizehints.height;
214 mysizehints.max_width = mysizehints.width;
215 mysizehints.win_gravity = NorthWestGravity;
217 FScreenCenterOnScreen(
218 NULL, FSCREEN_PRIMARY, &wx, &wy, view.width, view.height);
219 FScreenMangleScreenIntoUSPosHints(FSCREEN_PRIMARY, &mysizehints);
221 wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False);
222 XSetWMProtocols(dpy,win,&wm_del_win,1);
224 XSetWMNormalHints(dpy,win,&mysizehints);
225 change_window_name("FvwmBanner");
227 XMoveResizeWindow(dpy, win, wx, wy, mysizehints.width, mysizehints.height);
229 if (FHaveShapeExtension && view.mask != None)
230 FShapeCombineMask(dpy, win, FShapeBounding, 0, 0, view.mask, FShapeSet);
232 XMapWindow(dpy,win);
233 XSync(dpy,0);
234 XSelectInput(dpy,win,ButtonReleaseMask);
236 /* tell fvwm we're running */
237 SendFinishedStartupNotification(fd);
239 /* Display the window */
240 value.tv_usec = timeout % 1000000;
241 value.tv_sec = timeout / 1000000;
242 while(1)
244 FD_ZERO(&in_fdset);
245 FD_SET(x_fd,&in_fdset);
247 if(!FPending(dpy))
249 retval=select(x_fd + 1,SELECT_FD_SET_CAST &in_fdset, 0, 0, &value);
251 if (retval==0)
253 XDestroyWindow(dpy,win);
254 XSync(dpy,0);
255 exit(0);
258 if (FD_ISSET(x_fd, &in_fdset))
260 /* read a packet */
261 FNextEvent(dpy,&Event);
262 switch(Event.type)
264 case ButtonRelease:
265 XDestroyWindow(dpy,win);
266 XSync(dpy,0);
267 exit(0);
268 case ClientMessage:
269 if (Event.xclient.format==32 && Event.xclient.data.l[0]==wm_del_win)
271 XDestroyWindow(dpy,win);
272 XSync(dpy,0);
273 exit(0);
275 default:
276 break;
280 return 0;
285 * Looks for a color XPM icon file
288 void GetXBMData(void)
290 if ((view.pixmap =
291 XCreatePixmapFromBitmapData(dpy, win, (char *)fvwm_logo_xbm_bits,
292 fvwm_logo_xbm_width, fvwm_logo_xbm_height,
293 BlackPixel(dpy,screen),
294 WhitePixel(dpy,screen),
295 Pdepth)) == None)
297 fprintf(stderr,"FvwmBanner: ERROR couldn't convert data to pixmap\n");
298 exit(1);
300 view.width = fvwm_logo_xbm_width;
301 view.height = fvwm_logo_xbm_height;
302 view.depth = Pdepth;
303 view.mask = None;
306 void GetXPMData(char **data)
308 if(!PImageLoadPixmapFromXpmData(
309 dpy, win, 0, data, &view.pixmap, &view.mask,
310 &view.width, &view.height, &view.depth))
312 GetXBMData();
316 void GetImageFile(char *file, char *path)
318 char *full_file = NULL;
319 FvwmPictureAttributes fpa;
321 fpa.mask = FPAM_NO_ALLOC_PIXELS | FPAM_DITHER | FPAM_NO_ALPHA;
322 if (file)
323 full_file = PictureFindImageFile(file,path,R_OK);
325 if (full_file)
327 if(PImageLoadPixmapFromFile(
328 dpy, Root, full_file, &view.pixmap, &view.mask, None,
329 &view.width, &view.height, &view.depth, 0, NULL, 0,
330 fpa))
332 return;
334 fprintf(stderr,"FvwmBanner: ERROR loading image file\n");
336 else
338 fprintf(stderr,
339 "FvwmBanner: ERROR finding image file in ImagePath\n");
340 GetXPMData(fvwm_logo_xpm);
344 static void parseOptions(int fd[2])
346 char *tline= NULL;
347 char *tok;
349 InitGetConfigLine(fd,MyName);
350 while (GetConfigLine (fd, &tline),tline != NULL)
352 if (strlen(tline) > 1)
354 tok = PeekToken(tline, &tline);
355 if (StrEquals(tok, XINERAMA_CONFIG_STRING))
357 FScreenConfigureModule(tline);
358 continue;
360 if (StrEquals(tok, "ImagePath"))
362 CopyString(&imagePath, tline);
363 if (imagePath[0] == 0)
365 free (imagePath);
366 imagePath = (char *) 0;
368 continue;
370 if (strncasecmp(tok,MyName,MyNameLen))
372 /* if not for me: ignore it*/
373 continue;
375 /* start of interesting part */
376 tok += MyNameLen;
377 if (StrEquals(tok, "Pixmap"))
379 if (imageName == (char *) 0)
381 CopyString(&imageName, tline);
382 if (imageName[0] == 0)
384 free (imageName);
385 imageName = (char *) 0;
388 continue;
390 if (StrEquals(tok, "NoDecor"))
392 no_wm = True;
393 continue;
395 if (StrEquals(tok, "Timeout"))
397 timeout = atoi(tline) * 1000000;
398 continue;
402 return;
406 * Change the window name displayed in the title bar.
408 void change_window_name(char *str)
410 XTextProperty name;
412 if (XStringListToTextProperty(&str,1,&name) == 0)
414 fprintf(stderr,"FvwmBanner: cannot allocate window name");
415 return;
417 XSetWMName(dpy,win,&name);
418 XSetWMIconName(dpy,win,&name);
419 XFree(name.value);
425 * Procedure:
426 * SIGPIPE handler - SIGPIPE means fvwm is dying
430 /*ARGSUSED*/
431 RETSIGTYPE DeadPipe (int nonsense)
433 exit (0);
434 SIGNAL_RETURN;