Cleanup includes of wcore.h, defaults.h and pixmap.h
[wmaker-crm.git] / src / dialog.c
blob4c953fdaa80b5cfed1b87e7af72a669886c31c53
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 "xinerama.h"
63 extern WPreferences wPreferences;
65 static WMPoint getCenter(WScreen * scr, int width, int height)
67 return wGetPointToCenterRectInHead(scr, wGetHeadForPointerLocation(scr), width, height);
70 int wMessageDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
72 WMAlertPanel *panel;
73 Window parent;
74 WWindow *wwin;
75 int result;
76 WMPoint center;
78 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
80 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
82 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
84 center = getCenter(scr, 400, 180);
85 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
86 wwin->client_leader = WMWidgetXID(panel->win);
88 WMMapWidget(panel->win);
90 wWindowMap(wwin);
92 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
94 result = panel->result;
96 WMUnmapWidget(panel->win);
98 wUnmanageWindow(wwin, False, False);
100 WMDestroyAlertPanel(panel);
102 XDestroyWindow(dpy, parent);
104 return result;
107 void toggleSaveSession(WMWidget * w, void *data)
109 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
112 int wExitDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
114 WMAlertPanel *panel;
115 WMButton *saveSessionBtn;
116 Window parent;
117 WWindow *wwin;
118 WMPoint center;
119 int result;
121 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
123 /* add save session button */
124 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
125 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
126 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn), False, True, 200, 0, 0);
127 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
128 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
129 WMRealizeWidget(saveSessionBtn);
130 WMMapWidget(saveSessionBtn);
132 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
134 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
136 center = getCenter(scr, 400, 180);
137 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
139 wwin->client_leader = WMWidgetXID(panel->win);
141 WMMapWidget(panel->win);
143 wWindowMap(wwin);
145 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
147 result = panel->result;
149 WMUnmapWidget(panel->win);
151 wUnmanageWindow(wwin, False, False);
153 WMDestroyAlertPanel(panel);
155 XDestroyWindow(dpy, parent);
157 return result;
160 typedef struct _WMInputPanelWithHistory {
161 WMInputPanel *panel;
162 WMArray *history;
163 int histpos;
164 char *prefix;
165 char *suffix;
166 char *rest;
167 WMArray *variants;
168 int varpos;
169 } WMInputPanelWithHistory;
171 static char *HistoryFileName(char *name)
173 char *filename = NULL;
175 filename = wstrdup(wusergnusteppath());
176 filename = wstrappend(filename, "/.AppInfo/WindowMaker/History");
177 if (name && strlen(name)) {
178 filename = wstrappend(filename, ".");
179 filename = wstrappend(filename, name);
181 return filename;
184 static int matchString(void *str1, void *str2)
186 return (strcmp((char *)str1, (char *)str2) == 0 ? 1 : 0);
189 static WMArray *LoadHistory(char *filename, int max)
191 WMPropList *plhistory;
192 WMPropList *plitem;
193 WMArray *history;
194 int i, num;
196 history = WMCreateArrayWithDestructor(1, wfree);
197 WMAddToArray(history, wstrdup(""));
199 plhistory = WMReadPropListFromFile((char *)filename);
201 if (plhistory && WMIsPLArray(plhistory)) {
202 num = WMGetPropListItemCount(plhistory);
203 if (num > max)
204 num = max;
206 for (i = 0; i < num; ++i) {
207 plitem = WMGetFromPLArray(plhistory, i);
208 if (WMIsPLString(plitem) && WMFindInArray(history, matchString,
209 WMGetFromPLString(plitem)) == WANotFound)
210 WMAddToArray(history, WMGetFromPLString(plitem));
214 return history;
217 static void SaveHistory(WMArray * history, char *filename)
219 int i;
220 WMPropList *plhistory;
222 plhistory = WMCreatePLArray(NULL);
224 for (i = 0; i < WMGetArrayItemCount(history); ++i)
225 WMAddToPLArray(plhistory, WMCreatePLString(WMGetFromArray(history, i)));
227 WMWritePropListToFile(plhistory, (char *)filename);
228 WMReleasePropList(plhistory);
231 static int strmatch(const char *str1, const char *str2)
233 return !strcmp(str1, str2);
236 static int pstrcmp(const char **str1, const char **str2)
238 return strcmp(*str1, *str2);
241 static void
242 ScanFiles(const char *dir, const char *prefix, unsigned acceptmask, unsigned declinemask, WMArray * result)
244 int prefixlen;
245 DIR *d;
246 struct dirent *de;
247 struct stat sb;
248 char *fullfilename, *suffix;
250 prefixlen = strlen(prefix);
251 if ((d = opendir(dir)) != NULL) {
252 while ((de = readdir(d)) != NULL) {
253 if (strlen(de->d_name) > prefixlen &&
254 !strncmp(prefix, de->d_name, prefixlen) &&
255 strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..")) {
256 fullfilename = wstrconcat((char *)dir, "/");
257 fullfilename = wstrappend(fullfilename, de->d_name);
259 if (stat(fullfilename, &sb) == 0 &&
260 (sb.st_mode & acceptmask) &&
261 !(sb.st_mode & declinemask) &&
262 WMFindInArray(result, (WMMatchDataProc *) strmatch,
263 de->d_name + prefixlen) == WANotFound) {
264 suffix = wstrdup(de->d_name + prefixlen);
265 if (sb.st_mode & S_IFDIR)
266 wstrappend(suffix,"/");
267 WMAddToArray(result, suffix);
269 wfree(fullfilename);
272 closedir(d);
276 static WMArray *GenerateVariants(const char *complete)
278 Bool firstWord = True;
279 WMArray *variants = NULL;
280 char *pos = NULL, *path = NULL, *tmp = NULL, *dir = NULL, *prefix = NULL;
282 variants = WMCreateArrayWithDestructor(0, wfree);
284 while (*complete == ' ')
285 ++complete;
287 if ((pos = strrchr(complete, ' ')) != NULL) {
288 complete = pos + 1;
289 firstWord = False;
292 if ((pos = strrchr(complete, '/')) != NULL) {
293 tmp = wstrndup((char *)complete, pos - complete + 1);
294 if (*tmp == '~' && *(tmp + 1) == '/' && getenv("HOME")) {
295 dir = wstrdup(getenv("HOME"));
296 dir = wstrappend(dir, tmp + 1);
297 wfree(tmp);
298 } else {
299 dir = tmp;
301 prefix = wstrdup(pos + 1);
302 ScanFiles(dir, prefix, (unsigned)-1, 0, variants);
303 wfree(dir);
304 wfree(prefix);
305 } else if (*complete == '~') {
306 WMAddToArray(variants, wstrdup("/"));
307 } else if (firstWord) {
308 path = getenv("PATH");
309 while (path) {
310 pos = strchr(path, ':');
311 if (pos) {
312 tmp = wstrndup(path, pos - path);
313 path = pos + 1;
314 } else if (*path != '\0') {
315 tmp = wstrdup(path);
316 path = NULL;
317 } else
318 break;
319 ScanFiles(tmp, complete, S_IXOTH | S_IXGRP | S_IXUSR, S_IFDIR, variants);
320 wfree(tmp);
324 WMSortArray(variants, (WMCompareDataProc *) pstrcmp);
325 return variants;
328 static void handleHistoryKeyPress(XEvent * event, void *clientData)
330 char *text;
331 unsigned pos;
332 WMInputPanelWithHistory *p = (WMInputPanelWithHistory *) clientData;
333 KeySym ksym;
335 ksym = XLookupKeysym(&event->xkey, 0);
337 switch (ksym) {
338 case XK_Up:
339 if (p->histpos < WMGetArrayItemCount(p->history) - 1) {
340 if (p->histpos == 0)
341 wfree(WMReplaceInArray(p->history, 0, WMGetTextFieldText(p->panel->text)));
342 p->histpos++;
343 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
345 break;
346 case XK_Down:
347 if (p->histpos > 0) {
348 p->histpos--;
349 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
351 break;
352 case XK_Tab:
353 if (!p->variants) {
354 text = WMGetTextFieldText(p->panel->text);
355 pos = WMGetTextFieldCursorPosition(p->panel->text);
356 p->prefix = wstrndup(text, pos);
357 p->suffix = wstrdup(text + pos);
358 wfree(text);
359 p->variants = GenerateVariants(p->prefix);
360 p->varpos = 0;
361 if (!p->variants) {
362 wfree(p->prefix);
363 wfree(p->suffix);
364 p->prefix = NULL;
365 p->suffix = NULL;
368 if (p->variants && p->prefix && p->suffix) {
369 p->varpos++;
370 if (p->varpos > WMGetArrayItemCount(p->variants))
371 p->varpos = 0;
372 if (p->varpos > 0)
373 text = wstrconcat(p->prefix, WMGetFromArray(p->variants, p->varpos - 1));
374 else
375 text = wstrdup(p->prefix);
376 pos = strlen(text);
377 text = wstrappend(text, p->suffix);
378 WMSetTextFieldText(p->panel->text, text);
379 WMSetTextFieldCursorPosition(p->panel->text, pos);
380 wfree(text);
382 break;
384 if (ksym != XK_Tab) {
385 if (p->prefix) {
386 wfree(p->prefix);
387 p->prefix = NULL;
389 if (p->suffix) {
390 wfree(p->suffix);
391 p->suffix = NULL;
393 if (p->variants) {
394 WMFreeArray(p->variants);
395 p->variants = NULL;
400 int wAdvancedInputDialog(WScreen * scr, char *title, char *message, char *name, char **text)
402 WWindow *wwin;
403 Window parent;
404 char *result;
405 WMPoint center;
406 WMInputPanelWithHistory *p;
407 char *filename;
409 filename = HistoryFileName(name);
410 p = wmalloc(sizeof(WMInputPanelWithHistory));
411 p->panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
412 p->history = LoadHistory(filename, wPreferences.history_lines);
413 p->histpos = 0;
414 p->prefix = NULL;
415 p->suffix = NULL;
416 p->rest = NULL;
417 p->variants = NULL;
418 p->varpos = 0;
419 WMCreateEventHandler(WMWidgetView(p->panel->text), KeyPressMask, handleHistoryKeyPress, p);
421 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
422 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
424 XReparentWindow(dpy, WMWidgetXID(p->panel->win), parent, 0, 0);
426 center = getCenter(scr, 320, 160);
427 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
429 wwin->client_leader = WMWidgetXID(p->panel->win);
431 WMMapWidget(p->panel->win);
433 wWindowMap(wwin);
435 WMRunModalLoop(WMWidgetScreen(p->panel->win), WMWidgetView(p->panel->win));
437 if (p->panel->result == WAPRDefault) {
438 result = WMGetTextFieldText(p->panel->text);
439 wfree(WMReplaceInArray(p->history, 0, wstrdup(result)));
440 SaveHistory(p->history, filename);
441 } else
442 result = NULL;
444 wUnmanageWindow(wwin, False, False);
446 WMDestroyInputPanel(p->panel);
447 WMFreeArray(p->history);
448 wfree(p);
449 wfree(filename);
451 XDestroyWindow(dpy, parent);
453 if (result == NULL)
454 return False;
455 else {
456 if (*text)
457 wfree(*text);
458 *text = result;
460 return True;
464 int wInputDialog(WScreen * scr, char *title, char *message, char **text)
466 WWindow *wwin;
467 Window parent;
468 WMInputPanel *panel;
469 char *result;
470 WMPoint center;
472 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
474 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
475 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
477 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
479 center = getCenter(scr, 320, 160);
480 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
482 wwin->client_leader = WMWidgetXID(panel->win);
484 WMMapWidget(panel->win);
486 wWindowMap(wwin);
488 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
490 if (panel->result == WAPRDefault)
491 result = WMGetTextFieldText(panel->text);
492 else
493 result = NULL;
495 wUnmanageWindow(wwin, False, False);
497 WMDestroyInputPanel(panel);
499 XDestroyWindow(dpy, parent);
501 if (result == NULL)
502 return False;
503 else {
504 if (*text)
505 wfree(*text);
506 *text = result;
508 return True;
513 *****************************************************************
514 * Icon Selection Panel
515 *****************************************************************
518 typedef struct IconPanel {
520 WScreen *scr;
522 WMWindow *win;
524 WMLabel *dirLabel;
525 WMLabel *iconLabel;
527 WMList *dirList;
528 WMList *iconList;
529 WMFont *normalfont;
531 WMButton *previewButton;
533 WMLabel *iconView;
535 WMLabel *fileLabel;
536 WMTextField *fileField;
538 WMButton *okButton;
539 WMButton *cancelButton;
540 #if 0
541 WMButton *chooseButton;
542 #endif
543 short done;
544 short result;
545 short preview;
546 } IconPanel;
548 static void listPixmaps(WScreen * scr, WMList * lPtr, char *path)
550 struct dirent *dentry;
551 DIR *dir;
552 char pbuf[PATH_MAX + 16];
553 char *apath;
554 IconPanel *panel = WMGetHangedData(lPtr);
556 panel->preview = False;
558 apath = wexpandpath(path);
559 dir = opendir(apath);
561 if (!dir) {
562 char *msg;
563 char *tmp;
564 tmp = _("Could not open directory ");
565 msg = wmalloc(strlen(tmp) + strlen(path) + 6);
566 strcpy(msg, tmp);
567 strcat(msg, path);
569 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
570 wfree(msg);
571 wfree(apath);
572 return;
575 /* list contents in the column */
576 while ((dentry = readdir(dir))) {
577 struct stat statb;
579 if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") == 0)
580 continue;
582 strcpy(pbuf, apath);
583 strcat(pbuf, "/");
584 strcat(pbuf, dentry->d_name);
586 if (stat(pbuf, &statb) < 0)
587 continue;
589 if (statb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)
590 && statb.st_mode & (S_IFREG | S_IFLNK)) {
591 WMAddListItem(lPtr, dentry->d_name);
594 WMSortListItems(lPtr);
596 closedir(dir);
597 wfree(apath);
598 panel->preview = True;
601 static void setViewedImage(IconPanel * panel, char *file)
603 WMPixmap *pixmap;
604 RColor color;
606 color.red = 0xae;
607 color.green = 0xaa;
608 color.blue = 0xae;
609 color.alpha = 0;
610 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win), file, &color);
611 if (!pixmap) {
612 WMSetButtonEnabled(panel->okButton, False);
614 WMSetLabelText(panel->iconView, _("Could not load image file "));
616 WMSetLabelImage(panel->iconView, NULL);
617 } else {
618 WMSetButtonEnabled(panel->okButton, True);
620 WMSetLabelText(panel->iconView, NULL);
621 WMSetLabelImage(panel->iconView, pixmap);
622 WMReleasePixmap(pixmap);
626 static void listCallback(void *self, void *data)
628 WMList *lPtr = (WMList *) self;
629 IconPanel *panel = (IconPanel *) data;
630 char *path;
632 if (lPtr == panel->dirList) {
633 WMListItem *item = WMGetListSelectedItem(lPtr);
635 if (item == NULL)
636 return;
637 path = item->text;
639 WMSetTextFieldText(panel->fileField, path);
641 WMSetLabelImage(panel->iconView, NULL);
643 WMSetButtonEnabled(panel->okButton, False);
645 WMClearList(panel->iconList);
646 listPixmaps(panel->scr, panel->iconList, path);
647 } else {
648 char *tmp, *iconFile;
649 WMListItem *item = WMGetListSelectedItem(panel->dirList);
651 if (item == NULL)
652 return;
653 path = item->text;
654 tmp = wexpandpath(path);
656 item = WMGetListSelectedItem(panel->iconList);
657 if (item == NULL)
658 return;
659 iconFile = item->text;
661 path = wmalloc(strlen(tmp) + strlen(iconFile) + 4);
662 strcpy(path, tmp);
663 strcat(path, "/");
664 strcat(path, iconFile);
665 wfree(tmp);
666 WMSetTextFieldText(panel->fileField, path);
667 setViewedImage(panel, path);
668 wfree(path);
672 static void listIconPaths(WMList * lPtr)
674 char *paths;
675 char *path;
677 paths = wstrdup(wPreferences.icon_path);
679 path = strtok(paths, ":");
681 do {
682 char *tmp;
684 tmp = wexpandpath(path);
685 /* do not sort, because the order implies the order of
686 * directories searched */
687 if (access(tmp, X_OK) == 0)
688 WMAddListItem(lPtr, path);
689 wfree(tmp);
690 } while ((path = strtok(NULL, ":")) != NULL);
692 wfree(paths);
695 static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
697 IconPanel *panel = WMGetHangedData(lPtr);
698 WScreen *scr = panel->scr;
699 GC gc = scr->draw_gc;
700 GC copygc = scr->copy_gc;
701 char *file, *dirfile;
702 WMPixmap *pixmap;
703 WMColor *back;
704 WMSize size;
705 WMScreen *wmscr = WMWidgetScreen(panel->win);
706 RColor color;
707 int x, y, width, height, len;
709 if (!panel->preview)
710 return;
712 x = rect->pos.x;
713 y = rect->pos.y;
714 width = rect->size.width;
715 height = rect->size.height;
717 back = (state & WLDSSelected) ? scr->white : scr->gray;
719 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
720 len = strlen(dirfile) + strlen(text) + 4;
721 file = wmalloc(len);
722 snprintf(file, len, "%s/%s", dirfile, text);
723 wfree(dirfile);
725 color.red = WMRedComponentOfColor(back) >> 8;
726 color.green = WMGreenComponentOfColor(back) >> 8;
727 color.blue = WMBlueComponentOfColor(back) >> 8;
728 color.alpha = WMGetColorAlpha(back) >> 8;
730 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
731 wfree(file);
733 if (!pixmap) {
734 /*WMRemoveListItem(lPtr, index); */
735 return;
738 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
740 XSetClipMask(dpy, gc, None);
741 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54); */
742 XDrawLine(dpy, d, WMColorGC(scr->white), x, y + height - 1, x + width, y + height - 1);
744 size = WMGetPixmapSize(pixmap);
746 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
747 XSetClipOrigin(dpy, copygc, x + (width - size.width) / 2, y + 2);
748 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
749 size.width > 100 ? 100 : size.width, size.height > 64 ? 64 : size.height,
750 x + (width - size.width) / 2, y + 2);
753 int i, j;
754 int fheight = WMFontHeight(panel->normalfont);
755 int tlen = strlen(text);
756 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
757 int ofx, ofy;
759 ofx = x + (width - twidth) / 2;
760 ofy = y + 64 - fheight;
762 for (i = -1; i < 2; i++)
763 for (j = -1; j < 2; j++)
764 WMDrawString(wmscr, d, scr->white, panel->normalfont,
765 ofx + i, ofy + j, text, tlen);
767 WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy, text, tlen);
770 WMReleasePixmap(pixmap);
771 /* I hope it is better to do not use cache / on my box it is fast nuff */
772 XFlush(dpy);
775 static void buttonCallback(void *self, void *clientData)
777 WMButton *bPtr = (WMButton *) self;
778 IconPanel *panel = (IconPanel *) clientData;
780 if (bPtr == panel->okButton) {
781 panel->done = True;
782 panel->result = True;
783 } else if (bPtr == panel->cancelButton) {
784 panel->done = True;
785 panel->result = False;
786 } else if (bPtr == panel->previewButton) {
787 /**** Previewer ****/
788 WMSetButtonEnabled(bPtr, False);
789 WMSetListUserDrawItemHeight(panel->iconList, 68);
790 WMSetListUserDrawProc(panel->iconList, drawIconProc);
791 WMRedisplayWidget(panel->iconList);
792 /* for draw proc to access screen/gc */
793 /*** end preview ***/
795 #if 0
796 else if (bPtr == panel->chooseButton) {
797 WMOpenPanel *op;
799 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
801 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
802 char *path;
803 path = WMGetFilePanelFile(op);
804 WMSetTextFieldText(panel->fileField, path);
805 setViewedImage(panel, path);
806 wfree(path);
808 WMDestroyFilePanel(op);
810 #endif
813 static void keyPressHandler(XEvent * event, void *data)
815 IconPanel *panel = (IconPanel *) data;
816 char buffer[32];
817 int count;
818 KeySym ksym;
819 int iidx;
820 int didx;
821 int item = 0;
822 WMList *list = NULL;
824 if (event->type == KeyRelease)
825 return;
827 buffer[0] = 0;
828 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
830 iidx = WMGetListSelectedItemRow(panel->iconList);
831 didx = WMGetListSelectedItemRow(panel->dirList);
833 switch (ksym) {
834 case XK_Up:
835 if (iidx > 0)
836 item = iidx - 1;
837 else
838 item = iidx;
839 list = panel->iconList;
840 break;
841 case XK_Down:
842 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
843 item = iidx + 1;
844 else
845 item = iidx;
846 list = panel->iconList;
847 break;
848 case XK_Home:
849 item = 0;
850 list = panel->iconList;
851 break;
852 case XK_End:
853 item = WMGetListNumberOfRows(panel->iconList) - 1;
854 list = panel->iconList;
855 break;
856 case XK_Next:
857 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
858 item = didx + 1;
859 else
860 item = didx;
861 list = panel->dirList;
862 break;
863 case XK_Prior:
864 if (didx > 0)
865 item = didx - 1;
866 else
867 item = 0;
868 list = panel->dirList;
869 break;
870 case XK_Return:
871 WMPerformButtonClick(panel->okButton);
872 break;
873 case XK_Escape:
874 WMPerformButtonClick(panel->cancelButton);
875 break;
878 if (list) {
879 WMSelectListItem(list, item);
880 WMSetListPosition(list, item - 5);
881 listCallback(list, panel);
885 Bool wIconChooserDialog(WScreen * scr, char **file, char *instance, char *class)
887 WWindow *wwin;
888 Window parent;
889 IconPanel *panel;
890 WMColor *color;
891 WMFont *boldFont;
892 Bool result;
894 panel = wmalloc(sizeof(IconPanel));
895 memset(panel, 0, sizeof(IconPanel));
897 panel->scr = scr;
899 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
900 WMResizeWidget(panel->win, 450, 280);
902 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask | KeyReleaseMask, keyPressHandler, panel);
904 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
905 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
907 panel->dirLabel = WMCreateLabel(panel->win);
908 WMResizeWidget(panel->dirLabel, 200, 20);
909 WMMoveWidget(panel->dirLabel, 10, 7);
910 WMSetLabelText(panel->dirLabel, _("Directories"));
911 WMSetLabelFont(panel->dirLabel, boldFont);
912 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
914 WMSetLabelRelief(panel->dirLabel, WRSunken);
916 panel->iconLabel = WMCreateLabel(panel->win);
917 WMResizeWidget(panel->iconLabel, 140, 20);
918 WMMoveWidget(panel->iconLabel, 215, 7);
919 WMSetLabelText(panel->iconLabel, _("Icons"));
920 WMSetLabelFont(panel->iconLabel, boldFont);
921 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
923 WMReleaseFont(boldFont);
925 color = WMWhiteColor(scr->wmscreen);
926 WMSetLabelTextColor(panel->dirLabel, color);
927 WMSetLabelTextColor(panel->iconLabel, color);
928 WMReleaseColor(color);
930 color = WMDarkGrayColor(scr->wmscreen);
931 WMSetWidgetBackgroundColor(panel->iconLabel, color);
932 WMSetWidgetBackgroundColor(panel->dirLabel, color);
933 WMReleaseColor(color);
935 WMSetLabelRelief(panel->iconLabel, WRSunken);
937 panel->dirList = WMCreateList(panel->win);
938 WMResizeWidget(panel->dirList, 200, 170);
939 WMMoveWidget(panel->dirList, 10, 30);
940 WMSetListAction(panel->dirList, listCallback, panel);
942 panel->iconList = WMCreateList(panel->win);
943 WMResizeWidget(panel->iconList, 140, 170);
944 WMMoveWidget(panel->iconList, 215, 30);
945 WMSetListAction(panel->iconList, listCallback, panel);
947 WMHangData(panel->iconList, panel);
949 panel->previewButton = WMCreateCommandButton(panel->win);
950 WMResizeWidget(panel->previewButton, 75, 26);
951 WMMoveWidget(panel->previewButton, 365, 130);
952 WMSetButtonText(panel->previewButton, _("Preview"));
953 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
955 panel->iconView = WMCreateLabel(panel->win);
956 WMResizeWidget(panel->iconView, 75, 75);
957 WMMoveWidget(panel->iconView, 365, 40);
958 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
959 WMSetLabelRelief(panel->iconView, WRSunken);
960 WMSetLabelTextAlignment(panel->iconView, WACenter);
962 panel->fileLabel = WMCreateLabel(panel->win);
963 WMResizeWidget(panel->fileLabel, 80, 20);
964 WMMoveWidget(panel->fileLabel, 10, 210);
965 WMSetLabelText(panel->fileLabel, _("File Name:"));
967 panel->fileField = WMCreateTextField(panel->win);
968 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
969 WMResizeWidget(panel->fileField, 345, 20);
970 WMMoveWidget(panel->fileField, 95, 210);
971 WMSetTextFieldEditable(panel->fileField, False);
973 panel->okButton = WMCreateCommandButton(panel->win);
974 WMResizeWidget(panel->okButton, 80, 26);
975 WMMoveWidget(panel->okButton, 360, 240);
976 WMSetButtonText(panel->okButton, _("OK"));
977 WMSetButtonEnabled(panel->okButton, False);
978 WMSetButtonAction(panel->okButton, buttonCallback, panel);
980 panel->cancelButton = WMCreateCommandButton(panel->win);
981 WMResizeWidget(panel->cancelButton, 80, 26);
982 WMMoveWidget(panel->cancelButton, 270, 240);
983 WMSetButtonText(panel->cancelButton, _("Cancel"));
984 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
985 #if 0
986 panel->chooseButton = WMCreateCommandButton(panel->win);
987 WMResizeWidget(panel->chooseButton, 110, 26);
988 WMMoveWidget(panel->chooseButton, 150, 240);
989 WMSetButtonText(panel->chooseButton, _("Choose File"));
990 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
991 #endif
992 WMRealizeWidget(panel->win);
993 WMMapSubwidgets(panel->win);
995 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
997 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1000 char *tmp;
1001 int len = (instance ? strlen(instance) : 0)
1002 + (class ? strlen(class) : 0) + 32;
1003 WMPoint center;
1005 tmp = wmalloc(len);
1007 if (tmp && (instance || class))
1008 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
1009 else
1010 strcpy(tmp, _("Icon Chooser"));
1012 center = getCenter(scr, 450, 280);
1014 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x, center.y, 450, 280);
1015 wfree(tmp);
1018 /* put icon paths in the list */
1019 listIconPaths(panel->dirList);
1021 WMMapWidget(panel->win);
1023 wWindowMap(wwin);
1025 while (!panel->done) {
1026 XEvent event;
1028 WMNextEvent(dpy, &event);
1029 WMHandleEvent(&event);
1032 if (panel->result) {
1033 char *defaultPath, *wantedPath;
1035 /* check if the file the user selected is not the one that
1036 * would be loaded by default with the current search path */
1037 *file = WMGetListSelectedItem(panel->iconList)->text;
1038 if (**file == 0) {
1039 wfree(*file);
1040 *file = NULL;
1041 } else {
1042 defaultPath = FindImage(wPreferences.icon_path, *file);
1043 wantedPath = WMGetTextFieldText(panel->fileField);
1044 /* if the file is not the default, use full path */
1045 if (strcmp(wantedPath, defaultPath) != 0) {
1046 *file = wantedPath;
1047 } else {
1048 *file = wstrdup(*file);
1049 wfree(wantedPath);
1051 wfree(defaultPath);
1053 } else {
1054 *file = NULL;
1057 result = panel->result;
1059 WMReleaseFont(panel->normalfont);
1061 WMUnmapWidget(panel->win);
1063 WMDestroyWidget(panel->win);
1065 wUnmanageWindow(wwin, False, False);
1067 wfree(panel);
1069 XDestroyWindow(dpy, parent);
1071 return result;
1075 ***********************************************************************
1076 * Info Panel
1077 ***********************************************************************
1080 typedef struct {
1081 WScreen *scr;
1082 WWindow *wwin;
1083 WMWindow *win;
1084 WMLabel *logoL;
1085 WMLabel *name1L;
1086 WMFrame *lineF;
1087 WMLabel *name2L;
1088 WMLabel *versionL;
1089 WMLabel *infoL;
1090 WMLabel *copyrL;
1091 } InfoPanel;
1093 #define COPYRIGHT_TEXT \
1094 "Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
1095 "Copyright \xc2\xa9 1998-2006 Dan Pascu"
1097 static InfoPanel *thePanel = NULL;
1099 static void destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
1101 WMUnmapWidget(thePanel);
1102 wUnmanageWindow(thePanel->wwin, False, False);
1103 WMDestroyWidget(thePanel->win);
1104 wfree(thePanel);
1105 thePanel = NULL;
1108 void wShowInfoPanel(WScreen * scr)
1110 InfoPanel *panel;
1111 WMPixmap *logo;
1112 WMSize size;
1113 WMFont *font;
1114 char *strbuf = NULL;
1115 char buffer[256];
1116 char *name;
1117 Window parent;
1118 WWindow *wwin;
1119 char **strl;
1120 int i, width = 50, sepHeight;
1121 char *visuals[] = {
1122 "StaticGray",
1123 "GrayScale",
1124 "StaticColor",
1125 "PseudoColor",
1126 "TrueColor",
1127 "DirectColor"
1130 if (thePanel) {
1131 if (thePanel->scr == scr) {
1132 wRaiseFrame(thePanel->wwin->frame->core);
1133 wSetFocusTo(scr, thePanel->wwin);
1135 return;
1138 panel = wmalloc(sizeof(InfoPanel));
1139 memset(panel, 0, sizeof(InfoPanel));
1141 panel->scr = scr;
1143 panel->win = WMCreateWindow(scr->wmscreen, "info");
1144 WMResizeWidget(panel->win, 390, 230);
1146 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
1147 if (!logo) {
1148 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1150 if (logo) {
1151 size = WMGetPixmapSize(logo);
1152 panel->logoL = WMCreateLabel(panel->win);
1153 WMResizeWidget(panel->logoL, 64, 64);
1154 WMMoveWidget(panel->logoL, 30, 20);
1155 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1156 WMSetLabelImage(panel->logoL, logo);
1157 WMReleasePixmap(logo);
1160 sepHeight = 3;
1161 panel->name1L = WMCreateLabel(panel->win);
1162 WMResizeWidget(panel->name1L, 240, 30 + 2);
1163 WMMoveWidget(panel->name1L, 100, 30 - 2 - sepHeight);
1165 name = "Lucida Sans,Comic Sans MS,URW Gothic L,Trebuchet MS" ":italic:pixelsize=28:antialias=true";
1166 font = WMCreateFont(scr->wmscreen, name);
1167 strbuf = "Window Maker";
1168 if (font) {
1169 width = WMWidthOfString(font, strbuf, strlen(strbuf));
1170 WMSetLabelFont(panel->name1L, font);
1171 WMReleaseFont(font);
1173 WMSetLabelTextAlignment(panel->name1L, WACenter);
1174 WMSetLabelText(panel->name1L, strbuf);
1176 panel->lineF = WMCreateFrame(panel->win);
1177 WMResizeWidget(panel->lineF, width, sepHeight);
1178 WMMoveWidget(panel->lineF, 100 + (240 - width) / 2, 60 - sepHeight);
1179 WMSetFrameRelief(panel->lineF, WRSimple);
1180 WMSetWidgetBackgroundColor(panel->lineF, scr->black);
1182 panel->name2L = WMCreateLabel(panel->win);
1183 WMResizeWidget(panel->name2L, 240, 24);
1184 WMMoveWidget(panel->name2L, 100, 60);
1185 name = "URW Gothic L,Nimbus Sans L:pixelsize=16:antialias=true";
1186 font = WMCreateFont(scr->wmscreen, name);
1187 if (font) {
1188 WMSetLabelFont(panel->name2L, font);
1189 WMReleaseFont(font);
1190 font = NULL;
1192 WMSetLabelTextAlignment(panel->name2L, WACenter);
1193 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1195 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1196 panel->versionL = WMCreateLabel(panel->win);
1197 WMResizeWidget(panel->versionL, 310, 16);
1198 WMMoveWidget(panel->versionL, 30, 95);
1199 WMSetLabelTextAlignment(panel->versionL, WARight);
1200 WMSetLabelText(panel->versionL, buffer);
1201 WMSetLabelWraps(panel->versionL, False);
1203 panel->copyrL = WMCreateLabel(panel->win);
1204 WMResizeWidget(panel->copyrL, 360, 40);
1205 WMMoveWidget(panel->copyrL, 15, 185);
1206 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1207 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1208 font = WMSystemFontOfSize(scr->wmscreen, 11);
1209 if (font) {
1210 WMSetLabelFont(panel->copyrL, font);
1211 WMReleaseFont(font);
1212 font = NULL;
1215 strbuf = NULL;
1216 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1217 (unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
1219 strbuf = wstrappend(strbuf, buffer);
1221 switch (scr->w_depth) {
1222 case 15:
1223 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1224 break;
1225 case 16:
1226 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1227 break;
1228 case 24:
1229 case 32:
1230 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1231 break;
1232 default:
1233 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1 << scr->w_depth);
1234 strbuf = wstrappend(strbuf, buffer);
1235 break;
1238 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1240 struct mallinfo ma = mallinfo();
1241 snprintf(buffer, sizeof(buffer),
1242 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1243 (ma.arena + ma.hblkhd) / 1024, (ma.uordblks + ma.hblkhd) / 1024);
1245 strbuf = wstrappend(strbuf, buffer);
1247 #endif
1249 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1250 strl = RSupportedFileFormats();
1251 for (i = 0; strl[i] != NULL; i++) {
1252 strbuf = wstrappend(strbuf, strl[i]);
1253 strbuf = wstrappend(strbuf, " ");
1256 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1258 char *list[9];
1259 char buf[80];
1260 int j = 0;
1262 list[j++] = "WMSPEC";
1263 #ifdef MWM_HINTS
1264 list[j++] = "MWM";
1265 #endif
1267 buf[0] = 0;
1268 for (i = 0; i < j; i++) {
1269 if (i > 0) {
1270 if (i == j - 1)
1271 strcat(buf, _(" and "));
1272 else
1273 strcat(buf, ", ");
1275 strcat(buf, list[i]);
1277 strbuf = wstrappend(strbuf, buf);
1280 #ifdef XINERAMA
1281 strbuf = wstrappend(strbuf, _("\n"));
1282 #ifdef SOLARIS_XINERAMA
1283 strbuf = wstrappend(strbuf, _("Solaris "));
1284 #endif
1285 strbuf = wstrappend(strbuf, _("Xinerama: "));
1287 char tmp[128];
1288 snprintf(tmp, sizeof(tmp) - 1, "%d heads found.", scr->xine_info.count);
1289 strbuf = wstrappend(strbuf, tmp);
1291 #endif
1293 panel->infoL = WMCreateLabel(panel->win);
1294 WMResizeWidget(panel->infoL, 350, 75);
1295 WMMoveWidget(panel->infoL, 15, 115);
1296 WMSetLabelText(panel->infoL, strbuf);
1297 font = WMSystemFontOfSize(scr->wmscreen, 11);
1298 if (font) {
1299 WMSetLabelFont(panel->infoL, font);
1300 WMReleaseFont(font);
1301 font = NULL;
1303 wfree(strbuf);
1305 WMRealizeWidget(panel->win);
1306 WMMapSubwidgets(panel->win);
1308 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1310 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1312 WMMapWidget(panel->win);
1315 WMPoint center = getCenter(scr, 382, 230);
1317 wwin = wManageInternalWindow(scr, parent, None, _("Info"), center.x, center.y, 382, 230);
1320 WSETUFLAG(wwin, no_closable, 0);
1321 WSETUFLAG(wwin, no_close_button, 0);
1322 #ifdef XKB_BUTTON_HINT
1323 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1324 #endif
1325 wWindowUpdateButtonImages(wwin);
1326 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1327 wwin->frame->on_click_right = destroyInfoPanel;
1329 wWindowMap(wwin);
1331 panel->wwin = wwin;
1332 thePanel = panel;
1336 ***********************************************************************
1337 * Legal Panel
1338 ***********************************************************************
1341 typedef struct {
1342 WScreen *scr;
1344 WWindow *wwin;
1346 WMWindow *win;
1348 WMLabel *licenseL;
1349 } LegalPanel;
1351 static LegalPanel *legalPanel = NULL;
1353 static void destroyLegalPanel(WCoreWindow * foo, void *data, XEvent * event)
1355 WMUnmapWidget(legalPanel->win);
1357 WMDestroyWidget(legalPanel->win);
1359 wUnmanageWindow(legalPanel->wwin, False, False);
1361 wfree(legalPanel);
1363 legalPanel = NULL;
1366 void wShowLegalPanel(WScreen * scr)
1368 LegalPanel *panel;
1369 Window parent;
1370 WWindow *wwin;
1372 if (legalPanel) {
1373 if (legalPanel->scr == scr) {
1374 wRaiseFrame(legalPanel->wwin->frame->core);
1375 wSetFocusTo(scr, legalPanel->wwin);
1377 return;
1380 panel = wmalloc(sizeof(LegalPanel));
1382 panel->scr = scr;
1384 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1385 WMResizeWidget(panel->win, 420, 250);
1387 panel->licenseL = WMCreateLabel(panel->win);
1388 WMSetLabelWraps(panel->licenseL, True);
1389 WMResizeWidget(panel->licenseL, 400, 230);
1390 WMMoveWidget(panel->licenseL, 10, 10);
1391 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1392 WMSetLabelText(panel->licenseL,
1393 _(" Window Maker is free software; you can redistribute it and/or\n"
1394 "modify it under the terms of the GNU General Public License as\n"
1395 "published by the Free Software Foundation; either version 2 of the\n"
1396 "License, or (at your option) any later version.\n\n"
1397 " Window Maker is distributed in the hope that it will be useful,\n"
1398 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1399 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1400 "See the GNU General Public License for more details.\n\n"
1401 " You should have received a copy of the GNU General Public\n"
1402 "License along with this program; if not, write to the Free Software\n"
1403 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n" "02111-1307, USA."));
1404 WMSetLabelRelief(panel->licenseL, WRGroove);
1406 WMRealizeWidget(panel->win);
1407 WMMapSubwidgets(panel->win);
1409 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1411 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1414 WMPoint center = getCenter(scr, 420, 250);
1416 wwin = wManageInternalWindow(scr, parent, None, _("Legal"), center.x, center.y, 420, 250);
1419 WSETUFLAG(wwin, no_closable, 0);
1420 WSETUFLAG(wwin, no_close_button, 0);
1421 wWindowUpdateButtonImages(wwin);
1422 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1423 #ifdef XKB_BUTTON_HINT
1424 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1425 #endif
1426 wwin->frame->on_click_right = destroyLegalPanel;
1428 panel->wwin = wwin;
1430 WMMapWidget(panel->win);
1432 wWindowMap(wwin);
1434 legalPanel = panel;
1438 ***********************************************************************
1439 * Crashing Dialog Panel
1440 ***********************************************************************
1443 extern WDDomain *WDWindowAttributes;
1445 typedef struct _CrashPanel {
1446 WMWindow *win; /* main window */
1448 WMLabel *iconL; /* application icon */
1449 WMLabel *nameL; /* title of panel */
1451 WMFrame *sepF; /* separator frame */
1453 WMLabel *noteL; /* Title of note */
1454 WMLabel *note2L; /* body of note with what happened */
1456 WMFrame *whatF; /* "what to do next" frame */
1457 WMPopUpButton *whatP; /* action selection popup button */
1459 WMButton *okB; /* ok button */
1461 Bool done; /* if finished with this dialog */
1462 int action; /* what to do after */
1464 KeyCode retKey;
1466 } CrashPanel;
1468 static void handleKeyPress(XEvent * event, void *clientData)
1470 CrashPanel *panel = (CrashPanel *) clientData;
1472 if (event->xkey.keycode == panel->retKey) {
1473 WMPerformButtonClick(panel->okB);
1477 static void okButtonCallback(void *self, void *clientData)
1479 CrashPanel *panel = (CrashPanel *) clientData;
1481 panel->done = True;
1484 static void setCrashAction(void *self, void *clientData)
1486 WMPopUpButton *pop = (WMPopUpButton *) self;
1487 CrashPanel *panel = (CrashPanel *) clientData;
1489 panel->action = WMGetPopUpButtonSelectedItem(pop);
1492 /* Make this read the logo from a compiled in pixmap -Dan */
1493 static WMPixmap *getWindowMakerIconImage(WMScreen * scr)
1495 WMPropList *dict, *key, *option, *value = NULL;
1496 WMPixmap *pix = NULL;
1497 char *path;
1499 if (!WDWindowAttributes || !WDWindowAttributes->dictionary)
1500 return NULL;
1502 WMPLSetCaseSensitive(True);
1504 key = WMCreatePLString("Logo.WMPanel");
1505 option = WMCreatePLString("Icon");
1507 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1509 if (dict) {
1510 value = WMGetFromPLDictionary(dict, option);
1513 WMReleasePropList(key);
1514 WMReleasePropList(option);
1516 WMPLSetCaseSensitive(False);
1518 if (value && WMIsPLString(value)) {
1519 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1521 if (path) {
1522 RColor gray;
1524 gray.red = 0xae;
1525 gray.green = 0xaa;
1526 gray.blue = 0xae;
1527 gray.alpha = 0;
1529 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1530 wfree(path);
1534 return pix;
1537 #define PWIDTH 295
1538 #define PHEIGHT 345
1540 int wShowCrashingDialogPanel(int whatSig)
1542 CrashPanel *panel;
1543 WMScreen *scr;
1544 WMFont *font;
1545 WMPixmap *logo;
1546 int screen_no, scr_width, scr_height;
1547 int action;
1548 char buf[256];
1550 panel = wmalloc(sizeof(CrashPanel));
1551 memset(panel, 0, sizeof(CrashPanel));
1553 screen_no = DefaultScreen(dpy);
1554 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1555 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1557 scr = WMCreateScreen(dpy, screen_no);
1558 if (!scr) {
1559 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1560 return WMAbort;
1563 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1565 panel->win = WMCreateWindow(scr, "crashingDialog");
1566 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1567 WMMoveWidget(panel->win, (scr_width - PWIDTH) / 2, (scr_height - PHEIGHT) / 2);
1569 logo = getWindowMakerIconImage(scr);
1570 if (logo) {
1571 panel->iconL = WMCreateLabel(panel->win);
1572 WMResizeWidget(panel->iconL, 64, 64);
1573 WMMoveWidget(panel->iconL, 10, 10);
1574 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1575 WMSetLabelImage(panel->iconL, logo);
1578 panel->nameL = WMCreateLabel(panel->win);
1579 WMResizeWidget(panel->nameL, 200, 30);
1580 WMMoveWidget(panel->nameL, 80, 25);
1581 WMSetLabelTextAlignment(panel->nameL, WALeft);
1582 font = WMBoldSystemFontOfSize(scr, 24);
1583 WMSetLabelFont(panel->nameL, font);
1584 WMReleaseFont(font);
1585 WMSetLabelText(panel->nameL, _("Fatal error"));
1587 panel->sepF = WMCreateFrame(panel->win);
1588 WMResizeWidget(panel->sepF, PWIDTH + 4, 2);
1589 WMMoveWidget(panel->sepF, -2, 80);
1591 panel->noteL = WMCreateLabel(panel->win);
1592 WMResizeWidget(panel->noteL, PWIDTH - 20, 40);
1593 WMMoveWidget(panel->noteL, 10, 90);
1594 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1595 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1596 WMSetLabelText(panel->noteL, buf);
1598 panel->note2L = WMCreateLabel(panel->win);
1599 WMResizeWidget(panel->note2L, PWIDTH - 20, 100);
1600 WMMoveWidget(panel->note2L, 10, 130);
1601 WMSetLabelTextAlignment(panel->note2L, WALeft);
1602 WMSetLabelText(panel->note2L,
1603 _(" This fatal error occured probably due to a bug."
1604 " Please fill the included BUGFORM and " "report it to bugs@windowmaker.info."));
1605 WMSetLabelWraps(panel->note2L, True);
1607 panel->whatF = WMCreateFrame(panel->win);
1608 WMResizeWidget(panel->whatF, PWIDTH - 20, 50);
1609 WMMoveWidget(panel->whatF, 10, 240);
1610 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1612 panel->whatP = WMCreatePopUpButton(panel->whatF);
1613 WMResizeWidget(panel->whatP, PWIDTH - 20 - 70, 20);
1614 WMMoveWidget(panel->whatP, 35, 20);
1615 WMSetPopUpButtonPullsDown(panel->whatP, False);
1616 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1617 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1618 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1619 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1620 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1621 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1622 panel->action = WMRestart;
1624 WMMapSubwidgets(panel->whatF);
1626 panel->okB = WMCreateCommandButton(panel->win);
1627 WMResizeWidget(panel->okB, 80, 26);
1628 WMMoveWidget(panel->okB, 205, 309);
1629 WMSetButtonText(panel->okB, _("OK"));
1630 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1631 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1632 WMSetButtonImagePosition(panel->okB, WIPRight);
1633 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1635 panel->done = 0;
1637 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask, handleKeyPress, panel);
1639 WMRealizeWidget(panel->win);
1640 WMMapSubwidgets(panel->win);
1642 WMMapWidget(panel->win);
1644 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1646 while (!panel->done) {
1647 XEvent event;
1649 WMNextEvent(dpy, &event);
1650 WMHandleEvent(&event);
1653 action = panel->action;
1655 WMUnmapWidget(panel->win);
1656 WMDestroyWidget(panel->win);
1657 wfree(panel);
1659 return action;
1662 /*****************************************************************************
1663 * About GNUstep Panel
1664 *****************************************************************************/
1666 static void
1667 drawGNUstepLogo(Display * dpy, Drawable d, int width, int height,
1668 unsigned long blackPixel, unsigned long whitePixel)
1670 GC gc;
1671 XGCValues gcv;
1672 XRectangle rects[3];
1674 gcv.foreground = blackPixel;
1675 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1677 XFillArc(dpy, d, gc, width / 45, height / 45,
1678 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
1680 rects[0].x = 0;
1681 rects[0].y = 37 * height / 45;
1682 rects[0].width = width / 3;
1683 rects[0].height = height - rects[0].y;
1685 rects[1].x = rects[0].width;
1686 rects[1].y = height / 2;
1687 rects[1].width = width - 2 * width / 3;
1688 rects[1].height = height - rects[1].y;
1690 rects[2].x = 2 * width / 3;
1691 rects[2].y = height - 37 * height / 45;
1692 rects[2].width = width / 3;
1693 rects[2].height = height - rects[2].y;
1695 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1696 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1698 XSetForeground(dpy, gc, whitePixel);
1699 XFillArc(dpy, d, gc, width / 45, height / 45,
1700 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
1702 XFreeGC(dpy, gc);
1705 typedef struct {
1706 WScreen *scr;
1708 WWindow *wwin;
1710 WMWindow *win;
1712 WMLabel *gstepL;
1713 WMLabel *textL;
1714 } GNUstepPanel;
1716 static GNUstepPanel *gnustepPanel = NULL;
1718 static void destroyGNUstepPanel(WCoreWindow * foo, void *data, XEvent * event)
1720 WMUnmapWidget(gnustepPanel->win);
1722 WMDestroyWidget(gnustepPanel->win);
1724 wUnmanageWindow(gnustepPanel->wwin, False, False);
1726 wfree(gnustepPanel);
1728 gnustepPanel = NULL;
1731 void wShowGNUstepPanel(WScreen * scr)
1733 GNUstepPanel *panel;
1734 Window parent;
1735 WWindow *wwin;
1736 WMPixmap *pixmap;
1737 WMColor *color;
1739 if (gnustepPanel) {
1740 if (gnustepPanel->scr == scr) {
1741 wRaiseFrame(gnustepPanel->wwin->frame->core);
1742 wSetFocusTo(scr, gnustepPanel->wwin);
1744 return;
1747 panel = wmalloc(sizeof(GNUstepPanel));
1749 panel->scr = scr;
1751 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1752 WMResizeWidget(panel->win, 325, 205);
1754 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130, WMScreenDepth(scr->wmscreen), True);
1756 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1758 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130, WMColorPixel(color), scr->white_pixel);
1760 WMReleaseColor(color);
1762 XSetForeground(dpy, scr->mono_gc, 0);
1763 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0, 130, 130);
1764 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1766 panel->gstepL = WMCreateLabel(panel->win);
1767 WMResizeWidget(panel->gstepL, 285, 64);
1768 WMMoveWidget(panel->gstepL, 20, 0);
1769 WMSetLabelTextAlignment(panel->gstepL, WARight);
1770 WMSetLabelText(panel->gstepL, "GNUstep");
1772 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1774 WMSetLabelFont(panel->gstepL, font);
1775 WMReleaseFont(font);
1778 panel->textL = WMCreateLabel(panel->win);
1779 WMResizeWidget(panel->textL, 305, 140);
1780 WMMoveWidget(panel->textL, 10, 50);
1781 WMSetLabelTextAlignment(panel->textL, WARight);
1782 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1783 WMSetLabelText(panel->textL,
1784 _("Window Maker is part of the GNUstep project.\n"
1785 "The GNUstep project aims to create a free\n"
1786 "implementation of the OpenStep(tm) specification\n"
1787 "which is a object-oriented framework for\n"
1788 "creating advanced graphical, multi-platform\n"
1789 "applications. Additionally, a development and\n"
1790 "user desktop enviroment will be created on top\n"
1791 "of the framework. For more information about\n"
1792 "GNUstep, please visit: www.gnustep.org"));
1793 WMSetLabelImage(panel->textL, pixmap);
1795 WMReleasePixmap(pixmap);
1797 WMRealizeWidget(panel->win);
1798 WMMapSubwidgets(panel->win);
1800 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1802 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1805 WMPoint center = getCenter(scr, 325, 200);
1807 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"), center.x, center.y, 325, 200);
1810 WSETUFLAG(wwin, no_closable, 0);
1811 WSETUFLAG(wwin, no_close_button, 0);
1812 wWindowUpdateButtonImages(wwin);
1813 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1814 #ifdef XKB_BUTTON_HINT
1815 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1816 #endif
1817 wwin->frame->on_click_right = destroyGNUstepPanel;
1819 panel->wwin = wwin;
1821 WMMapWidget(panel->win);
1823 wWindowMap(wwin);
1825 gnustepPanel = panel;