Remove SILLYNESS
[wmaker-crm.git] / src / dialog.c
blob3a70c39810b0941173b11be4257f7398ef55ef93
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
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 * USA.
24 #include "wconfig.h"
26 #include <X11/Xlib.h>
27 #include <X11/Xutil.h>
28 #include <X11/keysym.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <unistd.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <dirent.h>
37 #include <limits.h>
39 #ifdef HAVE_MALLOC_H
40 #include <malloc.h>
41 #endif
43 #include <signal.h>
44 #ifdef __FreeBSD__
45 #include <sys/signal.h>
46 #endif
48 #ifndef PATH_MAX
49 #define PATH_MAX DEFAULT_PATH_MAX
50 #endif
52 #include "WindowMaker.h"
53 #include "GNUstep.h"
54 #include "screen.h"
55 #include "dialog.h"
56 #include "funcs.h"
57 #include "stacking.h"
58 #include "framewin.h"
59 #include "window.h"
60 #include "actions.h"
61 #include "defaults.h"
62 #include "xinerama.h"
64 extern WPreferences wPreferences;
66 static WMPoint getCenter(WScreen * scr, int width, int height)
68 return wGetPointToCenterRectInHead(scr, wGetHeadForPointerLocation(scr), width, height);
71 int wMessageDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
73 WMAlertPanel *panel;
74 Window parent;
75 WWindow *wwin;
76 int result;
77 WMPoint center;
79 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
81 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
83 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
85 center = getCenter(scr, 400, 180);
86 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
87 wwin->client_leader = WMWidgetXID(panel->win);
89 WMMapWidget(panel->win);
91 wWindowMap(wwin);
93 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
95 result = panel->result;
97 WMUnmapWidget(panel->win);
99 wUnmanageWindow(wwin, False, False);
101 WMDestroyAlertPanel(panel);
103 XDestroyWindow(dpy, parent);
105 return result;
108 void toggleSaveSession(WMWidget * w, void *data)
110 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
113 int wExitDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
115 WMAlertPanel *panel;
116 WMButton *saveSessionBtn;
117 Window parent;
118 WWindow *wwin;
119 WMPoint center;
120 int result;
122 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
124 /* add save session button */
125 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
126 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
127 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn), False, True, 200, 0, 0);
128 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
129 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
130 WMRealizeWidget(saveSessionBtn);
131 WMMapWidget(saveSessionBtn);
133 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
135 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
137 center = getCenter(scr, 400, 180);
138 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
140 wwin->client_leader = WMWidgetXID(panel->win);
142 WMMapWidget(panel->win);
144 wWindowMap(wwin);
146 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
148 result = panel->result;
150 WMUnmapWidget(panel->win);
152 wUnmanageWindow(wwin, False, False);
154 WMDestroyAlertPanel(panel);
156 XDestroyWindow(dpy, parent);
158 return result;
161 typedef struct _WMInputPanelWithHistory {
162 WMInputPanel *panel;
163 WMArray *history;
164 int histpos;
165 char *prefix;
166 char *suffix;
167 char *rest;
168 WMArray *variants;
169 int varpos;
170 } WMInputPanelWithHistory;
172 static char *HistoryFileName(char *name)
174 char *filename = NULL;
176 filename = wstrdup(wusergnusteppath());
177 filename = wstrappend(filename, "/.AppInfo/WindowMaker/History");
178 if (name && strlen(name)) {
179 filename = wstrappend(filename, ".");
180 filename = wstrappend(filename, name);
182 return filename;
185 static int matchString(void *str1, void *str2)
187 return (strcmp((char *)str1, (char *)str2) == 0 ? 1 : 0);
190 static WMArray *LoadHistory(char *filename, int max)
192 WMPropList *plhistory;
193 WMPropList *plitem;
194 WMArray *history;
195 int i, num;
197 history = WMCreateArrayWithDestructor(1, wfree);
198 WMAddToArray(history, wstrdup(""));
200 plhistory = WMReadPropListFromFile((char *)filename);
202 if (plhistory && WMIsPLArray(plhistory)) {
203 num = WMGetPropListItemCount(plhistory);
204 if (num > max)
205 num = max;
207 for (i = 0; i < num; ++i) {
208 plitem = WMGetFromPLArray(plhistory, i);
209 if (WMIsPLString(plitem) && WMFindInArray(history, matchString,
210 WMGetFromPLString(plitem)) == WANotFound)
211 WMAddToArray(history, WMGetFromPLString(plitem));
215 return history;
218 static void SaveHistory(WMArray * history, char *filename)
220 int i;
221 WMPropList *plhistory;
223 plhistory = WMCreatePLArray(NULL);
225 for (i = 0; i < WMGetArrayItemCount(history); ++i)
226 WMAddToPLArray(plhistory, WMCreatePLString(WMGetFromArray(history, i)));
228 WMWritePropListToFile(plhistory, (char *)filename, True);
229 WMReleasePropList(plhistory);
232 static int strmatch(const char *str1, const char *str2)
234 return !strcmp(str1, str2);
237 static int pstrcmp(const char **str1, const char **str2)
239 return strcmp(*str1, *str2);
242 static void
243 ScanFiles(const char *dir, const char *prefix, unsigned acceptmask, unsigned declinemask, WMArray * result)
245 int prefixlen;
246 DIR *d;
247 struct dirent *de;
248 struct stat sb;
249 char *fullfilename, *suffix;
251 prefixlen = strlen(prefix);
252 if ((d = opendir(dir)) != NULL) {
253 while ((de = readdir(d)) != NULL) {
254 if (strlen(de->d_name) > prefixlen &&
255 !strncmp(prefix, de->d_name, prefixlen) &&
256 strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..")) {
257 fullfilename = wstrconcat((char *)dir, "/");
258 fullfilename = wstrappend(fullfilename, de->d_name);
260 if (stat(fullfilename, &sb) == 0 &&
261 (sb.st_mode & acceptmask) &&
262 !(sb.st_mode & declinemask) &&
263 WMFindInArray(result, (WMMatchDataProc *) strmatch,
264 de->d_name + prefixlen) == WANotFound) {
265 suffix = wstrdup(de->d_name + prefixlen);
266 WMAddToArray(result, suffix);
268 wfree(fullfilename);
271 closedir(d);
275 static WMArray *GenerateVariants(const char *complete)
277 Bool firstWord = True;
278 WMArray *variants = NULL;
279 char *pos = NULL, *path = NULL, *tmp = NULL, *dir = NULL, *prefix = NULL;
281 variants = WMCreateArrayWithDestructor(0, wfree);
283 while (*complete == ' ')
284 ++complete;
286 if ((pos = strrchr(complete, ' ')) != NULL) {
287 complete = pos + 1;
288 firstWord = False;
291 if ((pos = strrchr(complete, '/')) != NULL) {
292 tmp = wstrndup((char *)complete, pos - complete + 1);
293 if (*tmp == '~' && *(tmp + 1) == '/' && getenv("HOME")) {
294 dir = wstrdup(getenv("HOME"));
295 dir = wstrappend(dir, tmp + 1);
296 wfree(tmp);
297 } else {
298 dir = tmp;
300 prefix = wstrdup(pos + 1);
301 ScanFiles(dir, prefix, (unsigned)-1, 0, variants);
302 wfree(dir);
303 wfree(prefix);
304 } else if (*complete == '~') {
305 WMAddToArray(variants, wstrdup("/"));
306 } else if (firstWord) {
307 path = getenv("PATH");
308 while (path) {
309 pos = strchr(path, ':');
310 if (pos) {
311 tmp = wstrndup(path, pos - path);
312 path = pos + 1;
313 } else if (*path != '\0') {
314 tmp = wstrdup(path);
315 path = NULL;
316 } else
317 break;
318 ScanFiles(tmp, complete, S_IXOTH | S_IXGRP | S_IXUSR, S_IFDIR, variants);
319 wfree(tmp);
323 WMSortArray(variants, (WMCompareDataProc *) pstrcmp);
324 return variants;
327 static void handleHistoryKeyPress(XEvent * event, void *clientData)
329 char *text;
330 unsigned pos;
331 WMInputPanelWithHistory *p = (WMInputPanelWithHistory *) clientData;
332 KeySym ksym;
334 ksym = XLookupKeysym(&event->xkey, 0);
336 switch (ksym) {
337 case XK_Up:
338 if (p->histpos < WMGetArrayItemCount(p->history) - 1) {
339 if (p->histpos == 0)
340 wfree(WMReplaceInArray(p->history, 0, WMGetTextFieldText(p->panel->text)));
341 p->histpos++;
342 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
344 break;
345 case XK_Down:
346 if (p->histpos > 0) {
347 p->histpos--;
348 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
350 break;
351 case XK_Tab:
352 if (!p->variants) {
353 text = WMGetTextFieldText(p->panel->text);
354 pos = WMGetTextFieldCursorPosition(p->panel->text);
355 p->prefix = wstrndup(text, pos);
356 p->suffix = wstrdup(text + pos);
357 wfree(text);
358 p->variants = GenerateVariants(p->prefix);
359 p->varpos = 0;
360 if (!p->variants) {
361 wfree(p->prefix);
362 wfree(p->suffix);
363 p->prefix = NULL;
364 p->suffix = NULL;
367 if (p->variants && p->prefix && p->suffix) {
368 p->varpos++;
369 if (p->varpos > WMGetArrayItemCount(p->variants))
370 p->varpos = 0;
371 if (p->varpos > 0)
372 text = wstrconcat(p->prefix, WMGetFromArray(p->variants, p->varpos - 1));
373 else
374 text = wstrdup(p->prefix);
375 pos = strlen(text);
376 text = wstrappend(text, p->suffix);
377 WMSetTextFieldText(p->panel->text, text);
378 WMSetTextFieldCursorPosition(p->panel->text, pos);
379 wfree(text);
381 break;
383 if (ksym != XK_Tab) {
384 if (p->prefix) {
385 wfree(p->prefix);
386 p->prefix = NULL;
388 if (p->suffix) {
389 wfree(p->suffix);
390 p->suffix = NULL;
392 if (p->variants) {
393 WMFreeArray(p->variants);
394 p->variants = NULL;
399 int wAdvancedInputDialog(WScreen * scr, char *title, char *message, char *name, char **text)
401 WWindow *wwin;
402 Window parent;
403 char *result;
404 WMPoint center;
405 WMInputPanelWithHistory *p;
406 char *filename;
408 filename = HistoryFileName(name);
409 p = wmalloc(sizeof(WMInputPanelWithHistory));
410 p->panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
411 p->history = LoadHistory(filename, wPreferences.history_lines);
412 p->histpos = 0;
413 p->prefix = NULL;
414 p->suffix = NULL;
415 p->rest = NULL;
416 p->variants = NULL;
417 p->varpos = 0;
418 WMCreateEventHandler(WMWidgetView(p->panel->text), KeyPressMask, handleHistoryKeyPress, p);
420 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
421 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
423 XReparentWindow(dpy, WMWidgetXID(p->panel->win), parent, 0, 0);
425 center = getCenter(scr, 320, 160);
426 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
428 wwin->client_leader = WMWidgetXID(p->panel->win);
430 WMMapWidget(p->panel->win);
432 wWindowMap(wwin);
434 WMRunModalLoop(WMWidgetScreen(p->panel->win), WMWidgetView(p->panel->win));
436 if (p->panel->result == WAPRDefault) {
437 result = WMGetTextFieldText(p->panel->text);
438 wfree(WMReplaceInArray(p->history, 0, wstrdup(result)));
439 SaveHistory(p->history, filename);
440 } else
441 result = NULL;
443 wUnmanageWindow(wwin, False, False);
445 WMDestroyInputPanel(p->panel);
446 WMFreeArray(p->history);
447 wfree(p);
448 wfree(filename);
450 XDestroyWindow(dpy, parent);
452 if (result == NULL)
453 return False;
454 else {
455 if (*text)
456 wfree(*text);
457 *text = result;
459 return True;
463 int wInputDialog(WScreen * scr, char *title, char *message, char **text)
465 WWindow *wwin;
466 Window parent;
467 WMInputPanel *panel;
468 char *result;
469 WMPoint center;
471 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
473 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
474 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
476 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
478 center = getCenter(scr, 320, 160);
479 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
481 wwin->client_leader = WMWidgetXID(panel->win);
483 WMMapWidget(panel->win);
485 wWindowMap(wwin);
487 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
489 if (panel->result == WAPRDefault)
490 result = WMGetTextFieldText(panel->text);
491 else
492 result = NULL;
494 wUnmanageWindow(wwin, False, False);
496 WMDestroyInputPanel(panel);
498 XDestroyWindow(dpy, parent);
500 if (result == NULL)
501 return False;
502 else {
503 if (*text)
504 wfree(*text);
505 *text = result;
507 return True;
512 *****************************************************************
513 * Icon Selection Panel
514 *****************************************************************
517 typedef struct IconPanel {
519 WScreen *scr;
521 WMWindow *win;
523 WMLabel *dirLabel;
524 WMLabel *iconLabel;
526 WMList *dirList;
527 WMList *iconList;
528 WMFont *normalfont;
530 WMButton *previewButton;
532 WMLabel *iconView;
534 WMLabel *fileLabel;
535 WMTextField *fileField;
537 WMButton *okButton;
538 WMButton *cancelButton;
539 #if 0
540 WMButton *chooseButton;
541 #endif
542 short done;
543 short result;
544 short preview;
545 } IconPanel;
547 static void listPixmaps(WScreen * scr, WMList * lPtr, char *path)
549 struct dirent *dentry;
550 DIR *dir;
551 char pbuf[PATH_MAX + 16];
552 char *apath;
553 IconPanel *panel = WMGetHangedData(lPtr);
555 panel->preview = False;
557 apath = wexpandpath(path);
558 dir = opendir(apath);
560 if (!dir) {
561 char *msg;
562 char *tmp;
563 tmp = _("Could not open directory ");
564 msg = wmalloc(strlen(tmp) + strlen(path) + 6);
565 strcpy(msg, tmp);
566 strcat(msg, path);
568 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
569 wfree(msg);
570 wfree(apath);
571 return;
574 /* list contents in the column */
575 while ((dentry = readdir(dir))) {
576 struct stat statb;
578 if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") == 0)
579 continue;
581 strcpy(pbuf, apath);
582 strcat(pbuf, "/");
583 strcat(pbuf, dentry->d_name);
585 if (stat(pbuf, &statb) < 0)
586 continue;
588 if (statb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)
589 && statb.st_mode & (S_IFREG | S_IFLNK)) {
590 WMAddListItem(lPtr, dentry->d_name);
593 WMSortListItems(lPtr);
595 closedir(dir);
596 wfree(apath);
597 panel->preview = True;
600 static void setViewedImage(IconPanel * panel, char *file)
602 WMPixmap *pixmap;
603 RColor color;
605 color.red = 0xae;
606 color.green = 0xaa;
607 color.blue = 0xae;
608 color.alpha = 0;
609 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win), file, &color);
610 if (!pixmap) {
611 WMSetButtonEnabled(panel->okButton, False);
613 WMSetLabelText(panel->iconView, _("Could not load image file "));
615 WMSetLabelImage(panel->iconView, NULL);
616 } else {
617 WMSetButtonEnabled(panel->okButton, True);
619 WMSetLabelText(panel->iconView, NULL);
620 WMSetLabelImage(panel->iconView, pixmap);
621 WMReleasePixmap(pixmap);
625 static void listCallback(void *self, void *data)
627 WMList *lPtr = (WMList *) self;
628 IconPanel *panel = (IconPanel *) data;
629 char *path;
631 if (lPtr == panel->dirList) {
632 WMListItem *item = WMGetListSelectedItem(lPtr);
634 if (item == NULL)
635 return;
636 path = item->text;
638 WMSetTextFieldText(panel->fileField, path);
640 WMSetLabelImage(panel->iconView, NULL);
642 WMSetButtonEnabled(panel->okButton, False);
644 WMClearList(panel->iconList);
645 listPixmaps(panel->scr, panel->iconList, path);
646 } else {
647 char *tmp, *iconFile;
648 WMListItem *item = WMGetListSelectedItem(panel->dirList);
650 if (item == NULL)
651 return;
652 path = item->text;
653 tmp = wexpandpath(path);
655 item = WMGetListSelectedItem(panel->iconList);
656 if (item == NULL)
657 return;
658 iconFile = item->text;
660 path = wmalloc(strlen(tmp) + strlen(iconFile) + 4);
661 strcpy(path, tmp);
662 strcat(path, "/");
663 strcat(path, iconFile);
664 wfree(tmp);
665 WMSetTextFieldText(panel->fileField, path);
666 setViewedImage(panel, path);
667 wfree(path);
671 static void listIconPaths(WMList * lPtr)
673 char *paths;
674 char *path;
676 paths = wstrdup(wPreferences.icon_path);
678 path = strtok(paths, ":");
680 do {
681 char *tmp;
683 tmp = wexpandpath(path);
684 /* do not sort, because the order implies the order of
685 * directories searched */
686 if (access(tmp, X_OK) == 0)
687 WMAddListItem(lPtr, path);
688 wfree(tmp);
689 } while ((path = strtok(NULL, ":")) != NULL);
691 wfree(paths);
694 static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
696 IconPanel *panel = WMGetHangedData(lPtr);
697 WScreen *scr = panel->scr;
698 GC gc = scr->draw_gc;
699 GC copygc = scr->copy_gc;
700 char *file, *dirfile;
701 WMPixmap *pixmap;
702 WMColor *back;
703 WMSize size;
704 WMScreen *wmscr = WMWidgetScreen(panel->win);
705 RColor color;
706 int x, y, width, height, len;
708 if (!panel->preview)
709 return;
711 x = rect->pos.x;
712 y = rect->pos.y;
713 width = rect->size.width;
714 height = rect->size.height;
716 back = (state & WLDSSelected) ? scr->white : scr->gray;
718 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
719 len = strlen(dirfile) + strlen(text) + 4;
720 file = wmalloc(len);
721 snprintf(file, len, "%s/%s", dirfile, text);
722 wfree(dirfile);
724 color.red = WMRedComponentOfColor(back) >> 8;
725 color.green = WMGreenComponentOfColor(back) >> 8;
726 color.blue = WMBlueComponentOfColor(back) >> 8;
727 color.alpha = WMGetColorAlpha(back) >> 8;
729 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
730 wfree(file);
732 if (!pixmap) {
733 /*WMRemoveListItem(lPtr, index); */
734 return;
737 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
739 XSetClipMask(dpy, gc, None);
740 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54); */
741 XDrawLine(dpy, d, WMColorGC(scr->white), x, y + height - 1, x + width, y + height - 1);
743 size = WMGetPixmapSize(pixmap);
745 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
746 XSetClipOrigin(dpy, copygc, x + (width - size.width) / 2, y + 2);
747 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
748 size.width > 100 ? 100 : size.width, size.height > 64 ? 64 : size.height,
749 x + (width - size.width) / 2, y + 2);
752 int i, j;
753 int fheight = WMFontHeight(panel->normalfont);
754 int tlen = strlen(text);
755 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
756 int ofx, ofy;
758 ofx = x + (width - twidth) / 2;
759 ofy = y + 64 - fheight;
761 for (i = -1; i < 2; i++)
762 for (j = -1; j < 2; j++)
763 WMDrawString(wmscr, d, scr->white, panel->normalfont,
764 ofx + i, ofy + j, text, tlen);
766 WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy, text, tlen);
769 WMReleasePixmap(pixmap);
770 /* I hope it is better to do not use cache / on my box it is fast nuff */
771 XFlush(dpy);
774 static void buttonCallback(void *self, void *clientData)
776 WMButton *bPtr = (WMButton *) self;
777 IconPanel *panel = (IconPanel *) clientData;
779 if (bPtr == panel->okButton) {
780 panel->done = True;
781 panel->result = True;
782 } else if (bPtr == panel->cancelButton) {
783 panel->done = True;
784 panel->result = False;
785 } else if (bPtr == panel->previewButton) {
786 /**** Previewer ****/
787 WMSetButtonEnabled(bPtr, False);
788 WMSetListUserDrawItemHeight(panel->iconList, 68);
789 WMSetListUserDrawProc(panel->iconList, drawIconProc);
790 WMRedisplayWidget(panel->iconList);
791 /* for draw proc to access screen/gc */
792 /*** end preview ***/
794 #if 0
795 else if (bPtr == panel->chooseButton) {
796 WMOpenPanel *op;
798 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
800 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
801 char *path;
802 path = WMGetFilePanelFile(op);
803 WMSetTextFieldText(panel->fileField, path);
804 setViewedImage(panel, path);
805 wfree(path);
807 WMDestroyFilePanel(op);
809 #endif
812 static void keyPressHandler(XEvent * event, void *data)
814 IconPanel *panel = (IconPanel *) data;
815 char buffer[32];
816 int count;
817 KeySym ksym;
818 int iidx;
819 int didx;
820 int item = 0;
821 WMList *list = NULL;
823 if (event->type == KeyRelease)
824 return;
826 buffer[0] = 0;
827 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
829 iidx = WMGetListSelectedItemRow(panel->iconList);
830 didx = WMGetListSelectedItemRow(panel->dirList);
832 switch (ksym) {
833 case XK_Up:
834 if (iidx > 0)
835 item = iidx - 1;
836 else
837 item = iidx;
838 list = panel->iconList;
839 break;
840 case XK_Down:
841 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
842 item = iidx + 1;
843 else
844 item = iidx;
845 list = panel->iconList;
846 break;
847 case XK_Home:
848 item = 0;
849 list = panel->iconList;
850 break;
851 case XK_End:
852 item = WMGetListNumberOfRows(panel->iconList) - 1;
853 list = panel->iconList;
854 break;
855 case XK_Next:
856 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
857 item = didx + 1;
858 else
859 item = didx;
860 list = panel->dirList;
861 break;
862 case XK_Prior:
863 if (didx > 0)
864 item = didx - 1;
865 else
866 item = 0;
867 list = panel->dirList;
868 break;
869 case XK_Return:
870 WMPerformButtonClick(panel->okButton);
871 break;
872 case XK_Escape:
873 WMPerformButtonClick(panel->cancelButton);
874 break;
877 if (list) {
878 WMSelectListItem(list, item);
879 WMSetListPosition(list, item - 5);
880 listCallback(list, panel);
884 Bool wIconChooserDialog(WScreen * scr, char **file, char *instance, char *class)
886 WWindow *wwin;
887 Window parent;
888 IconPanel *panel;
889 WMColor *color;
890 WMFont *boldFont;
891 Bool result;
893 panel = wmalloc(sizeof(IconPanel));
894 memset(panel, 0, sizeof(IconPanel));
896 panel->scr = scr;
898 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
899 WMResizeWidget(panel->win, 450, 280);
901 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask | KeyReleaseMask, keyPressHandler, panel);
903 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
904 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
906 panel->dirLabel = WMCreateLabel(panel->win);
907 WMResizeWidget(panel->dirLabel, 200, 20);
908 WMMoveWidget(panel->dirLabel, 10, 7);
909 WMSetLabelText(panel->dirLabel, _("Directories"));
910 WMSetLabelFont(panel->dirLabel, boldFont);
911 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
913 WMSetLabelRelief(panel->dirLabel, WRSunken);
915 panel->iconLabel = WMCreateLabel(panel->win);
916 WMResizeWidget(panel->iconLabel, 140, 20);
917 WMMoveWidget(panel->iconLabel, 215, 7);
918 WMSetLabelText(panel->iconLabel, _("Icons"));
919 WMSetLabelFont(panel->iconLabel, boldFont);
920 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
922 WMReleaseFont(boldFont);
924 color = WMWhiteColor(scr->wmscreen);
925 WMSetLabelTextColor(panel->dirLabel, color);
926 WMSetLabelTextColor(panel->iconLabel, color);
927 WMReleaseColor(color);
929 color = WMDarkGrayColor(scr->wmscreen);
930 WMSetWidgetBackgroundColor(panel->iconLabel, color);
931 WMSetWidgetBackgroundColor(panel->dirLabel, color);
932 WMReleaseColor(color);
934 WMSetLabelRelief(panel->iconLabel, WRSunken);
936 panel->dirList = WMCreateList(panel->win);
937 WMResizeWidget(panel->dirList, 200, 170);
938 WMMoveWidget(panel->dirList, 10, 30);
939 WMSetListAction(panel->dirList, listCallback, panel);
941 panel->iconList = WMCreateList(panel->win);
942 WMResizeWidget(panel->iconList, 140, 170);
943 WMMoveWidget(panel->iconList, 215, 30);
944 WMSetListAction(panel->iconList, listCallback, panel);
946 WMHangData(panel->iconList, panel);
948 panel->previewButton = WMCreateCommandButton(panel->win);
949 WMResizeWidget(panel->previewButton, 75, 26);
950 WMMoveWidget(panel->previewButton, 365, 130);
951 WMSetButtonText(panel->previewButton, _("Preview"));
952 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
954 panel->iconView = WMCreateLabel(panel->win);
955 WMResizeWidget(panel->iconView, 75, 75);
956 WMMoveWidget(panel->iconView, 365, 40);
957 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
958 WMSetLabelRelief(panel->iconView, WRSunken);
959 WMSetLabelTextAlignment(panel->iconView, WACenter);
961 panel->fileLabel = WMCreateLabel(panel->win);
962 WMResizeWidget(panel->fileLabel, 80, 20);
963 WMMoveWidget(panel->fileLabel, 10, 210);
964 WMSetLabelText(panel->fileLabel, _("File Name:"));
966 panel->fileField = WMCreateTextField(panel->win);
967 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
968 WMResizeWidget(panel->fileField, 345, 20);
969 WMMoveWidget(panel->fileField, 95, 210);
970 WMSetTextFieldEditable(panel->fileField, False);
972 panel->okButton = WMCreateCommandButton(panel->win);
973 WMResizeWidget(panel->okButton, 80, 26);
974 WMMoveWidget(panel->okButton, 360, 240);
975 WMSetButtonText(panel->okButton, _("OK"));
976 WMSetButtonEnabled(panel->okButton, False);
977 WMSetButtonAction(panel->okButton, buttonCallback, panel);
979 panel->cancelButton = WMCreateCommandButton(panel->win);
980 WMResizeWidget(panel->cancelButton, 80, 26);
981 WMMoveWidget(panel->cancelButton, 270, 240);
982 WMSetButtonText(panel->cancelButton, _("Cancel"));
983 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
984 #if 0
985 panel->chooseButton = WMCreateCommandButton(panel->win);
986 WMResizeWidget(panel->chooseButton, 110, 26);
987 WMMoveWidget(panel->chooseButton, 150, 240);
988 WMSetButtonText(panel->chooseButton, _("Choose File"));
989 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
990 #endif
991 WMRealizeWidget(panel->win);
992 WMMapSubwidgets(panel->win);
994 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
996 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
999 char *tmp;
1000 int len = (instance ? strlen(instance) : 0)
1001 + (class ? strlen(class) : 0) + 32;
1002 WMPoint center;
1004 tmp = wmalloc(len);
1006 if (tmp && (instance || class))
1007 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
1008 else
1009 strcpy(tmp, _("Icon Chooser"));
1011 center = getCenter(scr, 450, 280);
1013 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x, center.y, 450, 280);
1014 wfree(tmp);
1017 /* put icon paths in the list */
1018 listIconPaths(panel->dirList);
1020 WMMapWidget(panel->win);
1022 wWindowMap(wwin);
1024 while (!panel->done) {
1025 XEvent event;
1027 WMNextEvent(dpy, &event);
1028 WMHandleEvent(&event);
1031 if (panel->result) {
1032 char *defaultPath, *wantedPath;
1034 /* check if the file the user selected is not the one that
1035 * would be loaded by default with the current search path */
1036 *file = WMGetListSelectedItem(panel->iconList)->text;
1037 if (**file == 0) {
1038 wfree(*file);
1039 *file = NULL;
1040 } else {
1041 defaultPath = FindImage(wPreferences.icon_path, *file);
1042 wantedPath = WMGetTextFieldText(panel->fileField);
1043 /* if the file is not the default, use full path */
1044 if (strcmp(wantedPath, defaultPath) != 0) {
1045 *file = wantedPath;
1046 } else {
1047 *file = wstrdup(*file);
1048 wfree(wantedPath);
1050 wfree(defaultPath);
1052 } else {
1053 *file = NULL;
1056 result = panel->result;
1058 WMReleaseFont(panel->normalfont);
1060 WMUnmapWidget(panel->win);
1062 WMDestroyWidget(panel->win);
1064 wUnmanageWindow(wwin, False, False);
1066 wfree(panel);
1068 XDestroyWindow(dpy, parent);
1070 return result;
1074 ***********************************************************************
1075 * Info Panel
1076 ***********************************************************************
1079 typedef struct {
1080 WScreen *scr;
1081 WWindow *wwin;
1082 WMWindow *win;
1083 WMLabel *logoL;
1084 WMLabel *name1L;
1085 WMFrame *lineF;
1086 WMLabel *name2L;
1087 WMLabel *versionL;
1088 WMLabel *infoL;
1089 WMLabel *copyrL;
1090 } InfoPanel;
1092 #define COPYRIGHT_TEXT \
1093 "Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
1094 "Copyright \xc2\xa9 1998-2006 Dan Pascu"
1096 static InfoPanel *thePanel = NULL;
1098 static void destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
1100 WMUnmapWidget(thePanel);
1101 wUnmanageWindow(thePanel->wwin, False, False);
1102 WMDestroyWidget(thePanel->win);
1103 wfree(thePanel);
1104 thePanel = NULL;
1107 void wShowInfoPanel(WScreen * scr)
1109 InfoPanel *panel;
1110 WMPixmap *logo;
1111 WMSize size;
1112 WMFont *font;
1113 char *strbuf = NULL;
1114 char buffer[256];
1115 char *name;
1116 Window parent;
1117 WWindow *wwin;
1118 char **strl;
1119 int i, width = 50, sepHeight;
1120 char *visuals[] = {
1121 "StaticGray",
1122 "GrayScale",
1123 "StaticColor",
1124 "PseudoColor",
1125 "TrueColor",
1126 "DirectColor"
1129 if (thePanel) {
1130 if (thePanel->scr == scr) {
1131 wRaiseFrame(thePanel->wwin->frame->core);
1132 wSetFocusTo(scr, thePanel->wwin);
1134 return;
1137 panel = wmalloc(sizeof(InfoPanel));
1138 memset(panel, 0, sizeof(InfoPanel));
1140 panel->scr = scr;
1142 panel->win = WMCreateWindow(scr->wmscreen, "info");
1143 WMResizeWidget(panel->win, 390, 230);
1145 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
1146 if (!logo) {
1147 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1149 if (logo) {
1150 size = WMGetPixmapSize(logo);
1151 panel->logoL = WMCreateLabel(panel->win);
1152 WMResizeWidget(panel->logoL, 64, 64);
1153 WMMoveWidget(panel->logoL, 30, 20);
1154 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1155 WMSetLabelImage(panel->logoL, logo);
1156 WMReleasePixmap(logo);
1159 sepHeight = 3;
1160 panel->name1L = WMCreateLabel(panel->win);
1161 WMResizeWidget(panel->name1L, 240, 30 + 2);
1162 WMMoveWidget(panel->name1L, 100, 30 - 2 - sepHeight);
1164 name = "Lucida Sans,Comic Sans MS,URW Gothic L,Trebuchet MS" ":italic:pixelsize=28:antialias=true";
1165 font = WMCreateFont(scr->wmscreen, name);
1166 strbuf = "Window Maker";
1167 if (font) {
1168 width = WMWidthOfString(font, strbuf, strlen(strbuf));
1169 WMSetLabelFont(panel->name1L, font);
1170 WMReleaseFont(font);
1172 WMSetLabelTextAlignment(panel->name1L, WACenter);
1173 WMSetLabelText(panel->name1L, strbuf);
1175 panel->lineF = WMCreateFrame(panel->win);
1176 WMResizeWidget(panel->lineF, width, sepHeight);
1177 WMMoveWidget(panel->lineF, 100 + (240 - width) / 2, 60 - sepHeight);
1178 WMSetFrameRelief(panel->lineF, WRSimple);
1179 WMSetWidgetBackgroundColor(panel->lineF, scr->black);
1181 panel->name2L = WMCreateLabel(panel->win);
1182 WMResizeWidget(panel->name2L, 240, 24);
1183 WMMoveWidget(panel->name2L, 100, 60);
1184 name = "URW Gothic L,Nimbus Sans L:pixelsize=16:antialias=true";
1185 font = WMCreateFont(scr->wmscreen, name);
1186 if (font) {
1187 WMSetLabelFont(panel->name2L, font);
1188 WMReleaseFont(font);
1189 font = NULL;
1191 WMSetLabelTextAlignment(panel->name2L, WACenter);
1192 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1194 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1195 panel->versionL = WMCreateLabel(panel->win);
1196 WMResizeWidget(panel->versionL, 310, 16);
1197 WMMoveWidget(panel->versionL, 30, 95);
1198 WMSetLabelTextAlignment(panel->versionL, WARight);
1199 WMSetLabelText(panel->versionL, buffer);
1200 WMSetLabelWraps(panel->versionL, False);
1202 panel->copyrL = WMCreateLabel(panel->win);
1203 WMResizeWidget(panel->copyrL, 360, 40);
1204 WMMoveWidget(panel->copyrL, 15, 185);
1205 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1206 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1207 font = WMSystemFontOfSize(scr->wmscreen, 11);
1208 if (font) {
1209 WMSetLabelFont(panel->copyrL, font);
1210 WMReleaseFont(font);
1211 font = NULL;
1214 strbuf = NULL;
1215 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1216 (unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
1218 strbuf = wstrappend(strbuf, buffer);
1220 switch (scr->w_depth) {
1221 case 15:
1222 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1223 break;
1224 case 16:
1225 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1226 break;
1227 case 24:
1228 case 32:
1229 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1230 break;
1231 default:
1232 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1 << scr->w_depth);
1233 strbuf = wstrappend(strbuf, buffer);
1234 break;
1237 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1239 struct mallinfo ma = mallinfo();
1240 snprintf(buffer, sizeof(buffer),
1241 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1242 (ma.arena + ma.hblkhd) / 1024, (ma.uordblks + ma.hblkhd) / 1024);
1244 strbuf = wstrappend(strbuf, buffer);
1246 #endif
1248 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1249 strl = RSupportedFileFormats();
1250 for (i = 0; strl[i] != NULL; i++) {
1251 strbuf = wstrappend(strbuf, strl[i]);
1252 strbuf = wstrappend(strbuf, " ");
1255 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1257 char *list[9];
1258 char buf[80];
1259 int j = 0;
1261 list[j++] = "WMSPEC";
1262 #ifdef MWM_HINTS
1263 list[j++] = "MWM";
1264 #endif
1266 buf[0] = 0;
1267 for (i = 0; i < j; i++) {
1268 if (i > 0) {
1269 if (i == j - 1)
1270 strcat(buf, _(" and "));
1271 else
1272 strcat(buf, ", ");
1274 strcat(buf, list[i]);
1276 strbuf = wstrappend(strbuf, buf);
1279 #ifdef VIRTUAL_DESKTOP
1280 if (wPreferences.vdesk_enable)
1281 strbuf = wstrappend(strbuf, _(", VirtualDesktop enabled"));
1282 else
1283 strbuf = wstrappend(strbuf, _(", VirtualDesktop disabled"));
1284 #endif
1286 #ifdef XINERAMA
1287 strbuf = wstrappend(strbuf, _("\n"));
1288 #ifdef SOLARIS_XINERAMA
1289 strbuf = wstrappend(strbuf, _("Solaris "));
1290 #endif
1291 strbuf = wstrappend(strbuf, _("Xinerama: "));
1293 char tmp[128];
1294 snprintf(tmp, sizeof(tmp) - 1, "%d heads found.", scr->xine_info.count);
1295 strbuf = wstrappend(strbuf, tmp);
1297 #endif
1299 panel->infoL = WMCreateLabel(panel->win);
1300 WMResizeWidget(panel->infoL, 350, 75);
1301 WMMoveWidget(panel->infoL, 15, 115);
1302 WMSetLabelText(panel->infoL, strbuf);
1303 font = WMSystemFontOfSize(scr->wmscreen, 11);
1304 if (font) {
1305 WMSetLabelFont(panel->infoL, font);
1306 WMReleaseFont(font);
1307 font = NULL;
1309 wfree(strbuf);
1311 WMRealizeWidget(panel->win);
1312 WMMapSubwidgets(panel->win);
1314 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1316 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1318 WMMapWidget(panel->win);
1321 WMPoint center = getCenter(scr, 382, 230);
1323 wwin = wManageInternalWindow(scr, parent, None, _("Info"), center.x, center.y, 382, 230);
1326 WSETUFLAG(wwin, no_closable, 0);
1327 WSETUFLAG(wwin, no_close_button, 0);
1328 #ifdef XKB_BUTTON_HINT
1329 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1330 #endif
1331 wWindowUpdateButtonImages(wwin);
1332 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1333 wwin->frame->on_click_right = destroyInfoPanel;
1335 wWindowMap(wwin);
1337 panel->wwin = wwin;
1338 thePanel = panel;
1342 ***********************************************************************
1343 * Legal Panel
1344 ***********************************************************************
1347 typedef struct {
1348 WScreen *scr;
1350 WWindow *wwin;
1352 WMWindow *win;
1354 WMLabel *licenseL;
1355 } LegalPanel;
1357 static LegalPanel *legalPanel = NULL;
1359 static void destroyLegalPanel(WCoreWindow * foo, void *data, XEvent * event)
1361 WMUnmapWidget(legalPanel->win);
1363 WMDestroyWidget(legalPanel->win);
1365 wUnmanageWindow(legalPanel->wwin, False, False);
1367 wfree(legalPanel);
1369 legalPanel = NULL;
1372 void wShowLegalPanel(WScreen * scr)
1374 LegalPanel *panel;
1375 Window parent;
1376 WWindow *wwin;
1378 if (legalPanel) {
1379 if (legalPanel->scr == scr) {
1380 wRaiseFrame(legalPanel->wwin->frame->core);
1381 wSetFocusTo(scr, legalPanel->wwin);
1383 return;
1386 panel = wmalloc(sizeof(LegalPanel));
1388 panel->scr = scr;
1390 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1391 WMResizeWidget(panel->win, 420, 250);
1393 panel->licenseL = WMCreateLabel(panel->win);
1394 WMSetLabelWraps(panel->licenseL, True);
1395 WMResizeWidget(panel->licenseL, 400, 230);
1396 WMMoveWidget(panel->licenseL, 10, 10);
1397 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1398 WMSetLabelText(panel->licenseL,
1399 _(" Window Maker is free software; you can redistribute it and/or\n"
1400 "modify it under the terms of the GNU General Public License as\n"
1401 "published by the Free Software Foundation; either version 2 of the\n"
1402 "License, or (at your option) any later version.\n\n"
1403 " Window Maker is distributed in the hope that it will be useful,\n"
1404 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1405 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1406 "See the GNU General Public License for more details.\n\n"
1407 " You should have received a copy of the GNU General Public\n"
1408 "License along with this program; if not, write to the Free Software\n"
1409 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n" "02111-1307, USA."));
1410 WMSetLabelRelief(panel->licenseL, WRGroove);
1412 WMRealizeWidget(panel->win);
1413 WMMapSubwidgets(panel->win);
1415 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1417 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1420 WMPoint center = getCenter(scr, 420, 250);
1422 wwin = wManageInternalWindow(scr, parent, None, _("Legal"), center.x, center.y, 420, 250);
1425 WSETUFLAG(wwin, no_closable, 0);
1426 WSETUFLAG(wwin, no_close_button, 0);
1427 wWindowUpdateButtonImages(wwin);
1428 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1429 #ifdef XKB_BUTTON_HINT
1430 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1431 #endif
1432 wwin->frame->on_click_right = destroyLegalPanel;
1434 panel->wwin = wwin;
1436 WMMapWidget(panel->win);
1438 wWindowMap(wwin);
1440 legalPanel = panel;
1444 ***********************************************************************
1445 * Crashing Dialog Panel
1446 ***********************************************************************
1449 extern WDDomain *WDWindowAttributes;
1451 typedef struct _CrashPanel {
1452 WMWindow *win; /* main window */
1454 WMLabel *iconL; /* application icon */
1455 WMLabel *nameL; /* title of panel */
1457 WMFrame *sepF; /* separator frame */
1459 WMLabel *noteL; /* Title of note */
1460 WMLabel *note2L; /* body of note with what happened */
1462 WMFrame *whatF; /* "what to do next" frame */
1463 WMPopUpButton *whatP; /* action selection popup button */
1465 WMButton *okB; /* ok button */
1467 Bool done; /* if finished with this dialog */
1468 int action; /* what to do after */
1470 KeyCode retKey;
1472 } CrashPanel;
1474 static void handleKeyPress(XEvent * event, void *clientData)
1476 CrashPanel *panel = (CrashPanel *) clientData;
1478 if (event->xkey.keycode == panel->retKey) {
1479 WMPerformButtonClick(panel->okB);
1483 static void okButtonCallback(void *self, void *clientData)
1485 CrashPanel *panel = (CrashPanel *) clientData;
1487 panel->done = True;
1490 static void setCrashAction(void *self, void *clientData)
1492 WMPopUpButton *pop = (WMPopUpButton *) self;
1493 CrashPanel *panel = (CrashPanel *) clientData;
1495 panel->action = WMGetPopUpButtonSelectedItem(pop);
1498 /* Make this read the logo from a compiled in pixmap -Dan */
1499 static WMPixmap *getWindowMakerIconImage(WMScreen * scr)
1501 WMPropList *dict, *key, *option, *value = NULL;
1502 WMPixmap *pix = NULL;
1503 char *path;
1505 if (!WDWindowAttributes || !WDWindowAttributes->dictionary)
1506 return NULL;
1508 WMPLSetCaseSensitive(True);
1510 key = WMCreatePLString("Logo.WMPanel");
1511 option = WMCreatePLString("Icon");
1513 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1515 if (dict) {
1516 value = WMGetFromPLDictionary(dict, option);
1519 WMReleasePropList(key);
1520 WMReleasePropList(option);
1522 WMPLSetCaseSensitive(False);
1524 if (value && WMIsPLString(value)) {
1525 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1527 if (path) {
1528 RColor gray;
1530 gray.red = 0xae;
1531 gray.green = 0xaa;
1532 gray.blue = 0xae;
1533 gray.alpha = 0;
1535 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1536 wfree(path);
1540 return pix;
1543 #define PWIDTH 295
1544 #define PHEIGHT 345
1546 int wShowCrashingDialogPanel(int whatSig)
1548 CrashPanel *panel;
1549 WMScreen *scr;
1550 WMFont *font;
1551 WMPixmap *logo;
1552 int screen_no, scr_width, scr_height;
1553 int action;
1554 char buf[256];
1556 panel = wmalloc(sizeof(CrashPanel));
1557 memset(panel, 0, sizeof(CrashPanel));
1559 screen_no = DefaultScreen(dpy);
1560 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1561 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1563 scr = WMCreateScreen(dpy, screen_no);
1564 if (!scr) {
1565 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1566 return WMAbort;
1569 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1571 panel->win = WMCreateWindow(scr, "crashingDialog");
1572 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1573 WMMoveWidget(panel->win, (scr_width - PWIDTH) / 2, (scr_height - PHEIGHT) / 2);
1575 logo = getWindowMakerIconImage(scr);
1576 if (logo) {
1577 panel->iconL = WMCreateLabel(panel->win);
1578 WMResizeWidget(panel->iconL, 64, 64);
1579 WMMoveWidget(panel->iconL, 10, 10);
1580 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1581 WMSetLabelImage(panel->iconL, logo);
1584 panel->nameL = WMCreateLabel(panel->win);
1585 WMResizeWidget(panel->nameL, 200, 30);
1586 WMMoveWidget(panel->nameL, 80, 25);
1587 WMSetLabelTextAlignment(panel->nameL, WALeft);
1588 font = WMBoldSystemFontOfSize(scr, 24);
1589 WMSetLabelFont(panel->nameL, font);
1590 WMReleaseFont(font);
1591 WMSetLabelText(panel->nameL, _("Fatal error"));
1593 panel->sepF = WMCreateFrame(panel->win);
1594 WMResizeWidget(panel->sepF, PWIDTH + 4, 2);
1595 WMMoveWidget(panel->sepF, -2, 80);
1597 panel->noteL = WMCreateLabel(panel->win);
1598 WMResizeWidget(panel->noteL, PWIDTH - 20, 40);
1599 WMMoveWidget(panel->noteL, 10, 90);
1600 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1601 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1602 WMSetLabelText(panel->noteL, buf);
1604 panel->note2L = WMCreateLabel(panel->win);
1605 WMResizeWidget(panel->note2L, PWIDTH - 20, 100);
1606 WMMoveWidget(panel->note2L, 10, 130);
1607 WMSetLabelTextAlignment(panel->note2L, WALeft);
1608 WMSetLabelText(panel->note2L,
1609 _(" This fatal error occured probably due to a bug."
1610 " Please fill the included BUGFORM and " "report it to bugs@windowmaker.info."));
1611 WMSetLabelWraps(panel->note2L, True);
1613 panel->whatF = WMCreateFrame(panel->win);
1614 WMResizeWidget(panel->whatF, PWIDTH - 20, 50);
1615 WMMoveWidget(panel->whatF, 10, 240);
1616 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1618 panel->whatP = WMCreatePopUpButton(panel->whatF);
1619 WMResizeWidget(panel->whatP, PWIDTH - 20 - 70, 20);
1620 WMMoveWidget(panel->whatP, 35, 20);
1621 WMSetPopUpButtonPullsDown(panel->whatP, False);
1622 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1623 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1624 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1625 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1626 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1627 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1628 panel->action = WMRestart;
1630 WMMapSubwidgets(panel->whatF);
1632 panel->okB = WMCreateCommandButton(panel->win);
1633 WMResizeWidget(panel->okB, 80, 26);
1634 WMMoveWidget(panel->okB, 205, 309);
1635 WMSetButtonText(panel->okB, _("OK"));
1636 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1637 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1638 WMSetButtonImagePosition(panel->okB, WIPRight);
1639 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1641 panel->done = 0;
1643 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask, handleKeyPress, panel);
1645 WMRealizeWidget(panel->win);
1646 WMMapSubwidgets(panel->win);
1648 WMMapWidget(panel->win);
1650 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1652 while (!panel->done) {
1653 XEvent event;
1655 WMNextEvent(dpy, &event);
1656 WMHandleEvent(&event);
1659 action = panel->action;
1661 WMUnmapWidget(panel->win);
1662 WMDestroyWidget(panel->win);
1663 wfree(panel);
1665 return action;
1668 /*****************************************************************************
1669 * About GNUstep Panel
1670 *****************************************************************************/
1672 static void
1673 drawGNUstepLogo(Display * dpy, Drawable d, int width, int height,
1674 unsigned long blackPixel, unsigned long whitePixel)
1676 GC gc;
1677 XGCValues gcv;
1678 XRectangle rects[3];
1680 gcv.foreground = blackPixel;
1681 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1683 XFillArc(dpy, d, gc, width / 45, height / 45,
1684 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
1686 rects[0].x = 0;
1687 rects[0].y = 37 * height / 45;
1688 rects[0].width = width / 3;
1689 rects[0].height = height - rects[0].y;
1691 rects[1].x = rects[0].width;
1692 rects[1].y = height / 2;
1693 rects[1].width = width - 2 * width / 3;
1694 rects[1].height = height - rects[1].y;
1696 rects[2].x = 2 * width / 3;
1697 rects[2].y = height - 37 * height / 45;
1698 rects[2].width = width / 3;
1699 rects[2].height = height - rects[2].y;
1701 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1702 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1704 XSetForeground(dpy, gc, whitePixel);
1705 XFillArc(dpy, d, gc, width / 45, height / 45,
1706 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
1708 XFreeGC(dpy, gc);
1711 typedef struct {
1712 WScreen *scr;
1714 WWindow *wwin;
1716 WMWindow *win;
1718 WMLabel *gstepL;
1719 WMLabel *textL;
1720 } GNUstepPanel;
1722 static GNUstepPanel *gnustepPanel = NULL;
1724 static void destroyGNUstepPanel(WCoreWindow * foo, void *data, XEvent * event)
1726 WMUnmapWidget(gnustepPanel->win);
1728 WMDestroyWidget(gnustepPanel->win);
1730 wUnmanageWindow(gnustepPanel->wwin, False, False);
1732 wfree(gnustepPanel);
1734 gnustepPanel = NULL;
1737 void wShowGNUstepPanel(WScreen * scr)
1739 GNUstepPanel *panel;
1740 Window parent;
1741 WWindow *wwin;
1742 WMPixmap *pixmap;
1743 WMColor *color;
1745 if (gnustepPanel) {
1746 if (gnustepPanel->scr == scr) {
1747 wRaiseFrame(gnustepPanel->wwin->frame->core);
1748 wSetFocusTo(scr, gnustepPanel->wwin);
1750 return;
1753 panel = wmalloc(sizeof(GNUstepPanel));
1755 panel->scr = scr;
1757 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1758 WMResizeWidget(panel->win, 325, 205);
1760 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130, WMScreenDepth(scr->wmscreen), True);
1762 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1764 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130, WMColorPixel(color), scr->white_pixel);
1766 WMReleaseColor(color);
1768 XSetForeground(dpy, scr->mono_gc, 0);
1769 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0, 130, 130);
1770 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1772 panel->gstepL = WMCreateLabel(panel->win);
1773 WMResizeWidget(panel->gstepL, 285, 64);
1774 WMMoveWidget(panel->gstepL, 20, 0);
1775 WMSetLabelTextAlignment(panel->gstepL, WARight);
1776 WMSetLabelText(panel->gstepL, "GNUstep");
1778 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1780 WMSetLabelFont(panel->gstepL, font);
1781 WMReleaseFont(font);
1784 panel->textL = WMCreateLabel(panel->win);
1785 WMResizeWidget(panel->textL, 305, 140);
1786 WMMoveWidget(panel->textL, 10, 50);
1787 WMSetLabelTextAlignment(panel->textL, WARight);
1788 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1789 WMSetLabelText(panel->textL,
1790 _("Window Maker is part of the GNUstep project.\n"
1791 "The GNUstep project aims to create a free\n"
1792 "implementation of the OpenStep(tm) specification\n"
1793 "which is a object-oriented framework for\n"
1794 "creating advanced graphical, multi-platform\n"
1795 "applications. Additionally, a development and\n"
1796 "user desktop enviroment will be created on top\n"
1797 "of the framework. For more information about\n"
1798 "GNUstep, please visit: www.gnustep.org"));
1799 WMSetLabelImage(panel->textL, pixmap);
1801 WMReleasePixmap(pixmap);
1803 WMRealizeWidget(panel->win);
1804 WMMapSubwidgets(panel->win);
1806 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1808 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1811 WMPoint center = getCenter(scr, 325, 200);
1813 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"), center.x, center.y, 325, 200);
1816 WSETUFLAG(wwin, no_closable, 0);
1817 WSETUFLAG(wwin, no_close_button, 0);
1818 wWindowUpdateButtonImages(wwin);
1819 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1820 #ifdef XKB_BUTTON_HINT
1821 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1822 #endif
1823 wwin->frame->on_click_right = destroyGNUstepPanel;
1825 panel->wwin = wwin;
1827 WMMapWidget(panel->win);
1829 wWindowMap(wwin);
1831 gnustepPanel = panel;