Get rid of cropline(), use wtrimspace() instead
[wmaker-crm.git] / src / dialog.c
blob904eac3d121406727b040cefd84babbbf106cb28
1 /* dialog.c - dialog windows for internal use
3 * Window Maker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 1998-2003 Dan Pascu
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "wconfig.h"
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <X11/keysym.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <dirent.h>
36 #include <limits.h>
38 #ifdef HAVE_MALLOC_H
39 #include <malloc.h>
40 #endif
42 #include <signal.h>
43 #ifdef __FreeBSD__
44 #include <sys/signal.h>
45 #endif
47 #ifndef PATH_MAX
48 #define PATH_MAX DEFAULT_PATH_MAX
49 #endif
51 #include "WindowMaker.h"
52 #include "GNUstep.h"
53 #include "screen.h"
54 #include "dialog.h"
55 #include "funcs.h"
56 #include "stacking.h"
57 #include "framewin.h"
58 #include "window.h"
59 #include "actions.h"
60 #include "xinerama.h"
62 extern WPreferences wPreferences;
64 static WMPoint getCenter(WScreen * scr, int width, int height)
66 return wGetPointToCenterRectInHead(scr, wGetHeadForPointerLocation(scr), width, height);
69 int wMessageDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
71 WMAlertPanel *panel;
72 Window parent;
73 WWindow *wwin;
74 int result;
75 WMPoint center;
77 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
79 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
81 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
83 center = getCenter(scr, 400, 180);
84 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
85 wwin->client_leader = WMWidgetXID(panel->win);
87 WMMapWidget(panel->win);
89 wWindowMap(wwin);
91 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
93 result = panel->result;
95 WMUnmapWidget(panel->win);
97 wUnmanageWindow(wwin, False, False);
99 WMDestroyAlertPanel(panel);
101 XDestroyWindow(dpy, parent);
103 return result;
106 static void toggleSaveSession(WMWidget *w, void *data)
108 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
111 int wExitDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
113 WMAlertPanel *panel;
114 WMButton *saveSessionBtn;
115 Window parent;
116 WWindow *wwin;
117 WMPoint center;
118 int result;
120 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
122 /* add save session button */
123 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
124 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
125 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn), False, True, 200, 0, 0);
126 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
127 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
128 WMRealizeWidget(saveSessionBtn);
129 WMMapWidget(saveSessionBtn);
131 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
133 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
135 center = getCenter(scr, 400, 180);
136 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
138 wwin->client_leader = WMWidgetXID(panel->win);
140 WMMapWidget(panel->win);
142 wWindowMap(wwin);
144 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
146 result = panel->result;
148 WMUnmapWidget(panel->win);
150 wUnmanageWindow(wwin, False, False);
152 WMDestroyAlertPanel(panel);
154 XDestroyWindow(dpy, parent);
156 return result;
159 typedef struct _WMInputPanelWithHistory {
160 WMInputPanel *panel;
161 WMArray *history;
162 int histpos;
163 char *prefix;
164 char *suffix;
165 char *rest;
166 WMArray *variants;
167 int varpos;
168 } WMInputPanelWithHistory;
170 static char *HistoryFileName(char *name)
172 char *filename = NULL;
174 filename = wstrdup(wusergnusteppath());
175 filename = wstrappend(filename, "/.AppInfo/WindowMaker/History");
176 if (name && strlen(name)) {
177 filename = wstrappend(filename, ".");
178 filename = wstrappend(filename, name);
180 return filename;
183 static int strmatch(const void *str1, const void *str2)
185 return !strcmp((const char *)str1, (const char *)str2);
188 static WMArray *LoadHistory(char *filename, int max)
190 WMPropList *plhistory;
191 WMPropList *plitem;
192 WMArray *history;
193 int i, num;
195 history = WMCreateArrayWithDestructor(1, wfree);
196 WMAddToArray(history, wstrdup(""));
198 plhistory = WMReadPropListFromFile((char *)filename);
200 if (plhistory && WMIsPLArray(plhistory)) {
201 num = WMGetPropListItemCount(plhistory);
202 if (num > max)
203 num = max;
205 for (i = 0; i < num; ++i) {
206 plitem = WMGetFromPLArray(plhistory, i);
207 if (WMIsPLString(plitem) && WMFindInArray(history, strmatch,
208 WMGetFromPLString(plitem)) == WANotFound)
209 WMAddToArray(history, WMGetFromPLString(plitem));
213 return history;
216 static void SaveHistory(WMArray * history, char *filename)
218 int i;
219 WMPropList *plhistory;
221 plhistory = WMCreatePLArray(NULL);
223 for (i = 0; i < WMGetArrayItemCount(history); ++i)
224 WMAddToPLArray(plhistory, WMCreatePLString(WMGetFromArray(history, i)));
226 WMWritePropListToFile(plhistory, (char *)filename);
227 WMReleasePropList(plhistory);
230 static int pstrcmp(const char **str1, const char **str2)
232 return strcmp(*str1, *str2);
235 static void
236 ScanFiles(const char *dir, const char *prefix, unsigned acceptmask, unsigned declinemask, WMArray * result)
238 int prefixlen;
239 DIR *d;
240 struct dirent *de;
241 struct stat sb;
242 char *fullfilename, *suffix;
244 prefixlen = strlen(prefix);
245 if ((d = opendir(dir)) != NULL) {
246 while ((de = readdir(d)) != NULL) {
247 if (strlen(de->d_name) > prefixlen &&
248 !strncmp(prefix, de->d_name, prefixlen) &&
249 strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..")) {
250 fullfilename = wstrconcat((char *)dir, "/");
251 fullfilename = wstrappend(fullfilename, de->d_name);
253 if (stat(fullfilename, &sb) == 0 &&
254 (sb.st_mode & acceptmask) &&
255 !(sb.st_mode & declinemask) &&
256 WMFindInArray(result, (WMMatchDataProc *) strmatch,
257 de->d_name + prefixlen) == WANotFound) {
258 suffix = wstrdup(de->d_name + prefixlen);
259 if (sb.st_mode & S_IFDIR)
260 wstrappend(suffix,"/");
261 WMAddToArray(result, suffix);
263 wfree(fullfilename);
266 closedir(d);
270 static WMArray *GenerateVariants(const char *complete)
272 Bool firstWord = True;
273 WMArray *variants = NULL;
274 char *pos = NULL, *path = NULL, *tmp = NULL, *dir = NULL, *prefix = NULL;
276 variants = WMCreateArrayWithDestructor(0, wfree);
278 while (*complete == ' ')
279 ++complete;
281 if ((pos = strrchr(complete, ' ')) != NULL) {
282 complete = pos + 1;
283 firstWord = False;
286 if ((pos = strrchr(complete, '/')) != NULL) {
287 tmp = wstrndup((char *)complete, pos - complete + 1);
288 if (*tmp == '~' && *(tmp + 1) == '/' && getenv("HOME")) {
289 dir = wstrdup(getenv("HOME"));
290 dir = wstrappend(dir, tmp + 1);
291 wfree(tmp);
292 } else {
293 dir = tmp;
295 prefix = wstrdup(pos + 1);
296 ScanFiles(dir, prefix, (unsigned)-1, 0, variants);
297 wfree(dir);
298 wfree(prefix);
299 } else if (*complete == '~') {
300 WMAddToArray(variants, wstrdup("/"));
301 } else if (firstWord) {
302 path = getenv("PATH");
303 while (path) {
304 pos = strchr(path, ':');
305 if (pos) {
306 tmp = wstrndup(path, pos - path);
307 path = pos + 1;
308 } else if (*path != '\0') {
309 tmp = wstrdup(path);
310 path = NULL;
311 } else
312 break;
313 ScanFiles(tmp, complete, S_IXOTH | S_IXGRP | S_IXUSR, S_IFDIR, variants);
314 wfree(tmp);
318 WMSortArray(variants, (WMCompareDataProc *) pstrcmp);
319 return variants;
322 static void handleHistoryKeyPress(XEvent * event, void *clientData)
324 char *text;
325 unsigned pos;
326 WMInputPanelWithHistory *p = (WMInputPanelWithHistory *) clientData;
327 KeySym ksym;
329 ksym = XLookupKeysym(&event->xkey, 0);
331 switch (ksym) {
332 case XK_Up:
333 if (p->histpos < WMGetArrayItemCount(p->history) - 1) {
334 if (p->histpos == 0)
335 wfree(WMReplaceInArray(p->history, 0, WMGetTextFieldText(p->panel->text)));
336 p->histpos++;
337 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
339 break;
340 case XK_Down:
341 if (p->histpos > 0) {
342 p->histpos--;
343 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
345 break;
346 case XK_Tab:
347 if (!p->variants) {
348 text = WMGetTextFieldText(p->panel->text);
349 pos = WMGetTextFieldCursorPosition(p->panel->text);
350 p->prefix = wstrndup(text, pos);
351 p->suffix = wstrdup(text + pos);
352 wfree(text);
353 p->variants = GenerateVariants(p->prefix);
354 p->varpos = 0;
355 if (!p->variants) {
356 wfree(p->prefix);
357 wfree(p->suffix);
358 p->prefix = NULL;
359 p->suffix = NULL;
362 if (p->variants && p->prefix && p->suffix) {
363 p->varpos++;
364 if (p->varpos > WMGetArrayItemCount(p->variants))
365 p->varpos = 0;
366 if (p->varpos > 0)
367 text = wstrconcat(p->prefix, WMGetFromArray(p->variants, p->varpos - 1));
368 else
369 text = wstrdup(p->prefix);
370 pos = strlen(text);
371 text = wstrappend(text, p->suffix);
372 WMSetTextFieldText(p->panel->text, text);
373 WMSetTextFieldCursorPosition(p->panel->text, pos);
374 wfree(text);
376 break;
378 if (ksym != XK_Tab) {
379 if (p->prefix) {
380 wfree(p->prefix);
381 p->prefix = NULL;
383 if (p->suffix) {
384 wfree(p->suffix);
385 p->suffix = NULL;
387 if (p->variants) {
388 WMFreeArray(p->variants);
389 p->variants = NULL;
394 int wAdvancedInputDialog(WScreen * scr, char *title, char *message, char *name, char **text)
396 WWindow *wwin;
397 Window parent;
398 char *result;
399 WMPoint center;
400 WMInputPanelWithHistory *p;
401 char *filename;
403 filename = HistoryFileName(name);
404 p = wmalloc(sizeof(WMInputPanelWithHistory));
405 p->panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
406 p->history = LoadHistory(filename, wPreferences.history_lines);
407 p->histpos = 0;
408 p->prefix = NULL;
409 p->suffix = NULL;
410 p->rest = NULL;
411 p->variants = NULL;
412 p->varpos = 0;
413 WMCreateEventHandler(WMWidgetView(p->panel->text), KeyPressMask, handleHistoryKeyPress, p);
415 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
416 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
418 XReparentWindow(dpy, WMWidgetXID(p->panel->win), parent, 0, 0);
420 center = getCenter(scr, 320, 160);
421 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
423 wwin->client_leader = WMWidgetXID(p->panel->win);
425 WMMapWidget(p->panel->win);
427 wWindowMap(wwin);
429 WMRunModalLoop(WMWidgetScreen(p->panel->win), WMWidgetView(p->panel->win));
431 if (p->panel->result == WAPRDefault) {
432 result = WMGetTextFieldText(p->panel->text);
433 wfree(WMReplaceInArray(p->history, 0, wstrdup(result)));
434 SaveHistory(p->history, filename);
435 } else
436 result = NULL;
438 wUnmanageWindow(wwin, False, False);
440 WMDestroyInputPanel(p->panel);
441 WMFreeArray(p->history);
442 wfree(p);
443 wfree(filename);
445 XDestroyWindow(dpy, parent);
447 if (result == NULL)
448 return False;
449 else {
450 if (*text)
451 wfree(*text);
452 *text = result;
454 return True;
458 int wInputDialog(WScreen * scr, char *title, char *message, char **text)
460 WWindow *wwin;
461 Window parent;
462 WMInputPanel *panel;
463 char *result;
464 WMPoint center;
466 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
468 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
469 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
471 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
473 center = getCenter(scr, 320, 160);
474 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
476 wwin->client_leader = WMWidgetXID(panel->win);
478 WMMapWidget(panel->win);
480 wWindowMap(wwin);
482 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
484 if (panel->result == WAPRDefault)
485 result = WMGetTextFieldText(panel->text);
486 else
487 result = NULL;
489 wUnmanageWindow(wwin, False, False);
491 WMDestroyInputPanel(panel);
493 XDestroyWindow(dpy, parent);
495 if (result == NULL)
496 return False;
497 else {
498 if (*text)
499 wfree(*text);
500 *text = result;
502 return True;
507 *****************************************************************
508 * Icon Selection Panel
509 *****************************************************************
512 typedef struct IconPanel {
514 WScreen *scr;
516 WMWindow *win;
518 WMLabel *dirLabel;
519 WMLabel *iconLabel;
521 WMList *dirList;
522 WMList *iconList;
523 WMFont *normalfont;
525 WMButton *previewButton;
527 WMLabel *iconView;
529 WMLabel *fileLabel;
530 WMTextField *fileField;
532 WMButton *okButton;
533 WMButton *cancelButton;
534 #if 0
535 WMButton *chooseButton;
536 #endif
537 short done;
538 short result;
539 short preview;
540 } IconPanel;
542 static void listPixmaps(WScreen * scr, WMList * lPtr, char *path)
544 struct dirent *dentry;
545 DIR *dir;
546 char pbuf[PATH_MAX + 16];
547 char *apath;
548 IconPanel *panel = WMGetHangedData(lPtr);
550 panel->preview = False;
552 apath = wexpandpath(path);
553 dir = opendir(apath);
555 if (!dir) {
556 char *msg;
557 char *tmp;
558 tmp = _("Could not open directory ");
559 msg = wmalloc(strlen(tmp) + strlen(path) + 6);
560 strcpy(msg, tmp);
561 strcat(msg, path);
563 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
564 wfree(msg);
565 wfree(apath);
566 return;
569 /* list contents in the column */
570 while ((dentry = readdir(dir))) {
571 struct stat statb;
573 if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") == 0)
574 continue;
576 strcpy(pbuf, apath);
577 strcat(pbuf, "/");
578 strcat(pbuf, dentry->d_name);
580 if (stat(pbuf, &statb) < 0)
581 continue;
583 if (statb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)
584 && statb.st_mode & (S_IFREG | S_IFLNK)) {
585 WMAddListItem(lPtr, dentry->d_name);
588 WMSortListItems(lPtr);
590 closedir(dir);
591 wfree(apath);
592 panel->preview = True;
595 static void setViewedImage(IconPanel * panel, char *file)
597 WMPixmap *pixmap;
598 RColor color;
600 color.red = 0xae;
601 color.green = 0xaa;
602 color.blue = 0xae;
603 color.alpha = 0;
604 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win), file, &color);
605 if (!pixmap) {
606 WMSetButtonEnabled(panel->okButton, False);
608 WMSetLabelText(panel->iconView, _("Could not load image file "));
610 WMSetLabelImage(panel->iconView, NULL);
611 } else {
612 WMSetButtonEnabled(panel->okButton, True);
614 WMSetLabelText(panel->iconView, NULL);
615 WMSetLabelImage(panel->iconView, pixmap);
616 WMReleasePixmap(pixmap);
620 static void listCallback(void *self, void *data)
622 WMList *lPtr = (WMList *) self;
623 IconPanel *panel = (IconPanel *) data;
624 char *path;
626 if (lPtr == panel->dirList) {
627 WMListItem *item = WMGetListSelectedItem(lPtr);
629 if (item == NULL)
630 return;
631 path = item->text;
633 WMSetTextFieldText(panel->fileField, path);
635 WMSetLabelImage(panel->iconView, NULL);
637 WMSetButtonEnabled(panel->okButton, False);
639 WMClearList(panel->iconList);
640 listPixmaps(panel->scr, panel->iconList, path);
641 } else {
642 char *tmp, *iconFile;
643 WMListItem *item = WMGetListSelectedItem(panel->dirList);
645 if (item == NULL)
646 return;
647 path = item->text;
648 tmp = wexpandpath(path);
650 item = WMGetListSelectedItem(panel->iconList);
651 if (item == NULL)
652 return;
653 iconFile = item->text;
655 path = wmalloc(strlen(tmp) + strlen(iconFile) + 4);
656 strcpy(path, tmp);
657 strcat(path, "/");
658 strcat(path, iconFile);
659 wfree(tmp);
660 WMSetTextFieldText(panel->fileField, path);
661 setViewedImage(panel, path);
662 wfree(path);
666 static void listIconPaths(WMList * lPtr)
668 char *paths;
669 char *path;
671 paths = wstrdup(wPreferences.icon_path);
673 path = strtok(paths, ":");
675 do {
676 char *tmp;
678 tmp = wexpandpath(path);
679 /* do not sort, because the order implies the order of
680 * directories searched */
681 if (access(tmp, X_OK) == 0)
682 WMAddListItem(lPtr, path);
683 wfree(tmp);
684 } while ((path = strtok(NULL, ":")) != NULL);
686 wfree(paths);
689 static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
691 IconPanel *panel = WMGetHangedData(lPtr);
692 WScreen *scr = panel->scr;
693 GC gc = scr->draw_gc;
694 GC copygc = scr->copy_gc;
695 char *file, *dirfile;
696 WMPixmap *pixmap;
697 WMColor *back;
698 WMSize size;
699 WMScreen *wmscr = WMWidgetScreen(panel->win);
700 RColor color;
701 int x, y, width, height, len;
703 if (!panel->preview)
704 return;
706 x = rect->pos.x;
707 y = rect->pos.y;
708 width = rect->size.width;
709 height = rect->size.height;
711 back = (state & WLDSSelected) ? scr->white : scr->gray;
713 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
714 len = strlen(dirfile) + strlen(text) + 4;
715 file = wmalloc(len);
716 snprintf(file, len, "%s/%s", dirfile, text);
717 wfree(dirfile);
719 color.red = WMRedComponentOfColor(back) >> 8;
720 color.green = WMGreenComponentOfColor(back) >> 8;
721 color.blue = WMBlueComponentOfColor(back) >> 8;
722 color.alpha = WMGetColorAlpha(back) >> 8;
724 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
725 wfree(file);
727 if (!pixmap) {
728 /*WMRemoveListItem(lPtr, index); */
729 return;
732 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
734 XSetClipMask(dpy, gc, None);
735 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54); */
736 XDrawLine(dpy, d, WMColorGC(scr->white), x, y + height - 1, x + width, y + height - 1);
738 size = WMGetPixmapSize(pixmap);
740 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
741 XSetClipOrigin(dpy, copygc, x + (width - size.width) / 2, y + 2);
742 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
743 size.width > 100 ? 100 : size.width, size.height > 64 ? 64 : size.height,
744 x + (width - size.width) / 2, y + 2);
747 int i, j;
748 int fheight = WMFontHeight(panel->normalfont);
749 int tlen = strlen(text);
750 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
751 int ofx, ofy;
753 ofx = x + (width - twidth) / 2;
754 ofy = y + 64 - fheight;
756 for (i = -1; i < 2; i++)
757 for (j = -1; j < 2; j++)
758 WMDrawString(wmscr, d, scr->white, panel->normalfont,
759 ofx + i, ofy + j, text, tlen);
761 WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy, text, tlen);
764 WMReleasePixmap(pixmap);
765 /* I hope it is better to do not use cache / on my box it is fast nuff */
766 XFlush(dpy);
769 static void buttonCallback(void *self, void *clientData)
771 WMButton *bPtr = (WMButton *) self;
772 IconPanel *panel = (IconPanel *) clientData;
774 if (bPtr == panel->okButton) {
775 panel->done = True;
776 panel->result = True;
777 } else if (bPtr == panel->cancelButton) {
778 panel->done = True;
779 panel->result = False;
780 } else if (bPtr == panel->previewButton) {
781 /**** Previewer ****/
782 WMSetButtonEnabled(bPtr, False);
783 WMSetListUserDrawItemHeight(panel->iconList, 68);
784 WMSetListUserDrawProc(panel->iconList, drawIconProc);
785 WMRedisplayWidget(panel->iconList);
786 /* for draw proc to access screen/gc */
787 /*** end preview ***/
789 #if 0
790 else if (bPtr == panel->chooseButton) {
791 WMOpenPanel *op;
793 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
795 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
796 char *path;
797 path = WMGetFilePanelFile(op);
798 WMSetTextFieldText(panel->fileField, path);
799 setViewedImage(panel, path);
800 wfree(path);
802 WMDestroyFilePanel(op);
804 #endif
807 static void keyPressHandler(XEvent * event, void *data)
809 IconPanel *panel = (IconPanel *) data;
810 char buffer[32];
811 KeySym ksym;
812 int iidx;
813 int didx;
814 int item = 0;
815 WMList *list = NULL;
817 if (event->type == KeyRelease)
818 return;
820 buffer[0] = 0;
821 XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
823 iidx = WMGetListSelectedItemRow(panel->iconList);
824 didx = WMGetListSelectedItemRow(panel->dirList);
826 switch (ksym) {
827 case XK_Up:
828 if (iidx > 0)
829 item = iidx - 1;
830 else
831 item = iidx;
832 list = panel->iconList;
833 break;
834 case XK_Down:
835 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
836 item = iidx + 1;
837 else
838 item = iidx;
839 list = panel->iconList;
840 break;
841 case XK_Home:
842 item = 0;
843 list = panel->iconList;
844 break;
845 case XK_End:
846 item = WMGetListNumberOfRows(panel->iconList) - 1;
847 list = panel->iconList;
848 break;
849 case XK_Next:
850 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
851 item = didx + 1;
852 else
853 item = didx;
854 list = panel->dirList;
855 break;
856 case XK_Prior:
857 if (didx > 0)
858 item = didx - 1;
859 else
860 item = 0;
861 list = panel->dirList;
862 break;
863 case XK_Return:
864 WMPerformButtonClick(panel->okButton);
865 break;
866 case XK_Escape:
867 WMPerformButtonClick(panel->cancelButton);
868 break;
871 if (list) {
872 WMSelectListItem(list, item);
873 WMSetListPosition(list, item - 5);
874 listCallback(list, panel);
878 Bool wIconChooserDialog(WScreen * scr, char **file, char *instance, char *class)
880 WWindow *wwin;
881 Window parent;
882 IconPanel *panel;
883 WMColor *color;
884 WMFont *boldFont;
885 Bool result;
887 panel = wmalloc(sizeof(IconPanel));
888 memset(panel, 0, sizeof(IconPanel));
890 panel->scr = scr;
892 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
893 WMResizeWidget(panel->win, 450, 280);
895 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask | KeyReleaseMask, keyPressHandler, panel);
897 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
898 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
900 panel->dirLabel = WMCreateLabel(panel->win);
901 WMResizeWidget(panel->dirLabel, 200, 20);
902 WMMoveWidget(panel->dirLabel, 10, 7);
903 WMSetLabelText(panel->dirLabel, _("Directories"));
904 WMSetLabelFont(panel->dirLabel, boldFont);
905 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
907 WMSetLabelRelief(panel->dirLabel, WRSunken);
909 panel->iconLabel = WMCreateLabel(panel->win);
910 WMResizeWidget(panel->iconLabel, 140, 20);
911 WMMoveWidget(panel->iconLabel, 215, 7);
912 WMSetLabelText(panel->iconLabel, _("Icons"));
913 WMSetLabelFont(panel->iconLabel, boldFont);
914 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
916 WMReleaseFont(boldFont);
918 color = WMWhiteColor(scr->wmscreen);
919 WMSetLabelTextColor(panel->dirLabel, color);
920 WMSetLabelTextColor(panel->iconLabel, color);
921 WMReleaseColor(color);
923 color = WMDarkGrayColor(scr->wmscreen);
924 WMSetWidgetBackgroundColor(panel->iconLabel, color);
925 WMSetWidgetBackgroundColor(panel->dirLabel, color);
926 WMReleaseColor(color);
928 WMSetLabelRelief(panel->iconLabel, WRSunken);
930 panel->dirList = WMCreateList(panel->win);
931 WMResizeWidget(panel->dirList, 200, 170);
932 WMMoveWidget(panel->dirList, 10, 30);
933 WMSetListAction(panel->dirList, listCallback, panel);
935 panel->iconList = WMCreateList(panel->win);
936 WMResizeWidget(panel->iconList, 140, 170);
937 WMMoveWidget(panel->iconList, 215, 30);
938 WMSetListAction(panel->iconList, listCallback, panel);
940 WMHangData(panel->iconList, panel);
942 panel->previewButton = WMCreateCommandButton(panel->win);
943 WMResizeWidget(panel->previewButton, 75, 26);
944 WMMoveWidget(panel->previewButton, 365, 130);
945 WMSetButtonText(panel->previewButton, _("Preview"));
946 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
948 panel->iconView = WMCreateLabel(panel->win);
949 WMResizeWidget(panel->iconView, 75, 75);
950 WMMoveWidget(panel->iconView, 365, 40);
951 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
952 WMSetLabelRelief(panel->iconView, WRSunken);
953 WMSetLabelTextAlignment(panel->iconView, WACenter);
955 panel->fileLabel = WMCreateLabel(panel->win);
956 WMResizeWidget(panel->fileLabel, 80, 20);
957 WMMoveWidget(panel->fileLabel, 10, 210);
958 WMSetLabelText(panel->fileLabel, _("File Name:"));
960 panel->fileField = WMCreateTextField(panel->win);
961 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
962 WMResizeWidget(panel->fileField, 345, 20);
963 WMMoveWidget(panel->fileField, 95, 210);
964 WMSetTextFieldEditable(panel->fileField, False);
966 panel->okButton = WMCreateCommandButton(panel->win);
967 WMResizeWidget(panel->okButton, 80, 26);
968 WMMoveWidget(panel->okButton, 360, 240);
969 WMSetButtonText(panel->okButton, _("OK"));
970 WMSetButtonEnabled(panel->okButton, False);
971 WMSetButtonAction(panel->okButton, buttonCallback, panel);
973 panel->cancelButton = WMCreateCommandButton(panel->win);
974 WMResizeWidget(panel->cancelButton, 80, 26);
975 WMMoveWidget(panel->cancelButton, 270, 240);
976 WMSetButtonText(panel->cancelButton, _("Cancel"));
977 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
978 #if 0
979 panel->chooseButton = WMCreateCommandButton(panel->win);
980 WMResizeWidget(panel->chooseButton, 110, 26);
981 WMMoveWidget(panel->chooseButton, 150, 240);
982 WMSetButtonText(panel->chooseButton, _("Choose File"));
983 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
984 #endif
985 WMRealizeWidget(panel->win);
986 WMMapSubwidgets(panel->win);
988 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
990 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
993 char *tmp;
994 int len = (instance ? strlen(instance) : 0)
995 + (class ? strlen(class) : 0) + 32;
996 WMPoint center;
998 tmp = wmalloc(len);
1000 if (tmp && (instance || class))
1001 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
1002 else
1003 strcpy(tmp, _("Icon Chooser"));
1005 center = getCenter(scr, 450, 280);
1007 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x, center.y, 450, 280);
1008 wfree(tmp);
1011 /* put icon paths in the list */
1012 listIconPaths(panel->dirList);
1014 WMMapWidget(panel->win);
1016 wWindowMap(wwin);
1018 while (!panel->done) {
1019 XEvent event;
1021 WMNextEvent(dpy, &event);
1022 WMHandleEvent(&event);
1025 if (panel->result) {
1026 char *defaultPath, *wantedPath;
1028 /* check if the file the user selected is not the one that
1029 * would be loaded by default with the current search path */
1030 *file = WMGetListSelectedItem(panel->iconList)->text;
1031 if (**file == 0) {
1032 wfree(*file);
1033 *file = NULL;
1034 } else {
1035 defaultPath = FindImage(wPreferences.icon_path, *file);
1036 wantedPath = WMGetTextFieldText(panel->fileField);
1037 /* if the file is not the default, use full path */
1038 if (strcmp(wantedPath, defaultPath) != 0) {
1039 *file = wantedPath;
1040 } else {
1041 *file = wstrdup(*file);
1042 wfree(wantedPath);
1044 wfree(defaultPath);
1046 } else {
1047 *file = NULL;
1050 result = panel->result;
1052 WMReleaseFont(panel->normalfont);
1054 WMUnmapWidget(panel->win);
1056 WMDestroyWidget(panel->win);
1058 wUnmanageWindow(wwin, False, False);
1060 wfree(panel);
1062 XDestroyWindow(dpy, parent);
1064 return result;
1068 ***********************************************************************
1069 * Info Panel
1070 ***********************************************************************
1073 typedef struct {
1074 WScreen *scr;
1075 WWindow *wwin;
1076 WMWindow *win;
1077 WMLabel *logoL;
1078 WMLabel *name1L;
1079 WMFrame *lineF;
1080 WMLabel *name2L;
1081 WMLabel *versionL;
1082 WMLabel *infoL;
1083 WMLabel *copyrL;
1084 } InfoPanel;
1086 #define COPYRIGHT_TEXT \
1087 "Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
1088 "Copyright \xc2\xa9 1998-2006 Dan Pascu"
1090 static InfoPanel *thePanel = NULL;
1092 static void destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
1094 WMUnmapWidget(thePanel);
1095 wUnmanageWindow(thePanel->wwin, False, False);
1096 WMDestroyWidget(thePanel->win);
1097 wfree(thePanel);
1098 thePanel = NULL;
1101 void wShowInfoPanel(WScreen * scr)
1103 InfoPanel *panel;
1104 WMPixmap *logo;
1105 WMFont *font;
1106 char *strbuf = NULL;
1107 char buffer[256];
1108 char *name;
1109 Window parent;
1110 WWindow *wwin;
1111 char **strl;
1112 int i, width = 50, sepHeight;
1113 char *visuals[] = {
1114 "StaticGray",
1115 "GrayScale",
1116 "StaticColor",
1117 "PseudoColor",
1118 "TrueColor",
1119 "DirectColor"
1122 if (thePanel) {
1123 if (thePanel->scr == scr) {
1124 wRaiseFrame(thePanel->wwin->frame->core);
1125 wSetFocusTo(scr, thePanel->wwin);
1127 return;
1130 panel = wmalloc(sizeof(InfoPanel));
1131 memset(panel, 0, sizeof(InfoPanel));
1133 panel->scr = scr;
1135 panel->win = WMCreateWindow(scr->wmscreen, "info");
1136 WMResizeWidget(panel->win, 390, 230);
1138 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
1139 if (!logo) {
1140 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1142 if (logo) {
1143 panel->logoL = WMCreateLabel(panel->win);
1144 WMResizeWidget(panel->logoL, 64, 64);
1145 WMMoveWidget(panel->logoL, 30, 20);
1146 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1147 WMSetLabelImage(panel->logoL, logo);
1148 WMReleasePixmap(logo);
1151 sepHeight = 3;
1152 panel->name1L = WMCreateLabel(panel->win);
1153 WMResizeWidget(panel->name1L, 240, 30 + 2);
1154 WMMoveWidget(panel->name1L, 100, 30 - 2 - sepHeight);
1156 name = "Lucida Sans,Comic Sans MS,URW Gothic L,Trebuchet MS" ":italic:pixelsize=28:antialias=true";
1157 font = WMCreateFont(scr->wmscreen, name);
1158 strbuf = "Window Maker";
1159 if (font) {
1160 width = WMWidthOfString(font, strbuf, strlen(strbuf));
1161 WMSetLabelFont(panel->name1L, font);
1162 WMReleaseFont(font);
1164 WMSetLabelTextAlignment(panel->name1L, WACenter);
1165 WMSetLabelText(panel->name1L, strbuf);
1167 panel->lineF = WMCreateFrame(panel->win);
1168 WMResizeWidget(panel->lineF, width, sepHeight);
1169 WMMoveWidget(panel->lineF, 100 + (240 - width) / 2, 60 - sepHeight);
1170 WMSetFrameRelief(panel->lineF, WRSimple);
1171 WMSetWidgetBackgroundColor(panel->lineF, scr->black);
1173 panel->name2L = WMCreateLabel(panel->win);
1174 WMResizeWidget(panel->name2L, 240, 24);
1175 WMMoveWidget(panel->name2L, 100, 60);
1176 name = "URW Gothic L,Nimbus Sans L:pixelsize=16:antialias=true";
1177 font = WMCreateFont(scr->wmscreen, name);
1178 if (font) {
1179 WMSetLabelFont(panel->name2L, font);
1180 WMReleaseFont(font);
1181 font = NULL;
1183 WMSetLabelTextAlignment(panel->name2L, WACenter);
1184 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1186 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1187 panel->versionL = WMCreateLabel(panel->win);
1188 WMResizeWidget(panel->versionL, 310, 16);
1189 WMMoveWidget(panel->versionL, 30, 95);
1190 WMSetLabelTextAlignment(panel->versionL, WARight);
1191 WMSetLabelText(panel->versionL, buffer);
1192 WMSetLabelWraps(panel->versionL, False);
1194 panel->copyrL = WMCreateLabel(panel->win);
1195 WMResizeWidget(panel->copyrL, 360, 40);
1196 WMMoveWidget(panel->copyrL, 15, 185);
1197 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1198 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1199 font = WMSystemFontOfSize(scr->wmscreen, 11);
1200 if (font) {
1201 WMSetLabelFont(panel->copyrL, font);
1202 WMReleaseFont(font);
1203 font = NULL;
1206 strbuf = NULL;
1207 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1208 (unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
1210 strbuf = wstrappend(strbuf, buffer);
1212 switch (scr->w_depth) {
1213 case 15:
1214 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1215 break;
1216 case 16:
1217 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1218 break;
1219 case 24:
1220 case 32:
1221 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1222 break;
1223 default:
1224 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1 << scr->w_depth);
1225 strbuf = wstrappend(strbuf, buffer);
1226 break;
1229 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1231 struct mallinfo ma = mallinfo();
1232 snprintf(buffer, sizeof(buffer),
1233 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1234 (ma.arena + ma.hblkhd) / 1024, (ma.uordblks + ma.hblkhd) / 1024);
1236 strbuf = wstrappend(strbuf, buffer);
1238 #endif
1240 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1241 strl = RSupportedFileFormats();
1242 for (i = 0; strl[i] != NULL; i++) {
1243 strbuf = wstrappend(strbuf, strl[i]);
1244 strbuf = wstrappend(strbuf, " ");
1247 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1249 char *list[9];
1250 char buf[80];
1251 int j = 0;
1253 list[j++] = "WMSPEC";
1254 #ifdef MWM_HINTS
1255 list[j++] = "MWM";
1256 #endif
1258 buf[0] = 0;
1259 for (i = 0; i < j; i++) {
1260 if (i > 0) {
1261 if (i == j - 1)
1262 strcat(buf, _(" and "));
1263 else
1264 strcat(buf, ", ");
1266 strcat(buf, list[i]);
1268 strbuf = wstrappend(strbuf, buf);
1271 #ifdef XINERAMA
1272 strbuf = wstrappend(strbuf, _("\n"));
1273 #ifdef SOLARIS_XINERAMA
1274 strbuf = wstrappend(strbuf, _("Solaris "));
1275 #endif
1276 strbuf = wstrappend(strbuf, _("Xinerama: "));
1278 char tmp[128];
1279 snprintf(tmp, sizeof(tmp) - 1, "%d heads found.", scr->xine_info.count);
1280 strbuf = wstrappend(strbuf, tmp);
1282 #endif
1284 panel->infoL = WMCreateLabel(panel->win);
1285 WMResizeWidget(panel->infoL, 350, 75);
1286 WMMoveWidget(panel->infoL, 15, 115);
1287 WMSetLabelText(panel->infoL, strbuf);
1288 font = WMSystemFontOfSize(scr->wmscreen, 11);
1289 if (font) {
1290 WMSetLabelFont(panel->infoL, font);
1291 WMReleaseFont(font);
1292 font = NULL;
1294 wfree(strbuf);
1296 WMRealizeWidget(panel->win);
1297 WMMapSubwidgets(panel->win);
1299 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1301 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1303 WMMapWidget(panel->win);
1306 WMPoint center = getCenter(scr, 382, 230);
1308 wwin = wManageInternalWindow(scr, parent, None, _("Info"), center.x, center.y, 382, 230);
1311 WSETUFLAG(wwin, no_closable, 0);
1312 WSETUFLAG(wwin, no_close_button, 0);
1313 #ifdef XKB_BUTTON_HINT
1314 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1315 #endif
1316 wWindowUpdateButtonImages(wwin);
1317 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1318 wwin->frame->on_click_right = destroyInfoPanel;
1320 wWindowMap(wwin);
1322 panel->wwin = wwin;
1323 thePanel = panel;
1327 ***********************************************************************
1328 * Legal Panel
1329 ***********************************************************************
1332 typedef struct {
1333 WScreen *scr;
1335 WWindow *wwin;
1337 WMWindow *win;
1339 WMLabel *licenseL;
1340 } LegalPanel;
1342 static LegalPanel *legalPanel = NULL;
1344 static void destroyLegalPanel(WCoreWindow * foo, void *data, XEvent * event)
1346 WMUnmapWidget(legalPanel->win);
1348 WMDestroyWidget(legalPanel->win);
1350 wUnmanageWindow(legalPanel->wwin, False, False);
1352 wfree(legalPanel);
1354 legalPanel = NULL;
1357 void wShowLegalPanel(WScreen * scr)
1359 LegalPanel *panel;
1360 Window parent;
1361 WWindow *wwin;
1363 if (legalPanel) {
1364 if (legalPanel->scr == scr) {
1365 wRaiseFrame(legalPanel->wwin->frame->core);
1366 wSetFocusTo(scr, legalPanel->wwin);
1368 return;
1371 panel = wmalloc(sizeof(LegalPanel));
1373 panel->scr = scr;
1375 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1376 WMResizeWidget(panel->win, 420, 250);
1378 panel->licenseL = WMCreateLabel(panel->win);
1379 WMSetLabelWraps(panel->licenseL, True);
1380 WMResizeWidget(panel->licenseL, 400, 230);
1381 WMMoveWidget(panel->licenseL, 10, 10);
1382 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1383 WMSetLabelText(panel->licenseL,
1384 _(" Window Maker is free software; you can redistribute it and/or\n"
1385 "modify it under the terms of the GNU General Public License as\n"
1386 "published by the Free Software Foundation; either version 2 of the\n"
1387 "License, or (at your option) any later version.\n\n"
1388 " Window Maker is distributed in the hope that it will be useful,\n"
1389 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1390 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1391 "See the GNU General Public License for more details.\n\n"
1392 " You should have received a copy of the GNU General Public\n"
1393 "License along with this program; if not, write to the Free Software\n"
1394 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n"
1395 "02110-1301 USA."));
1396 WMSetLabelRelief(panel->licenseL, WRGroove);
1398 WMRealizeWidget(panel->win);
1399 WMMapSubwidgets(panel->win);
1401 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1403 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1406 WMPoint center = getCenter(scr, 420, 250);
1408 wwin = wManageInternalWindow(scr, parent, None, _("Legal"), center.x, center.y, 420, 250);
1411 WSETUFLAG(wwin, no_closable, 0);
1412 WSETUFLAG(wwin, no_close_button, 0);
1413 wWindowUpdateButtonImages(wwin);
1414 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1415 #ifdef XKB_BUTTON_HINT
1416 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1417 #endif
1418 wwin->frame->on_click_right = destroyLegalPanel;
1420 panel->wwin = wwin;
1422 WMMapWidget(panel->win);
1424 wWindowMap(wwin);
1426 legalPanel = panel;
1430 ***********************************************************************
1431 * Crashing Dialog Panel
1432 ***********************************************************************
1435 extern WDDomain *WDWindowAttributes;
1437 typedef struct _CrashPanel {
1438 WMWindow *win; /* main window */
1440 WMLabel *iconL; /* application icon */
1441 WMLabel *nameL; /* title of panel */
1443 WMFrame *sepF; /* separator frame */
1445 WMLabel *noteL; /* Title of note */
1446 WMLabel *note2L; /* body of note with what happened */
1448 WMFrame *whatF; /* "what to do next" frame */
1449 WMPopUpButton *whatP; /* action selection popup button */
1451 WMButton *okB; /* ok button */
1453 Bool done; /* if finished with this dialog */
1454 int action; /* what to do after */
1456 KeyCode retKey;
1458 } CrashPanel;
1460 static void handleKeyPress(XEvent * event, void *clientData)
1462 CrashPanel *panel = (CrashPanel *) clientData;
1464 if (event->xkey.keycode == panel->retKey) {
1465 WMPerformButtonClick(panel->okB);
1469 static void okButtonCallback(void *self, void *clientData)
1471 CrashPanel *panel = (CrashPanel *) clientData;
1473 panel->done = True;
1476 static void setCrashAction(void *self, void *clientData)
1478 WMPopUpButton *pop = (WMPopUpButton *) self;
1479 CrashPanel *panel = (CrashPanel *) clientData;
1481 panel->action = WMGetPopUpButtonSelectedItem(pop);
1484 /* Make this read the logo from a compiled in pixmap -Dan */
1485 static WMPixmap *getWindowMakerIconImage(WMScreen * scr)
1487 WMPropList *dict, *key, *option, *value = NULL;
1488 WMPixmap *pix = NULL;
1489 char *path;
1491 if (!WDWindowAttributes || !WDWindowAttributes->dictionary)
1492 return NULL;
1494 WMPLSetCaseSensitive(True);
1496 key = WMCreatePLString("Logo.WMPanel");
1497 option = WMCreatePLString("Icon");
1499 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1501 if (dict) {
1502 value = WMGetFromPLDictionary(dict, option);
1505 WMReleasePropList(key);
1506 WMReleasePropList(option);
1508 WMPLSetCaseSensitive(False);
1510 if (value && WMIsPLString(value)) {
1511 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1513 if (path) {
1514 RColor gray;
1516 gray.red = 0xae;
1517 gray.green = 0xaa;
1518 gray.blue = 0xae;
1519 gray.alpha = 0;
1521 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1522 wfree(path);
1526 return pix;
1529 #define PWIDTH 295
1530 #define PHEIGHT 345
1532 int wShowCrashingDialogPanel(int whatSig)
1534 CrashPanel *panel;
1535 WMScreen *scr;
1536 WMFont *font;
1537 WMPixmap *logo;
1538 int screen_no, scr_width, scr_height;
1539 int action;
1540 char buf[256];
1542 panel = wmalloc(sizeof(CrashPanel));
1543 memset(panel, 0, sizeof(CrashPanel));
1545 screen_no = DefaultScreen(dpy);
1546 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1547 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1549 scr = WMCreateScreen(dpy, screen_no);
1550 if (!scr) {
1551 werror(_("cannot open connection for crashing dialog panel. Aborting."));
1552 return WMAbort;
1555 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1557 panel->win = WMCreateWindow(scr, "crashingDialog");
1558 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1559 WMMoveWidget(panel->win, (scr_width - PWIDTH) / 2, (scr_height - PHEIGHT) / 2);
1561 logo = getWindowMakerIconImage(scr);
1562 if (logo) {
1563 panel->iconL = WMCreateLabel(panel->win);
1564 WMResizeWidget(panel->iconL, 64, 64);
1565 WMMoveWidget(panel->iconL, 10, 10);
1566 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1567 WMSetLabelImage(panel->iconL, logo);
1570 panel->nameL = WMCreateLabel(panel->win);
1571 WMResizeWidget(panel->nameL, 200, 30);
1572 WMMoveWidget(panel->nameL, 80, 25);
1573 WMSetLabelTextAlignment(panel->nameL, WALeft);
1574 font = WMBoldSystemFontOfSize(scr, 24);
1575 WMSetLabelFont(panel->nameL, font);
1576 WMReleaseFont(font);
1577 WMSetLabelText(panel->nameL, _("Fatal error"));
1579 panel->sepF = WMCreateFrame(panel->win);
1580 WMResizeWidget(panel->sepF, PWIDTH + 4, 2);
1581 WMMoveWidget(panel->sepF, -2, 80);
1583 panel->noteL = WMCreateLabel(panel->win);
1584 WMResizeWidget(panel->noteL, PWIDTH - 20, 40);
1585 WMMoveWidget(panel->noteL, 10, 90);
1586 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1587 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1588 WMSetLabelText(panel->noteL, buf);
1590 panel->note2L = WMCreateLabel(panel->win);
1591 WMResizeWidget(panel->note2L, PWIDTH - 20, 100);
1592 WMMoveWidget(panel->note2L, 10, 130);
1593 WMSetLabelTextAlignment(panel->note2L, WALeft);
1594 WMSetLabelText(panel->note2L,
1595 _(" This fatal error occured probably due to a bug."
1596 " Please fill the included BUGFORM and " "report it to bugs@windowmaker.info."));
1597 WMSetLabelWraps(panel->note2L, True);
1599 panel->whatF = WMCreateFrame(panel->win);
1600 WMResizeWidget(panel->whatF, PWIDTH - 20, 50);
1601 WMMoveWidget(panel->whatF, 10, 240);
1602 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1604 panel->whatP = WMCreatePopUpButton(panel->whatF);
1605 WMResizeWidget(panel->whatP, PWIDTH - 20 - 70, 20);
1606 WMMoveWidget(panel->whatP, 35, 20);
1607 WMSetPopUpButtonPullsDown(panel->whatP, False);
1608 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1609 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1610 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1611 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1612 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1613 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1614 panel->action = WMRestart;
1616 WMMapSubwidgets(panel->whatF);
1618 panel->okB = WMCreateCommandButton(panel->win);
1619 WMResizeWidget(panel->okB, 80, 26);
1620 WMMoveWidget(panel->okB, 205, 309);
1621 WMSetButtonText(panel->okB, _("OK"));
1622 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1623 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1624 WMSetButtonImagePosition(panel->okB, WIPRight);
1625 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1627 panel->done = 0;
1629 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask, handleKeyPress, panel);
1631 WMRealizeWidget(panel->win);
1632 WMMapSubwidgets(panel->win);
1634 WMMapWidget(panel->win);
1636 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1638 while (!panel->done) {
1639 XEvent event;
1641 WMNextEvent(dpy, &event);
1642 WMHandleEvent(&event);
1645 action = panel->action;
1647 WMUnmapWidget(panel->win);
1648 WMDestroyWidget(panel->win);
1649 wfree(panel);
1651 return action;
1654 /*****************************************************************************
1655 * About GNUstep Panel
1656 *****************************************************************************/
1658 static void
1659 drawGNUstepLogo(Display * dpy, Drawable d, int width, int height,
1660 unsigned long blackPixel, unsigned long whitePixel)
1662 GC gc;
1663 XGCValues gcv;
1664 XRectangle rects[3];
1666 gcv.foreground = blackPixel;
1667 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1669 XFillArc(dpy, d, gc, width / 45, height / 45,
1670 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
1672 rects[0].x = 0;
1673 rects[0].y = 37 * height / 45;
1674 rects[0].width = width / 3;
1675 rects[0].height = height - rects[0].y;
1677 rects[1].x = rects[0].width;
1678 rects[1].y = height / 2;
1679 rects[1].width = width - 2 * width / 3;
1680 rects[1].height = height - rects[1].y;
1682 rects[2].x = 2 * width / 3;
1683 rects[2].y = height - 37 * height / 45;
1684 rects[2].width = width / 3;
1685 rects[2].height = height - rects[2].y;
1687 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1688 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1690 XSetForeground(dpy, gc, whitePixel);
1691 XFillArc(dpy, d, gc, width / 45, height / 45,
1692 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
1694 XFreeGC(dpy, gc);
1697 typedef struct {
1698 WScreen *scr;
1700 WWindow *wwin;
1702 WMWindow *win;
1704 WMLabel *gstepL;
1705 WMLabel *textL;
1706 } GNUstepPanel;
1708 static GNUstepPanel *gnustepPanel = NULL;
1710 static void destroyGNUstepPanel(WCoreWindow * foo, void *data, XEvent * event)
1712 WMUnmapWidget(gnustepPanel->win);
1714 WMDestroyWidget(gnustepPanel->win);
1716 wUnmanageWindow(gnustepPanel->wwin, False, False);
1718 wfree(gnustepPanel);
1720 gnustepPanel = NULL;
1723 void wShowGNUstepPanel(WScreen * scr)
1725 GNUstepPanel *panel;
1726 Window parent;
1727 WWindow *wwin;
1728 WMPixmap *pixmap;
1729 WMColor *color;
1731 if (gnustepPanel) {
1732 if (gnustepPanel->scr == scr) {
1733 wRaiseFrame(gnustepPanel->wwin->frame->core);
1734 wSetFocusTo(scr, gnustepPanel->wwin);
1736 return;
1739 panel = wmalloc(sizeof(GNUstepPanel));
1741 panel->scr = scr;
1743 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1744 WMResizeWidget(panel->win, 325, 205);
1746 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130, WMScreenDepth(scr->wmscreen), True);
1748 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1750 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130, WMColorPixel(color), scr->white_pixel);
1752 WMReleaseColor(color);
1754 XSetForeground(dpy, scr->mono_gc, 0);
1755 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0, 130, 130);
1756 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1758 panel->gstepL = WMCreateLabel(panel->win);
1759 WMResizeWidget(panel->gstepL, 285, 64);
1760 WMMoveWidget(panel->gstepL, 20, 0);
1761 WMSetLabelTextAlignment(panel->gstepL, WARight);
1762 WMSetLabelText(panel->gstepL, "GNUstep");
1764 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1766 WMSetLabelFont(panel->gstepL, font);
1767 WMReleaseFont(font);
1770 panel->textL = WMCreateLabel(panel->win);
1771 WMResizeWidget(panel->textL, 305, 140);
1772 WMMoveWidget(panel->textL, 10, 50);
1773 WMSetLabelTextAlignment(panel->textL, WARight);
1774 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1775 WMSetLabelText(panel->textL,
1776 _("Window Maker is part of the GNUstep project.\n"
1777 "The GNUstep project aims to create a free\n"
1778 "implementation of the OpenStep(tm) specification\n"
1779 "which is a object-oriented framework for\n"
1780 "creating advanced graphical, multi-platform\n"
1781 "applications. Additionally, a development and\n"
1782 "user desktop environment will be created on top\n"
1783 "of the framework. For more information about\n"
1784 "GNUstep, please visit: www.gnustep.org"));
1785 WMSetLabelImage(panel->textL, pixmap);
1787 WMReleasePixmap(pixmap);
1789 WMRealizeWidget(panel->win);
1790 WMMapSubwidgets(panel->win);
1792 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1794 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1797 WMPoint center = getCenter(scr, 325, 200);
1799 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"), center.x, center.y, 325, 200);
1802 WSETUFLAG(wwin, no_closable, 0);
1803 WSETUFLAG(wwin, no_close_button, 0);
1804 wWindowUpdateButtonImages(wwin);
1805 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1806 #ifdef XKB_BUTTON_HINT
1807 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1808 #endif
1809 wwin->frame->on_click_right = destroyGNUstepPanel;
1811 panel->wwin = wwin;
1813 WMMapWidget(panel->win);
1815 wWindowMap(wwin);
1817 gnustepPanel = panel;