wrlib: Fix typo in macro containing ImageMagick version
[wmaker-crm.git] / src / dialog.c
blob2d5a6d7bf0eb1e0227ce97855a0d364f97d43627
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
7 * Copyright (c) 2014 Window Maker Team
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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>
38 #include <errno.h>
40 #ifdef HAVE_MALLOC_H
41 #include <malloc.h>
42 #endif
44 #include <signal.h>
45 #ifdef __FreeBSD__
46 #include <sys/signal.h>
47 #endif
49 #ifndef PATH_MAX
50 #define PATH_MAX DEFAULT_PATH_MAX
51 #endif
53 #include "WindowMaker.h"
54 #include "GNUstep.h"
55 #include "screen.h"
56 #include "window.h"
57 #include "dialog.h"
58 #include "misc.h"
59 #include "stacking.h"
60 #include "framewin.h"
61 #include "window.h"
62 #include "actions.h"
63 #include "xinerama.h"
66 static WMPoint getCenter(WScreen * scr, int width, int height)
68 return wGetPointToCenterRectInHead(scr, wGetHeadForPointerLocation(scr), width, height);
71 int wMessageDialog(WScreen *scr, const char *title, const char *message, const char *defBtn, const char *altBtn, const char *othBtn)
73 WMAlertPanel *panel;
74 Window parent;
75 WWindow *wwin;
76 int result;
77 WMPoint center;
78 int pwidth, pheight;
80 panel = WMCreateScaledAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
81 pwidth = WMWidgetWidth(panel->win);
82 pheight = WMWidgetHeight(panel->win);
84 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, pwidth, pheight, 0, 0, 0);
86 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
88 center = getCenter(scr, pwidth, pheight);
89 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, pwidth, pheight);
90 wwin->client_leader = WMWidgetXID(panel->win);
92 WMMapWidget(panel->win);
94 wWindowMap(wwin);
96 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
98 result = panel->result;
100 WMUnmapWidget(panel->win);
102 wUnmanageWindow(wwin, False, False);
104 WMDestroyAlertPanel(panel);
106 XDestroyWindow(dpy, parent);
108 return result;
111 static void toggleSaveSession(WMWidget *w, void *data)
113 /* Parameter not used, but tell the compiler that it is ok */
114 (void) data;
116 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
119 int wExitDialog(WScreen *scr, const char *title, const char *message, const char *defBtn, const char *altBtn, const char *othBtn)
121 WMAlertPanel *panel;
122 WMButton *saveSessionBtn;
123 Window parent;
124 WWindow *wwin;
125 WMPoint center;
126 int result;
127 int pwidth, pheight;
129 panel = WMCreateScaledAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
130 pwidth = WMWidgetWidth(panel->win);
131 pheight = WMWidgetHeight(panel->win);
133 /* add save session button */
134 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
135 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
136 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn), False, True, pwidth / 2, 0, 0);
137 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
138 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
139 WMRealizeWidget(saveSessionBtn);
140 WMMapWidget(saveSessionBtn);
142 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, pwidth, pheight, 0, 0, 0);
144 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
146 center = getCenter(scr, pwidth, pheight);
147 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, pwidth, pheight);
149 wwin->client_leader = WMWidgetXID(panel->win);
151 WMMapWidget(panel->win);
153 wWindowMap(wwin);
155 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
157 result = panel->result;
159 WMUnmapWidget(panel->win);
161 wUnmanageWindow(wwin, False, False);
163 WMDestroyAlertPanel(panel);
165 XDestroyWindow(dpy, parent);
167 return result;
170 typedef struct _WMInputPanelWithHistory {
171 WMInputPanel *panel;
172 WMArray *history;
173 int histpos;
174 char *prefix;
175 char *suffix;
176 char *rest;
177 WMArray *variants;
178 int varpos;
179 } WMInputPanelWithHistory;
181 static char *HistoryFileName(const char *name)
183 char *filename = NULL;
185 filename = wstrdup(wusergnusteppath());
186 filename = wstrappend(filename, "/.AppInfo/WindowMaker/History");
187 if (name && strlen(name)) {
188 filename = wstrappend(filename, ".");
189 filename = wstrappend(filename, name);
191 return filename;
194 static int strmatch(const void *str1, const void *str2)
196 return !strcmp((const char *)str1, (const char *)str2);
199 static WMArray *LoadHistory(const char *filename, int max)
201 WMPropList *plhistory;
202 WMPropList *plitem;
203 WMArray *history;
204 int i, num;
205 char *str;
207 history = WMCreateArrayWithDestructor(1, wfree);
208 WMAddToArray(history, wstrdup(""));
210 plhistory = WMReadPropListFromFile(filename);
212 if (plhistory) {
213 if (WMIsPLArray(plhistory)) {
214 num = WMGetPropListItemCount(plhistory);
216 for (i = 0; i < num; ++i) {
217 plitem = WMGetFromPLArray(plhistory, i);
218 if (WMIsPLString(plitem)) {
219 str = WMGetFromPLString(plitem);
220 if (WMFindInArray(history, strmatch, str) == WANotFound) {
222 * The string here is duplicated because it will be freed
223 * automatically when the array is deleted. This is not really
224 * great because it is already an allocated string,
225 * unfortunately we cannot re-use it because it will be freed
226 * when we discard the PL (and we don't want to waste the PL's
227 * memory either)
229 WMAddToArray(history, wstrdup(str));
230 if (--max <= 0)
231 break;
236 WMReleasePropList(plhistory);
239 return history;
242 static void SaveHistory(WMArray * history, const char *filename)
244 int i;
245 WMPropList *plhistory;
247 plhistory = WMCreatePLArray(NULL);
249 for (i = 0; i < WMGetArrayItemCount(history); ++i)
250 WMAddToPLArray(plhistory, WMCreatePLString(WMGetFromArray(history, i)));
252 WMWritePropListToFile(plhistory, filename);
253 WMReleasePropList(plhistory);
256 static int pstrcmp(const char **str1, const char **str2)
258 return strcmp(*str1, *str2);
261 static void
262 ScanFiles(const char *dir, const char *prefix, unsigned acceptmask, unsigned declinemask, WMArray * result)
264 int prefixlen;
265 DIR *d;
266 struct dirent *de;
267 struct stat sb;
268 char *fullfilename, *suffix;
270 prefixlen = strlen(prefix);
271 d = opendir(dir);
272 if (d != NULL) {
273 while ((de = readdir(d)) != NULL) {
274 if (strlen(de->d_name) > prefixlen &&
275 !strncmp(prefix, de->d_name, prefixlen) &&
276 strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..")) {
277 fullfilename = wstrconcat((char *)dir, "/");
278 fullfilename = wstrappend(fullfilename, de->d_name);
280 if (stat(fullfilename, &sb) == 0 &&
281 (sb.st_mode & acceptmask) &&
282 !(sb.st_mode & declinemask) &&
283 WMFindInArray(result, (WMMatchDataProc *) strmatch,
284 de->d_name + prefixlen) == WANotFound) {
285 suffix = wstrdup(de->d_name + prefixlen);
286 if (sb.st_mode & S_IFDIR)
287 suffix = wstrappend(suffix, "/");
288 WMAddToArray(result, suffix);
290 wfree(fullfilename);
293 closedir(d);
297 static WMArray *GenerateVariants(const char *complete)
299 Bool firstWord = True;
300 WMArray *variants = NULL;
301 char *pos = NULL, *path = NULL, *tmp = NULL, *dir = NULL, *prefix = NULL;
303 variants = WMCreateArrayWithDestructor(0, wfree);
305 while (*complete == ' ')
306 ++complete;
308 pos = strrchr(complete, ' ');
309 if (pos != NULL) {
310 complete = pos + 1;
311 firstWord = False;
314 pos = strrchr(complete, '/');
315 if (pos != NULL) {
316 tmp = wstrndup((char *)complete, pos - complete + 1);
317 if (*tmp == '~' && *(tmp + 1) == '/' && getenv("HOME")) {
318 dir = wstrdup(getenv("HOME"));
319 dir = wstrappend(dir, tmp + 1);
320 wfree(tmp);
321 } else {
322 dir = tmp;
324 prefix = wstrdup(pos + 1);
325 ScanFiles(dir, prefix, (unsigned)-1, 0, variants);
326 wfree(dir);
327 wfree(prefix);
328 } else if (*complete == '~') {
329 WMAddToArray(variants, wstrdup("/"));
330 } else if (firstWord) {
331 path = getenv("PATH");
332 while (path) {
333 pos = strchr(path, ':');
334 if (pos) {
335 tmp = wstrndup(path, pos - path);
336 path = pos + 1;
337 } else if (*path != '\0') {
338 tmp = wstrdup(path);
339 path = NULL;
340 } else
341 break;
342 ScanFiles(tmp, complete, S_IXOTH | S_IXGRP | S_IXUSR, S_IFDIR, variants);
343 wfree(tmp);
347 WMSortArray(variants, (WMCompareDataProc *) pstrcmp);
348 return variants;
351 static void handleHistoryKeyPress(XEvent * event, void *clientData)
353 char *text;
354 unsigned pos;
355 WMInputPanelWithHistory *p = (WMInputPanelWithHistory *) clientData;
356 KeySym ksym;
358 ksym = XLookupKeysym(&event->xkey, 0);
360 switch (ksym) {
361 case XK_Up:
362 if (p->histpos < WMGetArrayItemCount(p->history) - 1) {
363 if (p->histpos == 0)
364 wfree(WMReplaceInArray(p->history, 0, WMGetTextFieldText(p->panel->text)));
365 p->histpos++;
366 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
368 break;
369 case XK_Down:
370 if (p->histpos > 0) {
371 p->histpos--;
372 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
374 break;
375 case XK_Tab:
376 if (!p->variants) {
377 text = WMGetTextFieldText(p->panel->text);
378 pos = WMGetTextFieldCursorPosition(p->panel->text);
379 p->prefix = wstrndup(text, pos);
380 p->suffix = wstrdup(text + pos);
381 wfree(text);
382 p->variants = GenerateVariants(p->prefix);
383 p->varpos = 0;
384 if (!p->variants) {
385 wfree(p->prefix);
386 wfree(p->suffix);
387 p->prefix = NULL;
388 p->suffix = NULL;
391 if (p->variants && p->prefix && p->suffix) {
392 p->varpos++;
393 if (p->varpos > WMGetArrayItemCount(p->variants))
394 p->varpos = 0;
395 if (p->varpos > 0)
396 text = wstrconcat(p->prefix, WMGetFromArray(p->variants, p->varpos - 1));
397 else
398 text = wstrdup(p->prefix);
399 pos = strlen(text);
400 text = wstrappend(text, p->suffix);
401 WMSetTextFieldText(p->panel->text, text);
402 WMSetTextFieldCursorPosition(p->panel->text, pos);
403 wfree(text);
405 break;
407 if (ksym != XK_Tab) {
408 if (p->prefix) {
409 wfree(p->prefix);
410 p->prefix = NULL;
412 if (p->suffix) {
413 wfree(p->suffix);
414 p->suffix = NULL;
416 if (p->variants) {
417 WMFreeArray(p->variants);
418 p->variants = NULL;
423 int wAdvancedInputDialog(WScreen *scr, const char *title, const char *message, const char *name, char **text)
425 WWindow *wwin;
426 Window parent;
427 char *result;
428 WMPoint center;
429 WMInputPanelWithHistory *p;
430 char *filename;
431 int pwidth, pheight;
433 filename = HistoryFileName(name);
434 p = wmalloc(sizeof(WMInputPanelWithHistory));
435 p->panel = WMCreateScaledInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
436 p->history = LoadHistory(filename, wPreferences.history_lines);
437 p->histpos = 0;
438 p->prefix = NULL;
439 p->suffix = NULL;
440 p->rest = NULL;
441 p->variants = NULL;
442 p->varpos = 0;
443 WMCreateEventHandler(WMWidgetView(p->panel->text), KeyPressMask, handleHistoryKeyPress, p);
444 pwidth = WMWidgetWidth(p->panel->win);
445 pheight = WMWidgetHeight(p->panel->win);
447 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, pwidth, pheight, 0, 0, 0);
448 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
450 XReparentWindow(dpy, WMWidgetXID(p->panel->win), parent, 0, 0);
452 center = getCenter(scr, pwidth, pheight);
453 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, pwidth, pheight);
455 wwin->client_leader = WMWidgetXID(p->panel->win);
457 WMMapWidget(p->panel->win);
459 wWindowMap(wwin);
461 WMRunModalLoop(WMWidgetScreen(p->panel->win), WMWidgetView(p->panel->win));
463 if (p->panel->result == WAPRDefault) {
464 result = WMGetTextFieldText(p->panel->text);
465 wfree(WMReplaceInArray(p->history, 0, wstrdup(result)));
466 SaveHistory(p->history, filename);
467 } else
468 result = NULL;
470 wUnmanageWindow(wwin, False, False);
472 WMDestroyInputPanel(p->panel);
473 WMFreeArray(p->history);
474 wfree(p);
475 wfree(filename);
477 XDestroyWindow(dpy, parent);
479 if (result == NULL)
480 return False;
481 else {
482 if (*text)
483 wfree(*text);
484 *text = result;
486 return True;
490 int wInputDialog(WScreen *scr, const char *title, const char *message, char **text)
492 WWindow *wwin;
493 Window parent;
494 WMInputPanel *panel;
495 char *result;
496 WMPoint center;
497 int pwidth, pheight;
499 panel = WMCreateScaledInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
500 pwidth = WMWidgetWidth(panel->win);
501 pheight = WMWidgetHeight(panel->win);
503 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, pwidth, pheight, 0, 0, 0);
504 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
506 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
508 center = getCenter(scr, pwidth, pheight);
509 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, pwidth, pheight);
511 wwin->client_leader = WMWidgetXID(panel->win);
513 WMMapWidget(panel->win);
515 wWindowMap(wwin);
517 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
519 if (panel->result == WAPRDefault)
520 result = WMGetTextFieldText(panel->text);
521 else
522 result = NULL;
524 wUnmanageWindow(wwin, False, False);
526 WMDestroyInputPanel(panel);
528 XDestroyWindow(dpy, parent);
530 if (result == NULL)
531 return False;
532 else {
533 if (*text)
534 wfree(*text);
535 *text = result;
537 return True;
542 *****************************************************************
543 * Icon Selection Panel
544 *****************************************************************
547 typedef struct IconPanel {
549 WScreen *scr;
551 WMWindow *win;
553 WMLabel *dirLabel;
554 WMLabel *iconLabel;
556 WMList *dirList;
557 WMList *iconList;
558 WMFont *normalfont;
560 WMButton *previewButton;
562 WMLabel *iconView;
564 WMLabel *fileLabel;
565 WMTextField *fileField;
567 WMButton *okButton;
568 WMButton *cancelButton;
569 #if 0
570 WMButton *chooseButton;
571 #endif
572 short done;
573 short result;
574 short preview;
575 } IconPanel;
577 static void listPixmaps(WScreen *scr, WMList *lPtr, const char *path)
579 struct dirent *dentry;
580 DIR *dir;
581 char pbuf[PATH_MAX + 16];
582 char *apath;
583 IconPanel *panel = WMGetHangedData(lPtr);
585 panel->preview = False;
587 apath = wexpandpath(path);
588 dir = opendir(apath);
590 if (!dir) {
591 wfree(apath);
592 snprintf(pbuf, sizeof(pbuf),
593 _("Could not open directory \"%s\":\n%s"),
594 path, strerror(errno));
595 wMessageDialog(scr, _("Error"), pbuf, _("OK"), NULL, NULL);
596 return;
599 /* list contents in the column */
600 while ((dentry = readdir(dir))) {
601 struct stat statb;
603 if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") == 0)
604 continue;
606 if (wstrlcpy(pbuf, apath, sizeof(pbuf)) >= sizeof(pbuf) ||
607 wstrlcat(pbuf, "/", sizeof(pbuf)) >= sizeof(pbuf) ||
608 wstrlcat(pbuf, dentry->d_name, sizeof(pbuf)) >= sizeof(pbuf)) {
609 wwarning(_("full path for file \"%s\" in \"%s\" is longer than %d bytes, skipped"),
610 dentry->d_name, path, (int) (sizeof(pbuf) - 1) );
611 continue;
614 if (stat(pbuf, &statb) < 0)
615 continue;
617 if (statb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)
618 && statb.st_mode & (S_IFREG | S_IFLNK)) {
619 WMAddListItem(lPtr, dentry->d_name);
622 WMSortListItems(lPtr);
624 closedir(dir);
625 wfree(apath);
626 panel->preview = True;
629 static void setViewedImage(IconPanel *panel, const char *file)
631 WMPixmap *pixmap;
632 RColor color;
633 int iwidth, iheight;
635 color.red = 0xae;
636 color.green = 0xaa;
637 color.blue = 0xae;
638 color.alpha = 0;
639 iwidth = WMWidgetWidth(panel->iconView);
640 iheight = WMWidgetHeight(panel->iconView);
641 pixmap = WMCreateScaledBlendedPixmapFromFile(WMWidgetScreen(panel->win), file, &color, iwidth, iheight);
643 if (!pixmap) {
644 WMSetButtonEnabled(panel->okButton, False);
646 WMSetLabelText(panel->iconView, _("Could not load image file "));
648 WMSetLabelImage(panel->iconView, NULL);
649 } else {
650 WMSetButtonEnabled(panel->okButton, True);
652 WMSetLabelText(panel->iconView, NULL);
653 WMSetLabelImage(panel->iconView, pixmap);
654 WMReleasePixmap(pixmap);
658 static void listCallback(void *self, void *data)
660 WMList *lPtr = (WMList *) self;
661 IconPanel *panel = (IconPanel *) data;
662 char *path;
664 if (lPtr == panel->dirList) {
665 WMListItem *item = WMGetListSelectedItem(lPtr);
667 if (item == NULL)
668 return;
669 path = item->text;
671 WMSetTextFieldText(panel->fileField, path);
673 WMSetLabelImage(panel->iconView, NULL);
675 WMSetButtonEnabled(panel->okButton, False);
677 WMClearList(panel->iconList);
678 listPixmaps(panel->scr, panel->iconList, path);
679 } else {
680 char *tmp, *iconFile;
681 WMListItem *item = WMGetListSelectedItem(panel->dirList);
683 if (item == NULL)
684 return;
685 path = item->text;
687 item = WMGetListSelectedItem(panel->iconList);
688 if (item == NULL)
689 return;
690 iconFile = item->text;
692 tmp = wexpandpath(path);
693 path = wmalloc(strlen(tmp) + strlen(iconFile) + 4);
694 strcpy(path, tmp);
695 strcat(path, "/");
696 strcat(path, iconFile);
697 wfree(tmp);
698 WMSetTextFieldText(panel->fileField, path);
699 setViewedImage(panel, path);
700 wfree(path);
704 static void listIconPaths(WMList * lPtr)
706 char *paths;
707 char *path;
709 paths = wstrdup(wPreferences.icon_path);
711 path = strtok(paths, ":");
713 do {
714 char *tmp;
716 tmp = wexpandpath(path);
717 /* do not sort, because the order implies the order of
718 * directories searched */
719 if (access(tmp, X_OK) == 0)
720 WMAddListItem(lPtr, path);
721 wfree(tmp);
722 } while ((path = strtok(NULL, ":")) != NULL);
724 wfree(paths);
727 static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
729 IconPanel *panel = WMGetHangedData(lPtr);
730 WScreen *scr = panel->scr;
731 GC gc = scr->draw_gc;
732 GC copygc = scr->copy_gc;
733 char *file, *dirfile;
734 WMPixmap *pixmap;
735 WMColor *back;
736 WMSize size;
737 WMScreen *wmscr = WMWidgetScreen(panel->win);
738 RColor color;
739 int x, y, width, height, len;
741 /* Parameter not used, but tell the compiler that it is ok */
742 (void) index;
744 if (!panel->preview)
745 return;
747 x = rect->pos.x;
748 y = rect->pos.y;
749 width = rect->size.width;
750 height = rect->size.height;
752 back = (state & WLDSSelected) ? scr->white : scr->gray;
754 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
755 len = strlen(dirfile) + strlen(text) + 4;
756 file = wmalloc(len);
757 snprintf(file, len, "%s/%s", dirfile, text);
758 wfree(dirfile);
760 color.red = WMRedComponentOfColor(back) >> 8;
761 color.green = WMGreenComponentOfColor(back) >> 8;
762 color.blue = WMBlueComponentOfColor(back) >> 8;
763 color.alpha = WMGetColorAlpha(back) >> 8;
765 pixmap = WMCreateScaledBlendedPixmapFromFile(wmscr, file, &color, width - 2, height - 2);
766 wfree(file);
768 if (!pixmap) {
769 /*WMRemoveListItem(lPtr, index); */
770 return;
773 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
775 XSetClipMask(dpy, gc, None);
776 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54); */
777 XDrawLine(dpy, d, WMColorGC(scr->white), x, y + height - 1, x + width, y + height - 1);
779 size = WMGetPixmapSize(pixmap);
781 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
782 XSetClipOrigin(dpy, copygc, x + (width - size.width) / 2, y + 2);
783 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
784 size.width > 100 ? 100 : size.width, size.height > 64 ? 64 : size.height,
785 x + (width - size.width) / 2, y + 2);
788 int i, j;
789 int fheight = WMFontHeight(panel->normalfont);
790 int tlen = strlen(text);
791 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
792 int ofx, ofy;
794 ofx = x + (width - twidth) / 2;
795 ofy = y + 64 - fheight;
797 for (i = -1; i < 2; i++)
798 for (j = -1; j < 2; j++)
799 WMDrawString(wmscr, d, scr->white, panel->normalfont,
800 ofx + i, ofy + j, text, tlen);
802 WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy, text, tlen);
805 WMReleasePixmap(pixmap);
806 /* I hope it is better to do not use cache / on my box it is fast nuff */
807 XFlush(dpy);
810 static void buttonCallback(void *self, void *clientData)
812 WMButton *bPtr = (WMButton *) self;
813 IconPanel *panel = (IconPanel *) clientData;
815 if (bPtr == panel->okButton) {
816 panel->done = True;
817 panel->result = True;
818 } else if (bPtr == panel->cancelButton) {
819 panel->done = True;
820 panel->result = False;
821 } else if (bPtr == panel->previewButton) {
822 /**** Previewer ****/
823 WMSetButtonEnabled(bPtr, False);
824 WMSetListUserDrawItemHeight(panel->iconList, 68);
825 WMSetListUserDrawProc(panel->iconList, drawIconProc);
826 WMRedisplayWidget(panel->iconList);
827 /* for draw proc to access screen/gc */
828 /*** end preview ***/
830 #if 0
831 else if (bPtr == panel->chooseButton) {
832 WMOpenPanel *op;
834 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
836 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
837 char *path;
838 path = WMGetFilePanelFile(op);
839 WMSetTextFieldText(panel->fileField, path);
840 setViewedImage(panel, path);
841 wfree(path);
843 WMDestroyFilePanel(op);
845 #endif
848 static void keyPressHandler(XEvent * event, void *data)
850 IconPanel *panel = (IconPanel *) data;
851 char buffer[32];
852 KeySym ksym;
853 int iidx;
854 int didx;
855 int item = 0;
856 WMList *list = NULL;
858 if (event->type == KeyRelease)
859 return;
861 buffer[0] = 0;
862 XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
864 iidx = WMGetListSelectedItemRow(panel->iconList);
865 didx = WMGetListSelectedItemRow(panel->dirList);
867 switch (ksym) {
868 case XK_Up:
869 if (iidx > 0)
870 item = iidx - 1;
871 else
872 item = iidx;
873 list = panel->iconList;
874 break;
875 case XK_Down:
876 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
877 item = iidx + 1;
878 else
879 item = iidx;
880 list = panel->iconList;
881 break;
882 case XK_Home:
883 item = 0;
884 list = panel->iconList;
885 break;
886 case XK_End:
887 item = WMGetListNumberOfRows(panel->iconList) - 1;
888 list = panel->iconList;
889 break;
890 case XK_Next:
891 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
892 item = didx + 1;
893 else
894 item = didx;
895 list = panel->dirList;
896 break;
897 case XK_Prior:
898 if (didx > 0)
899 item = didx - 1;
900 else
901 item = 0;
902 list = panel->dirList;
903 break;
904 case XK_Return:
905 WMPerformButtonClick(panel->okButton);
906 break;
907 case XK_Escape:
908 WMPerformButtonClick(panel->cancelButton);
909 break;
912 if (list) {
913 WMSelectListItem(list, item);
914 WMSetListPosition(list, item - 5);
915 listCallback(list, panel);
919 Bool wIconChooserDialog(WScreen *scr, char **file, const char *instance, const char *class)
921 WWindow *wwin;
922 Window parent;
923 IconPanel *panel;
924 WMColor *color;
925 WMFont *boldFont;
926 Bool result;
927 int wmScaleWidth, wmScaleHeight;
928 int pwidth, pheight;
930 panel = wmalloc(sizeof(IconPanel));
932 panel->scr = scr;
934 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
935 WMGetScaleBaseFromSystemFont(scr->wmscreen, &wmScaleWidth, &wmScaleHeight);
936 pwidth = WMScaleX(450);
937 pheight = WMScaleY(280);
938 WMResizeWidget(panel->win, pwidth, pheight);
940 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask | KeyReleaseMask, keyPressHandler, panel);
942 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, WMScaleY(12));
943 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), WMScaleY(12));
945 panel->dirLabel = WMCreateLabel(panel->win);
946 WMResizeWidget(panel->dirLabel, WMScaleX(200), WMScaleY(20));
947 WMMoveWidget(panel->dirLabel, WMScaleX(10), WMScaleY(7));
948 WMSetLabelText(panel->dirLabel, _("Directories"));
949 WMSetLabelFont(panel->dirLabel, boldFont);
950 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
952 WMSetLabelRelief(panel->dirLabel, WRSunken);
954 panel->iconLabel = WMCreateLabel(panel->win);
955 WMResizeWidget(panel->iconLabel, WMScaleX(140), WMScaleY(20));
956 WMMoveWidget(panel->iconLabel, WMScaleX(215), WMScaleY(7));
957 WMSetLabelText(panel->iconLabel, _("Icons"));
958 WMSetLabelFont(panel->iconLabel, boldFont);
959 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
961 WMReleaseFont(boldFont);
963 color = WMWhiteColor(scr->wmscreen);
964 WMSetLabelTextColor(panel->dirLabel, color);
965 WMSetLabelTextColor(panel->iconLabel, color);
966 WMReleaseColor(color);
968 color = WMDarkGrayColor(scr->wmscreen);
969 WMSetWidgetBackgroundColor(panel->iconLabel, color);
970 WMSetWidgetBackgroundColor(panel->dirLabel, color);
971 WMReleaseColor(color);
973 WMSetLabelRelief(panel->iconLabel, WRSunken);
975 panel->dirList = WMCreateList(panel->win);
976 WMResizeWidget(panel->dirList, WMScaleX(200), WMScaleY(170));
977 WMMoveWidget(panel->dirList, WMScaleX(10), WMScaleY(30));
978 WMSetListAction(panel->dirList, listCallback, panel);
980 panel->iconList = WMCreateList(panel->win);
981 WMResizeWidget(panel->iconList, WMScaleX(140), WMScaleY(170));
982 WMMoveWidget(panel->iconList, WMScaleX(215), WMScaleY(30));
983 WMSetListAction(panel->iconList, listCallback, panel);
985 WMHangData(panel->iconList, panel);
987 panel->previewButton = WMCreateCommandButton(panel->win);
988 WMResizeWidget(panel->previewButton, WMScaleX(75), WMScaleY(26));
989 WMMoveWidget(panel->previewButton, WMScaleX(365), WMScaleY(130));
990 WMSetButtonText(panel->previewButton, _("Preview"));
991 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
993 panel->iconView = WMCreateLabel(panel->win);
994 WMResizeWidget(panel->iconView, WMScaleX(75), WMScaleY(75));
995 WMMoveWidget(panel->iconView, WMScaleX(365), WMScaleY(40));
996 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
997 WMSetLabelRelief(panel->iconView, WRSunken);
998 WMSetLabelTextAlignment(panel->iconView, WACenter);
1000 panel->fileLabel = WMCreateLabel(panel->win);
1001 WMResizeWidget(panel->fileLabel, WMScaleX(80), WMScaleY(20));
1002 WMMoveWidget(panel->fileLabel, WMScaleX(10), WMScaleY(210));
1003 WMSetLabelText(panel->fileLabel, _("File Name:"));
1005 panel->fileField = WMCreateTextField(panel->win);
1006 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
1007 WMResizeWidget(panel->fileField, WMScaleX(345), WMScaleY(20));
1008 WMMoveWidget(panel->fileField, WMScaleX(95), WMScaleY(210));
1009 WMSetTextFieldEditable(panel->fileField, False);
1011 panel->okButton = WMCreateCommandButton(panel->win);
1012 WMResizeWidget(panel->okButton, WMScaleX(80), WMScaleY(26));
1013 WMMoveWidget(panel->okButton, WMScaleX(360), WMScaleY(242));
1014 WMSetButtonText(panel->okButton, _("OK"));
1015 WMSetButtonEnabled(panel->okButton, False);
1016 WMSetButtonAction(panel->okButton, buttonCallback, panel);
1018 panel->cancelButton = WMCreateCommandButton(panel->win);
1019 WMResizeWidget(panel->cancelButton, WMScaleX(80), WMScaleY(26));
1020 WMMoveWidget(panel->cancelButton, WMScaleX(270), WMScaleY(242));
1021 WMSetButtonText(panel->cancelButton, _("Cancel"));
1022 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
1023 #if 0
1024 panel->chooseButton = WMCreateCommandButton(panel->win);
1025 WMResizeWidget(panel->chooseButton, WMScaleX(110), WMScaleY(26));
1026 WMMoveWidget(panel->chooseButton, WMScaleX(150), WMScaleY(242));
1027 WMSetButtonText(panel->chooseButton, _("Choose File"));
1028 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
1029 #endif
1030 WMRealizeWidget(panel->win);
1031 WMMapSubwidgets(panel->win);
1033 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, pwidth, pheight, 0, 0, 0);
1035 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1038 static const char *prefix = NULL;
1039 char *title;
1040 int len;
1041 WMPoint center;
1043 if (prefix == NULL)
1044 prefix = _("Icon Chooser");
1046 len = strlen(prefix)
1047 + 2 // " ["
1048 + (instance ? strlen(instance) : 0)
1049 + 1 // "."
1050 + (class ? strlen(class) : 0)
1051 + 1 // "]"
1052 + 1; // final NUL
1054 title = wmalloc(len);
1055 strcpy(title, prefix);
1057 if (instance || class) {
1058 strcat(title, " [");
1059 if (instance != NULL)
1060 strcat(title, instance);
1061 if (instance && class)
1062 strcat(title, ".");
1063 if (class != NULL)
1064 strcat(title, class);
1065 strcat(title, "]");
1068 center = getCenter(scr, pwidth, pheight);
1070 wwin = wManageInternalWindow(scr, parent, None, title, center.x, center.y, pwidth, pheight);
1071 wfree(title);
1074 /* put icon paths in the list */
1075 listIconPaths(panel->dirList);
1077 WMMapWidget(panel->win);
1079 wWindowMap(wwin);
1081 while (!panel->done) {
1082 XEvent event;
1084 WMNextEvent(dpy, &event);
1085 WMHandleEvent(&event);
1088 if (panel->result) {
1089 char *defaultPath, *wantedPath;
1091 /* check if the file the user selected is not the one that
1092 * would be loaded by default with the current search path */
1093 *file = WMGetListSelectedItem(panel->iconList)->text;
1094 if (**file == 0) {
1095 wfree(*file);
1096 *file = NULL;
1097 } else {
1098 defaultPath = FindImage(wPreferences.icon_path, *file);
1099 wantedPath = WMGetTextFieldText(panel->fileField);
1100 /* if the file is not the default, use full path */
1101 if (strcmp(wantedPath, defaultPath) != 0) {
1102 *file = wantedPath;
1103 } else {
1104 *file = wstrdup(*file);
1105 wfree(wantedPath);
1107 wfree(defaultPath);
1109 } else {
1110 *file = NULL;
1113 result = panel->result;
1115 WMReleaseFont(panel->normalfont);
1117 WMUnmapWidget(panel->win);
1119 WMDestroyWidget(panel->win);
1121 wUnmanageWindow(wwin, False, False);
1123 wfree(panel);
1125 XDestroyWindow(dpy, parent);
1127 return result;
1131 ***********************************************************************
1132 * Info Panel
1133 ***********************************************************************
1136 typedef struct {
1137 WScreen *scr;
1138 WWindow *wwin;
1139 WMWindow *win;
1140 WMLabel *logoL;
1141 WMLabel *name1L;
1142 WMFrame *lineF;
1143 WMLabel *name2L;
1144 WMLabel *versionL;
1145 WMLabel *infoL;
1146 WMLabel *copyrL;
1147 } InfoPanel;
1149 #define COPYRIGHT_TEXT \
1150 "Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
1151 "Copyright \xc2\xa9 1998-2006 Dan Pascu\n"\
1152 "Copyright \xc2\xa9 2013-2020 Window Maker Developers Team"
1154 static InfoPanel *infoPanel = NULL;
1156 static void destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
1158 /* Parameter not used, but tell the compiler that it is ok */
1159 (void) foo;
1160 (void) data;
1161 (void) event;
1163 WMUnmapWidget(infoPanel);
1164 wUnmanageWindow(infoPanel->wwin, False, False);
1165 WMDestroyWidget(infoPanel->win);
1166 wfree(infoPanel);
1167 infoPanel = NULL;
1170 void wShowInfoPanel(WScreen *scr)
1172 InfoPanel *panel;
1173 WMPixmap *logo;
1174 WMFont *font;
1175 char *strbuf = NULL;
1176 const char *separator;
1177 char buffer[256];
1178 Window parent;
1179 WWindow *wwin;
1180 WMPoint center;
1181 char **strl;
1182 int i, width = 50, sepHeight;
1183 char *visuals[] = {
1184 "StaticGray",
1185 "GrayScale",
1186 "StaticColor",
1187 "PseudoColor",
1188 "TrueColor",
1189 "DirectColor"
1191 int wmScaleWidth, wmScaleHeight;
1192 int pwidth, pheight;
1194 if (infoPanel) {
1195 if (infoPanel->scr == scr) {
1196 wRaiseFrame(infoPanel->wwin->frame->core);
1197 wSetFocusTo(scr, infoPanel->wwin);
1199 return;
1202 panel = wmalloc(sizeof(InfoPanel));
1204 panel->scr = scr;
1206 panel->win = WMCreateWindow(scr->wmscreen, "info");
1207 WMGetScaleBaseFromSystemFont(scr->wmscreen, &wmScaleWidth, &wmScaleHeight);
1208 pwidth = WMScaleX(382);
1209 pheight = WMScaleY(250);
1210 WMResizeWidget(panel->win, pwidth, pheight);
1212 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
1213 if (!logo) {
1214 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1216 if (logo) {
1217 panel->logoL = WMCreateLabel(panel->win);
1218 WMResizeWidget(panel->logoL, WMScaleX(64), WMScaleY(64));
1219 WMMoveWidget(panel->logoL, WMScaleX(30), WMScaleY(20));
1220 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1221 WMSetLabelImage(panel->logoL, logo);
1222 WMReleasePixmap(logo);
1225 sepHeight = WMScaleY(3);
1226 panel->name1L = WMCreateLabel(panel->win);
1227 WMResizeWidget(panel->name1L, WMScaleX(240), WMScaleY(30) + WMScaleY(2));
1228 WMMoveWidget(panel->name1L, WMScaleX(100), WMScaleY(30) - WMScaleY(2) - sepHeight);
1230 snprintf(buffer,
1231 sizeof(buffer),
1232 "Lucida Sans,Comic Sans MS,URW Gothic L,Trebuchet MS:italic:pixelsize=%d:antialias=true",
1233 WMScaleY(24));
1234 font = WMCreateFont(scr->wmscreen, buffer);
1235 strbuf = "Window Maker";
1236 if (font) {
1237 width = WMWidthOfString(font, strbuf, strlen(strbuf));
1238 WMSetLabelFont(panel->name1L, font);
1239 WMReleaseFont(font);
1241 WMSetLabelTextAlignment(panel->name1L, WACenter);
1242 WMSetLabelText(panel->name1L, strbuf);
1244 panel->lineF = WMCreateFrame(panel->win);
1245 WMResizeWidget(panel->lineF, width, sepHeight);
1246 WMMoveWidget(panel->lineF, WMScaleX(100) + (WMScaleX(240) - width) / 2, WMScaleY(60) - sepHeight);
1247 WMSetFrameRelief(panel->lineF, WRSimple);
1248 WMSetWidgetBackgroundColor(panel->lineF, scr->black);
1250 panel->name2L = WMCreateLabel(panel->win);
1251 WMResizeWidget(panel->name2L, WMScaleX(240), WMScaleY(24));
1252 WMMoveWidget(panel->name2L, WMScaleX(100), WMScaleY(60));
1253 snprintf(buffer, sizeof(buffer), "URW Gothic L,Nimbus Sans L:pixelsize=%d:antialias=true", WMScaleY(16));
1254 font = WMCreateFont(scr->wmscreen, buffer);
1255 if (font) {
1256 WMSetLabelFont(panel->name2L, font);
1257 WMReleaseFont(font);
1258 font = NULL;
1260 WMSetLabelTextAlignment(panel->name2L, WACenter);
1261 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1263 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1264 panel->versionL = WMCreateLabel(panel->win);
1265 WMResizeWidget(panel->versionL, WMScaleX(310), WMScaleY(16));
1266 WMMoveWidget(panel->versionL, WMScaleX(30), WMScaleY(95));
1267 WMSetLabelTextAlignment(panel->versionL, WARight);
1268 WMSetLabelText(panel->versionL, buffer);
1269 WMSetLabelWraps(panel->versionL, False);
1271 panel->copyrL = WMCreateLabel(panel->win);
1272 WMResizeWidget(panel->copyrL, WMScaleX(360), WMScaleY(60));
1273 WMMoveWidget(panel->copyrL, WMScaleX(15), WMScaleY(190));
1274 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1275 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1276 font = WMSystemFontOfSize(scr->wmscreen, WMScaleY(11));
1277 if (font) {
1278 WMSetLabelFont(panel->copyrL, font);
1279 WMReleaseFont(font);
1280 font = NULL;
1283 strbuf = NULL;
1284 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1285 (unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
1287 strbuf = wstrappend(strbuf, buffer);
1289 switch (scr->w_depth) {
1290 case 15:
1291 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1292 break;
1293 case 16:
1294 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1295 break;
1296 case 24:
1297 case 32:
1298 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1299 break;
1300 default:
1301 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1 << scr->w_depth);
1302 strbuf = wstrappend(strbuf, buffer);
1303 break;
1306 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1308 struct mallinfo ma = mallinfo();
1309 snprintf(buffer, sizeof(buffer),
1310 #ifdef DEBUG
1311 _("Total memory allocated: %i kB (in use: %i kB, %d free chunks).\n"),
1312 #else
1313 _("Total memory allocated: %i kB (in use: %i kB).\n"),
1314 #endif
1315 (ma.arena + ma.hblkhd) / 1024,
1316 (ma.uordblks + ma.hblkhd) / 1024
1317 #ifdef DEBUG
1319 * This information is representative of the memory
1320 * fragmentation. In ideal case it should be 1, but
1321 * that is never possible
1323 , ma.ordblks
1324 #endif
1327 strbuf = wstrappend(strbuf, buffer);
1329 #endif
1331 strbuf = wstrappend(strbuf, _("Image formats: "));
1332 strl = RSupportedFileFormats();
1333 separator = NULL;
1334 for (i = 0; strl[i] != NULL; i++) {
1335 if (separator != NULL)
1336 strbuf = wstrappend(strbuf, separator);
1337 strbuf = wstrappend(strbuf, strl[i]);
1338 separator = ", ";
1341 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1342 strbuf = wstrappend(strbuf, "WMSPEC");
1344 #ifdef USE_MWM_HINTS
1345 strbuf = wstrappend(strbuf, ", MWM");
1346 #endif
1348 #ifdef USE_DOCK_XDND
1349 strbuf = wstrappend(strbuf, ", XDnD");
1350 #endif
1352 #ifdef USE_MAGICK
1353 strbuf = wstrappend(strbuf, ", ImageMagick");
1354 #endif
1356 #ifdef USE_XINERAMA
1357 strbuf = wstrappend(strbuf, _("\n"));
1358 #ifdef SOLARIS_XINERAMA
1359 strbuf = wstrappend(strbuf, _("Solaris "));
1360 #endif
1361 strbuf = wstrappend(strbuf, _("Xinerama: "));
1363 char tmp[128];
1364 snprintf(tmp, sizeof(tmp) - 1, _("%d head(s) found."), scr->xine_info.count);
1365 strbuf = wstrappend(strbuf, tmp);
1367 #endif
1369 #ifdef USE_RANDR
1370 strbuf = wstrappend(strbuf, _("\n"));
1371 strbuf = wstrappend(strbuf, "RandR: ");
1372 if (w_global.xext.randr.supported)
1373 strbuf = wstrappend(strbuf, _("supported"));
1374 else
1375 strbuf = wstrappend(strbuf, _("unsupported"));
1376 strbuf = wstrappend(strbuf, ".");
1377 #endif
1379 panel->infoL = WMCreateLabel(panel->win);
1380 WMResizeWidget(panel->infoL, WMScaleX(350), WMScaleY(80));
1381 WMMoveWidget(panel->infoL, WMScaleX(15), WMScaleY(115));
1382 WMSetLabelText(panel->infoL, strbuf);
1383 font = WMSystemFontOfSize(scr->wmscreen, WMScaleY(11));
1384 if (font) {
1385 WMSetLabelFont(panel->infoL, font);
1386 WMReleaseFont(font);
1387 font = NULL;
1389 wfree(strbuf);
1391 WMRealizeWidget(panel->win);
1392 WMMapSubwidgets(panel->win);
1394 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, pwidth, pheight, 0, 0, 0);
1396 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1398 WMMapWidget(panel->win);
1400 center = getCenter(scr, pwidth, pheight);
1401 wwin = wManageInternalWindow(scr, parent, None, _("Info"), center.x, center.y, pwidth, pheight);
1403 WSETUFLAG(wwin, no_closable, 0);
1404 WSETUFLAG(wwin, no_close_button, 0);
1405 #ifdef XKB_BUTTON_HINT
1406 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1407 #endif
1408 wWindowUpdateButtonImages(wwin);
1409 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1410 wwin->frame->on_click_right = destroyInfoPanel;
1412 wWindowMap(wwin);
1414 panel->wwin = wwin;
1415 infoPanel = panel;
1419 ***********************************************************************
1420 * Legal Panel
1421 ***********************************************************************
1424 typedef struct {
1425 WScreen *scr;
1426 WWindow *wwin;
1427 WMWindow *win;
1428 WMFrame *frame;
1429 WMLabel *licenseL;
1430 } LegalPanel;
1432 static LegalPanel *legalPanel = NULL;
1434 static void destroyLegalPanel(WCoreWindow * foo, void *data, XEvent * event)
1436 /* Parameter not used, but tell the compiler that it is ok */
1437 (void) foo;
1438 (void) data;
1439 (void) event;
1441 WMUnmapWidget(legalPanel->win);
1442 WMDestroyWidget(legalPanel->win);
1443 wUnmanageWindow(legalPanel->wwin, False, False);
1444 wfree(legalPanel);
1445 legalPanel = NULL;
1448 void wShowLegalPanel(WScreen *scr)
1450 LegalPanel *panel;
1451 Window parent;
1452 WWindow *wwin;
1453 WMPoint center;
1454 int wmScaleWidth, wmScaleHeight;
1455 int pwidth, pheight;
1457 if (legalPanel) {
1458 if (legalPanel->scr == scr) {
1459 wRaiseFrame(legalPanel->wwin->frame->core);
1460 wSetFocusTo(scr, legalPanel->wwin);
1462 return;
1465 panel = wmalloc(sizeof(LegalPanel));
1466 panel->scr = scr;
1467 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1468 WMGetScaleBaseFromSystemFont(scr->wmscreen, &wmScaleWidth, &wmScaleHeight);
1469 pwidth = WMScaleX(440);
1470 pheight = WMScaleY(270);
1471 WMResizeWidget(panel->win, pwidth, pheight);
1473 panel->frame = WMCreateFrame(panel->win);
1474 WMResizeWidget(panel->frame, pwidth - (2 * WMScaleX(10)), pheight - (2 * WMScaleY(10)));
1475 WMMoveWidget(panel->frame, WMScaleX(10), WMScaleY(10));
1476 WMSetFrameTitle(panel->frame, NULL);
1478 panel->licenseL = WMCreateLabel(panel->frame);
1479 WMSetLabelWraps(panel->licenseL, True);
1480 WMResizeWidget(panel->licenseL, pwidth - (4 * WMScaleX(10)), pheight - (4 * WMScaleY(10)));
1481 WMMoveWidget(panel->licenseL, WMScaleX(8), WMScaleY(8));
1482 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1483 WMSetLabelText(panel->licenseL,
1484 _(" Window Maker is free software; you can redistribute it and/or "
1485 "modify it under the terms of the GNU General Public License as "
1486 "published by the Free Software Foundation; either version 2 of the "
1487 "License, or (at your option) any later version.\n\n"
1488 " Window Maker is distributed in the hope that it will be useful, "
1489 "but WITHOUT ANY WARRANTY; without even the implied warranty "
1490 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. "
1491 "See the GNU General Public License for more details.\n\n"
1492 " You should have received a copy of the GNU General Public "
1493 "License along with this program; if not, write to the Free Software "
1494 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA"
1495 "02110-1301 USA."));
1497 WMRealizeWidget(panel->win);
1498 WMMapSubwidgets(panel->win);
1499 WMMapSubwidgets(panel->frame);
1501 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, pwidth, pheight, 0, 0, 0);
1502 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1503 center = getCenter(scr, pwidth, pheight);
1504 wwin = wManageInternalWindow(scr, parent, None, _("Legal"), center.x, center.y, pwidth, pheight);
1506 WSETUFLAG(wwin, no_closable, 0);
1507 WSETUFLAG(wwin, no_close_button, 0);
1508 wWindowUpdateButtonImages(wwin);
1509 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1510 #ifdef XKB_BUTTON_HINT
1511 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1512 #endif
1513 wwin->frame->on_click_right = destroyLegalPanel;
1514 panel->wwin = wwin;
1516 WMMapWidget(panel->win);
1517 wWindowMap(wwin);
1518 legalPanel = panel;
1522 ***********************************************************************
1523 * Crashing Dialog Panel
1524 ***********************************************************************
1527 typedef struct _CrashPanel {
1528 WMWindow *win; /* main window */
1530 WMLabel *iconL; /* application icon */
1531 WMLabel *nameL; /* title of panel */
1533 WMFrame *sepF; /* separator frame */
1535 WMLabel *noteL; /* Title of note */
1536 WMLabel *note2L; /* body of note with what happened */
1538 WMFrame *whatF; /* "what to do next" frame */
1539 WMPopUpButton *whatP; /* action selection popup button */
1541 WMButton *okB; /* ok button */
1543 Bool done; /* if finished with this dialog */
1544 int action; /* what to do after */
1546 KeyCode retKey;
1548 } CrashPanel;
1550 static void handleKeyPress(XEvent * event, void *clientData)
1552 CrashPanel *panel = (CrashPanel *) clientData;
1554 if (event->xkey.keycode == panel->retKey) {
1555 WMPerformButtonClick(panel->okB);
1559 static void okButtonCallback(void *self, void *clientData)
1561 CrashPanel *panel = (CrashPanel *) clientData;
1563 /* Parameter not used, but tell the compiler that it is ok */
1564 (void) self;
1566 panel->done = True;
1569 static void setCrashAction(void *self, void *clientData)
1571 WMPopUpButton *pop = (WMPopUpButton *) self;
1572 CrashPanel *panel = (CrashPanel *) clientData;
1574 panel->action = WMGetPopUpButtonSelectedItem(pop);
1577 /* Make this read the logo from a compiled in pixmap -Dan */
1578 static WMPixmap *getWindowMakerIconImage(WMScreen *scr)
1580 WMPixmap *pix = NULL;
1581 char *path = NULL;
1583 /* Get the Logo icon, without the default icon */
1584 path = get_icon_filename("Logo", "WMPanel", NULL, False);
1586 if (path) {
1587 RColor gray;
1589 gray.red = 0xae;
1590 gray.green = 0xaa;
1591 gray.blue = 0xae;
1592 gray.alpha = 0;
1594 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1595 wfree(path);
1598 return pix;
1601 #define PWIDTH 295
1602 #define PHEIGHT 345
1604 int wShowCrashingDialogPanel(int whatSig)
1606 CrashPanel *panel;
1607 WMScreen *scr;
1608 WMFont *font;
1609 WMPixmap *logo;
1610 int screen_no, scr_width, scr_height;
1611 int action;
1612 char buf[256];
1614 screen_no = DefaultScreen(dpy);
1615 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1616 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1618 scr = WMCreateScreen(dpy, screen_no);
1619 if (!scr) {
1620 werror(_("cannot open connection for crashing dialog panel. Aborting."));
1621 return WMAbort;
1624 panel = wmalloc(sizeof(CrashPanel));
1626 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1628 panel->win = WMCreateWindow(scr, "crashingDialog");
1629 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1630 WMMoveWidget(panel->win, (scr_width - PWIDTH) / 2, (scr_height - PHEIGHT) / 2);
1632 logo = getWindowMakerIconImage(scr);
1633 if (logo) {
1634 panel->iconL = WMCreateLabel(panel->win);
1635 WMResizeWidget(panel->iconL, 64, 64);
1636 WMMoveWidget(panel->iconL, 10, 10);
1637 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1638 WMSetLabelImage(panel->iconL, logo);
1641 panel->nameL = WMCreateLabel(panel->win);
1642 WMResizeWidget(panel->nameL, 200, 30);
1643 WMMoveWidget(panel->nameL, 80, 25);
1644 WMSetLabelTextAlignment(panel->nameL, WALeft);
1645 font = WMBoldSystemFontOfSize(scr, 24);
1646 WMSetLabelFont(panel->nameL, font);
1647 WMReleaseFont(font);
1648 WMSetLabelText(panel->nameL, _("Fatal error"));
1650 panel->sepF = WMCreateFrame(panel->win);
1651 WMResizeWidget(panel->sepF, PWIDTH + 4, 2);
1652 WMMoveWidget(panel->sepF, -2, 80);
1654 panel->noteL = WMCreateLabel(panel->win);
1655 WMResizeWidget(panel->noteL, PWIDTH - 20, 40);
1656 WMMoveWidget(panel->noteL, 10, 90);
1657 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1658 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1659 WMSetLabelText(panel->noteL, buf);
1661 panel->note2L = WMCreateLabel(panel->win);
1662 WMResizeWidget(panel->note2L, PWIDTH - 20, 100);
1663 WMMoveWidget(panel->note2L, 10, 130);
1664 WMSetLabelTextAlignment(panel->note2L, WALeft);
1665 snprintf(buf, sizeof(buf), /* Comment for the PO file: the %s is an email address */
1666 _(" This fatal error occurred probably due to a bug."
1667 " Please fill the included BUGFORM and report it to %s."),
1668 PACKAGE_BUGREPORT);
1669 WMSetLabelText(panel->note2L, buf);
1670 WMSetLabelWraps(panel->note2L, True);
1672 panel->whatF = WMCreateFrame(panel->win);
1673 WMResizeWidget(panel->whatF, PWIDTH - 20, 50);
1674 WMMoveWidget(panel->whatF, 10, 240);
1675 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1677 panel->whatP = WMCreatePopUpButton(panel->whatF);
1678 WMResizeWidget(panel->whatP, PWIDTH - 20 - 70, 20);
1679 WMMoveWidget(panel->whatP, 35, 20);
1680 WMSetPopUpButtonPullsDown(panel->whatP, False);
1681 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1682 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1683 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1684 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1685 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1686 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1687 panel->action = WMRestart;
1689 WMMapSubwidgets(panel->whatF);
1691 panel->okB = WMCreateCommandButton(panel->win);
1692 WMResizeWidget(panel->okB, 80, 26);
1693 WMMoveWidget(panel->okB, 205, 309);
1694 WMSetButtonText(panel->okB, _("OK"));
1695 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1696 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1697 WMSetButtonImagePosition(panel->okB, WIPRight);
1698 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1700 panel->done = 0;
1702 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask, handleKeyPress, panel);
1704 WMRealizeWidget(panel->win);
1705 WMMapSubwidgets(panel->win);
1707 WMMapWidget(panel->win);
1709 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1711 while (!panel->done) {
1712 XEvent event;
1714 WMNextEvent(dpy, &event);
1715 WMHandleEvent(&event);
1718 action = panel->action;
1720 WMUnmapWidget(panel->win);
1721 WMDestroyWidget(panel->win);
1722 wfree(panel);
1724 return action;