- API change in WINGs for WMDraw*String().
[wmaker-crm.git] / src / dialog.c
blobeb0f3dce516d1a0d53496ede1d95a92c99355791
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, whitecolor, panel->normalfont,
525 ofx+i, ofy+j, text, tlen);
527 WMDrawString(wmscr, d, blackcolor, panel->normalfont, ofx, ofy,
528 text, tlen);
531 WMReleasePixmap(pixmap);
532 /* I hope it is better to do not use cache / on my box it is fast nuff */
533 XFlush(dpy);
535 WMReleaseColor(blackcolor);
536 WMReleaseColor(whitecolor);
540 static void
541 buttonCallback(void *self, void *clientData)
543 WMButton *bPtr = (WMButton*)self;
544 IconPanel *panel = (IconPanel*)clientData;
547 if (bPtr==panel->okButton) {
548 panel->done = True;
549 panel->result = True;
550 } else if (bPtr==panel->cancelButton) {
551 panel->done = True;
552 panel->result = False;
553 } else if (bPtr==panel->previewButton) {
554 /**** Previewer ****/
555 WMSetButtonEnabled(bPtr, False);
556 WMSetListUserDrawItemHeight(panel->iconList, 68);
557 WMSetListUserDrawProc(panel->iconList, drawIconProc);
558 WMRedisplayWidget(panel->iconList);
559 /* for draw proc to access screen/gc */
560 /*** end preview ***/
562 #if 0
563 else if (bPtr==panel->chooseButton) {
564 WMOpenPanel *op;
566 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
568 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
569 char *path;
570 path = WMGetFilePanelFile(op);
571 WMSetTextFieldText(panel->fileField, path);
572 setViewedImage(panel, path);
573 wfree(path);
575 WMDestroyFilePanel(op);
577 #endif
581 static void
582 keyPressHandler(XEvent *event, void *data)
584 IconPanel *panel = (IconPanel*)data;
585 char buffer[32];
586 int count;
587 KeySym ksym;
588 int iidx;
589 int didx;
590 int item;
591 WMList *list = NULL;
593 if (event->type == KeyRelease)
594 return;
596 buffer[0] = 0;
597 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
600 iidx = WMGetListSelectedItemRow(panel->iconList);
601 didx = WMGetListSelectedItemRow(panel->dirList);
603 switch (ksym) {
604 case XK_Up:
605 if (iidx > 0)
606 item = iidx-1;
607 else
608 item = iidx;
609 list = panel->iconList;
610 break;
611 case XK_Down:
612 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
613 item = iidx+1;
614 else
615 item = iidx;
616 list = panel->iconList;
617 break;
618 case XK_Home:
619 item = 0;
620 list = panel->iconList;
621 break;
622 case XK_End:
623 item = WMGetListNumberOfRows(panel->iconList) - 1;
624 list = panel->iconList;
625 break;
626 case XK_Next:
627 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
628 item = didx + 1;
629 else
630 item = didx;
631 list = panel->dirList;
632 break;
633 case XK_Prior:
634 if (didx > 0)
635 item = didx - 1;
636 else
637 item = 0;
638 list = panel->dirList;
639 break;
640 case XK_Return:
641 WMPerformButtonClick(panel->okButton);
642 break;
643 case XK_Escape:
644 WMPerformButtonClick(panel->cancelButton);
645 break;
648 if (list) {
649 WMSelectListItem(list, item);
650 WMSetListPosition(list, item - 5);
651 listCallback(list, panel);
657 Bool
658 wIconChooserDialog(WScreen *scr, char **file, char *instance, char *class)
660 WWindow *wwin;
661 Window parent;
662 IconPanel *panel;
663 WMColor *color;
664 WMFont *boldFont;
666 panel = wmalloc(sizeof(IconPanel));
667 memset(panel, 0, sizeof(IconPanel));
669 panel->scr = scr;
671 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
672 WMResizeWidget(panel->win, 450, 280);
674 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask|KeyReleaseMask,
675 keyPressHandler, panel);
678 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
679 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
681 panel->dirLabel = WMCreateLabel(panel->win);
682 WMResizeWidget(panel->dirLabel, 200, 20);
683 WMMoveWidget(panel->dirLabel, 10, 7);
684 WMSetLabelText(panel->dirLabel, _("Directories"));
685 WMSetLabelFont(panel->dirLabel, boldFont);
686 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
688 WMSetLabelRelief(panel->dirLabel, WRSunken);
690 panel->iconLabel = WMCreateLabel(panel->win);
691 WMResizeWidget(panel->iconLabel, 140, 20);
692 WMMoveWidget(panel->iconLabel, 215, 7);
693 WMSetLabelText(panel->iconLabel, _("Icons"));
694 WMSetLabelFont(panel->iconLabel, boldFont);
695 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
697 WMReleaseFont(boldFont);
699 color = WMWhiteColor(scr->wmscreen);
700 WMSetLabelTextColor(panel->dirLabel, color);
701 WMSetLabelTextColor(panel->iconLabel, color);
702 WMReleaseColor(color);
704 color = WMDarkGrayColor(scr->wmscreen);
705 WMSetWidgetBackgroundColor(panel->iconLabel, color);
706 WMSetWidgetBackgroundColor(panel->dirLabel, color);
707 WMReleaseColor(color);
709 WMSetLabelRelief(panel->iconLabel, WRSunken);
711 panel->dirList = WMCreateList(panel->win);
712 WMResizeWidget(panel->dirList, 200, 170);
713 WMMoveWidget(panel->dirList, 10, 30);
714 WMSetListAction(panel->dirList, listCallback, panel);
716 panel->iconList = WMCreateList(panel->win);
717 WMResizeWidget(panel->iconList, 140, 170);
718 WMMoveWidget(panel->iconList, 215, 30);
719 WMSetListAction(panel->iconList, listCallback, panel);
721 WMHangData(panel->iconList,panel);
723 panel->previewButton = WMCreateCommandButton(panel->win);
724 WMResizeWidget(panel->previewButton, 75, 26);
725 WMMoveWidget(panel->previewButton, 365, 130);
726 WMSetButtonText(panel->previewButton, _("Preview"));
727 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
729 panel->iconView = WMCreateLabel(panel->win);
730 WMResizeWidget(panel->iconView, 75, 75);
731 WMMoveWidget(panel->iconView, 365, 40);
732 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
733 WMSetLabelRelief(panel->iconView, WRSunken);
734 WMSetLabelTextAlignment(panel->iconView, WACenter);
736 panel->fileLabel = WMCreateLabel(panel->win);
737 WMResizeWidget(panel->fileLabel, 80, 20);
738 WMMoveWidget(panel->fileLabel, 10, 210);
739 WMSetLabelText(panel->fileLabel, _("File Name:"));
741 panel->fileField = WMCreateTextField(panel->win);
742 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
743 WMResizeWidget(panel->fileField, 345, 20);
744 WMMoveWidget(panel->fileField, 95, 210);
745 WMSetTextFieldEditable(panel->fileField, False);
747 panel->okButton = WMCreateCommandButton(panel->win);
748 WMResizeWidget(panel->okButton, 80, 26);
749 WMMoveWidget(panel->okButton, 360, 240);
750 WMSetButtonText(panel->okButton, _("OK"));
751 WMSetButtonEnabled(panel->okButton, False);
752 WMSetButtonAction(panel->okButton, buttonCallback, panel);
754 panel->cancelButton = WMCreateCommandButton(panel->win);
755 WMResizeWidget(panel->cancelButton, 80, 26);
756 WMMoveWidget(panel->cancelButton, 270, 240);
757 WMSetButtonText(panel->cancelButton, _("Cancel"));
758 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
759 #if 0
760 panel->chooseButton = WMCreateCommandButton(panel->win);
761 WMResizeWidget(panel->chooseButton, 110, 26);
762 WMMoveWidget(panel->chooseButton, 150, 240);
763 WMSetButtonText(panel->chooseButton, _("Choose File"));
764 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
765 #endif
766 WMRealizeWidget(panel->win);
767 WMMapSubwidgets(panel->win);
769 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
771 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
774 char *tmp;
775 int len = (instance ? strlen(instance) : 0)
776 + (class ? strlen(class) : 0) + 32;
777 WMPoint center;
779 tmp = wmalloc(len);
781 if (tmp && (instance || class))
782 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
783 else
784 strcpy(tmp, _("Icon Chooser"));
786 center = getCenter(scr, 450, 280);
788 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x,center.y,
789 450, 280);
790 wfree(tmp);
793 /* put icon paths in the list */
794 listIconPaths(panel->dirList);
796 WMMapWidget(panel->win);
798 wWindowMap(wwin);
800 while (!panel->done) {
801 XEvent event;
803 WMNextEvent(dpy, &event);
804 WMHandleEvent(&event);
807 if (panel->result) {
808 char *defaultPath, *wantedPath;
810 /* check if the file the user selected is not the one that
811 * would be loaded by default with the current search path */
812 *file = WMGetListSelectedItem(panel->iconList)->text;
813 if ((*file)[0]==0) {
814 wfree(*file);
815 *file = NULL;
816 } else {
817 defaultPath = FindImage(wPreferences.icon_path, *file);
818 wantedPath = WMGetTextFieldText(panel->fileField);
819 /* if the file is not the default, use full path */
820 if (strcmp(wantedPath, defaultPath)!=0) {
821 *file = wantedPath;
822 } else {
823 *file = wstrdup(*file);
824 wfree(wantedPath);
826 wfree(defaultPath);
828 } else {
829 *file = NULL;
832 WMReleaseFont(panel->normalfont);
834 WMUnmapWidget(panel->win);
836 WMDestroyWidget(panel->win);
838 wUnmanageWindow(wwin, False, False);
840 wfree(panel);
842 XDestroyWindow(dpy, parent);
844 return panel->result;
849 ***********************************************************************
850 * Info Panel
851 ***********************************************************************
855 typedef struct {
856 WScreen *scr;
858 WWindow *wwin;
860 WMWindow *win;
862 WMLabel *logoL;
863 WMLabel *name1L;
864 WMLabel *name2L;
866 WMLabel *versionL;
868 WMLabel *infoL;
870 WMLabel *copyrL;
872 #ifdef SILLYNESS
873 WMHandlerID timer;
874 int cycle;
875 RImage *icon;
876 RImage *pic;
877 WMPixmap *oldPix;
878 WMFont *oldFont;
879 char *str;
880 int x;
881 #endif
882 } InfoPanel;
886 #define COPYRIGHT_TEXT \
887 "Copyright \xa9 1997-2002 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
888 "Copyright \xa9 1998-2002 Dan Pascu <dan@windowmaker.org>"
892 static InfoPanel *thePanel = NULL;
894 static void
895 destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
897 #ifdef SILLYNESS
898 if (thePanel->timer) {
899 WMDeleteTimerHandler(thePanel->timer);
901 if (thePanel->oldPix) {
902 WMReleasePixmap(thePanel->oldPix);
904 if (thePanel->oldFont) {
905 WMReleaseFont(thePanel->oldFont);
907 if (thePanel->icon) {
908 RReleaseImage(thePanel->icon);
910 if (thePanel->pic) {
911 RReleaseImage(thePanel->pic);
913 #endif /* SILLYNESS */
914 WMUnmapWidget(thePanel);
916 wUnmanageWindow(thePanel->wwin, False, False);
918 WMDestroyWidget(thePanel->win);
920 wfree(thePanel);
922 thePanel = NULL;
926 WMPixmap*
927 renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
929 WMPixmap *wpix = NULL;
930 Pixmap grad = None;
931 Pixmap mask = None;
932 RContext *rc = WMScreenRContext(scr);
933 XFontStruct *f = NULL;
934 int w, h;
935 GC gc = None;
937 f = XLoadQueryFont(dpy, font);
938 if (!f)
939 return NULL;
941 w = XTextWidth(f, text, strlen(text));
942 h = f->ascent+f->descent;
944 mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
945 gc = XCreateGC(dpy, mask, 0, NULL);
946 XSetForeground(dpy, gc, 0);
947 XSetFont(dpy, gc, f->fid);
948 XFillRectangle(dpy, mask, gc, 0, 0, w, h);
950 XSetForeground(dpy, gc, 1);
951 XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
952 XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
953 XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
955 grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
957 WMColor *color;
959 color = WMBlackColor(scr);
960 XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
961 WMReleaseColor(color);
964 wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
966 if (gc)
967 XFreeGC(dpy, gc);
968 XFreeFont(dpy, f);
970 return wpix;
973 #ifdef SILLYNESS
975 extern WMPixmap *DoXThing();
976 extern Bool InitXThing();
978 static void
979 logoPushCallback(void *data)
981 InfoPanel *panel = (InfoPanel*)data;
982 char buffer[512];
983 int i;
984 static int oldi = 0;
985 int len;
986 static int jingobeu[] = {
987 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
988 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
989 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
991 static int c = 0;
993 if (panel->x) {
994 XKeyboardControl kc;
995 XKeyboardState ksave;
996 unsigned long mask = KBBellPitch|KBBellDuration|KBBellPercent;
998 XGetKeyboardControl(dpy, &ksave);
1000 if (panel->x > 0) {
1001 if(jingobeu[panel->x-1]==0) {
1002 panel->x=-1;
1003 } else if (jingobeu[panel->x-1]<0) {
1004 panel->x++;
1005 c=jingobeu[panel->x-1]/50;
1006 panel->x++;
1007 } else if (c==0) {
1008 kc.bell_percent=50;
1009 kc.bell_pitch=jingobeu[panel->x-1];
1010 panel->x++;
1011 kc.bell_duration=jingobeu[panel->x-1];
1012 c=jingobeu[panel->x-1]/50;
1013 panel->x++;
1014 XChangeKeyboardControl(dpy, mask, &kc);
1015 XBell(dpy, 50);
1016 XFlush(dpy);
1017 } else {
1018 c--;
1021 if (!(panel->cycle % 4)) {
1022 WMPixmap *p;
1024 p = DoXThing(panel->wwin);
1025 WMSetLabelImage(panel->logoL, p);
1027 kc.bell_pitch = ksave.bell_pitch;
1028 kc.bell_percent = ksave.bell_percent;
1029 kc.bell_duration = ksave.bell_duration;
1030 XChangeKeyboardControl(dpy, mask, &kc);
1031 } else if (panel->cycle < 30) {
1032 RImage *image;
1033 WMPixmap *pix;
1034 RColor gray;
1036 gray.red = 0xae; gray.green = 0xaa;
1037 gray.blue = 0xae; gray.alpha = 0;
1039 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
1040 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
1041 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
1042 RReleaseImage(image);
1043 WMSetLabelImage(panel->logoL, pix);
1044 WMReleasePixmap(pix);
1047 /* slow down text a little */
1048 i = (int)(panel->cycle * 50.0/85.0)%200;
1050 if (i != oldi) {
1051 len = strlen(panel->str);
1053 strncpy(buffer, panel->str, i<len ? i : len);
1054 if (i >= len)
1055 memset(&buffer[len], ' ', i-len);
1057 strncpy(buffer, panel->str, i<len ? i : len);
1058 if (i >= len)
1059 memset(&buffer[len], ' ', i-len);
1060 buffer[i]=0;
1062 WMSetLabelText(panel->versionL, buffer);
1064 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1066 oldi = i;
1069 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1070 panel->cycle++;
1074 static void
1075 handleLogoPush(XEvent *event, void *data)
1077 InfoPanel *panel = (InfoPanel*)data;
1078 static int broken = 0;
1079 static int clicks = 0;
1080 static char *pic_data[] = {
1081 "45 45 57 1",
1082 " c None",
1083 ". c #000000",
1084 "X c #383C00",
1085 "o c #515500",
1086 "O c #616100",
1087 "+ c #616900",
1088 "@ c #696D00",
1089 "# c #697100",
1090 "$ c #495100",
1091 "% c #202800",
1092 "& c #969600",
1093 "* c #CFCF00",
1094 "= c #D7DB00",
1095 "- c #D7D700",
1096 "; c #C7CB00",
1097 ": c #A6AA00",
1098 "> c #494900",
1099 ", c #8E8E00",
1100 "< c #DFE700",
1101 "1 c #F7FF00",
1102 "2 c #FFFF00",
1103 "3 c #E7EB00",
1104 "4 c #B6B600",
1105 "5 c #595900",
1106 "6 c #717500",
1107 "7 c #AEB200",
1108 "8 c #CFD300",
1109 "9 c #E7EF00",
1110 "0 c #EFF300",
1111 "q c #9EA200",
1112 "w c #F7FB00",
1113 "e c #F7F700",
1114 "r c #BEBE00",
1115 "t c #8E9200",
1116 "y c #EFF700",
1117 "u c #969A00",
1118 "i c #414500",
1119 "p c #595D00",
1120 "a c #E7E700",
1121 "s c #C7C700",
1122 "d c #797D00",
1123 "f c #BEC300",
1124 "g c #DFE300",
1125 "h c #868600",
1126 "j c #EFEF00",
1127 "k c #9E9E00",
1128 "l c #616500",
1129 "z c #DFDF00",
1130 "x c #868A00",
1131 "c c #969200",
1132 "v c #B6BA00",
1133 "b c #A6A600",
1134 "n c #8E8A00",
1135 "m c #717100",
1136 "M c #AEAE00",
1137 "N c #AEAA00",
1138 "B c #868200",
1139 " ............... ",
1140 " ....XoO+@##+O$%.... ",
1141 " ...%X&*========-;;:o... ",
1142 " ...>.>,<122222222222134@... ",
1143 " ..>5678912222222222222220q%.. ",
1144 " ..$.&-w2222222222222222222er>.. ",
1145 " ..O.t31222222222222222222222y4>.. ",
1146 " ...O5u3222222222222222222222222yri... ",
1147 " ..>p&a22222222222222222222222222wso.. ",
1148 " ..ids91222222222222222222222222222wfi.. ",
1149 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1150 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1151 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1152 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1153 "..io*222222222&...u22222222yt..%*22222220:%. ",
1154 "..>k02222222227...f222222222v..X=222222229t. ",
1155 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1156 ".%vw222222222221y2222222222219*y2222222222wd.",
1157 ".X;2222222222222222222222222222222222222222b.",
1158 ".i*2222222222222222222222222222222222222222v.",
1159 ".i*2222222222222222222222222222222222222222;.",
1160 ".i*22222222222222222222222222222222222222228.",
1161 ".>*2222222222222222222222222222222222222222=.",
1162 ".i*22222222222222222222222222222222222222228.",
1163 ".i*2222222222222222222222222222222222222222;.",
1164 ".X*222222222222222222222222222222we12222222r.",
1165 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1166 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1167 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1168 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1169 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1170 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1171 " ...:e2222218mdz22222222222222a&$vw222220@...",
1172 " ...O-122222y:.u02222222222229q$uj222221r... ",
1173 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1174 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1175 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1176 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1177 " ..Xb9122222109g-****;<y22221zn%... ",
1178 " ..X&801222222222222222222w-h.... ",
1179 " ...o:=022222222222222221=lX... ",
1180 " ..X@:;3w2222222222210fO... ",
1181 " ...XX&v8<30000003-N@... ",
1182 " .....XmnbN:q&Bo.... ",
1183 " ............ "
1185 static char *msgs[] = {
1186 "Have a nice day!",
1187 "Focus follow mouse users will burn in hell!!!",
1188 "Mooo Canada!!!!",
1189 "Hi! My name is bobby...",
1190 "AHH! The neurotic monkeys are after me!",
1191 "WE GET SIGNAL",
1192 "HOW ARE YOU GENTLEMEN?",
1193 "WHAT YOU SAY??",
1194 "SOMEBODY SET UP US THE BOMB",
1195 "ALL YOUR BASE ARE BELONG TO US!",
1196 "Oh My God!!! Larry is back!"
1200 clicks++;
1202 if (!panel->timer && !broken && clicks > 0) {
1203 WMFont *font;
1205 panel->x = 0;
1206 clicks = 0;
1207 if (!panel->icon) {
1208 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1209 if (!panel->icon) {
1210 broken = 1;
1211 return;
1212 } else {
1213 RColor color;
1215 color.red = 0xae; color.green = 0xaa;
1216 color.blue = 0xae; color.alpha = 0;
1218 panel->icon = RCloneImage(panel->icon);
1219 RCombineImageWithColor(panel->icon, &color);
1222 if (!panel->pic) {
1223 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1224 if (!panel->pic) {
1225 broken = 1;
1226 RReleaseImage(panel->icon);
1227 panel->icon = NULL;
1228 return;
1232 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1234 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1235 panel->cycle = 0;
1236 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1237 /* If we don't use a fixed font, scrolling will be jumpy */
1238 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1239 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1240 WMRetainFont(panel->oldFont);
1241 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
1242 if (font) {
1243 WMSetLabelFont(panel->versionL, font);
1244 WMReleaseFont(font);
1246 WMSetLabelText(panel->versionL, "");
1247 } else if (panel->timer) {
1248 char version[20];
1250 panel->x = 0;
1251 clicks = 0;
1252 WMSetLabelImage(panel->logoL, panel->oldPix);
1253 WMReleasePixmap(panel->oldPix);
1254 panel->oldPix = NULL;
1256 WMDeleteTimerHandler(panel->timer);
1257 panel->timer = NULL;
1259 WMSetLabelFont(panel->versionL, panel->oldFont);
1260 if (panel->oldFont) {
1261 WMReleaseFont(panel->oldFont);
1262 panel->oldFont = NULL;
1264 snprintf(version, sizeof(version), _("Version %s"), VERSION);
1265 WMSetLabelText(panel->versionL, version);
1266 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1270 XEvent ev;
1271 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1272 ButtonPress, &ev));
1275 #endif /* SILLYNESS */
1278 void
1279 wShowInfoPanel(WScreen *scr)
1281 InfoPanel *panel;
1282 WMPixmap *logo;
1283 WMSize size;
1284 WMFont *font;
1285 char *strbuf = NULL;
1286 char buffer[256];
1287 Window parent;
1288 WWindow *wwin;
1289 RColor color1, color2;
1290 char **strl;
1291 int i;
1292 char *visuals[] = {
1293 "StaticGray",
1294 "GrayScale",
1295 "StaticColor",
1296 "PseudoColor",
1297 "TrueColor",
1298 "DirectColor"
1302 if (thePanel) {
1303 if (thePanel->scr == scr) {
1304 wRaiseFrame(thePanel->wwin->frame->core);
1305 wSetFocusTo(scr, thePanel->wwin);
1307 return;
1310 panel = wmalloc(sizeof(InfoPanel));
1311 memset(panel, 0, sizeof(InfoPanel));
1313 panel->scr = scr;
1315 panel->win = WMCreateWindow(scr->wmscreen, "info");
1316 WMResizeWidget(panel->win, 382, 230);
1318 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor*)NULL);
1319 if (!logo) {
1320 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1322 if (logo) {
1323 size = WMGetPixmapSize(logo);
1324 panel->logoL = WMCreateLabel(panel->win);
1325 WMResizeWidget(panel->logoL, 64, 64);
1326 WMMoveWidget(panel->logoL, 30, 20);
1327 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1328 WMSetLabelImage(panel->logoL, logo);
1329 #ifdef SILLYNESS
1330 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1331 handleLogoPush, panel);
1332 #endif
1333 WMReleasePixmap(logo);
1336 panel->name1L = WMCreateLabel(panel->win);
1337 WMResizeWidget(panel->name1L, 240, 30);
1338 WMMoveWidget(panel->name1L, 100, 30);
1339 color1.red = 0;
1340 color1.green = 0;
1341 color1.blue = 0;
1342 color2.red = 0x50;
1343 color2.green = 0x50;
1344 color2.blue = 0x70;
1345 logo = renderText(scr->wmscreen, "Window Maker",
1346 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1347 if (logo) {
1348 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1349 WMSetLabelImage(panel->name1L, logo);
1350 WMReleasePixmap(logo);
1351 } else {
1352 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1353 if (font) {
1354 WMSetLabelFont(panel->name1L, font);
1355 WMReleaseFont(font);
1357 WMSetLabelTextAlignment(panel->name1L, WACenter);
1358 WMSetLabelText(panel->name1L, "Window Maker");
1361 panel->name2L = WMCreateLabel(panel->win);
1362 WMResizeWidget(panel->name2L, 240, 24);
1363 WMMoveWidget(panel->name2L, 100, 60);
1364 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1365 if (font) {
1366 WMSetLabelFont(panel->name2L, font);
1367 WMReleaseFont(font);
1368 font = NULL;
1370 WMSetLabelTextAlignment(panel->name2L, WACenter);
1371 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1374 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1375 panel->versionL = WMCreateLabel(panel->win);
1376 WMResizeWidget(panel->versionL, 310, 16);
1377 WMMoveWidget(panel->versionL, 30, 95);
1378 WMSetLabelTextAlignment(panel->versionL, WARight);
1379 WMSetLabelText(panel->versionL, buffer);
1380 WMSetLabelWraps(panel->versionL, False);
1382 panel->copyrL = WMCreateLabel(panel->win);
1383 WMResizeWidget(panel->copyrL, 340, 40);
1384 WMMoveWidget(panel->copyrL, 15, 185);
1385 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1386 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1387 /* we want the (c) character in the helvetica font */
1388 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1389 if (font) {
1390 WMSetLabelFont(panel->copyrL, font);
1391 WMReleaseFont(font);
1392 font = NULL;
1395 strbuf = NULL;
1396 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1397 (unsigned)scr->w_visual->visualid,
1398 visuals[scr->w_visual->class], scr->w_depth);
1400 strbuf = wstrappend(strbuf, buffer);
1402 switch (scr->w_depth) {
1403 case 15:
1404 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1405 break;
1406 case 16:
1407 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1408 break;
1409 case 24:
1410 case 32:
1411 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1412 break;
1413 default:
1414 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1<<scr->w_depth);
1415 strbuf = wstrappend(strbuf, buffer);
1416 break;
1420 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1422 struct mallinfo ma = mallinfo();
1423 snprintf(buffer, sizeof(buffer),
1424 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1425 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1427 strbuf = wstrappend(strbuf, buffer);
1429 #endif
1431 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1432 strl = RSupportedFileFormats();
1433 for (i=0; strl[i]!=NULL; i++) {
1434 strbuf = wstrappend(strbuf, strl[i]);
1435 strbuf = wstrappend(strbuf, " ");
1438 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1440 char *list[8];
1441 char buf[80];
1442 int j = 0;
1444 #ifdef MWM_HINTS
1445 list[j++] = "MWM";
1446 #endif
1447 #ifdef KWM_HINTS
1448 list[j++] = "KDE";
1449 #endif
1450 #ifdef GNOME_STUFF
1451 list[j++] = "GNOME";
1452 #endif
1453 #ifdef OLWM_HINTS
1454 list[j++] = "OLWM";
1455 #endif
1457 buf[0] = 0;
1458 for (i = 0; i < j; i++) {
1459 if (i > 0) {
1460 if (i == j - 1)
1461 strcat(buf, _(" and "));
1462 else
1463 strcat(buf, ", ");
1465 strcat(buf, list[i]);
1467 strbuf = wstrappend(strbuf, buf);
1470 if (wPreferences.no_sound) {
1471 strbuf = wstrappend(strbuf, _("\nSound disabled"));
1472 } else {
1473 strbuf = wstrappend(strbuf, _("\nSound enabled"));
1477 panel->infoL = WMCreateLabel(panel->win);
1478 WMResizeWidget(panel->infoL, 350, 75);
1479 WMMoveWidget(panel->infoL, 15, 115);
1480 WMSetLabelText(panel->infoL, strbuf);
1481 font = WMCreateFont(scr->wmscreen, HELVETICA10_FONT);
1482 if (font) {
1483 WMSetLabelFont(panel->infoL, font);
1484 WMReleaseFont(font);
1485 font = NULL;
1487 wfree(strbuf);
1490 WMRealizeWidget(panel->win);
1491 WMMapSubwidgets(panel->win);
1493 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1495 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1497 WMMapWidget(panel->win);
1500 WMPoint center = getCenter(scr, 382, 230);
1502 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1503 center.x, center.y,
1504 382, 230);
1507 WSETUFLAG(wwin, no_closable, 0);
1508 WSETUFLAG(wwin, no_close_button, 0);
1509 #ifdef XKB_BUTTON_HINT
1510 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1511 #endif
1512 wWindowUpdateButtonImages(wwin);
1513 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1514 wwin->frame->on_click_right = destroyInfoPanel;
1516 wWindowMap(wwin);
1518 panel->wwin = wwin;
1520 thePanel = panel;
1521 #ifdef SILLYNESS
1522 if (InitXThing(panel->scr)) {
1523 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1524 panel->cycle = 0;
1525 panel->x = 1;
1526 panel->str = _("Merry Christmas!");
1527 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1529 #endif
1534 ***********************************************************************
1535 * Legal Panel
1536 ***********************************************************************
1539 typedef struct {
1540 WScreen *scr;
1542 WWindow *wwin;
1544 WMWindow *win;
1546 WMLabel *licenseL;
1547 } LegalPanel;
1550 static LegalPanel *legalPanel = NULL;
1552 static void
1553 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1555 WMUnmapWidget(legalPanel->win);
1557 WMDestroyWidget(legalPanel->win);
1559 wUnmanageWindow(legalPanel->wwin, False, False);
1561 wfree(legalPanel);
1563 legalPanel = NULL;
1567 void
1568 wShowLegalPanel(WScreen *scr)
1570 LegalPanel *panel;
1571 Window parent;
1572 WWindow *wwin;
1574 if (legalPanel) {
1575 if (legalPanel->scr == scr) {
1576 wRaiseFrame(legalPanel->wwin->frame->core);
1577 wSetFocusTo(scr, legalPanel->wwin);
1579 return;
1582 panel = wmalloc(sizeof(LegalPanel));
1584 panel->scr = scr;
1586 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1587 WMResizeWidget(panel->win, 420, 250);
1590 panel->licenseL = WMCreateLabel(panel->win);
1591 WMSetLabelWraps(panel->licenseL, True);
1592 WMResizeWidget(panel->licenseL, 400, 230);
1593 WMMoveWidget(panel->licenseL, 10, 10);
1594 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1595 WMSetLabelText(panel->licenseL,
1596 _(" Window Maker is free software; you can redistribute it and/or\n"
1597 "modify it under the terms of the GNU General Public License as\n"
1598 "published by the Free Software Foundation; either version 2 of the\n"
1599 "License, or (at your option) any later version.\n\n"
1600 " Window Maker is distributed in the hope that it will be useful,\n"
1601 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1602 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1603 "See the GNU General Public License for more details.\n\n"
1604 " You should have received a copy of the GNU General Public\n"
1605 "License along with this program; if not, write to the Free Software\n"
1606 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1607 "02111-1307, USA."));
1608 WMSetLabelRelief(panel->licenseL, WRGroove);
1610 WMRealizeWidget(panel->win);
1611 WMMapSubwidgets(panel->win);
1613 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1615 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1618 WMPoint center = getCenter(scr, 420, 250);
1620 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1621 center.x, center.y,
1622 420, 250);
1625 WSETUFLAG(wwin, no_closable, 0);
1626 WSETUFLAG(wwin, no_close_button, 0);
1627 wWindowUpdateButtonImages(wwin);
1628 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1629 #ifdef XKB_BUTTON_HINT
1630 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1631 #endif
1632 wwin->frame->on_click_right = destroyLegalPanel;
1634 panel->wwin = wwin;
1636 WMMapWidget(panel->win);
1638 wWindowMap(wwin);
1640 legalPanel = panel;
1645 ***********************************************************************
1646 * Crashing Dialog Panel
1647 ***********************************************************************
1650 extern WDDomain *WDWindowAttributes;
1653 typedef struct _CrashPanel {
1654 WMWindow *win; /* main window */
1656 WMLabel *iconL; /* application icon */
1657 WMLabel *nameL; /* title of panel */
1659 WMFrame *sepF; /* separator frame */
1661 WMLabel *noteL; /* Title of note */
1662 WMLabel *note2L; /* body of note with what happened */
1664 WMFrame *whatF; /* "what to do next" frame */
1665 WMPopUpButton *whatP; /* action selection popup button */
1667 WMButton *okB; /* ok button */
1669 Bool done; /* if finished with this dialog */
1670 int action; /* what to do after */
1672 KeyCode retKey;
1674 } CrashPanel;
1677 static void
1678 handleKeyPress(XEvent *event, void *clientData)
1680 CrashPanel *panel = (CrashPanel*)clientData;
1682 if (event->xkey.keycode == panel->retKey) {
1683 WMPerformButtonClick(panel->okB);
1688 static void
1689 okButtonCallback(void *self, void *clientData)
1691 CrashPanel *panel = (CrashPanel*)clientData;
1693 panel->done = True;
1697 static void
1698 setCrashAction(void *self, void *clientData)
1700 WMPopUpButton *pop = (WMPopUpButton*)self;
1701 CrashPanel *panel = (CrashPanel*)clientData;
1703 panel->action = WMGetPopUpButtonSelectedItem(pop);
1707 static WMPixmap*
1708 getWindowMakerIconImage(WMScreen *scr)
1710 WMPropList *dict, *key, *option, *value=NULL;
1711 WMPixmap *pix=NULL;
1712 char *path;
1714 WMPLSetCaseSensitive(True);
1716 key = WMCreatePLString("Logo.WMPanel");
1717 option = WMCreatePLString("Icon");
1719 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1721 if (dict) {
1722 value = WMGetFromPLDictionary(dict, option);
1725 WMReleasePropList(key);
1726 WMReleasePropList(option);
1728 WMPLSetCaseSensitive(False);
1730 if (value && WMIsPLString(value)) {
1731 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1733 if (path) {
1734 RColor gray;
1736 gray.red = 0xae; gray.green = 0xaa;
1737 gray.blue = 0xae; gray.alpha = 0;
1739 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1740 wfree(path);
1744 return pix;
1748 #define PWIDTH 295
1749 #define PHEIGHT 345
1753 wShowCrashingDialogPanel(int whatSig)
1755 CrashPanel *panel;
1756 WMScreen *scr;
1757 WMFont *font;
1758 WMPixmap *logo;
1759 int screen_no, scr_width, scr_height;
1760 int action;
1761 char buf[256];
1763 panel = wmalloc(sizeof(CrashPanel));
1764 memset(panel, 0, sizeof(CrashPanel));
1766 screen_no = DefaultScreen(dpy);
1767 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1768 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1770 scr = WMCreateScreen(dpy, screen_no);
1771 if (!scr) {
1772 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1773 return WMAbort;
1776 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1778 panel->win = WMCreateWindow(scr, "crashingDialog");
1779 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1780 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1782 logo = getWindowMakerIconImage(scr);
1783 if (logo) {
1784 panel->iconL = WMCreateLabel(panel->win);
1785 WMResizeWidget(panel->iconL, 64, 64);
1786 WMMoveWidget(panel->iconL, 10, 10);
1787 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1788 WMSetLabelImage(panel->iconL, logo);
1791 panel->nameL = WMCreateLabel(panel->win);
1792 WMResizeWidget(panel->nameL, 190, 18);
1793 WMMoveWidget(panel->nameL, 80, 35);
1794 WMSetLabelTextAlignment(panel->nameL, WALeft);
1795 font = WMBoldSystemFontOfSize(scr, 18);
1796 WMSetLabelFont(panel->nameL, font);
1797 WMReleaseFont(font);
1798 WMSetLabelText(panel->nameL, _("Fatal error"));
1800 panel->sepF = WMCreateFrame(panel->win);
1801 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1802 WMMoveWidget(panel->sepF, -2, 80);
1804 panel->noteL = WMCreateLabel(panel->win);
1805 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1806 WMMoveWidget(panel->noteL, 10, 90);
1807 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1808 #ifdef SYS_SIGLIST_DECLARED
1809 snprintf(buf, sizeof(buf), _("Window Maker received signal %i\n(%s)."),
1810 whatSig, sys_siglist[whatSig]);
1811 #else
1812 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1813 #endif
1814 WMSetLabelText(panel->noteL, buf);
1816 panel->note2L = WMCreateLabel(panel->win);
1817 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1818 WMMoveWidget(panel->note2L, 10, 130);
1819 WMSetLabelTextAlignment(panel->note2L, WALeft);
1820 WMSetLabelText(panel->note2L,
1821 _(" This fatal error occured probably due to a bug."
1822 " Please fill the included BUGFORM and "
1823 "report it to bugs@windowmaker.org."));
1824 WMSetLabelWraps(panel->note2L, True);
1827 panel->whatF = WMCreateFrame(panel->win);
1828 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1829 WMMoveWidget(panel->whatF, 10, 240);
1830 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1832 panel->whatP = WMCreatePopUpButton(panel->whatF);
1833 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1834 WMMoveWidget(panel->whatP, 35, 20);
1835 WMSetPopUpButtonPullsDown(panel->whatP, False);
1836 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1837 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1838 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1839 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1840 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1841 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1842 panel->action = WMRestart;
1844 WMMapSubwidgets(panel->whatF);
1846 panel->okB = WMCreateCommandButton(panel->win);
1847 WMResizeWidget(panel->okB, 80, 26);
1848 WMMoveWidget(panel->okB, 205, 309);
1849 WMSetButtonText(panel->okB, _("OK"));
1850 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1851 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1852 WMSetButtonImagePosition(panel->okB, WIPRight);
1853 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1855 panel->done = 0;
1857 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1858 handleKeyPress, panel);
1860 WMRealizeWidget(panel->win);
1861 WMMapSubwidgets(panel->win);
1863 WMMapWidget(panel->win);
1865 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1867 while (!panel->done) {
1868 XEvent event;
1870 WMNextEvent(dpy, &event);
1871 WMHandleEvent(&event);
1874 action = panel->action;
1876 WMUnmapWidget(panel->win);
1877 WMDestroyWidget(panel->win);
1878 wfree(panel);
1880 return action;
1886 /*****************************************************************************
1887 * About GNUstep Panel
1888 *****************************************************************************/
1891 static void
1892 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1893 unsigned long blackPixel, unsigned long whitePixel)
1895 GC gc;
1896 XGCValues gcv;
1897 XRectangle rects[3];
1899 gcv.foreground = blackPixel;
1900 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1902 XFillArc(dpy, d, gc, width/45, height/45,
1903 width - 2*width/45, height - 2*height/45, 0, 360*64);
1905 rects[0].x = 0;
1906 rects[0].y = 37*height/45;
1907 rects[0].width = width/3;
1908 rects[0].height = height - rects[0].y;
1910 rects[1].x = rects[0].width;
1911 rects[1].y = height/2;
1912 rects[1].width = width - 2*width/3;
1913 rects[1].height = height - rects[1].y;
1915 rects[2].x = 2*width/3;
1916 rects[2].y = height - 37*height/45;
1917 rects[2].width = width/3;
1918 rects[2].height = height - rects[2].y;
1920 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1921 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1923 XSetForeground(dpy, gc, whitePixel);
1924 XFillArc(dpy, d, gc, width/45, height/45,
1925 width - 2*width/45, height - 2*height/45, 0, 360*64);
1927 XFreeGC(dpy, gc);
1931 typedef struct {
1932 WScreen *scr;
1934 WWindow *wwin;
1936 WMWindow *win;
1938 WMLabel *gstepL;
1939 WMLabel *textL;
1940 } GNUstepPanel;
1943 static GNUstepPanel *gnustepPanel = NULL;
1945 static void
1946 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1948 WMUnmapWidget(gnustepPanel->win);
1950 WMDestroyWidget(gnustepPanel->win);
1952 wUnmanageWindow(gnustepPanel->wwin, False, False);
1954 wfree(gnustepPanel);
1956 gnustepPanel = NULL;
1960 void
1961 wShowGNUstepPanel(WScreen *scr)
1963 GNUstepPanel *panel;
1964 Window parent;
1965 WWindow *wwin;
1966 WMPixmap *pixmap;
1967 WMColor *color;
1969 if (gnustepPanel) {
1970 if (gnustepPanel->scr == scr) {
1971 wRaiseFrame(gnustepPanel->wwin->frame->core);
1972 wSetFocusTo(scr, gnustepPanel->wwin);
1974 return;
1977 panel = wmalloc(sizeof(GNUstepPanel));
1979 panel->scr = scr;
1981 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1982 WMResizeWidget(panel->win, 325, 200);
1984 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1985 WMScreenDepth(scr->wmscreen), True);
1987 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1989 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1990 WMColorPixel(color), scr->white_pixel);
1992 WMReleaseColor(color);
1994 XSetForeground(dpy, scr->mono_gc, 0);
1995 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1996 130, 130);
1997 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1999 panel->gstepL = WMCreateLabel(panel->win);
2000 WMResizeWidget(panel->gstepL, 285, 64);
2001 WMMoveWidget(panel->gstepL, 20, 0);
2002 WMSetLabelTextAlignment(panel->gstepL, WARight);
2003 WMSetLabelText(panel->gstepL, "GNUstep");
2005 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
2007 WMSetLabelFont(panel->gstepL, font);
2008 WMReleaseFont(font);
2011 panel->textL = WMCreateLabel(panel->win);
2012 WMResizeWidget(panel->textL, 275, 130);
2013 WMMoveWidget(panel->textL, 30, 50);
2014 WMSetLabelTextAlignment(panel->textL, WARight);
2015 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
2016 WMSetLabelText(panel->textL,
2017 _("Window Maker is part of the GNUstep project.\n"\
2018 "The GNUstep project aims to create a free\n"\
2019 "implementation of the OpenStep(tm) specification\n"\
2020 "which is a object-oriented framework for\n"\
2021 "creating advanced graphical, multi-platform\n"\
2022 "applications. Additionally, a development and\n"\
2023 "user desktop enviroment will be created on top\n"\
2024 "of the framework. For more information about\n"\
2025 "GNUstep, please visit: www.gnustep.org"));
2026 WMSetLabelImage(panel->textL, pixmap);
2028 WMReleasePixmap(pixmap);
2030 WMRealizeWidget(panel->win);
2031 WMMapSubwidgets(panel->win);
2033 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
2035 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
2038 WMPoint center = getCenter(scr, 325, 200);
2040 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
2041 center.x, center.y,
2042 325, 200);
2045 WSETUFLAG(wwin, no_closable, 0);
2046 WSETUFLAG(wwin, no_close_button, 0);
2047 wWindowUpdateButtonImages(wwin);
2048 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
2049 #ifdef XKB_BUTTON_HINT
2050 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
2051 #endif
2052 wwin->frame->on_click_right = destroyGNUstepPanel;
2054 panel->wwin = wwin;
2056 WMMapWidget(panel->win);
2058 wWindowMap(wwin);
2060 gnustepPanel = panel;