- Updated WINGs/NEWS with info about hw the API changed how how things
[wmaker-crm.git] / src / dialog.c
blobad4fc4ec51efed270fc17b0e8e63adc961e79831
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, int state,
442 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 *black, *white, *gray, *back;
450 WMSize size;
451 WMScreen *wmscr = WMWidgetScreen(panel->win);
452 RColor color;
453 int x, y, width, height, len;
455 if(!panel->preview) return;
457 x = rect->pos.x;
458 y = rect->pos.y;
459 width = rect->size.width;
460 height = rect->size.height;
462 black = WMBlackColor(wmscr);
463 white = WMWhiteColor(wmscr);
464 gray = WMGrayColor(wmscr);
465 back = (state & WLDSSelected) ? white : gray;
467 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
468 len = strlen(dirfile)+strlen(text)+4;
469 file = wmalloc(len);
470 snprintf(file, len, "%s/%s", dirfile, text);
471 wfree(dirfile);
473 color.red = WMRedComponentOfColor(back) >> 8;
474 color.green = WMGreenComponentOfColor(back) >> 8;
475 color.blue = WMBlueComponentOfColor(back) >> 8;
476 color.alpha = WMGetColorAlpha(back) >> 8;
478 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
479 wfree(file);
481 if (!pixmap) {
482 /*WMRemoveListItem(lPtr, index);*/
483 WMReleaseColor(black);
484 WMReleaseColor(white);
485 WMReleaseColor(gray);
486 return;
489 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
491 XSetClipMask(dpy, gc, None);
492 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54);*/
493 XDrawLine(dpy, d, WMColorGC(white), x, y+height-1, x+width, y+height-1);
495 size = WMGetPixmapSize(pixmap);
497 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
498 XSetClipOrigin(dpy, copygc, x + (width-size.width)/2, y+2);
499 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
500 size.width>100?100:size.width, size.height>64?64:size.height,
501 x + (width-size.width)/2, y+2);
504 int i,j;
505 int fheight = WMFontHeight(panel->normalfont);
506 int tlen = strlen(text);
507 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
508 int ofx, ofy;
510 ofx = x + (width - twidth)/2;
511 ofy = y + 64 - fheight;
513 for(i=-1;i<2;i++)
514 for(j=-1;j<2;j++)
515 WMDrawString(wmscr, d, white, panel->normalfont,
516 ofx+i, ofy+j, text, tlen);
518 WMDrawString(wmscr, d, black, panel->normalfont, ofx, ofy,
519 text, tlen);
522 WMReleasePixmap(pixmap);
523 /* I hope it is better to do not use cache / on my box it is fast nuff */
524 XFlush(dpy);
526 WMReleaseColor(black);
527 WMReleaseColor(white);
528 WMReleaseColor(gray);
532 static void
533 buttonCallback(void *self, void *clientData)
535 WMButton *bPtr = (WMButton*)self;
536 IconPanel *panel = (IconPanel*)clientData;
539 if (bPtr==panel->okButton) {
540 panel->done = True;
541 panel->result = True;
542 } else if (bPtr==panel->cancelButton) {
543 panel->done = True;
544 panel->result = False;
545 } else if (bPtr==panel->previewButton) {
546 /**** Previewer ****/
547 WMSetButtonEnabled(bPtr, False);
548 WMSetListUserDrawItemHeight(panel->iconList, 68);
549 WMSetListUserDrawProc(panel->iconList, drawIconProc);
550 WMRedisplayWidget(panel->iconList);
551 /* for draw proc to access screen/gc */
552 /*** end preview ***/
554 #if 0
555 else if (bPtr==panel->chooseButton) {
556 WMOpenPanel *op;
558 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
560 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
561 char *path;
562 path = WMGetFilePanelFile(op);
563 WMSetTextFieldText(panel->fileField, path);
564 setViewedImage(panel, path);
565 wfree(path);
567 WMDestroyFilePanel(op);
569 #endif
573 static void
574 keyPressHandler(XEvent *event, void *data)
576 IconPanel *panel = (IconPanel*)data;
577 char buffer[32];
578 int count;
579 KeySym ksym;
580 int iidx;
581 int didx;
582 int item;
583 WMList *list = NULL;
585 if (event->type == KeyRelease)
586 return;
588 buffer[0] = 0;
589 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
592 iidx = WMGetListSelectedItemRow(panel->iconList);
593 didx = WMGetListSelectedItemRow(panel->dirList);
595 switch (ksym) {
596 case XK_Up:
597 if (iidx > 0)
598 item = iidx-1;
599 else
600 item = iidx;
601 list = panel->iconList;
602 break;
603 case XK_Down:
604 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
605 item = iidx+1;
606 else
607 item = iidx;
608 list = panel->iconList;
609 break;
610 case XK_Home:
611 item = 0;
612 list = panel->iconList;
613 break;
614 case XK_End:
615 item = WMGetListNumberOfRows(panel->iconList) - 1;
616 list = panel->iconList;
617 break;
618 case XK_Next:
619 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
620 item = didx + 1;
621 else
622 item = didx;
623 list = panel->dirList;
624 break;
625 case XK_Prior:
626 if (didx > 0)
627 item = didx - 1;
628 else
629 item = 0;
630 list = panel->dirList;
631 break;
632 case XK_Return:
633 WMPerformButtonClick(panel->okButton);
634 break;
635 case XK_Escape:
636 WMPerformButtonClick(panel->cancelButton);
637 break;
640 if (list) {
641 WMSelectListItem(list, item);
642 WMSetListPosition(list, item - 5);
643 listCallback(list, panel);
649 Bool
650 wIconChooserDialog(WScreen *scr, char **file, char *instance, char *class)
652 WWindow *wwin;
653 Window parent;
654 IconPanel *panel;
655 WMColor *color;
656 WMFont *boldFont;
658 panel = wmalloc(sizeof(IconPanel));
659 memset(panel, 0, sizeof(IconPanel));
661 panel->scr = scr;
663 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
664 WMResizeWidget(panel->win, 450, 280);
666 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask|KeyReleaseMask,
667 keyPressHandler, panel);
670 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
671 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
673 panel->dirLabel = WMCreateLabel(panel->win);
674 WMResizeWidget(panel->dirLabel, 200, 20);
675 WMMoveWidget(panel->dirLabel, 10, 7);
676 WMSetLabelText(panel->dirLabel, _("Directories"));
677 WMSetLabelFont(panel->dirLabel, boldFont);
678 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
680 WMSetLabelRelief(panel->dirLabel, WRSunken);
682 panel->iconLabel = WMCreateLabel(panel->win);
683 WMResizeWidget(panel->iconLabel, 140, 20);
684 WMMoveWidget(panel->iconLabel, 215, 7);
685 WMSetLabelText(panel->iconLabel, _("Icons"));
686 WMSetLabelFont(panel->iconLabel, boldFont);
687 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
689 WMReleaseFont(boldFont);
691 color = WMWhiteColor(scr->wmscreen);
692 WMSetLabelTextColor(panel->dirLabel, color);
693 WMSetLabelTextColor(panel->iconLabel, color);
694 WMReleaseColor(color);
696 color = WMDarkGrayColor(scr->wmscreen);
697 WMSetWidgetBackgroundColor(panel->iconLabel, color);
698 WMSetWidgetBackgroundColor(panel->dirLabel, color);
699 WMReleaseColor(color);
701 WMSetLabelRelief(panel->iconLabel, WRSunken);
703 panel->dirList = WMCreateList(panel->win);
704 WMResizeWidget(panel->dirList, 200, 170);
705 WMMoveWidget(panel->dirList, 10, 30);
706 WMSetListAction(panel->dirList, listCallback, panel);
708 panel->iconList = WMCreateList(panel->win);
709 WMResizeWidget(panel->iconList, 140, 170);
710 WMMoveWidget(panel->iconList, 215, 30);
711 WMSetListAction(panel->iconList, listCallback, panel);
713 WMHangData(panel->iconList,panel);
715 panel->previewButton = WMCreateCommandButton(panel->win);
716 WMResizeWidget(panel->previewButton, 75, 26);
717 WMMoveWidget(panel->previewButton, 365, 130);
718 WMSetButtonText(panel->previewButton, _("Preview"));
719 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
721 panel->iconView = WMCreateLabel(panel->win);
722 WMResizeWidget(panel->iconView, 75, 75);
723 WMMoveWidget(panel->iconView, 365, 40);
724 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
725 WMSetLabelRelief(panel->iconView, WRSunken);
726 WMSetLabelTextAlignment(panel->iconView, WACenter);
728 panel->fileLabel = WMCreateLabel(panel->win);
729 WMResizeWidget(panel->fileLabel, 80, 20);
730 WMMoveWidget(panel->fileLabel, 10, 210);
731 WMSetLabelText(panel->fileLabel, _("File Name:"));
733 panel->fileField = WMCreateTextField(panel->win);
734 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
735 WMResizeWidget(panel->fileField, 345, 20);
736 WMMoveWidget(panel->fileField, 95, 210);
737 WMSetTextFieldEditable(panel->fileField, False);
739 panel->okButton = WMCreateCommandButton(panel->win);
740 WMResizeWidget(panel->okButton, 80, 26);
741 WMMoveWidget(panel->okButton, 360, 240);
742 WMSetButtonText(panel->okButton, _("OK"));
743 WMSetButtonEnabled(panel->okButton, False);
744 WMSetButtonAction(panel->okButton, buttonCallback, panel);
746 panel->cancelButton = WMCreateCommandButton(panel->win);
747 WMResizeWidget(panel->cancelButton, 80, 26);
748 WMMoveWidget(panel->cancelButton, 270, 240);
749 WMSetButtonText(panel->cancelButton, _("Cancel"));
750 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
751 #if 0
752 panel->chooseButton = WMCreateCommandButton(panel->win);
753 WMResizeWidget(panel->chooseButton, 110, 26);
754 WMMoveWidget(panel->chooseButton, 150, 240);
755 WMSetButtonText(panel->chooseButton, _("Choose File"));
756 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
757 #endif
758 WMRealizeWidget(panel->win);
759 WMMapSubwidgets(panel->win);
761 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
763 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
766 char *tmp;
767 int len = (instance ? strlen(instance) : 0)
768 + (class ? strlen(class) : 0) + 32;
769 WMPoint center;
771 tmp = wmalloc(len);
773 if (tmp && (instance || class))
774 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
775 else
776 strcpy(tmp, _("Icon Chooser"));
778 center = getCenter(scr, 450, 280);
780 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x,center.y,
781 450, 280);
782 wfree(tmp);
785 /* put icon paths in the list */
786 listIconPaths(panel->dirList);
788 WMMapWidget(panel->win);
790 wWindowMap(wwin);
792 while (!panel->done) {
793 XEvent event;
795 WMNextEvent(dpy, &event);
796 WMHandleEvent(&event);
799 if (panel->result) {
800 char *defaultPath, *wantedPath;
802 /* check if the file the user selected is not the one that
803 * would be loaded by default with the current search path */
804 *file = WMGetListSelectedItem(panel->iconList)->text;
805 if ((*file)[0]==0) {
806 wfree(*file);
807 *file = NULL;
808 } else {
809 defaultPath = FindImage(wPreferences.icon_path, *file);
810 wantedPath = WMGetTextFieldText(panel->fileField);
811 /* if the file is not the default, use full path */
812 if (strcmp(wantedPath, defaultPath)!=0) {
813 *file = wantedPath;
814 } else {
815 *file = wstrdup(*file);
816 wfree(wantedPath);
818 wfree(defaultPath);
820 } else {
821 *file = NULL;
824 WMReleaseFont(panel->normalfont);
826 WMUnmapWidget(panel->win);
828 WMDestroyWidget(panel->win);
830 wUnmanageWindow(wwin, False, False);
832 wfree(panel);
834 XDestroyWindow(dpy, parent);
836 return panel->result;
841 ***********************************************************************
842 * Info Panel
843 ***********************************************************************
847 typedef struct {
848 WScreen *scr;
850 WWindow *wwin;
852 WMWindow *win;
854 WMLabel *logoL;
855 WMLabel *name1L;
856 WMLabel *name2L;
858 WMLabel *versionL;
860 WMLabel *infoL;
862 WMLabel *copyrL;
864 #ifdef SILLYNESS
865 WMHandlerID timer;
866 int cycle;
867 RImage *icon;
868 RImage *pic;
869 WMPixmap *oldPix;
870 WMFont *oldFont;
871 char *str;
872 int x;
873 #endif
874 } InfoPanel;
878 #define COPYRIGHT_TEXT \
879 "Copyright \xa9 1997-2002 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
880 "Copyright \xa9 1998-2002 Dan Pascu <dan@windowmaker.org>"
884 static InfoPanel *thePanel = NULL;
886 static void
887 destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
889 #ifdef SILLYNESS
890 if (thePanel->timer) {
891 WMDeleteTimerHandler(thePanel->timer);
893 if (thePanel->oldPix) {
894 WMReleasePixmap(thePanel->oldPix);
896 if (thePanel->oldFont) {
897 WMReleaseFont(thePanel->oldFont);
899 if (thePanel->icon) {
900 RReleaseImage(thePanel->icon);
902 if (thePanel->pic) {
903 RReleaseImage(thePanel->pic);
905 #endif /* SILLYNESS */
906 WMUnmapWidget(thePanel);
908 wUnmanageWindow(thePanel->wwin, False, False);
910 WMDestroyWidget(thePanel->win);
912 wfree(thePanel);
914 thePanel = NULL;
918 WMPixmap*
919 renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
921 WMPixmap *wpix = NULL;
922 Pixmap grad = None;
923 Pixmap mask = None;
924 RContext *rc = WMScreenRContext(scr);
925 XFontStruct *f = NULL;
926 int w, h;
927 GC gc = None;
929 f = XLoadQueryFont(dpy, font);
930 if (!f)
931 return NULL;
933 w = XTextWidth(f, text, strlen(text));
934 h = f->ascent+f->descent;
936 mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
937 gc = XCreateGC(dpy, mask, 0, NULL);
938 XSetForeground(dpy, gc, 0);
939 XSetFont(dpy, gc, f->fid);
940 XFillRectangle(dpy, mask, gc, 0, 0, w, h);
942 XSetForeground(dpy, gc, 1);
943 XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
944 XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
945 XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
947 grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
949 WMColor *color;
951 color = WMBlackColor(scr);
952 XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
953 WMReleaseColor(color);
956 wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
958 if (gc)
959 XFreeGC(dpy, gc);
960 XFreeFont(dpy, f);
962 return wpix;
965 #ifdef SILLYNESS
967 extern WMPixmap *DoXThing();
968 extern Bool InitXThing();
970 static void
971 logoPushCallback(void *data)
973 InfoPanel *panel = (InfoPanel*)data;
974 char buffer[512];
975 int i;
976 static int oldi = 0;
977 int len;
978 static int jingobeu[] = {
979 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
980 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
981 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
983 static int c = 0;
985 if (panel->x) {
986 XKeyboardControl kc;
987 XKeyboardState ksave;
988 unsigned long mask = KBBellPitch|KBBellDuration|KBBellPercent;
990 XGetKeyboardControl(dpy, &ksave);
992 if (panel->x > 0) {
993 if(jingobeu[panel->x-1]==0) {
994 panel->x=-1;
995 } else if (jingobeu[panel->x-1]<0) {
996 panel->x++;
997 c=jingobeu[panel->x-1]/50;
998 panel->x++;
999 } else if (c==0) {
1000 kc.bell_percent=50;
1001 kc.bell_pitch=jingobeu[panel->x-1];
1002 panel->x++;
1003 kc.bell_duration=jingobeu[panel->x-1];
1004 c=jingobeu[panel->x-1]/50;
1005 panel->x++;
1006 XChangeKeyboardControl(dpy, mask, &kc);
1007 XBell(dpy, 50);
1008 XFlush(dpy);
1009 } else {
1010 c--;
1013 if (!(panel->cycle % 4)) {
1014 WMPixmap *p;
1016 p = DoXThing(panel->wwin);
1017 WMSetLabelImage(panel->logoL, p);
1019 kc.bell_pitch = ksave.bell_pitch;
1020 kc.bell_percent = ksave.bell_percent;
1021 kc.bell_duration = ksave.bell_duration;
1022 XChangeKeyboardControl(dpy, mask, &kc);
1023 } else if (panel->cycle < 30) {
1024 RImage *image;
1025 WMPixmap *pix;
1026 RColor gray;
1028 gray.red = 0xae; gray.green = 0xaa;
1029 gray.blue = 0xae; gray.alpha = 0;
1031 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
1032 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
1033 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
1034 RReleaseImage(image);
1035 WMSetLabelImage(panel->logoL, pix);
1036 WMReleasePixmap(pix);
1039 /* slow down text a little */
1040 i = (int)(panel->cycle * 50.0/85.0)%200;
1042 if (i != oldi) {
1043 len = strlen(panel->str);
1045 strncpy(buffer, panel->str, i<len ? i : len);
1046 if (i >= len)
1047 memset(&buffer[len], ' ', i-len);
1049 strncpy(buffer, panel->str, i<len ? i : len);
1050 if (i >= len)
1051 memset(&buffer[len], ' ', i-len);
1052 buffer[i]=0;
1054 WMSetLabelText(panel->versionL, buffer);
1056 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1058 oldi = i;
1061 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1062 panel->cycle++;
1066 static void
1067 handleLogoPush(XEvent *event, void *data)
1069 InfoPanel *panel = (InfoPanel*)data;
1070 static int broken = 0;
1071 static int clicks = 0;
1072 static char *pic_data[] = {
1073 "45 45 57 1",
1074 " c None",
1075 ". c #000000",
1076 "X c #383C00",
1077 "o c #515500",
1078 "O c #616100",
1079 "+ c #616900",
1080 "@ c #696D00",
1081 "# c #697100",
1082 "$ c #495100",
1083 "% c #202800",
1084 "& c #969600",
1085 "* c #CFCF00",
1086 "= c #D7DB00",
1087 "- c #D7D700",
1088 "; c #C7CB00",
1089 ": c #A6AA00",
1090 "> c #494900",
1091 ", c #8E8E00",
1092 "< c #DFE700",
1093 "1 c #F7FF00",
1094 "2 c #FFFF00",
1095 "3 c #E7EB00",
1096 "4 c #B6B600",
1097 "5 c #595900",
1098 "6 c #717500",
1099 "7 c #AEB200",
1100 "8 c #CFD300",
1101 "9 c #E7EF00",
1102 "0 c #EFF300",
1103 "q c #9EA200",
1104 "w c #F7FB00",
1105 "e c #F7F700",
1106 "r c #BEBE00",
1107 "t c #8E9200",
1108 "y c #EFF700",
1109 "u c #969A00",
1110 "i c #414500",
1111 "p c #595D00",
1112 "a c #E7E700",
1113 "s c #C7C700",
1114 "d c #797D00",
1115 "f c #BEC300",
1116 "g c #DFE300",
1117 "h c #868600",
1118 "j c #EFEF00",
1119 "k c #9E9E00",
1120 "l c #616500",
1121 "z c #DFDF00",
1122 "x c #868A00",
1123 "c c #969200",
1124 "v c #B6BA00",
1125 "b c #A6A600",
1126 "n c #8E8A00",
1127 "m c #717100",
1128 "M c #AEAE00",
1129 "N c #AEAA00",
1130 "B c #868200",
1131 " ............... ",
1132 " ....XoO+@##+O$%.... ",
1133 " ...%X&*========-;;:o... ",
1134 " ...>.>,<122222222222134@... ",
1135 " ..>5678912222222222222220q%.. ",
1136 " ..$.&-w2222222222222222222er>.. ",
1137 " ..O.t31222222222222222222222y4>.. ",
1138 " ...O5u3222222222222222222222222yri... ",
1139 " ..>p&a22222222222222222222222222wso.. ",
1140 " ..ids91222222222222222222222222222wfi.. ",
1141 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1142 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1143 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1144 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1145 "..io*222222222&...u22222222yt..%*22222220:%. ",
1146 "..>k02222222227...f222222222v..X=222222229t. ",
1147 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1148 ".%vw222222222221y2222222222219*y2222222222wd.",
1149 ".X;2222222222222222222222222222222222222222b.",
1150 ".i*2222222222222222222222222222222222222222v.",
1151 ".i*2222222222222222222222222222222222222222;.",
1152 ".i*22222222222222222222222222222222222222228.",
1153 ".>*2222222222222222222222222222222222222222=.",
1154 ".i*22222222222222222222222222222222222222228.",
1155 ".i*2222222222222222222222222222222222222222;.",
1156 ".X*222222222222222222222222222222we12222222r.",
1157 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1158 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1159 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1160 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1161 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1162 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1163 " ...:e2222218mdz22222222222222a&$vw222220@...",
1164 " ...O-122222y:.u02222222222229q$uj222221r... ",
1165 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1166 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1167 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1168 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1169 " ..Xb9122222109g-****;<y22221zn%... ",
1170 " ..X&801222222222222222222w-h.... ",
1171 " ...o:=022222222222222221=lX... ",
1172 " ..X@:;3w2222222222210fO... ",
1173 " ...XX&v8<30000003-N@... ",
1174 " .....XmnbN:q&Bo.... ",
1175 " ............ "
1177 static char *msgs[] = {
1178 "Have a nice day!",
1179 "Focus follow mouse users will burn in hell!!!",
1180 "Mooo Canada!!!!",
1181 "Hi! My name is bobby...",
1182 "AHH! The neurotic monkeys are after me!",
1183 "WE GET SIGNAL",
1184 "HOW ARE YOU GENTLEMEN?",
1185 "WHAT YOU SAY??",
1186 "SOMEBODY SET UP US THE BOMB",
1187 "ALL YOUR BASE ARE BELONG TO US!",
1188 "Oh My God!!! Larry is back!"
1192 clicks++;
1194 if (!panel->timer && !broken && clicks > 0) {
1195 WMFont *font;
1197 panel->x = 0;
1198 clicks = 0;
1199 if (!panel->icon) {
1200 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1201 if (!panel->icon) {
1202 broken = 1;
1203 return;
1204 } else {
1205 RColor color;
1207 color.red = 0xae; color.green = 0xaa;
1208 color.blue = 0xae; color.alpha = 0;
1210 panel->icon = RCloneImage(panel->icon);
1211 RCombineImageWithColor(panel->icon, &color);
1214 if (!panel->pic) {
1215 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1216 if (!panel->pic) {
1217 broken = 1;
1218 RReleaseImage(panel->icon);
1219 panel->icon = NULL;
1220 return;
1224 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1226 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1227 panel->cycle = 0;
1228 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1229 /* If we don't use a fixed font, scrolling will be jumpy */
1230 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1231 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1232 WMRetainFont(panel->oldFont);
1233 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
1234 if (font) {
1235 WMSetLabelFont(panel->versionL, font);
1236 WMReleaseFont(font);
1238 WMSetLabelText(panel->versionL, "");
1239 } else if (panel->timer) {
1240 char version[20];
1242 panel->x = 0;
1243 clicks = 0;
1244 WMSetLabelImage(panel->logoL, panel->oldPix);
1245 WMReleasePixmap(panel->oldPix);
1246 panel->oldPix = NULL;
1248 WMDeleteTimerHandler(panel->timer);
1249 panel->timer = NULL;
1251 WMSetLabelFont(panel->versionL, panel->oldFont);
1252 if (panel->oldFont) {
1253 WMReleaseFont(panel->oldFont);
1254 panel->oldFont = NULL;
1256 snprintf(version, sizeof(version), _("Version %s"), VERSION);
1257 WMSetLabelText(panel->versionL, version);
1258 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1262 XEvent ev;
1263 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1264 ButtonPress, &ev));
1267 #endif /* SILLYNESS */
1270 void
1271 wShowInfoPanel(WScreen *scr)
1273 InfoPanel *panel;
1274 WMPixmap *logo;
1275 WMSize size;
1276 WMFont *font;
1277 char *strbuf = NULL;
1278 char buffer[256];
1279 Window parent;
1280 WWindow *wwin;
1281 RColor color1, color2;
1282 char **strl;
1283 int i;
1284 char *visuals[] = {
1285 "StaticGray",
1286 "GrayScale",
1287 "StaticColor",
1288 "PseudoColor",
1289 "TrueColor",
1290 "DirectColor"
1294 if (thePanel) {
1295 if (thePanel->scr == scr) {
1296 wRaiseFrame(thePanel->wwin->frame->core);
1297 wSetFocusTo(scr, thePanel->wwin);
1299 return;
1302 panel = wmalloc(sizeof(InfoPanel));
1303 memset(panel, 0, sizeof(InfoPanel));
1305 panel->scr = scr;
1307 panel->win = WMCreateWindow(scr->wmscreen, "info");
1308 WMResizeWidget(panel->win, 382, 230);
1310 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor*)NULL);
1311 if (!logo) {
1312 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1314 if (logo) {
1315 size = WMGetPixmapSize(logo);
1316 panel->logoL = WMCreateLabel(panel->win);
1317 WMResizeWidget(panel->logoL, 64, 64);
1318 WMMoveWidget(panel->logoL, 30, 20);
1319 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1320 WMSetLabelImage(panel->logoL, logo);
1321 #ifdef SILLYNESS
1322 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1323 handleLogoPush, panel);
1324 #endif
1325 WMReleasePixmap(logo);
1328 panel->name1L = WMCreateLabel(panel->win);
1329 WMResizeWidget(panel->name1L, 240, 30);
1330 WMMoveWidget(panel->name1L, 100, 30);
1331 color1.red = 0;
1332 color1.green = 0;
1333 color1.blue = 0;
1334 color2.red = 0x50;
1335 color2.green = 0x50;
1336 color2.blue = 0x70;
1337 logo = renderText(scr->wmscreen, "Window Maker",
1338 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1339 if (logo) {
1340 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1341 WMSetLabelImage(panel->name1L, logo);
1342 WMReleasePixmap(logo);
1343 } else {
1344 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1345 if (font) {
1346 WMSetLabelFont(panel->name1L, font);
1347 WMReleaseFont(font);
1349 WMSetLabelTextAlignment(panel->name1L, WACenter);
1350 WMSetLabelText(panel->name1L, "Window Maker");
1353 panel->name2L = WMCreateLabel(panel->win);
1354 WMResizeWidget(panel->name2L, 240, 24);
1355 WMMoveWidget(panel->name2L, 100, 60);
1356 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1357 if (font) {
1358 WMSetLabelFont(panel->name2L, font);
1359 WMReleaseFont(font);
1360 font = NULL;
1362 WMSetLabelTextAlignment(panel->name2L, WACenter);
1363 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1366 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1367 panel->versionL = WMCreateLabel(panel->win);
1368 WMResizeWidget(panel->versionL, 310, 16);
1369 WMMoveWidget(panel->versionL, 30, 95);
1370 WMSetLabelTextAlignment(panel->versionL, WARight);
1371 WMSetLabelText(panel->versionL, buffer);
1372 WMSetLabelWraps(panel->versionL, False);
1374 panel->copyrL = WMCreateLabel(panel->win);
1375 WMResizeWidget(panel->copyrL, 340, 40);
1376 WMMoveWidget(panel->copyrL, 15, 185);
1377 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1378 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1379 /* we want the (c) character in the helvetica font */
1380 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1381 if (font) {
1382 WMSetLabelFont(panel->copyrL, font);
1383 WMReleaseFont(font);
1384 font = NULL;
1387 strbuf = NULL;
1388 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1389 (unsigned)scr->w_visual->visualid,
1390 visuals[scr->w_visual->class], scr->w_depth);
1392 strbuf = wstrappend(strbuf, buffer);
1394 switch (scr->w_depth) {
1395 case 15:
1396 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1397 break;
1398 case 16:
1399 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1400 break;
1401 case 24:
1402 case 32:
1403 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1404 break;
1405 default:
1406 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1<<scr->w_depth);
1407 strbuf = wstrappend(strbuf, buffer);
1408 break;
1412 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1414 struct mallinfo ma = mallinfo();
1415 snprintf(buffer, sizeof(buffer),
1416 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1417 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1419 strbuf = wstrappend(strbuf, buffer);
1421 #endif
1423 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1424 strl = RSupportedFileFormats();
1425 for (i=0; strl[i]!=NULL; i++) {
1426 strbuf = wstrappend(strbuf, strl[i]);
1427 strbuf = wstrappend(strbuf, " ");
1430 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1432 char *list[8];
1433 char buf[80];
1434 int j = 0;
1436 #ifdef MWM_HINTS
1437 list[j++] = "MWM";
1438 #endif
1439 #ifdef KWM_HINTS
1440 list[j++] = "KDE";
1441 #endif
1442 #ifdef GNOME_STUFF
1443 list[j++] = "GNOME";
1444 #endif
1445 #ifdef OLWM_HINTS
1446 list[j++] = "OLWM";
1447 #endif
1449 buf[0] = 0;
1450 for (i = 0; i < j; i++) {
1451 if (i > 0) {
1452 if (i == j - 1)
1453 strcat(buf, _(" and "));
1454 else
1455 strcat(buf, ", ");
1457 strcat(buf, list[i]);
1459 strbuf = wstrappend(strbuf, buf);
1462 if (wPreferences.no_sound) {
1463 strbuf = wstrappend(strbuf, _("\nSound disabled"));
1464 } else {
1465 strbuf = wstrappend(strbuf, _("\nSound enabled"));
1469 panel->infoL = WMCreateLabel(panel->win);
1470 WMResizeWidget(panel->infoL, 350, 75);
1471 WMMoveWidget(panel->infoL, 15, 115);
1472 WMSetLabelText(panel->infoL, strbuf);
1473 font = WMCreateFont(scr->wmscreen, HELVETICA10_FONT);
1474 if (font) {
1475 WMSetLabelFont(panel->infoL, font);
1476 WMReleaseFont(font);
1477 font = NULL;
1479 wfree(strbuf);
1482 WMRealizeWidget(panel->win);
1483 WMMapSubwidgets(panel->win);
1485 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1487 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1489 WMMapWidget(panel->win);
1492 WMPoint center = getCenter(scr, 382, 230);
1494 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1495 center.x, center.y,
1496 382, 230);
1499 WSETUFLAG(wwin, no_closable, 0);
1500 WSETUFLAG(wwin, no_close_button, 0);
1501 #ifdef XKB_BUTTON_HINT
1502 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1503 #endif
1504 wWindowUpdateButtonImages(wwin);
1505 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1506 wwin->frame->on_click_right = destroyInfoPanel;
1508 wWindowMap(wwin);
1510 panel->wwin = wwin;
1512 thePanel = panel;
1513 #ifdef SILLYNESS
1514 if (InitXThing(panel->scr)) {
1515 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1516 panel->cycle = 0;
1517 panel->x = 1;
1518 panel->str = _("Merry Christmas!");
1519 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1521 #endif
1526 ***********************************************************************
1527 * Legal Panel
1528 ***********************************************************************
1531 typedef struct {
1532 WScreen *scr;
1534 WWindow *wwin;
1536 WMWindow *win;
1538 WMLabel *licenseL;
1539 } LegalPanel;
1542 static LegalPanel *legalPanel = NULL;
1544 static void
1545 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1547 WMUnmapWidget(legalPanel->win);
1549 WMDestroyWidget(legalPanel->win);
1551 wUnmanageWindow(legalPanel->wwin, False, False);
1553 wfree(legalPanel);
1555 legalPanel = NULL;
1559 void
1560 wShowLegalPanel(WScreen *scr)
1562 LegalPanel *panel;
1563 Window parent;
1564 WWindow *wwin;
1566 if (legalPanel) {
1567 if (legalPanel->scr == scr) {
1568 wRaiseFrame(legalPanel->wwin->frame->core);
1569 wSetFocusTo(scr, legalPanel->wwin);
1571 return;
1574 panel = wmalloc(sizeof(LegalPanel));
1576 panel->scr = scr;
1578 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1579 WMResizeWidget(panel->win, 420, 250);
1582 panel->licenseL = WMCreateLabel(panel->win);
1583 WMSetLabelWraps(panel->licenseL, True);
1584 WMResizeWidget(panel->licenseL, 400, 230);
1585 WMMoveWidget(panel->licenseL, 10, 10);
1586 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1587 WMSetLabelText(panel->licenseL,
1588 _(" Window Maker is free software; you can redistribute it and/or\n"
1589 "modify it under the terms of the GNU General Public License as\n"
1590 "published by the Free Software Foundation; either version 2 of the\n"
1591 "License, or (at your option) any later version.\n\n"
1592 " Window Maker is distributed in the hope that it will be useful,\n"
1593 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1594 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1595 "See the GNU General Public License for more details.\n\n"
1596 " You should have received a copy of the GNU General Public\n"
1597 "License along with this program; if not, write to the Free Software\n"
1598 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1599 "02111-1307, USA."));
1600 WMSetLabelRelief(panel->licenseL, WRGroove);
1602 WMRealizeWidget(panel->win);
1603 WMMapSubwidgets(panel->win);
1605 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1607 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1610 WMPoint center = getCenter(scr, 420, 250);
1612 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1613 center.x, center.y,
1614 420, 250);
1617 WSETUFLAG(wwin, no_closable, 0);
1618 WSETUFLAG(wwin, no_close_button, 0);
1619 wWindowUpdateButtonImages(wwin);
1620 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1621 #ifdef XKB_BUTTON_HINT
1622 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1623 #endif
1624 wwin->frame->on_click_right = destroyLegalPanel;
1626 panel->wwin = wwin;
1628 WMMapWidget(panel->win);
1630 wWindowMap(wwin);
1632 legalPanel = panel;
1637 ***********************************************************************
1638 * Crashing Dialog Panel
1639 ***********************************************************************
1642 extern WDDomain *WDWindowAttributes;
1645 typedef struct _CrashPanel {
1646 WMWindow *win; /* main window */
1648 WMLabel *iconL; /* application icon */
1649 WMLabel *nameL; /* title of panel */
1651 WMFrame *sepF; /* separator frame */
1653 WMLabel *noteL; /* Title of note */
1654 WMLabel *note2L; /* body of note with what happened */
1656 WMFrame *whatF; /* "what to do next" frame */
1657 WMPopUpButton *whatP; /* action selection popup button */
1659 WMButton *okB; /* ok button */
1661 Bool done; /* if finished with this dialog */
1662 int action; /* what to do after */
1664 KeyCode retKey;
1666 } CrashPanel;
1669 static void
1670 handleKeyPress(XEvent *event, void *clientData)
1672 CrashPanel *panel = (CrashPanel*)clientData;
1674 if (event->xkey.keycode == panel->retKey) {
1675 WMPerformButtonClick(panel->okB);
1680 static void
1681 okButtonCallback(void *self, void *clientData)
1683 CrashPanel *panel = (CrashPanel*)clientData;
1685 panel->done = True;
1689 static void
1690 setCrashAction(void *self, void *clientData)
1692 WMPopUpButton *pop = (WMPopUpButton*)self;
1693 CrashPanel *panel = (CrashPanel*)clientData;
1695 panel->action = WMGetPopUpButtonSelectedItem(pop);
1699 static WMPixmap*
1700 getWindowMakerIconImage(WMScreen *scr)
1702 WMPropList *dict, *key, *option, *value=NULL;
1703 WMPixmap *pix=NULL;
1704 char *path;
1706 WMPLSetCaseSensitive(True);
1708 key = WMCreatePLString("Logo.WMPanel");
1709 option = WMCreatePLString("Icon");
1711 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1713 if (dict) {
1714 value = WMGetFromPLDictionary(dict, option);
1717 WMReleasePropList(key);
1718 WMReleasePropList(option);
1720 WMPLSetCaseSensitive(False);
1722 if (value && WMIsPLString(value)) {
1723 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1725 if (path) {
1726 RColor gray;
1728 gray.red = 0xae; gray.green = 0xaa;
1729 gray.blue = 0xae; gray.alpha = 0;
1731 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1732 wfree(path);
1736 return pix;
1740 #define PWIDTH 295
1741 #define PHEIGHT 345
1745 wShowCrashingDialogPanel(int whatSig)
1747 CrashPanel *panel;
1748 WMScreen *scr;
1749 WMFont *font;
1750 WMPixmap *logo;
1751 int screen_no, scr_width, scr_height;
1752 int action;
1753 char buf[256];
1755 panel = wmalloc(sizeof(CrashPanel));
1756 memset(panel, 0, sizeof(CrashPanel));
1758 screen_no = DefaultScreen(dpy);
1759 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1760 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1762 scr = WMCreateScreen(dpy, screen_no);
1763 if (!scr) {
1764 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1765 return WMAbort;
1768 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1770 panel->win = WMCreateWindow(scr, "crashingDialog");
1771 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1772 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1774 logo = getWindowMakerIconImage(scr);
1775 if (logo) {
1776 panel->iconL = WMCreateLabel(panel->win);
1777 WMResizeWidget(panel->iconL, 64, 64);
1778 WMMoveWidget(panel->iconL, 10, 10);
1779 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1780 WMSetLabelImage(panel->iconL, logo);
1783 panel->nameL = WMCreateLabel(panel->win);
1784 WMResizeWidget(panel->nameL, 190, 18);
1785 WMMoveWidget(panel->nameL, 80, 35);
1786 WMSetLabelTextAlignment(panel->nameL, WALeft);
1787 font = WMBoldSystemFontOfSize(scr, 18);
1788 WMSetLabelFont(panel->nameL, font);
1789 WMReleaseFont(font);
1790 WMSetLabelText(panel->nameL, _("Fatal error"));
1792 panel->sepF = WMCreateFrame(panel->win);
1793 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1794 WMMoveWidget(panel->sepF, -2, 80);
1796 panel->noteL = WMCreateLabel(panel->win);
1797 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1798 WMMoveWidget(panel->noteL, 10, 90);
1799 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1800 #ifdef SYS_SIGLIST_DECLARED
1801 snprintf(buf, sizeof(buf), _("Window Maker received signal %i\n(%s)."),
1802 whatSig, sys_siglist[whatSig]);
1803 #else
1804 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1805 #endif
1806 WMSetLabelText(panel->noteL, buf);
1808 panel->note2L = WMCreateLabel(panel->win);
1809 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1810 WMMoveWidget(panel->note2L, 10, 130);
1811 WMSetLabelTextAlignment(panel->note2L, WALeft);
1812 WMSetLabelText(panel->note2L,
1813 _(" This fatal error occured probably due to a bug."
1814 " Please fill the included BUGFORM and "
1815 "report it to bugs@windowmaker.org."));
1816 WMSetLabelWraps(panel->note2L, True);
1819 panel->whatF = WMCreateFrame(panel->win);
1820 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1821 WMMoveWidget(panel->whatF, 10, 240);
1822 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1824 panel->whatP = WMCreatePopUpButton(panel->whatF);
1825 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1826 WMMoveWidget(panel->whatP, 35, 20);
1827 WMSetPopUpButtonPullsDown(panel->whatP, False);
1828 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1829 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1830 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1831 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1832 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1833 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1834 panel->action = WMRestart;
1836 WMMapSubwidgets(panel->whatF);
1838 panel->okB = WMCreateCommandButton(panel->win);
1839 WMResizeWidget(panel->okB, 80, 26);
1840 WMMoveWidget(panel->okB, 205, 309);
1841 WMSetButtonText(panel->okB, _("OK"));
1842 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1843 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1844 WMSetButtonImagePosition(panel->okB, WIPRight);
1845 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1847 panel->done = 0;
1849 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1850 handleKeyPress, panel);
1852 WMRealizeWidget(panel->win);
1853 WMMapSubwidgets(panel->win);
1855 WMMapWidget(panel->win);
1857 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1859 while (!panel->done) {
1860 XEvent event;
1862 WMNextEvent(dpy, &event);
1863 WMHandleEvent(&event);
1866 action = panel->action;
1868 WMUnmapWidget(panel->win);
1869 WMDestroyWidget(panel->win);
1870 wfree(panel);
1872 return action;
1878 /*****************************************************************************
1879 * About GNUstep Panel
1880 *****************************************************************************/
1883 static void
1884 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1885 unsigned long blackPixel, unsigned long whitePixel)
1887 GC gc;
1888 XGCValues gcv;
1889 XRectangle rects[3];
1891 gcv.foreground = blackPixel;
1892 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1894 XFillArc(dpy, d, gc, width/45, height/45,
1895 width - 2*width/45, height - 2*height/45, 0, 360*64);
1897 rects[0].x = 0;
1898 rects[0].y = 37*height/45;
1899 rects[0].width = width/3;
1900 rects[0].height = height - rects[0].y;
1902 rects[1].x = rects[0].width;
1903 rects[1].y = height/2;
1904 rects[1].width = width - 2*width/3;
1905 rects[1].height = height - rects[1].y;
1907 rects[2].x = 2*width/3;
1908 rects[2].y = height - 37*height/45;
1909 rects[2].width = width/3;
1910 rects[2].height = height - rects[2].y;
1912 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1913 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1915 XSetForeground(dpy, gc, whitePixel);
1916 XFillArc(dpy, d, gc, width/45, height/45,
1917 width - 2*width/45, height - 2*height/45, 0, 360*64);
1919 XFreeGC(dpy, gc);
1923 typedef struct {
1924 WScreen *scr;
1926 WWindow *wwin;
1928 WMWindow *win;
1930 WMLabel *gstepL;
1931 WMLabel *textL;
1932 } GNUstepPanel;
1935 static GNUstepPanel *gnustepPanel = NULL;
1937 static void
1938 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1940 WMUnmapWidget(gnustepPanel->win);
1942 WMDestroyWidget(gnustepPanel->win);
1944 wUnmanageWindow(gnustepPanel->wwin, False, False);
1946 wfree(gnustepPanel);
1948 gnustepPanel = NULL;
1952 void
1953 wShowGNUstepPanel(WScreen *scr)
1955 GNUstepPanel *panel;
1956 Window parent;
1957 WWindow *wwin;
1958 WMPixmap *pixmap;
1959 WMColor *color;
1961 if (gnustepPanel) {
1962 if (gnustepPanel->scr == scr) {
1963 wRaiseFrame(gnustepPanel->wwin->frame->core);
1964 wSetFocusTo(scr, gnustepPanel->wwin);
1966 return;
1969 panel = wmalloc(sizeof(GNUstepPanel));
1971 panel->scr = scr;
1973 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1974 WMResizeWidget(panel->win, 325, 200);
1976 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1977 WMScreenDepth(scr->wmscreen), True);
1979 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1981 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1982 WMColorPixel(color), scr->white_pixel);
1984 WMReleaseColor(color);
1986 XSetForeground(dpy, scr->mono_gc, 0);
1987 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1988 130, 130);
1989 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1991 panel->gstepL = WMCreateLabel(panel->win);
1992 WMResizeWidget(panel->gstepL, 285, 64);
1993 WMMoveWidget(panel->gstepL, 20, 0);
1994 WMSetLabelTextAlignment(panel->gstepL, WARight);
1995 WMSetLabelText(panel->gstepL, "GNUstep");
1997 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1999 WMSetLabelFont(panel->gstepL, font);
2000 WMReleaseFont(font);
2003 panel->textL = WMCreateLabel(panel->win);
2004 WMResizeWidget(panel->textL, 275, 130);
2005 WMMoveWidget(panel->textL, 30, 50);
2006 WMSetLabelTextAlignment(panel->textL, WARight);
2007 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
2008 WMSetLabelText(panel->textL,
2009 _("Window Maker is part of the GNUstep project.\n"\
2010 "The GNUstep project aims to create a free\n"\
2011 "implementation of the OpenStep(tm) specification\n"\
2012 "which is a object-oriented framework for\n"\
2013 "creating advanced graphical, multi-platform\n"\
2014 "applications. Additionally, a development and\n"\
2015 "user desktop enviroment will be created on top\n"\
2016 "of the framework. For more information about\n"\
2017 "GNUstep, please visit: www.gnustep.org"));
2018 WMSetLabelImage(panel->textL, pixmap);
2020 WMReleasePixmap(pixmap);
2022 WMRealizeWidget(panel->win);
2023 WMMapSubwidgets(panel->win);
2025 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
2027 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
2030 WMPoint center = getCenter(scr, 325, 200);
2032 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
2033 center.x, center.y,
2034 325, 200);
2037 WSETUFLAG(wwin, no_closable, 0);
2038 WSETUFLAG(wwin, no_close_button, 0);
2039 wWindowUpdateButtonImages(wwin);
2040 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
2041 #ifdef XKB_BUTTON_HINT
2042 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
2043 #endif
2044 wwin->frame->on_click_right = destroyGNUstepPanel;
2046 panel->wwin = wwin;
2048 WMMapWidget(panel->win);
2050 wWindowMap(wwin);
2052 gnustepPanel = panel;