Improve dockapp recognition
[wmaker-crm.git] / src / dialog.c
bloba08fc6b9ee811d84e2104ff65c756c176fa44543
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 static 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 strmatch(const void *str1, const void *str2)
186 return !strcmp((const char *)str1, (const char *)str2);
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, strmatch,
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 pstrcmp(const char **str1, const char **str2)
233 return strcmp(*str1, *str2);
236 static void
237 ScanFiles(const char *dir, const char *prefix, unsigned acceptmask, unsigned declinemask, WMArray * result)
239 int prefixlen;
240 DIR *d;
241 struct dirent *de;
242 struct stat sb;
243 char *fullfilename, *suffix;
245 prefixlen = strlen(prefix);
246 if ((d = opendir(dir)) != NULL) {
247 while ((de = readdir(d)) != NULL) {
248 if (strlen(de->d_name) > prefixlen &&
249 !strncmp(prefix, de->d_name, prefixlen) &&
250 strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..")) {
251 fullfilename = wstrconcat((char *)dir, "/");
252 fullfilename = wstrappend(fullfilename, de->d_name);
254 if (stat(fullfilename, &sb) == 0 &&
255 (sb.st_mode & acceptmask) &&
256 !(sb.st_mode & declinemask) &&
257 WMFindInArray(result, (WMMatchDataProc *) strmatch,
258 de->d_name + prefixlen) == WANotFound) {
259 suffix = wstrdup(de->d_name + prefixlen);
260 if (sb.st_mode & S_IFDIR)
261 wstrappend(suffix,"/");
262 WMAddToArray(result, suffix);
264 wfree(fullfilename);
267 closedir(d);
271 static WMArray *GenerateVariants(const char *complete)
273 Bool firstWord = True;
274 WMArray *variants = NULL;
275 char *pos = NULL, *path = NULL, *tmp = NULL, *dir = NULL, *prefix = NULL;
277 variants = WMCreateArrayWithDestructor(0, wfree);
279 while (*complete == ' ')
280 ++complete;
282 if ((pos = strrchr(complete, ' ')) != NULL) {
283 complete = pos + 1;
284 firstWord = False;
287 if ((pos = strrchr(complete, '/')) != NULL) {
288 tmp = wstrndup((char *)complete, pos - complete + 1);
289 if (*tmp == '~' && *(tmp + 1) == '/' && getenv("HOME")) {
290 dir = wstrdup(getenv("HOME"));
291 dir = wstrappend(dir, tmp + 1);
292 wfree(tmp);
293 } else {
294 dir = tmp;
296 prefix = wstrdup(pos + 1);
297 ScanFiles(dir, prefix, (unsigned)-1, 0, variants);
298 wfree(dir);
299 wfree(prefix);
300 } else if (*complete == '~') {
301 WMAddToArray(variants, wstrdup("/"));
302 } else if (firstWord) {
303 path = getenv("PATH");
304 while (path) {
305 pos = strchr(path, ':');
306 if (pos) {
307 tmp = wstrndup(path, pos - path);
308 path = pos + 1;
309 } else if (*path != '\0') {
310 tmp = wstrdup(path);
311 path = NULL;
312 } else
313 break;
314 ScanFiles(tmp, complete, S_IXOTH | S_IXGRP | S_IXUSR, S_IFDIR, variants);
315 wfree(tmp);
319 WMSortArray(variants, (WMCompareDataProc *) pstrcmp);
320 return variants;
323 static void handleHistoryKeyPress(XEvent * event, void *clientData)
325 char *text;
326 unsigned pos;
327 WMInputPanelWithHistory *p = (WMInputPanelWithHistory *) clientData;
328 KeySym ksym;
330 ksym = XLookupKeysym(&event->xkey, 0);
332 switch (ksym) {
333 case XK_Up:
334 if (p->histpos < WMGetArrayItemCount(p->history) - 1) {
335 if (p->histpos == 0)
336 wfree(WMReplaceInArray(p->history, 0, WMGetTextFieldText(p->panel->text)));
337 p->histpos++;
338 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
340 break;
341 case XK_Down:
342 if (p->histpos > 0) {
343 p->histpos--;
344 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
346 break;
347 case XK_Tab:
348 if (!p->variants) {
349 text = WMGetTextFieldText(p->panel->text);
350 pos = WMGetTextFieldCursorPosition(p->panel->text);
351 p->prefix = wstrndup(text, pos);
352 p->suffix = wstrdup(text + pos);
353 wfree(text);
354 p->variants = GenerateVariants(p->prefix);
355 p->varpos = 0;
356 if (!p->variants) {
357 wfree(p->prefix);
358 wfree(p->suffix);
359 p->prefix = NULL;
360 p->suffix = NULL;
363 if (p->variants && p->prefix && p->suffix) {
364 p->varpos++;
365 if (p->varpos > WMGetArrayItemCount(p->variants))
366 p->varpos = 0;
367 if (p->varpos > 0)
368 text = wstrconcat(p->prefix, WMGetFromArray(p->variants, p->varpos - 1));
369 else
370 text = wstrdup(p->prefix);
371 pos = strlen(text);
372 text = wstrappend(text, p->suffix);
373 WMSetTextFieldText(p->panel->text, text);
374 WMSetTextFieldCursorPosition(p->panel->text, pos);
375 wfree(text);
377 break;
379 if (ksym != XK_Tab) {
380 if (p->prefix) {
381 wfree(p->prefix);
382 p->prefix = NULL;
384 if (p->suffix) {
385 wfree(p->suffix);
386 p->suffix = NULL;
388 if (p->variants) {
389 WMFreeArray(p->variants);
390 p->variants = NULL;
395 int wAdvancedInputDialog(WScreen * scr, char *title, char *message, char *name, char **text)
397 WWindow *wwin;
398 Window parent;
399 char *result;
400 WMPoint center;
401 WMInputPanelWithHistory *p;
402 char *filename;
404 filename = HistoryFileName(name);
405 p = wmalloc(sizeof(WMInputPanelWithHistory));
406 p->panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
407 p->history = LoadHistory(filename, wPreferences.history_lines);
408 p->histpos = 0;
409 p->prefix = NULL;
410 p->suffix = NULL;
411 p->rest = NULL;
412 p->variants = NULL;
413 p->varpos = 0;
414 WMCreateEventHandler(WMWidgetView(p->panel->text), KeyPressMask, handleHistoryKeyPress, p);
416 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
417 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
419 XReparentWindow(dpy, WMWidgetXID(p->panel->win), parent, 0, 0);
421 center = getCenter(scr, 320, 160);
422 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
424 wwin->client_leader = WMWidgetXID(p->panel->win);
426 WMMapWidget(p->panel->win);
428 wWindowMap(wwin);
430 WMRunModalLoop(WMWidgetScreen(p->panel->win), WMWidgetView(p->panel->win));
432 if (p->panel->result == WAPRDefault) {
433 result = WMGetTextFieldText(p->panel->text);
434 wfree(WMReplaceInArray(p->history, 0, wstrdup(result)));
435 SaveHistory(p->history, filename);
436 } else
437 result = NULL;
439 wUnmanageWindow(wwin, False, False);
441 WMDestroyInputPanel(p->panel);
442 WMFreeArray(p->history);
443 wfree(p);
444 wfree(filename);
446 XDestroyWindow(dpy, parent);
448 if (result == NULL)
449 return False;
450 else {
451 if (*text)
452 wfree(*text);
453 *text = result;
455 return True;
459 int wInputDialog(WScreen * scr, char *title, char *message, char **text)
461 WWindow *wwin;
462 Window parent;
463 WMInputPanel *panel;
464 char *result;
465 WMPoint center;
467 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
469 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
470 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
472 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
474 center = getCenter(scr, 320, 160);
475 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
477 wwin->client_leader = WMWidgetXID(panel->win);
479 WMMapWidget(panel->win);
481 wWindowMap(wwin);
483 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
485 if (panel->result == WAPRDefault)
486 result = WMGetTextFieldText(panel->text);
487 else
488 result = NULL;
490 wUnmanageWindow(wwin, False, False);
492 WMDestroyInputPanel(panel);
494 XDestroyWindow(dpy, parent);
496 if (result == NULL)
497 return False;
498 else {
499 if (*text)
500 wfree(*text);
501 *text = result;
503 return True;
508 *****************************************************************
509 * Icon Selection Panel
510 *****************************************************************
513 typedef struct IconPanel {
515 WScreen *scr;
517 WMWindow *win;
519 WMLabel *dirLabel;
520 WMLabel *iconLabel;
522 WMList *dirList;
523 WMList *iconList;
524 WMFont *normalfont;
526 WMButton *previewButton;
528 WMLabel *iconView;
530 WMLabel *fileLabel;
531 WMTextField *fileField;
533 WMButton *okButton;
534 WMButton *cancelButton;
535 #if 0
536 WMButton *chooseButton;
537 #endif
538 short done;
539 short result;
540 short preview;
541 } IconPanel;
543 static void listPixmaps(WScreen * scr, WMList * lPtr, char *path)
545 struct dirent *dentry;
546 DIR *dir;
547 char pbuf[PATH_MAX + 16];
548 char *apath;
549 IconPanel *panel = WMGetHangedData(lPtr);
551 panel->preview = False;
553 apath = wexpandpath(path);
554 dir = opendir(apath);
556 if (!dir) {
557 char *msg;
558 char *tmp;
559 tmp = _("Could not open directory ");
560 msg = wmalloc(strlen(tmp) + strlen(path) + 6);
561 strcpy(msg, tmp);
562 strcat(msg, path);
564 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
565 wfree(msg);
566 wfree(apath);
567 return;
570 /* list contents in the column */
571 while ((dentry = readdir(dir))) {
572 struct stat statb;
574 if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") == 0)
575 continue;
577 strcpy(pbuf, apath);
578 strcat(pbuf, "/");
579 strcat(pbuf, dentry->d_name);
581 if (stat(pbuf, &statb) < 0)
582 continue;
584 if (statb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)
585 && statb.st_mode & (S_IFREG | S_IFLNK)) {
586 WMAddListItem(lPtr, dentry->d_name);
589 WMSortListItems(lPtr);
591 closedir(dir);
592 wfree(apath);
593 panel->preview = True;
596 static void setViewedImage(IconPanel * panel, char *file)
598 WMPixmap *pixmap;
599 RColor color;
601 color.red = 0xae;
602 color.green = 0xaa;
603 color.blue = 0xae;
604 color.alpha = 0;
605 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win), file, &color);
606 if (!pixmap) {
607 WMSetButtonEnabled(panel->okButton, False);
609 WMSetLabelText(panel->iconView, _("Could not load image file "));
611 WMSetLabelImage(panel->iconView, NULL);
612 } else {
613 WMSetButtonEnabled(panel->okButton, True);
615 WMSetLabelText(panel->iconView, NULL);
616 WMSetLabelImage(panel->iconView, pixmap);
617 WMReleasePixmap(pixmap);
621 static void listCallback(void *self, void *data)
623 WMList *lPtr = (WMList *) self;
624 IconPanel *panel = (IconPanel *) data;
625 char *path;
627 if (lPtr == panel->dirList) {
628 WMListItem *item = WMGetListSelectedItem(lPtr);
630 if (item == NULL)
631 return;
632 path = item->text;
634 WMSetTextFieldText(panel->fileField, path);
636 WMSetLabelImage(panel->iconView, NULL);
638 WMSetButtonEnabled(panel->okButton, False);
640 WMClearList(panel->iconList);
641 listPixmaps(panel->scr, panel->iconList, path);
642 } else {
643 char *tmp, *iconFile;
644 WMListItem *item = WMGetListSelectedItem(panel->dirList);
646 if (item == NULL)
647 return;
648 path = item->text;
649 tmp = wexpandpath(path);
651 item = WMGetListSelectedItem(panel->iconList);
652 if (item == NULL)
653 return;
654 iconFile = item->text;
656 path = wmalloc(strlen(tmp) + strlen(iconFile) + 4);
657 strcpy(path, tmp);
658 strcat(path, "/");
659 strcat(path, iconFile);
660 wfree(tmp);
661 WMSetTextFieldText(panel->fileField, path);
662 setViewedImage(panel, path);
663 wfree(path);
667 static void listIconPaths(WMList * lPtr)
669 char *paths;
670 char *path;
672 paths = wstrdup(wPreferences.icon_path);
674 path = strtok(paths, ":");
676 do {
677 char *tmp;
679 tmp = wexpandpath(path);
680 /* do not sort, because the order implies the order of
681 * directories searched */
682 if (access(tmp, X_OK) == 0)
683 WMAddListItem(lPtr, path);
684 wfree(tmp);
685 } while ((path = strtok(NULL, ":")) != NULL);
687 wfree(paths);
690 static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
692 IconPanel *panel = WMGetHangedData(lPtr);
693 WScreen *scr = panel->scr;
694 GC gc = scr->draw_gc;
695 GC copygc = scr->copy_gc;
696 char *file, *dirfile;
697 WMPixmap *pixmap;
698 WMColor *back;
699 WMSize size;
700 WMScreen *wmscr = WMWidgetScreen(panel->win);
701 RColor color;
702 int x, y, width, height, len;
704 if (!panel->preview)
705 return;
707 x = rect->pos.x;
708 y = rect->pos.y;
709 width = rect->size.width;
710 height = rect->size.height;
712 back = (state & WLDSSelected) ? scr->white : scr->gray;
714 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
715 len = strlen(dirfile) + strlen(text) + 4;
716 file = wmalloc(len);
717 snprintf(file, len, "%s/%s", dirfile, text);
718 wfree(dirfile);
720 color.red = WMRedComponentOfColor(back) >> 8;
721 color.green = WMGreenComponentOfColor(back) >> 8;
722 color.blue = WMBlueComponentOfColor(back) >> 8;
723 color.alpha = WMGetColorAlpha(back) >> 8;
725 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
726 wfree(file);
728 if (!pixmap) {
729 /*WMRemoveListItem(lPtr, index); */
730 return;
733 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
735 XSetClipMask(dpy, gc, None);
736 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54); */
737 XDrawLine(dpy, d, WMColorGC(scr->white), x, y + height - 1, x + width, y + height - 1);
739 size = WMGetPixmapSize(pixmap);
741 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
742 XSetClipOrigin(dpy, copygc, x + (width - size.width) / 2, y + 2);
743 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
744 size.width > 100 ? 100 : size.width, size.height > 64 ? 64 : size.height,
745 x + (width - size.width) / 2, y + 2);
748 int i, j;
749 int fheight = WMFontHeight(panel->normalfont);
750 int tlen = strlen(text);
751 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
752 int ofx, ofy;
754 ofx = x + (width - twidth) / 2;
755 ofy = y + 64 - fheight;
757 for (i = -1; i < 2; i++)
758 for (j = -1; j < 2; j++)
759 WMDrawString(wmscr, d, scr->white, panel->normalfont,
760 ofx + i, ofy + j, text, tlen);
762 WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy, text, tlen);
765 WMReleasePixmap(pixmap);
766 /* I hope it is better to do not use cache / on my box it is fast nuff */
767 XFlush(dpy);
770 static void buttonCallback(void *self, void *clientData)
772 WMButton *bPtr = (WMButton *) self;
773 IconPanel *panel = (IconPanel *) clientData;
775 if (bPtr == panel->okButton) {
776 panel->done = True;
777 panel->result = True;
778 } else if (bPtr == panel->cancelButton) {
779 panel->done = True;
780 panel->result = False;
781 } else if (bPtr == panel->previewButton) {
782 /**** Previewer ****/
783 WMSetButtonEnabled(bPtr, False);
784 WMSetListUserDrawItemHeight(panel->iconList, 68);
785 WMSetListUserDrawProc(panel->iconList, drawIconProc);
786 WMRedisplayWidget(panel->iconList);
787 /* for draw proc to access screen/gc */
788 /*** end preview ***/
790 #if 0
791 else if (bPtr == panel->chooseButton) {
792 WMOpenPanel *op;
794 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
796 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
797 char *path;
798 path = WMGetFilePanelFile(op);
799 WMSetTextFieldText(panel->fileField, path);
800 setViewedImage(panel, path);
801 wfree(path);
803 WMDestroyFilePanel(op);
805 #endif
808 static void keyPressHandler(XEvent * event, void *data)
810 IconPanel *panel = (IconPanel *) data;
811 char buffer[32];
812 int count;
813 KeySym ksym;
814 int iidx;
815 int didx;
816 int item = 0;
817 WMList *list = NULL;
819 if (event->type == KeyRelease)
820 return;
822 buffer[0] = 0;
823 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
825 iidx = WMGetListSelectedItemRow(panel->iconList);
826 didx = WMGetListSelectedItemRow(panel->dirList);
828 switch (ksym) {
829 case XK_Up:
830 if (iidx > 0)
831 item = iidx - 1;
832 else
833 item = iidx;
834 list = panel->iconList;
835 break;
836 case XK_Down:
837 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
838 item = iidx + 1;
839 else
840 item = iidx;
841 list = panel->iconList;
842 break;
843 case XK_Home:
844 item = 0;
845 list = panel->iconList;
846 break;
847 case XK_End:
848 item = WMGetListNumberOfRows(panel->iconList) - 1;
849 list = panel->iconList;
850 break;
851 case XK_Next:
852 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
853 item = didx + 1;
854 else
855 item = didx;
856 list = panel->dirList;
857 break;
858 case XK_Prior:
859 if (didx > 0)
860 item = didx - 1;
861 else
862 item = 0;
863 list = panel->dirList;
864 break;
865 case XK_Return:
866 WMPerformButtonClick(panel->okButton);
867 break;
868 case XK_Escape:
869 WMPerformButtonClick(panel->cancelButton);
870 break;
873 if (list) {
874 WMSelectListItem(list, item);
875 WMSetListPosition(list, item - 5);
876 listCallback(list, panel);
880 Bool wIconChooserDialog(WScreen * scr, char **file, char *instance, char *class)
882 WWindow *wwin;
883 Window parent;
884 IconPanel *panel;
885 WMColor *color;
886 WMFont *boldFont;
887 Bool result;
889 panel = wmalloc(sizeof(IconPanel));
890 memset(panel, 0, sizeof(IconPanel));
892 panel->scr = scr;
894 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
895 WMResizeWidget(panel->win, 450, 280);
897 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask | KeyReleaseMask, keyPressHandler, panel);
899 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
900 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
902 panel->dirLabel = WMCreateLabel(panel->win);
903 WMResizeWidget(panel->dirLabel, 200, 20);
904 WMMoveWidget(panel->dirLabel, 10, 7);
905 WMSetLabelText(panel->dirLabel, _("Directories"));
906 WMSetLabelFont(panel->dirLabel, boldFont);
907 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
909 WMSetLabelRelief(panel->dirLabel, WRSunken);
911 panel->iconLabel = WMCreateLabel(panel->win);
912 WMResizeWidget(panel->iconLabel, 140, 20);
913 WMMoveWidget(panel->iconLabel, 215, 7);
914 WMSetLabelText(panel->iconLabel, _("Icons"));
915 WMSetLabelFont(panel->iconLabel, boldFont);
916 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
918 WMReleaseFont(boldFont);
920 color = WMWhiteColor(scr->wmscreen);
921 WMSetLabelTextColor(panel->dirLabel, color);
922 WMSetLabelTextColor(panel->iconLabel, color);
923 WMReleaseColor(color);
925 color = WMDarkGrayColor(scr->wmscreen);
926 WMSetWidgetBackgroundColor(panel->iconLabel, color);
927 WMSetWidgetBackgroundColor(panel->dirLabel, color);
928 WMReleaseColor(color);
930 WMSetLabelRelief(panel->iconLabel, WRSunken);
932 panel->dirList = WMCreateList(panel->win);
933 WMResizeWidget(panel->dirList, 200, 170);
934 WMMoveWidget(panel->dirList, 10, 30);
935 WMSetListAction(panel->dirList, listCallback, panel);
937 panel->iconList = WMCreateList(panel->win);
938 WMResizeWidget(panel->iconList, 140, 170);
939 WMMoveWidget(panel->iconList, 215, 30);
940 WMSetListAction(panel->iconList, listCallback, panel);
942 WMHangData(panel->iconList, panel);
944 panel->previewButton = WMCreateCommandButton(panel->win);
945 WMResizeWidget(panel->previewButton, 75, 26);
946 WMMoveWidget(panel->previewButton, 365, 130);
947 WMSetButtonText(panel->previewButton, _("Preview"));
948 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
950 panel->iconView = WMCreateLabel(panel->win);
951 WMResizeWidget(panel->iconView, 75, 75);
952 WMMoveWidget(panel->iconView, 365, 40);
953 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
954 WMSetLabelRelief(panel->iconView, WRSunken);
955 WMSetLabelTextAlignment(panel->iconView, WACenter);
957 panel->fileLabel = WMCreateLabel(panel->win);
958 WMResizeWidget(panel->fileLabel, 80, 20);
959 WMMoveWidget(panel->fileLabel, 10, 210);
960 WMSetLabelText(panel->fileLabel, _("File Name:"));
962 panel->fileField = WMCreateTextField(panel->win);
963 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
964 WMResizeWidget(panel->fileField, 345, 20);
965 WMMoveWidget(panel->fileField, 95, 210);
966 WMSetTextFieldEditable(panel->fileField, False);
968 panel->okButton = WMCreateCommandButton(panel->win);
969 WMResizeWidget(panel->okButton, 80, 26);
970 WMMoveWidget(panel->okButton, 360, 240);
971 WMSetButtonText(panel->okButton, _("OK"));
972 WMSetButtonEnabled(panel->okButton, False);
973 WMSetButtonAction(panel->okButton, buttonCallback, panel);
975 panel->cancelButton = WMCreateCommandButton(panel->win);
976 WMResizeWidget(panel->cancelButton, 80, 26);
977 WMMoveWidget(panel->cancelButton, 270, 240);
978 WMSetButtonText(panel->cancelButton, _("Cancel"));
979 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
980 #if 0
981 panel->chooseButton = WMCreateCommandButton(panel->win);
982 WMResizeWidget(panel->chooseButton, 110, 26);
983 WMMoveWidget(panel->chooseButton, 150, 240);
984 WMSetButtonText(panel->chooseButton, _("Choose File"));
985 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
986 #endif
987 WMRealizeWidget(panel->win);
988 WMMapSubwidgets(panel->win);
990 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
992 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
995 char *tmp;
996 int len = (instance ? strlen(instance) : 0)
997 + (class ? strlen(class) : 0) + 32;
998 WMPoint center;
1000 tmp = wmalloc(len);
1002 if (tmp && (instance || class))
1003 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
1004 else
1005 strcpy(tmp, _("Icon Chooser"));
1007 center = getCenter(scr, 450, 280);
1009 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x, center.y, 450, 280);
1010 wfree(tmp);
1013 /* put icon paths in the list */
1014 listIconPaths(panel->dirList);
1016 WMMapWidget(panel->win);
1018 wWindowMap(wwin);
1020 while (!panel->done) {
1021 XEvent event;
1023 WMNextEvent(dpy, &event);
1024 WMHandleEvent(&event);
1027 if (panel->result) {
1028 char *defaultPath, *wantedPath;
1030 /* check if the file the user selected is not the one that
1031 * would be loaded by default with the current search path */
1032 *file = WMGetListSelectedItem(panel->iconList)->text;
1033 if (**file == 0) {
1034 wfree(*file);
1035 *file = NULL;
1036 } else {
1037 defaultPath = FindImage(wPreferences.icon_path, *file);
1038 wantedPath = WMGetTextFieldText(panel->fileField);
1039 /* if the file is not the default, use full path */
1040 if (strcmp(wantedPath, defaultPath) != 0) {
1041 *file = wantedPath;
1042 } else {
1043 *file = wstrdup(*file);
1044 wfree(wantedPath);
1046 wfree(defaultPath);
1048 } else {
1049 *file = NULL;
1052 result = panel->result;
1054 WMReleaseFont(panel->normalfont);
1056 WMUnmapWidget(panel->win);
1058 WMDestroyWidget(panel->win);
1060 wUnmanageWindow(wwin, False, False);
1062 wfree(panel);
1064 XDestroyWindow(dpy, parent);
1066 return result;
1070 ***********************************************************************
1071 * Info Panel
1072 ***********************************************************************
1075 typedef struct {
1076 WScreen *scr;
1077 WWindow *wwin;
1078 WMWindow *win;
1079 WMLabel *logoL;
1080 WMLabel *name1L;
1081 WMFrame *lineF;
1082 WMLabel *name2L;
1083 WMLabel *versionL;
1084 WMLabel *infoL;
1085 WMLabel *copyrL;
1086 } InfoPanel;
1088 #define COPYRIGHT_TEXT \
1089 "Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
1090 "Copyright \xc2\xa9 1998-2006 Dan Pascu"
1092 static InfoPanel *thePanel = NULL;
1094 static void destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
1096 WMUnmapWidget(thePanel);
1097 wUnmanageWindow(thePanel->wwin, False, False);
1098 WMDestroyWidget(thePanel->win);
1099 wfree(thePanel);
1100 thePanel = NULL;
1103 void wShowInfoPanel(WScreen * scr)
1105 InfoPanel *panel;
1106 WMPixmap *logo;
1107 WMSize size;
1108 WMFont *font;
1109 char *strbuf = NULL;
1110 char buffer[256];
1111 char *name;
1112 Window parent;
1113 WWindow *wwin;
1114 char **strl;
1115 int i, width = 50, sepHeight;
1116 char *visuals[] = {
1117 "StaticGray",
1118 "GrayScale",
1119 "StaticColor",
1120 "PseudoColor",
1121 "TrueColor",
1122 "DirectColor"
1125 if (thePanel) {
1126 if (thePanel->scr == scr) {
1127 wRaiseFrame(thePanel->wwin->frame->core);
1128 wSetFocusTo(scr, thePanel->wwin);
1130 return;
1133 panel = wmalloc(sizeof(InfoPanel));
1134 memset(panel, 0, sizeof(InfoPanel));
1136 panel->scr = scr;
1138 panel->win = WMCreateWindow(scr->wmscreen, "info");
1139 WMResizeWidget(panel->win, 390, 230);
1141 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
1142 if (!logo) {
1143 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1145 if (logo) {
1146 size = WMGetPixmapSize(logo);
1147 panel->logoL = WMCreateLabel(panel->win);
1148 WMResizeWidget(panel->logoL, 64, 64);
1149 WMMoveWidget(panel->logoL, 30, 20);
1150 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1151 WMSetLabelImage(panel->logoL, logo);
1152 WMReleasePixmap(logo);
1155 sepHeight = 3;
1156 panel->name1L = WMCreateLabel(panel->win);
1157 WMResizeWidget(panel->name1L, 240, 30 + 2);
1158 WMMoveWidget(panel->name1L, 100, 30 - 2 - sepHeight);
1160 name = "Lucida Sans,Comic Sans MS,URW Gothic L,Trebuchet MS" ":italic:pixelsize=28:antialias=true";
1161 font = WMCreateFont(scr->wmscreen, name);
1162 strbuf = "Window Maker";
1163 if (font) {
1164 width = WMWidthOfString(font, strbuf, strlen(strbuf));
1165 WMSetLabelFont(panel->name1L, font);
1166 WMReleaseFont(font);
1168 WMSetLabelTextAlignment(panel->name1L, WACenter);
1169 WMSetLabelText(panel->name1L, strbuf);
1171 panel->lineF = WMCreateFrame(panel->win);
1172 WMResizeWidget(panel->lineF, width, sepHeight);
1173 WMMoveWidget(panel->lineF, 100 + (240 - width) / 2, 60 - sepHeight);
1174 WMSetFrameRelief(panel->lineF, WRSimple);
1175 WMSetWidgetBackgroundColor(panel->lineF, scr->black);
1177 panel->name2L = WMCreateLabel(panel->win);
1178 WMResizeWidget(panel->name2L, 240, 24);
1179 WMMoveWidget(panel->name2L, 100, 60);
1180 name = "URW Gothic L,Nimbus Sans L:pixelsize=16:antialias=true";
1181 font = WMCreateFont(scr->wmscreen, name);
1182 if (font) {
1183 WMSetLabelFont(panel->name2L, font);
1184 WMReleaseFont(font);
1185 font = NULL;
1187 WMSetLabelTextAlignment(panel->name2L, WACenter);
1188 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1190 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1191 panel->versionL = WMCreateLabel(panel->win);
1192 WMResizeWidget(panel->versionL, 310, 16);
1193 WMMoveWidget(panel->versionL, 30, 95);
1194 WMSetLabelTextAlignment(panel->versionL, WARight);
1195 WMSetLabelText(panel->versionL, buffer);
1196 WMSetLabelWraps(panel->versionL, False);
1198 panel->copyrL = WMCreateLabel(panel->win);
1199 WMResizeWidget(panel->copyrL, 360, 40);
1200 WMMoveWidget(panel->copyrL, 15, 185);
1201 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1202 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1203 font = WMSystemFontOfSize(scr->wmscreen, 11);
1204 if (font) {
1205 WMSetLabelFont(panel->copyrL, font);
1206 WMReleaseFont(font);
1207 font = NULL;
1210 strbuf = NULL;
1211 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1212 (unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
1214 strbuf = wstrappend(strbuf, buffer);
1216 switch (scr->w_depth) {
1217 case 15:
1218 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1219 break;
1220 case 16:
1221 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1222 break;
1223 case 24:
1224 case 32:
1225 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1226 break;
1227 default:
1228 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1 << scr->w_depth);
1229 strbuf = wstrappend(strbuf, buffer);
1230 break;
1233 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1235 struct mallinfo ma = mallinfo();
1236 snprintf(buffer, sizeof(buffer),
1237 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1238 (ma.arena + ma.hblkhd) / 1024, (ma.uordblks + ma.hblkhd) / 1024);
1240 strbuf = wstrappend(strbuf, buffer);
1242 #endif
1244 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1245 strl = RSupportedFileFormats();
1246 for (i = 0; strl[i] != NULL; i++) {
1247 strbuf = wstrappend(strbuf, strl[i]);
1248 strbuf = wstrappend(strbuf, " ");
1251 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1253 char *list[9];
1254 char buf[80];
1255 int j = 0;
1257 list[j++] = "WMSPEC";
1258 #ifdef MWM_HINTS
1259 list[j++] = "MWM";
1260 #endif
1262 buf[0] = 0;
1263 for (i = 0; i < j; i++) {
1264 if (i > 0) {
1265 if (i == j - 1)
1266 strcat(buf, _(" and "));
1267 else
1268 strcat(buf, ", ");
1270 strcat(buf, list[i]);
1272 strbuf = wstrappend(strbuf, buf);
1275 #ifdef XINERAMA
1276 strbuf = wstrappend(strbuf, _("\n"));
1277 #ifdef SOLARIS_XINERAMA
1278 strbuf = wstrappend(strbuf, _("Solaris "));
1279 #endif
1280 strbuf = wstrappend(strbuf, _("Xinerama: "));
1282 char tmp[128];
1283 snprintf(tmp, sizeof(tmp) - 1, "%d heads found.", scr->xine_info.count);
1284 strbuf = wstrappend(strbuf, tmp);
1286 #endif
1288 panel->infoL = WMCreateLabel(panel->win);
1289 WMResizeWidget(panel->infoL, 350, 75);
1290 WMMoveWidget(panel->infoL, 15, 115);
1291 WMSetLabelText(panel->infoL, strbuf);
1292 font = WMSystemFontOfSize(scr->wmscreen, 11);
1293 if (font) {
1294 WMSetLabelFont(panel->infoL, font);
1295 WMReleaseFont(font);
1296 font = NULL;
1298 wfree(strbuf);
1300 WMRealizeWidget(panel->win);
1301 WMMapSubwidgets(panel->win);
1303 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1305 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1307 WMMapWidget(panel->win);
1310 WMPoint center = getCenter(scr, 382, 230);
1312 wwin = wManageInternalWindow(scr, parent, None, _("Info"), center.x, center.y, 382, 230);
1315 WSETUFLAG(wwin, no_closable, 0);
1316 WSETUFLAG(wwin, no_close_button, 0);
1317 #ifdef XKB_BUTTON_HINT
1318 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1319 #endif
1320 wWindowUpdateButtonImages(wwin);
1321 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1322 wwin->frame->on_click_right = destroyInfoPanel;
1324 wWindowMap(wwin);
1326 panel->wwin = wwin;
1327 thePanel = panel;
1331 ***********************************************************************
1332 * Legal Panel
1333 ***********************************************************************
1336 typedef struct {
1337 WScreen *scr;
1339 WWindow *wwin;
1341 WMWindow *win;
1343 WMLabel *licenseL;
1344 } LegalPanel;
1346 static LegalPanel *legalPanel = NULL;
1348 static void destroyLegalPanel(WCoreWindow * foo, void *data, XEvent * event)
1350 WMUnmapWidget(legalPanel->win);
1352 WMDestroyWidget(legalPanel->win);
1354 wUnmanageWindow(legalPanel->wwin, False, False);
1356 wfree(legalPanel);
1358 legalPanel = NULL;
1361 void wShowLegalPanel(WScreen * scr)
1363 LegalPanel *panel;
1364 Window parent;
1365 WWindow *wwin;
1367 if (legalPanel) {
1368 if (legalPanel->scr == scr) {
1369 wRaiseFrame(legalPanel->wwin->frame->core);
1370 wSetFocusTo(scr, legalPanel->wwin);
1372 return;
1375 panel = wmalloc(sizeof(LegalPanel));
1377 panel->scr = scr;
1379 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1380 WMResizeWidget(panel->win, 420, 250);
1382 panel->licenseL = WMCreateLabel(panel->win);
1383 WMSetLabelWraps(panel->licenseL, True);
1384 WMResizeWidget(panel->licenseL, 400, 230);
1385 WMMoveWidget(panel->licenseL, 10, 10);
1386 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1387 WMSetLabelText(panel->licenseL,
1388 _(" Window Maker is free software; you can redistribute it and/or\n"
1389 "modify it under the terms of the GNU General Public License as\n"
1390 "published by the Free Software Foundation; either version 2 of the\n"
1391 "License, or (at your option) any later version.\n\n"
1392 " Window Maker is distributed in the hope that it will be useful,\n"
1393 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1394 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1395 "See the GNU General Public License for more details.\n\n"
1396 " You should have received a copy of the GNU General Public\n"
1397 "License along with this program; if not, write to the Free Software\n"
1398 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n" "02111-1307, USA."));
1399 WMSetLabelRelief(panel->licenseL, WRGroove);
1401 WMRealizeWidget(panel->win);
1402 WMMapSubwidgets(panel->win);
1404 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1406 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1409 WMPoint center = getCenter(scr, 420, 250);
1411 wwin = wManageInternalWindow(scr, parent, None, _("Legal"), center.x, center.y, 420, 250);
1414 WSETUFLAG(wwin, no_closable, 0);
1415 WSETUFLAG(wwin, no_close_button, 0);
1416 wWindowUpdateButtonImages(wwin);
1417 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1418 #ifdef XKB_BUTTON_HINT
1419 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1420 #endif
1421 wwin->frame->on_click_right = destroyLegalPanel;
1423 panel->wwin = wwin;
1425 WMMapWidget(panel->win);
1427 wWindowMap(wwin);
1429 legalPanel = panel;
1433 ***********************************************************************
1434 * Crashing Dialog Panel
1435 ***********************************************************************
1438 extern WDDomain *WDWindowAttributes;
1440 typedef struct _CrashPanel {
1441 WMWindow *win; /* main window */
1443 WMLabel *iconL; /* application icon */
1444 WMLabel *nameL; /* title of panel */
1446 WMFrame *sepF; /* separator frame */
1448 WMLabel *noteL; /* Title of note */
1449 WMLabel *note2L; /* body of note with what happened */
1451 WMFrame *whatF; /* "what to do next" frame */
1452 WMPopUpButton *whatP; /* action selection popup button */
1454 WMButton *okB; /* ok button */
1456 Bool done; /* if finished with this dialog */
1457 int action; /* what to do after */
1459 KeyCode retKey;
1461 } CrashPanel;
1463 static void handleKeyPress(XEvent * event, void *clientData)
1465 CrashPanel *panel = (CrashPanel *) clientData;
1467 if (event->xkey.keycode == panel->retKey) {
1468 WMPerformButtonClick(panel->okB);
1472 static void okButtonCallback(void *self, void *clientData)
1474 CrashPanel *panel = (CrashPanel *) clientData;
1476 panel->done = True;
1479 static void setCrashAction(void *self, void *clientData)
1481 WMPopUpButton *pop = (WMPopUpButton *) self;
1482 CrashPanel *panel = (CrashPanel *) clientData;
1484 panel->action = WMGetPopUpButtonSelectedItem(pop);
1487 /* Make this read the logo from a compiled in pixmap -Dan */
1488 static WMPixmap *getWindowMakerIconImage(WMScreen * scr)
1490 WMPropList *dict, *key, *option, *value = NULL;
1491 WMPixmap *pix = NULL;
1492 char *path;
1494 if (!WDWindowAttributes || !WDWindowAttributes->dictionary)
1495 return NULL;
1497 WMPLSetCaseSensitive(True);
1499 key = WMCreatePLString("Logo.WMPanel");
1500 option = WMCreatePLString("Icon");
1502 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1504 if (dict) {
1505 value = WMGetFromPLDictionary(dict, option);
1508 WMReleasePropList(key);
1509 WMReleasePropList(option);
1511 WMPLSetCaseSensitive(False);
1513 if (value && WMIsPLString(value)) {
1514 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1516 if (path) {
1517 RColor gray;
1519 gray.red = 0xae;
1520 gray.green = 0xaa;
1521 gray.blue = 0xae;
1522 gray.alpha = 0;
1524 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1525 wfree(path);
1529 return pix;
1532 #define PWIDTH 295
1533 #define PHEIGHT 345
1535 int wShowCrashingDialogPanel(int whatSig)
1537 CrashPanel *panel;
1538 WMScreen *scr;
1539 WMFont *font;
1540 WMPixmap *logo;
1541 int screen_no, scr_width, scr_height;
1542 int action;
1543 char buf[256];
1545 panel = wmalloc(sizeof(CrashPanel));
1546 memset(panel, 0, sizeof(CrashPanel));
1548 screen_no = DefaultScreen(dpy);
1549 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1550 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1552 scr = WMCreateScreen(dpy, screen_no);
1553 if (!scr) {
1554 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1555 return WMAbort;
1558 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1560 panel->win = WMCreateWindow(scr, "crashingDialog");
1561 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1562 WMMoveWidget(panel->win, (scr_width - PWIDTH) / 2, (scr_height - PHEIGHT) / 2);
1564 logo = getWindowMakerIconImage(scr);
1565 if (logo) {
1566 panel->iconL = WMCreateLabel(panel->win);
1567 WMResizeWidget(panel->iconL, 64, 64);
1568 WMMoveWidget(panel->iconL, 10, 10);
1569 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1570 WMSetLabelImage(panel->iconL, logo);
1573 panel->nameL = WMCreateLabel(panel->win);
1574 WMResizeWidget(panel->nameL, 200, 30);
1575 WMMoveWidget(panel->nameL, 80, 25);
1576 WMSetLabelTextAlignment(panel->nameL, WALeft);
1577 font = WMBoldSystemFontOfSize(scr, 24);
1578 WMSetLabelFont(panel->nameL, font);
1579 WMReleaseFont(font);
1580 WMSetLabelText(panel->nameL, _("Fatal error"));
1582 panel->sepF = WMCreateFrame(panel->win);
1583 WMResizeWidget(panel->sepF, PWIDTH + 4, 2);
1584 WMMoveWidget(panel->sepF, -2, 80);
1586 panel->noteL = WMCreateLabel(panel->win);
1587 WMResizeWidget(panel->noteL, PWIDTH - 20, 40);
1588 WMMoveWidget(panel->noteL, 10, 90);
1589 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1590 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1591 WMSetLabelText(panel->noteL, buf);
1593 panel->note2L = WMCreateLabel(panel->win);
1594 WMResizeWidget(panel->note2L, PWIDTH - 20, 100);
1595 WMMoveWidget(panel->note2L, 10, 130);
1596 WMSetLabelTextAlignment(panel->note2L, WALeft);
1597 WMSetLabelText(panel->note2L,
1598 _(" This fatal error occured probably due to a bug."
1599 " Please fill the included BUGFORM and " "report it to bugs@windowmaker.info."));
1600 WMSetLabelWraps(panel->note2L, True);
1602 panel->whatF = WMCreateFrame(panel->win);
1603 WMResizeWidget(panel->whatF, PWIDTH - 20, 50);
1604 WMMoveWidget(panel->whatF, 10, 240);
1605 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1607 panel->whatP = WMCreatePopUpButton(panel->whatF);
1608 WMResizeWidget(panel->whatP, PWIDTH - 20 - 70, 20);
1609 WMMoveWidget(panel->whatP, 35, 20);
1610 WMSetPopUpButtonPullsDown(panel->whatP, False);
1611 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1612 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1613 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1614 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1615 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1616 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1617 panel->action = WMRestart;
1619 WMMapSubwidgets(panel->whatF);
1621 panel->okB = WMCreateCommandButton(panel->win);
1622 WMResizeWidget(panel->okB, 80, 26);
1623 WMMoveWidget(panel->okB, 205, 309);
1624 WMSetButtonText(panel->okB, _("OK"));
1625 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1626 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1627 WMSetButtonImagePosition(panel->okB, WIPRight);
1628 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1630 panel->done = 0;
1632 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask, handleKeyPress, panel);
1634 WMRealizeWidget(panel->win);
1635 WMMapSubwidgets(panel->win);
1637 WMMapWidget(panel->win);
1639 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1641 while (!panel->done) {
1642 XEvent event;
1644 WMNextEvent(dpy, &event);
1645 WMHandleEvent(&event);
1648 action = panel->action;
1650 WMUnmapWidget(panel->win);
1651 WMDestroyWidget(panel->win);
1652 wfree(panel);
1654 return action;
1657 /*****************************************************************************
1658 * About GNUstep Panel
1659 *****************************************************************************/
1661 static void
1662 drawGNUstepLogo(Display * dpy, Drawable d, int width, int height,
1663 unsigned long blackPixel, unsigned long whitePixel)
1665 GC gc;
1666 XGCValues gcv;
1667 XRectangle rects[3];
1669 gcv.foreground = blackPixel;
1670 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1672 XFillArc(dpy, d, gc, width / 45, height / 45,
1673 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
1675 rects[0].x = 0;
1676 rects[0].y = 37 * height / 45;
1677 rects[0].width = width / 3;
1678 rects[0].height = height - rects[0].y;
1680 rects[1].x = rects[0].width;
1681 rects[1].y = height / 2;
1682 rects[1].width = width - 2 * width / 3;
1683 rects[1].height = height - rects[1].y;
1685 rects[2].x = 2 * width / 3;
1686 rects[2].y = height - 37 * height / 45;
1687 rects[2].width = width / 3;
1688 rects[2].height = height - rects[2].y;
1690 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1691 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1693 XSetForeground(dpy, gc, whitePixel);
1694 XFillArc(dpy, d, gc, width / 45, height / 45,
1695 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
1697 XFreeGC(dpy, gc);
1700 typedef struct {
1701 WScreen *scr;
1703 WWindow *wwin;
1705 WMWindow *win;
1707 WMLabel *gstepL;
1708 WMLabel *textL;
1709 } GNUstepPanel;
1711 static GNUstepPanel *gnustepPanel = NULL;
1713 static void destroyGNUstepPanel(WCoreWindow * foo, void *data, XEvent * event)
1715 WMUnmapWidget(gnustepPanel->win);
1717 WMDestroyWidget(gnustepPanel->win);
1719 wUnmanageWindow(gnustepPanel->wwin, False, False);
1721 wfree(gnustepPanel);
1723 gnustepPanel = NULL;
1726 void wShowGNUstepPanel(WScreen * scr)
1728 GNUstepPanel *panel;
1729 Window parent;
1730 WWindow *wwin;
1731 WMPixmap *pixmap;
1732 WMColor *color;
1734 if (gnustepPanel) {
1735 if (gnustepPanel->scr == scr) {
1736 wRaiseFrame(gnustepPanel->wwin->frame->core);
1737 wSetFocusTo(scr, gnustepPanel->wwin);
1739 return;
1742 panel = wmalloc(sizeof(GNUstepPanel));
1744 panel->scr = scr;
1746 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1747 WMResizeWidget(panel->win, 325, 205);
1749 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130, WMScreenDepth(scr->wmscreen), True);
1751 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1753 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130, WMColorPixel(color), scr->white_pixel);
1755 WMReleaseColor(color);
1757 XSetForeground(dpy, scr->mono_gc, 0);
1758 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0, 130, 130);
1759 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1761 panel->gstepL = WMCreateLabel(panel->win);
1762 WMResizeWidget(panel->gstepL, 285, 64);
1763 WMMoveWidget(panel->gstepL, 20, 0);
1764 WMSetLabelTextAlignment(panel->gstepL, WARight);
1765 WMSetLabelText(panel->gstepL, "GNUstep");
1767 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1769 WMSetLabelFont(panel->gstepL, font);
1770 WMReleaseFont(font);
1773 panel->textL = WMCreateLabel(panel->win);
1774 WMResizeWidget(panel->textL, 305, 140);
1775 WMMoveWidget(panel->textL, 10, 50);
1776 WMSetLabelTextAlignment(panel->textL, WARight);
1777 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1778 WMSetLabelText(panel->textL,
1779 _("Window Maker is part of the GNUstep project.\n"
1780 "The GNUstep project aims to create a free\n"
1781 "implementation of the OpenStep(tm) specification\n"
1782 "which is a object-oriented framework for\n"
1783 "creating advanced graphical, multi-platform\n"
1784 "applications. Additionally, a development and\n"
1785 "user desktop enviroment will be created on top\n"
1786 "of the framework. For more information about\n"
1787 "GNUstep, please visit: www.gnustep.org"));
1788 WMSetLabelImage(panel->textL, pixmap);
1790 WMReleasePixmap(pixmap);
1792 WMRealizeWidget(panel->win);
1793 WMMapSubwidgets(panel->win);
1795 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1797 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1800 WMPoint center = getCenter(scr, 325, 200);
1802 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"), center.x, center.y, 325, 200);
1805 WSETUFLAG(wwin, no_closable, 0);
1806 WSETUFLAG(wwin, no_close_button, 0);
1807 wWindowUpdateButtonImages(wwin);
1808 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1809 #ifdef XKB_BUTTON_HINT
1810 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1811 #endif
1812 wwin->frame->on_click_right = destroyGNUstepPanel;
1814 panel->wwin = wwin;
1816 WMMapWidget(panel->win);
1818 wWindowMap(wwin);
1820 gnustepPanel = panel;