bef0985cf735fbecc84b84724a1b145ae6420412
[wmaker-crm.git] / src / dialog.c
blobbef0985cf735fbecc84b84724a1b145ae6420412
1 /* dialog.c - dialog windows for internal use
3 * Window Maker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 1998-2003 Dan Pascu
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "wconfig.h"
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <X11/keysym.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <dirent.h>
36 #include <limits.h>
38 #ifdef HAVE_MALLOC_H
39 #include <malloc.h>
40 #endif
42 #include <signal.h>
43 #ifdef __FreeBSD__
44 #include <sys/signal.h>
45 #endif
47 #ifndef PATH_MAX
48 #define PATH_MAX DEFAULT_PATH_MAX
49 #endif
51 #include "WindowMaker.h"
52 #include "GNUstep.h"
53 #include "screen.h"
54 #include "window.h"
55 #include "dialog.h"
56 #include "misc.h"
57 #include "stacking.h"
58 #include "framewin.h"
59 #include "window.h"
60 #include "actions.h"
61 #include "xinerama.h"
63 extern WPreferences wPreferences;
65 static WMPoint getCenter(WScreen * scr, int width, int height)
67 return wGetPointToCenterRectInHead(scr, wGetHeadForPointerLocation(scr), width, height);
70 int wMessageDialog(WScreen *scr, const char *title, const char *message, const char *defBtn, const char *altBtn, const char *othBtn)
72 WMAlertPanel *panel;
73 Window parent;
74 WWindow *wwin;
75 int result;
76 WMPoint center;
78 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
80 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
82 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
84 center = getCenter(scr, 400, 180);
85 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
86 wwin->client_leader = WMWidgetXID(panel->win);
88 WMMapWidget(panel->win);
90 wWindowMap(wwin);
92 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
94 result = panel->result;
96 WMUnmapWidget(panel->win);
98 wUnmanageWindow(wwin, False, False);
100 WMDestroyAlertPanel(panel);
102 XDestroyWindow(dpy, parent);
104 return result;
107 static void toggleSaveSession(WMWidget *w, void *data)
109 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
112 int wExitDialog(WScreen *scr, const char *title, const char *message, const char *defBtn, const char *altBtn, const char *othBtn)
114 WMAlertPanel *panel;
115 WMButton *saveSessionBtn;
116 Window parent;
117 WWindow *wwin;
118 WMPoint center;
119 int result;
121 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
123 /* add save session button */
124 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
125 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
126 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn), False, True, 200, 0, 0);
127 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
128 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
129 WMRealizeWidget(saveSessionBtn);
130 WMMapWidget(saveSessionBtn);
132 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
134 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
136 center = getCenter(scr, 400, 180);
137 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
139 wwin->client_leader = WMWidgetXID(panel->win);
141 WMMapWidget(panel->win);
143 wWindowMap(wwin);
145 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
147 result = panel->result;
149 WMUnmapWidget(panel->win);
151 wUnmanageWindow(wwin, False, False);
153 WMDestroyAlertPanel(panel);
155 XDestroyWindow(dpy, parent);
157 return result;
160 typedef struct _WMInputPanelWithHistory {
161 WMInputPanel *panel;
162 WMArray *history;
163 int histpos;
164 char *prefix;
165 char *suffix;
166 char *rest;
167 WMArray *variants;
168 int varpos;
169 } WMInputPanelWithHistory;
171 static char *HistoryFileName(const char *name)
173 char *filename = NULL;
175 filename = wstrdup(wusergnusteppath());
176 filename = wstrappend(filename, "/.AppInfo/WindowMaker/History");
177 if (name && strlen(name)) {
178 filename = wstrappend(filename, ".");
179 filename = wstrappend(filename, name);
181 return filename;
184 static int strmatch(const void *str1, const void *str2)
186 return !strcmp((const char *)str1, (const char *)str2);
189 static WMArray *LoadHistory(const char *filename, int max)
191 WMPropList *plhistory;
192 WMPropList *plitem;
193 WMArray *history;
194 int i, num;
195 char *str;
197 history = WMCreateArrayWithDestructor(1, wfree);
198 WMAddToArray(history, wstrdup(""));
200 plhistory = WMReadPropListFromFile(filename);
202 if (plhistory) {
203 if (WMIsPLArray(plhistory)) {
204 num = WMGetPropListItemCount(plhistory);
206 for (i = 0; i < num; ++i) {
207 plitem = WMGetFromPLArray(plhistory, i);
208 if (WMIsPLString(plitem)) {
209 str = WMGetFromPLString(plitem);
210 if (WMFindInArray(history, strmatch, str) == WANotFound) {
212 * The string here is duplicated because it will be freed
213 * automatically when the array is deleted. This is not really
214 * great because it is already an allocated string,
215 * unfortunately we cannot re-use it because it will be freed
216 * when we discard the PL (and we don't want to waste the PL's
217 * memory either)
219 WMAddToArray(history, wstrdup(str));
220 if (--max <= 0)
221 break;
226 WMReleasePropList(plhistory);
229 return history;
232 static void SaveHistory(WMArray * history, const char *filename)
234 int i;
235 WMPropList *plhistory;
237 plhistory = WMCreatePLArray(NULL);
239 for (i = 0; i < WMGetArrayItemCount(history); ++i)
240 WMAddToPLArray(plhistory, WMCreatePLString(WMGetFromArray(history, i)));
242 WMWritePropListToFile(plhistory, filename);
243 WMReleasePropList(plhistory);
246 static int pstrcmp(const char **str1, const char **str2)
248 return strcmp(*str1, *str2);
251 static void
252 ScanFiles(const char *dir, const char *prefix, unsigned acceptmask, unsigned declinemask, WMArray * result)
254 int prefixlen;
255 DIR *d;
256 struct dirent *de;
257 struct stat sb;
258 char *fullfilename, *suffix;
260 prefixlen = strlen(prefix);
261 if ((d = opendir(dir)) != NULL) {
262 while ((de = readdir(d)) != NULL) {
263 if (strlen(de->d_name) > prefixlen &&
264 !strncmp(prefix, de->d_name, prefixlen) &&
265 strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..")) {
266 fullfilename = wstrconcat((char *)dir, "/");
267 fullfilename = wstrappend(fullfilename, de->d_name);
269 if (stat(fullfilename, &sb) == 0 &&
270 (sb.st_mode & acceptmask) &&
271 !(sb.st_mode & declinemask) &&
272 WMFindInArray(result, (WMMatchDataProc *) strmatch,
273 de->d_name + prefixlen) == WANotFound) {
274 suffix = wstrdup(de->d_name + prefixlen);
275 if (sb.st_mode & S_IFDIR)
276 wstrappend(suffix,"/");
277 WMAddToArray(result, suffix);
279 wfree(fullfilename);
282 closedir(d);
286 static WMArray *GenerateVariants(const char *complete)
288 Bool firstWord = True;
289 WMArray *variants = NULL;
290 char *pos = NULL, *path = NULL, *tmp = NULL, *dir = NULL, *prefix = NULL;
292 variants = WMCreateArrayWithDestructor(0, wfree);
294 while (*complete == ' ')
295 ++complete;
297 if ((pos = strrchr(complete, ' ')) != NULL) {
298 complete = pos + 1;
299 firstWord = False;
302 if ((pos = strrchr(complete, '/')) != NULL) {
303 tmp = wstrndup((char *)complete, pos - complete + 1);
304 if (*tmp == '~' && *(tmp + 1) == '/' && getenv("HOME")) {
305 dir = wstrdup(getenv("HOME"));
306 dir = wstrappend(dir, tmp + 1);
307 wfree(tmp);
308 } else {
309 dir = tmp;
311 prefix = wstrdup(pos + 1);
312 ScanFiles(dir, prefix, (unsigned)-1, 0, variants);
313 wfree(dir);
314 wfree(prefix);
315 } else if (*complete == '~') {
316 WMAddToArray(variants, wstrdup("/"));
317 } else if (firstWord) {
318 path = getenv("PATH");
319 while (path) {
320 pos = strchr(path, ':');
321 if (pos) {
322 tmp = wstrndup(path, pos - path);
323 path = pos + 1;
324 } else if (*path != '\0') {
325 tmp = wstrdup(path);
326 path = NULL;
327 } else
328 break;
329 ScanFiles(tmp, complete, S_IXOTH | S_IXGRP | S_IXUSR, S_IFDIR, variants);
330 wfree(tmp);
334 WMSortArray(variants, (WMCompareDataProc *) pstrcmp);
335 return variants;
338 static void handleHistoryKeyPress(XEvent * event, void *clientData)
340 char *text;
341 unsigned pos;
342 WMInputPanelWithHistory *p = (WMInputPanelWithHistory *) clientData;
343 KeySym ksym;
345 ksym = XLookupKeysym(&event->xkey, 0);
347 switch (ksym) {
348 case XK_Up:
349 if (p->histpos < WMGetArrayItemCount(p->history) - 1) {
350 if (p->histpos == 0)
351 wfree(WMReplaceInArray(p->history, 0, WMGetTextFieldText(p->panel->text)));
352 p->histpos++;
353 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
355 break;
356 case XK_Down:
357 if (p->histpos > 0) {
358 p->histpos--;
359 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
361 break;
362 case XK_Tab:
363 if (!p->variants) {
364 text = WMGetTextFieldText(p->panel->text);
365 pos = WMGetTextFieldCursorPosition(p->panel->text);
366 p->prefix = wstrndup(text, pos);
367 p->suffix = wstrdup(text + pos);
368 wfree(text);
369 p->variants = GenerateVariants(p->prefix);
370 p->varpos = 0;
371 if (!p->variants) {
372 wfree(p->prefix);
373 wfree(p->suffix);
374 p->prefix = NULL;
375 p->suffix = NULL;
378 if (p->variants && p->prefix && p->suffix) {
379 p->varpos++;
380 if (p->varpos > WMGetArrayItemCount(p->variants))
381 p->varpos = 0;
382 if (p->varpos > 0)
383 text = wstrconcat(p->prefix, WMGetFromArray(p->variants, p->varpos - 1));
384 else
385 text = wstrdup(p->prefix);
386 pos = strlen(text);
387 text = wstrappend(text, p->suffix);
388 WMSetTextFieldText(p->panel->text, text);
389 WMSetTextFieldCursorPosition(p->panel->text, pos);
390 wfree(text);
392 break;
394 if (ksym != XK_Tab) {
395 if (p->prefix) {
396 wfree(p->prefix);
397 p->prefix = NULL;
399 if (p->suffix) {
400 wfree(p->suffix);
401 p->suffix = NULL;
403 if (p->variants) {
404 WMFreeArray(p->variants);
405 p->variants = NULL;
410 int wAdvancedInputDialog(WScreen *scr, const char *title, const char *message, const char *name, char **text)
412 WWindow *wwin;
413 Window parent;
414 char *result;
415 WMPoint center;
416 WMInputPanelWithHistory *p;
417 char *filename;
419 filename = HistoryFileName(name);
420 p = wmalloc(sizeof(WMInputPanelWithHistory));
421 p->panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
422 p->history = LoadHistory(filename, wPreferences.history_lines);
423 p->histpos = 0;
424 p->prefix = NULL;
425 p->suffix = NULL;
426 p->rest = NULL;
427 p->variants = NULL;
428 p->varpos = 0;
429 WMCreateEventHandler(WMWidgetView(p->panel->text), KeyPressMask, handleHistoryKeyPress, p);
431 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
432 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
434 XReparentWindow(dpy, WMWidgetXID(p->panel->win), parent, 0, 0);
436 center = getCenter(scr, 320, 160);
437 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
439 wwin->client_leader = WMWidgetXID(p->panel->win);
441 WMMapWidget(p->panel->win);
443 wWindowMap(wwin);
445 WMRunModalLoop(WMWidgetScreen(p->panel->win), WMWidgetView(p->panel->win));
447 if (p->panel->result == WAPRDefault) {
448 result = WMGetTextFieldText(p->panel->text);
449 wfree(WMReplaceInArray(p->history, 0, wstrdup(result)));
450 SaveHistory(p->history, filename);
451 } else
452 result = NULL;
454 wUnmanageWindow(wwin, False, False);
456 WMDestroyInputPanel(p->panel);
457 WMFreeArray(p->history);
458 wfree(p);
459 wfree(filename);
461 XDestroyWindow(dpy, parent);
463 if (result == NULL)
464 return False;
465 else {
466 if (*text)
467 wfree(*text);
468 *text = result;
470 return True;
474 int wInputDialog(WScreen *scr, const char *title, const char *message, char **text)
476 WWindow *wwin;
477 Window parent;
478 WMInputPanel *panel;
479 char *result;
480 WMPoint center;
482 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
484 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
485 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
487 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
489 center = getCenter(scr, 320, 160);
490 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
492 wwin->client_leader = WMWidgetXID(panel->win);
494 WMMapWidget(panel->win);
496 wWindowMap(wwin);
498 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
500 if (panel->result == WAPRDefault)
501 result = WMGetTextFieldText(panel->text);
502 else
503 result = NULL;
505 wUnmanageWindow(wwin, False, False);
507 WMDestroyInputPanel(panel);
509 XDestroyWindow(dpy, parent);
511 if (result == NULL)
512 return False;
513 else {
514 if (*text)
515 wfree(*text);
516 *text = result;
518 return True;
523 *****************************************************************
524 * Icon Selection Panel
525 *****************************************************************
528 typedef struct IconPanel {
530 WScreen *scr;
532 WMWindow *win;
534 WMLabel *dirLabel;
535 WMLabel *iconLabel;
537 WMList *dirList;
538 WMList *iconList;
539 WMFont *normalfont;
541 WMButton *previewButton;
543 WMLabel *iconView;
545 WMLabel *fileLabel;
546 WMTextField *fileField;
548 WMButton *okButton;
549 WMButton *cancelButton;
550 #if 0
551 WMButton *chooseButton;
552 #endif
553 short done;
554 short result;
555 short preview;
556 } IconPanel;
558 static void listPixmaps(WScreen *scr, WMList *lPtr, const char *path)
560 struct dirent *dentry;
561 DIR *dir;
562 char pbuf[PATH_MAX + 16];
563 char *apath;
564 IconPanel *panel = WMGetHangedData(lPtr);
566 panel->preview = False;
568 apath = wexpandpath(path);
569 dir = opendir(apath);
571 if (!dir) {
572 char *msg;
573 char *tmp;
574 tmp = _("Could not open directory ");
575 msg = wmalloc(strlen(tmp) + strlen(path) + 6);
576 strcpy(msg, tmp);
577 strcat(msg, path);
579 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
580 wfree(msg);
581 wfree(apath);
582 return;
585 /* list contents in the column */
586 while ((dentry = readdir(dir))) {
587 struct stat statb;
589 if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") == 0)
590 continue;
592 strcpy(pbuf, apath);
593 strcat(pbuf, "/");
594 strcat(pbuf, dentry->d_name);
596 if (stat(pbuf, &statb) < 0)
597 continue;
599 if (statb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)
600 && statb.st_mode & (S_IFREG | S_IFLNK)) {
601 WMAddListItem(lPtr, dentry->d_name);
604 WMSortListItems(lPtr);
606 closedir(dir);
607 wfree(apath);
608 panel->preview = True;
611 static void setViewedImage(IconPanel *panel, const char *file)
613 WMPixmap *pixmap;
614 RColor color;
616 color.red = 0xae;
617 color.green = 0xaa;
618 color.blue = 0xae;
619 color.alpha = 0;
620 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win), file, &color);
621 if (!pixmap) {
622 WMSetButtonEnabled(panel->okButton, False);
624 WMSetLabelText(panel->iconView, _("Could not load image file "));
626 WMSetLabelImage(panel->iconView, NULL);
627 } else {
628 WMSetButtonEnabled(panel->okButton, True);
630 WMSetLabelText(panel->iconView, NULL);
631 WMSetLabelImage(panel->iconView, pixmap);
632 WMReleasePixmap(pixmap);
636 static void listCallback(void *self, void *data)
638 WMList *lPtr = (WMList *) self;
639 IconPanel *panel = (IconPanel *) data;
640 char *path;
642 if (lPtr == panel->dirList) {
643 WMListItem *item = WMGetListSelectedItem(lPtr);
645 if (item == NULL)
646 return;
647 path = item->text;
649 WMSetTextFieldText(panel->fileField, path);
651 WMSetLabelImage(panel->iconView, NULL);
653 WMSetButtonEnabled(panel->okButton, False);
655 WMClearList(panel->iconList);
656 listPixmaps(panel->scr, panel->iconList, path);
657 } else {
658 char *tmp, *iconFile;
659 WMListItem *item = WMGetListSelectedItem(panel->dirList);
661 if (item == NULL)
662 return;
663 path = item->text;
664 tmp = wexpandpath(path);
666 item = WMGetListSelectedItem(panel->iconList);
667 if (item == NULL)
668 return;
669 iconFile = item->text;
671 path = wmalloc(strlen(tmp) + strlen(iconFile) + 4);
672 strcpy(path, tmp);
673 strcat(path, "/");
674 strcat(path, iconFile);
675 wfree(tmp);
676 WMSetTextFieldText(panel->fileField, path);
677 setViewedImage(panel, path);
678 wfree(path);
682 static void listIconPaths(WMList * lPtr)
684 char *paths;
685 char *path;
687 paths = wstrdup(wPreferences.icon_path);
689 path = strtok(paths, ":");
691 do {
692 char *tmp;
694 tmp = wexpandpath(path);
695 /* do not sort, because the order implies the order of
696 * directories searched */
697 if (access(tmp, X_OK) == 0)
698 WMAddListItem(lPtr, path);
699 wfree(tmp);
700 } while ((path = strtok(NULL, ":")) != NULL);
702 wfree(paths);
705 static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
707 IconPanel *panel = WMGetHangedData(lPtr);
708 WScreen *scr = panel->scr;
709 GC gc = scr->draw_gc;
710 GC copygc = scr->copy_gc;
711 char *file, *dirfile;
712 WMPixmap *pixmap;
713 WMColor *back;
714 WMSize size;
715 WMScreen *wmscr = WMWidgetScreen(panel->win);
716 RColor color;
717 int x, y, width, height, len;
719 if (!panel->preview)
720 return;
722 x = rect->pos.x;
723 y = rect->pos.y;
724 width = rect->size.width;
725 height = rect->size.height;
727 back = (state & WLDSSelected) ? scr->white : scr->gray;
729 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
730 len = strlen(dirfile) + strlen(text) + 4;
731 file = wmalloc(len);
732 snprintf(file, len, "%s/%s", dirfile, text);
733 wfree(dirfile);
735 color.red = WMRedComponentOfColor(back) >> 8;
736 color.green = WMGreenComponentOfColor(back) >> 8;
737 color.blue = WMBlueComponentOfColor(back) >> 8;
738 color.alpha = WMGetColorAlpha(back) >> 8;
740 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
741 wfree(file);
743 if (!pixmap) {
744 /*WMRemoveListItem(lPtr, index); */
745 return;
748 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
750 XSetClipMask(dpy, gc, None);
751 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54); */
752 XDrawLine(dpy, d, WMColorGC(scr->white), x, y + height - 1, x + width, y + height - 1);
754 size = WMGetPixmapSize(pixmap);
756 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
757 XSetClipOrigin(dpy, copygc, x + (width - size.width) / 2, y + 2);
758 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
759 size.width > 100 ? 100 : size.width, size.height > 64 ? 64 : size.height,
760 x + (width - size.width) / 2, y + 2);
763 int i, j;
764 int fheight = WMFontHeight(panel->normalfont);
765 int tlen = strlen(text);
766 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
767 int ofx, ofy;
769 ofx = x + (width - twidth) / 2;
770 ofy = y + 64 - fheight;
772 for (i = -1; i < 2; i++)
773 for (j = -1; j < 2; j++)
774 WMDrawString(wmscr, d, scr->white, panel->normalfont,
775 ofx + i, ofy + j, text, tlen);
777 WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy, text, tlen);
780 WMReleasePixmap(pixmap);
781 /* I hope it is better to do not use cache / on my box it is fast nuff */
782 XFlush(dpy);
785 static void buttonCallback(void *self, void *clientData)
787 WMButton *bPtr = (WMButton *) self;
788 IconPanel *panel = (IconPanel *) clientData;
790 if (bPtr == panel->okButton) {
791 panel->done = True;
792 panel->result = True;
793 } else if (bPtr == panel->cancelButton) {
794 panel->done = True;
795 panel->result = False;
796 } else if (bPtr == panel->previewButton) {
797 /**** Previewer ****/
798 WMSetButtonEnabled(bPtr, False);
799 WMSetListUserDrawItemHeight(panel->iconList, 68);
800 WMSetListUserDrawProc(panel->iconList, drawIconProc);
801 WMRedisplayWidget(panel->iconList);
802 /* for draw proc to access screen/gc */
803 /*** end preview ***/
805 #if 0
806 else if (bPtr == panel->chooseButton) {
807 WMOpenPanel *op;
809 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
811 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
812 char *path;
813 path = WMGetFilePanelFile(op);
814 WMSetTextFieldText(panel->fileField, path);
815 setViewedImage(panel, path);
816 wfree(path);
818 WMDestroyFilePanel(op);
820 #endif
823 static void keyPressHandler(XEvent * event, void *data)
825 IconPanel *panel = (IconPanel *) data;
826 char buffer[32];
827 KeySym ksym;
828 int iidx;
829 int didx;
830 int item = 0;
831 WMList *list = NULL;
833 if (event->type == KeyRelease)
834 return;
836 buffer[0] = 0;
837 XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
839 iidx = WMGetListSelectedItemRow(panel->iconList);
840 didx = WMGetListSelectedItemRow(panel->dirList);
842 switch (ksym) {
843 case XK_Up:
844 if (iidx > 0)
845 item = iidx - 1;
846 else
847 item = iidx;
848 list = panel->iconList;
849 break;
850 case XK_Down:
851 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
852 item = iidx + 1;
853 else
854 item = iidx;
855 list = panel->iconList;
856 break;
857 case XK_Home:
858 item = 0;
859 list = panel->iconList;
860 break;
861 case XK_End:
862 item = WMGetListNumberOfRows(panel->iconList) - 1;
863 list = panel->iconList;
864 break;
865 case XK_Next:
866 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
867 item = didx + 1;
868 else
869 item = didx;
870 list = panel->dirList;
871 break;
872 case XK_Prior:
873 if (didx > 0)
874 item = didx - 1;
875 else
876 item = 0;
877 list = panel->dirList;
878 break;
879 case XK_Return:
880 WMPerformButtonClick(panel->okButton);
881 break;
882 case XK_Escape:
883 WMPerformButtonClick(panel->cancelButton);
884 break;
887 if (list) {
888 WMSelectListItem(list, item);
889 WMSetListPosition(list, item - 5);
890 listCallback(list, panel);
894 Bool wIconChooserDialog(WScreen *scr, char **file, const char *instance, const char *class)
896 WWindow *wwin;
897 Window parent;
898 IconPanel *panel;
899 WMColor *color;
900 WMFont *boldFont;
901 Bool result;
903 panel = wmalloc(sizeof(IconPanel));
905 panel->scr = scr;
907 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
908 WMResizeWidget(panel->win, 450, 280);
910 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask | KeyReleaseMask, keyPressHandler, panel);
912 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
913 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
915 panel->dirLabel = WMCreateLabel(panel->win);
916 WMResizeWidget(panel->dirLabel, 200, 20);
917 WMMoveWidget(panel->dirLabel, 10, 7);
918 WMSetLabelText(panel->dirLabel, _("Directories"));
919 WMSetLabelFont(panel->dirLabel, boldFont);
920 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
922 WMSetLabelRelief(panel->dirLabel, WRSunken);
924 panel->iconLabel = WMCreateLabel(panel->win);
925 WMResizeWidget(panel->iconLabel, 140, 20);
926 WMMoveWidget(panel->iconLabel, 215, 7);
927 WMSetLabelText(panel->iconLabel, _("Icons"));
928 WMSetLabelFont(panel->iconLabel, boldFont);
929 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
931 WMReleaseFont(boldFont);
933 color = WMWhiteColor(scr->wmscreen);
934 WMSetLabelTextColor(panel->dirLabel, color);
935 WMSetLabelTextColor(panel->iconLabel, color);
936 WMReleaseColor(color);
938 color = WMDarkGrayColor(scr->wmscreen);
939 WMSetWidgetBackgroundColor(panel->iconLabel, color);
940 WMSetWidgetBackgroundColor(panel->dirLabel, color);
941 WMReleaseColor(color);
943 WMSetLabelRelief(panel->iconLabel, WRSunken);
945 panel->dirList = WMCreateList(panel->win);
946 WMResizeWidget(panel->dirList, 200, 170);
947 WMMoveWidget(panel->dirList, 10, 30);
948 WMSetListAction(panel->dirList, listCallback, panel);
950 panel->iconList = WMCreateList(panel->win);
951 WMResizeWidget(panel->iconList, 140, 170);
952 WMMoveWidget(panel->iconList, 215, 30);
953 WMSetListAction(panel->iconList, listCallback, panel);
955 WMHangData(panel->iconList, panel);
957 panel->previewButton = WMCreateCommandButton(panel->win);
958 WMResizeWidget(panel->previewButton, 75, 26);
959 WMMoveWidget(panel->previewButton, 365, 130);
960 WMSetButtonText(panel->previewButton, _("Preview"));
961 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
963 panel->iconView = WMCreateLabel(panel->win);
964 WMResizeWidget(panel->iconView, 75, 75);
965 WMMoveWidget(panel->iconView, 365, 40);
966 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
967 WMSetLabelRelief(panel->iconView, WRSunken);
968 WMSetLabelTextAlignment(panel->iconView, WACenter);
970 panel->fileLabel = WMCreateLabel(panel->win);
971 WMResizeWidget(panel->fileLabel, 80, 20);
972 WMMoveWidget(panel->fileLabel, 10, 210);
973 WMSetLabelText(panel->fileLabel, _("File Name:"));
975 panel->fileField = WMCreateTextField(panel->win);
976 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
977 WMResizeWidget(panel->fileField, 345, 20);
978 WMMoveWidget(panel->fileField, 95, 210);
979 WMSetTextFieldEditable(panel->fileField, False);
981 panel->okButton = WMCreateCommandButton(panel->win);
982 WMResizeWidget(panel->okButton, 80, 26);
983 WMMoveWidget(panel->okButton, 360, 240);
984 WMSetButtonText(panel->okButton, _("OK"));
985 WMSetButtonEnabled(panel->okButton, False);
986 WMSetButtonAction(panel->okButton, buttonCallback, panel);
988 panel->cancelButton = WMCreateCommandButton(panel->win);
989 WMResizeWidget(panel->cancelButton, 80, 26);
990 WMMoveWidget(panel->cancelButton, 270, 240);
991 WMSetButtonText(panel->cancelButton, _("Cancel"));
992 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
993 #if 0
994 panel->chooseButton = WMCreateCommandButton(panel->win);
995 WMResizeWidget(panel->chooseButton, 110, 26);
996 WMMoveWidget(panel->chooseButton, 150, 240);
997 WMSetButtonText(panel->chooseButton, _("Choose File"));
998 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
999 #endif
1000 WMRealizeWidget(panel->win);
1001 WMMapSubwidgets(panel->win);
1003 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
1005 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1008 char *tmp;
1009 int len = (instance ? strlen(instance) : 0)
1010 + (class ? strlen(class) : 0) + 32;
1011 WMPoint center;
1013 tmp = wmalloc(len);
1015 if (tmp && (instance || class))
1016 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
1017 else
1018 strcpy(tmp, _("Icon Chooser"));
1020 center = getCenter(scr, 450, 280);
1022 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x, center.y, 450, 280);
1023 wfree(tmp);
1026 /* put icon paths in the list */
1027 listIconPaths(panel->dirList);
1029 WMMapWidget(panel->win);
1031 wWindowMap(wwin);
1033 while (!panel->done) {
1034 XEvent event;
1036 WMNextEvent(dpy, &event);
1037 WMHandleEvent(&event);
1040 if (panel->result) {
1041 char *defaultPath, *wantedPath;
1043 /* check if the file the user selected is not the one that
1044 * would be loaded by default with the current search path */
1045 *file = WMGetListSelectedItem(panel->iconList)->text;
1046 if (**file == 0) {
1047 wfree(*file);
1048 *file = NULL;
1049 } else {
1050 defaultPath = FindImage(wPreferences.icon_path, *file);
1051 wantedPath = WMGetTextFieldText(panel->fileField);
1052 /* if the file is not the default, use full path */
1053 if (strcmp(wantedPath, defaultPath) != 0) {
1054 *file = wantedPath;
1055 } else {
1056 *file = wstrdup(*file);
1057 wfree(wantedPath);
1059 wfree(defaultPath);
1061 } else {
1062 *file = NULL;
1065 result = panel->result;
1067 WMReleaseFont(panel->normalfont);
1069 WMUnmapWidget(panel->win);
1071 WMDestroyWidget(panel->win);
1073 wUnmanageWindow(wwin, False, False);
1075 wfree(panel);
1077 XDestroyWindow(dpy, parent);
1079 return result;
1083 ***********************************************************************
1084 * Info Panel
1085 ***********************************************************************
1088 typedef struct {
1089 WScreen *scr;
1090 WWindow *wwin;
1091 WMWindow *win;
1092 WMLabel *logoL;
1093 WMLabel *name1L;
1094 WMFrame *lineF;
1095 WMLabel *name2L;
1096 WMLabel *versionL;
1097 WMLabel *infoL;
1098 WMLabel *copyrL;
1099 } InfoPanel;
1101 #define COPYRIGHT_TEXT \
1102 "Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
1103 "Copyright \xc2\xa9 1998-2006 Dan Pascu"
1105 static InfoPanel *thePanel = NULL;
1107 static void destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
1109 WMUnmapWidget(thePanel);
1110 wUnmanageWindow(thePanel->wwin, False, False);
1111 WMDestroyWidget(thePanel->win);
1112 wfree(thePanel);
1113 thePanel = NULL;
1116 void wShowInfoPanel(WScreen * scr)
1118 InfoPanel *panel;
1119 WMPixmap *logo;
1120 WMFont *font;
1121 char *strbuf = NULL;
1122 const char *separator;
1123 char buffer[256];
1124 const char *name;
1125 Window parent;
1126 WWindow *wwin;
1127 char **strl;
1128 int i, width = 50, sepHeight;
1129 char *visuals[] = {
1130 "StaticGray",
1131 "GrayScale",
1132 "StaticColor",
1133 "PseudoColor",
1134 "TrueColor",
1135 "DirectColor"
1138 if (thePanel) {
1139 if (thePanel->scr == scr) {
1140 wRaiseFrame(thePanel->wwin->frame->core);
1141 wSetFocusTo(scr, thePanel->wwin);
1143 return;
1146 panel = wmalloc(sizeof(InfoPanel));
1148 panel->scr = scr;
1150 panel->win = WMCreateWindow(scr->wmscreen, "info");
1151 WMResizeWidget(panel->win, 390, 230);
1153 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
1154 if (!logo) {
1155 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1157 if (logo) {
1158 panel->logoL = WMCreateLabel(panel->win);
1159 WMResizeWidget(panel->logoL, 64, 64);
1160 WMMoveWidget(panel->logoL, 30, 20);
1161 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1162 WMSetLabelImage(panel->logoL, logo);
1163 WMReleasePixmap(logo);
1166 sepHeight = 3;
1167 panel->name1L = WMCreateLabel(panel->win);
1168 WMResizeWidget(panel->name1L, 240, 30 + 2);
1169 WMMoveWidget(panel->name1L, 100, 30 - 2 - sepHeight);
1171 name = "Lucida Sans,Comic Sans MS,URW Gothic L,Trebuchet MS" ":italic:pixelsize=28:antialias=true";
1172 font = WMCreateFont(scr->wmscreen, name);
1173 strbuf = "Window Maker";
1174 if (font) {
1175 width = WMWidthOfString(font, strbuf, strlen(strbuf));
1176 WMSetLabelFont(panel->name1L, font);
1177 WMReleaseFont(font);
1179 WMSetLabelTextAlignment(panel->name1L, WACenter);
1180 WMSetLabelText(panel->name1L, strbuf);
1182 panel->lineF = WMCreateFrame(panel->win);
1183 WMResizeWidget(panel->lineF, width, sepHeight);
1184 WMMoveWidget(panel->lineF, 100 + (240 - width) / 2, 60 - sepHeight);
1185 WMSetFrameRelief(panel->lineF, WRSimple);
1186 WMSetWidgetBackgroundColor(panel->lineF, scr->black);
1188 panel->name2L = WMCreateLabel(panel->win);
1189 WMResizeWidget(panel->name2L, 240, 24);
1190 WMMoveWidget(panel->name2L, 100, 60);
1191 name = "URW Gothic L,Nimbus Sans L:pixelsize=16:antialias=true";
1192 font = WMCreateFont(scr->wmscreen, name);
1193 if (font) {
1194 WMSetLabelFont(panel->name2L, font);
1195 WMReleaseFont(font);
1196 font = NULL;
1198 WMSetLabelTextAlignment(panel->name2L, WACenter);
1199 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1201 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1202 panel->versionL = WMCreateLabel(panel->win);
1203 WMResizeWidget(panel->versionL, 310, 16);
1204 WMMoveWidget(panel->versionL, 30, 95);
1205 WMSetLabelTextAlignment(panel->versionL, WARight);
1206 WMSetLabelText(panel->versionL, buffer);
1207 WMSetLabelWraps(panel->versionL, False);
1209 panel->copyrL = WMCreateLabel(panel->win);
1210 WMResizeWidget(panel->copyrL, 360, 40);
1211 WMMoveWidget(panel->copyrL, 15, 185);
1212 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1213 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1214 font = WMSystemFontOfSize(scr->wmscreen, 11);
1215 if (font) {
1216 WMSetLabelFont(panel->copyrL, font);
1217 WMReleaseFont(font);
1218 font = NULL;
1221 strbuf = NULL;
1222 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1223 (unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
1225 strbuf = wstrappend(strbuf, buffer);
1227 switch (scr->w_depth) {
1228 case 15:
1229 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1230 break;
1231 case 16:
1232 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1233 break;
1234 case 24:
1235 case 32:
1236 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1237 break;
1238 default:
1239 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1 << scr->w_depth);
1240 strbuf = wstrappend(strbuf, buffer);
1241 break;
1244 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1246 struct mallinfo ma = mallinfo();
1247 snprintf(buffer, sizeof(buffer),
1248 #ifdef DEBUG
1249 _("Total memory allocated: %i kB (in use: %i kB, %d free chunks).\n"),
1250 #else
1251 _("Total memory allocated: %i kB (in use: %i kB).\n"),
1252 #endif
1253 (ma.arena + ma.hblkhd) / 1024,
1254 (ma.uordblks + ma.hblkhd) / 1024
1255 #ifdef DEBUG
1257 * This information is representative of the memory
1258 * fragmentation. In ideal case it should be 1, but
1259 * that is never possible
1261 , ma.ordblks
1262 #endif
1265 strbuf = wstrappend(strbuf, buffer);
1267 #endif
1269 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1270 strl = RSupportedFileFormats();
1271 separator = NULL;
1272 for (i = 0; strl[i] != NULL; i++) {
1273 if (separator != NULL)
1274 strbuf = wstrappend(strbuf, separator);
1275 strbuf = wstrappend(strbuf, strl[i]);
1276 separator = ", ";
1279 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1280 strbuf = wstrappend(strbuf, "WMSPEC");
1282 #ifdef HAVE_XRANDR
1283 strbuf = wstrappend(strbuf, ", XRandR ");
1284 if (has_randr)
1285 strbuf = wstrappend(strbuf, _("(Supported)"));
1286 else
1287 strbuf = wstrappend(strbuf, _("(Unsupported)"));
1288 #endif
1290 #ifdef MWM_HINTS
1291 strbuf = wstrappend(strbuf, ", MWM");
1292 #endif
1294 #ifdef XINERAMA
1295 strbuf = wstrappend(strbuf, _("\n"));
1296 #ifdef SOLARIS_XINERAMA
1297 strbuf = wstrappend(strbuf, _("Solaris "));
1298 #endif
1299 strbuf = wstrappend(strbuf, _("Xinerama: "));
1301 char tmp[128];
1302 snprintf(tmp, sizeof(tmp) - 1, _("%d heads found."), scr->xine_info.count);
1303 strbuf = wstrappend(strbuf, tmp);
1305 #endif
1307 panel->infoL = WMCreateLabel(panel->win);
1308 WMResizeWidget(panel->infoL, 350, 75);
1309 WMMoveWidget(panel->infoL, 15, 115);
1310 WMSetLabelText(panel->infoL, strbuf);
1311 font = WMSystemFontOfSize(scr->wmscreen, 11);
1312 if (font) {
1313 WMSetLabelFont(panel->infoL, font);
1314 WMReleaseFont(font);
1315 font = NULL;
1317 wfree(strbuf);
1319 WMRealizeWidget(panel->win);
1320 WMMapSubwidgets(panel->win);
1322 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1324 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1326 WMMapWidget(panel->win);
1329 WMPoint center = getCenter(scr, 382, 230);
1331 wwin = wManageInternalWindow(scr, parent, None, _("Info"), center.x, center.y, 382, 230);
1334 WSETUFLAG(wwin, no_closable, 0);
1335 WSETUFLAG(wwin, no_close_button, 0);
1336 #ifdef XKB_BUTTON_HINT
1337 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1338 #endif
1339 wWindowUpdateButtonImages(wwin);
1340 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1341 wwin->frame->on_click_right = destroyInfoPanel;
1343 wWindowMap(wwin);
1345 panel->wwin = wwin;
1346 thePanel = panel;
1350 ***********************************************************************
1351 * Legal Panel
1352 ***********************************************************************
1355 typedef struct {
1356 WScreen *scr;
1358 WWindow *wwin;
1360 WMWindow *win;
1362 WMLabel *licenseL;
1363 } LegalPanel;
1365 static LegalPanel *legalPanel = NULL;
1367 static void destroyLegalPanel(WCoreWindow * foo, void *data, XEvent * event)
1369 WMUnmapWidget(legalPanel->win);
1371 WMDestroyWidget(legalPanel->win);
1373 wUnmanageWindow(legalPanel->wwin, False, False);
1375 wfree(legalPanel);
1377 legalPanel = NULL;
1380 void wShowLegalPanel(WScreen * scr)
1382 LegalPanel *panel;
1383 Window parent;
1384 WWindow *wwin;
1386 if (legalPanel) {
1387 if (legalPanel->scr == scr) {
1388 wRaiseFrame(legalPanel->wwin->frame->core);
1389 wSetFocusTo(scr, legalPanel->wwin);
1391 return;
1394 panel = wmalloc(sizeof(LegalPanel));
1396 panel->scr = scr;
1398 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1399 WMResizeWidget(panel->win, 420, 250);
1401 panel->licenseL = WMCreateLabel(panel->win);
1402 WMSetLabelWraps(panel->licenseL, True);
1403 WMResizeWidget(panel->licenseL, 400, 230);
1404 WMMoveWidget(panel->licenseL, 10, 10);
1405 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1406 WMSetLabelText(panel->licenseL,
1407 _(" Window Maker is free software; you can redistribute it and/or\n"
1408 "modify it under the terms of the GNU General Public License as\n"
1409 "published by the Free Software Foundation; either version 2 of the\n"
1410 "License, or (at your option) any later version.\n\n"
1411 " Window Maker is distributed in the hope that it will be useful,\n"
1412 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1413 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1414 "See the GNU General Public License for more details.\n\n"
1415 " You should have received a copy of the GNU General Public\n"
1416 "License along with this program; if not, write to the Free Software\n"
1417 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n"
1418 "02110-1301 USA."));
1419 WMSetLabelRelief(panel->licenseL, WRGroove);
1421 WMRealizeWidget(panel->win);
1422 WMMapSubwidgets(panel->win);
1424 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1426 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1429 WMPoint center = getCenter(scr, 420, 250);
1431 wwin = wManageInternalWindow(scr, parent, None, _("Legal"), center.x, center.y, 420, 250);
1434 WSETUFLAG(wwin, no_closable, 0);
1435 WSETUFLAG(wwin, no_close_button, 0);
1436 wWindowUpdateButtonImages(wwin);
1437 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1438 #ifdef XKB_BUTTON_HINT
1439 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1440 #endif
1441 wwin->frame->on_click_right = destroyLegalPanel;
1443 panel->wwin = wwin;
1445 WMMapWidget(panel->win);
1447 wWindowMap(wwin);
1449 legalPanel = panel;
1453 ***********************************************************************
1454 * Crashing Dialog Panel
1455 ***********************************************************************
1458 extern WDDomain *WDWindowAttributes;
1460 typedef struct _CrashPanel {
1461 WMWindow *win; /* main window */
1463 WMLabel *iconL; /* application icon */
1464 WMLabel *nameL; /* title of panel */
1466 WMFrame *sepF; /* separator frame */
1468 WMLabel *noteL; /* Title of note */
1469 WMLabel *note2L; /* body of note with what happened */
1471 WMFrame *whatF; /* "what to do next" frame */
1472 WMPopUpButton *whatP; /* action selection popup button */
1474 WMButton *okB; /* ok button */
1476 Bool done; /* if finished with this dialog */
1477 int action; /* what to do after */
1479 KeyCode retKey;
1481 } CrashPanel;
1483 static void handleKeyPress(XEvent * event, void *clientData)
1485 CrashPanel *panel = (CrashPanel *) clientData;
1487 if (event->xkey.keycode == panel->retKey) {
1488 WMPerformButtonClick(panel->okB);
1492 static void okButtonCallback(void *self, void *clientData)
1494 CrashPanel *panel = (CrashPanel *) clientData;
1496 panel->done = True;
1499 static void setCrashAction(void *self, void *clientData)
1501 WMPopUpButton *pop = (WMPopUpButton *) self;
1502 CrashPanel *panel = (CrashPanel *) clientData;
1504 panel->action = WMGetPopUpButtonSelectedItem(pop);
1507 /* Make this read the logo from a compiled in pixmap -Dan */
1508 static WMPixmap *getWindowMakerIconImage(WMScreen *scr)
1510 WMPixmap *pix = NULL;
1511 char *path = NULL;
1513 /* Get the Logo icon, without the default icon */
1514 path = get_icon_filename(NULL, "Logo", "WMPanel", NULL, False);
1516 if (path) {
1517 RColor gray;
1519 gray.red = 0xae;
1520 gray.green = 0xaa;
1521 gray.blue = 0xae;
1522 gray.alpha = 0;
1524 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1525 wfree(path);
1528 return pix;
1531 #define PWIDTH 295
1532 #define PHEIGHT 345
1534 int wShowCrashingDialogPanel(int whatSig)
1536 CrashPanel *panel;
1537 WMScreen *scr;
1538 WMFont *font;
1539 WMPixmap *logo;
1540 int screen_no, scr_width, scr_height;
1541 int action;
1542 char buf[256];
1544 panel = wmalloc(sizeof(CrashPanel));
1546 screen_no = DefaultScreen(dpy);
1547 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1548 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1550 scr = WMCreateScreen(dpy, screen_no);
1551 if (!scr) {
1552 werror(_("cannot open connection for crashing dialog panel. Aborting."));
1553 return WMAbort;
1556 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1558 panel->win = WMCreateWindow(scr, "crashingDialog");
1559 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1560 WMMoveWidget(panel->win, (scr_width - PWIDTH) / 2, (scr_height - PHEIGHT) / 2);
1562 logo = getWindowMakerIconImage(scr);
1563 if (logo) {
1564 panel->iconL = WMCreateLabel(panel->win);
1565 WMResizeWidget(panel->iconL, 64, 64);
1566 WMMoveWidget(panel->iconL, 10, 10);
1567 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1568 WMSetLabelImage(panel->iconL, logo);
1571 panel->nameL = WMCreateLabel(panel->win);
1572 WMResizeWidget(panel->nameL, 200, 30);
1573 WMMoveWidget(panel->nameL, 80, 25);
1574 WMSetLabelTextAlignment(panel->nameL, WALeft);
1575 font = WMBoldSystemFontOfSize(scr, 24);
1576 WMSetLabelFont(panel->nameL, font);
1577 WMReleaseFont(font);
1578 WMSetLabelText(panel->nameL, _("Fatal error"));
1580 panel->sepF = WMCreateFrame(panel->win);
1581 WMResizeWidget(panel->sepF, PWIDTH + 4, 2);
1582 WMMoveWidget(panel->sepF, -2, 80);
1584 panel->noteL = WMCreateLabel(panel->win);
1585 WMResizeWidget(panel->noteL, PWIDTH - 20, 40);
1586 WMMoveWidget(panel->noteL, 10, 90);
1587 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1588 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1589 WMSetLabelText(panel->noteL, buf);
1591 panel->note2L = WMCreateLabel(panel->win);
1592 WMResizeWidget(panel->note2L, PWIDTH - 20, 100);
1593 WMMoveWidget(panel->note2L, 10, 130);
1594 WMSetLabelTextAlignment(panel->note2L, WALeft);
1595 WMSetLabelText(panel->note2L,
1596 _(" This fatal error occured probably due to a bug."
1597 " Please fill the included BUGFORM and " "report it to bugs@windowmaker.info."));
1598 WMSetLabelWraps(panel->note2L, True);
1600 panel->whatF = WMCreateFrame(panel->win);
1601 WMResizeWidget(panel->whatF, PWIDTH - 20, 50);
1602 WMMoveWidget(panel->whatF, 10, 240);
1603 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1605 panel->whatP = WMCreatePopUpButton(panel->whatF);
1606 WMResizeWidget(panel->whatP, PWIDTH - 20 - 70, 20);
1607 WMMoveWidget(panel->whatP, 35, 20);
1608 WMSetPopUpButtonPullsDown(panel->whatP, False);
1609 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1610 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1611 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1612 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1613 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1614 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1615 panel->action = WMRestart;
1617 WMMapSubwidgets(panel->whatF);
1619 panel->okB = WMCreateCommandButton(panel->win);
1620 WMResizeWidget(panel->okB, 80, 26);
1621 WMMoveWidget(panel->okB, 205, 309);
1622 WMSetButtonText(panel->okB, _("OK"));
1623 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1624 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1625 WMSetButtonImagePosition(panel->okB, WIPRight);
1626 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1628 panel->done = 0;
1630 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask, handleKeyPress, panel);
1632 WMRealizeWidget(panel->win);
1633 WMMapSubwidgets(panel->win);
1635 WMMapWidget(panel->win);
1637 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1639 while (!panel->done) {
1640 XEvent event;
1642 WMNextEvent(dpy, &event);
1643 WMHandleEvent(&event);
1646 action = panel->action;
1648 WMUnmapWidget(panel->win);
1649 WMDestroyWidget(panel->win);
1650 wfree(panel);
1652 return action;