wmaker: Replaced local 'extern' definition of wPreferences by proper header usage
[wmaker-crm.git] / src / dialog.c
blobc36d9fa4e7c1a7a69d9958e267b3aed6b7ffcdb5
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"
64 static WMPoint getCenter(WScreen * scr, int width, int height)
66 return wGetPointToCenterRectInHead(scr, wGetHeadForPointerLocation(scr), width, height);
69 int wMessageDialog(WScreen *scr, const char *title, const char *message, const char *defBtn, const char *altBtn, const char *othBtn)
71 WMAlertPanel *panel;
72 Window parent;
73 WWindow *wwin;
74 int result;
75 WMPoint center;
77 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
79 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
81 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
83 center = getCenter(scr, 400, 180);
84 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
85 wwin->client_leader = WMWidgetXID(panel->win);
87 WMMapWidget(panel->win);
89 wWindowMap(wwin);
91 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
93 result = panel->result;
95 WMUnmapWidget(panel->win);
97 wUnmanageWindow(wwin, False, False);
99 WMDestroyAlertPanel(panel);
101 XDestroyWindow(dpy, parent);
103 return result;
106 static void toggleSaveSession(WMWidget *w, void *data)
108 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
111 int wExitDialog(WScreen *scr, const char *title, const char *message, const char *defBtn, const char *altBtn, const char *othBtn)
113 WMAlertPanel *panel;
114 WMButton *saveSessionBtn;
115 Window parent;
116 WWindow *wwin;
117 WMPoint center;
118 int result;
120 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
122 /* add save session button */
123 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
124 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
125 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn), False, True, 200, 0, 0);
126 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
127 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
128 WMRealizeWidget(saveSessionBtn);
129 WMMapWidget(saveSessionBtn);
131 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
133 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
135 center = getCenter(scr, 400, 180);
136 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
138 wwin->client_leader = WMWidgetXID(panel->win);
140 WMMapWidget(panel->win);
142 wWindowMap(wwin);
144 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
146 result = panel->result;
148 WMUnmapWidget(panel->win);
150 wUnmanageWindow(wwin, False, False);
152 WMDestroyAlertPanel(panel);
154 XDestroyWindow(dpy, parent);
156 return result;
159 typedef struct _WMInputPanelWithHistory {
160 WMInputPanel *panel;
161 WMArray *history;
162 int histpos;
163 char *prefix;
164 char *suffix;
165 char *rest;
166 WMArray *variants;
167 int varpos;
168 } WMInputPanelWithHistory;
170 static char *HistoryFileName(const char *name)
172 char *filename = NULL;
174 filename = wstrdup(wusergnusteppath());
175 filename = wstrappend(filename, "/.AppInfo/WindowMaker/History");
176 if (name && strlen(name)) {
177 filename = wstrappend(filename, ".");
178 filename = wstrappend(filename, name);
180 return filename;
183 static int strmatch(const void *str1, const void *str2)
185 return !strcmp((const char *)str1, (const char *)str2);
188 static WMArray *LoadHistory(const char *filename, int max)
190 WMPropList *plhistory;
191 WMPropList *plitem;
192 WMArray *history;
193 int i, num;
194 char *str;
196 history = WMCreateArrayWithDestructor(1, wfree);
197 WMAddToArray(history, wstrdup(""));
199 plhistory = WMReadPropListFromFile(filename);
201 if (plhistory) {
202 if (WMIsPLArray(plhistory)) {
203 num = WMGetPropListItemCount(plhistory);
205 for (i = 0; i < num; ++i) {
206 plitem = WMGetFromPLArray(plhistory, i);
207 if (WMIsPLString(plitem)) {
208 str = WMGetFromPLString(plitem);
209 if (WMFindInArray(history, strmatch, str) == WANotFound) {
211 * The string here is duplicated because it will be freed
212 * automatically when the array is deleted. This is not really
213 * great because it is already an allocated string,
214 * unfortunately we cannot re-use it because it will be freed
215 * when we discard the PL (and we don't want to waste the PL's
216 * memory either)
218 WMAddToArray(history, wstrdup(str));
219 if (--max <= 0)
220 break;
225 WMReleasePropList(plhistory);
228 return history;
231 static void SaveHistory(WMArray * history, const char *filename)
233 int i;
234 WMPropList *plhistory;
236 plhistory = WMCreatePLArray(NULL);
238 for (i = 0; i < WMGetArrayItemCount(history); ++i)
239 WMAddToPLArray(plhistory, WMCreatePLString(WMGetFromArray(history, i)));
241 WMWritePropListToFile(plhistory, filename);
242 WMReleasePropList(plhistory);
245 static int pstrcmp(const char **str1, const char **str2)
247 return strcmp(*str1, *str2);
250 static void
251 ScanFiles(const char *dir, const char *prefix, unsigned acceptmask, unsigned declinemask, WMArray * result)
253 int prefixlen;
254 DIR *d;
255 struct dirent *de;
256 struct stat sb;
257 char *fullfilename, *suffix;
259 prefixlen = strlen(prefix);
260 if ((d = opendir(dir)) != NULL) {
261 while ((de = readdir(d)) != NULL) {
262 if (strlen(de->d_name) > prefixlen &&
263 !strncmp(prefix, de->d_name, prefixlen) &&
264 strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..")) {
265 fullfilename = wstrconcat((char *)dir, "/");
266 fullfilename = wstrappend(fullfilename, de->d_name);
268 if (stat(fullfilename, &sb) == 0 &&
269 (sb.st_mode & acceptmask) &&
270 !(sb.st_mode & declinemask) &&
271 WMFindInArray(result, (WMMatchDataProc *) strmatch,
272 de->d_name + prefixlen) == WANotFound) {
273 suffix = wstrdup(de->d_name + prefixlen);
274 if (sb.st_mode & S_IFDIR)
275 wstrappend(suffix,"/");
276 WMAddToArray(result, suffix);
278 wfree(fullfilename);
281 closedir(d);
285 static WMArray *GenerateVariants(const char *complete)
287 Bool firstWord = True;
288 WMArray *variants = NULL;
289 char *pos = NULL, *path = NULL, *tmp = NULL, *dir = NULL, *prefix = NULL;
291 variants = WMCreateArrayWithDestructor(0, wfree);
293 while (*complete == ' ')
294 ++complete;
296 if ((pos = strrchr(complete, ' ')) != NULL) {
297 complete = pos + 1;
298 firstWord = False;
301 if ((pos = strrchr(complete, '/')) != NULL) {
302 tmp = wstrndup((char *)complete, pos - complete + 1);
303 if (*tmp == '~' && *(tmp + 1) == '/' && getenv("HOME")) {
304 dir = wstrdup(getenv("HOME"));
305 dir = wstrappend(dir, tmp + 1);
306 wfree(tmp);
307 } else {
308 dir = tmp;
310 prefix = wstrdup(pos + 1);
311 ScanFiles(dir, prefix, (unsigned)-1, 0, variants);
312 wfree(dir);
313 wfree(prefix);
314 } else if (*complete == '~') {
315 WMAddToArray(variants, wstrdup("/"));
316 } else if (firstWord) {
317 path = getenv("PATH");
318 while (path) {
319 pos = strchr(path, ':');
320 if (pos) {
321 tmp = wstrndup(path, pos - path);
322 path = pos + 1;
323 } else if (*path != '\0') {
324 tmp = wstrdup(path);
325 path = NULL;
326 } else
327 break;
328 ScanFiles(tmp, complete, S_IXOTH | S_IXGRP | S_IXUSR, S_IFDIR, variants);
329 wfree(tmp);
333 WMSortArray(variants, (WMCompareDataProc *) pstrcmp);
334 return variants;
337 static void handleHistoryKeyPress(XEvent * event, void *clientData)
339 char *text;
340 unsigned pos;
341 WMInputPanelWithHistory *p = (WMInputPanelWithHistory *) clientData;
342 KeySym ksym;
344 ksym = XLookupKeysym(&event->xkey, 0);
346 switch (ksym) {
347 case XK_Up:
348 if (p->histpos < WMGetArrayItemCount(p->history) - 1) {
349 if (p->histpos == 0)
350 wfree(WMReplaceInArray(p->history, 0, WMGetTextFieldText(p->panel->text)));
351 p->histpos++;
352 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
354 break;
355 case XK_Down:
356 if (p->histpos > 0) {
357 p->histpos--;
358 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
360 break;
361 case XK_Tab:
362 if (!p->variants) {
363 text = WMGetTextFieldText(p->panel->text);
364 pos = WMGetTextFieldCursorPosition(p->panel->text);
365 p->prefix = wstrndup(text, pos);
366 p->suffix = wstrdup(text + pos);
367 wfree(text);
368 p->variants = GenerateVariants(p->prefix);
369 p->varpos = 0;
370 if (!p->variants) {
371 wfree(p->prefix);
372 wfree(p->suffix);
373 p->prefix = NULL;
374 p->suffix = NULL;
377 if (p->variants && p->prefix && p->suffix) {
378 p->varpos++;
379 if (p->varpos > WMGetArrayItemCount(p->variants))
380 p->varpos = 0;
381 if (p->varpos > 0)
382 text = wstrconcat(p->prefix, WMGetFromArray(p->variants, p->varpos - 1));
383 else
384 text = wstrdup(p->prefix);
385 pos = strlen(text);
386 text = wstrappend(text, p->suffix);
387 WMSetTextFieldText(p->panel->text, text);
388 WMSetTextFieldCursorPosition(p->panel->text, pos);
389 wfree(text);
391 break;
393 if (ksym != XK_Tab) {
394 if (p->prefix) {
395 wfree(p->prefix);
396 p->prefix = NULL;
398 if (p->suffix) {
399 wfree(p->suffix);
400 p->suffix = NULL;
402 if (p->variants) {
403 WMFreeArray(p->variants);
404 p->variants = NULL;
409 int wAdvancedInputDialog(WScreen *scr, const char *title, const char *message, const char *name, char **text)
411 WWindow *wwin;
412 Window parent;
413 char *result;
414 WMPoint center;
415 WMInputPanelWithHistory *p;
416 char *filename;
418 filename = HistoryFileName(name);
419 p = wmalloc(sizeof(WMInputPanelWithHistory));
420 p->panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
421 p->history = LoadHistory(filename, wPreferences.history_lines);
422 p->histpos = 0;
423 p->prefix = NULL;
424 p->suffix = NULL;
425 p->rest = NULL;
426 p->variants = NULL;
427 p->varpos = 0;
428 WMCreateEventHandler(WMWidgetView(p->panel->text), KeyPressMask, handleHistoryKeyPress, p);
430 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
431 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
433 XReparentWindow(dpy, WMWidgetXID(p->panel->win), parent, 0, 0);
435 center = getCenter(scr, 320, 160);
436 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
438 wwin->client_leader = WMWidgetXID(p->panel->win);
440 WMMapWidget(p->panel->win);
442 wWindowMap(wwin);
444 WMRunModalLoop(WMWidgetScreen(p->panel->win), WMWidgetView(p->panel->win));
446 if (p->panel->result == WAPRDefault) {
447 result = WMGetTextFieldText(p->panel->text);
448 wfree(WMReplaceInArray(p->history, 0, wstrdup(result)));
449 SaveHistory(p->history, filename);
450 } else
451 result = NULL;
453 wUnmanageWindow(wwin, False, False);
455 WMDestroyInputPanel(p->panel);
456 WMFreeArray(p->history);
457 wfree(p);
458 wfree(filename);
460 XDestroyWindow(dpy, parent);
462 if (result == NULL)
463 return False;
464 else {
465 if (*text)
466 wfree(*text);
467 *text = result;
469 return True;
473 int wInputDialog(WScreen *scr, const char *title, const char *message, char **text)
475 WWindow *wwin;
476 Window parent;
477 WMInputPanel *panel;
478 char *result;
479 WMPoint center;
481 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
483 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
484 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
486 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
488 center = getCenter(scr, 320, 160);
489 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
491 wwin->client_leader = WMWidgetXID(panel->win);
493 WMMapWidget(panel->win);
495 wWindowMap(wwin);
497 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
499 if (panel->result == WAPRDefault)
500 result = WMGetTextFieldText(panel->text);
501 else
502 result = NULL;
504 wUnmanageWindow(wwin, False, False);
506 WMDestroyInputPanel(panel);
508 XDestroyWindow(dpy, parent);
510 if (result == NULL)
511 return False;
512 else {
513 if (*text)
514 wfree(*text);
515 *text = result;
517 return True;
522 *****************************************************************
523 * Icon Selection Panel
524 *****************************************************************
527 typedef struct IconPanel {
529 WScreen *scr;
531 WMWindow *win;
533 WMLabel *dirLabel;
534 WMLabel *iconLabel;
536 WMList *dirList;
537 WMList *iconList;
538 WMFont *normalfont;
540 WMButton *previewButton;
542 WMLabel *iconView;
544 WMLabel *fileLabel;
545 WMTextField *fileField;
547 WMButton *okButton;
548 WMButton *cancelButton;
549 #if 0
550 WMButton *chooseButton;
551 #endif
552 short done;
553 short result;
554 short preview;
555 } IconPanel;
557 static void listPixmaps(WScreen *scr, WMList *lPtr, const char *path)
559 struct dirent *dentry;
560 DIR *dir;
561 char pbuf[PATH_MAX + 16];
562 char *apath;
563 IconPanel *panel = WMGetHangedData(lPtr);
565 panel->preview = False;
567 apath = wexpandpath(path);
568 dir = opendir(apath);
570 if (!dir) {
571 char *msg;
572 char *tmp;
573 tmp = _("Could not open directory ");
574 msg = wmalloc(strlen(tmp) + strlen(path) + 6);
575 strcpy(msg, tmp);
576 strcat(msg, path);
578 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
579 wfree(msg);
580 wfree(apath);
581 return;
584 /* list contents in the column */
585 while ((dentry = readdir(dir))) {
586 struct stat statb;
588 if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") == 0)
589 continue;
591 strcpy(pbuf, apath);
592 strcat(pbuf, "/");
593 strcat(pbuf, dentry->d_name);
595 if (stat(pbuf, &statb) < 0)
596 continue;
598 if (statb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)
599 && statb.st_mode & (S_IFREG | S_IFLNK)) {
600 WMAddListItem(lPtr, dentry->d_name);
603 WMSortListItems(lPtr);
605 closedir(dir);
606 wfree(apath);
607 panel->preview = True;
610 static void setViewedImage(IconPanel *panel, const char *file)
612 WMPixmap *pixmap;
613 RColor color;
615 color.red = 0xae;
616 color.green = 0xaa;
617 color.blue = 0xae;
618 color.alpha = 0;
619 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win), file, &color);
620 if (!pixmap) {
621 WMSetButtonEnabled(panel->okButton, False);
623 WMSetLabelText(panel->iconView, _("Could not load image file "));
625 WMSetLabelImage(panel->iconView, NULL);
626 } else {
627 WMSetButtonEnabled(panel->okButton, True);
629 WMSetLabelText(panel->iconView, NULL);
630 WMSetLabelImage(panel->iconView, pixmap);
631 WMReleasePixmap(pixmap);
635 static void listCallback(void *self, void *data)
637 WMList *lPtr = (WMList *) self;
638 IconPanel *panel = (IconPanel *) data;
639 char *path;
641 if (lPtr == panel->dirList) {
642 WMListItem *item = WMGetListSelectedItem(lPtr);
644 if (item == NULL)
645 return;
646 path = item->text;
648 WMSetTextFieldText(panel->fileField, path);
650 WMSetLabelImage(panel->iconView, NULL);
652 WMSetButtonEnabled(panel->okButton, False);
654 WMClearList(panel->iconList);
655 listPixmaps(panel->scr, panel->iconList, path);
656 } else {
657 char *tmp, *iconFile;
658 WMListItem *item = WMGetListSelectedItem(panel->dirList);
660 if (item == NULL)
661 return;
662 path = item->text;
663 tmp = wexpandpath(path);
665 item = WMGetListSelectedItem(panel->iconList);
666 if (item == NULL)
667 return;
668 iconFile = item->text;
670 path = wmalloc(strlen(tmp) + strlen(iconFile) + 4);
671 strcpy(path, tmp);
672 strcat(path, "/");
673 strcat(path, iconFile);
674 wfree(tmp);
675 WMSetTextFieldText(panel->fileField, path);
676 setViewedImage(panel, path);
677 wfree(path);
681 static void listIconPaths(WMList * lPtr)
683 char *paths;
684 char *path;
686 paths = wstrdup(wPreferences.icon_path);
688 path = strtok(paths, ":");
690 do {
691 char *tmp;
693 tmp = wexpandpath(path);
694 /* do not sort, because the order implies the order of
695 * directories searched */
696 if (access(tmp, X_OK) == 0)
697 WMAddListItem(lPtr, path);
698 wfree(tmp);
699 } while ((path = strtok(NULL, ":")) != NULL);
701 wfree(paths);
704 static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
706 IconPanel *panel = WMGetHangedData(lPtr);
707 WScreen *scr = panel->scr;
708 GC gc = scr->draw_gc;
709 GC copygc = scr->copy_gc;
710 char *file, *dirfile;
711 WMPixmap *pixmap;
712 WMColor *back;
713 WMSize size;
714 WMScreen *wmscr = WMWidgetScreen(panel->win);
715 RColor color;
716 int x, y, width, height, len;
718 if (!panel->preview)
719 return;
721 x = rect->pos.x;
722 y = rect->pos.y;
723 width = rect->size.width;
724 height = rect->size.height;
726 back = (state & WLDSSelected) ? scr->white : scr->gray;
728 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
729 len = strlen(dirfile) + strlen(text) + 4;
730 file = wmalloc(len);
731 snprintf(file, len, "%s/%s", dirfile, text);
732 wfree(dirfile);
734 color.red = WMRedComponentOfColor(back) >> 8;
735 color.green = WMGreenComponentOfColor(back) >> 8;
736 color.blue = WMBlueComponentOfColor(back) >> 8;
737 color.alpha = WMGetColorAlpha(back) >> 8;
739 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
740 wfree(file);
742 if (!pixmap) {
743 /*WMRemoveListItem(lPtr, index); */
744 return;
747 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
749 XSetClipMask(dpy, gc, None);
750 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54); */
751 XDrawLine(dpy, d, WMColorGC(scr->white), x, y + height - 1, x + width, y + height - 1);
753 size = WMGetPixmapSize(pixmap);
755 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
756 XSetClipOrigin(dpy, copygc, x + (width - size.width) / 2, y + 2);
757 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
758 size.width > 100 ? 100 : size.width, size.height > 64 ? 64 : size.height,
759 x + (width - size.width) / 2, y + 2);
762 int i, j;
763 int fheight = WMFontHeight(panel->normalfont);
764 int tlen = strlen(text);
765 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
766 int ofx, ofy;
768 ofx = x + (width - twidth) / 2;
769 ofy = y + 64 - fheight;
771 for (i = -1; i < 2; i++)
772 for (j = -1; j < 2; j++)
773 WMDrawString(wmscr, d, scr->white, panel->normalfont,
774 ofx + i, ofy + j, text, tlen);
776 WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy, text, tlen);
779 WMReleasePixmap(pixmap);
780 /* I hope it is better to do not use cache / on my box it is fast nuff */
781 XFlush(dpy);
784 static void buttonCallback(void *self, void *clientData)
786 WMButton *bPtr = (WMButton *) self;
787 IconPanel *panel = (IconPanel *) clientData;
789 if (bPtr == panel->okButton) {
790 panel->done = True;
791 panel->result = True;
792 } else if (bPtr == panel->cancelButton) {
793 panel->done = True;
794 panel->result = False;
795 } else if (bPtr == panel->previewButton) {
796 /**** Previewer ****/
797 WMSetButtonEnabled(bPtr, False);
798 WMSetListUserDrawItemHeight(panel->iconList, 68);
799 WMSetListUserDrawProc(panel->iconList, drawIconProc);
800 WMRedisplayWidget(panel->iconList);
801 /* for draw proc to access screen/gc */
802 /*** end preview ***/
804 #if 0
805 else if (bPtr == panel->chooseButton) {
806 WMOpenPanel *op;
808 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
810 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
811 char *path;
812 path = WMGetFilePanelFile(op);
813 WMSetTextFieldText(panel->fileField, path);
814 setViewedImage(panel, path);
815 wfree(path);
817 WMDestroyFilePanel(op);
819 #endif
822 static void keyPressHandler(XEvent * event, void *data)
824 IconPanel *panel = (IconPanel *) data;
825 char buffer[32];
826 KeySym ksym;
827 int iidx;
828 int didx;
829 int item = 0;
830 WMList *list = NULL;
832 if (event->type == KeyRelease)
833 return;
835 buffer[0] = 0;
836 XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
838 iidx = WMGetListSelectedItemRow(panel->iconList);
839 didx = WMGetListSelectedItemRow(panel->dirList);
841 switch (ksym) {
842 case XK_Up:
843 if (iidx > 0)
844 item = iidx - 1;
845 else
846 item = iidx;
847 list = panel->iconList;
848 break;
849 case XK_Down:
850 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
851 item = iidx + 1;
852 else
853 item = iidx;
854 list = panel->iconList;
855 break;
856 case XK_Home:
857 item = 0;
858 list = panel->iconList;
859 break;
860 case XK_End:
861 item = WMGetListNumberOfRows(panel->iconList) - 1;
862 list = panel->iconList;
863 break;
864 case XK_Next:
865 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
866 item = didx + 1;
867 else
868 item = didx;
869 list = panel->dirList;
870 break;
871 case XK_Prior:
872 if (didx > 0)
873 item = didx - 1;
874 else
875 item = 0;
876 list = panel->dirList;
877 break;
878 case XK_Return:
879 WMPerformButtonClick(panel->okButton);
880 break;
881 case XK_Escape:
882 WMPerformButtonClick(panel->cancelButton);
883 break;
886 if (list) {
887 WMSelectListItem(list, item);
888 WMSetListPosition(list, item - 5);
889 listCallback(list, panel);
893 Bool wIconChooserDialog(WScreen *scr, char **file, const char *instance, const char *class)
895 WWindow *wwin;
896 Window parent;
897 IconPanel *panel;
898 WMColor *color;
899 WMFont *boldFont;
900 Bool result;
902 panel = wmalloc(sizeof(IconPanel));
904 panel->scr = scr;
906 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
907 WMResizeWidget(panel->win, 450, 280);
909 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask | KeyReleaseMask, keyPressHandler, panel);
911 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
912 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
914 panel->dirLabel = WMCreateLabel(panel->win);
915 WMResizeWidget(panel->dirLabel, 200, 20);
916 WMMoveWidget(panel->dirLabel, 10, 7);
917 WMSetLabelText(panel->dirLabel, _("Directories"));
918 WMSetLabelFont(panel->dirLabel, boldFont);
919 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
921 WMSetLabelRelief(panel->dirLabel, WRSunken);
923 panel->iconLabel = WMCreateLabel(panel->win);
924 WMResizeWidget(panel->iconLabel, 140, 20);
925 WMMoveWidget(panel->iconLabel, 215, 7);
926 WMSetLabelText(panel->iconLabel, _("Icons"));
927 WMSetLabelFont(panel->iconLabel, boldFont);
928 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
930 WMReleaseFont(boldFont);
932 color = WMWhiteColor(scr->wmscreen);
933 WMSetLabelTextColor(panel->dirLabel, color);
934 WMSetLabelTextColor(panel->iconLabel, color);
935 WMReleaseColor(color);
937 color = WMDarkGrayColor(scr->wmscreen);
938 WMSetWidgetBackgroundColor(panel->iconLabel, color);
939 WMSetWidgetBackgroundColor(panel->dirLabel, color);
940 WMReleaseColor(color);
942 WMSetLabelRelief(panel->iconLabel, WRSunken);
944 panel->dirList = WMCreateList(panel->win);
945 WMResizeWidget(panel->dirList, 200, 170);
946 WMMoveWidget(panel->dirList, 10, 30);
947 WMSetListAction(panel->dirList, listCallback, panel);
949 panel->iconList = WMCreateList(panel->win);
950 WMResizeWidget(panel->iconList, 140, 170);
951 WMMoveWidget(panel->iconList, 215, 30);
952 WMSetListAction(panel->iconList, listCallback, panel);
954 WMHangData(panel->iconList, panel);
956 panel->previewButton = WMCreateCommandButton(panel->win);
957 WMResizeWidget(panel->previewButton, 75, 26);
958 WMMoveWidget(panel->previewButton, 365, 130);
959 WMSetButtonText(panel->previewButton, _("Preview"));
960 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
962 panel->iconView = WMCreateLabel(panel->win);
963 WMResizeWidget(panel->iconView, 75, 75);
964 WMMoveWidget(panel->iconView, 365, 40);
965 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
966 WMSetLabelRelief(panel->iconView, WRSunken);
967 WMSetLabelTextAlignment(panel->iconView, WACenter);
969 panel->fileLabel = WMCreateLabel(panel->win);
970 WMResizeWidget(panel->fileLabel, 80, 20);
971 WMMoveWidget(panel->fileLabel, 10, 210);
972 WMSetLabelText(panel->fileLabel, _("File Name:"));
974 panel->fileField = WMCreateTextField(panel->win);
975 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
976 WMResizeWidget(panel->fileField, 345, 20);
977 WMMoveWidget(panel->fileField, 95, 210);
978 WMSetTextFieldEditable(panel->fileField, False);
980 panel->okButton = WMCreateCommandButton(panel->win);
981 WMResizeWidget(panel->okButton, 80, 26);
982 WMMoveWidget(panel->okButton, 360, 240);
983 WMSetButtonText(panel->okButton, _("OK"));
984 WMSetButtonEnabled(panel->okButton, False);
985 WMSetButtonAction(panel->okButton, buttonCallback, panel);
987 panel->cancelButton = WMCreateCommandButton(panel->win);
988 WMResizeWidget(panel->cancelButton, 80, 26);
989 WMMoveWidget(panel->cancelButton, 270, 240);
990 WMSetButtonText(panel->cancelButton, _("Cancel"));
991 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
992 #if 0
993 panel->chooseButton = WMCreateCommandButton(panel->win);
994 WMResizeWidget(panel->chooseButton, 110, 26);
995 WMMoveWidget(panel->chooseButton, 150, 240);
996 WMSetButtonText(panel->chooseButton, _("Choose File"));
997 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
998 #endif
999 WMRealizeWidget(panel->win);
1000 WMMapSubwidgets(panel->win);
1002 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
1004 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1007 char *tmp;
1008 int len = (instance ? strlen(instance) : 0)
1009 + (class ? strlen(class) : 0) + 32;
1010 WMPoint center;
1012 tmp = wmalloc(len);
1014 if (tmp && (instance || class))
1015 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
1016 else
1017 strcpy(tmp, _("Icon Chooser"));
1019 center = getCenter(scr, 450, 280);
1021 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x, center.y, 450, 280);
1022 wfree(tmp);
1025 /* put icon paths in the list */
1026 listIconPaths(panel->dirList);
1028 WMMapWidget(panel->win);
1030 wWindowMap(wwin);
1032 while (!panel->done) {
1033 XEvent event;
1035 WMNextEvent(dpy, &event);
1036 WMHandleEvent(&event);
1039 if (panel->result) {
1040 char *defaultPath, *wantedPath;
1042 /* check if the file the user selected is not the one that
1043 * would be loaded by default with the current search path */
1044 *file = WMGetListSelectedItem(panel->iconList)->text;
1045 if (**file == 0) {
1046 wfree(*file);
1047 *file = NULL;
1048 } else {
1049 defaultPath = FindImage(wPreferences.icon_path, *file);
1050 wantedPath = WMGetTextFieldText(panel->fileField);
1051 /* if the file is not the default, use full path */
1052 if (strcmp(wantedPath, defaultPath) != 0) {
1053 *file = wantedPath;
1054 } else {
1055 *file = wstrdup(*file);
1056 wfree(wantedPath);
1058 wfree(defaultPath);
1060 } else {
1061 *file = NULL;
1064 result = panel->result;
1066 WMReleaseFont(panel->normalfont);
1068 WMUnmapWidget(panel->win);
1070 WMDestroyWidget(panel->win);
1072 wUnmanageWindow(wwin, False, False);
1074 wfree(panel);
1076 XDestroyWindow(dpy, parent);
1078 return result;
1082 ***********************************************************************
1083 * Info Panel
1084 ***********************************************************************
1087 typedef struct {
1088 WScreen *scr;
1089 WWindow *wwin;
1090 WMWindow *win;
1091 WMLabel *logoL;
1092 WMLabel *name1L;
1093 WMFrame *lineF;
1094 WMLabel *name2L;
1095 WMLabel *versionL;
1096 WMLabel *infoL;
1097 WMLabel *copyrL;
1098 } InfoPanel;
1100 #define COPYRIGHT_TEXT \
1101 "Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
1102 "Copyright \xc2\xa9 1998-2006 Dan Pascu"
1104 static InfoPanel *thePanel = NULL;
1106 static void destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
1108 WMUnmapWidget(thePanel);
1109 wUnmanageWindow(thePanel->wwin, False, False);
1110 WMDestroyWidget(thePanel->win);
1111 wfree(thePanel);
1112 thePanel = NULL;
1115 void wShowInfoPanel(WScreen * scr)
1117 InfoPanel *panel;
1118 WMPixmap *logo;
1119 WMFont *font;
1120 char *strbuf = NULL;
1121 const char *separator;
1122 char buffer[256];
1123 const char *name;
1124 Window parent;
1125 WWindow *wwin;
1126 char **strl;
1127 int i, width = 50, sepHeight;
1128 char *visuals[] = {
1129 "StaticGray",
1130 "GrayScale",
1131 "StaticColor",
1132 "PseudoColor",
1133 "TrueColor",
1134 "DirectColor"
1137 if (thePanel) {
1138 if (thePanel->scr == scr) {
1139 wRaiseFrame(thePanel->wwin->frame->core);
1140 wSetFocusTo(scr, thePanel->wwin);
1142 return;
1145 panel = wmalloc(sizeof(InfoPanel));
1147 panel->scr = scr;
1149 panel->win = WMCreateWindow(scr->wmscreen, "info");
1150 WMResizeWidget(panel->win, 390, 230);
1152 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
1153 if (!logo) {
1154 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1156 if (logo) {
1157 panel->logoL = WMCreateLabel(panel->win);
1158 WMResizeWidget(panel->logoL, 64, 64);
1159 WMMoveWidget(panel->logoL, 30, 20);
1160 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1161 WMSetLabelImage(panel->logoL, logo);
1162 WMReleasePixmap(logo);
1165 sepHeight = 3;
1166 panel->name1L = WMCreateLabel(panel->win);
1167 WMResizeWidget(panel->name1L, 240, 30 + 2);
1168 WMMoveWidget(panel->name1L, 100, 30 - 2 - sepHeight);
1170 name = "Lucida Sans,Comic Sans MS,URW Gothic L,Trebuchet MS" ":italic:pixelsize=28:antialias=true";
1171 font = WMCreateFont(scr->wmscreen, name);
1172 strbuf = "Window Maker";
1173 if (font) {
1174 width = WMWidthOfString(font, strbuf, strlen(strbuf));
1175 WMSetLabelFont(panel->name1L, font);
1176 WMReleaseFont(font);
1178 WMSetLabelTextAlignment(panel->name1L, WACenter);
1179 WMSetLabelText(panel->name1L, strbuf);
1181 panel->lineF = WMCreateFrame(panel->win);
1182 WMResizeWidget(panel->lineF, width, sepHeight);
1183 WMMoveWidget(panel->lineF, 100 + (240 - width) / 2, 60 - sepHeight);
1184 WMSetFrameRelief(panel->lineF, WRSimple);
1185 WMSetWidgetBackgroundColor(panel->lineF, scr->black);
1187 panel->name2L = WMCreateLabel(panel->win);
1188 WMResizeWidget(panel->name2L, 240, 24);
1189 WMMoveWidget(panel->name2L, 100, 60);
1190 name = "URW Gothic L,Nimbus Sans L:pixelsize=16:antialias=true";
1191 font = WMCreateFont(scr->wmscreen, name);
1192 if (font) {
1193 WMSetLabelFont(panel->name2L, font);
1194 WMReleaseFont(font);
1195 font = NULL;
1197 WMSetLabelTextAlignment(panel->name2L, WACenter);
1198 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1200 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1201 panel->versionL = WMCreateLabel(panel->win);
1202 WMResizeWidget(panel->versionL, 310, 16);
1203 WMMoveWidget(panel->versionL, 30, 95);
1204 WMSetLabelTextAlignment(panel->versionL, WARight);
1205 WMSetLabelText(panel->versionL, buffer);
1206 WMSetLabelWraps(panel->versionL, False);
1208 panel->copyrL = WMCreateLabel(panel->win);
1209 WMResizeWidget(panel->copyrL, 360, 40);
1210 WMMoveWidget(panel->copyrL, 15, 185);
1211 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1212 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1213 font = WMSystemFontOfSize(scr->wmscreen, 11);
1214 if (font) {
1215 WMSetLabelFont(panel->copyrL, font);
1216 WMReleaseFont(font);
1217 font = NULL;
1220 strbuf = NULL;
1221 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1222 (unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
1224 strbuf = wstrappend(strbuf, buffer);
1226 switch (scr->w_depth) {
1227 case 15:
1228 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1229 break;
1230 case 16:
1231 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1232 break;
1233 case 24:
1234 case 32:
1235 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1236 break;
1237 default:
1238 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1 << scr->w_depth);
1239 strbuf = wstrappend(strbuf, buffer);
1240 break;
1243 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1245 struct mallinfo ma = mallinfo();
1246 snprintf(buffer, sizeof(buffer),
1247 #ifdef DEBUG
1248 _("Total memory allocated: %i kB (in use: %i kB, %d free chunks).\n"),
1249 #else
1250 _("Total memory allocated: %i kB (in use: %i kB).\n"),
1251 #endif
1252 (ma.arena + ma.hblkhd) / 1024,
1253 (ma.uordblks + ma.hblkhd) / 1024
1254 #ifdef DEBUG
1256 * This information is representative of the memory
1257 * fragmentation. In ideal case it should be 1, but
1258 * that is never possible
1260 , ma.ordblks
1261 #endif
1264 strbuf = wstrappend(strbuf, buffer);
1266 #endif
1268 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1269 strl = RSupportedFileFormats();
1270 separator = NULL;
1271 for (i = 0; strl[i] != NULL; i++) {
1272 if (separator != NULL)
1273 strbuf = wstrappend(strbuf, separator);
1274 strbuf = wstrappend(strbuf, strl[i]);
1275 separator = ", ";
1278 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1279 strbuf = wstrappend(strbuf, "WMSPEC");
1281 #ifdef HAVE_XRANDR
1282 strbuf = wstrappend(strbuf, ", XRandR ");
1283 if (has_randr)
1284 strbuf = wstrappend(strbuf, _("(Supported)"));
1285 else
1286 strbuf = wstrappend(strbuf, _("(Unsupported)"));
1287 #endif
1289 #ifdef MWM_HINTS
1290 strbuf = wstrappend(strbuf, ", MWM");
1291 #endif
1293 #ifdef XINERAMA
1294 strbuf = wstrappend(strbuf, _("\n"));
1295 #ifdef SOLARIS_XINERAMA
1296 strbuf = wstrappend(strbuf, _("Solaris "));
1297 #endif
1298 strbuf = wstrappend(strbuf, _("Xinerama: "));
1300 char tmp[128];
1301 snprintf(tmp, sizeof(tmp) - 1, _("%d heads found."), scr->xine_info.count);
1302 strbuf = wstrappend(strbuf, tmp);
1304 #endif
1306 panel->infoL = WMCreateLabel(panel->win);
1307 WMResizeWidget(panel->infoL, 350, 75);
1308 WMMoveWidget(panel->infoL, 15, 115);
1309 WMSetLabelText(panel->infoL, strbuf);
1310 font = WMSystemFontOfSize(scr->wmscreen, 11);
1311 if (font) {
1312 WMSetLabelFont(panel->infoL, font);
1313 WMReleaseFont(font);
1314 font = NULL;
1316 wfree(strbuf);
1318 WMRealizeWidget(panel->win);
1319 WMMapSubwidgets(panel->win);
1321 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1323 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1325 WMMapWidget(panel->win);
1328 WMPoint center = getCenter(scr, 382, 230);
1330 wwin = wManageInternalWindow(scr, parent, None, _("Info"), center.x, center.y, 382, 230);
1333 WSETUFLAG(wwin, no_closable, 0);
1334 WSETUFLAG(wwin, no_close_button, 0);
1335 #ifdef XKB_BUTTON_HINT
1336 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1337 #endif
1338 wWindowUpdateButtonImages(wwin);
1339 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1340 wwin->frame->on_click_right = destroyInfoPanel;
1342 wWindowMap(wwin);
1344 panel->wwin = wwin;
1345 thePanel = panel;
1349 ***********************************************************************
1350 * Legal Panel
1351 ***********************************************************************
1354 typedef struct {
1355 WScreen *scr;
1357 WWindow *wwin;
1359 WMWindow *win;
1361 WMLabel *licenseL;
1362 } LegalPanel;
1364 static LegalPanel *legalPanel = NULL;
1366 static void destroyLegalPanel(WCoreWindow * foo, void *data, XEvent * event)
1368 WMUnmapWidget(legalPanel->win);
1370 WMDestroyWidget(legalPanel->win);
1372 wUnmanageWindow(legalPanel->wwin, False, False);
1374 wfree(legalPanel);
1376 legalPanel = NULL;
1379 void wShowLegalPanel(WScreen * scr)
1381 LegalPanel *panel;
1382 Window parent;
1383 WWindow *wwin;
1385 if (legalPanel) {
1386 if (legalPanel->scr == scr) {
1387 wRaiseFrame(legalPanel->wwin->frame->core);
1388 wSetFocusTo(scr, legalPanel->wwin);
1390 return;
1393 panel = wmalloc(sizeof(LegalPanel));
1395 panel->scr = scr;
1397 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1398 WMResizeWidget(panel->win, 420, 250);
1400 panel->licenseL = WMCreateLabel(panel->win);
1401 WMSetLabelWraps(panel->licenseL, True);
1402 WMResizeWidget(panel->licenseL, 400, 230);
1403 WMMoveWidget(panel->licenseL, 10, 10);
1404 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1405 WMSetLabelText(panel->licenseL,
1406 _(" Window Maker is free software; you can redistribute it and/or\n"
1407 "modify it under the terms of the GNU General Public License as\n"
1408 "published by the Free Software Foundation; either version 2 of the\n"
1409 "License, or (at your option) any later version.\n\n"
1410 " Window Maker is distributed in the hope that it will be useful,\n"
1411 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1412 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1413 "See the GNU General Public License for more details.\n\n"
1414 " You should have received a copy of the GNU General Public\n"
1415 "License along with this program; if not, write to the Free Software\n"
1416 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n"
1417 "02110-1301 USA."));
1418 WMSetLabelRelief(panel->licenseL, WRGroove);
1420 WMRealizeWidget(panel->win);
1421 WMMapSubwidgets(panel->win);
1423 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1425 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1428 WMPoint center = getCenter(scr, 420, 250);
1430 wwin = wManageInternalWindow(scr, parent, None, _("Legal"), center.x, center.y, 420, 250);
1433 WSETUFLAG(wwin, no_closable, 0);
1434 WSETUFLAG(wwin, no_close_button, 0);
1435 wWindowUpdateButtonImages(wwin);
1436 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1437 #ifdef XKB_BUTTON_HINT
1438 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1439 #endif
1440 wwin->frame->on_click_right = destroyLegalPanel;
1442 panel->wwin = wwin;
1444 WMMapWidget(panel->win);
1446 wWindowMap(wwin);
1448 legalPanel = panel;
1452 ***********************************************************************
1453 * Crashing Dialog Panel
1454 ***********************************************************************
1457 extern WDDomain *WDWindowAttributes;
1459 typedef struct _CrashPanel {
1460 WMWindow *win; /* main window */
1462 WMLabel *iconL; /* application icon */
1463 WMLabel *nameL; /* title of panel */
1465 WMFrame *sepF; /* separator frame */
1467 WMLabel *noteL; /* Title of note */
1468 WMLabel *note2L; /* body of note with what happened */
1470 WMFrame *whatF; /* "what to do next" frame */
1471 WMPopUpButton *whatP; /* action selection popup button */
1473 WMButton *okB; /* ok button */
1475 Bool done; /* if finished with this dialog */
1476 int action; /* what to do after */
1478 KeyCode retKey;
1480 } CrashPanel;
1482 static void handleKeyPress(XEvent * event, void *clientData)
1484 CrashPanel *panel = (CrashPanel *) clientData;
1486 if (event->xkey.keycode == panel->retKey) {
1487 WMPerformButtonClick(panel->okB);
1491 static void okButtonCallback(void *self, void *clientData)
1493 CrashPanel *panel = (CrashPanel *) clientData;
1495 panel->done = True;
1498 static void setCrashAction(void *self, void *clientData)
1500 WMPopUpButton *pop = (WMPopUpButton *) self;
1501 CrashPanel *panel = (CrashPanel *) clientData;
1503 panel->action = WMGetPopUpButtonSelectedItem(pop);
1506 /* Make this read the logo from a compiled in pixmap -Dan */
1507 static WMPixmap *getWindowMakerIconImage(WMScreen *scr)
1509 WMPixmap *pix = NULL;
1510 char *path = NULL;
1512 /* Get the Logo icon, without the default icon */
1513 path = get_icon_filename(NULL, "Logo", "WMPanel", NULL, False);
1515 if (path) {
1516 RColor gray;
1518 gray.red = 0xae;
1519 gray.green = 0xaa;
1520 gray.blue = 0xae;
1521 gray.alpha = 0;
1523 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1524 wfree(path);
1527 return pix;
1530 #define PWIDTH 295
1531 #define PHEIGHT 345
1533 int wShowCrashingDialogPanel(int whatSig)
1535 CrashPanel *panel;
1536 WMScreen *scr;
1537 WMFont *font;
1538 WMPixmap *logo;
1539 int screen_no, scr_width, scr_height;
1540 int action;
1541 char buf[256];
1543 panel = wmalloc(sizeof(CrashPanel));
1545 screen_no = DefaultScreen(dpy);
1546 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1547 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1549 scr = WMCreateScreen(dpy, screen_no);
1550 if (!scr) {
1551 werror(_("cannot open connection for crashing dialog panel. Aborting."));
1552 return WMAbort;
1555 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1557 panel->win = WMCreateWindow(scr, "crashingDialog");
1558 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1559 WMMoveWidget(panel->win, (scr_width - PWIDTH) / 2, (scr_height - PHEIGHT) / 2);
1561 logo = getWindowMakerIconImage(scr);
1562 if (logo) {
1563 panel->iconL = WMCreateLabel(panel->win);
1564 WMResizeWidget(panel->iconL, 64, 64);
1565 WMMoveWidget(panel->iconL, 10, 10);
1566 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1567 WMSetLabelImage(panel->iconL, logo);
1570 panel->nameL = WMCreateLabel(panel->win);
1571 WMResizeWidget(panel->nameL, 200, 30);
1572 WMMoveWidget(panel->nameL, 80, 25);
1573 WMSetLabelTextAlignment(panel->nameL, WALeft);
1574 font = WMBoldSystemFontOfSize(scr, 24);
1575 WMSetLabelFont(panel->nameL, font);
1576 WMReleaseFont(font);
1577 WMSetLabelText(panel->nameL, _("Fatal error"));
1579 panel->sepF = WMCreateFrame(panel->win);
1580 WMResizeWidget(panel->sepF, PWIDTH + 4, 2);
1581 WMMoveWidget(panel->sepF, -2, 80);
1583 panel->noteL = WMCreateLabel(panel->win);
1584 WMResizeWidget(panel->noteL, PWIDTH - 20, 40);
1585 WMMoveWidget(panel->noteL, 10, 90);
1586 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1587 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1588 WMSetLabelText(panel->noteL, buf);
1590 panel->note2L = WMCreateLabel(panel->win);
1591 WMResizeWidget(panel->note2L, PWIDTH - 20, 100);
1592 WMMoveWidget(panel->note2L, 10, 130);
1593 WMSetLabelTextAlignment(panel->note2L, WALeft);
1594 WMSetLabelText(panel->note2L,
1595 _(" This fatal error occured probably due to a bug."
1596 " Please fill the included BUGFORM and " "report it to bugs@windowmaker.info."));
1597 WMSetLabelWraps(panel->note2L, True);
1599 panel->whatF = WMCreateFrame(panel->win);
1600 WMResizeWidget(panel->whatF, PWIDTH - 20, 50);
1601 WMMoveWidget(panel->whatF, 10, 240);
1602 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1604 panel->whatP = WMCreatePopUpButton(panel->whatF);
1605 WMResizeWidget(panel->whatP, PWIDTH - 20 - 70, 20);
1606 WMMoveWidget(panel->whatP, 35, 20);
1607 WMSetPopUpButtonPullsDown(panel->whatP, False);
1608 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1609 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1610 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1611 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1612 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1613 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1614 panel->action = WMRestart;
1616 WMMapSubwidgets(panel->whatF);
1618 panel->okB = WMCreateCommandButton(panel->win);
1619 WMResizeWidget(panel->okB, 80, 26);
1620 WMMoveWidget(panel->okB, 205, 309);
1621 WMSetButtonText(panel->okB, _("OK"));
1622 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1623 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1624 WMSetButtonImagePosition(panel->okB, WIPRight);
1625 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1627 panel->done = 0;
1629 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask, handleKeyPress, panel);
1631 WMRealizeWidget(panel->win);
1632 WMMapSubwidgets(panel->win);
1634 WMMapWidget(panel->win);
1636 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1638 while (!panel->done) {
1639 XEvent event;
1641 WMNextEvent(dpy, &event);
1642 WMHandleEvent(&event);
1645 action = panel->action;
1647 WMUnmapWidget(panel->win);
1648 WMDestroyWidget(panel->win);
1649 wfree(panel);
1651 return action;