changed indentation to use spaces only
[wmaker-crm.git] / src / dialog.c
blobc021152d32260459ef0cfd9292fc72c1039a6099
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
71 getCenter(WScreen *scr, int width, int height)
73 return wGetPointToCenterRectInHead(scr, 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;
639 Bool result;
641 panel = wmalloc(sizeof(IconPanel));
642 memset(panel, 0, sizeof(IconPanel));
644 panel->scr = scr;
646 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
647 WMResizeWidget(panel->win, 450, 280);
649 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask|KeyReleaseMask,
650 keyPressHandler, panel);
653 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
654 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
656 panel->dirLabel = WMCreateLabel(panel->win);
657 WMResizeWidget(panel->dirLabel, 200, 20);
658 WMMoveWidget(panel->dirLabel, 10, 7);
659 WMSetLabelText(panel->dirLabel, _("Directories"));
660 WMSetLabelFont(panel->dirLabel, boldFont);
661 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
663 WMSetLabelRelief(panel->dirLabel, WRSunken);
665 panel->iconLabel = WMCreateLabel(panel->win);
666 WMResizeWidget(panel->iconLabel, 140, 20);
667 WMMoveWidget(panel->iconLabel, 215, 7);
668 WMSetLabelText(panel->iconLabel, _("Icons"));
669 WMSetLabelFont(panel->iconLabel, boldFont);
670 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
672 WMReleaseFont(boldFont);
674 color = WMWhiteColor(scr->wmscreen);
675 WMSetLabelTextColor(panel->dirLabel, color);
676 WMSetLabelTextColor(panel->iconLabel, color);
677 WMReleaseColor(color);
679 color = WMDarkGrayColor(scr->wmscreen);
680 WMSetWidgetBackgroundColor(panel->iconLabel, color);
681 WMSetWidgetBackgroundColor(panel->dirLabel, color);
682 WMReleaseColor(color);
684 WMSetLabelRelief(panel->iconLabel, WRSunken);
686 panel->dirList = WMCreateList(panel->win);
687 WMResizeWidget(panel->dirList, 200, 170);
688 WMMoveWidget(panel->dirList, 10, 30);
689 WMSetListAction(panel->dirList, listCallback, panel);
691 panel->iconList = WMCreateList(panel->win);
692 WMResizeWidget(panel->iconList, 140, 170);
693 WMMoveWidget(panel->iconList, 215, 30);
694 WMSetListAction(panel->iconList, listCallback, panel);
696 WMHangData(panel->iconList,panel);
698 panel->previewButton = WMCreateCommandButton(panel->win);
699 WMResizeWidget(panel->previewButton, 75, 26);
700 WMMoveWidget(panel->previewButton, 365, 130);
701 WMSetButtonText(panel->previewButton, _("Preview"));
702 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
704 panel->iconView = WMCreateLabel(panel->win);
705 WMResizeWidget(panel->iconView, 75, 75);
706 WMMoveWidget(panel->iconView, 365, 40);
707 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
708 WMSetLabelRelief(panel->iconView, WRSunken);
709 WMSetLabelTextAlignment(panel->iconView, WACenter);
711 panel->fileLabel = WMCreateLabel(panel->win);
712 WMResizeWidget(panel->fileLabel, 80, 20);
713 WMMoveWidget(panel->fileLabel, 10, 210);
714 WMSetLabelText(panel->fileLabel, _("File Name:"));
716 panel->fileField = WMCreateTextField(panel->win);
717 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
718 WMResizeWidget(panel->fileField, 345, 20);
719 WMMoveWidget(panel->fileField, 95, 210);
720 WMSetTextFieldEditable(panel->fileField, False);
722 panel->okButton = WMCreateCommandButton(panel->win);
723 WMResizeWidget(panel->okButton, 80, 26);
724 WMMoveWidget(panel->okButton, 360, 240);
725 WMSetButtonText(panel->okButton, _("OK"));
726 WMSetButtonEnabled(panel->okButton, False);
727 WMSetButtonAction(panel->okButton, buttonCallback, panel);
729 panel->cancelButton = WMCreateCommandButton(panel->win);
730 WMResizeWidget(panel->cancelButton, 80, 26);
731 WMMoveWidget(panel->cancelButton, 270, 240);
732 WMSetButtonText(panel->cancelButton, _("Cancel"));
733 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
734 #if 0
735 panel->chooseButton = WMCreateCommandButton(panel->win);
736 WMResizeWidget(panel->chooseButton, 110, 26);
737 WMMoveWidget(panel->chooseButton, 150, 240);
738 WMSetButtonText(panel->chooseButton, _("Choose File"));
739 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
740 #endif
741 WMRealizeWidget(panel->win);
742 WMMapSubwidgets(panel->win);
744 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
746 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
749 char *tmp;
750 int len = (instance ? strlen(instance) : 0)
751 + (class ? strlen(class) : 0) + 32;
752 WMPoint center;
754 tmp = wmalloc(len);
756 if (tmp && (instance || class))
757 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
758 else
759 strcpy(tmp, _("Icon Chooser"));
761 center = getCenter(scr, 450, 280);
763 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x,center.y,
764 450, 280);
765 wfree(tmp);
768 /* put icon paths in the list */
769 listIconPaths(panel->dirList);
771 WMMapWidget(panel->win);
773 wWindowMap(wwin);
775 while (!panel->done) {
776 XEvent event;
778 WMNextEvent(dpy, &event);
779 WMHandleEvent(&event);
782 if (panel->result) {
783 char *defaultPath, *wantedPath;
785 /* check if the file the user selected is not the one that
786 * would be loaded by default with the current search path */
787 *file = WMGetListSelectedItem(panel->iconList)->text;
788 if (**file==0) {
789 wfree(*file);
790 *file = NULL;
791 } else {
792 defaultPath = FindImage(wPreferences.icon_path, *file);
793 wantedPath = WMGetTextFieldText(panel->fileField);
794 /* if the file is not the default, use full path */
795 if (strcmp(wantedPath, defaultPath)!=0) {
796 *file = wantedPath;
797 } else {
798 *file = wstrdup(*file);
799 wfree(wantedPath);
801 wfree(defaultPath);
803 } else {
804 *file = NULL;
807 result = panel->result;
809 WMReleaseFont(panel->normalfont);
811 WMUnmapWidget(panel->win);
813 WMDestroyWidget(panel->win);
815 wUnmanageWindow(wwin, False, False);
817 wfree(panel);
819 XDestroyWindow(dpy, parent);
821 return result;
826 ***********************************************************************
827 * Info Panel
828 ***********************************************************************
832 typedef struct {
833 WScreen *scr;
835 WWindow *wwin;
837 WMWindow *win;
839 WMLabel *logoL;
840 WMLabel *name1L;
841 WMFrame *lineF;
842 WMLabel *name2L;
844 WMLabel *versionL;
846 WMLabel *infoL;
848 WMLabel *copyrL;
850 #ifdef SILLYNESS
851 WMHandlerID timer;
852 int cycle;
853 RImage *icon;
854 RImage *pic;
855 WMPixmap *oldPix;
856 WMFont *oldFont;
857 char *str;
858 int x;
859 #endif
860 } InfoPanel;
864 #define COPYRIGHT_TEXT \
865 "Copyright \xc2\xa9 1997-2004 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
866 "Copyright \xc2\xa9 1998-2004 Dan Pascu <dan@windowmaker.org>"
870 static InfoPanel *thePanel = NULL;
872 static void
873 destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
875 #ifdef SILLYNESS
876 if (thePanel->timer) {
877 WMDeleteTimerHandler(thePanel->timer);
879 if (thePanel->oldPix) {
880 WMReleasePixmap(thePanel->oldPix);
882 if (thePanel->oldFont) {
883 WMReleaseFont(thePanel->oldFont);
885 if (thePanel->icon) {
886 RReleaseImage(thePanel->icon);
888 if (thePanel->pic) {
889 RReleaseImage(thePanel->pic);
891 #endif /* SILLYNESS */
892 WMUnmapWidget(thePanel);
894 wUnmanageWindow(thePanel->wwin, False, False);
896 WMDestroyWidget(thePanel->win);
898 wfree(thePanel);
900 thePanel = NULL;
904 #ifdef SILLYNESS
906 extern WMPixmap *DoXThing();
907 extern Bool InitXThing();
909 static void
910 logoPushCallback(void *data)
912 InfoPanel *panel = (InfoPanel*)data;
913 char buffer[512];
914 int i;
915 static int oldi = 0;
916 int len;
917 static int jingobeu[] = {
918 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
919 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
920 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
922 static int c = 0;
924 if (panel->x) {
925 XKeyboardControl kc;
926 XKeyboardState ksave;
927 unsigned long mask = KBBellPitch|KBBellDuration|KBBellPercent;
929 XGetKeyboardControl(dpy, &ksave);
931 if (panel->x > 0) {
932 if(jingobeu[panel->x-1]==0) {
933 panel->x=-1;
934 } else if (jingobeu[panel->x-1]<0) {
935 panel->x++;
936 c=jingobeu[panel->x-1]/50;
937 panel->x++;
938 } else if (c==0) {
939 kc.bell_percent=50;
940 kc.bell_pitch=jingobeu[panel->x-1];
941 panel->x++;
942 kc.bell_duration=jingobeu[panel->x-1];
943 c=jingobeu[panel->x-1]/50;
944 panel->x++;
945 XChangeKeyboardControl(dpy, mask, &kc);
946 XBell(dpy, 50);
947 XFlush(dpy);
948 } else {
949 c--;
952 if (!(panel->cycle % 4)) {
953 WMPixmap *p;
955 p = DoXThing(panel->wwin);
956 WMSetLabelImage(panel->logoL, p);
958 kc.bell_pitch = ksave.bell_pitch;
959 kc.bell_percent = ksave.bell_percent;
960 kc.bell_duration = ksave.bell_duration;
961 XChangeKeyboardControl(dpy, mask, &kc);
962 } else if (panel->cycle < 30) {
963 RImage *image;
964 WMPixmap *pix;
965 RColor gray;
967 gray.red = 0xae; gray.green = 0xaa;
968 gray.blue = 0xae; gray.alpha = 0;
970 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
971 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
972 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
973 RReleaseImage(image);
974 WMSetLabelImage(panel->logoL, pix);
975 WMReleasePixmap(pix);
978 /* slow down text a little */
979 i = (int)(panel->cycle * 50.0/85.0)%200;
981 if (i != oldi) {
982 len = strlen(panel->str);
984 strncpy(buffer, panel->str, i<len ? i : len);
985 if (i >= len)
986 memset(&buffer[len], ' ', i-len);
988 strncpy(buffer, panel->str, i<len ? i : len);
989 if (i >= len)
990 memset(&buffer[len], ' ', i-len);
991 buffer[i]=0;
993 WMSetLabelText(panel->versionL, buffer);
995 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
997 oldi = i;
1000 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1001 panel->cycle++;
1005 static void
1006 handleLogoPush(XEvent *event, void *data)
1008 InfoPanel *panel = (InfoPanel*)data;
1009 static int broken = 0;
1010 static int clicks = 0;
1011 static char *pic_data[] = {
1012 "45 45 57 1",
1013 " c None",
1014 ". c #000000",
1015 "X c #383C00",
1016 "o c #515500",
1017 "O c #616100",
1018 "+ c #616900",
1019 "@ c #696D00",
1020 "# c #697100",
1021 "$ c #495100",
1022 "% c #202800",
1023 "& c #969600",
1024 "* c #CFCF00",
1025 "= c #D7DB00",
1026 "- c #D7D700",
1027 "; c #C7CB00",
1028 ": c #A6AA00",
1029 "> c #494900",
1030 ", c #8E8E00",
1031 "< c #DFE700",
1032 "1 c #F7FF00",
1033 "2 c #FFFF00",
1034 "3 c #E7EB00",
1035 "4 c #B6B600",
1036 "5 c #595900",
1037 "6 c #717500",
1038 "7 c #AEB200",
1039 "8 c #CFD300",
1040 "9 c #E7EF00",
1041 "0 c #EFF300",
1042 "q c #9EA200",
1043 "w c #F7FB00",
1044 "e c #F7F700",
1045 "r c #BEBE00",
1046 "t c #8E9200",
1047 "y c #EFF700",
1048 "u c #969A00",
1049 "i c #414500",
1050 "p c #595D00",
1051 "a c #E7E700",
1052 "s c #C7C700",
1053 "d c #797D00",
1054 "f c #BEC300",
1055 "g c #DFE300",
1056 "h c #868600",
1057 "j c #EFEF00",
1058 "k c #9E9E00",
1059 "l c #616500",
1060 "z c #DFDF00",
1061 "x c #868A00",
1062 "c c #969200",
1063 "v c #B6BA00",
1064 "b c #A6A600",
1065 "n c #8E8A00",
1066 "m c #717100",
1067 "M c #AEAE00",
1068 "N c #AEAA00",
1069 "B c #868200",
1070 " ............... ",
1071 " ....XoO+@##+O$%.... ",
1072 " ...%X&*========-;;:o... ",
1073 " ...>.>,<122222222222134@... ",
1074 " ..>5678912222222222222220q%.. ",
1075 " ..$.&-w2222222222222222222er>.. ",
1076 " ..O.t31222222222222222222222y4>.. ",
1077 " ...O5u3222222222222222222222222yri... ",
1078 " ..>p&a22222222222222222222222222wso.. ",
1079 " ..ids91222222222222222222222222222wfi.. ",
1080 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1081 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1082 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1083 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1084 "..io*222222222&...u22222222yt..%*22222220:%. ",
1085 "..>k02222222227...f222222222v..X=222222229t. ",
1086 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1087 ".%vw222222222221y2222222222219*y2222222222wd.",
1088 ".X;2222222222222222222222222222222222222222b.",
1089 ".i*2222222222222222222222222222222222222222v.",
1090 ".i*2222222222222222222222222222222222222222;.",
1091 ".i*22222222222222222222222222222222222222228.",
1092 ".>*2222222222222222222222222222222222222222=.",
1093 ".i*22222222222222222222222222222222222222228.",
1094 ".i*2222222222222222222222222222222222222222;.",
1095 ".X*222222222222222222222222222222we12222222r.",
1096 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1097 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1098 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1099 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1100 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1101 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1102 " ...:e2222218mdz22222222222222a&$vw222220@...",
1103 " ...O-122222y:.u02222222222229q$uj222221r... ",
1104 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1105 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1106 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1107 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1108 " ..Xb9122222109g-****;<y22221zn%... ",
1109 " ..X&801222222222222222222w-h.... ",
1110 " ...o:=022222222222222221=lX... ",
1111 " ..X@:;3w2222222222210fO... ",
1112 " ...XX&v8<30000003-N@... ",
1113 " .....XmnbN:q&Bo.... ",
1114 " ............ "
1116 static char *msgs[] = {
1117 "Have a nice day!",
1118 "Focus follow mouse users will burn in hell!!!",
1119 "Mooo Canada!!!!",
1120 "Hi! My name is bobby...",
1121 "AHH! The neurotic monkeys are after me!",
1122 "WE GET SIGNAL",
1123 "HOW ARE YOU GENTLEMEN?",
1124 "WHAT YOU SAY??",
1125 "SOMEBODY SET UP US THE BOMB",
1126 "ALL YOUR BASE ARE BELONG TO US!",
1127 "Oh My God!!! Larry is back!"
1131 clicks++;
1133 if (!panel->timer && !broken && clicks > 0) {
1134 WMFont *font;
1136 panel->x = 0;
1137 clicks = 0;
1138 if (!panel->icon) {
1139 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1140 if (!panel->icon) {
1141 broken = 1;
1142 return;
1143 } else {
1144 RColor color;
1146 color.red = 0xae; color.green = 0xaa;
1147 color.blue = 0xae; color.alpha = 0;
1149 panel->icon = RCloneImage(panel->icon);
1150 RCombineImageWithColor(panel->icon, &color);
1153 if (!panel->pic) {
1154 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1155 if (!panel->pic) {
1156 broken = 1;
1157 RReleaseImage(panel->icon);
1158 panel->icon = NULL;
1159 return;
1163 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1165 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1166 panel->cycle = 0;
1167 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1168 /* If we don't use a fixed font, scrolling will be jumpy */
1169 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1170 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1171 WMRetainFont(panel->oldFont);
1172 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*");
1173 if (font) {
1174 WMSetLabelFont(panel->versionL, font);
1175 WMReleaseFont(font);
1177 WMSetLabelText(panel->versionL, "");
1178 } else if (panel->timer) {
1179 char version[20];
1181 panel->x = 0;
1182 clicks = 0;
1183 WMSetLabelImage(panel->logoL, panel->oldPix);
1184 WMReleasePixmap(panel->oldPix);
1185 panel->oldPix = NULL;
1187 WMDeleteTimerHandler(panel->timer);
1188 panel->timer = NULL;
1190 WMSetLabelFont(panel->versionL, panel->oldFont);
1191 if (panel->oldFont) {
1192 WMReleaseFont(panel->oldFont);
1193 panel->oldFont = NULL;
1195 snprintf(version, sizeof(version), _("Version %s"), VERSION);
1196 WMSetLabelText(panel->versionL, version);
1197 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1201 XEvent ev;
1202 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1203 ButtonPress, &ev));
1206 #endif /* SILLYNESS */
1209 void
1210 wShowInfoPanel(WScreen *scr)
1212 InfoPanel *panel;
1213 WMPixmap *logo;
1214 WMSize size;
1215 WMFont *font;
1216 char *strbuf = NULL;
1217 char buffer[256];
1218 Window parent;
1219 WWindow *wwin;
1220 char **strl;
1221 int i, width, sepWidth;
1222 char *visuals[] = {
1223 "StaticGray",
1224 "GrayScale",
1225 "StaticColor",
1226 "PseudoColor",
1227 "TrueColor",
1228 "DirectColor"
1232 if (thePanel) {
1233 if (thePanel->scr == scr) {
1234 wRaiseFrame(thePanel->wwin->frame->core);
1235 wSetFocusTo(scr, thePanel->wwin);
1237 return;
1240 panel = wmalloc(sizeof(InfoPanel));
1241 memset(panel, 0, sizeof(InfoPanel));
1243 panel->scr = scr;
1245 panel->win = WMCreateWindow(scr->wmscreen, "info");
1246 WMResizeWidget(panel->win, 390, 230);
1248 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor*)NULL);
1249 if (!logo) {
1250 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1252 if (logo) {
1253 size = WMGetPixmapSize(logo);
1254 panel->logoL = WMCreateLabel(panel->win);
1255 WMResizeWidget(panel->logoL, 64, 64);
1256 WMMoveWidget(panel->logoL, 30, 20);
1257 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1258 WMSetLabelImage(panel->logoL, logo);
1259 #ifdef SILLYNESS
1260 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1261 handleLogoPush, panel);
1262 #endif
1263 WMReleasePixmap(logo);
1266 sepWidth = 3;
1267 panel->name1L = WMCreateLabel(panel->win);
1268 WMResizeWidget(panel->name1L, 240, 30 - sepWidth);
1269 WMMoveWidget(panel->name1L, 100, 30);
1271 if (WMIsAntialiasingEnabled(scr->wmscreen)) {
1272 font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1273 } else {
1274 font = WMCreateFont(scr->wmscreen, "-*-utopia-*-r-*-*-25-*");
1275 font = font ? font : WMBoldSystemFontOfSize(scr->wmscreen, 24);
1277 strbuf = "Window Maker";
1278 if (font) {
1279 width = WMWidthOfString(font, strbuf, strlen(strbuf));
1280 WMSetLabelFont(panel->name1L, font);
1281 WMReleaseFont(font);
1283 WMSetLabelTextAlignment(panel->name1L, WACenter);
1284 WMSetLabelText(panel->name1L, strbuf);
1286 panel->lineF = WMCreateFrame(panel->win);
1287 WMResizeWidget(panel->lineF, width, sepWidth);
1288 WMMoveWidget(panel->lineF, 100+(240-width)/2, 60 - sepWidth);
1289 WMSetFrameRelief(panel->lineF, WRSimple);
1290 WMSetWidgetBackgroundColor(panel->lineF, scr->black);
1292 panel->name2L = WMCreateLabel(panel->win);
1293 WMResizeWidget(panel->name2L, 240, 24);
1294 WMMoveWidget(panel->name2L, 100, 60);
1295 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1296 if (font) {
1297 WMSetLabelFont(panel->name2L, font);
1298 WMReleaseFont(font);
1299 font = NULL;
1301 WMSetLabelTextAlignment(panel->name2L, WACenter);
1302 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1304 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1305 panel->versionL = WMCreateLabel(panel->win);
1306 WMResizeWidget(panel->versionL, 310, 16);
1307 WMMoveWidget(panel->versionL, 30, 95);
1308 WMSetLabelTextAlignment(panel->versionL, WARight);
1309 WMSetLabelText(panel->versionL, buffer);
1310 WMSetLabelWraps(panel->versionL, False);
1312 panel->copyrL = WMCreateLabel(panel->win);
1313 WMResizeWidget(panel->copyrL, 360, 40);
1314 WMMoveWidget(panel->copyrL, 15, 185);
1315 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1316 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1317 font = WMSystemFontOfSize(scr->wmscreen, 11);
1318 if (font) {
1319 WMSetLabelFont(panel->copyrL, font);
1320 WMReleaseFont(font);
1321 font = NULL;
1324 strbuf = NULL;
1325 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1326 (unsigned)scr->w_visual->visualid,
1327 visuals[scr->w_visual->class], scr->w_depth);
1329 strbuf = wstrappend(strbuf, buffer);
1331 switch (scr->w_depth) {
1332 case 15:
1333 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1334 break;
1335 case 16:
1336 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1337 break;
1338 case 24:
1339 case 32:
1340 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1341 break;
1342 default:
1343 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1<<scr->w_depth);
1344 strbuf = wstrappend(strbuf, buffer);
1345 break;
1349 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1351 struct mallinfo ma = mallinfo();
1352 snprintf(buffer, sizeof(buffer),
1353 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1354 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1356 strbuf = wstrappend(strbuf, buffer);
1358 #endif
1360 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1361 strl = RSupportedFileFormats();
1362 for (i=0; strl[i]!=NULL; i++) {
1363 strbuf = wstrappend(strbuf, strl[i]);
1364 strbuf = wstrappend(strbuf, " ");
1367 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1369 char *list[9];
1370 char buf[80];
1371 int j = 0;
1373 #ifdef MWM_HINTS
1374 list[j++] = "MWM";
1375 #endif
1376 #ifdef KWM_HINTS
1377 list[j++] = "KDE";
1378 #endif
1379 #ifdef GNOME_STUFF
1380 list[j++] = "GNOME";
1381 #endif
1382 #ifdef OLWM_HINTS
1383 list[j++] = "OLWM";
1384 #endif
1385 #ifdef NETWM_HINTS
1386 list[j++] = "WMSPEC";
1387 #endif
1389 buf[0] = 0;
1390 for (i = 0; i < j; i++) {
1391 if (i > 0) {
1392 if (i == j - 1)
1393 strcat(buf, _(" and "));
1394 else
1395 strcat(buf, ", ");
1397 strcat(buf, list[i]);
1399 strbuf = wstrappend(strbuf, buf);
1402 if (wPreferences.no_sound) {
1403 strbuf = wstrappend(strbuf, _("\nSound disabled"));
1404 } else {
1405 strbuf = wstrappend(strbuf, _("\nSound enabled"));
1408 #ifdef XFT
1409 strbuf = wstrappend(strbuf, _("; Antialiased text"));
1410 #endif
1412 #ifdef VIRTUAL_DESKTOP
1413 strbuf = wstrappend(strbuf, _("; VirtualDesktop"));
1414 #endif
1416 #ifdef XINERAMA
1417 strbuf = wstrappend(strbuf, _("\n"));
1418 #ifdef SOLARIS_XINERAMA
1419 strbuf = wstrappend(strbuf, _("Solaris "));
1420 #endif
1421 strbuf = wstrappend(strbuf, _("Xinerama: "));
1423 char tmp[128];
1424 snprintf(tmp, sizeof(tmp)-1, "%d heads found.", scr->xine_info.count);
1425 strbuf = wstrappend(strbuf, tmp);
1427 #endif
1430 panel->infoL = WMCreateLabel(panel->win);
1431 WMResizeWidget(panel->infoL, 350, 75);
1432 WMMoveWidget(panel->infoL, 15, 115);
1433 WMSetLabelText(panel->infoL, strbuf);
1434 font = WMSystemFontOfSize(scr->wmscreen, 11);
1435 if (font) {
1436 WMSetLabelFont(panel->infoL, font);
1437 WMReleaseFont(font);
1438 font = NULL;
1440 wfree(strbuf);
1443 WMRealizeWidget(panel->win);
1444 WMMapSubwidgets(panel->win);
1446 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1448 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1450 WMMapWidget(panel->win);
1453 WMPoint center = getCenter(scr, 382, 230);
1455 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1456 center.x, center.y,
1457 382, 230);
1460 WSETUFLAG(wwin, no_closable, 0);
1461 WSETUFLAG(wwin, no_close_button, 0);
1462 #ifdef XKB_BUTTON_HINT
1463 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1464 #endif
1465 wWindowUpdateButtonImages(wwin);
1466 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1467 wwin->frame->on_click_right = destroyInfoPanel;
1469 wWindowMap(wwin);
1471 panel->wwin = wwin;
1473 thePanel = panel;
1474 #ifdef SILLYNESS
1475 if (InitXThing(panel->scr)) {
1476 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1477 panel->cycle = 0;
1478 panel->x = 1;
1479 panel->str = _("Merry Christmas!");
1480 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1482 #endif
1487 ***********************************************************************
1488 * Legal Panel
1489 ***********************************************************************
1492 typedef struct {
1493 WScreen *scr;
1495 WWindow *wwin;
1497 WMWindow *win;
1499 WMLabel *licenseL;
1500 } LegalPanel;
1503 static LegalPanel *legalPanel = NULL;
1505 static void
1506 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1508 WMUnmapWidget(legalPanel->win);
1510 WMDestroyWidget(legalPanel->win);
1512 wUnmanageWindow(legalPanel->wwin, False, False);
1514 wfree(legalPanel);
1516 legalPanel = NULL;
1520 void
1521 wShowLegalPanel(WScreen *scr)
1523 LegalPanel *panel;
1524 Window parent;
1525 WWindow *wwin;
1527 if (legalPanel) {
1528 if (legalPanel->scr == scr) {
1529 wRaiseFrame(legalPanel->wwin->frame->core);
1530 wSetFocusTo(scr, legalPanel->wwin);
1532 return;
1535 panel = wmalloc(sizeof(LegalPanel));
1537 panel->scr = scr;
1539 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1540 WMResizeWidget(panel->win, 420, 250);
1543 panel->licenseL = WMCreateLabel(panel->win);
1544 WMSetLabelWraps(panel->licenseL, True);
1545 WMResizeWidget(panel->licenseL, 400, 230);
1546 WMMoveWidget(panel->licenseL, 10, 10);
1547 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1548 WMSetLabelText(panel->licenseL,
1549 _(" Window Maker is free software; you can redistribute it and/or\n"
1550 "modify it under the terms of the GNU General Public License as\n"
1551 "published by the Free Software Foundation; either version 2 of the\n"
1552 "License, or (at your option) any later version.\n\n"
1553 " Window Maker is distributed in the hope that it will be useful,\n"
1554 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1555 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1556 "See the GNU General Public License for more details.\n\n"
1557 " You should have received a copy of the GNU General Public\n"
1558 "License along with this program; if not, write to the Free Software\n"
1559 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1560 "02111-1307, USA."));
1561 WMSetLabelRelief(panel->licenseL, WRGroove);
1563 WMRealizeWidget(panel->win);
1564 WMMapSubwidgets(panel->win);
1566 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1568 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1571 WMPoint center = getCenter(scr, 420, 250);
1573 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1574 center.x, center.y,
1575 420, 250);
1578 WSETUFLAG(wwin, no_closable, 0);
1579 WSETUFLAG(wwin, no_close_button, 0);
1580 wWindowUpdateButtonImages(wwin);
1581 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1582 #ifdef XKB_BUTTON_HINT
1583 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1584 #endif
1585 wwin->frame->on_click_right = destroyLegalPanel;
1587 panel->wwin = wwin;
1589 WMMapWidget(panel->win);
1591 wWindowMap(wwin);
1593 legalPanel = panel;
1598 ***********************************************************************
1599 * Crashing Dialog Panel
1600 ***********************************************************************
1603 extern WDDomain *WDWindowAttributes;
1606 typedef struct _CrashPanel {
1607 WMWindow *win; /* main window */
1609 WMLabel *iconL; /* application icon */
1610 WMLabel *nameL; /* title of panel */
1612 WMFrame *sepF; /* separator frame */
1614 WMLabel *noteL; /* Title of note */
1615 WMLabel *note2L; /* body of note with what happened */
1617 WMFrame *whatF; /* "what to do next" frame */
1618 WMPopUpButton *whatP; /* action selection popup button */
1620 WMButton *okB; /* ok button */
1622 Bool done; /* if finished with this dialog */
1623 int action; /* what to do after */
1625 KeyCode retKey;
1627 } CrashPanel;
1630 static void
1631 handleKeyPress(XEvent *event, void *clientData)
1633 CrashPanel *panel = (CrashPanel*)clientData;
1635 if (event->xkey.keycode == panel->retKey) {
1636 WMPerformButtonClick(panel->okB);
1641 static void
1642 okButtonCallback(void *self, void *clientData)
1644 CrashPanel *panel = (CrashPanel*)clientData;
1646 panel->done = True;
1650 static void
1651 setCrashAction(void *self, void *clientData)
1653 WMPopUpButton *pop = (WMPopUpButton*)self;
1654 CrashPanel *panel = (CrashPanel*)clientData;
1656 panel->action = WMGetPopUpButtonSelectedItem(pop);
1660 static WMPixmap*
1661 getWindowMakerIconImage(WMScreen *scr)
1663 WMPropList *dict, *key, *option, *value=NULL;
1664 WMPixmap *pix=NULL;
1665 char *path;
1667 WMPLSetCaseSensitive(True);
1669 key = WMCreatePLString("Logo.WMPanel");
1670 option = WMCreatePLString("Icon");
1672 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1674 if (dict) {
1675 value = WMGetFromPLDictionary(dict, option);
1678 WMReleasePropList(key);
1679 WMReleasePropList(option);
1681 WMPLSetCaseSensitive(False);
1683 if (value && WMIsPLString(value)) {
1684 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1686 if (path) {
1687 RColor gray;
1689 gray.red = 0xae; gray.green = 0xaa;
1690 gray.blue = 0xae; gray.alpha = 0;
1692 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1693 wfree(path);
1697 return pix;
1701 #define PWIDTH 295
1702 #define PHEIGHT 345
1706 wShowCrashingDialogPanel(int whatSig)
1708 CrashPanel *panel;
1709 WMScreen *scr;
1710 WMFont *font;
1711 WMPixmap *logo;
1712 int screen_no, scr_width, scr_height;
1713 int action;
1714 char buf[256];
1716 panel = wmalloc(sizeof(CrashPanel));
1717 memset(panel, 0, sizeof(CrashPanel));
1719 screen_no = DefaultScreen(dpy);
1720 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1721 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1723 scr = WMCreateScreen(dpy, screen_no);
1724 if (!scr) {
1725 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1726 return WMAbort;
1729 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1731 panel->win = WMCreateWindow(scr, "crashingDialog");
1732 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1733 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1735 logo = getWindowMakerIconImage(scr);
1736 if (logo) {
1737 panel->iconL = WMCreateLabel(panel->win);
1738 WMResizeWidget(panel->iconL, 64, 64);
1739 WMMoveWidget(panel->iconL, 10, 10);
1740 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1741 WMSetLabelImage(panel->iconL, logo);
1744 panel->nameL = WMCreateLabel(panel->win);
1745 WMResizeWidget(panel->nameL, 190, 18);
1746 WMMoveWidget(panel->nameL, 80, 35);
1747 WMSetLabelTextAlignment(panel->nameL, WALeft);
1748 font = WMBoldSystemFontOfSize(scr, 18);
1749 WMSetLabelFont(panel->nameL, font);
1750 WMReleaseFont(font);
1751 WMSetLabelText(panel->nameL, _("Fatal error"));
1753 panel->sepF = WMCreateFrame(panel->win);
1754 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1755 WMMoveWidget(panel->sepF, -2, 80);
1757 panel->noteL = WMCreateLabel(panel->win);
1758 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1759 WMMoveWidget(panel->noteL, 10, 90);
1760 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1761 #ifdef SYS_SIGLIST_DECLARED
1762 snprintf(buf, sizeof(buf), _("Window Maker received signal %i\n(%s)."),
1763 whatSig, sys_siglist[whatSig]);
1764 #else
1765 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1766 #endif
1767 WMSetLabelText(panel->noteL, buf);
1769 panel->note2L = WMCreateLabel(panel->win);
1770 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1771 WMMoveWidget(panel->note2L, 10, 130);
1772 WMSetLabelTextAlignment(panel->note2L, WALeft);
1773 WMSetLabelText(panel->note2L,
1774 _(" This fatal error occured probably due to a bug."
1775 " Please fill the included BUGFORM and "
1776 "report it to bugs@windowmaker.org."));
1777 WMSetLabelWraps(panel->note2L, True);
1780 panel->whatF = WMCreateFrame(panel->win);
1781 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1782 WMMoveWidget(panel->whatF, 10, 240);
1783 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1785 panel->whatP = WMCreatePopUpButton(panel->whatF);
1786 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1787 WMMoveWidget(panel->whatP, 35, 20);
1788 WMSetPopUpButtonPullsDown(panel->whatP, False);
1789 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1790 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1791 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1792 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1793 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1794 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1795 panel->action = WMRestart;
1797 WMMapSubwidgets(panel->whatF);
1799 panel->okB = WMCreateCommandButton(panel->win);
1800 WMResizeWidget(panel->okB, 80, 26);
1801 WMMoveWidget(panel->okB, 205, 309);
1802 WMSetButtonText(panel->okB, _("OK"));
1803 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1804 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1805 WMSetButtonImagePosition(panel->okB, WIPRight);
1806 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1808 panel->done = 0;
1810 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1811 handleKeyPress, panel);
1813 WMRealizeWidget(panel->win);
1814 WMMapSubwidgets(panel->win);
1816 WMMapWidget(panel->win);
1818 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1820 while (!panel->done) {
1821 XEvent event;
1823 WMNextEvent(dpy, &event);
1824 WMHandleEvent(&event);
1827 action = panel->action;
1829 WMUnmapWidget(panel->win);
1830 WMDestroyWidget(panel->win);
1831 wfree(panel);
1833 return action;
1839 /*****************************************************************************
1840 * About GNUstep Panel
1841 *****************************************************************************/
1844 static void
1845 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1846 unsigned long blackPixel, unsigned long whitePixel)
1848 GC gc;
1849 XGCValues gcv;
1850 XRectangle rects[3];
1852 gcv.foreground = blackPixel;
1853 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1855 XFillArc(dpy, d, gc, width/45, height/45,
1856 width - 2*width/45, height - 2*height/45, 0, 360*64);
1858 rects[0].x = 0;
1859 rects[0].y = 37*height/45;
1860 rects[0].width = width/3;
1861 rects[0].height = height - rects[0].y;
1863 rects[1].x = rects[0].width;
1864 rects[1].y = height/2;
1865 rects[1].width = width - 2*width/3;
1866 rects[1].height = height - rects[1].y;
1868 rects[2].x = 2*width/3;
1869 rects[2].y = height - 37*height/45;
1870 rects[2].width = width/3;
1871 rects[2].height = height - rects[2].y;
1873 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1874 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1876 XSetForeground(dpy, gc, whitePixel);
1877 XFillArc(dpy, d, gc, width/45, height/45,
1878 width - 2*width/45, height - 2*height/45, 0, 360*64);
1880 XFreeGC(dpy, gc);
1884 typedef struct {
1885 WScreen *scr;
1887 WWindow *wwin;
1889 WMWindow *win;
1891 WMLabel *gstepL;
1892 WMLabel *textL;
1893 } GNUstepPanel;
1896 static GNUstepPanel *gnustepPanel = NULL;
1898 static void
1899 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1901 WMUnmapWidget(gnustepPanel->win);
1903 WMDestroyWidget(gnustepPanel->win);
1905 wUnmanageWindow(gnustepPanel->wwin, False, False);
1907 wfree(gnustepPanel);
1909 gnustepPanel = NULL;
1913 void
1914 wShowGNUstepPanel(WScreen *scr)
1916 GNUstepPanel *panel;
1917 Window parent;
1918 WWindow *wwin;
1919 WMPixmap *pixmap;
1920 WMColor *color;
1922 if (gnustepPanel) {
1923 if (gnustepPanel->scr == scr) {
1924 wRaiseFrame(gnustepPanel->wwin->frame->core);
1925 wSetFocusTo(scr, gnustepPanel->wwin);
1927 return;
1930 panel = wmalloc(sizeof(GNUstepPanel));
1932 panel->scr = scr;
1934 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1935 WMResizeWidget(panel->win, 325, 205);
1937 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1938 WMScreenDepth(scr->wmscreen), True);
1940 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1942 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1943 WMColorPixel(color), scr->white_pixel);
1945 WMReleaseColor(color);
1947 XSetForeground(dpy, scr->mono_gc, 0);
1948 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1949 130, 130);
1950 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1952 panel->gstepL = WMCreateLabel(panel->win);
1953 WMResizeWidget(panel->gstepL, 285, 64);
1954 WMMoveWidget(panel->gstepL, 20, 0);
1955 WMSetLabelTextAlignment(panel->gstepL, WARight);
1956 WMSetLabelText(panel->gstepL, "GNUstep");
1958 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1960 WMSetLabelFont(panel->gstepL, font);
1961 WMReleaseFont(font);
1964 panel->textL = WMCreateLabel(panel->win);
1965 WMResizeWidget(panel->textL, 305, 140);
1966 WMMoveWidget(panel->textL, 10, 50);
1967 WMSetLabelTextAlignment(panel->textL, WARight);
1968 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1969 WMSetLabelText(panel->textL,
1970 _("Window Maker is part of the GNUstep project.\n"\
1971 "The GNUstep project aims to create a free\n"\
1972 "implementation of the OpenStep(tm) specification\n"\
1973 "which is a object-oriented framework for\n"\
1974 "creating advanced graphical, multi-platform\n"\
1975 "applications. Additionally, a development and\n"\
1976 "user desktop enviroment will be created on top\n"\
1977 "of the framework. For more information about\n"\
1978 "GNUstep, please visit: www.gnustep.org"));
1979 WMSetLabelImage(panel->textL, pixmap);
1981 WMReleasePixmap(pixmap);
1983 WMRealizeWidget(panel->win);
1984 WMMapSubwidgets(panel->win);
1986 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1988 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1991 WMPoint center = getCenter(scr, 325, 200);
1993 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
1994 center.x, center.y,
1995 325, 200);
1998 WSETUFLAG(wwin, no_closable, 0);
1999 WSETUFLAG(wwin, no_close_button, 0);
2000 wWindowUpdateButtonImages(wwin);
2001 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
2002 #ifdef XKB_BUTTON_HINT
2003 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
2004 #endif
2005 wwin->frame->on_click_right = destroyGNUstepPanel;
2007 panel->wwin = wwin;
2009 WMMapWidget(panel->win);
2011 wWindowMap(wwin);
2013 gnustepPanel = panel;