fixed issue with window being moved by 1 pixel up and left when the window
[wmaker-crm.git] / src / dialog.c
blob8205f83fe47dc7884f2549fa997483da936f0720
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 = 0;
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\n"\
866 "Copyright \xc2\xa9 1998-2004 Dan Pascu"
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!",
1128 "Alex Perez is aliveeeeeeee!!!"
1132 clicks++;
1134 if (!panel->timer && !broken && clicks > 0) {
1135 WMFont *font;
1137 panel->x = 0;
1138 clicks = 0;
1139 if (!panel->icon) {
1140 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1141 if (!panel->icon) {
1142 broken = 1;
1143 return;
1144 } else {
1145 RColor color;
1147 color.red = 0xae; color.green = 0xaa;
1148 color.blue = 0xae; color.alpha = 0;
1150 panel->icon = RCloneImage(panel->icon);
1151 RCombineImageWithColor(panel->icon, &color);
1154 if (!panel->pic) {
1155 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1156 if (!panel->pic) {
1157 broken = 1;
1158 RReleaseImage(panel->icon);
1159 panel->icon = NULL;
1160 return;
1164 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1166 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1167 panel->cycle = 0;
1168 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1169 /* If we don't use a fixed font, scrolling will be jumpy */
1170 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1171 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1172 WMRetainFont(panel->oldFont);
1173 font = WMCreateFont(WMWidgetScreen(panel->versionL),
1174 "Lucida Console,Courier New,monospace:pixelsize=12");
1175 if (font) {
1176 WMSetLabelFont(panel->versionL, font);
1177 WMReleaseFont(font);
1179 WMSetLabelText(panel->versionL, "");
1180 } else if (panel->timer) {
1181 char version[20];
1183 panel->x = 0;
1184 clicks = 0;
1185 WMSetLabelImage(panel->logoL, panel->oldPix);
1186 WMReleasePixmap(panel->oldPix);
1187 panel->oldPix = NULL;
1189 WMDeleteTimerHandler(panel->timer);
1190 panel->timer = NULL;
1192 WMSetLabelFont(panel->versionL, panel->oldFont);
1193 if (panel->oldFont) {
1194 WMReleaseFont(panel->oldFont);
1195 panel->oldFont = NULL;
1197 snprintf(version, sizeof(version), _("Version %s"), VERSION);
1198 WMSetLabelText(panel->versionL, version);
1199 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1203 XEvent ev;
1204 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1205 ButtonPress, &ev));
1208 #endif /* SILLYNESS */
1211 void
1212 wShowInfoPanel(WScreen *scr)
1214 InfoPanel *panel;
1215 WMPixmap *logo;
1216 WMSize size;
1217 WMFont *font;
1218 char *strbuf = NULL;
1219 char buffer[256];
1220 char *name;
1221 Window parent;
1222 WWindow *wwin;
1223 char **strl;
1224 int i, width=50, sepWidth;
1225 char *visuals[] = {
1226 "StaticGray",
1227 "GrayScale",
1228 "StaticColor",
1229 "PseudoColor",
1230 "TrueColor",
1231 "DirectColor"
1235 if (thePanel) {
1236 if (thePanel->scr == scr) {
1237 wRaiseFrame(thePanel->wwin->frame->core);
1238 wSetFocusTo(scr, thePanel->wwin);
1240 return;
1243 panel = wmalloc(sizeof(InfoPanel));
1244 memset(panel, 0, sizeof(InfoPanel));
1246 panel->scr = scr;
1248 panel->win = WMCreateWindow(scr->wmscreen, "info");
1249 WMResizeWidget(panel->win, 390, 230);
1251 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor*)NULL);
1252 if (!logo) {
1253 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1255 if (logo) {
1256 size = WMGetPixmapSize(logo);
1257 panel->logoL = WMCreateLabel(panel->win);
1258 WMResizeWidget(panel->logoL, 64, 64);
1259 WMMoveWidget(panel->logoL, 30, 20);
1260 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1261 WMSetLabelImage(panel->logoL, logo);
1262 #ifdef SILLYNESS
1263 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1264 handleLogoPush, panel);
1265 #endif
1266 WMReleasePixmap(logo);
1269 sepWidth = 3;
1270 panel->name1L = WMCreateLabel(panel->win);
1271 WMResizeWidget(panel->name1L, 240, 30 - sepWidth);
1272 WMMoveWidget(panel->name1L, 100, 30);
1274 name = "Lucida Sans,Comic Sans MS,URW Gothic L,Trebuchet MS"
1275 ":bold:pixelsize=26:antialias=true";
1276 font = WMCreateFont(scr->wmscreen, name);
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 name = "URW Gothic L,Nimbus Sans L:pixelsize=16:antialias=true";
1296 font = WMCreateFont(scr->wmscreen, name);
1297 if (font) {
1298 WMSetLabelFont(panel->name2L, font);
1299 WMReleaseFont(font);
1300 font = NULL;
1302 WMSetLabelTextAlignment(panel->name2L, WACenter);
1303 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1305 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1306 panel->versionL = WMCreateLabel(panel->win);
1307 WMResizeWidget(panel->versionL, 310, 16);
1308 WMMoveWidget(panel->versionL, 30, 95);
1309 WMSetLabelTextAlignment(panel->versionL, WARight);
1310 WMSetLabelText(panel->versionL, buffer);
1311 WMSetLabelWraps(panel->versionL, False);
1313 panel->copyrL = WMCreateLabel(panel->win);
1314 WMResizeWidget(panel->copyrL, 360, 40);
1315 WMMoveWidget(panel->copyrL, 15, 185);
1316 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1317 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1318 font = WMSystemFontOfSize(scr->wmscreen, 11);
1319 if (font) {
1320 WMSetLabelFont(panel->copyrL, font);
1321 WMReleaseFont(font);
1322 font = NULL;
1325 strbuf = NULL;
1326 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1327 (unsigned)scr->w_visual->visualid,
1328 visuals[scr->w_visual->class], scr->w_depth);
1330 strbuf = wstrappend(strbuf, buffer);
1332 switch (scr->w_depth) {
1333 case 15:
1334 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1335 break;
1336 case 16:
1337 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1338 break;
1339 case 24:
1340 case 32:
1341 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1342 break;
1343 default:
1344 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1<<scr->w_depth);
1345 strbuf = wstrappend(strbuf, buffer);
1346 break;
1350 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1352 struct mallinfo ma = mallinfo();
1353 snprintf(buffer, sizeof(buffer),
1354 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1355 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1357 strbuf = wstrappend(strbuf, buffer);
1359 #endif
1361 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1362 strl = RSupportedFileFormats();
1363 for (i=0; strl[i]!=NULL; i++) {
1364 strbuf = wstrappend(strbuf, strl[i]);
1365 strbuf = wstrappend(strbuf, " ");
1368 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1370 char *list[9];
1371 char buf[80];
1372 int j = 0;
1374 #ifdef NETWM_HINTS
1375 list[j++] = "WMSPEC";
1376 #endif
1377 #ifdef MWM_HINTS
1378 list[j++] = "MWM";
1379 #endif
1381 buf[0] = 0;
1382 for (i = 0; i < j; i++) {
1383 if (i > 0) {
1384 if (i == j - 1)
1385 strcat(buf, _(" and "));
1386 else
1387 strcat(buf, ", ");
1389 strcat(buf, list[i]);
1391 strbuf = wstrappend(strbuf, buf);
1394 if (wPreferences.no_sound) {
1395 strbuf = wstrappend(strbuf, _("\nSound disabled"));
1396 } else {
1397 strbuf = wstrappend(strbuf, _("\nSound enabled"));
1400 #ifdef VIRTUAL_DESKTOP
1401 if (wPreferences.vdesk_enable)
1402 strbuf = wstrappend(strbuf, _(", VirtualDesktop enabled"));
1403 else
1404 strbuf = wstrappend(strbuf, _(", VirtualDesktop disabled"));
1405 #endif
1407 #ifdef XINERAMA
1408 strbuf = wstrappend(strbuf, _("\n"));
1409 #ifdef SOLARIS_XINERAMA
1410 strbuf = wstrappend(strbuf, _("Solaris "));
1411 #endif
1412 strbuf = wstrappend(strbuf, _("Xinerama: "));
1414 char tmp[128];
1415 snprintf(tmp, sizeof(tmp)-1, "%d heads found.", scr->xine_info.count);
1416 strbuf = wstrappend(strbuf, tmp);
1418 #endif
1421 panel->infoL = WMCreateLabel(panel->win);
1422 WMResizeWidget(panel->infoL, 350, 75);
1423 WMMoveWidget(panel->infoL, 15, 115);
1424 WMSetLabelText(panel->infoL, strbuf);
1425 font = WMSystemFontOfSize(scr->wmscreen, 11);
1426 if (font) {
1427 WMSetLabelFont(panel->infoL, font);
1428 WMReleaseFont(font);
1429 font = NULL;
1431 wfree(strbuf);
1434 WMRealizeWidget(panel->win);
1435 WMMapSubwidgets(panel->win);
1437 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1439 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1441 WMMapWidget(panel->win);
1444 WMPoint center = getCenter(scr, 382, 230);
1446 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1447 center.x, center.y,
1448 382, 230);
1451 WSETUFLAG(wwin, no_closable, 0);
1452 WSETUFLAG(wwin, no_close_button, 0);
1453 #ifdef XKB_BUTTON_HINT
1454 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1455 #endif
1456 wWindowUpdateButtonImages(wwin);
1457 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1458 wwin->frame->on_click_right = destroyInfoPanel;
1460 wWindowMap(wwin);
1462 panel->wwin = wwin;
1464 thePanel = panel;
1465 #ifdef SILLYNESS
1466 if (InitXThing(panel->scr)) {
1467 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1468 panel->cycle = 0;
1469 panel->x = 1;
1470 panel->str = _("Merry Christmas!");
1471 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1473 #endif
1478 ***********************************************************************
1479 * Legal Panel
1480 ***********************************************************************
1483 typedef struct {
1484 WScreen *scr;
1486 WWindow *wwin;
1488 WMWindow *win;
1490 WMLabel *licenseL;
1491 } LegalPanel;
1494 static LegalPanel *legalPanel = NULL;
1496 static void
1497 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1499 WMUnmapWidget(legalPanel->win);
1501 WMDestroyWidget(legalPanel->win);
1503 wUnmanageWindow(legalPanel->wwin, False, False);
1505 wfree(legalPanel);
1507 legalPanel = NULL;
1511 void
1512 wShowLegalPanel(WScreen *scr)
1514 LegalPanel *panel;
1515 Window parent;
1516 WWindow *wwin;
1518 if (legalPanel) {
1519 if (legalPanel->scr == scr) {
1520 wRaiseFrame(legalPanel->wwin->frame->core);
1521 wSetFocusTo(scr, legalPanel->wwin);
1523 return;
1526 panel = wmalloc(sizeof(LegalPanel));
1528 panel->scr = scr;
1530 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1531 WMResizeWidget(panel->win, 420, 250);
1534 panel->licenseL = WMCreateLabel(panel->win);
1535 WMSetLabelWraps(panel->licenseL, True);
1536 WMResizeWidget(panel->licenseL, 400, 230);
1537 WMMoveWidget(panel->licenseL, 10, 10);
1538 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1539 WMSetLabelText(panel->licenseL,
1540 _(" Window Maker is free software; you can redistribute it and/or\n"
1541 "modify it under the terms of the GNU General Public License as\n"
1542 "published by the Free Software Foundation; either version 2 of the\n"
1543 "License, or (at your option) any later version.\n\n"
1544 " Window Maker is distributed in the hope that it will be useful,\n"
1545 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1546 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1547 "See the GNU General Public License for more details.\n\n"
1548 " You should have received a copy of the GNU General Public\n"
1549 "License along with this program; if not, write to the Free Software\n"
1550 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1551 "02111-1307, USA."));
1552 WMSetLabelRelief(panel->licenseL, WRGroove);
1554 WMRealizeWidget(panel->win);
1555 WMMapSubwidgets(panel->win);
1557 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1559 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1562 WMPoint center = getCenter(scr, 420, 250);
1564 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1565 center.x, center.y,
1566 420, 250);
1569 WSETUFLAG(wwin, no_closable, 0);
1570 WSETUFLAG(wwin, no_close_button, 0);
1571 wWindowUpdateButtonImages(wwin);
1572 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1573 #ifdef XKB_BUTTON_HINT
1574 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1575 #endif
1576 wwin->frame->on_click_right = destroyLegalPanel;
1578 panel->wwin = wwin;
1580 WMMapWidget(panel->win);
1582 wWindowMap(wwin);
1584 legalPanel = panel;
1589 ***********************************************************************
1590 * Crashing Dialog Panel
1591 ***********************************************************************
1594 extern WDDomain *WDWindowAttributes;
1597 typedef struct _CrashPanel {
1598 WMWindow *win; /* main window */
1600 WMLabel *iconL; /* application icon */
1601 WMLabel *nameL; /* title of panel */
1603 WMFrame *sepF; /* separator frame */
1605 WMLabel *noteL; /* Title of note */
1606 WMLabel *note2L; /* body of note with what happened */
1608 WMFrame *whatF; /* "what to do next" frame */
1609 WMPopUpButton *whatP; /* action selection popup button */
1611 WMButton *okB; /* ok button */
1613 Bool done; /* if finished with this dialog */
1614 int action; /* what to do after */
1616 KeyCode retKey;
1618 } CrashPanel;
1621 static void
1622 handleKeyPress(XEvent *event, void *clientData)
1624 CrashPanel *panel = (CrashPanel*)clientData;
1626 if (event->xkey.keycode == panel->retKey) {
1627 WMPerformButtonClick(panel->okB);
1632 static void
1633 okButtonCallback(void *self, void *clientData)
1635 CrashPanel *panel = (CrashPanel*)clientData;
1637 panel->done = True;
1641 static void
1642 setCrashAction(void *self, void *clientData)
1644 WMPopUpButton *pop = (WMPopUpButton*)self;
1645 CrashPanel *panel = (CrashPanel*)clientData;
1647 panel->action = WMGetPopUpButtonSelectedItem(pop);
1651 /* Make this read the logo from a compiled in pixmap -Dan */
1652 static WMPixmap*
1653 getWindowMakerIconImage(WMScreen *scr)
1655 WMPropList *dict, *key, *option, *value=NULL;
1656 WMPixmap *pix=NULL;
1657 char *path;
1659 if (!WDWindowAttributes || !WDWindowAttributes->dictionary)
1660 return NULL;
1662 WMPLSetCaseSensitive(True);
1664 key = WMCreatePLString("Logo.WMPanel");
1665 option = WMCreatePLString("Icon");
1667 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1669 if (dict) {
1670 value = WMGetFromPLDictionary(dict, option);
1673 WMReleasePropList(key);
1674 WMReleasePropList(option);
1676 WMPLSetCaseSensitive(False);
1678 if (value && WMIsPLString(value)) {
1679 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1681 if (path) {
1682 RColor gray;
1684 gray.red = 0xae; gray.green = 0xaa;
1685 gray.blue = 0xae; gray.alpha = 0;
1687 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1688 wfree(path);
1692 return pix;
1696 #define PWIDTH 295
1697 #define PHEIGHT 345
1701 wShowCrashingDialogPanel(int whatSig)
1703 CrashPanel *panel;
1704 WMScreen *scr;
1705 WMFont *font;
1706 WMPixmap *logo;
1707 int screen_no, scr_width, scr_height;
1708 int action;
1709 char buf[256];
1711 panel = wmalloc(sizeof(CrashPanel));
1712 memset(panel, 0, sizeof(CrashPanel));
1714 screen_no = DefaultScreen(dpy);
1715 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1716 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1718 scr = WMCreateScreen(dpy, screen_no);
1719 if (!scr) {
1720 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1721 return WMAbort;
1724 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1726 panel->win = WMCreateWindow(scr, "crashingDialog");
1727 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1728 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1730 logo = getWindowMakerIconImage(scr);
1731 if (logo) {
1732 panel->iconL = WMCreateLabel(panel->win);
1733 WMResizeWidget(panel->iconL, 64, 64);
1734 WMMoveWidget(panel->iconL, 10, 10);
1735 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1736 WMSetLabelImage(panel->iconL, logo);
1739 panel->nameL = WMCreateLabel(panel->win);
1740 WMResizeWidget(panel->nameL, 200, 30);
1741 WMMoveWidget(panel->nameL, 80, 25);
1742 WMSetLabelTextAlignment(panel->nameL, WALeft);
1743 font = WMBoldSystemFontOfSize(scr, 24);
1744 WMSetLabelFont(panel->nameL, font);
1745 WMReleaseFont(font);
1746 WMSetLabelText(panel->nameL, _("Fatal error"));
1748 panel->sepF = WMCreateFrame(panel->win);
1749 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1750 WMMoveWidget(panel->sepF, -2, 80);
1752 panel->noteL = WMCreateLabel(panel->win);
1753 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1754 WMMoveWidget(panel->noteL, 10, 90);
1755 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1756 #ifdef SYS_SIGLIST_DECLARED
1757 snprintf(buf, sizeof(buf), _("Window Maker received signal %i\n(%s)."),
1758 whatSig, sys_siglist[whatSig]);
1759 #else
1760 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1761 #endif
1762 WMSetLabelText(panel->noteL, buf);
1764 panel->note2L = WMCreateLabel(panel->win);
1765 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1766 WMMoveWidget(panel->note2L, 10, 130);
1767 WMSetLabelTextAlignment(panel->note2L, WALeft);
1768 WMSetLabelText(panel->note2L,
1769 _(" This fatal error occured probably due to a bug."
1770 " Please fill the included BUGFORM and "
1771 "report it to bugs@windowmaker.org."));
1772 WMSetLabelWraps(panel->note2L, True);
1775 panel->whatF = WMCreateFrame(panel->win);
1776 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1777 WMMoveWidget(panel->whatF, 10, 240);
1778 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1780 panel->whatP = WMCreatePopUpButton(panel->whatF);
1781 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1782 WMMoveWidget(panel->whatP, 35, 20);
1783 WMSetPopUpButtonPullsDown(panel->whatP, False);
1784 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1785 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1786 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1787 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1788 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1789 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1790 panel->action = WMRestart;
1792 WMMapSubwidgets(panel->whatF);
1794 panel->okB = WMCreateCommandButton(panel->win);
1795 WMResizeWidget(panel->okB, 80, 26);
1796 WMMoveWidget(panel->okB, 205, 309);
1797 WMSetButtonText(panel->okB, _("OK"));
1798 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1799 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1800 WMSetButtonImagePosition(panel->okB, WIPRight);
1801 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1803 panel->done = 0;
1805 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1806 handleKeyPress, panel);
1808 WMRealizeWidget(panel->win);
1809 WMMapSubwidgets(panel->win);
1811 WMMapWidget(panel->win);
1813 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1815 while (!panel->done) {
1816 XEvent event;
1818 WMNextEvent(dpy, &event);
1819 WMHandleEvent(&event);
1822 action = panel->action;
1824 WMUnmapWidget(panel->win);
1825 WMDestroyWidget(panel->win);
1826 wfree(panel);
1828 return action;
1834 /*****************************************************************************
1835 * About GNUstep Panel
1836 *****************************************************************************/
1839 static void
1840 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1841 unsigned long blackPixel, unsigned long whitePixel)
1843 GC gc;
1844 XGCValues gcv;
1845 XRectangle rects[3];
1847 gcv.foreground = blackPixel;
1848 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1850 XFillArc(dpy, d, gc, width/45, height/45,
1851 width - 2*width/45, height - 2*height/45, 0, 360*64);
1853 rects[0].x = 0;
1854 rects[0].y = 37*height/45;
1855 rects[0].width = width/3;
1856 rects[0].height = height - rects[0].y;
1858 rects[1].x = rects[0].width;
1859 rects[1].y = height/2;
1860 rects[1].width = width - 2*width/3;
1861 rects[1].height = height - rects[1].y;
1863 rects[2].x = 2*width/3;
1864 rects[2].y = height - 37*height/45;
1865 rects[2].width = width/3;
1866 rects[2].height = height - rects[2].y;
1868 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1869 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1871 XSetForeground(dpy, gc, whitePixel);
1872 XFillArc(dpy, d, gc, width/45, height/45,
1873 width - 2*width/45, height - 2*height/45, 0, 360*64);
1875 XFreeGC(dpy, gc);
1879 typedef struct {
1880 WScreen *scr;
1882 WWindow *wwin;
1884 WMWindow *win;
1886 WMLabel *gstepL;
1887 WMLabel *textL;
1888 } GNUstepPanel;
1891 static GNUstepPanel *gnustepPanel = NULL;
1893 static void
1894 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1896 WMUnmapWidget(gnustepPanel->win);
1898 WMDestroyWidget(gnustepPanel->win);
1900 wUnmanageWindow(gnustepPanel->wwin, False, False);
1902 wfree(gnustepPanel);
1904 gnustepPanel = NULL;
1908 void
1909 wShowGNUstepPanel(WScreen *scr)
1911 GNUstepPanel *panel;
1912 Window parent;
1913 WWindow *wwin;
1914 WMPixmap *pixmap;
1915 WMColor *color;
1917 if (gnustepPanel) {
1918 if (gnustepPanel->scr == scr) {
1919 wRaiseFrame(gnustepPanel->wwin->frame->core);
1920 wSetFocusTo(scr, gnustepPanel->wwin);
1922 return;
1925 panel = wmalloc(sizeof(GNUstepPanel));
1927 panel->scr = scr;
1929 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1930 WMResizeWidget(panel->win, 325, 205);
1932 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1933 WMScreenDepth(scr->wmscreen), True);
1935 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1937 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1938 WMColorPixel(color), scr->white_pixel);
1940 WMReleaseColor(color);
1942 XSetForeground(dpy, scr->mono_gc, 0);
1943 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1944 130, 130);
1945 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1947 panel->gstepL = WMCreateLabel(panel->win);
1948 WMResizeWidget(panel->gstepL, 285, 64);
1949 WMMoveWidget(panel->gstepL, 20, 0);
1950 WMSetLabelTextAlignment(panel->gstepL, WARight);
1951 WMSetLabelText(panel->gstepL, "GNUstep");
1953 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1955 WMSetLabelFont(panel->gstepL, font);
1956 WMReleaseFont(font);
1959 panel->textL = WMCreateLabel(panel->win);
1960 WMResizeWidget(panel->textL, 305, 140);
1961 WMMoveWidget(panel->textL, 10, 50);
1962 WMSetLabelTextAlignment(panel->textL, WARight);
1963 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1964 WMSetLabelText(panel->textL,
1965 _("Window Maker is part of the GNUstep project.\n"\
1966 "The GNUstep project aims to create a free\n"\
1967 "implementation of the OpenStep(tm) specification\n"\
1968 "which is a object-oriented framework for\n"\
1969 "creating advanced graphical, multi-platform\n"\
1970 "applications. Additionally, a development and\n"\
1971 "user desktop enviroment will be created on top\n"\
1972 "of the framework. For more information about\n"\
1973 "GNUstep, please visit: www.gnustep.org"));
1974 WMSetLabelImage(panel->textL, pixmap);
1976 WMReleasePixmap(pixmap);
1978 WMRealizeWidget(panel->win);
1979 WMMapSubwidgets(panel->win);
1981 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1983 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1986 WMPoint center = getCenter(scr, 325, 200);
1988 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
1989 center.x, center.y,
1990 325, 200);
1993 WSETUFLAG(wwin, no_closable, 0);
1994 WSETUFLAG(wwin, no_close_button, 0);
1995 wWindowUpdateButtonImages(wwin);
1996 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1997 #ifdef XKB_BUTTON_HINT
1998 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1999 #endif
2000 wwin->frame->on_click_right = destroyGNUstepPanel;
2002 panel->wwin = wwin;
2004 WMMapWidget(panel->win);
2006 wWindowMap(wwin);
2008 gnustepPanel = panel;