swpanel: Start with the first window when all are minimized
[wmaker-crm.git] / src / dialog.c
blob2f3f7939f4954ec977baefee3f2c18cc4757c9be
1 /* dialog.c - dialog windows for internal use
3 * Window Maker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 1998-2003 Dan Pascu
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 * USA.
24 #include "wconfig.h"
26 #include <X11/Xlib.h>
27 #include <X11/Xutil.h>
28 #include <X11/keysym.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <unistd.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <dirent.h>
37 #include <limits.h>
39 #ifdef HAVE_MALLOC_H
40 #include <malloc.h>
41 #endif
43 #include <signal.h>
44 #ifdef __FreeBSD__
45 #include <sys/signal.h>
46 #endif
48 #ifndef PATH_MAX
49 #define PATH_MAX DEFAULT_PATH_MAX
50 #endif
52 #include "WindowMaker.h"
53 #include "GNUstep.h"
54 #include "screen.h"
55 #include "dialog.h"
56 #include "funcs.h"
57 #include "stacking.h"
58 #include "framewin.h"
59 #include "window.h"
60 #include "actions.h"
61 #include "defaults.h"
62 #include "xinerama.h"
64 extern WPreferences wPreferences;
66 static WMPoint getCenter(WScreen * scr, int width, int height)
68 return wGetPointToCenterRectInHead(scr, wGetHeadForPointerLocation(scr), width, height);
71 int wMessageDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
73 WMAlertPanel *panel;
74 Window parent;
75 WWindow *wwin;
76 int result;
77 WMPoint center;
79 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
81 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
83 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
85 center = getCenter(scr, 400, 180);
86 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
87 wwin->client_leader = WMWidgetXID(panel->win);
89 WMMapWidget(panel->win);
91 wWindowMap(wwin);
93 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
95 result = panel->result;
97 WMUnmapWidget(panel->win);
99 wUnmanageWindow(wwin, False, False);
101 WMDestroyAlertPanel(panel);
103 XDestroyWindow(dpy, parent);
105 return result;
108 void toggleSaveSession(WMWidget * w, void *data)
110 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
113 int wExitDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
115 WMAlertPanel *panel;
116 WMButton *saveSessionBtn;
117 Window parent;
118 WWindow *wwin;
119 WMPoint center;
120 int result;
122 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
124 /* add save session button */
125 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
126 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
127 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn), False, True, 200, 0, 0);
128 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
129 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
130 WMRealizeWidget(saveSessionBtn);
131 WMMapWidget(saveSessionBtn);
133 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
135 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
137 center = getCenter(scr, 400, 180);
138 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
140 wwin->client_leader = WMWidgetXID(panel->win);
142 WMMapWidget(panel->win);
144 wWindowMap(wwin);
146 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
148 result = panel->result;
150 WMUnmapWidget(panel->win);
152 wUnmanageWindow(wwin, False, False);
154 WMDestroyAlertPanel(panel);
156 XDestroyWindow(dpy, parent);
158 return result;
161 int wInputDialog(WScreen * scr, char *title, char *message, char **text)
163 WWindow *wwin;
164 Window parent;
165 WMInputPanel *panel;
166 char *result;
167 WMPoint center;
169 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
171 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
172 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
174 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
176 center = getCenter(scr, 320, 160);
177 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
179 wwin->client_leader = WMWidgetXID(panel->win);
181 WMMapWidget(panel->win);
183 wWindowMap(wwin);
185 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
187 if (panel->result == WAPRDefault)
188 result = WMGetTextFieldText(panel->text);
189 else
190 result = NULL;
192 wUnmanageWindow(wwin, False, False);
194 WMDestroyInputPanel(panel);
196 XDestroyWindow(dpy, parent);
198 if (result == NULL)
199 return False;
200 else {
201 if (*text)
202 wfree(*text);
203 *text = result;
205 return True;
210 *****************************************************************
211 * Icon Selection Panel
212 *****************************************************************
215 typedef struct IconPanel {
217 WScreen *scr;
219 WMWindow *win;
221 WMLabel *dirLabel;
222 WMLabel *iconLabel;
224 WMList *dirList;
225 WMList *iconList;
226 WMFont *normalfont;
228 WMButton *previewButton;
230 WMLabel *iconView;
232 WMLabel *fileLabel;
233 WMTextField *fileField;
235 WMButton *okButton;
236 WMButton *cancelButton;
237 #if 0
238 WMButton *chooseButton;
239 #endif
240 short done;
241 short result;
242 short preview;
243 } IconPanel;
245 static void listPixmaps(WScreen * scr, WMList * lPtr, char *path)
247 struct dirent *dentry;
248 DIR *dir;
249 char pbuf[PATH_MAX + 16];
250 char *apath;
251 IconPanel *panel = WMGetHangedData(lPtr);
253 panel->preview = False;
255 apath = wexpandpath(path);
256 dir = opendir(apath);
258 if (!dir) {
259 char *msg;
260 char *tmp;
261 tmp = _("Could not open directory ");
262 msg = wmalloc(strlen(tmp) + strlen(path) + 6);
263 strcpy(msg, tmp);
264 strcat(msg, path);
266 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
267 wfree(msg);
268 wfree(apath);
269 return;
272 /* list contents in the column */
273 while ((dentry = readdir(dir))) {
274 struct stat statb;
276 if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") == 0)
277 continue;
279 strcpy(pbuf, apath);
280 strcat(pbuf, "/");
281 strcat(pbuf, dentry->d_name);
283 if (stat(pbuf, &statb) < 0)
284 continue;
286 if (statb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)
287 && statb.st_mode & (S_IFREG | S_IFLNK)) {
288 WMAddListItem(lPtr, dentry->d_name);
291 WMSortListItems(lPtr);
293 closedir(dir);
294 wfree(apath);
295 panel->preview = True;
298 static void setViewedImage(IconPanel * panel, char *file)
300 WMPixmap *pixmap;
301 RColor color;
303 color.red = 0xae;
304 color.green = 0xaa;
305 color.blue = 0xae;
306 color.alpha = 0;
307 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win), file, &color);
308 if (!pixmap) {
309 WMSetButtonEnabled(panel->okButton, False);
311 WMSetLabelText(panel->iconView, _("Could not load image file "));
313 WMSetLabelImage(panel->iconView, NULL);
314 } else {
315 WMSetButtonEnabled(panel->okButton, True);
317 WMSetLabelText(panel->iconView, NULL);
318 WMSetLabelImage(panel->iconView, pixmap);
319 WMReleasePixmap(pixmap);
323 static void listCallback(void *self, void *data)
325 WMList *lPtr = (WMList *) self;
326 IconPanel *panel = (IconPanel *) data;
327 char *path;
329 if (lPtr == panel->dirList) {
330 WMListItem *item = WMGetListSelectedItem(lPtr);
332 if (item == NULL)
333 return;
334 path = item->text;
336 WMSetTextFieldText(panel->fileField, path);
338 WMSetLabelImage(panel->iconView, NULL);
340 WMSetButtonEnabled(panel->okButton, False);
342 WMClearList(panel->iconList);
343 listPixmaps(panel->scr, panel->iconList, path);
344 } else {
345 char *tmp, *iconFile;
346 WMListItem *item = WMGetListSelectedItem(panel->dirList);
348 if (item == NULL)
349 return;
350 path = item->text;
351 tmp = wexpandpath(path);
353 item = WMGetListSelectedItem(panel->iconList);
354 if (item == NULL)
355 return;
356 iconFile = item->text;
358 path = wmalloc(strlen(tmp) + strlen(iconFile) + 4);
359 strcpy(path, tmp);
360 strcat(path, "/");
361 strcat(path, iconFile);
362 wfree(tmp);
363 WMSetTextFieldText(panel->fileField, path);
364 setViewedImage(panel, path);
365 wfree(path);
369 static void listIconPaths(WMList * lPtr)
371 char *paths;
372 char *path;
374 paths = wstrdup(wPreferences.icon_path);
376 path = strtok(paths, ":");
378 do {
379 char *tmp;
381 tmp = wexpandpath(path);
382 /* do not sort, because the order implies the order of
383 * directories searched */
384 if (access(tmp, X_OK) == 0)
385 WMAddListItem(lPtr, path);
386 wfree(tmp);
387 } while ((path = strtok(NULL, ":")) != NULL);
389 wfree(paths);
392 static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
394 IconPanel *panel = WMGetHangedData(lPtr);
395 WScreen *scr = panel->scr;
396 GC gc = scr->draw_gc;
397 GC copygc = scr->copy_gc;
398 char *file, *dirfile;
399 WMPixmap *pixmap;
400 WMColor *back;
401 WMSize size;
402 WMScreen *wmscr = WMWidgetScreen(panel->win);
403 RColor color;
404 int x, y, width, height, len;
406 if (!panel->preview)
407 return;
409 x = rect->pos.x;
410 y = rect->pos.y;
411 width = rect->size.width;
412 height = rect->size.height;
414 back = (state & WLDSSelected) ? scr->white : scr->gray;
416 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
417 len = strlen(dirfile) + strlen(text) + 4;
418 file = wmalloc(len);
419 snprintf(file, len, "%s/%s", dirfile, text);
420 wfree(dirfile);
422 color.red = WMRedComponentOfColor(back) >> 8;
423 color.green = WMGreenComponentOfColor(back) >> 8;
424 color.blue = WMBlueComponentOfColor(back) >> 8;
425 color.alpha = WMGetColorAlpha(back) >> 8;
427 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
428 wfree(file);
430 if (!pixmap) {
431 /*WMRemoveListItem(lPtr, index); */
432 return;
435 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
437 XSetClipMask(dpy, gc, None);
438 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54); */
439 XDrawLine(dpy, d, WMColorGC(scr->white), x, y + height - 1, x + width, y + height - 1);
441 size = WMGetPixmapSize(pixmap);
443 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
444 XSetClipOrigin(dpy, copygc, x + (width - size.width) / 2, y + 2);
445 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
446 size.width > 100 ? 100 : size.width, size.height > 64 ? 64 : size.height,
447 x + (width - size.width) / 2, y + 2);
450 int i, j;
451 int fheight = WMFontHeight(panel->normalfont);
452 int tlen = strlen(text);
453 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
454 int ofx, ofy;
456 ofx = x + (width - twidth) / 2;
457 ofy = y + 64 - fheight;
459 for (i = -1; i < 2; i++)
460 for (j = -1; j < 2; j++)
461 WMDrawString(wmscr, d, scr->white, panel->normalfont,
462 ofx + i, ofy + j, text, tlen);
464 WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy, text, tlen);
467 WMReleasePixmap(pixmap);
468 /* I hope it is better to do not use cache / on my box it is fast nuff */
469 XFlush(dpy);
472 static void buttonCallback(void *self, void *clientData)
474 WMButton *bPtr = (WMButton *) self;
475 IconPanel *panel = (IconPanel *) clientData;
477 if (bPtr == panel->okButton) {
478 panel->done = True;
479 panel->result = True;
480 } else if (bPtr == panel->cancelButton) {
481 panel->done = True;
482 panel->result = False;
483 } else if (bPtr == panel->previewButton) {
484 /**** Previewer ****/
485 WMSetButtonEnabled(bPtr, False);
486 WMSetListUserDrawItemHeight(panel->iconList, 68);
487 WMSetListUserDrawProc(panel->iconList, drawIconProc);
488 WMRedisplayWidget(panel->iconList);
489 /* for draw proc to access screen/gc */
490 /*** end preview ***/
492 #if 0
493 else if (bPtr == panel->chooseButton) {
494 WMOpenPanel *op;
496 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
498 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
499 char *path;
500 path = WMGetFilePanelFile(op);
501 WMSetTextFieldText(panel->fileField, path);
502 setViewedImage(panel, path);
503 wfree(path);
505 WMDestroyFilePanel(op);
507 #endif
510 static void keyPressHandler(XEvent * event, void *data)
512 IconPanel *panel = (IconPanel *) data;
513 char buffer[32];
514 int count;
515 KeySym ksym;
516 int iidx;
517 int didx;
518 int item = 0;
519 WMList *list = NULL;
521 if (event->type == KeyRelease)
522 return;
524 buffer[0] = 0;
525 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
527 iidx = WMGetListSelectedItemRow(panel->iconList);
528 didx = WMGetListSelectedItemRow(panel->dirList);
530 switch (ksym) {
531 case XK_Up:
532 if (iidx > 0)
533 item = iidx - 1;
534 else
535 item = iidx;
536 list = panel->iconList;
537 break;
538 case XK_Down:
539 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
540 item = iidx + 1;
541 else
542 item = iidx;
543 list = panel->iconList;
544 break;
545 case XK_Home:
546 item = 0;
547 list = panel->iconList;
548 break;
549 case XK_End:
550 item = WMGetListNumberOfRows(panel->iconList) - 1;
551 list = panel->iconList;
552 break;
553 case XK_Next:
554 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
555 item = didx + 1;
556 else
557 item = didx;
558 list = panel->dirList;
559 break;
560 case XK_Prior:
561 if (didx > 0)
562 item = didx - 1;
563 else
564 item = 0;
565 list = panel->dirList;
566 break;
567 case XK_Return:
568 WMPerformButtonClick(panel->okButton);
569 break;
570 case XK_Escape:
571 WMPerformButtonClick(panel->cancelButton);
572 break;
575 if (list) {
576 WMSelectListItem(list, item);
577 WMSetListPosition(list, item - 5);
578 listCallback(list, panel);
582 Bool wIconChooserDialog(WScreen * scr, char **file, char *instance, char *class)
584 WWindow *wwin;
585 Window parent;
586 IconPanel *panel;
587 WMColor *color;
588 WMFont *boldFont;
589 Bool result;
591 panel = wmalloc(sizeof(IconPanel));
592 memset(panel, 0, sizeof(IconPanel));
594 panel->scr = scr;
596 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
597 WMResizeWidget(panel->win, 450, 280);
599 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask | KeyReleaseMask, keyPressHandler, panel);
601 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
602 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
604 panel->dirLabel = WMCreateLabel(panel->win);
605 WMResizeWidget(panel->dirLabel, 200, 20);
606 WMMoveWidget(panel->dirLabel, 10, 7);
607 WMSetLabelText(panel->dirLabel, _("Directories"));
608 WMSetLabelFont(panel->dirLabel, boldFont);
609 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
611 WMSetLabelRelief(panel->dirLabel, WRSunken);
613 panel->iconLabel = WMCreateLabel(panel->win);
614 WMResizeWidget(panel->iconLabel, 140, 20);
615 WMMoveWidget(panel->iconLabel, 215, 7);
616 WMSetLabelText(panel->iconLabel, _("Icons"));
617 WMSetLabelFont(panel->iconLabel, boldFont);
618 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
620 WMReleaseFont(boldFont);
622 color = WMWhiteColor(scr->wmscreen);
623 WMSetLabelTextColor(panel->dirLabel, color);
624 WMSetLabelTextColor(panel->iconLabel, color);
625 WMReleaseColor(color);
627 color = WMDarkGrayColor(scr->wmscreen);
628 WMSetWidgetBackgroundColor(panel->iconLabel, color);
629 WMSetWidgetBackgroundColor(panel->dirLabel, color);
630 WMReleaseColor(color);
632 WMSetLabelRelief(panel->iconLabel, WRSunken);
634 panel->dirList = WMCreateList(panel->win);
635 WMResizeWidget(panel->dirList, 200, 170);
636 WMMoveWidget(panel->dirList, 10, 30);
637 WMSetListAction(panel->dirList, listCallback, panel);
639 panel->iconList = WMCreateList(panel->win);
640 WMResizeWidget(panel->iconList, 140, 170);
641 WMMoveWidget(panel->iconList, 215, 30);
642 WMSetListAction(panel->iconList, listCallback, panel);
644 WMHangData(panel->iconList, panel);
646 panel->previewButton = WMCreateCommandButton(panel->win);
647 WMResizeWidget(panel->previewButton, 75, 26);
648 WMMoveWidget(panel->previewButton, 365, 130);
649 WMSetButtonText(panel->previewButton, _("Preview"));
650 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
652 panel->iconView = WMCreateLabel(panel->win);
653 WMResizeWidget(panel->iconView, 75, 75);
654 WMMoveWidget(panel->iconView, 365, 40);
655 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
656 WMSetLabelRelief(panel->iconView, WRSunken);
657 WMSetLabelTextAlignment(panel->iconView, WACenter);
659 panel->fileLabel = WMCreateLabel(panel->win);
660 WMResizeWidget(panel->fileLabel, 80, 20);
661 WMMoveWidget(panel->fileLabel, 10, 210);
662 WMSetLabelText(panel->fileLabel, _("File Name:"));
664 panel->fileField = WMCreateTextField(panel->win);
665 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
666 WMResizeWidget(panel->fileField, 345, 20);
667 WMMoveWidget(panel->fileField, 95, 210);
668 WMSetTextFieldEditable(panel->fileField, False);
670 panel->okButton = WMCreateCommandButton(panel->win);
671 WMResizeWidget(panel->okButton, 80, 26);
672 WMMoveWidget(panel->okButton, 360, 240);
673 WMSetButtonText(panel->okButton, _("OK"));
674 WMSetButtonEnabled(panel->okButton, False);
675 WMSetButtonAction(panel->okButton, buttonCallback, panel);
677 panel->cancelButton = WMCreateCommandButton(panel->win);
678 WMResizeWidget(panel->cancelButton, 80, 26);
679 WMMoveWidget(panel->cancelButton, 270, 240);
680 WMSetButtonText(panel->cancelButton, _("Cancel"));
681 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
682 #if 0
683 panel->chooseButton = WMCreateCommandButton(panel->win);
684 WMResizeWidget(panel->chooseButton, 110, 26);
685 WMMoveWidget(panel->chooseButton, 150, 240);
686 WMSetButtonText(panel->chooseButton, _("Choose File"));
687 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
688 #endif
689 WMRealizeWidget(panel->win);
690 WMMapSubwidgets(panel->win);
692 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
694 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
697 char *tmp;
698 int len = (instance ? strlen(instance) : 0)
699 + (class ? strlen(class) : 0) + 32;
700 WMPoint center;
702 tmp = wmalloc(len);
704 if (tmp && (instance || class))
705 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
706 else
707 strcpy(tmp, _("Icon Chooser"));
709 center = getCenter(scr, 450, 280);
711 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x, center.y, 450, 280);
712 wfree(tmp);
715 /* put icon paths in the list */
716 listIconPaths(panel->dirList);
718 WMMapWidget(panel->win);
720 wWindowMap(wwin);
722 while (!panel->done) {
723 XEvent event;
725 WMNextEvent(dpy, &event);
726 WMHandleEvent(&event);
729 if (panel->result) {
730 char *defaultPath, *wantedPath;
732 /* check if the file the user selected is not the one that
733 * would be loaded by default with the current search path */
734 *file = WMGetListSelectedItem(panel->iconList)->text;
735 if (**file == 0) {
736 wfree(*file);
737 *file = NULL;
738 } else {
739 defaultPath = FindImage(wPreferences.icon_path, *file);
740 wantedPath = WMGetTextFieldText(panel->fileField);
741 /* if the file is not the default, use full path */
742 if (strcmp(wantedPath, defaultPath) != 0) {
743 *file = wantedPath;
744 } else {
745 *file = wstrdup(*file);
746 wfree(wantedPath);
748 wfree(defaultPath);
750 } else {
751 *file = NULL;
754 result = panel->result;
756 WMReleaseFont(panel->normalfont);
758 WMUnmapWidget(panel->win);
760 WMDestroyWidget(panel->win);
762 wUnmanageWindow(wwin, False, False);
764 wfree(panel);
766 XDestroyWindow(dpy, parent);
768 return result;
772 ***********************************************************************
773 * Info Panel
774 ***********************************************************************
777 typedef struct {
778 WScreen *scr;
780 WWindow *wwin;
782 WMWindow *win;
784 WMLabel *logoL;
785 WMLabel *name1L;
786 WMFrame *lineF;
787 WMLabel *name2L;
789 WMLabel *versionL;
791 WMLabel *infoL;
793 WMLabel *copyrL;
795 #ifdef SILLYNESS
796 WMHandlerID timer;
797 int cycle;
798 RImage *icon;
799 RImage *pic;
800 WMPixmap *oldPix;
801 WMFont *oldFont;
802 char *str;
803 int x;
804 #endif
805 } InfoPanel;
807 #define COPYRIGHT_TEXT \
808 "Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
809 "Copyright \xc2\xa9 1998-2006 Dan Pascu"
811 static InfoPanel *thePanel = NULL;
813 static void destroyInfoPanel(WCoreWindow * foo, void *data, XEvent * event)
815 #ifdef SILLYNESS
816 if (thePanel->timer) {
817 WMDeleteTimerHandler(thePanel->timer);
819 if (thePanel->oldPix) {
820 WMReleasePixmap(thePanel->oldPix);
822 if (thePanel->oldFont) {
823 WMReleaseFont(thePanel->oldFont);
825 if (thePanel->icon) {
826 RReleaseImage(thePanel->icon);
828 if (thePanel->pic) {
829 RReleaseImage(thePanel->pic);
831 #endif /* SILLYNESS */
832 WMUnmapWidget(thePanel);
834 wUnmanageWindow(thePanel->wwin, False, False);
836 WMDestroyWidget(thePanel->win);
838 wfree(thePanel);
840 thePanel = NULL;
843 #ifdef SILLYNESS
845 extern WMPixmap *DoXThing();
846 extern Bool InitXThing();
848 static void logoPushCallback(void *data)
850 InfoPanel *panel = (InfoPanel *) data;
851 char buffer[512];
852 int i;
853 static int oldi = 0;
854 int len;
855 static int jingobeu[] = {
856 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
857 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
858 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
860 static int c = 0;
862 if (panel->x) {
863 XKeyboardControl kc;
864 XKeyboardState ksave;
865 unsigned long mask = KBBellPitch | KBBellDuration | KBBellPercent;
867 XGetKeyboardControl(dpy, &ksave);
869 if (panel->x > 0) {
870 if (jingobeu[panel->x - 1] == 0) {
871 panel->x = -1;
872 } else if (jingobeu[panel->x - 1] < 0) {
873 panel->x++;
874 c = jingobeu[panel->x - 1] / 50;
875 panel->x++;
876 } else if (c == 0) {
877 kc.bell_percent = 50;
878 kc.bell_pitch = jingobeu[panel->x - 1];
879 panel->x++;
880 kc.bell_duration = jingobeu[panel->x - 1];
881 c = jingobeu[panel->x - 1] / 50;
882 panel->x++;
883 XChangeKeyboardControl(dpy, mask, &kc);
884 XBell(dpy, 50);
885 XFlush(dpy);
886 } else {
887 c--;
890 if (!(panel->cycle % 4)) {
891 WMPixmap *p;
893 p = DoXThing(panel->wwin);
894 WMSetLabelImage(panel->logoL, p);
896 kc.bell_pitch = ksave.bell_pitch;
897 kc.bell_percent = ksave.bell_percent;
898 kc.bell_duration = ksave.bell_duration;
899 XChangeKeyboardControl(dpy, mask, &kc);
900 } else if (panel->cycle < 30) {
901 RImage *image;
902 WMPixmap *pix;
903 RColor gray;
905 gray.red = 0xae;
906 gray.green = 0xaa;
907 gray.blue = 0xae;
908 gray.alpha = 0;
910 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
911 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle * 255 / 30);
912 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
913 RReleaseImage(image);
914 WMSetLabelImage(panel->logoL, pix);
915 WMReleasePixmap(pix);
918 /* slow down text a little */
919 i = (int)(panel->cycle * 50.0 / 85.0) % 200;
921 if (i != oldi) {
922 len = strlen(panel->str);
924 strncpy(buffer, panel->str, i < len ? i : len);
925 if (i >= len)
926 memset(&buffer[len], ' ', i - len);
928 strncpy(buffer, panel->str, i < len ? i : len);
929 if (i >= len)
930 memset(&buffer[len], ' ', i - len);
931 buffer[i] = 0;
933 WMSetLabelText(panel->versionL, buffer);
935 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
937 oldi = i;
940 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
941 panel->cycle++;
944 static void handleLogoPush(XEvent * event, void *data)
946 InfoPanel *panel = (InfoPanel *) data;
947 static int broken = 0;
948 static int clicks = 0;
949 static char *pic_data[] = {
950 "45 45 57 1",
951 " c None",
952 ". c #000000",
953 "X c #383C00",
954 "o c #515500",
955 "O c #616100",
956 "+ c #616900",
957 "@ c #696D00",
958 "# c #697100",
959 "$ c #495100",
960 "% c #202800",
961 "& c #969600",
962 "* c #CFCF00",
963 "= c #D7DB00",
964 "- c #D7D700",
965 "; c #C7CB00",
966 ": c #A6AA00",
967 "> c #494900",
968 ", c #8E8E00",
969 "< c #DFE700",
970 "1 c #F7FF00",
971 "2 c #FFFF00",
972 "3 c #E7EB00",
973 "4 c #B6B600",
974 "5 c #595900",
975 "6 c #717500",
976 "7 c #AEB200",
977 "8 c #CFD300",
978 "9 c #E7EF00",
979 "0 c #EFF300",
980 "q c #9EA200",
981 "w c #F7FB00",
982 "e c #F7F700",
983 "r c #BEBE00",
984 "t c #8E9200",
985 "y c #EFF700",
986 "u c #969A00",
987 "i c #414500",
988 "p c #595D00",
989 "a c #E7E700",
990 "s c #C7C700",
991 "d c #797D00",
992 "f c #BEC300",
993 "g c #DFE300",
994 "h c #868600",
995 "j c #EFEF00",
996 "k c #9E9E00",
997 "l c #616500",
998 "z c #DFDF00",
999 "x c #868A00",
1000 "c c #969200",
1001 "v c #B6BA00",
1002 "b c #A6A600",
1003 "n c #8E8A00",
1004 "m c #717100",
1005 "M c #AEAE00",
1006 "N c #AEAA00",
1007 "B c #868200",
1008 " ............... ",
1009 " ....XoO+@##+O$%.... ",
1010 " ...%X&*========-;;:o... ",
1011 " ...>.>,<122222222222134@... ",
1012 " ..>5678912222222222222220q%.. ",
1013 " ..$.&-w2222222222222222222er>.. ",
1014 " ..O.t31222222222222222222222y4>.. ",
1015 " ...O5u3222222222222222222222222yri... ",
1016 " ..>p&a22222222222222222222222222wso.. ",
1017 " ..ids91222222222222222222222222222wfi.. ",
1018 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1019 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1020 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1021 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1022 "..io*222222222&...u22222222yt..%*22222220:%. ",
1023 "..>k02222222227...f222222222v..X=222222229t. ",
1024 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1025 ".%vw222222222221y2222222222219*y2222222222wd.",
1026 ".X;2222222222222222222222222222222222222222b.",
1027 ".i*2222222222222222222222222222222222222222v.",
1028 ".i*2222222222222222222222222222222222222222;.",
1029 ".i*22222222222222222222222222222222222222228.",
1030 ".>*2222222222222222222222222222222222222222=.",
1031 ".i*22222222222222222222222222222222222222228.",
1032 ".i*2222222222222222222222222222222222222222;.",
1033 ".X*222222222222222222222222222222we12222222r.",
1034 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1035 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1036 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1037 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1038 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1039 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1040 " ...:e2222218mdz22222222222222a&$vw222220@...",
1041 " ...O-122222y:.u02222222222229q$uj222221r... ",
1042 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1043 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1044 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1045 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1046 " ..Xb9122222109g-****;<y22221zn%... ",
1047 " ..X&801222222222222222222w-h.... ",
1048 " ...o:=022222222222222221=lX... ",
1049 " ..X@:;3w2222222222210fO... ",
1050 " ...XX&v8<30000003-N@... ",
1051 " .....XmnbN:q&Bo.... ",
1052 " ............ "
1054 static char *msgs[] = {
1055 "Have a nice day!",
1056 "Focus follow mouse users will burn in hell!!!",
1057 "Mooo Canada!!!!",
1058 "Hi! My name is bobby...",
1059 "AHH! The neurotic monkeys are after me!",
1060 "WE GET SIGNAL",
1061 "HOW ARE YOU GENTLEMEN?",
1062 "WHAT YOU SAY??",
1063 "SOMEBODY SET UP US THE BOMB",
1064 "ALL YOUR BASE ARE BELONG TO US!",
1065 "Oh My God!!! Larry is back!",
1066 "Alex Perez is aliveeeeeeee!!!"
1069 clicks++;
1071 if (!panel->timer && !broken && clicks > 0) {
1072 WMFont *font;
1074 panel->x = 0;
1075 clicks = 0;
1076 if (!panel->icon) {
1077 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1078 if (!panel->icon) {
1079 broken = 1;
1080 return;
1081 } else {
1082 RColor color;
1084 color.red = 0xae;
1085 color.green = 0xaa;
1086 color.blue = 0xae;
1087 color.alpha = 0;
1089 panel->icon = RCloneImage(panel->icon);
1090 RCombineImageWithColor(panel->icon, &color);
1093 if (!panel->pic) {
1094 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1095 if (!panel->pic) {
1096 broken = 1;
1097 RReleaseImage(panel->icon);
1098 panel->icon = NULL;
1099 return;
1103 panel->str = msgs[rand() % (sizeof(msgs) / sizeof(char *))];
1105 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1106 panel->cycle = 0;
1107 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1108 /* If we don't use a fixed font, scrolling will be jumpy */
1109 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1110 if ((panel->oldFont = WMGetLabelFont(panel->versionL)) != NULL)
1111 WMRetainFont(panel->oldFont);
1112 font = WMCreateFont(WMWidgetScreen(panel->versionL),
1113 "Lucida Console,Courier New,monospace:pixelsize=12");
1114 if (font) {
1115 WMSetLabelFont(panel->versionL, font);
1116 WMReleaseFont(font);
1118 WMSetLabelText(panel->versionL, "");
1119 } else if (panel->timer) {
1120 char version[20];
1122 panel->x = 0;
1123 clicks = 0;
1124 WMSetLabelImage(panel->logoL, panel->oldPix);
1125 WMReleasePixmap(panel->oldPix);
1126 panel->oldPix = NULL;
1128 WMDeleteTimerHandler(panel->timer);
1129 panel->timer = NULL;
1131 WMSetLabelFont(panel->versionL, panel->oldFont);
1132 if (panel->oldFont) {
1133 WMReleaseFont(panel->oldFont);
1134 panel->oldFont = NULL;
1136 snprintf(version, sizeof(version), _("Version %s"), VERSION);
1137 WMSetLabelText(panel->versionL, version);
1138 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1142 XEvent ev;
1143 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL), ButtonPress, &ev)) ;
1146 #endif /* SILLYNESS */
1148 void wShowInfoPanel(WScreen * scr)
1150 InfoPanel *panel;
1151 WMPixmap *logo;
1152 WMSize size;
1153 WMFont *font;
1154 char *strbuf = NULL;
1155 char buffer[256];
1156 char *name;
1157 Window parent;
1158 WWindow *wwin;
1159 char **strl;
1160 int i, width = 50, sepHeight;
1161 char *visuals[] = {
1162 "StaticGray",
1163 "GrayScale",
1164 "StaticColor",
1165 "PseudoColor",
1166 "TrueColor",
1167 "DirectColor"
1170 if (thePanel) {
1171 if (thePanel->scr == scr) {
1172 wRaiseFrame(thePanel->wwin->frame->core);
1173 wSetFocusTo(scr, thePanel->wwin);
1175 return;
1178 panel = wmalloc(sizeof(InfoPanel));
1179 memset(panel, 0, sizeof(InfoPanel));
1181 panel->scr = scr;
1183 panel->win = WMCreateWindow(scr->wmscreen, "info");
1184 WMResizeWidget(panel->win, 390, 230);
1186 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
1187 if (!logo) {
1188 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1190 if (logo) {
1191 size = WMGetPixmapSize(logo);
1192 panel->logoL = WMCreateLabel(panel->win);
1193 WMResizeWidget(panel->logoL, 64, 64);
1194 WMMoveWidget(panel->logoL, 30, 20);
1195 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1196 WMSetLabelImage(panel->logoL, logo);
1197 #ifdef SILLYNESS
1198 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask, handleLogoPush, panel);
1199 #endif
1200 WMReleasePixmap(logo);
1203 sepHeight = 3;
1204 panel->name1L = WMCreateLabel(panel->win);
1205 WMResizeWidget(panel->name1L, 240, 30 + 2);
1206 WMMoveWidget(panel->name1L, 100, 30 - 2 - sepHeight);
1208 name = "Lucida Sans,Comic Sans MS,URW Gothic L,Trebuchet MS" ":italic:pixelsize=28:antialias=true";
1209 font = WMCreateFont(scr->wmscreen, name);
1210 strbuf = "Window Maker";
1211 if (font) {
1212 width = WMWidthOfString(font, strbuf, strlen(strbuf));
1213 WMSetLabelFont(panel->name1L, font);
1214 WMReleaseFont(font);
1216 WMSetLabelTextAlignment(panel->name1L, WACenter);
1217 WMSetLabelText(panel->name1L, strbuf);
1219 panel->lineF = WMCreateFrame(panel->win);
1220 WMResizeWidget(panel->lineF, width, sepHeight);
1221 WMMoveWidget(panel->lineF, 100 + (240 - width) / 2, 60 - sepHeight);
1222 WMSetFrameRelief(panel->lineF, WRSimple);
1223 WMSetWidgetBackgroundColor(panel->lineF, scr->black);
1225 panel->name2L = WMCreateLabel(panel->win);
1226 WMResizeWidget(panel->name2L, 240, 24);
1227 WMMoveWidget(panel->name2L, 100, 60);
1228 name = "URW Gothic L,Nimbus Sans L:pixelsize=16:antialias=true";
1229 font = WMCreateFont(scr->wmscreen, name);
1230 if (font) {
1231 WMSetLabelFont(panel->name2L, font);
1232 WMReleaseFont(font);
1233 font = NULL;
1235 WMSetLabelTextAlignment(panel->name2L, WACenter);
1236 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1238 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1239 panel->versionL = WMCreateLabel(panel->win);
1240 WMResizeWidget(panel->versionL, 310, 16);
1241 WMMoveWidget(panel->versionL, 30, 95);
1242 WMSetLabelTextAlignment(panel->versionL, WARight);
1243 WMSetLabelText(panel->versionL, buffer);
1244 WMSetLabelWraps(panel->versionL, False);
1246 panel->copyrL = WMCreateLabel(panel->win);
1247 WMResizeWidget(panel->copyrL, 360, 40);
1248 WMMoveWidget(panel->copyrL, 15, 185);
1249 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1250 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1251 font = WMSystemFontOfSize(scr->wmscreen, 11);
1252 if (font) {
1253 WMSetLabelFont(panel->copyrL, font);
1254 WMReleaseFont(font);
1255 font = NULL;
1258 strbuf = NULL;
1259 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1260 (unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
1262 strbuf = wstrappend(strbuf, buffer);
1264 switch (scr->w_depth) {
1265 case 15:
1266 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1267 break;
1268 case 16:
1269 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1270 break;
1271 case 24:
1272 case 32:
1273 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1274 break;
1275 default:
1276 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1 << scr->w_depth);
1277 strbuf = wstrappend(strbuf, buffer);
1278 break;
1281 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1283 struct mallinfo ma = mallinfo();
1284 snprintf(buffer, sizeof(buffer),
1285 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1286 (ma.arena + ma.hblkhd) / 1024, (ma.uordblks + ma.hblkhd) / 1024);
1288 strbuf = wstrappend(strbuf, buffer);
1290 #endif
1292 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1293 strl = RSupportedFileFormats();
1294 for (i = 0; strl[i] != NULL; i++) {
1295 strbuf = wstrappend(strbuf, strl[i]);
1296 strbuf = wstrappend(strbuf, " ");
1299 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1301 char *list[9];
1302 char buf[80];
1303 int j = 0;
1305 #ifdef NETWM_HINTS
1306 list[j++] = "WMSPEC";
1307 #endif
1308 #ifdef MWM_HINTS
1309 list[j++] = "MWM";
1310 #endif
1312 buf[0] = 0;
1313 for (i = 0; i < j; i++) {
1314 if (i > 0) {
1315 if (i == j - 1)
1316 strcat(buf, _(" and "));
1317 else
1318 strcat(buf, ", ");
1320 strcat(buf, list[i]);
1322 strbuf = wstrappend(strbuf, buf);
1325 if (wPreferences.no_sound) {
1326 strbuf = wstrappend(strbuf, _("\nSound disabled"));
1327 } else {
1328 strbuf = wstrappend(strbuf, _("\nSound enabled"));
1331 #ifdef VIRTUAL_DESKTOP
1332 if (wPreferences.vdesk_enable)
1333 strbuf = wstrappend(strbuf, _(", VirtualDesktop enabled"));
1334 else
1335 strbuf = wstrappend(strbuf, _(", VirtualDesktop disabled"));
1336 #endif
1338 #ifdef XINERAMA
1339 strbuf = wstrappend(strbuf, _("\n"));
1340 #ifdef SOLARIS_XINERAMA
1341 strbuf = wstrappend(strbuf, _("Solaris "));
1342 #endif
1343 strbuf = wstrappend(strbuf, _("Xinerama: "));
1345 char tmp[128];
1346 snprintf(tmp, sizeof(tmp) - 1, "%d heads found.", scr->xine_info.count);
1347 strbuf = wstrappend(strbuf, tmp);
1349 #endif
1351 panel->infoL = WMCreateLabel(panel->win);
1352 WMResizeWidget(panel->infoL, 350, 75);
1353 WMMoveWidget(panel->infoL, 15, 115);
1354 WMSetLabelText(panel->infoL, strbuf);
1355 font = WMSystemFontOfSize(scr->wmscreen, 11);
1356 if (font) {
1357 WMSetLabelFont(panel->infoL, font);
1358 WMReleaseFont(font);
1359 font = NULL;
1361 wfree(strbuf);
1363 WMRealizeWidget(panel->win);
1364 WMMapSubwidgets(panel->win);
1366 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1368 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1370 WMMapWidget(panel->win);
1373 WMPoint center = getCenter(scr, 382, 230);
1375 wwin = wManageInternalWindow(scr, parent, None, _("Info"), center.x, center.y, 382, 230);
1378 WSETUFLAG(wwin, no_closable, 0);
1379 WSETUFLAG(wwin, no_close_button, 0);
1380 #ifdef XKB_BUTTON_HINT
1381 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1382 #endif
1383 wWindowUpdateButtonImages(wwin);
1384 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1385 wwin->frame->on_click_right = destroyInfoPanel;
1387 wWindowMap(wwin);
1389 panel->wwin = wwin;
1391 thePanel = panel;
1392 #ifdef SILLYNESS
1393 if (InitXThing(panel->scr)) {
1394 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1395 panel->cycle = 0;
1396 panel->x = 1;
1397 panel->str = _("Merry Christmas!");
1398 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1400 #endif
1404 ***********************************************************************
1405 * Legal Panel
1406 ***********************************************************************
1409 typedef struct {
1410 WScreen *scr;
1412 WWindow *wwin;
1414 WMWindow *win;
1416 WMLabel *licenseL;
1417 } LegalPanel;
1419 static LegalPanel *legalPanel = NULL;
1421 static void destroyLegalPanel(WCoreWindow * foo, void *data, XEvent * event)
1423 WMUnmapWidget(legalPanel->win);
1425 WMDestroyWidget(legalPanel->win);
1427 wUnmanageWindow(legalPanel->wwin, False, False);
1429 wfree(legalPanel);
1431 legalPanel = NULL;
1434 void wShowLegalPanel(WScreen * scr)
1436 LegalPanel *panel;
1437 Window parent;
1438 WWindow *wwin;
1440 if (legalPanel) {
1441 if (legalPanel->scr == scr) {
1442 wRaiseFrame(legalPanel->wwin->frame->core);
1443 wSetFocusTo(scr, legalPanel->wwin);
1445 return;
1448 panel = wmalloc(sizeof(LegalPanel));
1450 panel->scr = scr;
1452 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1453 WMResizeWidget(panel->win, 420, 250);
1455 panel->licenseL = WMCreateLabel(panel->win);
1456 WMSetLabelWraps(panel->licenseL, True);
1457 WMResizeWidget(panel->licenseL, 400, 230);
1458 WMMoveWidget(panel->licenseL, 10, 10);
1459 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1460 WMSetLabelText(panel->licenseL,
1461 _(" Window Maker is free software; you can redistribute it and/or\n"
1462 "modify it under the terms of the GNU General Public License as\n"
1463 "published by the Free Software Foundation; either version 2 of the\n"
1464 "License, or (at your option) any later version.\n\n"
1465 " Window Maker is distributed in the hope that it will be useful,\n"
1466 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1467 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1468 "See the GNU General Public License for more details.\n\n"
1469 " You should have received a copy of the GNU General Public\n"
1470 "License along with this program; if not, write to the Free Software\n"
1471 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n" "02111-1307, USA."));
1472 WMSetLabelRelief(panel->licenseL, WRGroove);
1474 WMRealizeWidget(panel->win);
1475 WMMapSubwidgets(panel->win);
1477 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1479 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1482 WMPoint center = getCenter(scr, 420, 250);
1484 wwin = wManageInternalWindow(scr, parent, None, _("Legal"), center.x, center.y, 420, 250);
1487 WSETUFLAG(wwin, no_closable, 0);
1488 WSETUFLAG(wwin, no_close_button, 0);
1489 wWindowUpdateButtonImages(wwin);
1490 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1491 #ifdef XKB_BUTTON_HINT
1492 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1493 #endif
1494 wwin->frame->on_click_right = destroyLegalPanel;
1496 panel->wwin = wwin;
1498 WMMapWidget(panel->win);
1500 wWindowMap(wwin);
1502 legalPanel = panel;
1506 ***********************************************************************
1507 * Crashing Dialog Panel
1508 ***********************************************************************
1511 extern WDDomain *WDWindowAttributes;
1513 typedef struct _CrashPanel {
1514 WMWindow *win; /* main window */
1516 WMLabel *iconL; /* application icon */
1517 WMLabel *nameL; /* title of panel */
1519 WMFrame *sepF; /* separator frame */
1521 WMLabel *noteL; /* Title of note */
1522 WMLabel *note2L; /* body of note with what happened */
1524 WMFrame *whatF; /* "what to do next" frame */
1525 WMPopUpButton *whatP; /* action selection popup button */
1527 WMButton *okB; /* ok button */
1529 Bool done; /* if finished with this dialog */
1530 int action; /* what to do after */
1532 KeyCode retKey;
1534 } CrashPanel;
1536 static void handleKeyPress(XEvent * event, void *clientData)
1538 CrashPanel *panel = (CrashPanel *) clientData;
1540 if (event->xkey.keycode == panel->retKey) {
1541 WMPerformButtonClick(panel->okB);
1545 static void okButtonCallback(void *self, void *clientData)
1547 CrashPanel *panel = (CrashPanel *) clientData;
1549 panel->done = True;
1552 static void setCrashAction(void *self, void *clientData)
1554 WMPopUpButton *pop = (WMPopUpButton *) self;
1555 CrashPanel *panel = (CrashPanel *) clientData;
1557 panel->action = WMGetPopUpButtonSelectedItem(pop);
1560 /* Make this read the logo from a compiled in pixmap -Dan */
1561 static WMPixmap *getWindowMakerIconImage(WMScreen * scr)
1563 WMPropList *dict, *key, *option, *value = NULL;
1564 WMPixmap *pix = NULL;
1565 char *path;
1567 if (!WDWindowAttributes || !WDWindowAttributes->dictionary)
1568 return NULL;
1570 WMPLSetCaseSensitive(True);
1572 key = WMCreatePLString("Logo.WMPanel");
1573 option = WMCreatePLString("Icon");
1575 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1577 if (dict) {
1578 value = WMGetFromPLDictionary(dict, option);
1581 WMReleasePropList(key);
1582 WMReleasePropList(option);
1584 WMPLSetCaseSensitive(False);
1586 if (value && WMIsPLString(value)) {
1587 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1589 if (path) {
1590 RColor gray;
1592 gray.red = 0xae;
1593 gray.green = 0xaa;
1594 gray.blue = 0xae;
1595 gray.alpha = 0;
1597 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1598 wfree(path);
1602 return pix;
1605 #define PWIDTH 295
1606 #define PHEIGHT 345
1608 int wShowCrashingDialogPanel(int whatSig)
1610 CrashPanel *panel;
1611 WMScreen *scr;
1612 WMFont *font;
1613 WMPixmap *logo;
1614 int screen_no, scr_width, scr_height;
1615 int action;
1616 char buf[256];
1618 panel = wmalloc(sizeof(CrashPanel));
1619 memset(panel, 0, sizeof(CrashPanel));
1621 screen_no = DefaultScreen(dpy);
1622 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1623 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1625 scr = WMCreateScreen(dpy, screen_no);
1626 if (!scr) {
1627 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1628 return WMAbort;
1631 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1633 panel->win = WMCreateWindow(scr, "crashingDialog");
1634 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1635 WMMoveWidget(panel->win, (scr_width - PWIDTH) / 2, (scr_height - PHEIGHT) / 2);
1637 logo = getWindowMakerIconImage(scr);
1638 if (logo) {
1639 panel->iconL = WMCreateLabel(panel->win);
1640 WMResizeWidget(panel->iconL, 64, 64);
1641 WMMoveWidget(panel->iconL, 10, 10);
1642 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1643 WMSetLabelImage(panel->iconL, logo);
1646 panel->nameL = WMCreateLabel(panel->win);
1647 WMResizeWidget(panel->nameL, 200, 30);
1648 WMMoveWidget(panel->nameL, 80, 25);
1649 WMSetLabelTextAlignment(panel->nameL, WALeft);
1650 font = WMBoldSystemFontOfSize(scr, 24);
1651 WMSetLabelFont(panel->nameL, font);
1652 WMReleaseFont(font);
1653 WMSetLabelText(panel->nameL, _("Fatal error"));
1655 panel->sepF = WMCreateFrame(panel->win);
1656 WMResizeWidget(panel->sepF, PWIDTH + 4, 2);
1657 WMMoveWidget(panel->sepF, -2, 80);
1659 panel->noteL = WMCreateLabel(panel->win);
1660 WMResizeWidget(panel->noteL, PWIDTH - 20, 40);
1661 WMMoveWidget(panel->noteL, 10, 90);
1662 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1663 #ifdef SYS_SIGLIST_DECLARED
1664 snprintf(buf, sizeof(buf), _("Window Maker received signal %i\n(%s)."), whatSig, sys_siglist[whatSig]);
1665 #else
1666 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1667 #endif
1668 WMSetLabelText(panel->noteL, buf);
1670 panel->note2L = WMCreateLabel(panel->win);
1671 WMResizeWidget(panel->note2L, PWIDTH - 20, 100);
1672 WMMoveWidget(panel->note2L, 10, 130);
1673 WMSetLabelTextAlignment(panel->note2L, WALeft);
1674 WMSetLabelText(panel->note2L,
1675 _(" This fatal error occured probably due to a bug."
1676 " Please fill the included BUGFORM and " "report it to bugs@windowmaker.info."));
1677 WMSetLabelWraps(panel->note2L, True);
1679 panel->whatF = WMCreateFrame(panel->win);
1680 WMResizeWidget(panel->whatF, PWIDTH - 20, 50);
1681 WMMoveWidget(panel->whatF, 10, 240);
1682 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1684 panel->whatP = WMCreatePopUpButton(panel->whatF);
1685 WMResizeWidget(panel->whatP, PWIDTH - 20 - 70, 20);
1686 WMMoveWidget(panel->whatP, 35, 20);
1687 WMSetPopUpButtonPullsDown(panel->whatP, False);
1688 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1689 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1690 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1691 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1692 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1693 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1694 panel->action = WMRestart;
1696 WMMapSubwidgets(panel->whatF);
1698 panel->okB = WMCreateCommandButton(panel->win);
1699 WMResizeWidget(panel->okB, 80, 26);
1700 WMMoveWidget(panel->okB, 205, 309);
1701 WMSetButtonText(panel->okB, _("OK"));
1702 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1703 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1704 WMSetButtonImagePosition(panel->okB, WIPRight);
1705 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1707 panel->done = 0;
1709 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask, handleKeyPress, panel);
1711 WMRealizeWidget(panel->win);
1712 WMMapSubwidgets(panel->win);
1714 WMMapWidget(panel->win);
1716 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1718 while (!panel->done) {
1719 XEvent event;
1721 WMNextEvent(dpy, &event);
1722 WMHandleEvent(&event);
1725 action = panel->action;
1727 WMUnmapWidget(panel->win);
1728 WMDestroyWidget(panel->win);
1729 wfree(panel);
1731 return action;
1734 /*****************************************************************************
1735 * About GNUstep Panel
1736 *****************************************************************************/
1738 static void
1739 drawGNUstepLogo(Display * dpy, Drawable d, int width, int height,
1740 unsigned long blackPixel, unsigned long whitePixel)
1742 GC gc;
1743 XGCValues gcv;
1744 XRectangle rects[3];
1746 gcv.foreground = blackPixel;
1747 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1749 XFillArc(dpy, d, gc, width / 45, height / 45,
1750 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
1752 rects[0].x = 0;
1753 rects[0].y = 37 * height / 45;
1754 rects[0].width = width / 3;
1755 rects[0].height = height - rects[0].y;
1757 rects[1].x = rects[0].width;
1758 rects[1].y = height / 2;
1759 rects[1].width = width - 2 * width / 3;
1760 rects[1].height = height - rects[1].y;
1762 rects[2].x = 2 * width / 3;
1763 rects[2].y = height - 37 * height / 45;
1764 rects[2].width = width / 3;
1765 rects[2].height = height - rects[2].y;
1767 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1768 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1770 XSetForeground(dpy, gc, whitePixel);
1771 XFillArc(dpy, d, gc, width / 45, height / 45,
1772 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
1774 XFreeGC(dpy, gc);
1777 typedef struct {
1778 WScreen *scr;
1780 WWindow *wwin;
1782 WMWindow *win;
1784 WMLabel *gstepL;
1785 WMLabel *textL;
1786 } GNUstepPanel;
1788 static GNUstepPanel *gnustepPanel = NULL;
1790 static void destroyGNUstepPanel(WCoreWindow * foo, void *data, XEvent * event)
1792 WMUnmapWidget(gnustepPanel->win);
1794 WMDestroyWidget(gnustepPanel->win);
1796 wUnmanageWindow(gnustepPanel->wwin, False, False);
1798 wfree(gnustepPanel);
1800 gnustepPanel = NULL;
1803 void wShowGNUstepPanel(WScreen * scr)
1805 GNUstepPanel *panel;
1806 Window parent;
1807 WWindow *wwin;
1808 WMPixmap *pixmap;
1809 WMColor *color;
1811 if (gnustepPanel) {
1812 if (gnustepPanel->scr == scr) {
1813 wRaiseFrame(gnustepPanel->wwin->frame->core);
1814 wSetFocusTo(scr, gnustepPanel->wwin);
1816 return;
1819 panel = wmalloc(sizeof(GNUstepPanel));
1821 panel->scr = scr;
1823 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1824 WMResizeWidget(panel->win, 325, 205);
1826 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130, WMScreenDepth(scr->wmscreen), True);
1828 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1830 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130, WMColorPixel(color), scr->white_pixel);
1832 WMReleaseColor(color);
1834 XSetForeground(dpy, scr->mono_gc, 0);
1835 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0, 130, 130);
1836 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1838 panel->gstepL = WMCreateLabel(panel->win);
1839 WMResizeWidget(panel->gstepL, 285, 64);
1840 WMMoveWidget(panel->gstepL, 20, 0);
1841 WMSetLabelTextAlignment(panel->gstepL, WARight);
1842 WMSetLabelText(panel->gstepL, "GNUstep");
1844 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1846 WMSetLabelFont(panel->gstepL, font);
1847 WMReleaseFont(font);
1850 panel->textL = WMCreateLabel(panel->win);
1851 WMResizeWidget(panel->textL, 305, 140);
1852 WMMoveWidget(panel->textL, 10, 50);
1853 WMSetLabelTextAlignment(panel->textL, WARight);
1854 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1855 WMSetLabelText(panel->textL,
1856 _("Window Maker is part of the GNUstep project.\n"
1857 "The GNUstep project aims to create a free\n"
1858 "implementation of the OpenStep(tm) specification\n"
1859 "which is a object-oriented framework for\n"
1860 "creating advanced graphical, multi-platform\n"
1861 "applications. Additionally, a development and\n"
1862 "user desktop enviroment will be created on top\n"
1863 "of the framework. For more information about\n"
1864 "GNUstep, please visit: www.gnustep.org"));
1865 WMSetLabelImage(panel->textL, pixmap);
1867 WMReleasePixmap(pixmap);
1869 WMRealizeWidget(panel->win);
1870 WMMapSubwidgets(panel->win);
1872 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1874 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1877 WMPoint center = getCenter(scr, 325, 200);
1879 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"), center.x, center.y, 325, 200);
1882 WSETUFLAG(wwin, no_closable, 0);
1883 WSETUFLAG(wwin, no_close_button, 0);
1884 wWindowUpdateButtonImages(wwin);
1885 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1886 #ifdef XKB_BUTTON_HINT
1887 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1888 #endif
1889 wwin->frame->on_click_right = destroyGNUstepPanel;
1891 panel->wwin = wwin;
1893 WMMapWidget(panel->win);
1895 wWindowMap(wwin);
1897 gnustepPanel = panel;