Fixed some focus related problems when switching workspaces, including the
[wmaker-crm.git] / src / dialog.c
blob09f4066cbe130d08ad2e0f7ad0245236f51ed8c0
1 /* dialog.c - dialog windows for internal use
3 * Window Maker window manager
5 * Copyright (c) 1997-2002 Alfredo K. Kojima
6 * Copyright (c) 1998-2002 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"
65 extern WPreferences wPreferences;
69 int
70 wMessageDialog(WScreen *scr, char *title, char *message,
71 char *defBtn, char *altBtn, char *othBtn)
73 WMAlertPanel *panel;
74 Window parent;
75 WWindow *wwin;
76 int result;
78 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message,
79 defBtn, altBtn, othBtn);
81 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
83 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
85 wwin = wManageInternalWindow(scr, parent, None, NULL,
86 (scr->scr_width - 400)/2,
87 (scr->scr_height - 180)/2, 400, 180);
88 wwin->client_leader = WMWidgetXID(panel->win);
90 WMMapWidget(panel->win);
92 wWindowMap(wwin);
94 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
96 result = panel->result;
98 WMUnmapWidget(panel->win);
100 wUnmanageWindow(wwin, False, False);
102 WMDestroyAlertPanel(panel);
104 XDestroyWindow(dpy, parent);
106 return result;
110 void
111 toggleSaveSession(WMWidget *w, void *data)
113 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
118 wExitDialog(WScreen *scr, char *title, char *message,
119 char *defBtn, char *altBtn, char *othBtn)
121 WMAlertPanel *panel;
122 WMButton *saveSessionBtn;
123 Window parent;
124 WWindow *wwin;
125 int result;
127 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message,
128 defBtn, altBtn, othBtn);
130 /* add save session button */
131 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
132 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
133 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn),
134 False, True, 200, 0, 0);
135 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
136 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
137 WMRealizeWidget(saveSessionBtn);
138 WMMapWidget(saveSessionBtn);
140 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
142 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
144 wwin = wManageInternalWindow(scr, parent, None, NULL,
145 (scr->scr_width - 400)/2,
146 (scr->scr_height - 180)/2, 400, 180);
147 wwin->client_leader = WMWidgetXID(panel->win);
149 WMMapWidget(panel->win);
151 wWindowMap(wwin);
153 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
155 result = panel->result;
157 WMUnmapWidget(panel->win);
159 wUnmanageWindow(wwin, False, False);
161 WMDestroyAlertPanel(panel);
163 XDestroyWindow(dpy, parent);
165 return result;
170 wInputDialog(WScreen *scr, char *title, char *message, char **text)
172 WWindow *wwin;
173 Window parent;
174 WMInputPanel *panel;
175 char *result;
178 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text,
179 _("OK"), _("Cancel"));
182 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
183 XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
185 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
187 wwin = wManageInternalWindow(scr, parent, None, NULL,
188 (scr->scr_width - 320)/2,
189 (scr->scr_height - 160)/2, 320, 160);
191 wwin->client_leader = WMWidgetXID(panel->win);
193 WMMapWidget(panel->win);
195 wWindowMap(wwin);
197 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
199 if (panel->result == WAPRDefault)
200 result = WMGetTextFieldText(panel->text);
201 else
202 result = NULL;
204 wUnmanageWindow(wwin, False, False);
206 WMDestroyInputPanel(panel);
208 XDestroyWindow(dpy, parent);
210 if (result==NULL)
211 return False;
212 else {
213 if (*text)
214 wfree(*text);
215 *text = result;
217 return True;
223 *****************************************************************
224 * Icon Selection Panel
225 *****************************************************************
228 typedef struct IconPanel {
230 WScreen *scr;
232 WMWindow *win;
234 WMLabel *dirLabel;
235 WMLabel *iconLabel;
237 WMList *dirList;
238 WMList *iconList;
239 WMFont *normalfont;
241 WMButton *previewButton;
243 WMLabel *iconView;
245 WMLabel *fileLabel;
246 WMTextField *fileField;
248 WMButton *okButton;
249 WMButton *cancelButton;
250 #if 0
251 WMButton *chooseButton;
252 #endif
253 short done;
254 short result;
255 short preview;
256 } IconPanel;
260 static void
261 listPixmaps(WScreen *scr, WMList *lPtr, char *path)
263 struct dirent *dentry;
264 DIR *dir;
265 char pbuf[PATH_MAX+16];
266 char *apath;
267 IconPanel *panel = WMGetHangedData(lPtr);
269 panel->preview = False;
271 apath = wexpandpath(path);
272 dir = opendir(apath);
274 if (!dir) {
275 char *msg;
276 char *tmp;
277 tmp = _("Could not open directory ");
278 msg = wmalloc(strlen(tmp)+strlen(path)+6);
279 strcpy(msg, tmp);
280 strcat(msg, path);
282 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
283 wfree(msg);
284 wfree(apath);
285 return;
288 /* list contents in the column */
289 while ((dentry = readdir(dir))) {
290 struct stat statb;
292 if (strcmp(dentry->d_name, ".")==0 ||
293 strcmp(dentry->d_name, "..")==0)
294 continue;
296 strcpy(pbuf, apath);
297 strcat(pbuf, "/");
298 strcat(pbuf, dentry->d_name);
300 if (stat(pbuf, &statb)<0)
301 continue;
303 if (statb.st_mode & (S_IRUSR|S_IRGRP|S_IROTH)
304 && statb.st_mode & (S_IFREG|S_IFLNK)) {
305 WMAddListItem(lPtr, dentry->d_name);
308 WMSortListItems(lPtr);
310 closedir(dir);
311 wfree(apath);
312 panel->preview = True;
317 static void
318 setViewedImage(IconPanel *panel, char *file)
320 WMPixmap *pixmap;
321 RColor color;
323 color.red = 0xae;
324 color.green = 0xaa;
325 color.blue = 0xae;
326 color.alpha = 0;
327 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win),
328 file, &color);
329 if (!pixmap) {
330 WMSetButtonEnabled(panel->okButton, False);
332 WMSetLabelText(panel->iconView, _("Could not load image file "));
334 WMSetLabelImage(panel->iconView, NULL);
335 } else {
336 WMSetButtonEnabled(panel->okButton, True);
338 WMSetLabelText(panel->iconView, NULL);
339 WMSetLabelImage(panel->iconView, pixmap);
340 WMReleasePixmap(pixmap);
345 static void
346 listCallback(void *self, void *data)
348 WMList *lPtr = (WMList*)self;
349 IconPanel *panel = (IconPanel*)data;
350 char *path;
352 if (lPtr==panel->dirList) {
353 WMListItem *item = WMGetListSelectedItem(lPtr);
355 if (item == NULL)
356 return;
357 path = item->text;
359 WMSetTextFieldText(panel->fileField, path);
361 WMSetLabelImage(panel->iconView, NULL);
363 WMSetButtonEnabled(panel->okButton, False);
365 WMClearList(panel->iconList);
366 listPixmaps(panel->scr, panel->iconList, path);
367 } else {
368 char *tmp, *iconFile;
369 WMListItem *item = WMGetListSelectedItem(panel->dirList);
371 if (item == NULL)
372 return;
373 path = item->text;
374 tmp = wexpandpath(path);
376 item = WMGetListSelectedItem(panel->iconList);
377 if (item == NULL)
378 return;
379 iconFile = item->text;
381 path = wmalloc(strlen(tmp)+strlen(iconFile)+4);
382 strcpy(path, tmp);
383 strcat(path, "/");
384 strcat(path, iconFile);
385 wfree(tmp);
386 WMSetTextFieldText(panel->fileField, path);
387 setViewedImage(panel, path);
388 wfree(path);
393 static void
394 listIconPaths(WMList *lPtr)
396 char *paths;
397 char *path;
399 paths = wstrdup(wPreferences.icon_path);
401 path = strtok(paths, ":");
403 do {
404 char *tmp;
406 tmp = wexpandpath(path);
407 /* do not sort, because the order implies the order of
408 * directories searched */
409 if (access(tmp, X_OK)==0)
410 WMAddListItem(lPtr, path);
411 wfree(tmp);
412 } while ((path=strtok(NULL, ":"))!=NULL);
414 wfree(paths);
418 void
419 drawIconProc(WMList *lPtr, int index, Drawable d, char *text,
420 int state, WMRect *rect)
422 IconPanel *panel = WMGetHangedData(lPtr);
423 GC gc = panel->scr->draw_gc;
424 GC copygc = panel->scr->copy_gc;
425 char *file, *dirfile;
426 WMPixmap *pixmap;
427 WMColor *blackcolor;
428 WMColor *whitecolor;
429 WMSize size;
430 WMScreen *wmscr = WMWidgetScreen(panel->win);
431 RColor color;
432 int width;
434 if(!panel->preview) return;
436 width = rect->size.width;
438 blackcolor = WMBlackColor(wmscr);
439 whitecolor = WMWhiteColor(wmscr);
441 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
443 int len = strlen(dirfile)+strlen(text)+4;
444 file = wmalloc(len);
445 snprintf(file, len, "%s/%s", dirfile, text);
447 wfree(dirfile);
449 if ((state & WLDSSelected) != 0) {
450 color.red = color.green = color.blue = 0xff;
451 color.alpha = 0;
452 } else {
453 color.red = color.blue = 0xae;
454 color.green = 0xaa; color.alpha = 0;
456 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
457 wfree(file);
459 if (!pixmap) {
460 WMRemoveListItem(lPtr, index);
461 return;
464 XClearArea(dpy, d, rect->pos.x, rect->pos.y, width, rect->size.height,
465 False);
466 XSetClipMask(dpy, gc, None);
468 XDrawRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x + 5,
469 rect->pos.y +5, width - 10, 54);
471 XDrawLine(dpy, d, WMColorGC(whitecolor), rect->pos.x,
472 rect->pos.y+rect->size.height-1, rect->pos.x+width,
473 rect->pos.y+rect->size.height-1);
476 if (state&WLDSSelected) {
477 XFillRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x,
478 rect->pos.y, width, rect->size.height);
481 size = WMGetPixmapSize(pixmap);
483 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
484 XSetClipOrigin(dpy, copygc, rect->pos.x + (width-size.width)/2,
485 rect->pos.y+2);
486 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
487 size.width>100?100:size.width, size.height>64?64:size.height,
488 rect->pos.x + (width-size.width)/2, rect->pos.y+2);
491 int i,j;
492 int fheight = WMFontHeight(panel->normalfont);
493 int tlen = strlen(text);
494 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
495 int ofx, ofy;
497 ofx = rect->pos.x + (width - twidth)/2;
498 ofy = rect->pos.y + 64 - fheight;
500 for(i=-1;i<2;i++)
501 for(j=-1;j<2;j++)
502 WMDrawString(wmscr, d, WMColorGC(whitecolor),
503 panel->normalfont, ofx+i, ofy+j,
504 text, tlen);
506 WMDrawString(wmscr, d, WMColorGC(blackcolor), panel->normalfont,
507 ofx, ofy, text, tlen);
510 WMReleasePixmap(pixmap);
511 /* I hope it is better to do not use cache / on my box it is fast nuff */
512 XFlush(dpy);
514 WMReleaseColor(blackcolor);
515 WMReleaseColor(whitecolor);
519 static void
520 buttonCallback(void *self, void *clientData)
522 WMButton *bPtr = (WMButton*)self;
523 IconPanel *panel = (IconPanel*)clientData;
526 if (bPtr==panel->okButton) {
527 panel->done = True;
528 panel->result = True;
529 } else if (bPtr==panel->cancelButton) {
530 panel->done = True;
531 panel->result = False;
532 } else if (bPtr==panel->previewButton) {
533 /**** Previewer ****/
534 WMSetButtonEnabled(bPtr, False);
535 WMSetListUserDrawItemHeight(panel->iconList, 68);
536 WMSetListUserDrawProc(panel->iconList, drawIconProc);
537 WMRedisplayWidget(panel->iconList);
538 /* for draw proc to access screen/gc */
539 /*** end preview ***/
541 #if 0
542 else if (bPtr==panel->chooseButton) {
543 WMOpenPanel *op;
545 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
547 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
548 char *path;
549 path = WMGetFilePanelFile(op);
550 WMSetTextFieldText(panel->fileField, path);
551 setViewedImage(panel, path);
552 wfree(path);
554 WMDestroyFilePanel(op);
556 #endif
560 static void
561 keyPressHandler(XEvent *event, void *data)
563 IconPanel *panel = (IconPanel*)data;
564 char buffer[32];
565 int count;
566 KeySym ksym;
567 int iidx;
568 int didx;
569 int item;
570 WMList *list = NULL;
572 if (event->type == KeyRelease)
573 return;
575 buffer[0] = 0;
576 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
579 iidx = WMGetListSelectedItemRow(panel->iconList);
580 didx = WMGetListSelectedItemRow(panel->dirList);
582 switch (ksym) {
583 case XK_Up:
584 if (iidx > 0)
585 item = iidx-1;
586 else
587 item = iidx;
588 list = panel->iconList;
589 break;
590 case XK_Down:
591 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
592 item = iidx+1;
593 else
594 item = iidx;
595 list = panel->iconList;
596 break;
597 case XK_Home:
598 item = 0;
599 list = panel->iconList;
600 break;
601 case XK_End:
602 item = WMGetListNumberOfRows(panel->iconList) - 1;
603 list = panel->iconList;
604 break;
605 case XK_Next:
606 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
607 item = didx + 1;
608 else
609 item = didx;
610 list = panel->dirList;
611 break;
612 case XK_Prior:
613 if (didx > 0)
614 item = didx - 1;
615 else
616 item = 0;
617 list = panel->dirList;
618 break;
619 case XK_Return:
620 WMPerformButtonClick(panel->okButton);
621 break;
622 case XK_Escape:
623 WMPerformButtonClick(panel->cancelButton);
624 break;
627 if (list) {
628 WMSelectListItem(list, item);
629 WMSetListPosition(list, item - 5);
630 listCallback(list, panel);
636 Bool
637 wIconChooserDialog(WScreen *scr, char **file, char *instance, char *class)
639 WWindow *wwin;
640 Window parent;
641 IconPanel *panel;
642 WMColor *color;
643 WMFont *boldFont;
645 panel = wmalloc(sizeof(IconPanel));
646 memset(panel, 0, sizeof(IconPanel));
648 panel->scr = scr;
650 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
651 WMResizeWidget(panel->win, 450, 280);
653 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask|KeyReleaseMask,
654 keyPressHandler, panel);
657 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
658 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
660 panel->dirLabel = WMCreateLabel(panel->win);
661 WMResizeWidget(panel->dirLabel, 200, 20);
662 WMMoveWidget(panel->dirLabel, 10, 7);
663 WMSetLabelText(panel->dirLabel, _("Directories"));
664 WMSetLabelFont(panel->dirLabel, boldFont);
665 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
667 WMSetLabelRelief(panel->dirLabel, WRSunken);
669 panel->iconLabel = WMCreateLabel(panel->win);
670 WMResizeWidget(panel->iconLabel, 140, 20);
671 WMMoveWidget(panel->iconLabel, 215, 7);
672 WMSetLabelText(panel->iconLabel, _("Icons"));
673 WMSetLabelFont(panel->iconLabel, boldFont);
674 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
676 WMReleaseFont(boldFont);
678 color = WMWhiteColor(scr->wmscreen);
679 WMSetLabelTextColor(panel->dirLabel, color);
680 WMSetLabelTextColor(panel->iconLabel, color);
681 WMReleaseColor(color);
683 color = WMDarkGrayColor(scr->wmscreen);
684 WMSetWidgetBackgroundColor(panel->iconLabel, color);
685 WMSetWidgetBackgroundColor(panel->dirLabel, color);
686 WMReleaseColor(color);
688 WMSetLabelRelief(panel->iconLabel, WRSunken);
690 panel->dirList = WMCreateList(panel->win);
691 WMResizeWidget(panel->dirList, 200, 170);
692 WMMoveWidget(panel->dirList, 10, 30);
693 WMSetListAction(panel->dirList, listCallback, panel);
695 panel->iconList = WMCreateList(panel->win);
696 WMResizeWidget(panel->iconList, 140, 170);
697 WMMoveWidget(panel->iconList, 215, 30);
698 WMSetListAction(panel->iconList, listCallback, panel);
700 WMHangData(panel->iconList,panel);
702 panel->previewButton = WMCreateCommandButton(panel->win);
703 WMResizeWidget(panel->previewButton, 75, 26);
704 WMMoveWidget(panel->previewButton, 365, 130);
705 WMSetButtonText(panel->previewButton, _("Preview"));
706 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
708 panel->iconView = WMCreateLabel(panel->win);
709 WMResizeWidget(panel->iconView, 75, 75);
710 WMMoveWidget(panel->iconView, 365, 40);
711 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
712 WMSetLabelRelief(panel->iconView, WRSunken);
713 WMSetLabelTextAlignment(panel->iconView, WACenter);
715 panel->fileLabel = WMCreateLabel(panel->win);
716 WMResizeWidget(panel->fileLabel, 80, 20);
717 WMMoveWidget(panel->fileLabel, 10, 210);
718 WMSetLabelText(panel->fileLabel, _("File Name:"));
720 panel->fileField = WMCreateTextField(panel->win);
721 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
722 WMResizeWidget(panel->fileField, 345, 20);
723 WMMoveWidget(panel->fileField, 95, 210);
724 WMSetTextFieldEditable(panel->fileField, False);
726 panel->okButton = WMCreateCommandButton(panel->win);
727 WMResizeWidget(panel->okButton, 80, 26);
728 WMMoveWidget(panel->okButton, 360, 240);
729 WMSetButtonText(panel->okButton, _("OK"));
730 WMSetButtonEnabled(panel->okButton, False);
731 WMSetButtonAction(panel->okButton, buttonCallback, panel);
733 panel->cancelButton = WMCreateCommandButton(panel->win);
734 WMResizeWidget(panel->cancelButton, 80, 26);
735 WMMoveWidget(panel->cancelButton, 270, 240);
736 WMSetButtonText(panel->cancelButton, _("Cancel"));
737 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
738 #if 0
739 panel->chooseButton = WMCreateCommandButton(panel->win);
740 WMResizeWidget(panel->chooseButton, 110, 26);
741 WMMoveWidget(panel->chooseButton, 150, 240);
742 WMSetButtonText(panel->chooseButton, _("Choose File"));
743 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
744 #endif
745 WMRealizeWidget(panel->win);
746 WMMapSubwidgets(panel->win);
748 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
750 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
753 char *tmp;
754 int len = (instance ? strlen(instance) : 0)
755 + (class ? strlen(class) : 0) + 32;
757 tmp = wmalloc(len);
759 if (tmp && (instance || class))
760 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
761 else
762 strcpy(tmp, _("Icon Chooser"));
764 wwin = wManageInternalWindow(scr, parent, None, tmp,
765 (scr->scr_width - 450)/2,
766 (scr->scr_height - 280)/2, 450, 280);
767 wfree(tmp);
770 /* put icon paths in the list */
771 listIconPaths(panel->dirList);
773 WMMapWidget(panel->win);
775 wWindowMap(wwin);
777 while (!panel->done) {
778 XEvent event;
780 WMNextEvent(dpy, &event);
781 WMHandleEvent(&event);
784 if (panel->result) {
785 char *defaultPath, *wantedPath;
787 /* check if the file the user selected is not the one that
788 * would be loaded by default with the current search path */
789 *file = WMGetListSelectedItem(panel->iconList)->text;
790 if ((*file)[0]==0) {
791 wfree(*file);
792 *file = NULL;
793 } else {
794 defaultPath = FindImage(wPreferences.icon_path, *file);
795 wantedPath = WMGetTextFieldText(panel->fileField);
796 /* if the file is not the default, use full path */
797 if (strcmp(wantedPath, defaultPath)!=0) {
798 *file = wantedPath;
799 } else {
800 *file = wstrdup(*file);
801 wfree(wantedPath);
803 wfree(defaultPath);
805 } else {
806 *file = NULL;
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 panel->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 WMLabel *name2L;
843 WMLabel *versionL;
845 WMLabel *infoL;
847 WMLabel *copyrL;
849 #ifdef SILLYNESS
850 WMHandlerID timer;
851 int cycle;
852 RImage *icon;
853 RImage *pic;
854 WMPixmap *oldPix;
855 WMFont *oldFont;
856 char *str;
857 int x;
858 #endif
859 } InfoPanel;
863 #define COPYRIGHT_TEXT \
864 "Copyright \xa9 1997-2002 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
865 "Copyright \xa9 1998-2002 Dan Pascu <dan@windowmaker.org>"
869 static InfoPanel *thePanel = NULL;
871 static void
872 destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
874 #ifdef SILLYNESS
875 if (thePanel->timer) {
876 WMDeleteTimerHandler(thePanel->timer);
878 if (thePanel->oldPix) {
879 WMReleasePixmap(thePanel->oldPix);
881 if (thePanel->oldFont) {
882 WMReleaseFont(thePanel->oldFont);
884 if (thePanel->icon) {
885 RReleaseImage(thePanel->icon);
887 if (thePanel->pic) {
888 RReleaseImage(thePanel->pic);
890 #endif /* SILLYNESS */
891 WMUnmapWidget(thePanel);
893 wUnmanageWindow(thePanel->wwin, False, False);
895 WMDestroyWidget(thePanel->win);
897 wfree(thePanel);
899 thePanel = NULL;
903 WMPixmap*
904 renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
906 WMPixmap *wpix = NULL;
907 Pixmap grad = None;
908 Pixmap mask = None;
909 RContext *rc = WMScreenRContext(scr);
910 XFontStruct *f = NULL;
911 int w, h;
912 GC gc = None;
914 f = XLoadQueryFont(dpy, font);
915 if (!f)
916 return NULL;
918 w = XTextWidth(f, text, strlen(text));
919 h = f->ascent+f->descent;
921 mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
922 gc = XCreateGC(dpy, mask, 0, NULL);
923 XSetForeground(dpy, gc, 0);
924 XSetFont(dpy, gc, f->fid);
925 XFillRectangle(dpy, mask, gc, 0, 0, w, h);
927 XSetForeground(dpy, gc, 1);
928 XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
929 XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
930 XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
932 grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
934 WMColor *color;
936 color = WMBlackColor(scr);
937 XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
938 WMReleaseColor(color);
941 wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
943 if (gc)
944 XFreeGC(dpy, gc);
945 XFreeFont(dpy, f);
947 return wpix;
950 #ifdef SILLYNESS
952 extern WMPixmap *DoXThing();
953 extern Bool InitXThing();
955 static void
956 logoPushCallback(void *data)
958 InfoPanel *panel = (InfoPanel*)data;
959 char buffer[512];
960 int i;
961 static int oldi = 0;
962 int len;
963 static int jingobeu[] = {
964 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
965 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
966 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
968 static int c = 0;
970 if (panel->x) {
971 XKeyboardControl kc;
972 XKeyboardState ksave;
973 unsigned long mask = KBBellPitch|KBBellDuration|KBBellPercent;
975 XGetKeyboardControl(dpy, &ksave);
977 if (panel->x > 0) {
978 if(jingobeu[panel->x-1]==0) {
979 panel->x=-1;
980 } else if (jingobeu[panel->x-1]<0) {
981 panel->x++;
982 c=jingobeu[panel->x-1]/50;
983 panel->x++;
984 } else if (c==0) {
985 kc.bell_percent=50;
986 kc.bell_pitch=jingobeu[panel->x-1];
987 panel->x++;
988 kc.bell_duration=jingobeu[panel->x-1];
989 c=jingobeu[panel->x-1]/50;
990 panel->x++;
991 XChangeKeyboardControl(dpy, mask, &kc);
992 XBell(dpy, 50);
993 XFlush(dpy);
994 } else {
995 c--;
998 if (!(panel->cycle % 4)) {
999 WMPixmap *p;
1001 p = DoXThing(panel->wwin);
1002 WMSetLabelImage(panel->logoL, p);
1004 kc.bell_pitch = ksave.bell_pitch;
1005 kc.bell_percent = ksave.bell_percent;
1006 kc.bell_duration = ksave.bell_duration;
1007 XChangeKeyboardControl(dpy, mask, &kc);
1008 } else if (panel->cycle < 30) {
1009 RImage *image;
1010 WMPixmap *pix;
1011 RColor gray;
1013 gray.red = 0xae; gray.green = 0xaa;
1014 gray.blue = 0xae; gray.alpha = 0;
1016 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
1017 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
1018 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
1019 RReleaseImage(image);
1020 WMSetLabelImage(panel->logoL, pix);
1021 WMReleasePixmap(pix);
1024 /* slow down text a little */
1025 i = (int)(panel->cycle * 50.0/85.0)%200;
1027 if (i != oldi) {
1028 len = strlen(panel->str);
1030 strncpy(buffer, panel->str, i<len ? i : len);
1031 if (i >= len)
1032 memset(&buffer[len], ' ', i-len);
1034 strncpy(buffer, panel->str, i<len ? i : len);
1035 if (i >= len)
1036 memset(&buffer[len], ' ', i-len);
1037 buffer[i]=0;
1039 WMSetLabelText(panel->versionL, buffer);
1041 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1043 oldi = i;
1046 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1047 panel->cycle++;
1051 static void
1052 handleLogoPush(XEvent *event, void *data)
1054 InfoPanel *panel = (InfoPanel*)data;
1055 static int broken = 0;
1056 static int clicks = 0;
1057 static char *pic_data[] = {
1058 "45 45 57 1",
1059 " c None",
1060 ". c #000000",
1061 "X c #383C00",
1062 "o c #515500",
1063 "O c #616100",
1064 "+ c #616900",
1065 "@ c #696D00",
1066 "# c #697100",
1067 "$ c #495100",
1068 "% c #202800",
1069 "& c #969600",
1070 "* c #CFCF00",
1071 "= c #D7DB00",
1072 "- c #D7D700",
1073 "; c #C7CB00",
1074 ": c #A6AA00",
1075 "> c #494900",
1076 ", c #8E8E00",
1077 "< c #DFE700",
1078 "1 c #F7FF00",
1079 "2 c #FFFF00",
1080 "3 c #E7EB00",
1081 "4 c #B6B600",
1082 "5 c #595900",
1083 "6 c #717500",
1084 "7 c #AEB200",
1085 "8 c #CFD300",
1086 "9 c #E7EF00",
1087 "0 c #EFF300",
1088 "q c #9EA200",
1089 "w c #F7FB00",
1090 "e c #F7F700",
1091 "r c #BEBE00",
1092 "t c #8E9200",
1093 "y c #EFF700",
1094 "u c #969A00",
1095 "i c #414500",
1096 "p c #595D00",
1097 "a c #E7E700",
1098 "s c #C7C700",
1099 "d c #797D00",
1100 "f c #BEC300",
1101 "g c #DFE300",
1102 "h c #868600",
1103 "j c #EFEF00",
1104 "k c #9E9E00",
1105 "l c #616500",
1106 "z c #DFDF00",
1107 "x c #868A00",
1108 "c c #969200",
1109 "v c #B6BA00",
1110 "b c #A6A600",
1111 "n c #8E8A00",
1112 "m c #717100",
1113 "M c #AEAE00",
1114 "N c #AEAA00",
1115 "B c #868200",
1116 " ............... ",
1117 " ....XoO+@##+O$%.... ",
1118 " ...%X&*========-;;:o... ",
1119 " ...>.>,<122222222222134@... ",
1120 " ..>5678912222222222222220q%.. ",
1121 " ..$.&-w2222222222222222222er>.. ",
1122 " ..O.t31222222222222222222222y4>.. ",
1123 " ...O5u3222222222222222222222222yri... ",
1124 " ..>p&a22222222222222222222222222wso.. ",
1125 " ..ids91222222222222222222222222222wfi.. ",
1126 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1127 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1128 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1129 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1130 "..io*222222222&...u22222222yt..%*22222220:%. ",
1131 "..>k02222222227...f222222222v..X=222222229t. ",
1132 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1133 ".%vw222222222221y2222222222219*y2222222222wd.",
1134 ".X;2222222222222222222222222222222222222222b.",
1135 ".i*2222222222222222222222222222222222222222v.",
1136 ".i*2222222222222222222222222222222222222222;.",
1137 ".i*22222222222222222222222222222222222222228.",
1138 ".>*2222222222222222222222222222222222222222=.",
1139 ".i*22222222222222222222222222222222222222228.",
1140 ".i*2222222222222222222222222222222222222222;.",
1141 ".X*222222222222222222222222222222we12222222r.",
1142 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1143 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1144 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1145 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1146 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1147 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1148 " ...:e2222218mdz22222222222222a&$vw222220@...",
1149 " ...O-122222y:.u02222222222229q$uj222221r... ",
1150 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1151 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1152 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1153 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1154 " ..Xb9122222109g-****;<y22221zn%... ",
1155 " ..X&801222222222222222222w-h.... ",
1156 " ...o:=022222222222222221=lX... ",
1157 " ..X@:;3w2222222222210fO... ",
1158 " ...XX&v8<30000003-N@... ",
1159 " .....XmnbN:q&Bo.... ",
1160 " ............ "
1162 static char *msgs[] = {
1163 "Have a nice day!",
1164 "Focus follow mouse users will burn in hell!!!",
1165 "Mooo Canada!!!!",
1166 "Hi! My name is bobby...",
1167 "AHH! The neurotic monkeys are after me!",
1168 "WE GET SIGNAL",
1169 "HOW ARE YOU GENTLEMEN?",
1170 "WHAT YOU SAY??",
1171 "SOMEBODY SET UP US THE BOMB",
1172 "ALL YOUR BASE ARE BELONG TO US!",
1173 "Oh My God!!! Larry is back!"
1177 clicks++;
1179 if (!panel->timer && !broken && clicks > 0) {
1180 WMFont *font;
1182 panel->x = 0;
1183 clicks = 0;
1184 if (!panel->icon) {
1185 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1186 if (!panel->icon) {
1187 broken = 1;
1188 return;
1189 } else {
1190 RColor color;
1192 color.red = 0xae; color.green = 0xaa;
1193 color.blue = 0xae; color.alpha = 0;
1195 panel->icon = RCloneImage(panel->icon);
1196 RCombineImageWithColor(panel->icon, &color);
1199 if (!panel->pic) {
1200 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1201 if (!panel->pic) {
1202 broken = 1;
1203 RReleaseImage(panel->icon);
1204 panel->icon = NULL;
1205 return;
1209 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1211 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1212 panel->cycle = 0;
1213 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1214 /* If we don't use a fixed font, scrolling will be jumpy */
1215 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1216 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1217 WMRetainFont(panel->oldFont);
1218 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
1219 if (font) {
1220 WMSetLabelFont(panel->versionL, font);
1221 WMReleaseFont(font);
1223 WMSetLabelText(panel->versionL, "");
1224 } else if (panel->timer) {
1225 char version[20];
1227 panel->x = 0;
1228 clicks = 0;
1229 WMSetLabelImage(panel->logoL, panel->oldPix);
1230 WMReleasePixmap(panel->oldPix);
1231 panel->oldPix = NULL;
1233 WMDeleteTimerHandler(panel->timer);
1234 panel->timer = NULL;
1236 WMSetLabelFont(panel->versionL, panel->oldFont);
1237 if (panel->oldFont) {
1238 WMReleaseFont(panel->oldFont);
1239 panel->oldFont = NULL;
1241 snprintf(version, sizeof(version), _("Version %s"), VERSION);
1242 WMSetLabelText(panel->versionL, version);
1243 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1247 XEvent ev;
1248 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1249 ButtonPress, &ev));
1252 #endif /* SILLYNESS */
1255 void
1256 wShowInfoPanel(WScreen *scr)
1258 InfoPanel *panel;
1259 WMPixmap *logo;
1260 WMSize size;
1261 WMFont *font;
1262 char *strbuf = NULL;
1263 char buffer[256];
1264 Window parent;
1265 WWindow *wwin;
1266 RColor color1, color2;
1267 char **strl;
1268 int i;
1269 char *visuals[] = {
1270 "StaticGray",
1271 "GrayScale",
1272 "StaticColor",
1273 "PseudoColor",
1274 "TrueColor",
1275 "DirectColor"
1279 if (thePanel) {
1280 if (thePanel->scr == scr) {
1281 wRaiseFrame(thePanel->wwin->frame->core);
1282 wSetFocusTo(scr, thePanel->wwin);
1284 return;
1287 panel = wmalloc(sizeof(InfoPanel));
1288 memset(panel, 0, sizeof(InfoPanel));
1290 panel->scr = scr;
1292 panel->win = WMCreateWindow(scr->wmscreen, "info");
1293 WMResizeWidget(panel->win, 382, 230);
1295 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor*)NULL);
1296 if (!logo) {
1297 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1299 if (logo) {
1300 size = WMGetPixmapSize(logo);
1301 panel->logoL = WMCreateLabel(panel->win);
1302 WMResizeWidget(panel->logoL, 64, 64);
1303 WMMoveWidget(panel->logoL, 30, 20);
1304 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1305 WMSetLabelImage(panel->logoL, logo);
1306 #ifdef SILLYNESS
1307 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1308 handleLogoPush, panel);
1309 #endif
1310 WMReleasePixmap(logo);
1313 panel->name1L = WMCreateLabel(panel->win);
1314 WMResizeWidget(panel->name1L, 240, 30);
1315 WMMoveWidget(panel->name1L, 100, 30);
1316 color1.red = 0;
1317 color1.green = 0;
1318 color1.blue = 0;
1319 color2.red = 0x50;
1320 color2.green = 0x50;
1321 color2.blue = 0x70;
1322 logo = renderText(scr->wmscreen, "GNU Window Maker",
1323 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1324 if (logo) {
1325 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1326 WMSetLabelImage(panel->name1L, logo);
1327 WMReleasePixmap(logo);
1328 } else {
1329 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1330 if (font) {
1331 WMSetLabelFont(panel->name1L, font);
1332 WMReleaseFont(font);
1334 WMSetLabelTextAlignment(panel->name1L, WACenter);
1335 WMSetLabelText(panel->name1L, "GNU Window Maker");
1338 panel->name2L = WMCreateLabel(panel->win);
1339 WMResizeWidget(panel->name2L, 240, 24);
1340 WMMoveWidget(panel->name2L, 100, 60);
1341 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1342 if (font) {
1343 WMSetLabelFont(panel->name2L, font);
1344 WMReleaseFont(font);
1345 font = NULL;
1347 WMSetLabelTextAlignment(panel->name2L, WACenter);
1348 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1351 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1352 panel->versionL = WMCreateLabel(panel->win);
1353 WMResizeWidget(panel->versionL, 310, 16);
1354 WMMoveWidget(panel->versionL, 30, 95);
1355 WMSetLabelTextAlignment(panel->versionL, WARight);
1356 WMSetLabelText(panel->versionL, buffer);
1357 WMSetLabelWraps(panel->versionL, False);
1359 panel->copyrL = WMCreateLabel(panel->win);
1360 WMResizeWidget(panel->copyrL, 340, 40);
1361 WMMoveWidget(panel->copyrL, 15, 185);
1362 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1363 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1364 /* we want the (c) character in the helvetica font */
1365 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1366 if (font) {
1367 WMSetLabelFont(panel->copyrL, font);
1368 WMReleaseFont(font);
1369 font = NULL;
1372 strbuf = NULL;
1373 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1374 (unsigned)scr->w_visual->visualid,
1375 visuals[scr->w_visual->class], scr->w_depth);
1377 strbuf = wstrappend(strbuf, buffer);
1379 switch (scr->w_depth) {
1380 case 15:
1381 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1382 break;
1383 case 16:
1384 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1385 break;
1386 case 24:
1387 case 32:
1388 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1389 break;
1390 default:
1391 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1<<scr->w_depth);
1392 strbuf = wstrappend(strbuf, buffer);
1393 break;
1397 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1399 struct mallinfo ma = mallinfo();
1400 snprintf(buffer, sizeof(buffer),
1401 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1402 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1404 strbuf = wstrappend(strbuf, buffer);
1406 #endif
1408 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1409 strl = RSupportedFileFormats();
1410 for (i=0; strl[i]!=NULL; i++) {
1411 strbuf = wstrappend(strbuf, strl[i]);
1412 strbuf = wstrappend(strbuf, " ");
1415 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1417 char *list[8];
1418 char buf[80];
1419 int j = 0;
1421 #ifdef MWM_HINTS
1422 list[j++] = "MWM";
1423 #endif
1424 #ifdef KWM_HINTS
1425 list[j++] = "KDE";
1426 #endif
1427 #ifdef GNOME_STUFF
1428 list[j++] = "GNOME";
1429 #endif
1430 #ifdef OLWM_HINTS
1431 list[j++] = "OLWM";
1432 #endif
1434 buf[0] = 0;
1435 for (i = 0; i < j; i++) {
1436 if (i > 0) {
1437 if (i == j - 1)
1438 strcat(buf, _(" and "));
1439 else
1440 strcat(buf, ", ");
1442 strcat(buf, list[i]);
1444 strbuf = wstrappend(strbuf, buf);
1447 if (wPreferences.no_sound) {
1448 strbuf = wstrappend(strbuf, _("\nSound disabled"));
1449 } else {
1450 strbuf = wstrappend(strbuf, _("\nSound enabled"));
1454 panel->infoL = WMCreateLabel(panel->win);
1455 WMResizeWidget(panel->infoL, 350, 75);
1456 WMMoveWidget(panel->infoL, 15, 115);
1457 WMSetLabelText(panel->infoL, strbuf);
1458 font = WMCreateFont(scr->wmscreen, HELVETICA10_FONT);
1459 if (font) {
1460 WMSetLabelFont(panel->infoL, font);
1461 WMReleaseFont(font);
1462 font = NULL;
1464 wfree(strbuf);
1467 WMRealizeWidget(panel->win);
1468 WMMapSubwidgets(panel->win);
1470 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1472 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1474 WMMapWidget(panel->win);
1476 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1477 (scr->scr_width - 382)/2,
1478 (scr->scr_height - 230)/2, 382, 230);
1480 WSETUFLAG(wwin, no_closable, 0);
1481 WSETUFLAG(wwin, no_close_button, 0);
1482 #ifdef XKB_BUTTON_HINT
1483 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1484 #endif
1485 wWindowUpdateButtonImages(wwin);
1486 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1487 wwin->frame->on_click_right = destroyInfoPanel;
1489 wWindowMap(wwin);
1491 panel->wwin = wwin;
1493 thePanel = panel;
1494 #ifdef SILLYNESS
1495 if (InitXThing(panel->scr)) {
1496 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1497 panel->cycle = 0;
1498 panel->x = 1;
1499 panel->str = _("Merry Christmas!");
1500 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1502 #endif
1507 ***********************************************************************
1508 * Legal Panel
1509 ***********************************************************************
1512 typedef struct {
1513 WScreen *scr;
1515 WWindow *wwin;
1517 WMWindow *win;
1519 WMLabel *licenseL;
1520 } LegalPanel;
1523 static LegalPanel *legalPanel = NULL;
1525 static void
1526 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1528 WMUnmapWidget(legalPanel->win);
1530 WMDestroyWidget(legalPanel->win);
1532 wUnmanageWindow(legalPanel->wwin, False, False);
1534 wfree(legalPanel);
1536 legalPanel = NULL;
1540 void
1541 wShowLegalPanel(WScreen *scr)
1543 LegalPanel *panel;
1544 Window parent;
1545 WWindow *wwin;
1547 if (legalPanel) {
1548 if (legalPanel->scr == scr) {
1549 wRaiseFrame(legalPanel->wwin->frame->core);
1550 wSetFocusTo(scr, legalPanel->wwin);
1552 return;
1555 panel = wmalloc(sizeof(LegalPanel));
1557 panel->scr = scr;
1559 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1560 WMResizeWidget(panel->win, 420, 250);
1563 panel->licenseL = WMCreateLabel(panel->win);
1564 WMSetLabelWraps(panel->licenseL, True);
1565 WMResizeWidget(panel->licenseL, 400, 230);
1566 WMMoveWidget(panel->licenseL, 10, 10);
1567 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1568 WMSetLabelText(panel->licenseL,
1569 _(" Window Maker is free software; you can redistribute it and/or\n"
1570 "modify it under the terms of the GNU General Public License as\n"
1571 "published by the Free Software Foundation; either version 2 of the\n"
1572 "License, or (at your option) any later version.\n\n"
1573 " Window Maker is distributed in the hope that it will be useful,\n"
1574 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1575 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1576 "See the GNU General Public License for more details.\n\n"
1577 " You should have received a copy of the GNU General Public\n"
1578 "License along with this program; if not, write to the Free Software\n"
1579 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1580 "02111-1307, USA."));
1581 WMSetLabelRelief(panel->licenseL, WRGroove);
1583 WMRealizeWidget(panel->win);
1584 WMMapSubwidgets(panel->win);
1586 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1588 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1590 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1591 (scr->scr_width - 420)/2,
1592 (scr->scr_height - 250)/2, 420, 250);
1594 WSETUFLAG(wwin, no_closable, 0);
1595 WSETUFLAG(wwin, no_close_button, 0);
1596 wWindowUpdateButtonImages(wwin);
1597 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1598 #ifdef XKB_BUTTON_HINT
1599 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1600 #endif
1601 wwin->frame->on_click_right = destroyLegalPanel;
1603 panel->wwin = wwin;
1605 WMMapWidget(panel->win);
1607 wWindowMap(wwin);
1609 legalPanel = panel;
1614 ***********************************************************************
1615 * Crashing Dialog Panel
1616 ***********************************************************************
1619 extern WDDomain *WDWindowAttributes;
1622 typedef struct _CrashPanel {
1623 WMWindow *win; /* main window */
1625 WMLabel *iconL; /* application icon */
1626 WMLabel *nameL; /* title of panel */
1628 WMFrame *sepF; /* separator frame */
1630 WMLabel *noteL; /* Title of note */
1631 WMLabel *note2L; /* body of note with what happened */
1633 WMFrame *whatF; /* "what to do next" frame */
1634 WMPopUpButton *whatP; /* action selection popup button */
1636 WMButton *okB; /* ok button */
1638 Bool done; /* if finished with this dialog */
1639 int action; /* what to do after */
1641 KeyCode retKey;
1643 } CrashPanel;
1646 static void
1647 handleKeyPress(XEvent *event, void *clientData)
1649 CrashPanel *panel = (CrashPanel*)clientData;
1651 if (event->xkey.keycode == panel->retKey) {
1652 WMPerformButtonClick(panel->okB);
1657 static void
1658 okButtonCallback(void *self, void *clientData)
1660 CrashPanel *panel = (CrashPanel*)clientData;
1662 panel->done = True;
1666 static void
1667 setCrashAction(void *self, void *clientData)
1669 WMPopUpButton *pop = (WMPopUpButton*)self;
1670 CrashPanel *panel = (CrashPanel*)clientData;
1672 panel->action = WMGetPopUpButtonSelectedItem(pop);
1676 static WMPixmap*
1677 getWindowMakerIconImage(WMScreen *scr)
1679 WMPropList *dict, *key, *option, *value=NULL;
1680 WMPixmap *pix=NULL;
1681 char *path;
1683 WMPLSetCaseSensitive(True);
1685 key = WMCreatePLString("Logo.WMPanel");
1686 option = WMCreatePLString("Icon");
1688 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1690 if (dict) {
1691 value = WMGetFromPLDictionary(dict, option);
1694 WMReleasePropList(key);
1695 WMReleasePropList(option);
1697 WMPLSetCaseSensitive(False);
1699 if (value && WMIsPLString(value)) {
1700 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1702 if (path) {
1703 RColor gray;
1705 gray.red = 0xae; gray.green = 0xaa;
1706 gray.blue = 0xae; gray.alpha = 0;
1708 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1709 wfree(path);
1713 return pix;
1717 #define PWIDTH 295
1718 #define PHEIGHT 345
1722 wShowCrashingDialogPanel(int whatSig)
1724 CrashPanel *panel;
1725 WMScreen *scr;
1726 WMFont *font;
1727 WMPixmap *logo;
1728 int screen_no, scr_width, scr_height;
1729 int action;
1730 char buf[256];
1732 panel = wmalloc(sizeof(CrashPanel));
1733 memset(panel, 0, sizeof(CrashPanel));
1735 screen_no = DefaultScreen(dpy);
1736 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1737 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1739 scr = WMCreateScreen(dpy, screen_no);
1740 if (!scr) {
1741 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1742 return WMAbort;
1745 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1747 panel->win = WMCreateWindow(scr, "crashingDialog");
1748 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1749 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1751 logo = getWindowMakerIconImage(scr);
1752 if (logo) {
1753 panel->iconL = WMCreateLabel(panel->win);
1754 WMResizeWidget(panel->iconL, 64, 64);
1755 WMMoveWidget(panel->iconL, 10, 10);
1756 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1757 WMSetLabelImage(panel->iconL, logo);
1760 panel->nameL = WMCreateLabel(panel->win);
1761 WMResizeWidget(panel->nameL, 190, 18);
1762 WMMoveWidget(panel->nameL, 80, 35);
1763 WMSetLabelTextAlignment(panel->nameL, WALeft);
1764 font = WMBoldSystemFontOfSize(scr, 18);
1765 WMSetLabelFont(panel->nameL, font);
1766 WMReleaseFont(font);
1767 WMSetLabelText(panel->nameL, _("Fatal error"));
1769 panel->sepF = WMCreateFrame(panel->win);
1770 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1771 WMMoveWidget(panel->sepF, -2, 80);
1773 panel->noteL = WMCreateLabel(panel->win);
1774 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1775 WMMoveWidget(panel->noteL, 10, 90);
1776 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1777 #ifdef SYS_SIGLIST_DECLARED
1778 snprintf(buf, sizeof(buf), _("Window Maker received signal %i\n(%s)."),
1779 whatSig, sys_siglist[whatSig]);
1780 #else
1781 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1782 #endif
1783 WMSetLabelText(panel->noteL, buf);
1785 panel->note2L = WMCreateLabel(panel->win);
1786 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1787 WMMoveWidget(panel->note2L, 10, 130);
1788 WMSetLabelTextAlignment(panel->note2L, WALeft);
1789 WMSetLabelText(panel->note2L,
1790 _(" This fatal error occured probably due to a bug."
1791 " Please fill the included BUGFORM and "
1792 "report it to bugs@windowmaker.org."));
1793 WMSetLabelWraps(panel->note2L, True);
1796 panel->whatF = WMCreateFrame(panel->win);
1797 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1798 WMMoveWidget(panel->whatF, 10, 240);
1799 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1801 panel->whatP = WMCreatePopUpButton(panel->whatF);
1802 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1803 WMMoveWidget(panel->whatP, 35, 20);
1804 WMSetPopUpButtonPullsDown(panel->whatP, False);
1805 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1806 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1807 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1808 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1809 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1810 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1811 panel->action = WMRestart;
1813 WMMapSubwidgets(panel->whatF);
1815 panel->okB = WMCreateCommandButton(panel->win);
1816 WMResizeWidget(panel->okB, 80, 26);
1817 WMMoveWidget(panel->okB, 205, 309);
1818 WMSetButtonText(panel->okB, _("OK"));
1819 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1820 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1821 WMSetButtonImagePosition(panel->okB, WIPRight);
1822 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1824 panel->done = 0;
1826 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1827 handleKeyPress, panel);
1829 WMRealizeWidget(panel->win);
1830 WMMapSubwidgets(panel->win);
1832 WMMapWidget(panel->win);
1834 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1836 while (!panel->done) {
1837 XEvent event;
1839 WMNextEvent(dpy, &event);
1840 WMHandleEvent(&event);
1843 action = panel->action;
1845 WMUnmapWidget(panel->win);
1846 WMDestroyWidget(panel->win);
1847 wfree(panel);
1849 return action;
1855 /*****************************************************************************
1856 * About GNUstep Panel
1857 *****************************************************************************/
1860 static void
1861 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1862 unsigned long blackPixel, unsigned long whitePixel)
1864 GC gc;
1865 XGCValues gcv;
1866 XRectangle rects[3];
1868 gcv.foreground = blackPixel;
1869 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1871 XFillArc(dpy, d, gc, width/45, height/45,
1872 width - 2*width/45, height - 2*height/45, 0, 360*64);
1874 rects[0].x = 0;
1875 rects[0].y = 37*height/45;
1876 rects[0].width = width/3;
1877 rects[0].height = height - rects[0].y;
1879 rects[1].x = rects[0].width;
1880 rects[1].y = height/2;
1881 rects[1].width = width - 2*width/3;
1882 rects[1].height = height - rects[1].y;
1884 rects[2].x = 2*width/3;
1885 rects[2].y = height - 37*height/45;
1886 rects[2].width = width/3;
1887 rects[2].height = height - rects[2].y;
1889 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1890 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1892 XSetForeground(dpy, gc, whitePixel);
1893 XFillArc(dpy, d, gc, width/45, height/45,
1894 width - 2*width/45, height - 2*height/45, 0, 360*64);
1896 XFreeGC(dpy, gc);
1900 typedef struct {
1901 WScreen *scr;
1903 WWindow *wwin;
1905 WMWindow *win;
1907 WMLabel *gstepL;
1908 WMLabel *textL;
1909 } GNUstepPanel;
1912 static GNUstepPanel *gnustepPanel = NULL;
1914 static void
1915 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1917 WMUnmapWidget(gnustepPanel->win);
1919 WMDestroyWidget(gnustepPanel->win);
1921 wUnmanageWindow(gnustepPanel->wwin, False, False);
1923 wfree(gnustepPanel);
1925 gnustepPanel = NULL;
1929 void
1930 wShowGNUstepPanel(WScreen *scr)
1932 GNUstepPanel *panel;
1933 Window parent;
1934 WWindow *wwin;
1935 WMPixmap *pixmap;
1936 WMColor *color;
1938 if (gnustepPanel) {
1939 if (gnustepPanel->scr == scr) {
1940 wRaiseFrame(gnustepPanel->wwin->frame->core);
1941 wSetFocusTo(scr, gnustepPanel->wwin);
1943 return;
1946 panel = wmalloc(sizeof(GNUstepPanel));
1948 panel->scr = scr;
1950 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1951 WMResizeWidget(panel->win, 325, 200);
1953 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1954 WMScreenDepth(scr->wmscreen), True);
1956 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1958 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1959 WMColorPixel(color), scr->white_pixel);
1961 WMReleaseColor(color);
1963 XSetForeground(dpy, scr->mono_gc, 0);
1964 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1965 130, 130);
1966 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1968 panel->gstepL = WMCreateLabel(panel->win);
1969 WMResizeWidget(panel->gstepL, 285, 64);
1970 WMMoveWidget(panel->gstepL, 20, 0);
1971 WMSetLabelTextAlignment(panel->gstepL, WARight);
1972 WMSetLabelText(panel->gstepL, "GNUstep");
1974 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1976 WMSetLabelFont(panel->gstepL, font);
1977 WMReleaseFont(font);
1980 panel->textL = WMCreateLabel(panel->win);
1981 WMResizeWidget(panel->textL, 275, 130);
1982 WMMoveWidget(panel->textL, 30, 50);
1983 WMSetLabelTextAlignment(panel->textL, WARight);
1984 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1985 WMSetLabelText(panel->textL,
1986 _("Window Maker is part of the GNUstep project.\n"\
1987 "The GNUstep project aims to create a free\n"\
1988 "implementation of the OpenStep(tm) specification\n"\
1989 "which is a object-oriented framework for\n"\
1990 "creating advanced graphical, multi-platform\n"\
1991 "applications. Additionally, a development and\n"\
1992 "user desktop enviroment will be created on top\n"\
1993 "of the framework. For more information about\n"\
1994 "GNUstep, please visit: www.gnustep.org"));
1995 WMSetLabelImage(panel->textL, pixmap);
1997 WMReleasePixmap(pixmap);
1999 WMRealizeWidget(panel->win);
2000 WMMapSubwidgets(panel->win);
2002 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
2004 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
2006 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
2007 (scr->scr_width - 325)/2,
2008 (scr->scr_height - 200)/2, 325, 200);
2010 WSETUFLAG(wwin, no_closable, 0);
2011 WSETUFLAG(wwin, no_close_button, 0);
2012 wWindowUpdateButtonImages(wwin);
2013 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
2014 #ifdef XKB_BUTTON_HINT
2015 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
2016 #endif
2017 wwin->frame->on_click_right = destroyGNUstepPanel;
2019 panel->wwin = wwin;
2021 WMMapWidget(panel->win);
2023 wWindowMap(wwin);
2025 gnustepPanel = panel;