- Added xdnd v3 support in WINGs (Sylvain Reynal <sreynal@nerim.net>)
[wmaker-crm.git] / src / dialog.c
blob804ec381075ea28aa7e7790398d192a86d0a8de4
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
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 "dialog.h"
57 #include "funcs.h"
58 #include "stacking.h"
59 #include "framewin.h"
60 #include "window.h"
61 #include "actions.h"
62 #include "defaults.h"
63 #include "xinerama.h"
67 extern WPreferences wPreferences;
70 static WMPoint getCenter(WScreen *scr, int width, int height)
72 return wGetPointToCenterRectInHead(scr,
73 wGetHeadForPointerLocation(scr),
74 width, height);
78 int
79 wMessageDialog(WScreen *scr, char *title, char *message,
80 char *defBtn, char *altBtn, char *othBtn)
82 WMAlertPanel *panel;
83 Window parent;
84 WWindow *wwin;
85 int result;
86 WMPoint center;
88 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message,
89 defBtn, altBtn, othBtn);
91 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
93 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
96 center = getCenter(scr, 400, 180);
97 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y,
98 400, 180);
99 wwin->client_leader = WMWidgetXID(panel->win);
101 WMMapWidget(panel->win);
103 wWindowMap(wwin);
105 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
107 result = panel->result;
109 WMUnmapWidget(panel->win);
111 wUnmanageWindow(wwin, False, False);
113 WMDestroyAlertPanel(panel);
115 XDestroyWindow(dpy, parent);
117 return result;
121 void
122 toggleSaveSession(WMWidget *w, void *data)
124 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
129 wExitDialog(WScreen *scr, char *title, char *message,
130 char *defBtn, char *altBtn, char *othBtn)
132 WMAlertPanel *panel;
133 WMButton *saveSessionBtn;
134 Window parent;
135 WWindow *wwin;
136 WMPoint center;
137 int result;
139 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message,
140 defBtn, altBtn, othBtn);
142 /* add save session button */
143 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
144 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
145 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn),
146 False, True, 200, 0, 0);
147 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
148 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
149 WMRealizeWidget(saveSessionBtn);
150 WMMapWidget(saveSessionBtn);
152 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
154 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
156 center = getCenter(scr, 400, 180);
157 wwin = wManageInternalWindow(scr, parent, None, NULL,
158 center.x, center.y, 400, 180);
160 wwin->client_leader = WMWidgetXID(panel->win);
162 WMMapWidget(panel->win);
164 wWindowMap(wwin);
166 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
168 result = panel->result;
170 WMUnmapWidget(panel->win);
172 wUnmanageWindow(wwin, False, False);
174 WMDestroyAlertPanel(panel);
176 XDestroyWindow(dpy, parent);
178 return result;
183 wInputDialog(WScreen *scr, char *title, char *message, char **text)
185 WWindow *wwin;
186 Window parent;
187 WMInputPanel *panel;
188 char *result;
189 WMPoint center;
191 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text,
192 _("OK"), _("Cancel"));
195 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
196 XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
198 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
200 center = getCenter(scr, 320, 160);
201 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y,
202 320, 160);
204 wwin->client_leader = WMWidgetXID(panel->win);
206 WMMapWidget(panel->win);
208 wWindowMap(wwin);
210 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
212 if (panel->result == WAPRDefault)
213 result = WMGetTextFieldText(panel->text);
214 else
215 result = NULL;
217 wUnmanageWindow(wwin, False, False);
219 WMDestroyInputPanel(panel);
221 XDestroyWindow(dpy, parent);
223 if (result==NULL)
224 return False;
225 else {
226 if (*text)
227 wfree(*text);
228 *text = result;
230 return True;
236 *****************************************************************
237 * Icon Selection Panel
238 *****************************************************************
241 typedef struct IconPanel {
243 WScreen *scr;
245 WMWindow *win;
247 WMLabel *dirLabel;
248 WMLabel *iconLabel;
250 WMList *dirList;
251 WMList *iconList;
252 WMFont *normalfont;
254 WMButton *previewButton;
256 WMLabel *iconView;
258 WMLabel *fileLabel;
259 WMTextField *fileField;
261 WMButton *okButton;
262 WMButton *cancelButton;
263 #if 0
264 WMButton *chooseButton;
265 #endif
266 short done;
267 short result;
268 short preview;
269 } IconPanel;
273 static void
274 listPixmaps(WScreen *scr, WMList *lPtr, char *path)
276 struct dirent *dentry;
277 DIR *dir;
278 char pbuf[PATH_MAX+16];
279 char *apath;
280 IconPanel *panel = WMGetHangedData(lPtr);
282 panel->preview = False;
284 apath = wexpandpath(path);
285 dir = opendir(apath);
287 if (!dir) {
288 char *msg;
289 char *tmp;
290 tmp = _("Could not open directory ");
291 msg = wmalloc(strlen(tmp)+strlen(path)+6);
292 strcpy(msg, tmp);
293 strcat(msg, path);
295 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
296 wfree(msg);
297 wfree(apath);
298 return;
301 /* list contents in the column */
302 while ((dentry = readdir(dir))) {
303 struct stat statb;
305 if (strcmp(dentry->d_name, ".")==0 ||
306 strcmp(dentry->d_name, "..")==0)
307 continue;
309 strcpy(pbuf, apath);
310 strcat(pbuf, "/");
311 strcat(pbuf, dentry->d_name);
313 if (stat(pbuf, &statb)<0)
314 continue;
316 if (statb.st_mode & (S_IRUSR|S_IRGRP|S_IROTH)
317 && statb.st_mode & (S_IFREG|S_IFLNK)) {
318 WMAddListItem(lPtr, dentry->d_name);
321 WMSortListItems(lPtr);
323 closedir(dir);
324 wfree(apath);
325 panel->preview = True;
330 static void
331 setViewedImage(IconPanel *panel, char *file)
333 WMPixmap *pixmap;
334 RColor color;
336 color.red = 0xae;
337 color.green = 0xaa;
338 color.blue = 0xae;
339 color.alpha = 0;
340 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win),
341 file, &color);
342 if (!pixmap) {
343 WMSetButtonEnabled(panel->okButton, False);
345 WMSetLabelText(panel->iconView, _("Could not load image file "));
347 WMSetLabelImage(panel->iconView, NULL);
348 } else {
349 WMSetButtonEnabled(panel->okButton, True);
351 WMSetLabelText(panel->iconView, NULL);
352 WMSetLabelImage(panel->iconView, pixmap);
353 WMReleasePixmap(pixmap);
358 static void
359 listCallback(void *self, void *data)
361 WMList *lPtr = (WMList*)self;
362 IconPanel *panel = (IconPanel*)data;
363 char *path;
365 if (lPtr==panel->dirList) {
366 WMListItem *item = WMGetListSelectedItem(lPtr);
368 if (item == NULL)
369 return;
370 path = item->text;
372 WMSetTextFieldText(panel->fileField, path);
374 WMSetLabelImage(panel->iconView, NULL);
376 WMSetButtonEnabled(panel->okButton, False);
378 WMClearList(panel->iconList);
379 listPixmaps(panel->scr, panel->iconList, path);
380 } else {
381 char *tmp, *iconFile;
382 WMListItem *item = WMGetListSelectedItem(panel->dirList);
384 if (item == NULL)
385 return;
386 path = item->text;
387 tmp = wexpandpath(path);
389 item = WMGetListSelectedItem(panel->iconList);
390 if (item == NULL)
391 return;
392 iconFile = item->text;
394 path = wmalloc(strlen(tmp)+strlen(iconFile)+4);
395 strcpy(path, tmp);
396 strcat(path, "/");
397 strcat(path, iconFile);
398 wfree(tmp);
399 WMSetTextFieldText(panel->fileField, path);
400 setViewedImage(panel, path);
401 wfree(path);
406 static void
407 listIconPaths(WMList *lPtr)
409 char *paths;
410 char *path;
412 paths = wstrdup(wPreferences.icon_path);
414 path = strtok(paths, ":");
416 do {
417 char *tmp;
419 tmp = wexpandpath(path);
420 /* do not sort, because the order implies the order of
421 * directories searched */
422 if (access(tmp, X_OK)==0)
423 WMAddListItem(lPtr, path);
424 wfree(tmp);
425 } while ((path=strtok(NULL, ":"))!=NULL);
427 wfree(paths);
431 void
432 drawIconProc(WMList *lPtr, int index, Drawable d, char *text, int state,
433 WMRect *rect)
435 IconPanel *panel = WMGetHangedData(lPtr);
436 WScreen *scr = panel->scr;
437 GC gc = scr->draw_gc;
438 GC copygc = scr->copy_gc;
439 char *file, *dirfile;
440 WMPixmap *pixmap;
441 WMColor *back;
442 WMSize size;
443 WMScreen *wmscr = WMWidgetScreen(panel->win);
444 RColor color;
445 int x, y, width, height, len;
447 if(!panel->preview) return;
449 x = rect->pos.x;
450 y = rect->pos.y;
451 width = rect->size.width;
452 height = rect->size.height;
454 back = (state & WLDSSelected) ? scr->white : scr->gray;
456 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
457 len = strlen(dirfile)+strlen(text)+4;
458 file = wmalloc(len);
459 snprintf(file, len, "%s/%s", dirfile, text);
460 wfree(dirfile);
462 color.red = WMRedComponentOfColor(back) >> 8;
463 color.green = WMGreenComponentOfColor(back) >> 8;
464 color.blue = WMBlueComponentOfColor(back) >> 8;
465 color.alpha = WMGetColorAlpha(back) >> 8;
467 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
468 wfree(file);
470 if (!pixmap) {
471 /*WMRemoveListItem(lPtr, index);*/
472 return;
475 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
477 XSetClipMask(dpy, gc, None);
478 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54);*/
479 XDrawLine(dpy, d, WMColorGC(scr->white), x, y+height-1, x+width, y+height-1);
481 size = WMGetPixmapSize(pixmap);
483 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
484 XSetClipOrigin(dpy, copygc, x + (width-size.width)/2, y+2);
485 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
486 size.width>100?100:size.width, size.height>64?64:size.height,
487 x + (width-size.width)/2, y+2);
490 int i,j;
491 int fheight = WMFontHeight(panel->normalfont);
492 int tlen = strlen(text);
493 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
494 int ofx, ofy;
496 ofx = x + (width - twidth)/2;
497 ofy = y + 64 - fheight;
499 for(i=-1;i<2;i++)
500 for(j=-1;j<2;j++)
501 WMDrawString(wmscr, d, scr->white, panel->normalfont,
502 ofx+i, ofy+j, text, tlen);
504 WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy,
505 text, tlen);
508 WMReleasePixmap(pixmap);
509 /* I hope it is better to do not use cache / on my box it is fast nuff */
510 XFlush(dpy);
514 static void
515 buttonCallback(void *self, void *clientData)
517 WMButton *bPtr = (WMButton*)self;
518 IconPanel *panel = (IconPanel*)clientData;
521 if (bPtr==panel->okButton) {
522 panel->done = True;
523 panel->result = True;
524 } else if (bPtr==panel->cancelButton) {
525 panel->done = True;
526 panel->result = False;
527 } else if (bPtr==panel->previewButton) {
528 /**** Previewer ****/
529 WMSetButtonEnabled(bPtr, False);
530 WMSetListUserDrawItemHeight(panel->iconList, 68);
531 WMSetListUserDrawProc(panel->iconList, drawIconProc);
532 WMRedisplayWidget(panel->iconList);
533 /* for draw proc to access screen/gc */
534 /*** end preview ***/
536 #if 0
537 else if (bPtr==panel->chooseButton) {
538 WMOpenPanel *op;
540 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
542 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
543 char *path;
544 path = WMGetFilePanelFile(op);
545 WMSetTextFieldText(panel->fileField, path);
546 setViewedImage(panel, path);
547 wfree(path);
549 WMDestroyFilePanel(op);
551 #endif
555 static void
556 keyPressHandler(XEvent *event, void *data)
558 IconPanel *panel = (IconPanel*)data;
559 char buffer[32];
560 int count;
561 KeySym ksym;
562 int iidx;
563 int didx;
564 int item;
565 WMList *list = NULL;
567 if (event->type == KeyRelease)
568 return;
570 buffer[0] = 0;
571 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
574 iidx = WMGetListSelectedItemRow(panel->iconList);
575 didx = WMGetListSelectedItemRow(panel->dirList);
577 switch (ksym) {
578 case XK_Up:
579 if (iidx > 0)
580 item = iidx-1;
581 else
582 item = iidx;
583 list = panel->iconList;
584 break;
585 case XK_Down:
586 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
587 item = iidx+1;
588 else
589 item = iidx;
590 list = panel->iconList;
591 break;
592 case XK_Home:
593 item = 0;
594 list = panel->iconList;
595 break;
596 case XK_End:
597 item = WMGetListNumberOfRows(panel->iconList) - 1;
598 list = panel->iconList;
599 break;
600 case XK_Next:
601 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
602 item = didx + 1;
603 else
604 item = didx;
605 list = panel->dirList;
606 break;
607 case XK_Prior:
608 if (didx > 0)
609 item = didx - 1;
610 else
611 item = 0;
612 list = panel->dirList;
613 break;
614 case XK_Return:
615 WMPerformButtonClick(panel->okButton);
616 break;
617 case XK_Escape:
618 WMPerformButtonClick(panel->cancelButton);
619 break;
622 if (list) {
623 WMSelectListItem(list, item);
624 WMSetListPosition(list, item - 5);
625 listCallback(list, panel);
631 Bool
632 wIconChooserDialog(WScreen *scr, char **file, char *instance, char *class)
634 WWindow *wwin;
635 Window parent;
636 IconPanel *panel;
637 WMColor *color;
638 WMFont *boldFont;
640 panel = wmalloc(sizeof(IconPanel));
641 memset(panel, 0, sizeof(IconPanel));
643 panel->scr = scr;
645 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
646 WMResizeWidget(panel->win, 450, 280);
648 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask|KeyReleaseMask,
649 keyPressHandler, panel);
652 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
653 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
655 panel->dirLabel = WMCreateLabel(panel->win);
656 WMResizeWidget(panel->dirLabel, 200, 20);
657 WMMoveWidget(panel->dirLabel, 10, 7);
658 WMSetLabelText(panel->dirLabel, _("Directories"));
659 WMSetLabelFont(panel->dirLabel, boldFont);
660 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
662 WMSetLabelRelief(panel->dirLabel, WRSunken);
664 panel->iconLabel = WMCreateLabel(panel->win);
665 WMResizeWidget(panel->iconLabel, 140, 20);
666 WMMoveWidget(panel->iconLabel, 215, 7);
667 WMSetLabelText(panel->iconLabel, _("Icons"));
668 WMSetLabelFont(panel->iconLabel, boldFont);
669 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
671 WMReleaseFont(boldFont);
673 color = WMWhiteColor(scr->wmscreen);
674 WMSetLabelTextColor(panel->dirLabel, color);
675 WMSetLabelTextColor(panel->iconLabel, color);
676 WMReleaseColor(color);
678 color = WMDarkGrayColor(scr->wmscreen);
679 WMSetWidgetBackgroundColor(panel->iconLabel, color);
680 WMSetWidgetBackgroundColor(panel->dirLabel, color);
681 WMReleaseColor(color);
683 WMSetLabelRelief(panel->iconLabel, WRSunken);
685 panel->dirList = WMCreateList(panel->win);
686 WMResizeWidget(panel->dirList, 200, 170);
687 WMMoveWidget(panel->dirList, 10, 30);
688 WMSetListAction(panel->dirList, listCallback, panel);
690 panel->iconList = WMCreateList(panel->win);
691 WMResizeWidget(panel->iconList, 140, 170);
692 WMMoveWidget(panel->iconList, 215, 30);
693 WMSetListAction(panel->iconList, listCallback, panel);
695 WMHangData(panel->iconList,panel);
697 panel->previewButton = WMCreateCommandButton(panel->win);
698 WMResizeWidget(panel->previewButton, 75, 26);
699 WMMoveWidget(panel->previewButton, 365, 130);
700 WMSetButtonText(panel->previewButton, _("Preview"));
701 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
703 panel->iconView = WMCreateLabel(panel->win);
704 WMResizeWidget(panel->iconView, 75, 75);
705 WMMoveWidget(panel->iconView, 365, 40);
706 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
707 WMSetLabelRelief(panel->iconView, WRSunken);
708 WMSetLabelTextAlignment(panel->iconView, WACenter);
710 panel->fileLabel = WMCreateLabel(panel->win);
711 WMResizeWidget(panel->fileLabel, 80, 20);
712 WMMoveWidget(panel->fileLabel, 10, 210);
713 WMSetLabelText(panel->fileLabel, _("File Name:"));
715 panel->fileField = WMCreateTextField(panel->win);
716 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
717 WMResizeWidget(panel->fileField, 345, 20);
718 WMMoveWidget(panel->fileField, 95, 210);
719 WMSetTextFieldEditable(panel->fileField, False);
721 panel->okButton = WMCreateCommandButton(panel->win);
722 WMResizeWidget(panel->okButton, 80, 26);
723 WMMoveWidget(panel->okButton, 360, 240);
724 WMSetButtonText(panel->okButton, _("OK"));
725 WMSetButtonEnabled(panel->okButton, False);
726 WMSetButtonAction(panel->okButton, buttonCallback, panel);
728 panel->cancelButton = WMCreateCommandButton(panel->win);
729 WMResizeWidget(panel->cancelButton, 80, 26);
730 WMMoveWidget(panel->cancelButton, 270, 240);
731 WMSetButtonText(panel->cancelButton, _("Cancel"));
732 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
733 #if 0
734 panel->chooseButton = WMCreateCommandButton(panel->win);
735 WMResizeWidget(panel->chooseButton, 110, 26);
736 WMMoveWidget(panel->chooseButton, 150, 240);
737 WMSetButtonText(panel->chooseButton, _("Choose File"));
738 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
739 #endif
740 WMRealizeWidget(panel->win);
741 WMMapSubwidgets(panel->win);
743 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
745 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
748 char *tmp;
749 int len = (instance ? strlen(instance) : 0)
750 + (class ? strlen(class) : 0) + 32;
751 WMPoint center;
753 tmp = wmalloc(len);
755 if (tmp && (instance || class))
756 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
757 else
758 strcpy(tmp, _("Icon Chooser"));
760 center = getCenter(scr, 450, 280);
762 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x,center.y,
763 450, 280);
764 wfree(tmp);
767 /* put icon paths in the list */
768 listIconPaths(panel->dirList);
770 WMMapWidget(panel->win);
772 wWindowMap(wwin);
774 while (!panel->done) {
775 XEvent event;
777 WMNextEvent(dpy, &event);
778 WMHandleEvent(&event);
781 if (panel->result) {
782 char *defaultPath, *wantedPath;
784 /* check if the file the user selected is not the one that
785 * would be loaded by default with the current search path */
786 *file = WMGetListSelectedItem(panel->iconList)->text;
787 if ((*file)[0]==0) {
788 wfree(*file);
789 *file = NULL;
790 } else {
791 defaultPath = FindImage(wPreferences.icon_path, *file);
792 wantedPath = WMGetTextFieldText(panel->fileField);
793 /* if the file is not the default, use full path */
794 if (strcmp(wantedPath, defaultPath)!=0) {
795 *file = wantedPath;
796 } else {
797 *file = wstrdup(*file);
798 wfree(wantedPath);
800 wfree(defaultPath);
802 } else {
803 *file = NULL;
806 WMReleaseFont(panel->normalfont);
808 WMUnmapWidget(panel->win);
810 WMDestroyWidget(panel->win);
812 wUnmanageWindow(wwin, False, False);
814 wfree(panel);
816 XDestroyWindow(dpy, parent);
818 return panel->result;
823 ***********************************************************************
824 * Info Panel
825 ***********************************************************************
829 typedef struct {
830 WScreen *scr;
832 WWindow *wwin;
834 WMWindow *win;
836 WMLabel *logoL;
837 WMLabel *name1L;
838 WMFrame *lineF;
839 WMLabel *name2L;
841 WMLabel *versionL;
843 WMLabel *infoL;
845 WMLabel *copyrL;
847 #ifdef SILLYNESS
848 WMHandlerID timer;
849 int cycle;
850 RImage *icon;
851 RImage *pic;
852 WMPixmap *oldPix;
853 WMFont *oldFont;
854 char *str;
855 int x;
856 #endif
857 } InfoPanel;
861 #define COPYRIGHT_TEXT \
862 "Copyright \xa9 1997-2003 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
863 "Copyright \xa9 1998-2003 Dan Pascu <dan@windowmaker.org>"
867 static InfoPanel *thePanel = NULL;
869 static void
870 destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
872 #ifdef SILLYNESS
873 if (thePanel->timer) {
874 WMDeleteTimerHandler(thePanel->timer);
876 if (thePanel->oldPix) {
877 WMReleasePixmap(thePanel->oldPix);
879 if (thePanel->oldFont) {
880 WMReleaseFont(thePanel->oldFont);
882 if (thePanel->icon) {
883 RReleaseImage(thePanel->icon);
885 if (thePanel->pic) {
886 RReleaseImage(thePanel->pic);
888 #endif /* SILLYNESS */
889 WMUnmapWidget(thePanel);
891 wUnmanageWindow(thePanel->wwin, False, False);
893 WMDestroyWidget(thePanel->win);
895 wfree(thePanel);
897 thePanel = NULL;
901 #ifdef SILLYNESS
903 extern WMPixmap *DoXThing();
904 extern Bool InitXThing();
906 static void
907 logoPushCallback(void *data)
909 InfoPanel *panel = (InfoPanel*)data;
910 char buffer[512];
911 int i;
912 static int oldi = 0;
913 int len;
914 static int jingobeu[] = {
915 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
916 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
917 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
919 static int c = 0;
921 if (panel->x) {
922 XKeyboardControl kc;
923 XKeyboardState ksave;
924 unsigned long mask = KBBellPitch|KBBellDuration|KBBellPercent;
926 XGetKeyboardControl(dpy, &ksave);
928 if (panel->x > 0) {
929 if(jingobeu[panel->x-1]==0) {
930 panel->x=-1;
931 } else if (jingobeu[panel->x-1]<0) {
932 panel->x++;
933 c=jingobeu[panel->x-1]/50;
934 panel->x++;
935 } else if (c==0) {
936 kc.bell_percent=50;
937 kc.bell_pitch=jingobeu[panel->x-1];
938 panel->x++;
939 kc.bell_duration=jingobeu[panel->x-1];
940 c=jingobeu[panel->x-1]/50;
941 panel->x++;
942 XChangeKeyboardControl(dpy, mask, &kc);
943 XBell(dpy, 50);
944 XFlush(dpy);
945 } else {
946 c--;
949 if (!(panel->cycle % 4)) {
950 WMPixmap *p;
952 p = DoXThing(panel->wwin);
953 WMSetLabelImage(panel->logoL, p);
955 kc.bell_pitch = ksave.bell_pitch;
956 kc.bell_percent = ksave.bell_percent;
957 kc.bell_duration = ksave.bell_duration;
958 XChangeKeyboardControl(dpy, mask, &kc);
959 } else if (panel->cycle < 30) {
960 RImage *image;
961 WMPixmap *pix;
962 RColor gray;
964 gray.red = 0xae; gray.green = 0xaa;
965 gray.blue = 0xae; gray.alpha = 0;
967 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
968 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
969 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
970 RReleaseImage(image);
971 WMSetLabelImage(panel->logoL, pix);
972 WMReleasePixmap(pix);
975 /* slow down text a little */
976 i = (int)(panel->cycle * 50.0/85.0)%200;
978 if (i != oldi) {
979 len = strlen(panel->str);
981 strncpy(buffer, panel->str, i<len ? i : len);
982 if (i >= len)
983 memset(&buffer[len], ' ', i-len);
985 strncpy(buffer, panel->str, i<len ? i : len);
986 if (i >= len)
987 memset(&buffer[len], ' ', i-len);
988 buffer[i]=0;
990 WMSetLabelText(panel->versionL, buffer);
992 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
994 oldi = i;
997 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
998 panel->cycle++;
1002 static void
1003 handleLogoPush(XEvent *event, void *data)
1005 InfoPanel *panel = (InfoPanel*)data;
1006 static int broken = 0;
1007 static int clicks = 0;
1008 static char *pic_data[] = {
1009 "45 45 57 1",
1010 " c None",
1011 ". c #000000",
1012 "X c #383C00",
1013 "o c #515500",
1014 "O c #616100",
1015 "+ c #616900",
1016 "@ c #696D00",
1017 "# c #697100",
1018 "$ c #495100",
1019 "% c #202800",
1020 "& c #969600",
1021 "* c #CFCF00",
1022 "= c #D7DB00",
1023 "- c #D7D700",
1024 "; c #C7CB00",
1025 ": c #A6AA00",
1026 "> c #494900",
1027 ", c #8E8E00",
1028 "< c #DFE700",
1029 "1 c #F7FF00",
1030 "2 c #FFFF00",
1031 "3 c #E7EB00",
1032 "4 c #B6B600",
1033 "5 c #595900",
1034 "6 c #717500",
1035 "7 c #AEB200",
1036 "8 c #CFD300",
1037 "9 c #E7EF00",
1038 "0 c #EFF300",
1039 "q c #9EA200",
1040 "w c #F7FB00",
1041 "e c #F7F700",
1042 "r c #BEBE00",
1043 "t c #8E9200",
1044 "y c #EFF700",
1045 "u c #969A00",
1046 "i c #414500",
1047 "p c #595D00",
1048 "a c #E7E700",
1049 "s c #C7C700",
1050 "d c #797D00",
1051 "f c #BEC300",
1052 "g c #DFE300",
1053 "h c #868600",
1054 "j c #EFEF00",
1055 "k c #9E9E00",
1056 "l c #616500",
1057 "z c #DFDF00",
1058 "x c #868A00",
1059 "c c #969200",
1060 "v c #B6BA00",
1061 "b c #A6A600",
1062 "n c #8E8A00",
1063 "m c #717100",
1064 "M c #AEAE00",
1065 "N c #AEAA00",
1066 "B c #868200",
1067 " ............... ",
1068 " ....XoO+@##+O$%.... ",
1069 " ...%X&*========-;;:o... ",
1070 " ...>.>,<122222222222134@... ",
1071 " ..>5678912222222222222220q%.. ",
1072 " ..$.&-w2222222222222222222er>.. ",
1073 " ..O.t31222222222222222222222y4>.. ",
1074 " ...O5u3222222222222222222222222yri... ",
1075 " ..>p&a22222222222222222222222222wso.. ",
1076 " ..ids91222222222222222222222222222wfi.. ",
1077 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1078 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1079 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1080 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1081 "..io*222222222&...u22222222yt..%*22222220:%. ",
1082 "..>k02222222227...f222222222v..X=222222229t. ",
1083 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1084 ".%vw222222222221y2222222222219*y2222222222wd.",
1085 ".X;2222222222222222222222222222222222222222b.",
1086 ".i*2222222222222222222222222222222222222222v.",
1087 ".i*2222222222222222222222222222222222222222;.",
1088 ".i*22222222222222222222222222222222222222228.",
1089 ".>*2222222222222222222222222222222222222222=.",
1090 ".i*22222222222222222222222222222222222222228.",
1091 ".i*2222222222222222222222222222222222222222;.",
1092 ".X*222222222222222222222222222222we12222222r.",
1093 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1094 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1095 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1096 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1097 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1098 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1099 " ...:e2222218mdz22222222222222a&$vw222220@...",
1100 " ...O-122222y:.u02222222222229q$uj222221r... ",
1101 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1102 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1103 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1104 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1105 " ..Xb9122222109g-****;<y22221zn%... ",
1106 " ..X&801222222222222222222w-h.... ",
1107 " ...o:=022222222222222221=lX... ",
1108 " ..X@:;3w2222222222210fO... ",
1109 " ...XX&v8<30000003-N@... ",
1110 " .....XmnbN:q&Bo.... ",
1111 " ............ "
1113 static char *msgs[] = {
1114 "Have a nice day!",
1115 "Focus follow mouse users will burn in hell!!!",
1116 "Mooo Canada!!!!",
1117 "Hi! My name is bobby...",
1118 "AHH! The neurotic monkeys are after me!",
1119 "WE GET SIGNAL",
1120 "HOW ARE YOU GENTLEMEN?",
1121 "WHAT YOU SAY??",
1122 "SOMEBODY SET UP US THE BOMB",
1123 "ALL YOUR BASE ARE BELONG TO US!",
1124 "Oh My God!!! Larry is back!"
1128 clicks++;
1130 if (!panel->timer && !broken && clicks > 0) {
1131 WMFont *font;
1133 panel->x = 0;
1134 clicks = 0;
1135 if (!panel->icon) {
1136 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1137 if (!panel->icon) {
1138 broken = 1;
1139 return;
1140 } else {
1141 RColor color;
1143 color.red = 0xae; color.green = 0xaa;
1144 color.blue = 0xae; color.alpha = 0;
1146 panel->icon = RCloneImage(panel->icon);
1147 RCombineImageWithColor(panel->icon, &color);
1150 if (!panel->pic) {
1151 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1152 if (!panel->pic) {
1153 broken = 1;
1154 RReleaseImage(panel->icon);
1155 panel->icon = NULL;
1156 return;
1160 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1162 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1163 panel->cycle = 0;
1164 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1165 /* If we don't use a fixed font, scrolling will be jumpy */
1166 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1167 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1168 WMRetainFont(panel->oldFont);
1169 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*");
1170 if (font) {
1171 WMSetLabelFont(panel->versionL, font);
1172 WMReleaseFont(font);
1174 WMSetLabelText(panel->versionL, "");
1175 } else if (panel->timer) {
1176 char version[20];
1178 panel->x = 0;
1179 clicks = 0;
1180 WMSetLabelImage(panel->logoL, panel->oldPix);
1181 WMReleasePixmap(panel->oldPix);
1182 panel->oldPix = NULL;
1184 WMDeleteTimerHandler(panel->timer);
1185 panel->timer = NULL;
1187 WMSetLabelFont(panel->versionL, panel->oldFont);
1188 if (panel->oldFont) {
1189 WMReleaseFont(panel->oldFont);
1190 panel->oldFont = NULL;
1192 snprintf(version, sizeof(version), _("Version %s"), VERSION);
1193 WMSetLabelText(panel->versionL, version);
1194 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1198 XEvent ev;
1199 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1200 ButtonPress, &ev));
1203 #endif /* SILLYNESS */
1206 void
1207 wShowInfoPanel(WScreen *scr)
1209 InfoPanel *panel;
1210 WMPixmap *logo;
1211 WMSize size;
1212 WMFont *font;
1213 char *strbuf = NULL;
1214 char buffer[256];
1215 Window parent;
1216 WWindow *wwin;
1217 char **strl;
1218 int i, width, sepWidth;
1219 char *visuals[] = {
1220 "StaticGray",
1221 "GrayScale",
1222 "StaticColor",
1223 "PseudoColor",
1224 "TrueColor",
1225 "DirectColor"
1229 if (thePanel) {
1230 if (thePanel->scr == scr) {
1231 wRaiseFrame(thePanel->wwin->frame->core);
1232 wSetFocusTo(scr, thePanel->wwin);
1234 return;
1237 panel = wmalloc(sizeof(InfoPanel));
1238 memset(panel, 0, sizeof(InfoPanel));
1240 panel->scr = scr;
1242 panel->win = WMCreateWindow(scr->wmscreen, "info");
1243 WMResizeWidget(panel->win, 390, 230);
1245 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor*)NULL);
1246 if (!logo) {
1247 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1249 if (logo) {
1250 size = WMGetPixmapSize(logo);
1251 panel->logoL = WMCreateLabel(panel->win);
1252 WMResizeWidget(panel->logoL, 64, 64);
1253 WMMoveWidget(panel->logoL, 30, 20);
1254 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1255 WMSetLabelImage(panel->logoL, logo);
1256 #ifdef SILLYNESS
1257 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1258 handleLogoPush, panel);
1259 #endif
1260 WMReleasePixmap(logo);
1263 sepWidth = 3;
1264 panel->name1L = WMCreateLabel(panel->win);
1265 WMResizeWidget(panel->name1L, 240, 30 - sepWidth);
1266 WMMoveWidget(panel->name1L, 100, 30);
1268 if (WMIsAntialiasingEnabled(scr->wmscreen)) {
1269 font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1270 } else {
1271 font = WMCreateFont(scr->wmscreen, "-*-utopia-*-r-*-*-25-*");
1272 font = font ? font : WMBoldSystemFontOfSize(scr->wmscreen, 24);
1274 strbuf = "Window Maker";
1275 if (font) {
1276 width = WMWidthOfString(font, strbuf, strlen(strbuf));
1277 WMSetLabelFont(panel->name1L, font);
1278 WMReleaseFont(font);
1280 WMSetLabelTextAlignment(panel->name1L, WACenter);
1281 WMSetLabelText(panel->name1L, strbuf);
1283 panel->lineF = WMCreateFrame(panel->win);
1284 WMResizeWidget(panel->lineF, width, sepWidth);
1285 WMMoveWidget(panel->lineF, 100+(240-width)/2, 60 - sepWidth);
1286 WMSetFrameRelief(panel->lineF, WRSimple);
1287 WMSetWidgetBackgroundColor(panel->lineF, scr->black);
1289 panel->name2L = WMCreateLabel(panel->win);
1290 WMResizeWidget(panel->name2L, 240, 24);
1291 WMMoveWidget(panel->name2L, 100, 60);
1292 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1293 if (font) {
1294 WMSetLabelFont(panel->name2L, font);
1295 WMReleaseFont(font);
1296 font = NULL;
1298 WMSetLabelTextAlignment(panel->name2L, WACenter);
1299 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1301 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1302 panel->versionL = WMCreateLabel(panel->win);
1303 WMResizeWidget(panel->versionL, 310, 16);
1304 WMMoveWidget(panel->versionL, 30, 95);
1305 WMSetLabelTextAlignment(panel->versionL, WARight);
1306 WMSetLabelText(panel->versionL, buffer);
1307 WMSetLabelWraps(panel->versionL, False);
1309 panel->copyrL = WMCreateLabel(panel->win);
1310 WMResizeWidget(panel->copyrL, 360, 40);
1311 WMMoveWidget(panel->copyrL, 15, 185);
1312 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1313 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1314 /* we want the (c) character in the font, so don't use a FontSet here */
1315 // fix this -Dan font = WMCreateFontWithFlags(scr->wmscreen, "SystemFont-11", WFNormalFont);
1316 font = WMSystemFontOfSize(scr->wmscreen, 11);
1317 if (font) {
1318 WMSetLabelFont(panel->copyrL, font);
1319 WMReleaseFont(font);
1320 font = NULL;
1323 strbuf = NULL;
1324 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1325 (unsigned)scr->w_visual->visualid,
1326 visuals[scr->w_visual->class], scr->w_depth);
1328 strbuf = wstrappend(strbuf, buffer);
1330 switch (scr->w_depth) {
1331 case 15:
1332 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1333 break;
1334 case 16:
1335 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1336 break;
1337 case 24:
1338 case 32:
1339 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1340 break;
1341 default:
1342 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1<<scr->w_depth);
1343 strbuf = wstrappend(strbuf, buffer);
1344 break;
1348 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1350 struct mallinfo ma = mallinfo();
1351 snprintf(buffer, sizeof(buffer),
1352 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1353 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1355 strbuf = wstrappend(strbuf, buffer);
1357 #endif
1359 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1360 strl = RSupportedFileFormats();
1361 for (i=0; strl[i]!=NULL; i++) {
1362 strbuf = wstrappend(strbuf, strl[i]);
1363 strbuf = wstrappend(strbuf, " ");
1366 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1368 char *list[8];
1369 char buf[80];
1370 int j = 0;
1372 #ifdef MWM_HINTS
1373 list[j++] = "MWM";
1374 #endif
1375 #ifdef KWM_HINTS
1376 list[j++] = "KDE";
1377 #endif
1378 #ifdef GNOME_STUFF
1379 list[j++] = "GNOME";
1380 #endif
1381 #ifdef OLWM_HINTS
1382 list[j++] = "OLWM";
1383 #endif
1385 buf[0] = 0;
1386 for (i = 0; i < j; i++) {
1387 if (i > 0) {
1388 if (i == j - 1)
1389 strcat(buf, _(" and "));
1390 else
1391 strcat(buf, ", ");
1393 strcat(buf, list[i]);
1395 strbuf = wstrappend(strbuf, buf);
1398 if (wPreferences.no_sound) {
1399 strbuf = wstrappend(strbuf, _("\nSound disabled"));
1400 } else {
1401 strbuf = wstrappend(strbuf, _("\nSound enabled"));
1404 #ifdef XFT
1405 strbuf = wstrappend(strbuf, _("; Antialiased text"));
1406 #endif
1409 panel->infoL = WMCreateLabel(panel->win);
1410 WMResizeWidget(panel->infoL, 350, 75);
1411 WMMoveWidget(panel->infoL, 15, 115);
1412 WMSetLabelText(panel->infoL, strbuf);
1413 font = WMSystemFontOfSize(scr->wmscreen, 11);
1414 if (font) {
1415 WMSetLabelFont(panel->infoL, font);
1416 WMReleaseFont(font);
1417 font = NULL;
1419 wfree(strbuf);
1422 WMRealizeWidget(panel->win);
1423 WMMapSubwidgets(panel->win);
1425 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1427 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1429 WMMapWidget(panel->win);
1432 WMPoint center = getCenter(scr, 382, 230);
1434 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1435 center.x, center.y,
1436 382, 230);
1439 WSETUFLAG(wwin, no_closable, 0);
1440 WSETUFLAG(wwin, no_close_button, 0);
1441 #ifdef XKB_BUTTON_HINT
1442 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1443 #endif
1444 wWindowUpdateButtonImages(wwin);
1445 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1446 wwin->frame->on_click_right = destroyInfoPanel;
1448 wWindowMap(wwin);
1450 panel->wwin = wwin;
1452 thePanel = panel;
1453 #ifdef SILLYNESS
1454 if (InitXThing(panel->scr)) {
1455 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1456 panel->cycle = 0;
1457 panel->x = 1;
1458 panel->str = _("Merry Christmas!");
1459 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1461 #endif
1466 ***********************************************************************
1467 * Legal Panel
1468 ***********************************************************************
1471 typedef struct {
1472 WScreen *scr;
1474 WWindow *wwin;
1476 WMWindow *win;
1478 WMLabel *licenseL;
1479 } LegalPanel;
1482 static LegalPanel *legalPanel = NULL;
1484 static void
1485 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1487 WMUnmapWidget(legalPanel->win);
1489 WMDestroyWidget(legalPanel->win);
1491 wUnmanageWindow(legalPanel->wwin, False, False);
1493 wfree(legalPanel);
1495 legalPanel = NULL;
1499 void
1500 wShowLegalPanel(WScreen *scr)
1502 LegalPanel *panel;
1503 Window parent;
1504 WWindow *wwin;
1506 if (legalPanel) {
1507 if (legalPanel->scr == scr) {
1508 wRaiseFrame(legalPanel->wwin->frame->core);
1509 wSetFocusTo(scr, legalPanel->wwin);
1511 return;
1514 panel = wmalloc(sizeof(LegalPanel));
1516 panel->scr = scr;
1518 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1519 WMResizeWidget(panel->win, 420, 250);
1522 panel->licenseL = WMCreateLabel(panel->win);
1523 WMSetLabelWraps(panel->licenseL, True);
1524 WMResizeWidget(panel->licenseL, 400, 230);
1525 WMMoveWidget(panel->licenseL, 10, 10);
1526 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1527 WMSetLabelText(panel->licenseL,
1528 _(" Window Maker is free software; you can redistribute it and/or\n"
1529 "modify it under the terms of the GNU General Public License as\n"
1530 "published by the Free Software Foundation; either version 2 of the\n"
1531 "License, or (at your option) any later version.\n\n"
1532 " Window Maker is distributed in the hope that it will be useful,\n"
1533 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1534 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1535 "See the GNU General Public License for more details.\n\n"
1536 " You should have received a copy of the GNU General Public\n"
1537 "License along with this program; if not, write to the Free Software\n"
1538 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1539 "02111-1307, USA."));
1540 WMSetLabelRelief(panel->licenseL, WRGroove);
1542 WMRealizeWidget(panel->win);
1543 WMMapSubwidgets(panel->win);
1545 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1547 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1550 WMPoint center = getCenter(scr, 420, 250);
1552 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1553 center.x, center.y,
1554 420, 250);
1557 WSETUFLAG(wwin, no_closable, 0);
1558 WSETUFLAG(wwin, no_close_button, 0);
1559 wWindowUpdateButtonImages(wwin);
1560 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1561 #ifdef XKB_BUTTON_HINT
1562 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1563 #endif
1564 wwin->frame->on_click_right = destroyLegalPanel;
1566 panel->wwin = wwin;
1568 WMMapWidget(panel->win);
1570 wWindowMap(wwin);
1572 legalPanel = panel;
1577 ***********************************************************************
1578 * Crashing Dialog Panel
1579 ***********************************************************************
1582 extern WDDomain *WDWindowAttributes;
1585 typedef struct _CrashPanel {
1586 WMWindow *win; /* main window */
1588 WMLabel *iconL; /* application icon */
1589 WMLabel *nameL; /* title of panel */
1591 WMFrame *sepF; /* separator frame */
1593 WMLabel *noteL; /* Title of note */
1594 WMLabel *note2L; /* body of note with what happened */
1596 WMFrame *whatF; /* "what to do next" frame */
1597 WMPopUpButton *whatP; /* action selection popup button */
1599 WMButton *okB; /* ok button */
1601 Bool done; /* if finished with this dialog */
1602 int action; /* what to do after */
1604 KeyCode retKey;
1606 } CrashPanel;
1609 static void
1610 handleKeyPress(XEvent *event, void *clientData)
1612 CrashPanel *panel = (CrashPanel*)clientData;
1614 if (event->xkey.keycode == panel->retKey) {
1615 WMPerformButtonClick(panel->okB);
1620 static void
1621 okButtonCallback(void *self, void *clientData)
1623 CrashPanel *panel = (CrashPanel*)clientData;
1625 panel->done = True;
1629 static void
1630 setCrashAction(void *self, void *clientData)
1632 WMPopUpButton *pop = (WMPopUpButton*)self;
1633 CrashPanel *panel = (CrashPanel*)clientData;
1635 panel->action = WMGetPopUpButtonSelectedItem(pop);
1639 static WMPixmap*
1640 getWindowMakerIconImage(WMScreen *scr)
1642 WMPropList *dict, *key, *option, *value=NULL;
1643 WMPixmap *pix=NULL;
1644 char *path;
1646 WMPLSetCaseSensitive(True);
1648 key = WMCreatePLString("Logo.WMPanel");
1649 option = WMCreatePLString("Icon");
1651 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1653 if (dict) {
1654 value = WMGetFromPLDictionary(dict, option);
1657 WMReleasePropList(key);
1658 WMReleasePropList(option);
1660 WMPLSetCaseSensitive(False);
1662 if (value && WMIsPLString(value)) {
1663 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1665 if (path) {
1666 RColor gray;
1668 gray.red = 0xae; gray.green = 0xaa;
1669 gray.blue = 0xae; gray.alpha = 0;
1671 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1672 wfree(path);
1676 return pix;
1680 #define PWIDTH 295
1681 #define PHEIGHT 345
1685 wShowCrashingDialogPanel(int whatSig)
1687 CrashPanel *panel;
1688 WMScreen *scr;
1689 WMFont *font;
1690 WMPixmap *logo;
1691 int screen_no, scr_width, scr_height;
1692 int action;
1693 char buf[256];
1695 panel = wmalloc(sizeof(CrashPanel));
1696 memset(panel, 0, sizeof(CrashPanel));
1698 screen_no = DefaultScreen(dpy);
1699 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1700 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1702 scr = WMCreateScreen(dpy, screen_no);
1703 if (!scr) {
1704 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1705 return WMAbort;
1708 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1710 panel->win = WMCreateWindow(scr, "crashingDialog");
1711 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1712 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1714 logo = getWindowMakerIconImage(scr);
1715 if (logo) {
1716 panel->iconL = WMCreateLabel(panel->win);
1717 WMResizeWidget(panel->iconL, 64, 64);
1718 WMMoveWidget(panel->iconL, 10, 10);
1719 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1720 WMSetLabelImage(panel->iconL, logo);
1723 panel->nameL = WMCreateLabel(panel->win);
1724 WMResizeWidget(panel->nameL, 190, 18);
1725 WMMoveWidget(panel->nameL, 80, 35);
1726 WMSetLabelTextAlignment(panel->nameL, WALeft);
1727 font = WMBoldSystemFontOfSize(scr, 18);
1728 WMSetLabelFont(panel->nameL, font);
1729 WMReleaseFont(font);
1730 WMSetLabelText(panel->nameL, _("Fatal error"));
1732 panel->sepF = WMCreateFrame(panel->win);
1733 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1734 WMMoveWidget(panel->sepF, -2, 80);
1736 panel->noteL = WMCreateLabel(panel->win);
1737 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1738 WMMoveWidget(panel->noteL, 10, 90);
1739 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1740 #ifdef SYS_SIGLIST_DECLARED
1741 snprintf(buf, sizeof(buf), _("Window Maker received signal %i\n(%s)."),
1742 whatSig, sys_siglist[whatSig]);
1743 #else
1744 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1745 #endif
1746 WMSetLabelText(panel->noteL, buf);
1748 panel->note2L = WMCreateLabel(panel->win);
1749 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1750 WMMoveWidget(panel->note2L, 10, 130);
1751 WMSetLabelTextAlignment(panel->note2L, WALeft);
1752 WMSetLabelText(panel->note2L,
1753 _(" This fatal error occured probably due to a bug."
1754 " Please fill the included BUGFORM and "
1755 "report it to bugs@windowmaker.org."));
1756 WMSetLabelWraps(panel->note2L, True);
1759 panel->whatF = WMCreateFrame(panel->win);
1760 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1761 WMMoveWidget(panel->whatF, 10, 240);
1762 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1764 panel->whatP = WMCreatePopUpButton(panel->whatF);
1765 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1766 WMMoveWidget(panel->whatP, 35, 20);
1767 WMSetPopUpButtonPullsDown(panel->whatP, False);
1768 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1769 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1770 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1771 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1772 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1773 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1774 panel->action = WMRestart;
1776 WMMapSubwidgets(panel->whatF);
1778 panel->okB = WMCreateCommandButton(panel->win);
1779 WMResizeWidget(panel->okB, 80, 26);
1780 WMMoveWidget(panel->okB, 205, 309);
1781 WMSetButtonText(panel->okB, _("OK"));
1782 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1783 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1784 WMSetButtonImagePosition(panel->okB, WIPRight);
1785 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1787 panel->done = 0;
1789 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1790 handleKeyPress, panel);
1792 WMRealizeWidget(panel->win);
1793 WMMapSubwidgets(panel->win);
1795 WMMapWidget(panel->win);
1797 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1799 while (!panel->done) {
1800 XEvent event;
1802 WMNextEvent(dpy, &event);
1803 WMHandleEvent(&event);
1806 action = panel->action;
1808 WMUnmapWidget(panel->win);
1809 WMDestroyWidget(panel->win);
1810 wfree(panel);
1812 return action;
1818 /*****************************************************************************
1819 * About GNUstep Panel
1820 *****************************************************************************/
1823 static void
1824 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1825 unsigned long blackPixel, unsigned long whitePixel)
1827 GC gc;
1828 XGCValues gcv;
1829 XRectangle rects[3];
1831 gcv.foreground = blackPixel;
1832 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1834 XFillArc(dpy, d, gc, width/45, height/45,
1835 width - 2*width/45, height - 2*height/45, 0, 360*64);
1837 rects[0].x = 0;
1838 rects[0].y = 37*height/45;
1839 rects[0].width = width/3;
1840 rects[0].height = height - rects[0].y;
1842 rects[1].x = rects[0].width;
1843 rects[1].y = height/2;
1844 rects[1].width = width - 2*width/3;
1845 rects[1].height = height - rects[1].y;
1847 rects[2].x = 2*width/3;
1848 rects[2].y = height - 37*height/45;
1849 rects[2].width = width/3;
1850 rects[2].height = height - rects[2].y;
1852 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1853 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1855 XSetForeground(dpy, gc, whitePixel);
1856 XFillArc(dpy, d, gc, width/45, height/45,
1857 width - 2*width/45, height - 2*height/45, 0, 360*64);
1859 XFreeGC(dpy, gc);
1863 typedef struct {
1864 WScreen *scr;
1866 WWindow *wwin;
1868 WMWindow *win;
1870 WMLabel *gstepL;
1871 WMLabel *textL;
1872 } GNUstepPanel;
1875 static GNUstepPanel *gnustepPanel = NULL;
1877 static void
1878 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1880 WMUnmapWidget(gnustepPanel->win);
1882 WMDestroyWidget(gnustepPanel->win);
1884 wUnmanageWindow(gnustepPanel->wwin, False, False);
1886 wfree(gnustepPanel);
1888 gnustepPanel = NULL;
1892 void
1893 wShowGNUstepPanel(WScreen *scr)
1895 GNUstepPanel *panel;
1896 Window parent;
1897 WWindow *wwin;
1898 WMPixmap *pixmap;
1899 WMColor *color;
1901 if (gnustepPanel) {
1902 if (gnustepPanel->scr == scr) {
1903 wRaiseFrame(gnustepPanel->wwin->frame->core);
1904 wSetFocusTo(scr, gnustepPanel->wwin);
1906 return;
1909 panel = wmalloc(sizeof(GNUstepPanel));
1911 panel->scr = scr;
1913 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1914 WMResizeWidget(panel->win, 325, 205);
1916 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1917 WMScreenDepth(scr->wmscreen), True);
1919 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1921 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1922 WMColorPixel(color), scr->white_pixel);
1924 WMReleaseColor(color);
1926 XSetForeground(dpy, scr->mono_gc, 0);
1927 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1928 130, 130);
1929 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1931 panel->gstepL = WMCreateLabel(panel->win);
1932 WMResizeWidget(panel->gstepL, 285, 64);
1933 WMMoveWidget(panel->gstepL, 20, 0);
1934 WMSetLabelTextAlignment(panel->gstepL, WARight);
1935 WMSetLabelText(panel->gstepL, "GNUstep");
1937 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1939 WMSetLabelFont(panel->gstepL, font);
1940 WMReleaseFont(font);
1943 panel->textL = WMCreateLabel(panel->win);
1944 WMResizeWidget(panel->textL, 305, 140);
1945 WMMoveWidget(panel->textL, 10, 50);
1946 WMSetLabelTextAlignment(panel->textL, WARight);
1947 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1948 WMSetLabelText(panel->textL,
1949 _("Window Maker is part of the GNUstep project.\n"\
1950 "The GNUstep project aims to create a free\n"\
1951 "implementation of the OpenStep(tm) specification\n"\
1952 "which is a object-oriented framework for\n"\
1953 "creating advanced graphical, multi-platform\n"\
1954 "applications. Additionally, a development and\n"\
1955 "user desktop enviroment will be created on top\n"\
1956 "of the framework. For more information about\n"\
1957 "GNUstep, please visit: www.gnustep.org"));
1958 WMSetLabelImage(panel->textL, pixmap);
1960 WMReleasePixmap(pixmap);
1962 WMRealizeWidget(panel->win);
1963 WMMapSubwidgets(panel->win);
1965 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1967 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1970 WMPoint center = getCenter(scr, 325, 200);
1972 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
1973 center.x, center.y,
1974 325, 200);
1977 WSETUFLAG(wwin, no_closable, 0);
1978 WSETUFLAG(wwin, no_close_button, 0);
1979 wWindowUpdateButtonImages(wwin);
1980 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1981 #ifdef XKB_BUTTON_HINT
1982 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1983 #endif
1984 wwin->frame->on_click_right = destroyGNUstepPanel;
1986 panel->wwin = wwin;
1988 WMMapWidget(panel->win);
1990 wWindowMap(wwin);
1992 gnustepPanel = panel;