- Fixed dock's menu mapping position when dock is on the right side.
[wmaker-crm.git] / src / dialog.c
blobbf5fcc0b2792cfb3129e5e812ef0887ad2f8528f
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"
63 #include "xinerama.h"
65 extern WPreferences wPreferences;
68 static WMPoint getCenter(WScreen *scr, int width, int height)
70 WMPoint pt;
72 #ifdef XINERAMA
73 WMRect rect;
75 rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr));
77 pt.x = rect.pos.x + (rect.size.width - width)/2;
78 pt.y = rect.pos.y + (rect.size.height - height)/2;
79 #else
80 pt.x = (scr->scr_width - width) / 2;
81 pt.y = (scr->scr_height - height) / 2;
82 #endif
84 return pt;
89 int
90 wMessageDialog(WScreen *scr, char *title, char *message,
91 char *defBtn, char *altBtn, char *othBtn)
93 WMAlertPanel *panel;
94 Window parent;
95 WWindow *wwin;
96 int result;
97 WMPoint center;
99 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message,
100 defBtn, altBtn, othBtn);
102 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
104 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
107 center = getCenter(scr, 400, 180);
108 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y,
109 400, 180);
110 wwin->client_leader = WMWidgetXID(panel->win);
112 WMMapWidget(panel->win);
114 wWindowMap(wwin);
116 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
118 result = panel->result;
120 WMUnmapWidget(panel->win);
122 wUnmanageWindow(wwin, False, False);
124 WMDestroyAlertPanel(panel);
126 XDestroyWindow(dpy, parent);
128 return result;
132 void
133 toggleSaveSession(WMWidget *w, void *data)
135 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
140 wExitDialog(WScreen *scr, char *title, char *message,
141 char *defBtn, char *altBtn, char *othBtn)
143 WMAlertPanel *panel;
144 WMButton *saveSessionBtn;
145 Window parent;
146 WWindow *wwin;
147 int result;
149 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message,
150 defBtn, altBtn, othBtn);
152 /* add save session button */
153 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
154 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
155 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn),
156 False, True, 200, 0, 0);
157 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
158 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
159 WMRealizeWidget(saveSessionBtn);
160 WMMapWidget(saveSessionBtn);
162 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
164 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
166 wwin = wManageInternalWindow(scr, parent, None, NULL,
167 (scr->scr_width - 400)/2,
168 (scr->scr_height - 180)/2, 400, 180);
169 wwin->client_leader = WMWidgetXID(panel->win);
171 WMMapWidget(panel->win);
173 wWindowMap(wwin);
175 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
177 result = panel->result;
179 WMUnmapWidget(panel->win);
181 wUnmanageWindow(wwin, False, False);
183 WMDestroyAlertPanel(panel);
185 XDestroyWindow(dpy, parent);
187 return result;
192 wInputDialog(WScreen *scr, char *title, char *message, char **text)
194 WWindow *wwin;
195 Window parent;
196 WMInputPanel *panel;
197 char *result;
198 WMPoint center;
200 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text,
201 _("OK"), _("Cancel"));
204 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
205 XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
207 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
209 center = getCenter(scr, 320, 160);
210 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y,
211 320, 160);
213 wwin->client_leader = WMWidgetXID(panel->win);
215 WMMapWidget(panel->win);
217 wWindowMap(wwin);
219 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
221 if (panel->result == WAPRDefault)
222 result = WMGetTextFieldText(panel->text);
223 else
224 result = NULL;
226 wUnmanageWindow(wwin, False, False);
228 WMDestroyInputPanel(panel);
230 XDestroyWindow(dpy, parent);
232 if (result==NULL)
233 return False;
234 else {
235 if (*text)
236 wfree(*text);
237 *text = result;
239 return True;
245 *****************************************************************
246 * Icon Selection Panel
247 *****************************************************************
250 typedef struct IconPanel {
252 WScreen *scr;
254 WMWindow *win;
256 WMLabel *dirLabel;
257 WMLabel *iconLabel;
259 WMList *dirList;
260 WMList *iconList;
261 WMFont *normalfont;
263 WMButton *previewButton;
265 WMLabel *iconView;
267 WMLabel *fileLabel;
268 WMTextField *fileField;
270 WMButton *okButton;
271 WMButton *cancelButton;
272 #if 0
273 WMButton *chooseButton;
274 #endif
275 short done;
276 short result;
277 short preview;
278 } IconPanel;
282 static void
283 listPixmaps(WScreen *scr, WMList *lPtr, char *path)
285 struct dirent *dentry;
286 DIR *dir;
287 char pbuf[PATH_MAX+16];
288 char *apath;
289 IconPanel *panel = WMGetHangedData(lPtr);
291 panel->preview = False;
293 apath = wexpandpath(path);
294 dir = opendir(apath);
296 if (!dir) {
297 char *msg;
298 char *tmp;
299 tmp = _("Could not open directory ");
300 msg = wmalloc(strlen(tmp)+strlen(path)+6);
301 strcpy(msg, tmp);
302 strcat(msg, path);
304 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
305 wfree(msg);
306 wfree(apath);
307 return;
310 /* list contents in the column */
311 while ((dentry = readdir(dir))) {
312 struct stat statb;
314 if (strcmp(dentry->d_name, ".")==0 ||
315 strcmp(dentry->d_name, "..")==0)
316 continue;
318 strcpy(pbuf, apath);
319 strcat(pbuf, "/");
320 strcat(pbuf, dentry->d_name);
322 if (stat(pbuf, &statb)<0)
323 continue;
325 if (statb.st_mode & (S_IRUSR|S_IRGRP|S_IROTH)
326 && statb.st_mode & (S_IFREG|S_IFLNK)) {
327 WMAddListItem(lPtr, dentry->d_name);
330 WMSortListItems(lPtr);
332 closedir(dir);
333 wfree(apath);
334 panel->preview = True;
339 static void
340 setViewedImage(IconPanel *panel, char *file)
342 WMPixmap *pixmap;
343 RColor color;
345 color.red = 0xae;
346 color.green = 0xaa;
347 color.blue = 0xae;
348 color.alpha = 0;
349 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win),
350 file, &color);
351 if (!pixmap) {
352 WMSetButtonEnabled(panel->okButton, False);
354 WMSetLabelText(panel->iconView, _("Could not load image file "));
356 WMSetLabelImage(panel->iconView, NULL);
357 } else {
358 WMSetButtonEnabled(panel->okButton, True);
360 WMSetLabelText(panel->iconView, NULL);
361 WMSetLabelImage(panel->iconView, pixmap);
362 WMReleasePixmap(pixmap);
367 static void
368 listCallback(void *self, void *data)
370 WMList *lPtr = (WMList*)self;
371 IconPanel *panel = (IconPanel*)data;
372 char *path;
374 if (lPtr==panel->dirList) {
375 WMListItem *item = WMGetListSelectedItem(lPtr);
377 if (item == NULL)
378 return;
379 path = item->text;
381 WMSetTextFieldText(panel->fileField, path);
383 WMSetLabelImage(panel->iconView, NULL);
385 WMSetButtonEnabled(panel->okButton, False);
387 WMClearList(panel->iconList);
388 listPixmaps(panel->scr, panel->iconList, path);
389 } else {
390 char *tmp, *iconFile;
391 WMListItem *item = WMGetListSelectedItem(panel->dirList);
393 if (item == NULL)
394 return;
395 path = item->text;
396 tmp = wexpandpath(path);
398 item = WMGetListSelectedItem(panel->iconList);
399 if (item == NULL)
400 return;
401 iconFile = item->text;
403 path = wmalloc(strlen(tmp)+strlen(iconFile)+4);
404 strcpy(path, tmp);
405 strcat(path, "/");
406 strcat(path, iconFile);
407 wfree(tmp);
408 WMSetTextFieldText(panel->fileField, path);
409 setViewedImage(panel, path);
410 wfree(path);
415 static void
416 listIconPaths(WMList *lPtr)
418 char *paths;
419 char *path;
421 paths = wstrdup(wPreferences.icon_path);
423 path = strtok(paths, ":");
425 do {
426 char *tmp;
428 tmp = wexpandpath(path);
429 /* do not sort, because the order implies the order of
430 * directories searched */
431 if (access(tmp, X_OK)==0)
432 WMAddListItem(lPtr, path);
433 wfree(tmp);
434 } while ((path=strtok(NULL, ":"))!=NULL);
436 wfree(paths);
440 void
441 drawIconProc(WMList *lPtr, int index, Drawable d, char *text,
442 int state, WMRect *rect)
444 IconPanel *panel = WMGetHangedData(lPtr);
445 GC gc = panel->scr->draw_gc;
446 GC copygc = panel->scr->copy_gc;
447 char *file, *dirfile;
448 WMPixmap *pixmap;
449 WMColor *blackcolor;
450 WMColor *whitecolor;
451 WMSize size;
452 WMScreen *wmscr = WMWidgetScreen(panel->win);
453 RColor color;
454 int width;
456 if(!panel->preview) return;
458 width = rect->size.width;
460 blackcolor = WMBlackColor(wmscr);
461 whitecolor = WMWhiteColor(wmscr);
463 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
465 int len = strlen(dirfile)+strlen(text)+4;
466 file = wmalloc(len);
467 snprintf(file, len, "%s/%s", dirfile, text);
469 wfree(dirfile);
471 if ((state & WLDSSelected) != 0) {
472 color.red = color.green = color.blue = 0xff;
473 color.alpha = 0;
474 } else {
475 color.red = color.blue = 0xae;
476 color.green = 0xaa; color.alpha = 0;
478 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
479 wfree(file);
481 if (!pixmap) {
482 WMRemoveListItem(lPtr, index);
483 return;
486 XClearArea(dpy, d, rect->pos.x, rect->pos.y, width, rect->size.height,
487 False);
488 XSetClipMask(dpy, gc, None);
490 XDrawRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x + 5,
491 rect->pos.y +5, width - 10, 54);
493 XDrawLine(dpy, d, WMColorGC(whitecolor), rect->pos.x,
494 rect->pos.y+rect->size.height-1, rect->pos.x+width,
495 rect->pos.y+rect->size.height-1);
498 if (state&WLDSSelected) {
499 XFillRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x,
500 rect->pos.y, width, rect->size.height);
503 size = WMGetPixmapSize(pixmap);
505 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
506 XSetClipOrigin(dpy, copygc, rect->pos.x + (width-size.width)/2,
507 rect->pos.y+2);
508 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
509 size.width>100?100:size.width, size.height>64?64:size.height,
510 rect->pos.x + (width-size.width)/2, rect->pos.y+2);
513 int i,j;
514 int fheight = WMFontHeight(panel->normalfont);
515 int tlen = strlen(text);
516 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
517 int ofx, ofy;
519 ofx = rect->pos.x + (width - twidth)/2;
520 ofy = rect->pos.y + 64 - fheight;
522 for(i=-1;i<2;i++)
523 for(j=-1;j<2;j++)
524 WMDrawString(wmscr, d, WMColorGC(whitecolor),
525 panel->normalfont, ofx+i, ofy+j,
526 text, tlen);
528 WMDrawString(wmscr, d, WMColorGC(blackcolor), panel->normalfont,
529 ofx, ofy, text, tlen);
532 WMReleasePixmap(pixmap);
533 /* I hope it is better to do not use cache / on my box it is fast nuff */
534 XFlush(dpy);
536 WMReleaseColor(blackcolor);
537 WMReleaseColor(whitecolor);
541 static void
542 buttonCallback(void *self, void *clientData)
544 WMButton *bPtr = (WMButton*)self;
545 IconPanel *panel = (IconPanel*)clientData;
548 if (bPtr==panel->okButton) {
549 panel->done = True;
550 panel->result = True;
551 } else if (bPtr==panel->cancelButton) {
552 panel->done = True;
553 panel->result = False;
554 } else if (bPtr==panel->previewButton) {
555 /**** Previewer ****/
556 WMSetButtonEnabled(bPtr, False);
557 WMSetListUserDrawItemHeight(panel->iconList, 68);
558 WMSetListUserDrawProc(panel->iconList, drawIconProc);
559 WMRedisplayWidget(panel->iconList);
560 /* for draw proc to access screen/gc */
561 /*** end preview ***/
563 #if 0
564 else if (bPtr==panel->chooseButton) {
565 WMOpenPanel *op;
567 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
569 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
570 char *path;
571 path = WMGetFilePanelFile(op);
572 WMSetTextFieldText(panel->fileField, path);
573 setViewedImage(panel, path);
574 wfree(path);
576 WMDestroyFilePanel(op);
578 #endif
582 static void
583 keyPressHandler(XEvent *event, void *data)
585 IconPanel *panel = (IconPanel*)data;
586 char buffer[32];
587 int count;
588 KeySym ksym;
589 int iidx;
590 int didx;
591 int item;
592 WMList *list = NULL;
594 if (event->type == KeyRelease)
595 return;
597 buffer[0] = 0;
598 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
601 iidx = WMGetListSelectedItemRow(panel->iconList);
602 didx = WMGetListSelectedItemRow(panel->dirList);
604 switch (ksym) {
605 case XK_Up:
606 if (iidx > 0)
607 item = iidx-1;
608 else
609 item = iidx;
610 list = panel->iconList;
611 break;
612 case XK_Down:
613 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
614 item = iidx+1;
615 else
616 item = iidx;
617 list = panel->iconList;
618 break;
619 case XK_Home:
620 item = 0;
621 list = panel->iconList;
622 break;
623 case XK_End:
624 item = WMGetListNumberOfRows(panel->iconList) - 1;
625 list = panel->iconList;
626 break;
627 case XK_Next:
628 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
629 item = didx + 1;
630 else
631 item = didx;
632 list = panel->dirList;
633 break;
634 case XK_Prior:
635 if (didx > 0)
636 item = didx - 1;
637 else
638 item = 0;
639 list = panel->dirList;
640 break;
641 case XK_Return:
642 WMPerformButtonClick(panel->okButton);
643 break;
644 case XK_Escape:
645 WMPerformButtonClick(panel->cancelButton);
646 break;
649 if (list) {
650 WMSelectListItem(list, item);
651 WMSetListPosition(list, item - 5);
652 listCallback(list, panel);
658 Bool
659 wIconChooserDialog(WScreen *scr, char **file, char *instance, char *class)
661 WWindow *wwin;
662 Window parent;
663 IconPanel *panel;
664 WMColor *color;
665 WMFont *boldFont;
667 panel = wmalloc(sizeof(IconPanel));
668 memset(panel, 0, sizeof(IconPanel));
670 panel->scr = scr;
672 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
673 WMResizeWidget(panel->win, 450, 280);
675 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask|KeyReleaseMask,
676 keyPressHandler, panel);
679 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
680 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
682 panel->dirLabel = WMCreateLabel(panel->win);
683 WMResizeWidget(panel->dirLabel, 200, 20);
684 WMMoveWidget(panel->dirLabel, 10, 7);
685 WMSetLabelText(panel->dirLabel, _("Directories"));
686 WMSetLabelFont(panel->dirLabel, boldFont);
687 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
689 WMSetLabelRelief(panel->dirLabel, WRSunken);
691 panel->iconLabel = WMCreateLabel(panel->win);
692 WMResizeWidget(panel->iconLabel, 140, 20);
693 WMMoveWidget(panel->iconLabel, 215, 7);
694 WMSetLabelText(panel->iconLabel, _("Icons"));
695 WMSetLabelFont(panel->iconLabel, boldFont);
696 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
698 WMReleaseFont(boldFont);
700 color = WMWhiteColor(scr->wmscreen);
701 WMSetLabelTextColor(panel->dirLabel, color);
702 WMSetLabelTextColor(panel->iconLabel, color);
703 WMReleaseColor(color);
705 color = WMDarkGrayColor(scr->wmscreen);
706 WMSetWidgetBackgroundColor(panel->iconLabel, color);
707 WMSetWidgetBackgroundColor(panel->dirLabel, color);
708 WMReleaseColor(color);
710 WMSetLabelRelief(panel->iconLabel, WRSunken);
712 panel->dirList = WMCreateList(panel->win);
713 WMResizeWidget(panel->dirList, 200, 170);
714 WMMoveWidget(panel->dirList, 10, 30);
715 WMSetListAction(panel->dirList, listCallback, panel);
717 panel->iconList = WMCreateList(panel->win);
718 WMResizeWidget(panel->iconList, 140, 170);
719 WMMoveWidget(panel->iconList, 215, 30);
720 WMSetListAction(panel->iconList, listCallback, panel);
722 WMHangData(panel->iconList,panel);
724 panel->previewButton = WMCreateCommandButton(panel->win);
725 WMResizeWidget(panel->previewButton, 75, 26);
726 WMMoveWidget(panel->previewButton, 365, 130);
727 WMSetButtonText(panel->previewButton, _("Preview"));
728 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
730 panel->iconView = WMCreateLabel(panel->win);
731 WMResizeWidget(panel->iconView, 75, 75);
732 WMMoveWidget(panel->iconView, 365, 40);
733 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
734 WMSetLabelRelief(panel->iconView, WRSunken);
735 WMSetLabelTextAlignment(panel->iconView, WACenter);
737 panel->fileLabel = WMCreateLabel(panel->win);
738 WMResizeWidget(panel->fileLabel, 80, 20);
739 WMMoveWidget(panel->fileLabel, 10, 210);
740 WMSetLabelText(panel->fileLabel, _("File Name:"));
742 panel->fileField = WMCreateTextField(panel->win);
743 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
744 WMResizeWidget(panel->fileField, 345, 20);
745 WMMoveWidget(panel->fileField, 95, 210);
746 WMSetTextFieldEditable(panel->fileField, False);
748 panel->okButton = WMCreateCommandButton(panel->win);
749 WMResizeWidget(panel->okButton, 80, 26);
750 WMMoveWidget(panel->okButton, 360, 240);
751 WMSetButtonText(panel->okButton, _("OK"));
752 WMSetButtonEnabled(panel->okButton, False);
753 WMSetButtonAction(panel->okButton, buttonCallback, panel);
755 panel->cancelButton = WMCreateCommandButton(panel->win);
756 WMResizeWidget(panel->cancelButton, 80, 26);
757 WMMoveWidget(panel->cancelButton, 270, 240);
758 WMSetButtonText(panel->cancelButton, _("Cancel"));
759 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
760 #if 0
761 panel->chooseButton = WMCreateCommandButton(panel->win);
762 WMResizeWidget(panel->chooseButton, 110, 26);
763 WMMoveWidget(panel->chooseButton, 150, 240);
764 WMSetButtonText(panel->chooseButton, _("Choose File"));
765 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
766 #endif
767 WMRealizeWidget(panel->win);
768 WMMapSubwidgets(panel->win);
770 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
772 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
775 char *tmp;
776 int len = (instance ? strlen(instance) : 0)
777 + (class ? strlen(class) : 0) + 32;
778 WMPoint center;
780 tmp = wmalloc(len);
782 if (tmp && (instance || class))
783 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
784 else
785 strcpy(tmp, _("Icon Chooser"));
787 center = getCenter(scr, 450, 280);
789 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x,center.y,
790 450, 280);
791 wfree(tmp);
794 /* put icon paths in the list */
795 listIconPaths(panel->dirList);
797 WMMapWidget(panel->win);
799 wWindowMap(wwin);
801 while (!panel->done) {
802 XEvent event;
804 WMNextEvent(dpy, &event);
805 WMHandleEvent(&event);
808 if (panel->result) {
809 char *defaultPath, *wantedPath;
811 /* check if the file the user selected is not the one that
812 * would be loaded by default with the current search path */
813 *file = WMGetListSelectedItem(panel->iconList)->text;
814 if ((*file)[0]==0) {
815 wfree(*file);
816 *file = NULL;
817 } else {
818 defaultPath = FindImage(wPreferences.icon_path, *file);
819 wantedPath = WMGetTextFieldText(panel->fileField);
820 /* if the file is not the default, use full path */
821 if (strcmp(wantedPath, defaultPath)!=0) {
822 *file = wantedPath;
823 } else {
824 *file = wstrdup(*file);
825 wfree(wantedPath);
827 wfree(defaultPath);
829 } else {
830 *file = NULL;
833 WMReleaseFont(panel->normalfont);
835 WMUnmapWidget(panel->win);
837 WMDestroyWidget(panel->win);
839 wUnmanageWindow(wwin, False, False);
841 wfree(panel);
843 XDestroyWindow(dpy, parent);
845 return panel->result;
850 ***********************************************************************
851 * Info Panel
852 ***********************************************************************
856 typedef struct {
857 WScreen *scr;
859 WWindow *wwin;
861 WMWindow *win;
863 WMLabel *logoL;
864 WMLabel *name1L;
865 WMLabel *name2L;
867 WMLabel *versionL;
869 WMLabel *infoL;
871 WMLabel *copyrL;
873 #ifdef SILLYNESS
874 WMHandlerID timer;
875 int cycle;
876 RImage *icon;
877 RImage *pic;
878 WMPixmap *oldPix;
879 WMFont *oldFont;
880 char *str;
881 int x;
882 #endif
883 } InfoPanel;
887 #define COPYRIGHT_TEXT \
888 "Copyright \xa9 1997-2002 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
889 "Copyright \xa9 1998-2002 Dan Pascu <dan@windowmaker.org>"
893 static InfoPanel *thePanel = NULL;
895 static void
896 destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
898 #ifdef SILLYNESS
899 if (thePanel->timer) {
900 WMDeleteTimerHandler(thePanel->timer);
902 if (thePanel->oldPix) {
903 WMReleasePixmap(thePanel->oldPix);
905 if (thePanel->oldFont) {
906 WMReleaseFont(thePanel->oldFont);
908 if (thePanel->icon) {
909 RReleaseImage(thePanel->icon);
911 if (thePanel->pic) {
912 RReleaseImage(thePanel->pic);
914 #endif /* SILLYNESS */
915 WMUnmapWidget(thePanel);
917 wUnmanageWindow(thePanel->wwin, False, False);
919 WMDestroyWidget(thePanel->win);
921 wfree(thePanel);
923 thePanel = NULL;
927 WMPixmap*
928 renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
930 WMPixmap *wpix = NULL;
931 Pixmap grad = None;
932 Pixmap mask = None;
933 RContext *rc = WMScreenRContext(scr);
934 XFontStruct *f = NULL;
935 int w, h;
936 GC gc = None;
938 f = XLoadQueryFont(dpy, font);
939 if (!f)
940 return NULL;
942 w = XTextWidth(f, text, strlen(text));
943 h = f->ascent+f->descent;
945 mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
946 gc = XCreateGC(dpy, mask, 0, NULL);
947 XSetForeground(dpy, gc, 0);
948 XSetFont(dpy, gc, f->fid);
949 XFillRectangle(dpy, mask, gc, 0, 0, w, h);
951 XSetForeground(dpy, gc, 1);
952 XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
953 XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
954 XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
956 grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
958 WMColor *color;
960 color = WMBlackColor(scr);
961 XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
962 WMReleaseColor(color);
965 wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
967 if (gc)
968 XFreeGC(dpy, gc);
969 XFreeFont(dpy, f);
971 return wpix;
974 #ifdef SILLYNESS
976 extern WMPixmap *DoXThing();
977 extern Bool InitXThing();
979 static void
980 logoPushCallback(void *data)
982 InfoPanel *panel = (InfoPanel*)data;
983 char buffer[512];
984 int i;
985 static int oldi = 0;
986 int len;
987 static int jingobeu[] = {
988 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
989 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
990 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
992 static int c = 0;
994 if (panel->x) {
995 XKeyboardControl kc;
996 XKeyboardState ksave;
997 unsigned long mask = KBBellPitch|KBBellDuration|KBBellPercent;
999 XGetKeyboardControl(dpy, &ksave);
1001 if (panel->x > 0) {
1002 if(jingobeu[panel->x-1]==0) {
1003 panel->x=-1;
1004 } else if (jingobeu[panel->x-1]<0) {
1005 panel->x++;
1006 c=jingobeu[panel->x-1]/50;
1007 panel->x++;
1008 } else if (c==0) {
1009 kc.bell_percent=50;
1010 kc.bell_pitch=jingobeu[panel->x-1];
1011 panel->x++;
1012 kc.bell_duration=jingobeu[panel->x-1];
1013 c=jingobeu[panel->x-1]/50;
1014 panel->x++;
1015 XChangeKeyboardControl(dpy, mask, &kc);
1016 XBell(dpy, 50);
1017 XFlush(dpy);
1018 } else {
1019 c--;
1022 if (!(panel->cycle % 4)) {
1023 WMPixmap *p;
1025 p = DoXThing(panel->wwin);
1026 WMSetLabelImage(panel->logoL, p);
1028 kc.bell_pitch = ksave.bell_pitch;
1029 kc.bell_percent = ksave.bell_percent;
1030 kc.bell_duration = ksave.bell_duration;
1031 XChangeKeyboardControl(dpy, mask, &kc);
1032 } else if (panel->cycle < 30) {
1033 RImage *image;
1034 WMPixmap *pix;
1035 RColor gray;
1037 gray.red = 0xae; gray.green = 0xaa;
1038 gray.blue = 0xae; gray.alpha = 0;
1040 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
1041 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
1042 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
1043 RReleaseImage(image);
1044 WMSetLabelImage(panel->logoL, pix);
1045 WMReleasePixmap(pix);
1048 /* slow down text a little */
1049 i = (int)(panel->cycle * 50.0/85.0)%200;
1051 if (i != oldi) {
1052 len = strlen(panel->str);
1054 strncpy(buffer, panel->str, i<len ? i : len);
1055 if (i >= len)
1056 memset(&buffer[len], ' ', i-len);
1058 strncpy(buffer, panel->str, i<len ? i : len);
1059 if (i >= len)
1060 memset(&buffer[len], ' ', i-len);
1061 buffer[i]=0;
1063 WMSetLabelText(panel->versionL, buffer);
1065 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1067 oldi = i;
1070 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1071 panel->cycle++;
1075 static void
1076 handleLogoPush(XEvent *event, void *data)
1078 InfoPanel *panel = (InfoPanel*)data;
1079 static int broken = 0;
1080 static int clicks = 0;
1081 static char *pic_data[] = {
1082 "45 45 57 1",
1083 " c None",
1084 ". c #000000",
1085 "X c #383C00",
1086 "o c #515500",
1087 "O c #616100",
1088 "+ c #616900",
1089 "@ c #696D00",
1090 "# c #697100",
1091 "$ c #495100",
1092 "% c #202800",
1093 "& c #969600",
1094 "* c #CFCF00",
1095 "= c #D7DB00",
1096 "- c #D7D700",
1097 "; c #C7CB00",
1098 ": c #A6AA00",
1099 "> c #494900",
1100 ", c #8E8E00",
1101 "< c #DFE700",
1102 "1 c #F7FF00",
1103 "2 c #FFFF00",
1104 "3 c #E7EB00",
1105 "4 c #B6B600",
1106 "5 c #595900",
1107 "6 c #717500",
1108 "7 c #AEB200",
1109 "8 c #CFD300",
1110 "9 c #E7EF00",
1111 "0 c #EFF300",
1112 "q c #9EA200",
1113 "w c #F7FB00",
1114 "e c #F7F700",
1115 "r c #BEBE00",
1116 "t c #8E9200",
1117 "y c #EFF700",
1118 "u c #969A00",
1119 "i c #414500",
1120 "p c #595D00",
1121 "a c #E7E700",
1122 "s c #C7C700",
1123 "d c #797D00",
1124 "f c #BEC300",
1125 "g c #DFE300",
1126 "h c #868600",
1127 "j c #EFEF00",
1128 "k c #9E9E00",
1129 "l c #616500",
1130 "z c #DFDF00",
1131 "x c #868A00",
1132 "c c #969200",
1133 "v c #B6BA00",
1134 "b c #A6A600",
1135 "n c #8E8A00",
1136 "m c #717100",
1137 "M c #AEAE00",
1138 "N c #AEAA00",
1139 "B c #868200",
1140 " ............... ",
1141 " ....XoO+@##+O$%.... ",
1142 " ...%X&*========-;;:o... ",
1143 " ...>.>,<122222222222134@... ",
1144 " ..>5678912222222222222220q%.. ",
1145 " ..$.&-w2222222222222222222er>.. ",
1146 " ..O.t31222222222222222222222y4>.. ",
1147 " ...O5u3222222222222222222222222yri... ",
1148 " ..>p&a22222222222222222222222222wso.. ",
1149 " ..ids91222222222222222222222222222wfi.. ",
1150 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1151 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1152 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1153 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1154 "..io*222222222&...u22222222yt..%*22222220:%. ",
1155 "..>k02222222227...f222222222v..X=222222229t. ",
1156 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1157 ".%vw222222222221y2222222222219*y2222222222wd.",
1158 ".X;2222222222222222222222222222222222222222b.",
1159 ".i*2222222222222222222222222222222222222222v.",
1160 ".i*2222222222222222222222222222222222222222;.",
1161 ".i*22222222222222222222222222222222222222228.",
1162 ".>*2222222222222222222222222222222222222222=.",
1163 ".i*22222222222222222222222222222222222222228.",
1164 ".i*2222222222222222222222222222222222222222;.",
1165 ".X*222222222222222222222222222222we12222222r.",
1166 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1167 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1168 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1169 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1170 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1171 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1172 " ...:e2222218mdz22222222222222a&$vw222220@...",
1173 " ...O-122222y:.u02222222222229q$uj222221r... ",
1174 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1175 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1176 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1177 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1178 " ..Xb9122222109g-****;<y22221zn%... ",
1179 " ..X&801222222222222222222w-h.... ",
1180 " ...o:=022222222222222221=lX... ",
1181 " ..X@:;3w2222222222210fO... ",
1182 " ...XX&v8<30000003-N@... ",
1183 " .....XmnbN:q&Bo.... ",
1184 " ............ "
1186 static char *msgs[] = {
1187 "Have a nice day!",
1188 "Focus follow mouse users will burn in hell!!!",
1189 "Mooo Canada!!!!",
1190 "Hi! My name is bobby...",
1191 "AHH! The neurotic monkeys are after me!",
1192 "WE GET SIGNAL",
1193 "HOW ARE YOU GENTLEMEN?",
1194 "WHAT YOU SAY??",
1195 "SOMEBODY SET UP US THE BOMB",
1196 "ALL YOUR BASE ARE BELONG TO US!",
1197 "Oh My God!!! Larry is back!"
1201 clicks++;
1203 if (!panel->timer && !broken && clicks > 0) {
1204 WMFont *font;
1206 panel->x = 0;
1207 clicks = 0;
1208 if (!panel->icon) {
1209 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1210 if (!panel->icon) {
1211 broken = 1;
1212 return;
1213 } else {
1214 RColor color;
1216 color.red = 0xae; color.green = 0xaa;
1217 color.blue = 0xae; color.alpha = 0;
1219 panel->icon = RCloneImage(panel->icon);
1220 RCombineImageWithColor(panel->icon, &color);
1223 if (!panel->pic) {
1224 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1225 if (!panel->pic) {
1226 broken = 1;
1227 RReleaseImage(panel->icon);
1228 panel->icon = NULL;
1229 return;
1233 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1235 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1236 panel->cycle = 0;
1237 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1238 /* If we don't use a fixed font, scrolling will be jumpy */
1239 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1240 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1241 WMRetainFont(panel->oldFont);
1242 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
1243 if (font) {
1244 WMSetLabelFont(panel->versionL, font);
1245 WMReleaseFont(font);
1247 WMSetLabelText(panel->versionL, "");
1248 } else if (panel->timer) {
1249 char version[20];
1251 panel->x = 0;
1252 clicks = 0;
1253 WMSetLabelImage(panel->logoL, panel->oldPix);
1254 WMReleasePixmap(panel->oldPix);
1255 panel->oldPix = NULL;
1257 WMDeleteTimerHandler(panel->timer);
1258 panel->timer = NULL;
1260 WMSetLabelFont(panel->versionL, panel->oldFont);
1261 if (panel->oldFont) {
1262 WMReleaseFont(panel->oldFont);
1263 panel->oldFont = NULL;
1265 snprintf(version, sizeof(version), _("Version %s"), VERSION);
1266 WMSetLabelText(panel->versionL, version);
1267 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1271 XEvent ev;
1272 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1273 ButtonPress, &ev));
1276 #endif /* SILLYNESS */
1279 void
1280 wShowInfoPanel(WScreen *scr)
1282 InfoPanel *panel;
1283 WMPixmap *logo;
1284 WMSize size;
1285 WMFont *font;
1286 char *strbuf = NULL;
1287 char buffer[256];
1288 Window parent;
1289 WWindow *wwin;
1290 RColor color1, color2;
1291 char **strl;
1292 int i;
1293 char *visuals[] = {
1294 "StaticGray",
1295 "GrayScale",
1296 "StaticColor",
1297 "PseudoColor",
1298 "TrueColor",
1299 "DirectColor"
1303 if (thePanel) {
1304 if (thePanel->scr == scr) {
1305 wRaiseFrame(thePanel->wwin->frame->core);
1306 wSetFocusTo(scr, thePanel->wwin);
1308 return;
1311 panel = wmalloc(sizeof(InfoPanel));
1312 memset(panel, 0, sizeof(InfoPanel));
1314 panel->scr = scr;
1316 panel->win = WMCreateWindow(scr->wmscreen, "info");
1317 WMResizeWidget(panel->win, 382, 230);
1319 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor*)NULL);
1320 if (!logo) {
1321 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1323 if (logo) {
1324 size = WMGetPixmapSize(logo);
1325 panel->logoL = WMCreateLabel(panel->win);
1326 WMResizeWidget(panel->logoL, 64, 64);
1327 WMMoveWidget(panel->logoL, 30, 20);
1328 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1329 WMSetLabelImage(panel->logoL, logo);
1330 #ifdef SILLYNESS
1331 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1332 handleLogoPush, panel);
1333 #endif
1334 WMReleasePixmap(logo);
1337 panel->name1L = WMCreateLabel(panel->win);
1338 WMResizeWidget(panel->name1L, 240, 30);
1339 WMMoveWidget(panel->name1L, 100, 30);
1340 color1.red = 0;
1341 color1.green = 0;
1342 color1.blue = 0;
1343 color2.red = 0x50;
1344 color2.green = 0x50;
1345 color2.blue = 0x70;
1346 logo = renderText(scr->wmscreen, "Window Maker",
1347 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1348 if (logo) {
1349 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1350 WMSetLabelImage(panel->name1L, logo);
1351 WMReleasePixmap(logo);
1352 } else {
1353 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1354 if (font) {
1355 WMSetLabelFont(panel->name1L, font);
1356 WMReleaseFont(font);
1358 WMSetLabelTextAlignment(panel->name1L, WACenter);
1359 WMSetLabelText(panel->name1L, "Window Maker");
1362 panel->name2L = WMCreateLabel(panel->win);
1363 WMResizeWidget(panel->name2L, 240, 24);
1364 WMMoveWidget(panel->name2L, 100, 60);
1365 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1366 if (font) {
1367 WMSetLabelFont(panel->name2L, font);
1368 WMReleaseFont(font);
1369 font = NULL;
1371 WMSetLabelTextAlignment(panel->name2L, WACenter);
1372 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1375 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1376 panel->versionL = WMCreateLabel(panel->win);
1377 WMResizeWidget(panel->versionL, 310, 16);
1378 WMMoveWidget(panel->versionL, 30, 95);
1379 WMSetLabelTextAlignment(panel->versionL, WARight);
1380 WMSetLabelText(panel->versionL, buffer);
1381 WMSetLabelWraps(panel->versionL, False);
1383 panel->copyrL = WMCreateLabel(panel->win);
1384 WMResizeWidget(panel->copyrL, 340, 40);
1385 WMMoveWidget(panel->copyrL, 15, 185);
1386 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1387 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1388 /* we want the (c) character in the helvetica font */
1389 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1390 if (font) {
1391 WMSetLabelFont(panel->copyrL, font);
1392 WMReleaseFont(font);
1393 font = NULL;
1396 strbuf = NULL;
1397 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1398 (unsigned)scr->w_visual->visualid,
1399 visuals[scr->w_visual->class], scr->w_depth);
1401 strbuf = wstrappend(strbuf, buffer);
1403 switch (scr->w_depth) {
1404 case 15:
1405 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1406 break;
1407 case 16:
1408 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1409 break;
1410 case 24:
1411 case 32:
1412 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1413 break;
1414 default:
1415 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1<<scr->w_depth);
1416 strbuf = wstrappend(strbuf, buffer);
1417 break;
1421 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1423 struct mallinfo ma = mallinfo();
1424 snprintf(buffer, sizeof(buffer),
1425 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1426 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1428 strbuf = wstrappend(strbuf, buffer);
1430 #endif
1432 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1433 strl = RSupportedFileFormats();
1434 for (i=0; strl[i]!=NULL; i++) {
1435 strbuf = wstrappend(strbuf, strl[i]);
1436 strbuf = wstrappend(strbuf, " ");
1439 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1441 char *list[8];
1442 char buf[80];
1443 int j = 0;
1445 #ifdef MWM_HINTS
1446 list[j++] = "MWM";
1447 #endif
1448 #ifdef KWM_HINTS
1449 list[j++] = "KDE";
1450 #endif
1451 #ifdef GNOME_STUFF
1452 list[j++] = "GNOME";
1453 #endif
1454 #ifdef OLWM_HINTS
1455 list[j++] = "OLWM";
1456 #endif
1458 buf[0] = 0;
1459 for (i = 0; i < j; i++) {
1460 if (i > 0) {
1461 if (i == j - 1)
1462 strcat(buf, _(" and "));
1463 else
1464 strcat(buf, ", ");
1466 strcat(buf, list[i]);
1468 strbuf = wstrappend(strbuf, buf);
1471 if (wPreferences.no_sound) {
1472 strbuf = wstrappend(strbuf, _("\nSound disabled"));
1473 } else {
1474 strbuf = wstrappend(strbuf, _("\nSound enabled"));
1478 panel->infoL = WMCreateLabel(panel->win);
1479 WMResizeWidget(panel->infoL, 350, 75);
1480 WMMoveWidget(panel->infoL, 15, 115);
1481 WMSetLabelText(panel->infoL, strbuf);
1482 font = WMCreateFont(scr->wmscreen, HELVETICA10_FONT);
1483 if (font) {
1484 WMSetLabelFont(panel->infoL, font);
1485 WMReleaseFont(font);
1486 font = NULL;
1488 wfree(strbuf);
1491 WMRealizeWidget(panel->win);
1492 WMMapSubwidgets(panel->win);
1494 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1496 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1498 WMMapWidget(panel->win);
1501 WMPoint center = getCenter(scr, 382, 230);
1503 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1504 center.x, center.y,
1505 382, 230);
1508 WSETUFLAG(wwin, no_closable, 0);
1509 WSETUFLAG(wwin, no_close_button, 0);
1510 #ifdef XKB_BUTTON_HINT
1511 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1512 #endif
1513 wWindowUpdateButtonImages(wwin);
1514 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1515 wwin->frame->on_click_right = destroyInfoPanel;
1517 wWindowMap(wwin);
1519 panel->wwin = wwin;
1521 thePanel = panel;
1522 #ifdef SILLYNESS
1523 if (InitXThing(panel->scr)) {
1524 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1525 panel->cycle = 0;
1526 panel->x = 1;
1527 panel->str = _("Merry Christmas!");
1528 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1530 #endif
1535 ***********************************************************************
1536 * Legal Panel
1537 ***********************************************************************
1540 typedef struct {
1541 WScreen *scr;
1543 WWindow *wwin;
1545 WMWindow *win;
1547 WMLabel *licenseL;
1548 } LegalPanel;
1551 static LegalPanel *legalPanel = NULL;
1553 static void
1554 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1556 WMUnmapWidget(legalPanel->win);
1558 WMDestroyWidget(legalPanel->win);
1560 wUnmanageWindow(legalPanel->wwin, False, False);
1562 wfree(legalPanel);
1564 legalPanel = NULL;
1568 void
1569 wShowLegalPanel(WScreen *scr)
1571 LegalPanel *panel;
1572 Window parent;
1573 WWindow *wwin;
1575 if (legalPanel) {
1576 if (legalPanel->scr == scr) {
1577 wRaiseFrame(legalPanel->wwin->frame->core);
1578 wSetFocusTo(scr, legalPanel->wwin);
1580 return;
1583 panel = wmalloc(sizeof(LegalPanel));
1585 panel->scr = scr;
1587 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1588 WMResizeWidget(panel->win, 420, 250);
1591 panel->licenseL = WMCreateLabel(panel->win);
1592 WMSetLabelWraps(panel->licenseL, True);
1593 WMResizeWidget(panel->licenseL, 400, 230);
1594 WMMoveWidget(panel->licenseL, 10, 10);
1595 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1596 WMSetLabelText(panel->licenseL,
1597 _(" Window Maker is free software; you can redistribute it and/or\n"
1598 "modify it under the terms of the GNU General Public License as\n"
1599 "published by the Free Software Foundation; either version 2 of the\n"
1600 "License, or (at your option) any later version.\n\n"
1601 " Window Maker is distributed in the hope that it will be useful,\n"
1602 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1603 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1604 "See the GNU General Public License for more details.\n\n"
1605 " You should have received a copy of the GNU General Public\n"
1606 "License along with this program; if not, write to the Free Software\n"
1607 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1608 "02111-1307, USA."));
1609 WMSetLabelRelief(panel->licenseL, WRGroove);
1611 WMRealizeWidget(panel->win);
1612 WMMapSubwidgets(panel->win);
1614 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1616 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1619 WMPoint center = getCenter(scr, 420, 250);
1621 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1622 center.x, center.y,
1623 420, 250);
1626 WSETUFLAG(wwin, no_closable, 0);
1627 WSETUFLAG(wwin, no_close_button, 0);
1628 wWindowUpdateButtonImages(wwin);
1629 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1630 #ifdef XKB_BUTTON_HINT
1631 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1632 #endif
1633 wwin->frame->on_click_right = destroyLegalPanel;
1635 panel->wwin = wwin;
1637 WMMapWidget(panel->win);
1639 wWindowMap(wwin);
1641 legalPanel = panel;
1646 ***********************************************************************
1647 * Crashing Dialog Panel
1648 ***********************************************************************
1651 extern WDDomain *WDWindowAttributes;
1654 typedef struct _CrashPanel {
1655 WMWindow *win; /* main window */
1657 WMLabel *iconL; /* application icon */
1658 WMLabel *nameL; /* title of panel */
1660 WMFrame *sepF; /* separator frame */
1662 WMLabel *noteL; /* Title of note */
1663 WMLabel *note2L; /* body of note with what happened */
1665 WMFrame *whatF; /* "what to do next" frame */
1666 WMPopUpButton *whatP; /* action selection popup button */
1668 WMButton *okB; /* ok button */
1670 Bool done; /* if finished with this dialog */
1671 int action; /* what to do after */
1673 KeyCode retKey;
1675 } CrashPanel;
1678 static void
1679 handleKeyPress(XEvent *event, void *clientData)
1681 CrashPanel *panel = (CrashPanel*)clientData;
1683 if (event->xkey.keycode == panel->retKey) {
1684 WMPerformButtonClick(panel->okB);
1689 static void
1690 okButtonCallback(void *self, void *clientData)
1692 CrashPanel *panel = (CrashPanel*)clientData;
1694 panel->done = True;
1698 static void
1699 setCrashAction(void *self, void *clientData)
1701 WMPopUpButton *pop = (WMPopUpButton*)self;
1702 CrashPanel *panel = (CrashPanel*)clientData;
1704 panel->action = WMGetPopUpButtonSelectedItem(pop);
1708 static WMPixmap*
1709 getWindowMakerIconImage(WMScreen *scr)
1711 WMPropList *dict, *key, *option, *value=NULL;
1712 WMPixmap *pix=NULL;
1713 char *path;
1715 WMPLSetCaseSensitive(True);
1717 key = WMCreatePLString("Logo.WMPanel");
1718 option = WMCreatePLString("Icon");
1720 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1722 if (dict) {
1723 value = WMGetFromPLDictionary(dict, option);
1726 WMReleasePropList(key);
1727 WMReleasePropList(option);
1729 WMPLSetCaseSensitive(False);
1731 if (value && WMIsPLString(value)) {
1732 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1734 if (path) {
1735 RColor gray;
1737 gray.red = 0xae; gray.green = 0xaa;
1738 gray.blue = 0xae; gray.alpha = 0;
1740 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1741 wfree(path);
1745 return pix;
1749 #define PWIDTH 295
1750 #define PHEIGHT 345
1754 wShowCrashingDialogPanel(int whatSig)
1756 CrashPanel *panel;
1757 WMScreen *scr;
1758 WMFont *font;
1759 WMPixmap *logo;
1760 int screen_no, scr_width, scr_height;
1761 int action;
1762 char buf[256];
1764 panel = wmalloc(sizeof(CrashPanel));
1765 memset(panel, 0, sizeof(CrashPanel));
1767 screen_no = DefaultScreen(dpy);
1768 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1769 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1771 scr = WMCreateScreen(dpy, screen_no);
1772 if (!scr) {
1773 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1774 return WMAbort;
1777 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1779 panel->win = WMCreateWindow(scr, "crashingDialog");
1780 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1781 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1783 logo = getWindowMakerIconImage(scr);
1784 if (logo) {
1785 panel->iconL = WMCreateLabel(panel->win);
1786 WMResizeWidget(panel->iconL, 64, 64);
1787 WMMoveWidget(panel->iconL, 10, 10);
1788 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1789 WMSetLabelImage(panel->iconL, logo);
1792 panel->nameL = WMCreateLabel(panel->win);
1793 WMResizeWidget(panel->nameL, 190, 18);
1794 WMMoveWidget(panel->nameL, 80, 35);
1795 WMSetLabelTextAlignment(panel->nameL, WALeft);
1796 font = WMBoldSystemFontOfSize(scr, 18);
1797 WMSetLabelFont(panel->nameL, font);
1798 WMReleaseFont(font);
1799 WMSetLabelText(panel->nameL, _("Fatal error"));
1801 panel->sepF = WMCreateFrame(panel->win);
1802 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1803 WMMoveWidget(panel->sepF, -2, 80);
1805 panel->noteL = WMCreateLabel(panel->win);
1806 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1807 WMMoveWidget(panel->noteL, 10, 90);
1808 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1809 #ifdef SYS_SIGLIST_DECLARED
1810 snprintf(buf, sizeof(buf), _("Window Maker received signal %i\n(%s)."),
1811 whatSig, sys_siglist[whatSig]);
1812 #else
1813 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1814 #endif
1815 WMSetLabelText(panel->noteL, buf);
1817 panel->note2L = WMCreateLabel(panel->win);
1818 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1819 WMMoveWidget(panel->note2L, 10, 130);
1820 WMSetLabelTextAlignment(panel->note2L, WALeft);
1821 WMSetLabelText(panel->note2L,
1822 _(" This fatal error occured probably due to a bug."
1823 " Please fill the included BUGFORM and "
1824 "report it to bugs@windowmaker.org."));
1825 WMSetLabelWraps(panel->note2L, True);
1828 panel->whatF = WMCreateFrame(panel->win);
1829 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1830 WMMoveWidget(panel->whatF, 10, 240);
1831 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1833 panel->whatP = WMCreatePopUpButton(panel->whatF);
1834 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1835 WMMoveWidget(panel->whatP, 35, 20);
1836 WMSetPopUpButtonPullsDown(panel->whatP, False);
1837 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1838 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1839 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1840 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1841 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1842 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1843 panel->action = WMRestart;
1845 WMMapSubwidgets(panel->whatF);
1847 panel->okB = WMCreateCommandButton(panel->win);
1848 WMResizeWidget(panel->okB, 80, 26);
1849 WMMoveWidget(panel->okB, 205, 309);
1850 WMSetButtonText(panel->okB, _("OK"));
1851 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1852 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1853 WMSetButtonImagePosition(panel->okB, WIPRight);
1854 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1856 panel->done = 0;
1858 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1859 handleKeyPress, panel);
1861 WMRealizeWidget(panel->win);
1862 WMMapSubwidgets(panel->win);
1864 WMMapWidget(panel->win);
1866 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1868 while (!panel->done) {
1869 XEvent event;
1871 WMNextEvent(dpy, &event);
1872 WMHandleEvent(&event);
1875 action = panel->action;
1877 WMUnmapWidget(panel->win);
1878 WMDestroyWidget(panel->win);
1879 wfree(panel);
1881 return action;
1887 /*****************************************************************************
1888 * About GNUstep Panel
1889 *****************************************************************************/
1892 static void
1893 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1894 unsigned long blackPixel, unsigned long whitePixel)
1896 GC gc;
1897 XGCValues gcv;
1898 XRectangle rects[3];
1900 gcv.foreground = blackPixel;
1901 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1903 XFillArc(dpy, d, gc, width/45, height/45,
1904 width - 2*width/45, height - 2*height/45, 0, 360*64);
1906 rects[0].x = 0;
1907 rects[0].y = 37*height/45;
1908 rects[0].width = width/3;
1909 rects[0].height = height - rects[0].y;
1911 rects[1].x = rects[0].width;
1912 rects[1].y = height/2;
1913 rects[1].width = width - 2*width/3;
1914 rects[1].height = height - rects[1].y;
1916 rects[2].x = 2*width/3;
1917 rects[2].y = height - 37*height/45;
1918 rects[2].width = width/3;
1919 rects[2].height = height - rects[2].y;
1921 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1922 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1924 XSetForeground(dpy, gc, whitePixel);
1925 XFillArc(dpy, d, gc, width/45, height/45,
1926 width - 2*width/45, height - 2*height/45, 0, 360*64);
1928 XFreeGC(dpy, gc);
1932 typedef struct {
1933 WScreen *scr;
1935 WWindow *wwin;
1937 WMWindow *win;
1939 WMLabel *gstepL;
1940 WMLabel *textL;
1941 } GNUstepPanel;
1944 static GNUstepPanel *gnustepPanel = NULL;
1946 static void
1947 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1949 WMUnmapWidget(gnustepPanel->win);
1951 WMDestroyWidget(gnustepPanel->win);
1953 wUnmanageWindow(gnustepPanel->wwin, False, False);
1955 wfree(gnustepPanel);
1957 gnustepPanel = NULL;
1961 void
1962 wShowGNUstepPanel(WScreen *scr)
1964 GNUstepPanel *panel;
1965 Window parent;
1966 WWindow *wwin;
1967 WMPixmap *pixmap;
1968 WMColor *color;
1970 if (gnustepPanel) {
1971 if (gnustepPanel->scr == scr) {
1972 wRaiseFrame(gnustepPanel->wwin->frame->core);
1973 wSetFocusTo(scr, gnustepPanel->wwin);
1975 return;
1978 panel = wmalloc(sizeof(GNUstepPanel));
1980 panel->scr = scr;
1982 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1983 WMResizeWidget(panel->win, 325, 200);
1985 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1986 WMScreenDepth(scr->wmscreen), True);
1988 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1990 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1991 WMColorPixel(color), scr->white_pixel);
1993 WMReleaseColor(color);
1995 XSetForeground(dpy, scr->mono_gc, 0);
1996 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1997 130, 130);
1998 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
2000 panel->gstepL = WMCreateLabel(panel->win);
2001 WMResizeWidget(panel->gstepL, 285, 64);
2002 WMMoveWidget(panel->gstepL, 20, 0);
2003 WMSetLabelTextAlignment(panel->gstepL, WARight);
2004 WMSetLabelText(panel->gstepL, "GNUstep");
2006 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
2008 WMSetLabelFont(panel->gstepL, font);
2009 WMReleaseFont(font);
2012 panel->textL = WMCreateLabel(panel->win);
2013 WMResizeWidget(panel->textL, 275, 130);
2014 WMMoveWidget(panel->textL, 30, 50);
2015 WMSetLabelTextAlignment(panel->textL, WARight);
2016 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
2017 WMSetLabelText(panel->textL,
2018 _("Window Maker is part of the GNUstep project.\n"\
2019 "The GNUstep project aims to create a free\n"\
2020 "implementation of the OpenStep(tm) specification\n"\
2021 "which is a object-oriented framework for\n"\
2022 "creating advanced graphical, multi-platform\n"\
2023 "applications. Additionally, a development and\n"\
2024 "user desktop enviroment will be created on top\n"\
2025 "of the framework. For more information about\n"\
2026 "GNUstep, please visit: www.gnustep.org"));
2027 WMSetLabelImage(panel->textL, pixmap);
2029 WMReleasePixmap(pixmap);
2031 WMRealizeWidget(panel->win);
2032 WMMapSubwidgets(panel->win);
2034 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
2036 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
2039 WMPoint center = getCenter(scr, 325, 200);
2041 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
2042 center.x, center.y,
2043 325, 200);
2046 WSETUFLAG(wwin, no_closable, 0);
2047 WSETUFLAG(wwin, no_close_button, 0);
2048 wWindowUpdateButtonImages(wwin);
2049 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
2050 #ifdef XKB_BUTTON_HINT
2051 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
2052 #endif
2053 wwin->frame->on_click_right = destroyGNUstepPanel;
2055 panel->wwin = wwin;
2057 WMMapWidget(panel->win);
2059 wWindowMap(wwin);
2061 gnustepPanel = panel;