Add history to some dialog boxes
[wmaker-crm.git] / src / dialog.c
Commit [+]AuthorDateLineData
9d2e6ef9 scottc1998-09-29 22:36:29 +00001/* dialog.c - dialog windows for internal use
ab61c599 dan2001-05-13 23:22:21 +00002 *
9af1c6c4 dan1998-10-21 14:43:47 +00003 * Window Maker window manager
ab61c599 dan2001-05-13 23:22:21 +00004 *
4153e2fd dan2003-01-16 23:30:45 +00005 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 1998-2003 Dan Pascu
ab61c599 dan2001-05-13 23:22:21 +00007 *
9d2e6ef9 scottc1998-09-29 22:36:29 +00008 * 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.
12 *
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.
17 *
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
ab61c599 dan2001-05-13 23:22:21 +000020 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
9d2e6ef9 scottc1998-09-29 22:36:29 +000021 * USA.
22 */
23
24#include "wconfig.h"
25
26#include <X11/Xlib.h>
27#include <X11/Xutil.h>
28#include <X11/keysym.h>
29
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>
38
9aa1d138 kojima2000-04-09 23:55:46 +000039#ifdef HAVE_MALLOC_H
40#include <malloc.h>
41#endif
42
52917e53 dan1999-04-16 20:05:26 +000043#include <signal.h>
44#ifdef __FreeBSD__
45#include <sys/signal.h>
46#endif
47
9d2e6ef9 scottc1998-09-29 22:36:29 +000048#ifndef PATH_MAX
49#define PATH_MAX DEFAULT_PATH_MAX
50#endif
51
52#include "WindowMaker.h"
53#include "GNUstep.h"
54#include "screen.h"
55#include "dialog.h"
56#include "funcs.h"
57#include "stacking.h"
58#include "framewin.h"
59#include "window.h"
60#include "actions.h"
0261c326 dan1999-01-06 15:22:33 +000061#include "defaults.h"
5873385d kojima2002-02-15 21:30:42 +000062#include "xinerama.h"
9d2e6ef9 scottc1998-09-29 22:36:29 +000063
64extern WPreferences wPreferences;
65
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020066static WMPoint getCenter(WScreen * scr, int width, int height)
5873385d kojima2002-02-15 21:30:42 +000067{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020068 return wGetPointToCenterRectInHead(scr, wGetHeadForPointerLocation(scr), width, height);
5873385d kojima2002-02-15 21:30:42 +000069}
5873385d kojima2002-02-15 21:30:42 +000070
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020071int wMessageDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
9d2e6ef9 scottc1998-09-29 22:36:29 +000072{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020073 WMAlertPanel *panel;
74 Window parent;
75 WWindow *wwin;
76 int result;
77 WMPoint center;
9d2e6ef9 scottc1998-09-29 22:36:29 +000078
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020079 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
b21ad7ad dan2001-01-23 03:51:46 +000080
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020081 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
088c0ac2 dan1999-03-09 14:58:01 +000082
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020083 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
6830b057 dan2004-10-12 21:28:27 +000084
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020085 center = getCenter(scr, 400, 180);
86 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
87 wwin->client_leader = WMWidgetXID(panel->win);
9d2e6ef9 scottc1998-09-29 22:36:29 +000088
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020089 WMMapWidget(panel->win);
b21ad7ad dan2001-01-23 03:51:46 +000090
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020091 wWindowMap(wwin);
9d2e6ef9 scottc1998-09-29 22:36:29 +000092
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020093 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
9d2e6ef9 scottc1998-09-29 22:36:29 +000094
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020095 result = panel->result;
9d2e6ef9 scottc1998-09-29 22:36:29 +000096
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020097 WMUnmapWidget(panel->win);
9d2e6ef9 scottc1998-09-29 22:36:29 +000098
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020099 wUnmanageWindow(wwin, False, False);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000100
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200101 WMDestroyAlertPanel(panel);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000102
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200103 XDestroyWindow(dpy, parent);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000104
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200105 return result;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000106}
107
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200108void toggleSaveSession(WMWidget * w, void *data)
72150b1d dan2001-11-05 23:19:46 +0000109{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200110 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
72150b1d dan2001-11-05 23:19:46 +0000111}
112
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200113int wExitDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
72150b1d dan2001-11-05 23:19:46 +0000114{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200115 WMAlertPanel *panel;
116 WMButton *saveSessionBtn;
117 Window parent;
118 WWindow *wwin;
119 WMPoint center;
120 int result;
72150b1d dan2001-11-05 23:19:46 +0000121
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200122 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
72150b1d dan2001-11-05 23:19:46 +0000123
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200124 /* add save session button */
125 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
126 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
127 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn), False, True, 200, 0, 0);
128 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
129 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
130 WMRealizeWidget(saveSessionBtn);
131 WMMapWidget(saveSessionBtn);
72150b1d dan2001-11-05 23:19:46 +0000132
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200133 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
72150b1d dan2001-11-05 23:19:46 +0000134
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200135 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
72150b1d dan2001-11-05 23:19:46 +0000136
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200137 center = getCenter(scr, 400, 180);
138 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
a10214a5 kojima2002-11-28 22:04:07 +0000139
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200140 wwin->client_leader = WMWidgetXID(panel->win);
72150b1d dan2001-11-05 23:19:46 +0000141
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200142 WMMapWidget(panel->win);
72150b1d dan2001-11-05 23:19:46 +0000143
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200144 wWindowMap(wwin);
72150b1d dan2001-11-05 23:19:46 +0000145
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200146 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
72150b1d dan2001-11-05 23:19:46 +0000147
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200148 result = panel->result;
72150b1d dan2001-11-05 23:19:46 +0000149
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200150 WMUnmapWidget(panel->win);
72150b1d dan2001-11-05 23:19:46 +0000151
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200152 wUnmanageWindow(wwin, False, False);
72150b1d dan2001-11-05 23:19:46 +0000153
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200154 WMDestroyAlertPanel(panel);
72150b1d dan2001-11-05 23:19:46 +0000155
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200156 XDestroyWindow(dpy, parent);
72150b1d dan2001-11-05 23:19:46 +0000157
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200158 return result;
72150b1d dan2001-11-05 23:19:46 +0000159}
160
05720d97
AV
Alexey Voinov2007-08-14 15:15:37 +0400161typedef struct _WMInputPanelWithHistory {
162 WMInputPanel *panel;
163 WMArray *history;
164 int histpos;
165 char *prefix;
166 char *suffix;
167 char *rest;
168 WMArray *variants;
169 int varpos;
170} WMInputPanelWithHistory;
171
172static char *HistoryFileName(char *name)
173{
174 char *filename = NULL;
175
176 filename = wstrdup(wusergnusteppath());
177 filename = wstrappend(filename, "/.AppInfo/WindowMaker/History");
178 if (name && strlen(name)) {
179 filename = wstrappend(filename, ".");
180 filename = wstrappend(filename, name);
181 }
182 return filename;
183}
184
185static int matchString(void *str1, void *str2)
186{
187 return (strcmp((char *)str1, (char *)str2) == 0 ? 1 : 0);
188}
189
190static WMArray *LoadHistory(char *filename, int max)
191{
192 WMPropList *plhistory;
193 WMPropList *plitem;
194 WMArray *history;
195 int i, num;
196
197 history = WMCreateArrayWithDestructor(1, wfree);
198 WMAddToArray(history, wstrdup(""));
199
200 plhistory = WMReadPropListFromFile((char *)filename);
201
202 if (plhistory && WMIsPLArray(plhistory)) {
203 num = WMGetPropListItemCount(plhistory);
204 if (num > max)
205 num = max;
206
207 for (i = 0; i < num; ++i) {
208 plitem = WMGetFromPLArray(plhistory, i);
209 if (WMIsPLString(plitem) && WMFindInArray(history, matchString,
210 WMGetFromPLString(plitem)) == WANotFound)
211 WMAddToArray(history, WMGetFromPLString(plitem));
212 }
213 }
214
215 return history;
216}
217
218static void SaveHistory(WMArray * history, char *filename)
219{
220 int i;
221 WMPropList *plhistory;
222
223 plhistory = WMCreatePLArray(NULL);
224
225 for (i = 0; i < WMGetArrayItemCount(history); ++i)
226 WMAddToPLArray(plhistory, WMCreatePLString(WMGetFromArray(history, i)));
227
228 WMWritePropListToFile(plhistory, (char *)filename, True);
229 WMReleasePropList(plhistory);
230}
231
232static int strmatch(const char *str1, const char *str2)
233{
234 return !strcmp(str1, str2);
235}
236
237static int pstrcmp(const char **str1, const char **str2)
238{
239 return strcmp(*str1, *str2);
240}
241
242static void
243ScanFiles(const char *dir, const char *prefix, unsigned acceptmask, unsigned declinemask, WMArray * result)
244{
245 int prefixlen;
246 DIR *d;
247 struct dirent *de;
248 struct stat sb;
249 char *fullfilename, *suffix;
250
251 prefixlen = strlen(prefix);
252 if ((d = opendir(dir)) != NULL) {
253 while ((de = readdir(d)) != NULL) {
254 if (strlen(de->d_name) > prefixlen &&
255 !strncmp(prefix, de->d_name, prefixlen) &&
256 strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..")) {
257 fullfilename = wstrconcat((char *)dir, "/");
258 fullfilename = wstrappend(fullfilename, de->d_name);
259
260 if (stat(fullfilename, &sb) == 0 &&
261 (sb.st_mode & acceptmask) &&
262 !(sb.st_mode & declinemask) &&
263 WMFindInArray(result, (WMMatchDataProc *) strmatch,
264 de->d_name + prefixlen) == WANotFound) {
265 suffix = wstrdup(de->d_name + prefixlen);
266 WMAddToArray(result, suffix);
267 }
268 wfree(fullfilename);
269 }
270 }
271 closedir(d);
272 }
273}
274
275static WMArray *GenerateVariants(const char *complete)
276{
277 Bool firstWord = True;
278 WMArray *variants = NULL;
279 char *pos = NULL, *path = NULL, *tmp = NULL, *dir = NULL, *prefix = NULL;
280
281 variants = WMCreateArrayWithDestructor(0, wfree);
282
283 while (*complete == ' ')
284 ++complete;
285
286 if ((pos = strrchr(complete, ' ')) != NULL) {
287 complete = pos + 1;
288 firstWord = False;
289 }
290
291 if ((pos = strrchr(complete, '/')) != NULL) {
292 tmp = wstrndup((char *)complete, pos - complete + 1);
293 if (*tmp == '~' && *(tmp + 1) == '/' && getenv("HOME")) {
294 dir = wstrdup(getenv("HOME"));
295 dir = wstrappend(dir, tmp + 1);
296 wfree(tmp);
297 } else {
298 dir = tmp;
299 }
300 prefix = wstrdup(pos + 1);
301 ScanFiles(dir, prefix, (unsigned)-1, 0, variants);
302 wfree(dir);
303 wfree(prefix);
304 } else if (*complete == '~') {
305 WMAddToArray(variants, wstrdup("/"));
306 } else if (firstWord) {
307 path = getenv("PATH");
308 while (path) {
309 pos = strchr(path, ':');
310 if (pos) {
311 tmp = wstrndup(path, pos - path);
312 path = pos + 1;
313 } else if (*path != '\0') {
314 tmp = wstrdup(path);
315 path = NULL;
316 } else
317 break;
318 ScanFiles(tmp, complete, S_IXOTH | S_IXGRP | S_IXUSR, S_IFDIR, variants);
319 wfree(tmp);
320 }
321 }
322
323 WMSortArray(variants, (WMCompareDataProc *) pstrcmp);
324 return variants;
325}
326
327static void handleHistoryKeyPress(XEvent * event, void *clientData)
328{
329 char *text;
330 unsigned pos;
331 WMInputPanelWithHistory *p = (WMInputPanelWithHistory *) clientData;
332 KeySym ksym;
333
334 ksym = XLookupKeysym(&event->xkey, 0);
335
336 switch (ksym) {
337 case XK_Up:
338 if (p->histpos < WMGetArrayItemCount(p->history) - 1) {
339 if (p->histpos == 0)
340 wfree(WMReplaceInArray(p->history, 0, WMGetTextFieldText(p->panel->text)));
341 p->histpos++;
342 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
343 }
344 break;
345 case XK_Down:
346 if (p->histpos > 0) {
347 p->histpos--;
348 WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
349 }
350 break;
351 case XK_Tab:
352 if (!p->variants) {
353 text = WMGetTextFieldText(p->panel->text);
354 pos = WMGetTextFieldCursorPosition(p->panel->text);
355 p->prefix = wstrndup(text, pos);
356 p->suffix = wstrdup(text + pos);
357 wfree(text);
358 p->variants = GenerateVariants(p->prefix);
359 p->varpos = 0;
360 if (!p->variants) {
361 wfree(p->prefix);
362 wfree(p->suffix);
363 p->prefix = NULL;
364 p->suffix = NULL;
365 }
366 }
367 if (p->variants && p->prefix && p->suffix) {
368 p->varpos++;
369 if (p->varpos > WMGetArrayItemCount(p->variants))
370 p->varpos = 0;
371 if (p->varpos > 0)
372 text = wstrconcat(p->prefix, WMGetFromArray(p->variants, p->varpos - 1));
373 else
374 text = wstrdup(p->prefix);
375 pos = strlen(text);
376 text = wstrappend(text, p->suffix);
377 WMSetTextFieldText(p->panel->text, text);
378 WMSetTextFieldCursorPosition(p->panel->text, pos);
379 wfree(text);
380 }
381 break;
382 }
383 if (ksym != XK_Tab) {
384 if (p->prefix) {
385 wfree(p->prefix);
386 p->prefix = NULL;
387 }
388 if (p->suffix) {
389 wfree(p->suffix);
390 p->suffix = NULL;
391 }
392 if (p->variants) {
393 WMFreeArray(p->variants);
394 p->variants = NULL;
395 }
396 }
397}
398
399int wAdvancedInputDialog(WScreen * scr, char *title, char *message, char *name, char **text)
400{
401 WWindow *wwin;
402 Window parent;
403 char *result;
404 WMPoint center;
405 WMInputPanelWithHistory *p;
406 char *filename;
407
408 filename = HistoryFileName(name);
409 p = wmalloc(sizeof(WMInputPanelWithHistory));
410 p->panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
411 p->history = LoadHistory(filename, wPreferences.history_lines);
412 p->histpos = 0;
413 p->prefix = NULL;
414 p->suffix = NULL;
415 p->rest = NULL;
416 p->variants = NULL;
417 p->varpos = 0;
418 WMCreateEventHandler(WMWidgetView(p->panel->text), KeyPressMask, handleHistoryKeyPress, p);
419
420 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
421 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
422
423 XReparentWindow(dpy, WMWidgetXID(p->panel->win), parent, 0, 0);
424
425 center = getCenter(scr, 320, 160);
426 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
427
428 wwin->client_leader = WMWidgetXID(p->panel->win);
429
430 WMMapWidget(p->panel->win);
431
432 wWindowMap(wwin);
433
434 WMRunModalLoop(WMWidgetScreen(p->panel->win), WMWidgetView(p->panel->win));
435
436 if (p->panel->result == WAPRDefault) {
437 result = WMGetTextFieldText(p->panel->text);
438 wfree(WMReplaceInArray(p->history, 0, wstrdup(result)));
439 SaveHistory(p->history, filename);
440 } else
441 result = NULL;
442
443 wUnmanageWindow(wwin, False, False);
444
445 WMDestroyInputPanel(p->panel);
446 WMFreeArray(p->history);
447 wfree(p);
448 wfree(filename);
449
450 XDestroyWindow(dpy, parent);
451
452 if (result == NULL)
453 return False;
454 else {
455 if (*text)
456 wfree(*text);
457 *text = result;
458
459 return True;
460 }
461}
462
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200463int wInputDialog(WScreen * scr, char *title, char *message, char **text)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000464{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200465 WWindow *wwin;
466 Window parent;
467 WMInputPanel *panel;
468 char *result;
469 WMPoint center;
b21ad7ad dan2001-01-23 03:51:46 +0000470
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200471 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
9d2e6ef9 scottc1998-09-29 22:36:29 +0000472
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200473 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
474 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000475
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200476 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000477
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200478 center = getCenter(scr, 320, 160);
479 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000480
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200481 wwin->client_leader = WMWidgetXID(panel->win);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000482
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200483 WMMapWidget(panel->win);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000484
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200485 wWindowMap(wwin);
b21ad7ad dan2001-01-23 03:51:46 +0000486
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200487 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
b21ad7ad dan2001-01-23 03:51:46 +0000488
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200489 if (panel->result == WAPRDefault)
490 result = WMGetTextFieldText(panel->text);
491 else
492 result = NULL;
b21ad7ad dan2001-01-23 03:51:46 +0000493
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200494 wUnmanageWindow(wwin, False, False);
ab61c599 dan2001-05-13 23:22:21 +0000495
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200496 WMDestroyInputPanel(panel);
ab61c599 dan2001-05-13 23:22:21 +0000497
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200498 XDestroyWindow(dpy, parent);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000499
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200500 if (result == NULL)
501 return False;
502 else {
503 if (*text)
504 wfree(*text);
505 *text = result;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000506
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200507 return True;
508 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000509}
510
9d2e6ef9 scottc1998-09-29 22:36:29 +0000511/*
512 *****************************************************************
513 * Icon Selection Panel
514 *****************************************************************
515 */
516
517typedef struct IconPanel {
ab61c599 dan2001-05-13 23:22:21 +0000518
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200519 WScreen *scr;
ab61c599 dan2001-05-13 23:22:21 +0000520
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200521 WMWindow *win;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000522
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200523 WMLabel *dirLabel;
524 WMLabel *iconLabel;
ab61c599 dan2001-05-13 23:22:21 +0000525
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200526 WMList *dirList;
527 WMList *iconList;
528 WMFont *normalfont;
ab61c599 dan2001-05-13 23:22:21 +0000529
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200530 WMButton *previewButton;
c8e0f416 id1999-10-02 19:16:27 +0000531
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200532 WMLabel *iconView;
ab61c599 dan2001-05-13 23:22:21 +0000533
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200534 WMLabel *fileLabel;
535 WMTextField *fileField;
ab61c599 dan2001-05-13 23:22:21 +0000536
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200537 WMButton *okButton;
538 WMButton *cancelButton;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000539#if 0
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200540 WMButton *chooseButton;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000541#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200542 short done;
543 short result;
544 short preview;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000545} IconPanel;
546
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200547static void listPixmaps(WScreen * scr, WMList * lPtr, char *path)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000548{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200549 struct dirent *dentry;
550 DIR *dir;
551 char pbuf[PATH_MAX + 16];
552 char *apath;
553 IconPanel *panel = WMGetHangedData(lPtr);
554
555 panel->preview = False;
556
557 apath = wexpandpath(path);
558 dir = opendir(apath);
559
560 if (!dir) {
561 char *msg;
562 char *tmp;
563 tmp = _("Could not open directory ");
564 msg = wmalloc(strlen(tmp) + strlen(path) + 6);
565 strcpy(msg, tmp);
566 strcat(msg, path);
567
568 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
569 wfree(msg);
570 wfree(apath);
571 return;
572 }
573
574 /* list contents in the column */
575 while ((dentry = readdir(dir))) {
576 struct stat statb;
577
578 if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") == 0)
579 continue;
580
581 strcpy(pbuf, apath);
582 strcat(pbuf, "/");
583 strcat(pbuf, dentry->d_name);
584
585 if (stat(pbuf, &statb) < 0)
586 continue;
587
588 if (statb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)
589 && statb.st_mode & (S_IFREG | S_IFLNK)) {
590 WMAddListItem(lPtr, dentry->d_name);
591 }
592 }
593 WMSortListItems(lPtr);
594
595 closedir(dir);
596 wfree(apath);
597 panel->preview = True;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000598}
599
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200600static void setViewedImage(IconPanel * panel, char *file)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000601{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200602 WMPixmap *pixmap;
603 RColor color;
604
605 color.red = 0xae;
606 color.green = 0xaa;
607 color.blue = 0xae;
608 color.alpha = 0;
609 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win), file, &color);
610 if (!pixmap) {
611 WMSetButtonEnabled(panel->okButton, False);
612
613 WMSetLabelText(panel->iconView, _("Could not load image file "));
614
615 WMSetLabelImage(panel->iconView, NULL);
616 } else {
617 WMSetButtonEnabled(panel->okButton, True);
618
619 WMSetLabelText(panel->iconView, NULL);
620 WMSetLabelImage(panel->iconView, pixmap);
621 WMReleasePixmap(pixmap);
622 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000623}
624
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200625static void listCallback(void *self, void *data)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000626{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200627 WMList *lPtr = (WMList *) self;
628 IconPanel *panel = (IconPanel *) data;
629 char *path;
630
631 if (lPtr == panel->dirList) {
632 WMListItem *item = WMGetListSelectedItem(lPtr);
633
634 if (item == NULL)
635 return;
636 path = item->text;
637
638 WMSetTextFieldText(panel->fileField, path);
639
640 WMSetLabelImage(panel->iconView, NULL);
641
642 WMSetButtonEnabled(panel->okButton, False);
643
644 WMClearList(panel->iconList);
645 listPixmaps(panel->scr, panel->iconList, path);
646 } else {
647 char *tmp, *iconFile;
648 WMListItem *item = WMGetListSelectedItem(panel->dirList);
649
650 if (item == NULL)
651 return;
652 path = item->text;
653 tmp = wexpandpath(path);
654
655 item = WMGetListSelectedItem(panel->iconList);
656 if (item == NULL)
657 return;
658 iconFile = item->text;
659
660 path = wmalloc(strlen(tmp) + strlen(iconFile) + 4);
661 strcpy(path, tmp);
662 strcat(path, "/");
663 strcat(path, iconFile);
664 wfree(tmp);
665 WMSetTextFieldText(panel->fileField, path);
666 setViewedImage(panel, path);
667 wfree(path);
668 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000669}
670
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200671static void listIconPaths(WMList * lPtr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000672{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200673 char *paths;
674 char *path;
0261c326 dan1999-01-06 15:22:33 +0000675
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200676 paths = wstrdup(wPreferences.icon_path);
0261c326 dan1999-01-06 15:22:33 +0000677
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200678 path = strtok(paths, ":");
0261c326 dan1999-01-06 15:22:33 +0000679
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200680 do {
681 char *tmp;
6830b057 dan2004-10-12 21:28:27 +0000682
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200683 tmp = wexpandpath(path);
684 /* do not sort, because the order implies the order of
685 * directories searched */
686 if (access(tmp, X_OK) == 0)
687 WMAddListItem(lPtr, path);
688 wfree(tmp);
689 } while ((path = strtok(NULL, ":")) != NULL);
0261c326 dan1999-01-06 15:22:33 +0000690
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200691 wfree(paths);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000692}
693
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200694static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
dbdb44a4 kojima1999-10-02 20:24:41 +0000695{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200696 IconPanel *panel = WMGetHangedData(lPtr);
697 WScreen *scr = panel->scr;
698 GC gc = scr->draw_gc;
699 GC copygc = scr->copy_gc;
700 char *file, *dirfile;
701 WMPixmap *pixmap;
702 WMColor *back;
703 WMSize size;
704 WMScreen *wmscr = WMWidgetScreen(panel->win);
705 RColor color;
706 int x, y, width, height, len;
707
708 if (!panel->preview)
709 return;
710
711 x = rect->pos.x;
712 y = rect->pos.y;
713 width = rect->size.width;
714 height = rect->size.height;
715
716 back = (state & WLDSSelected) ? scr->white : scr->gray;
717
718 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
719 len = strlen(dirfile) + strlen(text) + 4;
720 file = wmalloc(len);
721 snprintf(file, len, "%s/%s", dirfile, text);
722 wfree(dirfile);
723
724 color.red = WMRedComponentOfColor(back) >> 8;
725 color.green = WMGreenComponentOfColor(back) >> 8;
726 color.blue = WMBlueComponentOfColor(back) >> 8;
727 color.alpha = WMGetColorAlpha(back) >> 8;
728
729 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
730 wfree(file);
731
732 if (!pixmap) {
733 /*WMRemoveListItem(lPtr, index); */
734 return;
735 }
736
737 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
738
739 XSetClipMask(dpy, gc, None);
740 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54); */
741 XDrawLine(dpy, d, WMColorGC(scr->white), x, y + height - 1, x + width, y + height - 1);
742
743 size = WMGetPixmapSize(pixmap);
744
745 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
746 XSetClipOrigin(dpy, copygc, x + (width - size.width) / 2, y + 2);
747 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
748 size.width > 100 ? 100 : size.width, size.height > 64 ? 64 : size.height,
749 x + (width - size.width) / 2, y + 2);
750
751 {
752 int i, j;
753 int fheight = WMFontHeight(panel->normalfont);
754 int tlen = strlen(text);
755 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
756 int ofx, ofy;
757
758 ofx = x + (width - twidth) / 2;
759 ofy = y + 64 - fheight;
760
761 for (i = -1; i < 2; i++)
762 for (j = -1; j < 2; j++)
763 WMDrawString(wmscr, d, scr->white, panel->normalfont,
764 ofx + i, ofy + j, text, tlen);
765
766 WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy, text, tlen);
767 }
768
769 WMReleasePixmap(pixmap);
770 /* I hope it is better to do not use cache / on my box it is fast nuff */
771 XFlush(dpy);
c8e0f416 id1999-10-02 19:16:27 +0000772}
9d2e6ef9 scottc1998-09-29 22:36:29 +0000773
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200774static void buttonCallback(void *self, void *clientData)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000775{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200776 WMButton *bPtr = (WMButton *) self;
777 IconPanel *panel = (IconPanel *) clientData;
778
779 if (bPtr == panel->okButton) {
780 panel->done = True;
781 panel->result = True;
782 } else if (bPtr == panel->cancelButton) {
783 panel->done = True;
784 panel->result = False;
785 } else if (bPtr == panel->previewButton) {
786 /**** Previewer ****/
787 WMSetButtonEnabled(bPtr, False);
788 WMSetListUserDrawItemHeight(panel->iconList, 68);
789 WMSetListUserDrawProc(panel->iconList, drawIconProc);
790 WMRedisplayWidget(panel->iconList);
791 /* for draw proc to access screen/gc */
792 /*** end preview ***/
793 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000794#if 0
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200795 else if (bPtr == panel->chooseButton) {
796 WMOpenPanel *op;
797
798 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
799
800 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
801 char *path;
802 path = WMGetFilePanelFile(op);
803 WMSetTextFieldText(panel->fileField, path);
804 setViewedImage(panel, path);
805 wfree(path);
806 }
807 WMDestroyFilePanel(op);
808 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000809#endif
810}
811
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200812static void keyPressHandler(XEvent * event, void *data)
57bc9c54 kojima2001-02-17 22:46:29 +0000813{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200814 IconPanel *panel = (IconPanel *) data;
815 char buffer[32];
816 int count;
817 KeySym ksym;
818 int iidx;
819 int didx;
820 int item = 0;
821 WMList *list = NULL;
822
823 if (event->type == KeyRelease)
824 return;
825
826 buffer[0] = 0;
827 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
828
829 iidx = WMGetListSelectedItemRow(panel->iconList);
830 didx = WMGetListSelectedItemRow(panel->dirList);
831
832 switch (ksym) {
833 case XK_Up:
834 if (iidx > 0)
835 item = iidx - 1;
836 else
837 item = iidx;
838 list = panel->iconList;
839 break;
840 case XK_Down:
841 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
842 item = iidx + 1;
843 else
844 item = iidx;
845 list = panel->iconList;
846 break;
847 case XK_Home:
848 item = 0;
849 list = panel->iconList;
850 break;
851 case XK_End:
852 item = WMGetListNumberOfRows(panel->iconList) - 1;
853 list = panel->iconList;
854 break;
855 case XK_Next:
856 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
857 item = didx + 1;
858 else
859 item = didx;
860 list = panel->dirList;
861 break;
862 case XK_Prior:
863 if (didx > 0)
864 item = didx - 1;
865 else
866 item = 0;
867 list = panel->dirList;
868 break;
869 case XK_Return:
870 WMPerformButtonClick(panel->okButton);
871 break;
872 case XK_Escape:
873 WMPerformButtonClick(panel->cancelButton);
874 break;
875 }
876
877 if (list) {
878 WMSelectListItem(list, item);
879 WMSetListPosition(list, item - 5);
880 listCallback(list, panel);
881 }
57bc9c54 kojima2001-02-17 22:46:29 +0000882}
883
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200884Bool wIconChooserDialog(WScreen * scr, char **file, char *instance, char *class)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000885{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200886 WWindow *wwin;
887 Window parent;
888 IconPanel *panel;
889 WMColor *color;
890 WMFont *boldFont;
891 Bool result;
892
893 panel = wmalloc(sizeof(IconPanel));
894 memset(panel, 0, sizeof(IconPanel));
895
896 panel->scr = scr;
897
898 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
899 WMResizeWidget(panel->win, 450, 280);
900
901 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask | KeyReleaseMask, keyPressHandler, panel);
902
903 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
904 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
905
906 panel->dirLabel = WMCreateLabel(panel->win);
907 WMResizeWidget(panel->dirLabel, 200, 20);
908 WMMoveWidget(panel->dirLabel, 10, 7);
909 WMSetLabelText(panel->dirLabel, _("Directories"));
910 WMSetLabelFont(panel->dirLabel, boldFont);
911 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
912
913 WMSetLabelRelief(panel->dirLabel, WRSunken);
914
915 panel->iconLabel = WMCreateLabel(panel->win);
916 WMResizeWidget(panel->iconLabel, 140, 20);
917 WMMoveWidget(panel->iconLabel, 215, 7);
918 WMSetLabelText(panel->iconLabel, _("Icons"));
919 WMSetLabelFont(panel->iconLabel, boldFont);
920 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
921
922 WMReleaseFont(boldFont);
923
924 color = WMWhiteColor(scr->wmscreen);
925 WMSetLabelTextColor(panel->dirLabel, color);
926 WMSetLabelTextColor(panel->iconLabel, color);
927 WMReleaseColor(color);
928
929 color = WMDarkGrayColor(scr->wmscreen);
930 WMSetWidgetBackgroundColor(panel->iconLabel, color);
931 WMSetWidgetBackgroundColor(panel->dirLabel, color);
932 WMReleaseColor(color);
933
934 WMSetLabelRelief(panel->iconLabel, WRSunken);
935
936 panel->dirList = WMCreateList(panel->win);
937 WMResizeWidget(panel->dirList, 200, 170);
938 WMMoveWidget(panel->dirList, 10, 30);
939 WMSetListAction(panel->dirList, listCallback, panel);
940
941 panel->iconList = WMCreateList(panel->win);
942 WMResizeWidget(panel->iconList, 140, 170);
943 WMMoveWidget(panel->iconList, 215, 30);
944 WMSetListAction(panel->iconList, listCallback, panel);
945
946 WMHangData(panel->iconList, panel);
947
948 panel->previewButton = WMCreateCommandButton(panel->win);
949 WMResizeWidget(panel->previewButton, 75, 26);
950 WMMoveWidget(panel->previewButton, 365, 130);
951 WMSetButtonText(panel->previewButton, _("Preview"));
952 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
953
954 panel->iconView = WMCreateLabel(panel->win);
955 WMResizeWidget(panel->iconView, 75, 75);
956 WMMoveWidget(panel->iconView, 365, 40);
957 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
958 WMSetLabelRelief(panel->iconView, WRSunken);
959 WMSetLabelTextAlignment(panel->iconView, WACenter);
960
961 panel->fileLabel = WMCreateLabel(panel->win);
962 WMResizeWidget(panel->fileLabel, 80, 20);
963 WMMoveWidget(panel->fileLabel, 10, 210);
964 WMSetLabelText(panel->fileLabel, _("File Name:"));
965
966 panel->fileField = WMCreateTextField(panel->win);
967 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
968 WMResizeWidget(panel->fileField, 345, 20);
969 WMMoveWidget(panel->fileField, 95, 210);
970 WMSetTextFieldEditable(panel->fileField, False);
971
972 panel->okButton = WMCreateCommandButton(panel->win);
973 WMResizeWidget(panel->okButton, 80, 26);
974 WMMoveWidget(panel->okButton, 360, 240);
975 WMSetButtonText(panel->okButton, _("OK"));
976 WMSetButtonEnabled(panel->okButton, False);
977 WMSetButtonAction(panel->okButton, buttonCallback, panel);
978
979 panel->cancelButton = WMCreateCommandButton(panel->win);
980 WMResizeWidget(panel->cancelButton, 80, 26);
981 WMMoveWidget(panel->cancelButton, 270, 240);
982 WMSetButtonText(panel->cancelButton, _("Cancel"));
983 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000984#if 0
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200985 panel->chooseButton = WMCreateCommandButton(panel->win);
986 WMResizeWidget(panel->chooseButton, 110, 26);
987 WMMoveWidget(panel->chooseButton, 150, 240);
988 WMSetButtonText(panel->chooseButton, _("Choose File"));
989 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000990#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200991 WMRealizeWidget(panel->win);
992 WMMapSubwidgets(panel->win);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000993
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200994 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000995
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200996 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000997
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200998 {
999 char *tmp;
1000 int len = (instance ? strlen(instance) : 0)
1001 + (class ? strlen(class) : 0) + 32;
1002 WMPoint center;
6830b057 dan2004-10-12 21:28:27 +00001003
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001004 tmp = wmalloc(len);
6830b057 dan2004-10-12 21:28:27 +00001005
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001006 if (tmp && (instance || class))
1007 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
1008 else
1009 strcpy(tmp, _("Icon Chooser"));
6830b057 dan2004-10-12 21:28:27 +00001010
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001011 center = getCenter(scr, 450, 280);
6830b057 dan2004-10-12 21:28:27 +00001012
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001013 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x, center.y, 450, 280);
1014 wfree(tmp);
1015 }
ab61c599 dan2001-05-13 23:22:21 +00001016
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001017 /* put icon paths in the list */
1018 listIconPaths(panel->dirList);
ab61c599 dan2001-05-13 23:22:21 +00001019
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001020 WMMapWidget(panel->win);
ab61c599 dan2001-05-13 23:22:21 +00001021
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001022 wWindowMap(wwin);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001023
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001024 while (!panel->done) {
1025 XEvent event;
ab61c599 dan2001-05-13 23:22:21 +00001026
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001027 WMNextEvent(dpy, &event);
1028 WMHandleEvent(&event);
1029 }
ab61c599 dan2001-05-13 23:22:21 +00001030
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001031 if (panel->result) {
1032 char *defaultPath, *wantedPath;
6830b057 dan2004-10-12 21:28:27 +00001033
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001034 /* check if the file the user selected is not the one that
1035 * would be loaded by default with the current search path */
1036 *file = WMGetListSelectedItem(panel->iconList)->text;
1037 if (**file == 0) {
1038 wfree(*file);
1039 *file = NULL;
1040 } else {
1041 defaultPath = FindImage(wPreferences.icon_path, *file);
1042 wantedPath = WMGetTextFieldText(panel->fileField);
1043 /* if the file is not the default, use full path */
1044 if (strcmp(wantedPath, defaultPath) != 0) {
1045 *file = wantedPath;
1046 } else {
1047 *file = wstrdup(*file);
1048 wfree(wantedPath);
1049 }
1050 wfree(defaultPath);
1051 }
1052 } else {
1053 *file = NULL;
1054 }
9d2e6ef9 scottc1998-09-29 22:36:29 +00001055
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001056 result = panel->result;
9aca0d5f dan2004-10-12 01:34:32 +00001057
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001058 WMReleaseFont(panel->normalfont);
c8e0f416 id1999-10-02 19:16:27 +00001059
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001060 WMUnmapWidget(panel->win);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001061
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001062 WMDestroyWidget(panel->win);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001063
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001064 wUnmanageWindow(wwin, False, False);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001065
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001066 wfree(panel);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001067
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001068 XDestroyWindow(dpy, parent);
ab61c599 dan2001-05-13 23:22:21 +00001069
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001070 return result;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001071}
1072
9d2e6ef9 scottc1998-09-29 22:36:29 +00001073/*
1074 ***********************************************************************
1075 * Info Panel
1076 ***********************************************************************
1077 */
1078
9d2e6ef9 scottc1998-09-29 22:36:29 +00001079typedef struct {
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001080 WScreen *scr;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001081
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001082 WWindow *wwin;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001083
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001084 WMWindow *win;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001085
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001086 WMLabel *logoL;
1087 WMLabel *name1L;
1088 WMFrame *lineF;
1089 WMLabel *name2L;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001090
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001091 WMLabel *versionL;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001092
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001093 WMLabel *infoL;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001094
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001095 WMLabel *copyrL;
0261c326 dan1999-01-06 15:22:33 +00001096
1097#ifdef SILLYNESS
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001098 WMHandlerID timer;
1099 int cycle;
1100 RImage *icon;
1101 RImage *pic;
1102 WMPixmap *oldPix;
1103 WMFont *oldFont;
1104 char *str;
1105 int x;
0261c326 dan1999-01-06 15:22:33 +00001106#endif
9d2e6ef9 scottc1998-09-29 22:36:29 +00001107} InfoPanel;
1108
9d2e6ef9 scottc1998-09-29 22:36:29 +00001109#define COPYRIGHT_TEXT \
42191340 dan2006-04-25 18:59:24 +00001110 "Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
1111 "Copyright \xc2\xa9 1998-2006 Dan Pascu"
9d2e6ef9 scottc1998-09-29 22:36:29 +00001112
9d2e6ef9 scottc1998-09-29 22:36:29 +00001113static InfoPanel *thePanel = NULL;
1114
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001115static void destroyInfoPanel(WCoreWindow * foo, void *data, XEvent * event)
9d2e6ef9 scottc1998-09-29 22:36:29 +00001116{
0261c326 dan1999-01-06 15:22:33 +00001117#ifdef SILLYNESS
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001118 if (thePanel->timer) {
1119 WMDeleteTimerHandler(thePanel->timer);
1120 }
1121 if (thePanel->oldPix) {
1122 WMReleasePixmap(thePanel->oldPix);
1123 }
1124 if (thePanel->oldFont) {
1125 WMReleaseFont(thePanel->oldFont);
1126 }
1127 if (thePanel->icon) {
1128 RReleaseImage(thePanel->icon);
1129 }
1130 if (thePanel->pic) {
1131 RReleaseImage(thePanel->pic);
1132 }
1133#endif /* SILLYNESS */
1134 WMUnmapWidget(thePanel);
1135
1136 wUnmanageWindow(thePanel->wwin, False, False);
1137
1138 WMDestroyWidget(thePanel->win);
1139
1140 wfree(thePanel);
1141
1142 thePanel = NULL;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001143}
1144
0261c326 dan1999-01-06 15:22:33 +00001145#ifdef SILLYNESS
416e3a82 dan1999-01-25 19:06:50 +00001146
1147extern WMPixmap *DoXThing();
1148extern Bool InitXThing();
1149
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001150static void logoPushCallback(void *data)
0261c326 dan1999-01-06 15:22:33 +00001151{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001152 InfoPanel *panel = (InfoPanel *) data;
1153 char buffer[512];
1154 int i;
1155 static int oldi = 0;
1156 int len;
1157 static int jingobeu[] = {
1158 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
1159 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
1160 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
1161 };
1162 static int c = 0;
1163
1164 if (panel->x) {
1165 XKeyboardControl kc;
1166 XKeyboardState ksave;
1167 unsigned long mask = KBBellPitch | KBBellDuration | KBBellPercent;
1168
1169 XGetKeyboardControl(dpy, &ksave);
1170
1171 if (panel->x > 0) {
1172 if (jingobeu[panel->x - 1] == 0) {
1173 panel->x = -1;
1174 } else if (jingobeu[panel->x - 1] < 0) {
1175 panel->x++;
1176 c = jingobeu[panel->x - 1] / 50;
1177 panel->x++;
1178 } else if (c == 0) {
1179 kc.bell_percent = 50;
1180 kc.bell_pitch = jingobeu[panel->x - 1];
1181 panel->x++;
1182 kc.bell_duration = jingobeu[panel->x - 1];
1183 c = jingobeu[panel->x - 1] / 50;
1184 panel->x++;
1185 XChangeKeyboardControl(dpy, mask, &kc);
1186 XBell(dpy, 50);
1187 XFlush(dpy);
1188 } else {
1189 c--;
1190 }
1191 }
1192 if (!(panel->cycle % 4)) {
1193 WMPixmap *p;
1194
1195 p = DoXThing(panel->wwin);
1196 WMSetLabelImage(panel->logoL, p);
1197 }
1198 kc.bell_pitch = ksave.bell_pitch;
1199 kc.bell_percent = ksave.bell_percent;
1200 kc.bell_duration = ksave.bell_duration;
1201 XChangeKeyboardControl(dpy, mask, &kc);
1202 } else if (panel->cycle < 30) {
1203 RImage *image;
1204 WMPixmap *pix;
1205 RColor gray;
1206
1207 gray.red = 0xae;
1208 gray.green = 0xaa;
1209 gray.blue = 0xae;
1210 gray.alpha = 0;
1211
1212 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
1213 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle * 255 / 30);
1214 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
1215 RReleaseImage(image);
1216 WMSetLabelImage(panel->logoL, pix);
1217 WMReleasePixmap(pix);
1218 }
1219
1220 /* slow down text a little */
1221 i = (int)(panel->cycle * 50.0 / 85.0) % 200;
1222
1223 if (i != oldi) {
1224 len = strlen(panel->str);
1225
1226 strncpy(buffer, panel->str, i < len ? i : len);
1227 if (i >= len)
1228 memset(&buffer[len], ' ', i - len);
1229
1230 strncpy(buffer, panel->str, i < len ? i : len);
1231 if (i >= len)
1232 memset(&buffer[len], ' ', i - len);
1233 buffer[i] = 0;
1234
1235 WMSetLabelText(panel->versionL, buffer);
1236
1237 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1238
1239 oldi = i;
1240 }
1241
1242 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1243 panel->cycle++;
0261c326 dan1999-01-06 15:22:33 +00001244}
1245
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001246static void handleLogoPush(XEvent * event, void *data)
0261c326 dan1999-01-06 15:22:33 +00001247{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001248 InfoPanel *panel = (InfoPanel *) data;
1249 static int broken = 0;
1250 static int clicks = 0;
1251 static char *pic_data[] = {
1252 "45 45 57 1",
1253 " c None",
1254 ". c #000000",
1255 "X c #383C00",
1256 "o c #515500",
1257 "O c #616100",
1258 "+ c #616900",
1259 "@ c #696D00",
1260 "# c #697100",
1261 "$ c #495100",
1262 "% c #202800",
1263 "& c #969600",
1264 "* c #CFCF00",
1265 "= c #D7DB00",
1266 "- c #D7D700",
1267 "; c #C7CB00",
1268 ": c #A6AA00",
1269 "> c #494900",
1270 ", c #8E8E00",
1271 "< c #DFE700",
1272 "1 c #F7FF00",
1273 "2 c #FFFF00",
1274 "3 c #E7EB00",
1275 "4 c #B6B600",
1276 "5 c #595900",
1277 "6 c #717500",
1278 "7 c #AEB200",
1279 "8 c #CFD300",
1280 "9 c #E7EF00",
1281 "0 c #EFF300",
1282 "q c #9EA200",
1283 "w c #F7FB00",
1284 "e c #F7F700",
1285 "r c #BEBE00",
1286 "t c #8E9200",
1287 "y c #EFF700",
1288 "u c #969A00",
1289 "i c #414500",
1290 "p c #595D00",
1291 "a c #E7E700",
1292 "s c #C7C700",
1293 "d c #797D00",
1294 "f c #BEC300",
1295 "g c #DFE300",
1296 "h c #868600",
1297 "j c #EFEF00",
1298 "k c #9E9E00",
1299 "l c #616500",
1300 "z c #DFDF00",
1301 "x c #868A00",
1302 "c c #969200",
1303 "v c #B6BA00",
1304 "b c #A6A600",
1305 "n c #8E8A00",
1306 "m c #717100",
1307 "M c #AEAE00",
1308 "N c #AEAA00",
1309 "B c #868200",
1310 " ............... ",
1311 " ....XoO+@##+O$%.... ",
1312 " ...%X&*========-;;:o... ",
1313 " ...>.>,<122222222222134@... ",
1314 " ..>5678912222222222222220q%.. ",
1315 " ..$.&-w2222222222222222222er>.. ",
1316 " ..O.t31222222222222222222222y4>.. ",
1317 " ...O5u3222222222222222222222222yri... ",
1318 " ..>p&a22222222222222222222222222wso.. ",
1319 " ..ids91222222222222222222222222222wfi.. ",
1320 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1321 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1322 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1323 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1324 "..io*222222222&...u22222222yt..%*22222220:%. ",
1325 "..>k02222222227...f222222222v..X=222222229t. ",
1326 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1327 ".%vw222222222221y2222222222219*y2222222222wd.",
1328 ".X;2222222222222222222222222222222222222222b.",
1329 ".i*2222222222222222222222222222222222222222v.",
1330 ".i*2222222222222222222222222222222222222222;.",
1331 ".i*22222222222222222222222222222222222222228.",
1332 ".>*2222222222222222222222222222222222222222=.",
1333 ".i*22222222222222222222222222222222222222228.",
1334 ".i*2222222222222222222222222222222222222222;.",
1335 ".X*222222222222222222222222222222we12222222r.",
1336 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1337 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1338 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1339 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1340 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1341 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1342 " ...:e2222218mdz22222222222222a&$vw222220@...",
1343 " ...O-122222y:.u02222222222229q$uj222221r... ",
1344 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1345 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1346 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1347 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1348 " ..Xb9122222109g-****;<y22221zn%... ",
1349 " ..X&801222222222222222222w-h.... ",
1350 " ...o:=022222222222222221=lX... ",
1351 " ..X@:;3w2222222222210fO... ",
1352 " ...XX&v8<30000003-N@... ",
1353 " .....XmnbN:q&Bo.... ",
1354 " ............ "
1355 };
1356 static char *msgs[] = {
1357 "Have a nice day!",
1358 "Focus follow mouse users will burn in hell!!!",
1359 "Mooo Canada!!!!",
1360 "Hi! My name is bobby...",
1361 "AHH! The neurotic monkeys are after me!",
1362 "WE GET SIGNAL",
1363 "HOW ARE YOU GENTLEMEN?",
1364 "WHAT YOU SAY??",
1365 "SOMEBODY SET UP US THE BOMB",
1366 "ALL YOUR BASE ARE BELONG TO US!",
1367 "Oh My God!!! Larry is back!",
1368 "Alex Perez is aliveeeeeeee!!!"
1369 };
1370
1371 clicks++;
1372
1373 if (!panel->timer && !broken && clicks > 0) {
1374 WMFont *font;
1375
1376 panel->x = 0;
1377 clicks = 0;
1378 if (!panel->icon) {
1379 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1380 if (!panel->icon) {
1381 broken = 1;
1382 return;
1383 } else {
1384 RColor color;
1385
1386 color.red = 0xae;
1387 color.green = 0xaa;
1388 color.blue = 0xae;
1389 color.alpha = 0;
1390
1391 panel->icon = RCloneImage(panel->icon);
1392 RCombineImageWithColor(panel->icon, &color);
1393 }
1394 }
1395 if (!panel->pic) {
1396 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1397 if (!panel->pic) {
1398 broken = 1;
1399 RReleaseImage(panel->icon);
1400 panel->icon = NULL;
1401 return;
1402 }
1403 }
1404
1405 panel->str = msgs[rand() % (sizeof(msgs) / sizeof(char *))];
1406
1407 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1408 panel->cycle = 0;
1409 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1410 /* If we don't use a fixed font, scrolling will be jumpy */
1411 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1412 if ((panel->oldFont = WMGetLabelFont(panel->versionL)) != NULL)
1413 WMRetainFont(panel->oldFont);
1414 font = WMCreateFont(WMWidgetScreen(panel->versionL),
1415 "Lucida Console,Courier New,monospace:pixelsize=12");
1416 if (font) {
1417 WMSetLabelFont(panel->versionL, font);
1418 WMReleaseFont(font);
1419 }
1420 WMSetLabelText(panel->versionL, "");
1421 } else if (panel->timer) {
1422 char version[20];
1423
1424 panel->x = 0;
1425 clicks = 0;
1426 WMSetLabelImage(panel->logoL, panel->oldPix);
1427 WMReleasePixmap(panel->oldPix);
1428 panel->oldPix = NULL;
1429
1430 WMDeleteTimerHandler(panel->timer);
1431 panel->timer = NULL;
1432
1433 WMSetLabelFont(panel->versionL, panel->oldFont);
1434 if (panel->oldFont) {
1435 WMReleaseFont(panel->oldFont);
1436 panel->oldFont = NULL;
1437 }
1438 snprintf(version, sizeof(version), _("Version %s"), VERSION);
1439 WMSetLabelText(panel->versionL, version);
1440 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1441 }
1442
1443 {
1444 XEvent ev;
1445 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL), ButtonPress, &ev)) ;
1446 }
0261c326 dan1999-01-06 15:22:33 +00001447}
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001448#endif /* SILLYNESS */
9d2e6ef9 scottc1998-09-29 22:36:29 +00001449
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001450void wShowInfoPanel(WScreen * scr)
9d2e6ef9 scottc1998-09-29 22:36:29 +00001451{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001452 InfoPanel *panel;
1453 WMPixmap *logo;
1454 WMSize size;
1455 WMFont *font;
1456 char *strbuf = NULL;
1457 char buffer[256];
1458 char *name;
1459 Window parent;
1460 WWindow *wwin;
1461 char **strl;
1462 int i, width = 50, sepHeight;
1463 char *visuals[] = {
1464 "StaticGray",
1465 "GrayScale",
1466 "StaticColor",
1467 "PseudoColor",
1468 "TrueColor",
1469 "DirectColor"
1470 };
1471
1472 if (thePanel) {
1473 if (thePanel->scr == scr) {
1474 wRaiseFrame(thePanel->wwin->frame->core);
1475 wSetFocusTo(scr, thePanel->wwin);
1476 }
1477 return;
1478 }
1479
1480 panel = wmalloc(sizeof(InfoPanel));
1481 memset(panel, 0, sizeof(InfoPanel));
1482
1483 panel->scr = scr;
1484
1485 panel->win = WMCreateWindow(scr->wmscreen, "info");
1486 WMResizeWidget(panel->win, 390, 230);
1487
1488 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
1489 if (!logo) {
1490 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1491 }
1492 if (logo) {
1493 size = WMGetPixmapSize(logo);
1494 panel->logoL = WMCreateLabel(panel->win);
1495 WMResizeWidget(panel->logoL, 64, 64);
1496 WMMoveWidget(panel->logoL, 30, 20);
1497 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1498 WMSetLabelImage(panel->logoL, logo);
0261c326 dan1999-01-06 15:22:33 +00001499#ifdef SILLYNESS
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001500 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask, handleLogoPush, panel);
0261c326 dan1999-01-06 15:22:33 +00001501#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001502 WMReleasePixmap(logo);
1503 }
1504
1505 sepHeight = 3;
1506 panel->name1L = WMCreateLabel(panel->win);
1507 WMResizeWidget(panel->name1L, 240, 30 + 2);
1508 WMMoveWidget(panel->name1L, 100, 30 - 2 - sepHeight);
1509
1510 name = "Lucida Sans,Comic Sans MS,URW Gothic L,Trebuchet MS" ":italic:pixelsize=28:antialias=true";
1511 font = WMCreateFont(scr->wmscreen, name);
1512 strbuf = "Window Maker";
1513 if (font) {
1514 width = WMWidthOfString(font, strbuf, strlen(strbuf));
1515 WMSetLabelFont(panel->name1L, font);
1516 WMReleaseFont(font);
1517 }
1518 WMSetLabelTextAlignment(panel->name1L, WACenter);
1519 WMSetLabelText(panel->name1L, strbuf);
1520
1521 panel->lineF = WMCreateFrame(panel->win);
1522 WMResizeWidget(panel->lineF, width, sepHeight);
1523 WMMoveWidget(panel->lineF, 100 + (240 - width) / 2, 60 - sepHeight);
1524 WMSetFrameRelief(panel->lineF, WRSimple);
1525 WMSetWidgetBackgroundColor(panel->lineF, scr->black);
1526
1527 panel->name2L = WMCreateLabel(panel->win);
1528 WMResizeWidget(panel->name2L, 240, 24);
1529 WMMoveWidget(panel->name2L, 100, 60);
1530 name = "URW Gothic L,Nimbus Sans L:pixelsize=16:antialias=true";
1531 font = WMCreateFont(scr->wmscreen, name);
1532 if (font) {
1533 WMSetLabelFont(panel->name2L, font);
1534 WMReleaseFont(font);
1535 font = NULL;
1536 }
1537 WMSetLabelTextAlignment(panel->name2L, WACenter);
1538 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1539
1540 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1541 panel->versionL = WMCreateLabel(panel->win);
1542 WMResizeWidget(panel->versionL, 310, 16);
1543 WMMoveWidget(panel->versionL, 30, 95);
1544 WMSetLabelTextAlignment(panel->versionL, WARight);
1545 WMSetLabelText(panel->versionL, buffer);
1546 WMSetLabelWraps(panel->versionL, False);
1547
1548 panel->copyrL = WMCreateLabel(panel->win);
1549 WMResizeWidget(panel->copyrL, 360, 40);
1550 WMMoveWidget(panel->copyrL, 15, 185);
1551 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1552 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1553 font = WMSystemFontOfSize(scr->wmscreen, 11);
1554 if (font) {
1555 WMSetLabelFont(panel->copyrL, font);
1556 WMReleaseFont(font);
1557 font = NULL;
1558 }
1559
1560 strbuf = NULL;
1561 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1562 (unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
1563
1564 strbuf = wstrappend(strbuf, buffer);
1565
1566 switch (scr->w_depth) {
1567 case 15:
1568 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1569 break;
1570 case 16:
1571 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1572 break;
1573 case 24:
1574 case 32:
1575 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1576 break;
1577 default:
1578 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1 << scr->w_depth);
1579 strbuf = wstrappend(strbuf, buffer);
1580 break;
1581 }
9af1c6c4 dan1998-10-21 14:43:47 +00001582
9aa1d138 kojima2000-04-09 23:55:46 +00001583#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001584 {
1585 struct mallinfo ma = mallinfo();
1586 snprintf(buffer, sizeof(buffer),
1587 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1588 (ma.arena + ma.hblkhd) / 1024, (ma.uordblks + ma.hblkhd) / 1024);
1589
1590 strbuf = wstrappend(strbuf, buffer);
1591 }
9aa1d138 kojima2000-04-09 23:55:46 +00001592#endif
ab61c599 dan2001-05-13 23:22:21 +00001593
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001594 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1595 strl = RSupportedFileFormats();
1596 for (i = 0; strl[i] != NULL; i++) {
1597 strbuf = wstrappend(strbuf, strl[i]);
1598 strbuf = wstrappend(strbuf, " ");
1599 }
0261c326 dan1999-01-06 15:22:33 +00001600
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001601 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1602 {
1603 char *list[9];
1604 char buf[80];
1605 int j = 0;
0261c326 dan1999-01-06 15:22:33 +00001606
9aca0d5f dan2004-10-12 01:34:32 +00001607#ifdef NETWM_HINTS
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001608 list[j++] = "WMSPEC";
9aca0d5f dan2004-10-12 01:34:32 +00001609#endif
0c09179f dan2004-10-14 23:05:20 +00001610#ifdef MWM_HINTS
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001611 list[j++] = "MWM";
0c09179f dan2004-10-14 23:05:20 +00001612#endif
9d2e6ef9 scottc1998-09-29 22:36:29 +00001613
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001614 buf[0] = 0;
1615 for (i = 0; i < j; i++) {
1616 if (i > 0) {
1617 if (i == j - 1)
1618 strcat(buf, _(" and "));
1619 else
1620 strcat(buf, ", ");
1621 }
1622 strcat(buf, list[i]);
1623 }
1624 strbuf = wstrappend(strbuf, buf);
1625 }
1626
1627 if (wPreferences.no_sound) {
1628 strbuf = wstrappend(strbuf, _("\nSound disabled"));
1629 } else {
1630 strbuf = wstrappend(strbuf, _("\nSound enabled"));
1631 }
430c12e2 dan2001-05-13 00:28:55 +00001632
9aca0d5f dan2004-10-12 01:34:32 +00001633#ifdef VIRTUAL_DESKTOP
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001634 if (wPreferences.vdesk_enable)
1635 strbuf = wstrappend(strbuf, _(", VirtualDesktop enabled"));
1636 else
1637 strbuf = wstrappend(strbuf, _(", VirtualDesktop disabled"));
9aca0d5f dan2004-10-12 01:34:32 +00001638#endif
1639
1640#ifdef XINERAMA
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001641 strbuf = wstrappend(strbuf, _("\n"));
9aca0d5f dan2004-10-12 01:34:32 +00001642#ifdef SOLARIS_XINERAMA
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001643 strbuf = wstrappend(strbuf, _("Solaris "));
9aca0d5f dan2004-10-12 01:34:32 +00001644#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001645 strbuf = wstrappend(strbuf, _("Xinerama: "));
1646 {
1647 char tmp[128];
1648 snprintf(tmp, sizeof(tmp) - 1, "%d heads found.", scr->xine_info.count);
1649 strbuf = wstrappend(strbuf, tmp);
1650 }
9aca0d5f dan2004-10-12 01:34:32 +00001651#endif
1652
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001653 panel->infoL = WMCreateLabel(panel->win);
1654 WMResizeWidget(panel->infoL, 350, 75);
1655 WMMoveWidget(panel->infoL, 15, 115);
1656 WMSetLabelText(panel->infoL, strbuf);
1657 font = WMSystemFontOfSize(scr->wmscreen, 11);
1658 if (font) {
1659 WMSetLabelFont(panel->infoL, font);
1660 WMReleaseFont(font);
1661 font = NULL;
1662 }
1663 wfree(strbuf);
0261c326 dan1999-01-06 15:22:33 +00001664
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001665 WMRealizeWidget(panel->win);
1666 WMMapSubwidgets(panel->win);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001667
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001668 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
ab61c599 dan2001-05-13 23:22:21 +00001669
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001670 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001671
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001672 WMMapWidget(panel->win);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001673
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001674 {
1675 WMPoint center = getCenter(scr, 382, 230);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001676
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001677 wwin = wManageInternalWindow(scr, parent, None, _("Info"), center.x, center.y, 382, 230);
1678 }
9d2e6ef9 scottc1998-09-29 22:36:29 +00001679
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001680 WSETUFLAG(wwin, no_closable, 0);
1681 WSETUFLAG(wwin, no_close_button, 0);
c28f3b2c id1999-05-20 23:30:53 +00001682#ifdef XKB_BUTTON_HINT
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001683 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
c28f3b2c id1999-05-20 23:30:53 +00001684#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001685 wWindowUpdateButtonImages(wwin);
1686 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1687 wwin->frame->on_click_right = destroyInfoPanel;
ab61c599 dan2001-05-13 23:22:21 +00001688
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001689 wWindowMap(wwin);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001690
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001691 panel->wwin = wwin;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001692
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001693 thePanel = panel;
7f9f8894 kojima1999-03-15 23:41:22 +00001694#ifdef SILLYNESS
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001695 if (InitXThing(panel->scr)) {
1696 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1697 panel->cycle = 0;
1698 panel->x = 1;
1699 panel->str = _("Merry Christmas!");
1700 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1701 }
e7495baf dan1999-02-17 11:06:40 +00001702#endif
9d2e6ef9 scottc1998-09-29 22:36:29 +00001703}
1704
9d2e6ef9 scottc1998-09-29 22:36:29 +00001705/*
1706 ***********************************************************************
1707 * Legal Panel
1708 ***********************************************************************
1709 */
1710
1711typedef struct {
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001712 WScreen *scr;
ab61c599 dan2001-05-13 23:22:21 +00001713
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001714 WWindow *wwin;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001715
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001716 WMWindow *win;
ab61c599 dan2001-05-13 23:22:21 +00001717
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001718 WMLabel *licenseL;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001719} LegalPanel;
1720
9d2e6ef9 scottc1998-09-29 22:36:29 +00001721static LegalPanel *legalPanel = NULL;
1722
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001723static void destroyLegalPanel(WCoreWindow * foo, void *data, XEvent * event)
9d2e6ef9 scottc1998-09-29 22:36:29 +00001724{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001725 WMUnmapWidget(legalPanel->win);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001726
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001727 WMDestroyWidget(legalPanel->win);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001728
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001729 wUnmanageWindow(legalPanel->wwin, False, False);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001730
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001731 wfree(legalPanel);
ab61c599 dan2001-05-13 23:22:21 +00001732
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001733 legalPanel = NULL;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001734}
1735
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001736void wShowLegalPanel(WScreen * scr)
9d2e6ef9 scottc1998-09-29 22:36:29 +00001737{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001738 LegalPanel *panel;
1739 Window parent;
1740 WWindow *wwin;
1741
1742 if (legalPanel) {
1743 if (legalPanel->scr == scr) {
1744 wRaiseFrame(legalPanel->wwin->frame->core);
1745 wSetFocusTo(scr, legalPanel->wwin);
1746 }
1747 return;
1748 }
1749
1750 panel = wmalloc(sizeof(LegalPanel));
1751
1752 panel->scr = scr;
1753
1754 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1755 WMResizeWidget(panel->win, 420, 250);
1756
1757 panel->licenseL = WMCreateLabel(panel->win);
1758 WMSetLabelWraps(panel->licenseL, True);
1759 WMResizeWidget(panel->licenseL, 400, 230);
1760 WMMoveWidget(panel->licenseL, 10, 10);
1761 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1762 WMSetLabelText(panel->licenseL,
1763 _(" Window Maker is free software; you can redistribute it and/or\n"
1764 "modify it under the terms of the GNU General Public License as\n"
1765 "published by the Free Software Foundation; either version 2 of the\n"
1766 "License, or (at your option) any later version.\n\n"
1767 " Window Maker is distributed in the hope that it will be useful,\n"
1768 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1769 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1770 "See the GNU General Public License for more details.\n\n"
1771 " You should have received a copy of the GNU General Public\n"
1772 "License along with this program; if not, write to the Free Software\n"
1773 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n" "02111-1307, USA."));
1774 WMSetLabelRelief(panel->licenseL, WRGroove);
1775
1776 WMRealizeWidget(panel->win);
1777 WMMapSubwidgets(panel->win);
1778
1779 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1780
1781 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1782
1783 {
1784 WMPoint center = getCenter(scr, 420, 250);
1785
1786 wwin = wManageInternalWindow(scr, parent, None, _("Legal"), center.x, center.y, 420, 250);
1787 }
1788
1789 WSETUFLAG(wwin, no_closable, 0);
1790 WSETUFLAG(wwin, no_close_button, 0);
1791 wWindowUpdateButtonImages(wwin);
1792 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
c28f3b2c id1999-05-20 23:30:53 +00001793#ifdef XKB_BUTTON_HINT
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001794 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
c28f3b2c id1999-05-20 23:30:53 +00001795#endif
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001796 wwin->frame->on_click_right = destroyLegalPanel;
ab61c599 dan2001-05-13 23:22:21 +00001797
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001798 panel->wwin = wwin;
ab61c599 dan2001-05-13 23:22:21 +00001799
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001800 WMMapWidget(panel->win);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001801
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001802 wWindowMap(wwin);
9d2e6ef9 scottc1998-09-29 22:36:29 +00001803
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001804 legalPanel = panel;
9d2e6ef9 scottc1998-09-29 22:36:29 +00001805}
1806
52917e53 dan1999-04-16 20:05:26 +00001807/*
1808 ***********************************************************************
1809 * Crashing Dialog Panel
1810 ***********************************************************************
1811 */
1812
1813extern WDDomain *WDWindowAttributes;
1814
52917e53 dan1999-04-16 20:05:26 +00001815typedef struct _CrashPanel {
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001816 WMWindow *win; /* main window */
52917e53 dan1999-04-16 20:05:26 +00001817
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001818 WMLabel *iconL; /* application icon */
1819 WMLabel *nameL; /* title of panel */
52917e53 dan1999-04-16 20:05:26 +00001820
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001821 WMFrame *sepF; /* separator frame */
52917e53 dan1999-04-16 20:05:26 +00001822
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001823 WMLabel *noteL; /* Title of note */
1824 WMLabel *note2L; /* body of note with what happened */
52917e53 dan1999-04-16 20:05:26 +00001825
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001826 WMFrame *whatF; /* "what to do next" frame */
1827 WMPopUpButton *whatP; /* action selection popup button */
52917e53 dan1999-04-16 20:05:26 +00001828
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001829 WMButton *okB; /* ok button */
52917e53 dan1999-04-16 20:05:26 +00001830
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001831 Bool done; /* if finished with this dialog */
1832 int action; /* what to do after */
52917e53 dan1999-04-16 20:05:26 +00001833
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001834 KeyCode retKey;
52917e53 dan1999-04-16 20:05:26 +00001835
1836} CrashPanel;
1837
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001838static void handleKeyPress(XEvent * event, void *clientData)
52917e53 dan1999-04-16 20:05:26 +00001839{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001840 CrashPanel *panel = (CrashPanel *) clientData;
52917e53 dan1999-04-16 20:05:26 +00001841
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001842 if (event->xkey.keycode == panel->retKey) {
1843 WMPerformButtonClick(panel->okB);
1844 }
52917e53 dan1999-04-16 20:05:26 +00001845}
1846
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001847static void okButtonCallback(void *self, void *clientData)
52917e53 dan1999-04-16 20:05:26 +00001848{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001849 CrashPanel *panel = (CrashPanel *) clientData;
52917e53 dan1999-04-16 20:05:26 +00001850
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001851 panel->done = True;
52917e53 dan1999-04-16 20:05:26 +00001852}
1853
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001854static void setCrashAction(void *self, void *clientData)
52917e53 dan1999-04-16 20:05:26 +00001855{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001856 WMPopUpButton *pop = (WMPopUpButton *) self;
1857 CrashPanel *panel = (CrashPanel *) clientData;
52917e53 dan1999-04-16 20:05:26 +00001858
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001859 panel->action = WMGetPopUpButtonSelectedItem(pop);
52917e53 dan1999-04-16 20:05:26 +00001860}
1861
0d9b73cd dan2004-10-25 02:23:41 +00001862/* Make this read the logo from a compiled in pixmap -Dan */
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001863static WMPixmap *getWindowMakerIconImage(WMScreen * scr)
52917e53 dan1999-04-16 20:05:26 +00001864{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001865 WMPropList *dict, *key, *option, *value = NULL;
1866 WMPixmap *pix = NULL;
1867 char *path;
52917e53 dan1999-04-16 20:05:26 +00001868
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001869 if (!WDWindowAttributes || !WDWindowAttributes->dictionary)
1870 return NULL;
0d9b73cd dan2004-10-25 02:23:41 +00001871
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001872 WMPLSetCaseSensitive(True);
52917e53 dan1999-04-16 20:05:26 +00001873
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001874 key = WMCreatePLString("Logo.WMPanel");
1875 option = WMCreatePLString("Icon");
52917e53 dan1999-04-16 20:05:26 +00001876
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001877 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
52917e53 dan1999-04-16 20:05:26 +00001878
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001879 if (dict) {
1880 value = WMGetFromPLDictionary(dict, option);
1881 }
52917e53 dan1999-04-16 20:05:26 +00001882
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001883 WMReleasePropList(key);
1884 WMReleasePropList(option);
52917e53 dan1999-04-16 20:05:26 +00001885
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001886 WMPLSetCaseSensitive(False);
52917e53 dan1999-04-16 20:05:26 +00001887
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001888 if (value && WMIsPLString(value)) {
1889 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
52917e53 dan1999-04-16 20:05:26 +00001890
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001891 if (path) {
1892 RColor gray;
52917e53 dan1999-04-16 20:05:26 +00001893
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001894 gray.red = 0xae;
1895 gray.green = 0xaa;
1896 gray.blue = 0xae;
1897 gray.alpha = 0;
36e46831 dan2001-04-21 07:12:21 +00001898
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001899 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1900 wfree(path);
1901 }
1902 }
52917e53 dan1999-04-16 20:05:26 +00001903
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001904 return pix;
52917e53 dan1999-04-16 20:05:26 +00001905}
1906
52917e53 dan1999-04-16 20:05:26 +00001907#define PWIDTH 295
1908#define PHEIGHT 345
1909
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001910int wShowCrashingDialogPanel(int whatSig)
52917e53 dan1999-04-16 20:05:26 +00001911{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001912 CrashPanel *panel;
1913 WMScreen *scr;
1914 WMFont *font;
1915 WMPixmap *logo;
1916 int screen_no, scr_width, scr_height;
1917 int action;
1918 char buf[256];
1919
1920 panel = wmalloc(sizeof(CrashPanel));
1921 memset(panel, 0, sizeof(CrashPanel));
1922
1923 screen_no = DefaultScreen(dpy);
1924 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1925 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1926
1927 scr = WMCreateScreen(dpy, screen_no);
1928 if (!scr) {
1929 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1930 return WMAbort;
1931 }
1932
1933 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1934
1935 panel->win = WMCreateWindow(scr, "crashingDialog");
1936 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1937 WMMoveWidget(panel->win, (scr_width - PWIDTH) / 2, (scr_height - PHEIGHT) / 2);
1938
1939 logo = getWindowMakerIconImage(scr);
1940 if (logo) {
1941 panel->iconL = WMCreateLabel(panel->win);
1942 WMResizeWidget(panel->iconL, 64, 64);
1943 WMMoveWidget(panel->iconL, 10, 10);
1944 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1945 WMSetLabelImage(panel->iconL, logo);
1946 }
1947
1948 panel->nameL = WMCreateLabel(panel->win);
1949 WMResizeWidget(panel->nameL, 200, 30);
1950 WMMoveWidget(panel->nameL, 80, 25);
1951 WMSetLabelTextAlignment(panel->nameL, WALeft);
1952 font = WMBoldSystemFontOfSize(scr, 24);
1953 WMSetLabelFont(panel->nameL, font);
1954 WMReleaseFont(font);
1955 WMSetLabelText(panel->nameL, _("Fatal error"));
1956
1957 panel->sepF = WMCreateFrame(panel->win);
1958 WMResizeWidget(panel->sepF, PWIDTH + 4, 2);
1959 WMMoveWidget(panel->sepF, -2, 80);
1960
1961 panel->noteL = WMCreateLabel(panel->win);
1962 WMResizeWidget(panel->noteL, PWIDTH - 20, 40);
1963 WMMoveWidget(panel->noteL, 10, 90);
1964 WMSetLabelTextAlignment(panel->noteL, WAJustified);
52917e53 dan1999-04-16 20:05:26 +00001965#ifdef SYS_SIGLIST_DECLARED
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001966 snprintf(buf, sizeof(buf), _("Window Maker received signal %i\n(%s)."), whatSig, sys_siglist[whatSig]);
52917e53 dan1999-04-16 20:05:26 +00001967#else
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02001968 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
52917e53 dan1999-04-16 20:05:26 +00001969#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02001970 WMSetLabelText(panel->noteL, buf);
1971
1972 panel->note2L = WMCreateLabel(panel->win);
1973 WMResizeWidget(panel->note2L, PWIDTH - 20, 100);
1974 WMMoveWidget(panel->note2L, 10, 130);
1975 WMSetLabelTextAlignment(panel->note2L, WALeft);
1976 WMSetLabelText(panel->note2L,
1977 _(" This fatal error occured probably due to a bug."
1978 " Please fill the included BUGFORM and " "report it to bugs@windowmaker.info."));
1979 WMSetLabelWraps(panel->note2L, True);
1980
1981 panel->whatF = WMCreateFrame(panel->win);
1982 WMResizeWidget(panel->whatF, PWIDTH - 20, 50);
1983 WMMoveWidget(panel->whatF, 10, 240);
1984 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1985
1986 panel->whatP = WMCreatePopUpButton(panel->whatF);
1987 WMResizeWidget(panel->whatP, PWIDTH - 20 - 70, 20);
1988 WMMoveWidget(panel->whatP, 35, 20);
1989 WMSetPopUpButtonPullsDown(panel->whatP, False);
1990 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1991 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1992 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1993 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1994 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1995 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1996 panel->action = WMRestart;
1997
1998 WMMapSubwidgets(panel->whatF);
1999
2000 panel->okB = WMCreateCommandButton(panel->win);
2001 WMResizeWidget(panel->okB, 80, 26);
2002 WMMoveWidget(panel->okB, 205, 309);
2003 WMSetButtonText(panel->okB, _("OK"));
2004 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
2005 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
2006 WMSetButtonImagePosition(panel->okB, WIPRight);
2007 WMSetButtonAction(panel->okB, okButtonCallback, panel);
2008
2009 panel->done = 0;
2010
2011 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask, handleKeyPress, panel);
2012
2013 WMRealizeWidget(panel->win);
2014 WMMapSubwidgets(panel->win);
2015
2016 WMMapWidget(panel->win);
2017
2018 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
2019
2020 while (!panel->done) {
2021 XEvent event;
2022
2023 WMNextEvent(dpy, &event);
2024 WMHandleEvent(&event);
2025 }
2026
2027 action = panel->action;
2028
2029 WMUnmapWidget(panel->win);
2030 WMDestroyWidget(panel->win);
2031 wfree(panel);
2032
2033 return action;
52917e53 dan1999-04-16 20:05:26 +00002034}
2035
c2434e89 kojima1999-05-01 17:44:43 +00002036/*****************************************************************************
2037 * About GNUstep Panel
2038 *****************************************************************************/
2039
c2434e89 kojima1999-05-01 17:44:43 +00002040static void
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02002041drawGNUstepLogo(Display * dpy, Drawable d, int width, int height,
2042 unsigned long blackPixel, unsigned long whitePixel)
c2434e89 kojima1999-05-01 17:44:43 +00002043{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02002044 GC gc;
2045 XGCValues gcv;
2046 XRectangle rects[3];
c2434e89 kojima1999-05-01 17:44:43 +00002047
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02002048 gcv.foreground = blackPixel;
2049 gc = XCreateGC(dpy, d, GCForeground, &gcv);
c2434e89 kojima1999-05-01 17:44:43 +00002050
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02002051 XFillArc(dpy, d, gc, width / 45, height / 45,
2052 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
c2434e89 kojima1999-05-01 17:44:43 +00002053
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02002054 rects[0].x = 0;
2055 rects[0].y = 37 * height / 45;
2056 rects[0].width = width / 3;
2057 rects[0].height = height - rects[0].y;
c2434e89 kojima1999-05-01 17:44:43 +00002058
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02002059 rects[1].x = rects[0].width;
2060 rects[1].y = height / 2;
2061 rects[1].width = width - 2 * width / 3;
2062 rects[1].height = height - rects[1].y;
c2434e89 kojima1999-05-01 17:44:43 +00002063
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02002064 rects[2].x = 2 * width / 3;
2065 rects[2].y = height - 37 * height / 45;
2066 rects[2].width = width / 3;
2067 rects[2].height = height - rects[2].y;
c2434e89 kojima1999-05-01 17:44:43 +00002068
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02002069 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
2070 XFillRectangle(dpy, d, gc, 0, 0, width, height);
c2434e89 kojima1999-05-01 17:44:43 +00002071
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02002072 XSetForeground(dpy, gc, whitePixel);
2073 XFillArc(dpy, d, gc, width / 45, height / 45,
2074 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
c2434e89 kojima1999-05-01 17:44:43 +00002075
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002076 XFreeGC(dpy, gc);
c2434e89 kojima1999-05-01 17:44:43 +00002077}
2078
c2434e89 kojima1999-05-01 17:44:43 +00002079typedef struct {
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002080 WScreen *scr;
ab61c599 dan2001-05-13 23:22:21 +00002081
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002082 WWindow *wwin;
c2434e89 kojima1999-05-01 17:44:43 +00002083
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002084 WMWindow *win;
c2434e89 kojima1999-05-01 17:44:43 +00002085
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02002086 WMLabel *gstepL;
2087 WMLabel *textL;
c2434e89 kojima1999-05-01 17:44:43 +00002088} GNUstepPanel;
2089
c2434e89 kojima1999-05-01 17:44:43 +00002090static GNUstepPanel *gnustepPanel = NULL;
2091
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002092static void destroyGNUstepPanel(WCoreWindow * foo, void *data, XEvent * event)
c2434e89 kojima1999-05-01 17:44:43 +00002093{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002094 WMUnmapWidget(gnustepPanel->win);
c2434e89 kojima1999-05-01 17:44:43 +00002095
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002096 WMDestroyWidget(gnustepPanel->win);
c2434e89 kojima1999-05-01 17:44:43 +00002097
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002098 wUnmanageWindow(gnustepPanel->wwin, False, False);
c2434e89 kojima1999-05-01 17:44:43 +00002099
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002100 wfree(gnustepPanel);
c2434e89 kojima1999-05-01 17:44:43 +00002101
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002102 gnustepPanel = NULL;
c2434e89 kojima1999-05-01 17:44:43 +00002103}
2104
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002105void wShowGNUstepPanel(WScreen * scr)
c2434e89 kojima1999-05-01 17:44:43 +00002106{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +02002107 GNUstepPanel *panel;
2108 Window parent;
2109 WWindow *wwin;
2110 WMPixmap *pixmap;
2111 WMColor *color;
2112
2113 if (gnustepPanel) {
2114 if (gnustepPanel->scr == scr) {
2115 wRaiseFrame(gnustepPanel->wwin->frame->core);
2116 wSetFocusTo(scr, gnustepPanel->wwin);
2117 }
2118 return;
2119 }
2120
2121 panel = wmalloc(sizeof(GNUstepPanel));
2122
2123 panel->scr = scr;
2124
2125 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
2126 WMResizeWidget(panel->win, 325, 205);
2127
2128 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130, WMScreenDepth(scr->wmscreen), True);
2129
2130 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
2131
2132 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130, WMColorPixel(color), scr->white_pixel);
2133
2134 WMReleaseColor(color);
2135
2136 XSetForeground(dpy, scr->mono_gc, 0);
2137 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0, 130, 130);
2138 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
2139
2140 panel->gstepL = WMCreateLabel(panel->win);
2141 WMResizeWidget(panel->gstepL, 285, 64);
2142 WMMoveWidget(panel->gstepL, 20, 0);
2143 WMSetLabelTextAlignment(panel->gstepL, WARight);
2144 WMSetLabelText(panel->gstepL, "GNUstep");
2145 {
2146 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
2147
2148 WMSetLabelFont(panel->gstepL, font);
2149 WMReleaseFont(font);
2150 }
2151
2152 panel->textL = WMCreateLabel(panel->win);
2153 WMResizeWidget(panel->textL, 305, 140);
2154 WMMoveWidget(panel->textL, 10, 50);
2155 WMSetLabelTextAlignment(panel->textL, WARight);
2156 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
2157 WMSetLabelText(panel->textL,
2158 _("Window Maker is part of the GNUstep project.\n"
2159 "The GNUstep project aims to create a free\n"
2160 "implementation of the OpenStep(tm) specification\n"
2161 "which is a object-oriented framework for\n"
2162 "creating advanced graphical, multi-platform\n"
2163 "applications. Additionally, a development and\n"
2164 "user desktop enviroment will be created on top\n"
2165 "of the framework. For more information about\n"
2166 "GNUstep, please visit: www.gnustep.org"));
2167 WMSetLabelImage(panel->textL, pixmap);
2168
2169 WMReleasePixmap(pixmap);
2170
2171 WMRealizeWidget(panel->win);
2172 WMMapSubwidgets(panel->win);
2173
2174 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
2175
2176 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
2177
2178 {
2179 WMPoint center = getCenter(scr, 325, 200);
2180
2181 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"), center.x, center.y, 325, 200);
2182 }
2183
2184 WSETUFLAG(wwin, no_closable, 0);
2185 WSETUFLAG(wwin, no_close_button, 0);
2186 wWindowUpdateButtonImages(wwin);
2187 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
c28f3b2c id1999-05-20 23:30:53 +00002188#ifdef XKB_BUTTON_HINT
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002189 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
c28f3b2c id1999-05-20 23:30:53 +00002190#endif
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002191 wwin->frame->on_click_right = destroyGNUstepPanel;
ab61c599 dan2001-05-13 23:22:21 +00002192
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002193 panel->wwin = wwin;
ab61c599 dan2001-05-13 23:22:21 +00002194
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002195 WMMapWidget(panel->win);
c2434e89 kojima1999-05-01 17:44:43 +00002196
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002197 wWindowMap(wwin);
c2434e89 kojima1999-05-01 17:44:43 +00002198
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +02002199 gnustepPanel = panel;
c2434e89 kojima1999-05-01 17:44:43 +00002200}