ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/menubar.C
(Generate patch)

Comparing rxvt-unicode/src/menubar.C (file contents):
Revision 1.4 by pcg, Sat Jan 31 00:20:21 2004 UTC vs.
Revision 1.30 by root, Wed Jan 4 04:42:45 2006 UTC

1/*--------------------------------*-C-*---------------------------------* 1/*--------------------------------*-C-*---------------------------------*
2 * File: menubar.c 2 * File: menubar.C
3 *----------------------------------------------------------------------* 3 *----------------------------------------------------------------------*
4 * $Id: menubar.C,v 1.4 2004/01/31 00:20:21 pcg Exp $
5 * 4 *
6 * Copyright (c) 1997,1998 mj olesen <olesen@me.QueensU.CA> 5 * Copyright (c) 1997,1998 mj olesen <olesen@me.QueensU.CA>
6 * Copyright (c) 2004 Marc Lehmann <pcg@goof.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 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 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
22 * refer.html (or refer.txt) contains up-to-date documentation. The 22 * refer.html (or refer.txt) contains up-to-date documentation. The
23 * summary that appears at the end of this file was taken from there. 23 * summary that appears at the end of this file was taken from there.
24 *----------------------------------------------------------------------*/ 24 *----------------------------------------------------------------------*/
25 25
26#include "../config.h" /* NECESSARY */ 26#include "../config.h" /* NECESSARY */
27
28#include <cstdlib>
29
27#include "rxvt.h" /* NECESSARY */ 30#include "rxvt.h" /* NECESSARY */
28#ifdef MENUBAR 31#ifdef MENUBAR
29#include "version.h" 32#include "version.h"
30#include "menubar.h" 33#include "menubar.h"
31#include "menubar.intpro" /* PROTOS for internal routines */
32 34
33#define Menu_PixelWidth(menu) \ 35#define Menu_PixelWidth(menu) \
34 (2 * SHADOW + Width2Pixel ((menu)->width + 3 * HSPACE)) 36 (2 * MENU_SHADOW + Width2Pixel ((menu)->width + 3 * HSPACE))
35 37
36static const struct { 38static const struct
39 {
37 const char name; /* (l)eft, (u)p, (d)own, (r)ight */ 40 const char name; /* (l)eft, (u)p, (d)own, (r)ight */
38 const unsigned char str[5]; /* str[0] = STRLEN (str+1) */ 41 const char str[5]; /* str[0] = strlen (str+1) */
42 }
39} Arrows[NARROWS] = { 43Arrows[NARROWS] = {
40 { 'l', "\003\033[D" }, 44 { 'l', "\003\033[D" },
41 { 'u', "\003\033[A" }, 45 { 'u', "\003\033[A" },
42 { 'd', "\003\033[B" }, 46 { 'd', "\003\033[B" },
43 { 'r', "\003\033[C" } 47 { 'r', "\003\033[C" }
44}; 48 };
45 49
46/*}}} */ 50/*}}} */
51
52static void
53draw_string (rxvt_drawable &d, GC gc, rxvt_fontset *fs, int x, int y, char *str, int len)
54{
55 mbstate mbs;
56
57 while (len)
58 {
59 wchar_t w;
60 int l = mbrtowc (&w, str, len, mbs);
61
62 if (l <= 0)
63 break;
64
65 len -= l;
66 str += l;
67
68 rxvt_font *font = (*fs)[fs->find_font (w)];
69 text_t ch = w;
70 font->draw (d, x, y, &ch, 1, Color_bg, Color_scroll);
71
72 x += font->width * wcwidth (w);
73 }
74}
47 75
48/* 76/*
49 * find an item called NAME in MENU 77 * find an item called NAME in MENU
50 */ 78 */
51menuitem_t * 79menuitem_t *
52rxvt_menuitem_find(const menu_t *menu, const char *name) 80rxvt_menuitem_find (const menu_t *menu, const char *name)
53{ 81{
54 menuitem_t *item; 82 menuitem_t *item;
55 83
56#ifdef DEBUG_STRICT 84#ifdef DEBUG_STRICT
57 assert(name != NULL); 85 assert (name != NULL);
58 assert(menu != NULL); 86 assert (menu != NULL);
59#endif 87#endif
60 88
61/* find the last item in the menu, this is good for separators */ 89 /* find the last item in the menu, this is good for separators */
62 for (item = menu->tail; item != NULL; item = item->prev) { 90 for (item = menu->tail; item != NULL; item = item->prev)
91 {
63 if (item->entry.type == MenuSubMenu) { 92 if (item->entry.type == MenuSubMenu)
93 {
64 if (!STRCMP(name, (item->entry.submenu.menu)->name)) 94 if (!strcmp (name, (item->entry.submenu.menu)->name))
65 break; 95 break;
96 }
66 } else if ((isSeparator(name) && isSeparator(item->name)) 97 else if ((isSeparator (name) && isSeparator (item->name))
67 || !STRCMP(name, item->name)) 98 || !strcmp (name, item->name))
68 break; 99 break;
69 } 100 }
70 return item; 101 return item;
71} 102}
72 103
73/* 104/*
74 * unlink ITEM from its MENU and free its memory 105 * unlink ITEM from its MENU and free its memory
75 */ 106 */
76void 107void
77rxvt_term::menuitem_free (menu_t *menu, menuitem_t *item) 108rxvt_term::menuitem_free (menu_t *menu, menuitem_t *item)
78{ 109{
79/* disconnect */ 110 /* disconnect */
80 menuitem_t *prev, *next; 111 menuitem_t *prev, *next;
81 112
82#ifdef DEBUG_STRICT 113#ifdef DEBUG_STRICT
83 assert(menu != NULL); 114 assert (menu != NULL);
84#endif 115#endif
85 116
86 prev = item->prev; 117 prev = item->prev;
87 next = item->next; 118 next = item->next;
88 if (prev != NULL) 119 if (prev != NULL)
89 prev->next = next; 120 prev->next = next;
90 if (next != NULL) 121 if (next != NULL)
91 next->prev = prev; 122 next->prev = prev;
92 123
93/* new head, tail */ 124 /* new head, tail */
94 if (menu->tail == item) 125 if (menu->tail == item)
95 menu->tail = prev; 126 menu->tail = prev;
96 if (menu->head == item) 127 if (menu->head == item)
97 menu->head = next; 128 menu->head = next;
98 129
99 switch (item->entry.type) { 130 switch (item->entry.type)
131 {
100 case MenuAction: 132 case MenuAction:
101 case MenuTerminalAction: 133 case MenuTerminalAction:
102 free(item->entry.action.str); 134 free (item->entry.action.str);
103 break; 135 break;
104 case MenuSubMenu: 136 case MenuSubMenu:
105 menu_delete (item->entry.submenu.menu); 137 menu_delete (item->entry.submenu.menu);
106 break; 138 break;
107 } 139 }
108 if (item->name != NULL) 140 if (item->name != NULL)
109 free(item->name); 141 free (item->name);
110 if (item->name2 != NULL) 142 if (item->name2 != NULL)
111 free(item->name2); 143 free (item->name2);
112 free(item); 144 free (item);
113} 145}
114 146
115/* 147/*
116 * sort command vs. terminal actions and 148 * sort command vs. terminal actions and
117 * remove the first character of STR if it's '\0' 149 * remove the first character of STR if it's '\0'
118 */ 150 */
119int 151int
120rxvt_action_type(action_t *action, unsigned char *str) 152rxvt_action_type (action_t *action, char *str)
121{ 153{
122 unsigned int len; 154 unsigned int len;
123 155
124#if defined (DEBUG_MENU) || defined (DEBUG_MENUARROWS) 156#if defined (DEBUG_MENU) || defined (DEBUG_MENUARROWS)
125 len = STRLEN(str); 157 len = strlen (str);
126 fprintf(stderr, "(len %d) = %s\n", len, str); 158 fprintf (stderr, " (len %d) = %s\n", len, str);
127#else 159#else
128 len = rxvt_Str_escaped((char *)str); 160 len = rxvt_Str_escaped ((char *)str);
129#endif 161#endif
130 162
131 if (!len) 163 if (!len)
132 return -1; 164 return -1;
133 165
134/* sort command vs. terminal actions */ 166 /* sort command vs. terminal actions */
135 action->type = MenuAction; 167 action->type = MenuAction;
136 if (str[0] == '\0') { 168 if (str[0] == '\0')
169 {
137 /* the functional equivalent: memmove (str, str+1, len); */ 170 /* the functional equivalent: memmove (str, str+1, len); */
138 unsigned char *dst = (str); 171 char *dst = (str);
139 unsigned char *src = (str + 1); 172 char *src = (str + 1);
140 unsigned char *end = (str + len); 173 char *end = (str + len);
141 174
142 while (src <= end) 175 while (src <= end)
143 *dst++ = *src++; 176 *dst++ = *src++;
144 177
145 len--; /* decrement length */ 178 len--; /* decrement length */
146 if (str[0] != '\0') 179 if (str[0] != '\0')
147 action->type = MenuTerminalAction; 180 action->type = MenuTerminalAction;
148 } 181 }
182
149 action->str = str; 183 action->str = str;
150 action->len = len; 184 action->len = len;
151 185
152 return 0; 186 return 0;
153} 187}
154 188
155int 189int
156rxvt_term::action_dispatch (action_t *action) 190rxvt_term::action_dispatch (action_t *action)
157{ 191{
158 switch (action->type) { 192 switch (action->type)
193 {
159 case MenuTerminalAction: 194 case MenuTerminalAction:
160 cmd_write (action->str, action->len); 195 cmd_write (action->str, action->len);
161 break; 196 break;
162 197
163 case MenuAction: 198 case MenuAction:
164 tt_write (action->str, action->len); 199 tt_write (action->str, action->len);
165 break; 200 break;
166 201
167 default: 202 default:
168 return -1; 203 return -1;
169 break; 204 break;
170 } 205 }
171 return 0; 206 return 0;
172} 207}
173 208
174/* return the arrow index corresponding to NAME */ 209/* return the arrow index corresponding to NAME */
175int 210int
176rxvt_menuarrow_find(char name) 211rxvt_menuarrow_find (char name)
177{ 212{
178 int i; 213 int i;
179 214
180 for (i = 0; i < NARROWS; i++) 215 for (i = 0; i < NARROWS; i++)
181 if (name == Arrows[i].name) 216 if (name == Arrows[i].name)
182 return i; 217 return i;
183 return -1; 218 return -1;
184} 219}
185 220
186/* free the memory associated with arrow NAME of the current menubar */ 221/* free the memory associated with arrow NAME of the current menubar */
187void 222void
188rxvt_term::menuarrow_free (char name) 223rxvt_term::menuarrow_free (char name)
189{ 224{
190 int i; 225 int i;
191 226
192 if (name) { 227 if (name)
228 {
193 i = rxvt_menuarrow_find(name); 229 i = rxvt_menuarrow_find (name);
194 if (i >= 0) { 230 if (i >= 0)
231 {
195 action_t *act = &(CurrentBar->arrows[i]); 232 action_t *act = & (CurrentBar->arrows[i]);
196 233
197 switch (act->type) { 234 switch (act->type)
235 {
198 case MenuAction: 236 case MenuAction:
199 case MenuTerminalAction: 237 case MenuTerminalAction:
200 free(act->str); 238 free (act->str);
201 act->str = NULL; 239 act->str = NULL;
202 act->len = 0; 240 act->len = 0;
203 break; 241 break;
242 }
243 act->type = MenuLabel;
244 }
204 } 245 }
205 act->type = MenuLabel; 246 else
206 } 247 {
207 } else {
208 for (i = 0; i < NARROWS; i++) 248 for (i = 0; i < NARROWS; i++)
209 menuarrow_free (Arrows[i].name); 249 menuarrow_free (Arrows[i].name);
210 } 250 }
211} 251}
212 252
213void 253void
214rxvt_term::menuarrow_add (char *string) 254rxvt_term::menuarrow_add (char *string)
215{ 255{
216 int i; 256 int i;
217 unsigned xtra_len; 257 unsigned xtra_len;
218 char *p; 258 char *p;
219 struct { 259 struct
260 {
220 char *str; 261 char *str;
221 int len; 262 int len;
222 } 263 }
223 beg = { NULL, 0 }, 264 beg = { NULL, 0 },
224 end = { NULL, 0 }, 265 end = { NULL, 0 },
225 *cur, 266 *cur,
226 parse[NARROWS]; 267 parse[NARROWS];
227 268
228 MEMSET(parse, 0, sizeof(parse)); 269 memset (parse, 0, sizeof (parse));
229 270
230/* fprintf(stderr, "add arrows = `%s'\n", string); */ 271 /* fprintf (stderr, "add arrows = `%s'\n", string); */
231 for (p = string; p != NULL && *p; string = p) { 272 for (p = string; p != NULL && *p; string = p)
273 {
232 p = (string + 3); 274 p = (string + 3);
233 /* fprintf(stderr, "parsing at %s\n", string); */ 275 /* fprintf (stderr, "parsing at %s\n", string); */
234 switch (string[1]) { 276 switch (string[1])
235 case 'b': 277 {
278 case 'b':
236 cur = &beg; 279 cur = &beg;
237 break; 280 break;
238 case 'e': 281 case 'e':
239 cur = &end; 282 cur = &end;
240 break; 283 break;
241 284
242 default: 285 default:
243 i = rxvt_menuarrow_find(string[1]); 286 i = rxvt_menuarrow_find (string[1]);
244 if (i >= 0) 287 if (i >= 0)
245 cur = &(parse[i]); 288 cur = & (parse[i]);
289 else
290 continue; /* not found */
291 break;
292 }
293
294 string = p;
295 cur->str = string;
296 cur->len = 0;
297
298 if (cur == &end)
299 {
300 p = strchr (string, '\0');
301 }
246 else 302 else
247 continue; /* not found */ 303 {
248 break;
249 }
250
251 string = p;
252 cur->str = string;
253 cur->len = 0;
254
255 if (cur == &end) {
256 p = STRCHR(string, '\0');
257 } else {
258 char *next = string; 304 char *next = string;
259 305
260 while (1) { 306 while (1)
261 p = STRCHR(next, '<'); 307 {
262 if (p != NULL) { 308 p = strchr (next, '<');
309 if (p != NULL)
310 {
263 if (p[1] && p[2] == '>') 311 if (p[1] && p[2] == '>')
264 break; 312 break;
265 /* parsed */ 313 /* parsed */
266 } else { 314 }
315 else
316 {
267 if (beg.str == NULL) /* no end needed */ 317 if (beg.str == NULL) /* no end needed */
268 p = STRCHR(next, '\0'); 318 p = strchr (next, '\0');
269 break; 319 break;
270 } 320 }
271 next = (p + 1); 321 next = (p + 1);
272 } 322 }
273 } 323 }
274 324
275 if (p == NULL) 325 if (p == NULL)
276 return; 326 return;
277 cur->len = (p - string); 327 cur->len = (p - string);
278 } 328 }
279 329
280#ifdef DEBUG_MENUARROWS 330#ifdef DEBUG_MENUARROWS
281 cur = &beg; 331 cur = &beg;
282 fprintf(stderr, "<b>(len %d) = %.*s\n", 332 fprintf (stderr, "<b> (len %d) = %.*s\n",
283 cur->len, cur->len, (cur->str ? cur->str : "")); 333 cur->len, cur->len, (cur->str ? cur->str : ""));
284 for (i = 0; i < NARROWS; i++) { 334 for (i = 0; i < NARROWS; i++)
335 {
285 cur = &(parse[i]); 336 cur = & (parse[i]);
286 fprintf(stderr, "<%c>(len %d) = %.*s\n", 337 fprintf (stderr, "<%c> (len %d) = %.*s\n",
287 Arrows[i].name, 338 Arrows[i].name,
288 cur->len, cur->len, (cur->str ? cur->str : "")); 339 cur->len, cur->len, (cur->str ? cur->str : ""));
289 } 340 }
290 cur = &end; 341 cur = &end;
291 fprintf(stderr, "<e>(len %d) = %.*s\n", 342 fprintf (stderr, "<e> (len %d) = %.*s\n",
292 cur->len, cur->len, (cur->str ? cur->str : "")); 343 cur->len, cur->len, (cur->str ? cur->str : ""));
293#endif 344#endif
294 345
295 xtra_len = (beg.len + end.len); 346 xtra_len = (beg.len + end.len);
296 for (i = 0; i < NARROWS; i++) { 347 for (i = 0; i < NARROWS; i++)
348 {
297 if (xtra_len || parse[i].len) 349 if (xtra_len || parse[i].len)
298 menuarrow_free (Arrows[i].name); 350 menuarrow_free (Arrows[i].name);
299 } 351 }
300 352
301 for (i = 0; i < NARROWS; i++) { 353 for (i = 0; i < NARROWS; i++)
302 unsigned char *str; 354 {
355 char *str;
303 unsigned int len; 356 unsigned int len;
304 357
305 if (!parse[i].len) 358 if (!parse[i].len)
306 continue; 359 continue;
307 360
308 str = rxvt_malloc(parse[i].len + xtra_len + 1); 361 str = (char *)rxvt_malloc (parse[i].len + xtra_len + 1);
309 362
310 len = 0; 363 len = 0;
311 if (beg.len) { 364 if (beg.len)
312 STRNCPY(str + len, beg.str, beg.len); 365 {
366 strncpy (str + len, beg.str, beg.len);
313 len += beg.len; 367 len += beg.len;
314 } 368 }
315 STRNCPY(str + len, parse[i].str, parse[i].len); 369 strncpy (str + len, parse[i].str, parse[i].len);
316 len += parse[i].len; 370 len += parse[i].len;
317 371
318 if (end.len) { 372 if (end.len)
319 STRNCPY(str + len, end.str, end.len); 373 {
374 strncpy (str + len, end.str, end.len);
320 len += end.len; 375 len += end.len;
321 } 376 }
322 str[len] = '\0'; 377 str[len] = '\0';
323 378
324#ifdef DEBUG_MENUARROWS 379#ifdef DEBUG_MENUARROWS
325 fprintf(stderr, "<%c>(len %d) = %s\n", Arrows[i].name, len, str); 380 fprintf (stderr, "<%c> (len %d) = %s\n", Arrows[i].name, len, str);
326#endif 381#endif
327 if (rxvt_action_type(&(CurrentBar->arrows[i]), str) < 0) 382 if (rxvt_action_type (& (CurrentBar->arrows[i]), str) < 0)
328 free(str); 383 free (str);
329 } 384 }
330} 385}
331 386
332menuitem_t * 387menuitem_t *
333rxvt_menuitem_add(menu_t *menu, const char *name, const char *name2, const char *action) 388rxvt_menuitem_add (menu_t *menu, const char *name, const char *name2, const char *action)
334{ 389{
335 menuitem_t *item; 390 menuitem_t *item;
336 unsigned int len; 391 unsigned int len;
337 392
338#ifdef DEBUG_STRICT 393#ifdef DEBUG_STRICT
339 assert(name != NULL); 394 assert (name != NULL);
340 assert(action != NULL); 395 assert (action != NULL);
341#endif 396#endif
342 397
343 if (menu == NULL) 398 if (menu == NULL)
344 return NULL; 399 return NULL;
345 400
346 if (isSeparator(name)) { 401 if (isSeparator (name))
402 {
347 /* add separator, no action */ 403 /* add separator, no action */
348 name = ""; 404 name = "";
349 action = ""; 405 action = "";
350 } else {
351 /*
352 * add/replace existing menu item
353 */
354 item = rxvt_menuitem_find(menu, name);
355 if (item != NULL) {
356 if (item->name2 != NULL && name2 != NULL) {
357 free(item->name2);
358 item->len2 = 0;
359 item->name2 = NULL;
360 } 406 }
407 else
408 {
409 /*
410 * add/replace existing menu item
411 */
412 item = rxvt_menuitem_find (menu, name);
413 if (item != NULL)
414 {
415 if (item->name2 != NULL && name2 != NULL)
416 {
417 free (item->name2);
418 item->len2 = 0;
419 item->name2 = NULL;
420 }
361 switch (item->entry.type) { 421 switch (item->entry.type)
422 {
362 case MenuAction: 423 case MenuAction:
363 case MenuTerminalAction: 424 case MenuTerminalAction:
364 free(item->entry.action.str); 425 free (item->entry.action.str);
365 item->entry.action.str = NULL; 426 item->entry.action.str = NULL;
366 break; 427 break;
428 }
429 goto Item_Found;
430 }
367 } 431 }
368 goto Item_Found;
369 }
370 }
371/* allocate a new itemect */ 432 /* allocate a new itemect */
372 item = (menuitem_t *) rxvt_malloc(sizeof(menuitem_t)); 433 item = (menuitem_t *) rxvt_malloc (sizeof (menuitem_t));
373 434
374 item->len2 = 0; 435 item->len2 = 0;
375 item->name2 = NULL; 436 item->name2 = NULL;
376 437
377 len = STRLEN(name); 438 len = strlen (name);
378 item->name = rxvt_malloc(len + 1); 439 item->name = (char *)rxvt_malloc (len + 1);
379 STRCPY(item->name, name); 440 strcpy (item->name, name);
380 if (name[0] == '.' && name[1] != '.') 441 if (name[0] == '.' && name[1] != '.')
381 len = 0; /* hidden menu name */ 442 len = 0; /* hidden menu name */
382 item->len = len; 443 item->len = len;
383 444
384/* add to tail of list */ 445 /* add to tail of list */
385 item->prev = menu->tail; 446 item->prev = menu->tail;
386 item->next = NULL; 447 item->next = NULL;
387 448
388 if (menu->tail != NULL) 449 if (menu->tail != NULL)
389 (menu->tail)->next = item; 450 (menu->tail)->next = item;
390 menu->tail = item; 451 menu->tail = item;
391/* fix head */ 452 /* fix head */
392 if (menu->head == NULL) 453 if (menu->head == NULL)
393 menu->head = item; 454 menu->head = item;
394 455
395/* 456 /*
396 * add action 457 * add action
397 */ 458 */
398 Item_Found: 459Item_Found:
399 if (name2 != NULL && item->name2 == NULL) { 460 if (name2 != NULL && item->name2 == NULL)
400 len = STRLEN(name2); 461 {
462 len = strlen (name2);
401 if (len == 0) 463 if (len == 0)
402 item->name2 = NULL; 464 item->name2 = NULL;
403 else { 465 else
466 {
404 item->name2 = rxvt_malloc(len + 1); 467 item->name2 = (char *)rxvt_malloc (len + 1);
405 STRCPY(item->name2, name2); 468 strcpy (item->name2, name2);
406 } 469 }
407 item->len2 = len; 470 item->len2 = len;
408 } 471 }
409 item->entry.type = MenuLabel; 472 item->entry.type = MenuLabel;
410 len = STRLEN(action); 473 len = strlen (action);
411 474
412 if (len == 0 && item->name2 != NULL) { 475 if (len == 0 && item->name2 != NULL)
476 {
413 action = item->name2; 477 action = item->name2;
414 len = item->len2; 478 len = item->len2;
415 } 479 }
416 if (len) { 480 if (len)
417 unsigned char *str = rxvt_malloc(len + 1); 481 {
482 char *str = (char *)rxvt_malloc (len + 1);
418 483
419 STRCPY(str, action); 484 strcpy (str, action);
420 485
421 if (rxvt_action_type(&(item->entry.action), str) < 0) 486 if (rxvt_action_type (& (item->entry.action), str) < 0)
422 free(str); 487 free (str);
423 } 488 }
424/* new item and a possible increase in width */ 489 /* new item and a possible increase in width */
425 if (menu->width < (item->len + item->len2)) 490 if (menu->width < (item->len + item->len2))
426 menu->width = (item->len + item->len2); 491 menu->width = (item->len + item->len2);
427 492
428 return item; 493 return item;
429} 494}
430 495
431/* 496/*
432 * search for the base starting menu for NAME. 497 * search for the base starting menu for NAME.
433 * return a pointer to the portion of NAME that remains 498 * return a pointer to the portion of NAME that remains
434 */ 499 */
435char * 500char *
436rxvt_term::menu_find_base (menu_t **menu, char *path) 501rxvt_term::menu_find_base (menu_t **menu, char *path)
437{ 502{
438 menu_t *m = NULL; 503 menu_t *m = NULL;
439 menuitem_t *item; 504 menuitem_t *item;
440 505
441#ifdef DEBUG_STRICT 506#ifdef DEBUG_STRICT
442 assert(menu != NULL); 507 assert (menu != NULL);
443 assert(CurrentBar != NULL); 508 assert (CurrentBar != NULL);
444#endif 509#endif
445 510
446 if (path[0] == '\0') 511 if (path[0] == '\0')
447 return path;
448
449 if (STRCHR(path, '/') != NULL) {
450 char *p = path;
451
452 while ((p = STRCHR(p, '/')) != NULL) {
453 p++;
454 if (*p == '/')
455 path = p;
456 }
457 if (path[0] == '/') {
458 path++;
459 *menu = NULL;
460 }
461 while ((p = STRCHR(path, '/')) != NULL) {
462 p[0] = '\0';
463 if (path[0] == '\0')
464 return NULL;
465 if (!STRCMP(path, DOT)) {
466 /* nothing to do */
467 } else if (!STRCMP(path, DOTS)) {
468 if (*menu != NULL)
469 *menu = (*menu)->parent;
470 } else {
471 path = menu_find_base (menu, path);
472 if (path[0] != '\0') { /* not found */
473 p[0] = '/'; /* fix-up name again */
474 return path;
475 }
476 }
477
478 path = (p + 1);
479 }
480 }
481 if (!STRCMP(path, DOTS)) {
482 path += STRLEN(DOTS);
483 if (*menu != NULL)
484 *menu = (*menu)->parent;
485 return path;
486 }
487/* find this menu */
488 if (*menu == NULL) {
489 for (m = CurrentBar->tail; m != NULL; m = m->prev) {
490 if (!STRCMP(path, m->name))
491 break;
492 }
493 } else {
494 /* find this menu */
495 for (item = (*menu)->tail; item != NULL; item = item->prev) {
496 if (item->entry.type == MenuSubMenu
497 && !STRCMP(path, (item->entry.submenu.menu)->name)) {
498 m = (item->entry.submenu.menu);
499 break;
500 }
501 }
502 }
503 if (m != NULL) {
504 *menu = m;
505 path += STRLEN(path);
506 }
507 return path; 512 return path;
513
514 if (strchr (path, '/') != NULL)
515 {
516 char *p = path;
517
518 while ((p = strchr (p, '/')) != NULL)
519 {
520 p++;
521 if (*p == '/')
522 path = p;
523 }
524
525 if (path[0] == '/')
526 {
527 path++;
528 *menu = NULL;
529 }
530
531 while ((p = strchr (path, '/')) != NULL)
532 {
533 p[0] = '\0';
534 if (path[0] == '\0')
535 return NULL;
536
537 if (!strcmp (path, DOT))
538 {
539 /* nothing to do */
540 }
541 else if (!strcmp (path, DOTS))
542 {
543 if (*menu != NULL)
544 *menu = (*menu)->parent;
545 }
546 else
547 {
548 path = menu_find_base (menu, path);
549 if (path[0] != '\0')
550 { /* not found */
551 p[0] = '/'; /* fix-up name again */
552 return path;
553 }
554 }
555
556 path = (p + 1);
557 }
558 }
559
560 if (!strcmp (path, DOTS))
561 {
562 path += strlen (DOTS);
563 if (*menu != NULL)
564 *menu = (*menu)->parent;
565 return path;
566 }
567
568 /* find this menu */
569 if (*menu == NULL)
570 {
571 for (m = CurrentBar->tail; m != NULL; m = m->prev)
572 if (!strcmp (path, m->name))
573 break;
574 }
575 else
576 {
577 /* find this menu */
578 for (item = (*menu)->tail; item != NULL; item = item->prev)
579 {
580 if (item->entry.type == MenuSubMenu
581 && !strcmp (path, (item->entry.submenu.menu)->name))
582 {
583 m = (item->entry.submenu.menu);
584 break;
585 }
586 }
587 }
588
589 if (m != NULL)
590 {
591 *menu = m;
592 path += strlen (path);
593 }
594
595 return path;
508} 596}
509 597
510/* 598/*
511 * delete this entire menu 599 * delete this entire menu
512 */ 600 */
513menu_t * 601menu_t *
514rxvt_term::menu_delete (menu_t *menu) 602rxvt_term::menu_delete (menu_t *menu)
515{ 603{
516 menu_t *parent = NULL, *prev, *next; 604 menu_t *parent = NULL, *prev, *next;
517 menuitem_t *item; 605 menuitem_t *item;
518 bar_t *CurrentBar = CurrentBar;
519 606
520#ifdef DEBUG_STRICT 607#ifdef DEBUG_STRICT
521 assert(CurrentBar != NULL); 608 assert (CurrentBar != NULL);
522#endif 609#endif
523 610
524/* delete the entire menu */ 611 /* delete the entire menu */
525 if (menu == NULL) 612 if (menu == NULL)
526 return NULL; 613 return NULL;
527 614
528 parent = menu->parent; 615 parent = menu->parent;
529 616
530/* unlink MENU */ 617 /* unlink MENU */
531 prev = menu->prev; 618 prev = menu->prev;
532 next = menu->next; 619 next = menu->next;
533 if (prev != NULL) 620 if (prev != NULL)
534 prev->next = next; 621 prev->next = next;
535 if (next != NULL) 622 if (next != NULL)
536 next->prev = prev; 623 next->prev = prev;
537 624
538/* fix the index */ 625 /* fix the index */
539 if (parent == NULL) { 626 if (parent == NULL)
627 {
540 const int len = (menu->len + HSPACE); 628 const int len = (menu->len + HSPACE);
541 629
542 if (CurrentBar->tail == menu) 630 if (CurrentBar->tail == menu)
543 CurrentBar->tail = prev; 631 CurrentBar->tail = prev;
544 if (CurrentBar->head == menu) 632 if (CurrentBar->head == menu)
545 CurrentBar->head = next; 633 CurrentBar->head = next;
546 634
547 for (next = menu->next; next != NULL; next = next->next) 635 for (next = menu->next; next != NULL; next = next->next)
548 next->x -= len; 636 next->x -= len;
549 } else { 637 }
638 else
639 {
550 for (item = parent->tail; item != NULL; item = item->prev) { 640 for (item = parent->tail; item != NULL; item = item->prev)
641 {
551 if (item->entry.type == MenuSubMenu 642 if (item->entry.type == MenuSubMenu
552 && item->entry.submenu.menu == menu) { 643 && item->entry.submenu.menu == menu)
644 {
553 item->entry.submenu.menu = NULL; 645 item->entry.submenu.menu = NULL;
554 menuitem_free (menu->parent, item); 646 menuitem_free (menu->parent, item);
555 break; 647 break;
648 }
649 }
556 } 650 }
557 }
558 }
559 651
560 item = menu->tail; 652 item = menu->tail;
561 while (item != NULL) { 653 while (item != NULL)
654 {
562 menuitem_t *p = item->prev; 655 menuitem_t *p = item->prev;
563 656
564 menuitem_free (menu, item); 657 menuitem_free (menu, item);
565 item = p; 658 item = p;
566 } 659 }
567 660
568 if (menu->name != NULL)
569 free(menu->name); 661 free (menu->name);
570 free(menu); 662 free (menu);
571 663
572 return parent; 664 return parent;
573} 665}
574 666
575menu_t * 667menu_t *
576rxvt_term::menu_add (menu_t *parent, char *path) 668rxvt_term::menu_add (menu_t *parent, char *path)
577{ 669{
578 menu_t *menu; 670 menu_t *menu;
579 bar_t *CurrentBar = CurrentBar;
580 671
581#ifdef DEBUG_STRICT 672#ifdef DEBUG_STRICT
582 assert(CurrentBar != NULL); 673 assert (CurrentBar != NULL);
583#endif 674#endif
584 675
585 if (STRCHR(path, '/') != NULL) { 676 if (strchr (path, '/') != NULL)
586 char *p; 677 {
678 char *p;
587 679
588 if (path[0] == '/') { 680 if (path[0] == '/')
681 {
589 /* shouldn't happen */ 682 /* shouldn't happen */
590 path++; 683 path++;
591 parent = NULL; 684 parent = NULL;
592 } 685 }
593 while ((p = STRCHR(path, '/')) != NULL) { 686 while ((p = strchr (path, '/')) != NULL)
687 {
594 p[0] = '\0'; 688 p[0] = '\0';
595 if (path[0] == '\0') 689 if (path[0] == '\0')
596 return NULL; 690 return NULL;
597 691
598 parent = menu_add (parent, path); 692 parent = menu_add (parent, path);
599 path = (p + 1); 693 path = (p + 1);
600 } 694 }
601 } 695 }
602 if (!STRCMP(path, DOTS)) 696 if (!strcmp (path, DOTS))
603 return (parent != NULL ? parent->parent : parent); 697 return (parent != NULL ? parent->parent : parent);
604 698
605 if (!STRCMP(path, DOT) || path[0] == '\0') 699 if (!strcmp (path, DOT) || path[0] == '\0')
606 return parent; 700 return parent;
607 701
608/* allocate a new menu */ 702 /* allocate a new menu */
609 menu = (menu_t *) rxvt_malloc(sizeof(menu_t)); 703 menu = (menu_t *) rxvt_malloc (sizeof (menu_t));
610 704
611 menu->width = 0; 705 menu->width = 0;
612 menu->parent = parent; 706 menu->parent = parent;
613 menu->len = STRLEN(path); 707 menu->len = strlen (path);
614 menu->name = rxvt_malloc((menu->len + 1)); 708 menu->name = (char *)rxvt_malloc ((menu->len + 1));
615 STRCPY(menu->name, path); 709 strcpy (menu->name, path);
616 710
617/* initialize head/tail */ 711 /* initialize head/tail */
618 menu->head = menu->tail = NULL; 712 menu->head = menu->tail = NULL;
619 menu->prev = menu->next = NULL; 713 menu->prev = menu->next = NULL;
620 714
621 menu->win = None; 715 menu->win = None;
716 menu->drawable = 0;
622 menu->x = menu->y = menu->w = menu->h = 0; 717 menu->x = menu->y = menu->w = menu->h = 0;
623 menu->item = NULL; 718 menu->item = NULL;
624 719
625/* add to tail of list */ 720 /* add to tail of list */
626 if (parent == NULL) { 721 if (parent == NULL)
722 {
627 menu->prev = CurrentBar->tail; 723 menu->prev = CurrentBar->tail;
628 if (CurrentBar->tail != NULL) 724 if (CurrentBar->tail != NULL)
629 CurrentBar->tail->next = menu; 725 CurrentBar->tail->next = menu;
630 CurrentBar->tail = menu; 726 CurrentBar->tail = menu;
631 if (CurrentBar->head == NULL) 727 if (CurrentBar->head == NULL)
632 CurrentBar->head = menu; /* fix head */ 728 CurrentBar->head = menu; /* fix head */
633 if (menu->prev) 729 if (menu->prev)
634 menu->x = (menu->prev->x + menu->prev->len + HSPACE); 730 menu->x = (menu->prev->x + menu->prev->len + HSPACE);
635 } else { 731 }
732 else
733 {
636 menuitem_t *item; 734 menuitem_t *item;
637 735
638 item = rxvt_menuitem_add(parent, path, "", ""); 736 item = rxvt_menuitem_add (parent, path, "", "");
639 if (item == NULL) { 737 if (item == NULL)
738 {
640 free(menu); 739 free (menu);
641 return parent; 740 return parent;
642 } 741 }
643#ifdef DEBUG_STRICT 742#ifdef DEBUG_STRICT
644 assert(item->entry.type == MenuLabel); 743 assert (item->entry.type == MenuLabel);
645#endif 744#endif
646 item->entry.type = MenuSubMenu; 745 item->entry.type = MenuSubMenu;
647 item->entry.submenu.menu = menu; 746 item->entry.submenu.menu = menu;
648 } 747 }
649 748
650 return menu; 749 return menu;
651} 750}
652 751
653void 752void
654rxvt_term::drawbox_menubar (int x, int len, int state) 753rxvt_term::drawbox_menubar (int x, int len, int state)
655{ 754{
656 GC top, bot; 755 GC top, bot;
657 756
658 x = Width2Pixel(x); 757 x = Width2Pixel (x);
659 len = Width2Pixel(len + HSPACE); 758 len = Width2Pixel (len + HSPACE);
660 if (x >= TermWin.width) 759 if (x >= width)
661 return; 760 return;
662 else if (x + len >= TermWin.width) 761 else if (x + len >= width)
663 len = (TermWin_TotalWidth() - x); 762 len = (this->width - x);
664 763
665#ifdef MENUBAR_SHADOW_IN 764#ifdef MENUBAR_SHADOW_IN
666 state = -state; 765 state = -state;
667#endif 766#endif
668 switch (state) { 767 switch (state)
768 {
669 case +1: 769 case +1:
670 top = topShadowGC; 770 top = topShadowGC;
671 bot = botShadowGC; 771 bot = botShadowGC;
672 break; /* SHADOW_OUT */ 772 break; /* SHADOW_OUT */
673 case -1: 773 case -1:
674 top = botShadowGC; 774 top = botShadowGC;
675 bot = topShadowGC; 775 bot = topShadowGC;
676 break; /* SHADOW_IN */ 776 break; /* SHADOW_IN */
677 default: 777 default:
678 top = bot = scrollbarGC; 778 top = bot = scrollbarGC;
679 break; /* neutral */ 779 break; /* neutral */
680 } 780 }
681 781
682 rxvt_Draw_Shadow(Xdisplay, menuBar.win, top, bot, 782 rxvt_Draw_Shadow (display->display, menuBar.win, top, bot,
683 x, 0, len, menuBar_TotalHeight()); 783 x, 0, len, menuBar_TotalHeight ());
684} 784}
685 785
686void 786void
687rxvt_term::drawtriangle (int x, int y, int state) 787rxvt_term::drawtriangle (int x, int y, int state)
688{ 788{
689 GC top, bot; 789 GC top, bot;
690 int w; 790 int w;
691 791
692#ifdef MENU_SHADOW_IN 792#ifdef MENU_SHADOW_IN
693 state = -state; 793 state = -state;
694#endif 794#endif
695 switch (state) { 795 switch (state)
796 {
696 case +1: 797 case +1:
697 top = topShadowGC; 798 top = topShadowGC;
698 bot = botShadowGC; 799 bot = botShadowGC;
699 break; /* SHADOW_OUT */ 800 break; /* SHADOW_OUT */
700 case -1: 801 case -1:
701 top = botShadowGC; 802 top = botShadowGC;
702 bot = topShadowGC; 803 bot = topShadowGC;
703 break; /* SHADOW_IN */ 804 break; /* SHADOW_IN */
704 default: 805 default:
705 top = bot = scrollbarGC; 806 top = bot = scrollbarGC;
706 break; /* neutral */ 807 break; /* neutral */
707 } 808 }
708 809
709 w = Height2Pixel(1) - 2 * SHADOW; 810 w = Height2Pixel (1) - 2 * MENU_SHADOW;
710 811
711 x -= SHADOW + (3 * w / 2); 812 x -= MENU_SHADOW + (3 * w / 2);
712 y += SHADOW * 3; 813 y += MENU_SHADOW * 3;
713 814
714 rxvt_Draw_Triangle(Xdisplay, ActiveMenu->win, top, bot, x, y, w, 815 rxvt_Draw_Triangle (display->display, ActiveMenu->win, top, bot, x, y, w, 'r');
715 'r');
716} 816}
717 817
718void 818void
719rxvt_term::drawbox_menuitem (int y, int state) 819rxvt_term::drawbox_menuitem (int y, int state)
720{ 820{
721 GC top, bot; 821 GC top, bot;
722 822
723#ifdef MENU_SHADOW_IN 823#ifdef MENU_SHADOW_IN
724 state = -state; 824 state = -state;
725#endif 825#endif
726 switch (state) { 826 switch (state)
827 {
727 case +1: 828 case +1:
728 top = topShadowGC; 829 top = topShadowGC;
729 bot = botShadowGC; 830 bot = botShadowGC;
730 break; /* SHADOW_OUT */ 831 break; /* SHADOW_OUT */
731 case -1: 832 case -1:
732 top = botShadowGC; 833 top = botShadowGC;
733 bot = topShadowGC; 834 bot = topShadowGC;
734 break; /* SHADOW_IN */ 835 break; /* SHADOW_IN */
735 default: 836 default:
736 top = bot = scrollbarGC; 837 top = bot = scrollbarGC;
737 break; /* neutral */ 838 break; /* neutral */
738 } 839 }
739 840
740 rxvt_Draw_Shadow(Xdisplay, ActiveMenu->win, top, bot, 841 rxvt_Draw_Shadow (display->display, ActiveMenu->win, top, bot,
741 SHADOW + 0, SHADOW + y, 842 MENU_SHADOW + 0, MENU_SHADOW + y,
742 ActiveMenu->w - 2 * (SHADOW), 843 ActiveMenu->w - 2 * (MENU_SHADOW),
743 HEIGHT_TEXT + 2 * SHADOW); 844 HEIGHT_TEXT + 2 * MENU_SHADOW);
744 XFlush(Xdisplay); 845 XFlush (display->display);
745} 846}
746 847
747#ifdef DEBUG_MENU_LAYOUT 848#ifdef DEBUG_MENU_LAYOUT
748void 849void
749rxvt_print_menu_ancestors(menu_t *menu) 850rxvt_print_menu_ancestors (menu_t *menu)
750{ 851{
751 if (menu == NULL) { 852 if (menu == NULL)
853 {
752 fprintf(stderr, "Top Level menu\n"); 854 fprintf (stderr, "Top Level menu\n");
753 return; 855 return;
754 } 856 }
857
755 fprintf(stderr, "menu %s ", menu->name); 858 fprintf (stderr, "menu %s ", menu->name);
756 if (menu->parent != NULL) { 859 if (menu->parent != NULL)
860 {
757 menuitem_t *item; 861 menuitem_t *item;
758 862
759 for (item = menu->parent->head; item != NULL; item = item->next) { 863 for (item = menu->parent->head; item != NULL; item = item->next)
864 {
760 if (item->entry.type == MenuSubMenu 865 if (item->entry.type == MenuSubMenu
761 && item->entry.submenu.menu == menu) { 866 && item->entry.submenu.menu == menu)
762 break; 867 {
868 break;
869 }
870 }
871
872 if (item == NULL)
873 {
874 fprintf (stderr, "is an orphan!\n");
875 return;
876 }
763 } 877 }
764 } 878
765 if (item == NULL) {
766 fprintf(stderr, "is an orphan!\n");
767 return;
768 }
769 }
770 fprintf(stderr, "\n"); 879 fprintf (stderr, "\n");
771 rxvt_print_menu_ancestors(menu->parent); 880 rxvt_print_menu_ancestors (menu->parent);
772} 881}
773 882
774void 883void
775rxvt_print_menu_descendants(menu_t *menu) 884rxvt_print_menu_descendants (menu_t *menu)
776{ 885{
777 menuitem_t *item; 886 menuitem_t *item;
778 menu_t *parent; 887 menu_t *parent;
779 int i, level = 0; 888 int i, level = 0;
780 889
781 parent = menu; 890 parent = menu;
891 do
782 do { 892 {
783 level++; 893 level++;
784 parent = parent->parent; 894 parent = parent->parent;
785 } 895 }
786 while (parent != NULL); 896 while (parent != NULL);
787 897
788 for (i = 0; i < level; i++) 898 for (i = 0; i < level; i++)
789 fprintf(stderr, ">"); 899 fprintf (stderr, ">");
790 fprintf(stderr, "%s\n", menu->name); 900 fprintf (stderr, "%s\n", menu->name);
791 901
792 for (item = menu->head; item != NULL; item = item->next) { 902 for (item = menu->head; item != NULL; item = item->next)
903 {
793 if (item->entry.type == MenuSubMenu) { 904 if (item->entry.type == MenuSubMenu)
905 {
794 if (item->entry.submenu.menu == NULL) 906 if (item->entry.submenu.menu == NULL)
795 fprintf(stderr, "> %s == NULL\n", item->name); 907 fprintf (stderr, "> %s == NULL\n", item->name);
796 else 908 else
797 rxvt_print_menu_descendants(item->entry.submenu.menu); 909 rxvt_print_menu_descendants (item->entry.submenu.menu);
798 } else { 910 }
911 else
912 {
799 for (i = 0; i < level; i++) 913 for (i = 0; i < level; i++)
800 fprintf(stderr, "+"); 914 fprintf (stderr, "+");
801 if (item->entry.type == MenuLabel) 915 if (item->entry.type == MenuLabel)
802 fprintf(stderr, "label: "); 916 fprintf (stderr, "label: ");
803 fprintf(stderr, "%s\n", item->name); 917 fprintf (stderr, "%s\n", item->name);
804 } 918 }
805 } 919 }
806 920
807 for (i = 0; i < level; i++) 921 for (i = 0; i < level; i++)
808 fprintf(stderr, "<"); 922 fprintf (stderr, "<");
809 fprintf(stderr, "\n"); 923 fprintf (stderr, "\n");
810} 924}
811#endif 925#endif
812 926
813/* pop up/down the current menu and redraw the menuBar button */ 927/* pop up/down the current menu and redraw the menuBar button */
814void 928void
815rxvt_term::menu_show () 929rxvt_term::menu_show ()
816{ 930{
817 int x, y, xright; 931 int x, y, xright;
818 menu_t *ActiveMenu = ActiveMenu;
819 menuitem_t *item; 932 menuitem_t *item;
820 933
821 if (ActiveMenu == NULL) 934 if (ActiveMenu == NULL)
822 return; 935 return;
823 936
824 x = ActiveMenu->x; 937 x = ActiveMenu->x;
825 if (ActiveMenu->parent == NULL) { 938 if (ActiveMenu->parent == NULL)
939 {
826 register int h; 940 register int h;
827 941
828 drawbox_menubar (x, ActiveMenu->len, -1); 942 drawbox_menubar (x, ActiveMenu->len, -1);
829 x = Width2Pixel(x); 943 x = Width2Pixel (x);
830 944
831 ActiveMenu->y = 1; 945 ActiveMenu->y = 1;
832 ActiveMenu->w = Menu_PixelWidth(ActiveMenu); 946 ActiveMenu->w = Menu_PixelWidth (ActiveMenu);
833 947
834 if ((x + ActiveMenu->w) >= TermWin.width) 948 if ((x + ActiveMenu->w) >= width)
835 x = (TermWin_TotalWidth() - ActiveMenu->w); 949 x = (this->width - ActiveMenu->w);
836 950
837 /* find the height */ 951 /* find the height */
838 for (h = 0, item = ActiveMenu->head; item != NULL; item = item->next) 952 for (h = 0, item = ActiveMenu->head; item != NULL; item = item->next)
839 h += isSeparator(item->name) ? HEIGHT_SEPARATOR 953 h += isSeparator (item->name) ? HEIGHT_SEPARATOR
840 : HEIGHT_TEXT + 2 * SHADOW; 954 : HEIGHT_TEXT + 2 * MENU_SHADOW;
841 ActiveMenu->h = h + 2 * SHADOW; 955 ActiveMenu->h = h + 2 * MENU_SHADOW;
842 } 956 }
957
843 if (ActiveMenu->win == None) { 958 if (ActiveMenu->win == None)
959 {
844 ActiveMenu->win = XCreateSimpleWindow(Xdisplay, TermWin.vt, 960 ActiveMenu->win = XCreateSimpleWindow (display->display, vt,
845 x, ActiveMenu->y, 961 x, ActiveMenu->y,
846 ActiveMenu->w, ActiveMenu->h, 962 ActiveMenu->w, ActiveMenu->h,
847 0, 963 0,
848 PixColors[Color_fg], 964 pix_colors[Color_fg],
849 PixColors[Color_scroll]); 965 pix_colors[Color_scroll]);
966 ActiveMenu->drawable = new rxvt_drawable (display, ActiveMenu->win);
850 XMapWindow(Xdisplay, ActiveMenu->win); 967 XMapWindow (display->display, ActiveMenu->win);
851 } 968 }
969
852 rxvt_Draw_Shadow(Xdisplay, ActiveMenu->win, 970 rxvt_Draw_Shadow (display->display, ActiveMenu->win,
853 topShadowGC, botShadowGC, 971 topShadowGC, botShadowGC,
854 0, 0, ActiveMenu->w, ActiveMenu->h); 972 0, 0, ActiveMenu->w, ActiveMenu->h);
855 973
856/* determine the correct right-alignment */ 974 /* determine the correct right-alignment */
857 for (xright = 0, item = ActiveMenu->head; item != NULL; item = item->next) 975 for (xright = 0, item = ActiveMenu->head; item != NULL; item = item->next)
858 if (item->len2 > xright) 976 if (item->len2 > xright)
859 xright = item->len2; 977 xright = item->len2;
860 978
861 for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next) { 979 for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next)
980 {
862 const int xoff = (SHADOW + Width2Pixel(HSPACE) / 2); 981 const int xoff = (MENU_SHADOW + Width2Pixel (HSPACE) / 2);
863 register int h; 982 register int h;
864 GC gc = menubarGC; 983 GC gc = menubarGC;
865 984
866 if (isSeparator(item->name)) { 985 if (isSeparator (item->name))
986 {
867 rxvt_Draw_Shadow(Xdisplay, ActiveMenu->win, 987 rxvt_Draw_Shadow (display->display, ActiveMenu->win,
868 topShadowGC, botShadowGC, 988 topShadowGC, botShadowGC,
869 SHADOW, y + SHADOW + 1, 989 MENU_SHADOW, y + MENU_SHADOW + 1,
870 ActiveMenu->w - 2 * SHADOW, 0); 990 ActiveMenu->w - 2 * MENU_SHADOW, 0);
871 h = HEIGHT_SEPARATOR; 991 h = HEIGHT_SEPARATOR;
872 } else { 992 }
993 else
994 {
873 char *name = item->name; 995 char *name = item->name;
874 int len = item->len; 996 int len = item->len;
875 997
876 if (item->entry.type == MenuLabel) { 998 if (item->entry.type == MenuLabel)
877 gc = botShadowGC; 999 gc = botShadowGC;
878 } else if (item->entry.type == MenuSubMenu) { 1000 else if (item->entry.type == MenuSubMenu)
879 int x1, y1; 1001 {
880 menuitem_t *it; 1002 int x1, y1;
1003 menuitem_t *it;
881 menu_t *menu = item->entry.submenu.menu; 1004 menu_t *menu = item->entry.submenu.menu;
882 1005
883 drawtriangle (ActiveMenu->w, y, +1); 1006 drawtriangle (ActiveMenu->w, y, +1);
884 1007
885 name = menu->name; 1008 name = menu->name;
886 len = menu->len; 1009 len = menu->len;
887 1010
888 y1 = ActiveMenu->y + y; 1011 y1 = ActiveMenu->y + y;
889 1012
890 menu->w = Menu_PixelWidth(menu); 1013 menu->w = Menu_PixelWidth (menu);
891 1014
892 /* place sub-menu at midpoint of parent menu */ 1015 /* place sub-menu at midpoint of parent menu */
893 x1 = ActiveMenu->w / 2; 1016 x1 = ActiveMenu->w / 2;
894 if (x1 > menu->w) /* right-flush menu if too small */ 1017 if (x1 > menu->w) /* right-flush menu if too small */
895 x1 += (x1 - menu->w); 1018 x1 += (x1 - menu->w);
896 x1 += x; 1019 x1 += x;
897 1020
898 /* find the height of this submenu */ 1021 /* find the height of this submenu */
899 for (h = 0, it = menu->head; it != NULL; it = it->next) 1022 for (h = 0, it = menu->head; it != NULL; it = it->next)
900 h += isSeparator(it->name) ? HEIGHT_SEPARATOR 1023 h += isSeparator (it->name) ? HEIGHT_SEPARATOR
901 : HEIGHT_TEXT + 2 * SHADOW; 1024 : HEIGHT_TEXT + 2 * MENU_SHADOW;
902 menu->h = h + 2 * SHADOW; 1025 menu->h = h + 2 * MENU_SHADOW;
903 1026
904 /* ensure menu is in window limits */ 1027 /* ensure menu is in window limits */
905 if ((x1 + menu->w) >= TermWin.width) 1028 if ((x1 + menu->w) >= width)
906 x1 = (TermWin_TotalWidth() - menu->w); 1029 x1 = (this->width - menu->w);
907 1030
908 if ((y1 + menu->h) >= TermWin.height) 1031 if ((y1 + menu->h) >= height)
909 y1 = (TermWin_TotalHeight() - menu->h); 1032 y1 = (this->height - menu->h);
910 1033
911 menu->x = (x1 < 0 ? 0 : x1); 1034 menu->x = (x1 < 0 ? 0 : x1);
912 menu->y = (y1 < 0 ? 0 : y1); 1035 menu->y = (y1 < 0 ? 0 : y1);
1036 }
913 } else if (item->name2 && !STRCMP(name, item->name2)) 1037 else if (item->name2 && !strcmp (name, item->name2))
914 name = NULL; 1038 name = NULL;
915 1039
916 if (len && name) { 1040 if (len && name)
917#ifdef USE_XIM 1041 draw_string (*ActiveMenu->drawable, gc, fontset[0],
918 if (TermWin.fontset) 1042 xoff, 2 * MENU_SHADOW + y, name, len);
919 XmbDrawString(Xdisplay,
920 ActiveMenu->win, TermWin.fontset,
921 gc, xoff,
922 2 * SHADOW + y + TermWin.font->ascent + 1,
923 name, len);
924 else
925#endif
926 XDrawString(Xdisplay, ActiveMenu->win, gc, xoff,
927 2 * SHADOW + y + TermWin.font->ascent + 1,
928 name, len);
929 }
930 1043
931 len = item->len2; 1044 len = item->len2;
932 name = item->name2; 1045 name = item->name2;
1046
933 if (len && name) { 1047 if (len && name)
934#ifdef USE_XIM 1048 draw_string (*ActiveMenu->drawable, gc, fontset[0],
935 if (TermWin.fontset) 1049 ActiveMenu->w - (xoff + Width2Pixel (xright)), 2 * MENU_SHADOW + y, name, len);
936 XmbDrawString(Xdisplay, 1050
937 ActiveMenu->win, TermWin.fontset,
938 gc,
939 ActiveMenu->w - (xoff + Width2Pixel(xright)),
940 2 * SHADOW + y + TermWin.font->ascent + 1,
941 name, len);
942 else
943#endif
944 XDrawString(Xdisplay, ActiveMenu->win, gc,
945 ActiveMenu->w - (xoff + Width2Pixel(xright)),
946 2 * SHADOW + y + TermWin.font->ascent + 1,
947 name, len);
948 }
949 h = HEIGHT_TEXT + 2 * SHADOW; 1051 h = HEIGHT_TEXT + 2 * MENU_SHADOW;
950 } 1052 }
951 y += h; 1053 y += h;
952 } 1054 }
953} 1055}
954 1056
955void 1057void
956rxvt_term::menu_display (void (*update)(rxvt_t *)) 1058rxvt_term::menu_display (void (rxvt_term::*update) ())
957{ 1059{
958 menu_t *ActiveMenu = ActiveMenu;
959
960 if (ActiveMenu == NULL) 1060 if (ActiveMenu == NULL)
961 return; 1061 return;
1062
1063 delete ActiveMenu->drawable;
962 if (ActiveMenu->win != None) 1064 if (ActiveMenu->win != None)
963 XDestroyWindow(Xdisplay, ActiveMenu->win); 1065 XDestroyWindow (display->display, ActiveMenu->win);
964 ActiveMenu->win = None; 1066 ActiveMenu->win = None;
965 ActiveMenu->item = NULL; 1067 ActiveMenu->item = NULL;
966 1068
967 if (ActiveMenu->parent == NULL) 1069 if (ActiveMenu->parent == NULL)
968 drawbox_menubar (ActiveMenu->x, ActiveMenu->len, +1); 1070 drawbox_menubar (ActiveMenu->x, ActiveMenu->len, +1);
1071
969 ActiveMenu = ActiveMenu->parent; 1072 ActiveMenu = ActiveMenu->parent;
970 update(r); 1073 (this->*update) ();
971} 1074}
972 1075
973void 1076void
974rxvt_term::menu_hide_all () 1077rxvt_term::menu_hide_all ()
975{ 1078{
976 menu_display (rxvt_menu_hide_all); 1079 menu_display (&rxvt_term::menu_hide_all);
977} 1080}
978 1081
979void 1082void
980rxvt_term::menu_hide () 1083rxvt_term::menu_hide ()
981{ 1084{
982 menu_display (rxvt_menu_show); 1085 menu_display (&rxvt_term::menu_show);
983} 1086}
984 1087
985void 1088void
986rxvt_term::menu_clear (menu_t *menu) 1089rxvt_term::menu_clear (menu_t *menu)
987{ 1090{
988 if (menu != NULL) { 1091 if (menu != NULL)
1092 {
989 menuitem_t *item = menu->tail; 1093 menuitem_t *item = menu->tail;
990 1094
991 while (item != NULL) { 1095 while (item != NULL)
1096 {
992 menuitem_free (menu, item); 1097 menuitem_free (menu, item);
993 /* it didn't get freed ... why? */ 1098 /* it didn't get freed ... why? */
994 if (item == menu->tail) 1099 if (item == menu->tail)
995 return; 1100 return;
996 item = menu->tail; 1101 item = menu->tail;
997 } 1102 }
998 menu->width = 0; 1103 menu->width = 0;
999 } 1104 }
1000} 1105}
1001 1106
1002void 1107void
1003rxvt_term::menubar_clear () 1108rxvt_term::menubar_clear ()
1004{ 1109{
1005 bar_t *CurrentBar = CurrentBar;
1006
1007 if (CurrentBar != NULL) { 1110 if (CurrentBar != NULL)
1111 {
1008 menu_t *menu = CurrentBar->tail; 1112 menu_t *menu = CurrentBar->tail;
1009 1113
1010 while (menu != NULL) { 1114 while (menu != NULL)
1115 {
1011 menu_t *prev = menu->prev; 1116 menu_t *prev = menu->prev;
1012 1117
1013 menu_delete (menu); 1118 menu_delete (menu);
1014 menu = prev; 1119 menu = prev;
1015 } 1120 }
1016 CurrentBar->head = CurrentBar->tail = NULL; 1121 CurrentBar->head = CurrentBar->tail = NULL;
1017 1122
1018 if (CurrentBar->title) { 1123 if (CurrentBar->title)
1124 {
1019 free(CurrentBar->title); 1125 free (CurrentBar->title);
1020 CurrentBar->title = NULL; 1126 CurrentBar->title = NULL;
1021 } 1127 }
1128
1022 menuarrow_free (0); /* remove all arrow functions */ 1129 menuarrow_free (0); /* remove all arrow functions */
1023 } 1130 }
1131
1024 ActiveMenu = NULL; 1132 ActiveMenu = NULL;
1025} 1133}
1026 1134
1027#if (MENUBAR_MAX > 1) 1135#if (MENUBAR_MAX > 1)
1028/* find if menu already exists */ 1136/* find if menu already exists */
1029bar_t * 1137bar_t *
1030rxvt_term::menubar_find (const char *name) 1138rxvt_term::menubar_find (const char *name)
1031{ 1139{
1032 bar_t *bar = CurrentBar; 1140 bar_t *bar = CurrentBar;
1033 1141
1034#ifdef DEBUG_MENUBAR_STACKING 1142#ifdef DEBUG_MENUBAR_STACKING
1035 fprintf(stderr, "looking for [menu:%s] ...", name ? name : "(nil)"); 1143 fprintf (stderr, "looking for [menu:%s] ...", name ? name : " (nil)");
1036#endif 1144#endif
1037 if (bar == NULL || name == NULL) 1145 if (bar == NULL || name == NULL)
1038 return NULL; 1146 return NULL;
1039 1147
1040 if (STRLEN(name) && STRCMP(name, "*")) { 1148 if (strlen (name) && strcmp (name, "*"))
1041 do { 1149 {
1042 if (!STRCMP(bar->name, name)) { 1150 do
1151 {
1152 if (!strcmp (bar->name, name))
1153 {
1043#ifdef DEBUG_MENUBAR_STACKING 1154#ifdef DEBUG_MENUBAR_STACKING
1044 fprintf(stderr, " found!\n"); 1155 fprintf (stderr, " found!\n");
1045#endif 1156#endif
1046 return bar; 1157 return bar;
1047 } 1158 }
1048 bar = bar->next; 1159 bar = bar->next;
1049 } 1160 }
1050 while (bar != CurrentBar); 1161 while (bar != CurrentBar);
1051 bar = NULL; 1162 bar = NULL;
1052 } 1163 }
1053#ifdef DEBUG_MENUBAR_STACKING 1164#ifdef DEBUG_MENUBAR_STACKING
1054 fprintf(stderr, "%s found!\n", (bar ? "" : " NOT")); 1165 fprintf (stderr, "%s found!\n", (bar ? "" : " NOT"));
1055#endif 1166#endif
1056 1167
1057 return bar; 1168 return bar;
1058} 1169}
1059 1170
1060int 1171int
1061rxvt_term::menubar_push (const char *name) 1172rxvt_term::menubar_push (const char *name)
1062{ 1173{
1063 int ret = 1; 1174 int ret = 1;
1064 bar_t *bar; 1175 bar_t *bar;
1065 1176
1066 if (CurrentBar == NULL) { 1177 if (CurrentBar == NULL)
1178 {
1067 /* allocate first one */ 1179 /* allocate first one */
1068 bar = (bar_t *) rxvt_malloc(sizeof(bar_t)); 1180 bar = (bar_t *) rxvt_malloc (sizeof (bar_t));
1069 1181
1070 MEMSET(bar, 0, sizeof(bar_t)); 1182 memset (bar, 0, sizeof (bar_t));
1071 /* circular linked-list */ 1183 /* circular linked-list */
1072 bar->next = bar->prev = bar; 1184 bar->next = bar->prev = bar;
1073 bar->head = bar->tail = NULL; 1185 bar->head = bar->tail = NULL;
1074 bar->title = NULL; 1186 bar->title = NULL;
1075 CurrentBar = bar;
1076 Nbars++;
1077
1078 menubar_clear ();
1079 } else {
1080 /* find if menu already exists */
1081 bar = menubar_find (name);
1082 if (bar != NULL) {
1083 /* found it, use it */
1084 CurrentBar = bar; 1187 CurrentBar = bar;
1085 } else { 1188 Nbars++;
1189
1190 menubar_clear ();
1191 }
1192 else
1193 {
1194 /* find if menu already exists */
1195 bar = menubar_find (name);
1196 if (bar != NULL)
1197 {
1198 /* found it, use it */
1199 CurrentBar = bar;
1200 }
1201 else
1202 {
1086 /* create if needed, or reuse the existing empty menubar */ 1203 /* create if needed, or reuse the existing empty menubar */
1087 if (CurrentBar->head != NULL) { 1204 if (CurrentBar->head != NULL)
1205 {
1088 /* need to malloc another one */ 1206 /* need to malloc another one */
1089 if (Nbars < MENUBAR_MAX) 1207 if (Nbars < MENUBAR_MAX)
1090 bar = (bar_t *) rxvt_malloc(sizeof(bar_t)); 1208 bar = (bar_t *) rxvt_malloc (sizeof (bar_t));
1091 else 1209 else
1092 bar = NULL; 1210 bar = NULL;
1093 1211
1094 /* malloc failed or too many menubars, reuse another */ 1212 /* malloc failed or too many menubars, reuse another */
1095 if (bar == NULL) { 1213 if (bar == NULL)
1214 {
1096 bar = CurrentBar->next; 1215 bar = CurrentBar->next;
1097 ret = -1; 1216 ret = -1;
1098 } else { 1217 }
1218 else
1219 {
1099 bar->head = bar->tail = NULL; 1220 bar->head = bar->tail = NULL;
1100 bar->title = NULL; 1221 bar->title = NULL;
1101 1222
1102 bar->next = CurrentBar->next; 1223 bar->next = CurrentBar->next;
1103 CurrentBar->next = bar; 1224 CurrentBar->next = bar;
1104 bar->prev = CurrentBar; 1225 bar->prev = CurrentBar;
1105 bar->next->prev = bar; 1226 bar->next->prev = bar;
1106 1227
1107 Nbars++; 1228 Nbars++;
1108 } 1229 }
1109 CurrentBar = bar; 1230 CurrentBar = bar;
1110 1231
1232 }
1233
1234 menubar_clear ();
1235 }
1111 } 1236 }
1112 menubar_clear ();
1113 }
1114 }
1115 1237
1116/* give menubar this name */ 1238 /* give menubar this name */
1117 STRNCPY(CurrentBar->name, name, MAXNAME); 1239 strncpy (CurrentBar->name, name, MAXNAME);
1118 CurrentBar->name[MAXNAME - 1] = '\0'; 1240 CurrentBar->name[MAXNAME - 1] = '\0';
1119 1241
1120 return ret; 1242 return ret;
1121} 1243}
1122 1244
1123/* switch to a menu called NAME and remove it */ 1245/* switch to a menu called NAME and remove it */
1124void 1246void
1125rxvt_term::menubar_remove (const char *name) 1247rxvt_term::menubar_remove (const char *name)
1126{ 1248{
1127 bar_t *bar; 1249 bar_t *bar;
1128 1250
1129 if ((bar = menubar_find (name)) == NULL) 1251 if ((bar = menubar_find (name)) == NULL)
1130 return; 1252 return;
1131 CurrentBar = bar; 1253 CurrentBar = bar;
1132 1254
1255 do
1133 do { 1256 {
1134 menubar_clear (); 1257 menubar_clear ();
1135 /* 1258 /*
1136 * pop a menubar, clean it up first 1259 * pop a menubar, clean it up first
1137 */ 1260 */
1138 if (CurrentBar != NULL) { 1261 if (CurrentBar != NULL)
1262 {
1139 bar_t *prev = CurrentBar->prev; 1263 bar_t *prev = CurrentBar->prev;
1140 bar_t *next = CurrentBar->next; 1264 bar_t *next = CurrentBar->next;
1141 1265
1142 if (prev == next && prev == CurrentBar) { /* only 1 left */ 1266 if (prev == next && prev == CurrentBar)
1143 prev = NULL; 1267 { /* only 1 left */
1144 Nbars = 0; /* safety */ 1268 prev = NULL;
1145 } else { 1269 Nbars = 0; /* safety */
1146 next->prev = prev; 1270 }
1147 prev->next = next; 1271 else
1148 Nbars--; 1272 {
1273 next->prev = prev;
1274 prev->next = next;
1275 Nbars--;
1276 }
1277
1278 free (CurrentBar);
1279 CurrentBar = prev;
1280 }
1149 } 1281 }
1150
1151 free(CurrentBar);
1152 CurrentBar = prev;
1153 }
1154 }
1155 while (CurrentBar && !STRCMP(name, "*")); 1282 while (CurrentBar && !strcmp (name, "*"));
1156} 1283}
1157 1284
1158void 1285void
1159rxvt_action_decode(FILE *fp, action_t *act) 1286rxvt_action_decode (FILE *fp, action_t *act)
1160{ 1287{
1161 unsigned char *str; 1288 char *str;
1162 short len; 1289 short len;
1163 1290
1164 if (act == NULL || (len = act->len) == 0 || (str = act->str) == NULL) 1291 if (act == NULL || (len = act->len) == 0 || (str = act->str) == NULL)
1165 return; 1292 return;
1166 1293
1167 if (act->type == MenuTerminalAction) { 1294 if (act->type == MenuTerminalAction)
1295 {
1168 fprintf(fp, "^@"); 1296 fprintf (fp, "^@");
1169 /* can strip trailing ^G from XTerm sequence */ 1297 /* can strip trailing ^G from XTerm sequence */
1170 if (str[0] == C0_ESC && str[1] == ']' && str[len - 1] == C0_BEL) 1298 if (str[0] == C0_ESC && str[1] == ']' && str[len - 1] == C0_BEL)
1171 len--; 1299 len--;
1300 }
1172 } else if (str[0] == C0_ESC) { 1301 else if (str[0] == C0_ESC)
1302 {
1173 switch (str[1]) { 1303 switch (str[1])
1174 case '[': 1304 {
1175 case ']': 1305 case '[':
1176 break; 1306 case ']':
1307 break;
1177 1308
1178 case 'x': 1309 case 'x':
1179 /* can strip trailing '\r' from M-x sequence */ 1310 /* can strip trailing '\r' from M-x sequence */
1180 if (str[len - 1] == '\r') 1311 if (str[len - 1] == '\r')
1181 len--; 1312 len--;
1182 /* FALLTHROUGH */ 1313 /* FALLTHROUGH */
1183 1314
1184 default: 1315 default:
1185 fprintf(fp, "M-"); /* meta prefix */ 1316 fprintf (fp, "M-"); /* meta prefix */
1186 str++; 1317 str++;
1187 len--; 1318 len--;
1188 break; 1319 break;
1189 } 1320 }
1190 } 1321 }
1191/* 1322
1323 /*
1192 * control character form is preferred, since backslash-escaping 1324 * control character form is preferred, since backslash-escaping
1193 * can be really ugly looking when the backslashes themselves also 1325 * can be really ugly looking when the backslashes themselves also
1194 * have to be escaped to avoid Shell (or whatever scripting 1326 * have to be escaped to avoid Shell (or whatever scripting
1195 * language) interpretation 1327 * language) interpretation
1196 */ 1328 */
1197 while (len > 0) { 1329 while (len > 0)
1198 unsigned char ch = *str++; 1330 {
1331 char ch = *str++;
1199 1332
1200 switch (ch) { 1333 switch (ch)
1201 case C0_ESC: 1334 {
1335 case C0_ESC:
1202 fprintf(fp, "\\E"); 1336 fprintf (fp, "\\E");
1203 break; /* escape */ 1337 break; /* escape */
1204 case '\r': 1338 case '\r':
1205 fprintf(fp, "\\r"); 1339 fprintf (fp, "\\r");
1206 break; /* carriage-return */ 1340 break; /* carriage-return */
1207 case '\\': 1341 case '\\':
1208 fprintf(fp, "\\\\"); 1342 fprintf (fp, "\\\\");
1209 break; /* backslash */ 1343 break; /* backslash */
1210 case '^': 1344 case '^':
1211 fprintf(fp, "\\^"); 1345 fprintf (fp, "\\^");
1212 break; /* caret */ 1346 break; /* caret */
1213 case 127: 1347 case 127:
1214 fprintf(fp, "^?"); 1348 fprintf (fp, "^?");
1215 default: 1349 default:
1216 if (ch <= 31) 1350 if (ch <= 31)
1217 fprintf(fp, "^%c", ('@' + ch)); 1351 fprintf (fp, "^%c", ('@' + ch));
1218 else if (ch > 127) 1352 else if ((unsigned char)ch > 127)
1219 fprintf(fp, "\\%o", ch); 1353 fprintf (fp, "\\%o", ch);
1220 else 1354 else
1221 fprintf(fp, "%c", ch); 1355 fprintf (fp, "%c", ch);
1222 break; 1356 break;
1223 } 1357 }
1224 len--; 1358
1359 len--;
1225 } 1360 }
1361
1226 fprintf(fp, "\n"); 1362 fprintf (fp, "\n");
1227} 1363}
1228 1364
1229void 1365void
1230rxvt_menu_dump(FILE *fp, menu_t *menu) 1366rxvt_menu_dump (FILE *fp, menu_t *menu)
1231{ 1367{
1232 menuitem_t *item; 1368 menuitem_t *item;
1233 1369
1234/* create a new menu and clear it */ 1370 /* create a new menu and clear it */
1235 fprintf(fp, (menu->parent ? "./%s/*\n" : "/%s/*\n"), menu->name); 1371 fprintf (fp, (menu->parent ? "./%s/*\n" : "/%s/*\n"), menu->name);
1236 1372
1237 for (item = menu->head; item != NULL; item = item->next) { 1373 for (item = menu->head; item != NULL; item = item->next)
1374 {
1238 switch (item->entry.type) { 1375 switch (item->entry.type)
1376 {
1239 case MenuSubMenu: 1377 case MenuSubMenu:
1240 if (item->entry.submenu.menu == NULL) 1378 if (item->entry.submenu.menu == NULL)
1241 fprintf(fp, "> %s == NULL\n", item->name); 1379 fprintf (fp, "> %s == NULL\n", item->name);
1242 else 1380 else
1243 rxvt_menu_dump(fp, item->entry.submenu.menu); 1381 rxvt_menu_dump (fp, item->entry.submenu.menu);
1244 break; 1382 break;
1245 1383
1246 case MenuLabel: 1384 case MenuLabel:
1247 fprintf(fp, "{%s}\n", (STRLEN(item->name) ? item->name : "-")); 1385 fprintf (fp, "{%s}\n", (strlen (item->name) ? item->name : "-"));
1248 break; 1386 break;
1249 1387
1250 case MenuTerminalAction: 1388 case MenuTerminalAction:
1251 case MenuAction: 1389 case MenuAction:
1252 fprintf(fp, "{%s}", item->name); 1390 fprintf (fp, "{%s}", item->name);
1253 if (item->name2 != NULL && STRLEN(item->name2)) 1391 if (item->name2 != NULL && strlen (item->name2))
1254 fprintf(fp, "{%s}", item->name2); 1392 fprintf (fp, "{%s}", item->name2);
1255 fprintf(fp, "\t"); 1393 fprintf (fp, "\t");
1256 rxvt_action_decode(fp, &(item->entry.action)); 1394 rxvt_action_decode (fp, & (item->entry.action));
1257 break; 1395 break;
1258 } 1396 }
1259 } 1397 }
1260 1398
1261 fprintf(fp, (menu->parent ? "../\n" : "/\n\n")); 1399 fprintf (fp, (menu->parent ? "../\n" : "/\n\n"));
1262} 1400}
1263 1401
1264void 1402void
1265rxvt_term::menubar_dump (FILE *fp) 1403rxvt_term::menubar_dump (FILE *fp)
1266{ 1404{
1267 bar_t *bar = CurrentBar; 1405 bar_t *bar = CurrentBar;
1268 time_t t; 1406 time_t t;
1269 1407
1270 if (bar == NULL || fp == NULL) 1408 if (bar == NULL || fp == NULL)
1271 return; 1409 return;
1272 time(&t); 1410 time (&t);
1273 1411
1274 fprintf(fp, 1412 fprintf (fp,
1275 "# " APL_SUBCLASS " (%s) Pid: %u\n# Date: %s\n\n", 1413 "# " RESCLASS " (%s) Pid: %u\n# Date: %s\n\n",
1276 rs[Rs_name], (unsigned int)getpid(), ctime(&t)); 1414 rs[Rs_name], (unsigned int)getpid (), ctime (&t));
1277 1415
1278/* dump in reverse order */ 1416 /* dump in reverse order */
1279 bar = CurrentBar->prev; 1417 bar = CurrentBar->prev;
1418 do
1280 do { 1419 {
1281 menu_t *menu; 1420 menu_t *menu;
1282 int i; 1421 int i;
1283 1422
1284 fprintf(fp, "[menu:%s]\n", bar->name); 1423 fprintf (fp, "[menu:%s]\n", bar->name);
1285 1424
1286 if (bar->title != NULL) 1425 if (bar->title != NULL)
1287 fprintf(fp, "[title:%s]\n", bar->title); 1426 fprintf (fp, "[title:%s]\n", bar->title);
1288 1427
1289 for (i = 0; i < NARROWS; i++) { 1428 for (i = 0; i < NARROWS; i++)
1429 {
1290 switch (bar->arrows[i].type) { 1430 switch (bar->arrows[i].type)
1431 {
1291 case MenuTerminalAction: 1432 case MenuTerminalAction:
1292 case MenuAction: 1433 case MenuAction:
1293 fprintf(fp, "<%c>", Arrows[i].name); 1434 fprintf (fp, "<%c>", Arrows[i].name);
1294 rxvt_action_decode(fp, &(bar->arrows[i])); 1435 rxvt_action_decode (fp, & (bar->arrows[i]));
1295 break; 1436 break;
1296 } 1437 }
1297 } 1438 }
1298 fprintf(fp, "\n"); 1439 fprintf (fp, "\n");
1299 1440
1300 for (menu = bar->head; menu != NULL; menu = menu->next) 1441 for (menu = bar->head; menu != NULL; menu = menu->next)
1301 rxvt_menu_dump(fp, menu); 1442 rxvt_menu_dump (fp, menu);
1302 1443
1303 fprintf(fp, "\n[done:%s]\n\n", bar->name); 1444 fprintf (fp, "\n[done:%s]\n\n", bar->name);
1304 bar = bar->prev; 1445 bar = bar->prev;
1305 } 1446 }
1306 while (bar != CurrentBar->prev); 1447 while (bar != CurrentBar->prev);
1307} 1448}
1308#endif /* (MENUBAR_MAX > 1) */ 1449#endif /* (MENUBAR_MAX > 1) */
1309 1450
1310/* 1451/*
1311 * read in menubar commands from FILENAME 1452 * read in menubar commands from FILENAME
1323 * read `file' starting with [menu:tag] 1464 * read `file' starting with [menu:tag]
1324 */ 1465 */
1325void 1466void
1326rxvt_term::menubar_read (const char *filename) 1467rxvt_term::menubar_read (const char *filename)
1327{ 1468{
1328/* read in a menu from a file */ 1469 /* read in a menu from a file */
1329 FILE *fp; 1470 FILE *fp;
1330 char buffer[256]; 1471 char buffer[256];
1331 char *p, *file, *tag = NULL; 1472 char *p, *file, *tag = NULL;
1332 1473
1333 file = (char *)rxvt_File_find(filename, ".menu", rs[Rs_path]); 1474 file = (char *)rxvt_File_find (filename, ".menu", rs[Rs_path]);
1334 if (file == NULL) 1475 if (file == NULL)
1335 return; 1476 return;
1477
1336 fp = fopen(file, "rb"); 1478 fp = fopen (file, "rb");
1337 free(file); 1479 free (file);
1338 if (fp == NULL) 1480 if (fp == NULL)
1339 return; 1481 return;
1340 1482
1341#if (MENUBAR_MAX > 1) 1483#if (MENUBAR_MAX > 1)
1342/* semi-colon delimited */ 1484 /* semi-colon delimited */
1343 if ((tag = STRCHR(filename, ';')) != NULL) { 1485 if ((tag = strchr (filename, ';')) != NULL)
1344 tag++; 1486 {
1487 tag++;
1345 if (*tag == '\0') 1488 if (*tag == '\0')
1346 tag = NULL; 1489 tag = NULL;
1347 } 1490 }
1348#endif /* (MENUBAR_MAX > 1) */ 1491#endif /* (MENUBAR_MAX > 1) */
1349#ifdef DEBUG_MENU 1492#ifdef DEBUG_MENU
1350 fprintf(stderr, "[read:%s]\n", p); 1493 fprintf (stderr, "[read:%s]\n", p);
1351 if (tag) 1494 if (tag)
1352 fprintf(stderr, "looking for [menu:%s]\n", tag); 1495 fprintf (stderr, "looking for [menu:%s]\n", tag);
1353#endif 1496#endif
1354 1497
1355 while ((p = fgets(buffer, sizeof(buffer), fp)) != NULL) { 1498 while ((p = fgets (buffer, sizeof (buffer), fp)) != NULL)
1499 {
1356 int n; 1500 int n;
1357 1501
1358 if ((n = rxvt_Str_match(p, "[menu")) != 0) { 1502 if ((n = rxvt_Str_match (p, "[menu")) != 0)
1359 if (tag) { 1503 {
1504 if (tag)
1505 {
1360 /* looking for [menu:tag] */ 1506 /* looking for [menu:tag] */
1361 if (p[n] == ':' && p[n + 1] != ']') { 1507 if (p[n] == ':' && p[n + 1] != ']')
1362 n++; 1508 {
1509 n++;
1363 n += rxvt_Str_match(p + n, tag); 1510 n += rxvt_Str_match (p + n, tag);
1364 if (p[n] == ']') { 1511 if (p[n] == ']')
1512 {
1365#ifdef DEBUG_MENU 1513#ifdef DEBUG_MENU
1366 fprintf(stderr, "[menu:%s]\n", tag); 1514 fprintf (stderr, "[menu:%s]\n", tag);
1367#endif 1515#endif
1368 break; 1516 break;
1517 }
1518 }
1519 }
1520 else if (p[n] == ':' || p[n] == ']')
1521 break;
1522 }
1369 } 1523 }
1370 }
1371 } else if (p[n] == ':' || p[n] == ']')
1372 break;
1373 }
1374 }
1375 1524
1376/* found [menu], [menu:???] tag */ 1525 /* found [menu], [menu:???] tag */
1377 while (p != NULL) { 1526 while (p != NULL)
1527 {
1378 int n; 1528 int n;
1379 1529
1380#ifdef DEBUG_MENU 1530#ifdef DEBUG_MENU
1381 fprintf(stderr, "read line = %s\n", p); 1531 fprintf (stderr, "read line = %s\n", p);
1382#endif 1532#endif
1383 1533
1384 /* looking for [done:tag] or [done:] */ 1534 /* looking for [done:tag] or [done:] */
1385 if ((n = rxvt_Str_match(p, "[done")) != 0) { 1535 if ((n = rxvt_Str_match (p, "[done")) != 0)
1536 {
1386 if (p[n] == ']') { 1537 if (p[n] == ']')
1387 menu_readonly = 1; 1538 {
1388 break;
1389 } else if (p[n] == ':') {
1390 n++;
1391 if (p[n] == ']') {
1392 menu_readonly = 1; 1539 menu_readonly = 1;
1393 break; 1540 break;
1394 } else if (tag) { 1541 }
1542 else if (p[n] == ':')
1543 {
1544 n++;
1545 if (p[n] == ']')
1546 {
1547 menu_readonly = 1;
1548 break;
1549 }
1550 else if (tag)
1551 {
1395 n += rxvt_Str_match(p + n, tag); 1552 n += rxvt_Str_match (p + n, tag);
1396 if (p[n] == ']') { 1553 if (p[n] == ']')
1554 {
1397#ifdef DEBUG_MENU 1555#ifdef DEBUG_MENU
1398 fprintf(stderr, "[done:%s]\n", tag); 1556 fprintf (stderr, "[done:%s]\n", tag);
1399#endif 1557#endif
1400 menu_readonly = 1; 1558 menu_readonly = 1;
1401 break; 1559 break;
1402 } 1560 }
1403 } else { 1561 }
1562 else
1563 {
1404 /* what? ... skip this line */ 1564 /* what? ... skip this line */
1405 p[0] = COMMENT_CHAR; 1565 p[0] = COMMENT_CHAR;
1406 } 1566 }
1407 } 1567 }
1408 } 1568 }
1409 /* 1569
1570 /*
1410 * remove leading/trailing space 1571 * remove leading/trailing space
1411 * and strip-off leading/trailing quotes
1412 * skip blank or comment lines 1572 * skip blank or comment lines
1413 */ 1573 */
1414 rxvt_Str_trim(p); 1574 rxvt_Str_trim (p);
1415 if (*p && *p != '#') { 1575 if (*p && *p != '#')
1576 {
1416 menu_readonly = 0; /* if case we read another file */ 1577 menu_readonly = 0; /* if case we read another file */
1417 menubar_dispatch (p); 1578 menubar_dispatch (p);
1418 } 1579 }
1419 /* get another line */ 1580 /* get another line */
1420 p = fgets(buffer, sizeof(buffer), fp); 1581 p = fgets (buffer, sizeof (buffer), fp);
1421 } 1582 }
1422 1583
1423 fclose(fp); 1584 fclose (fp);
1424} 1585}
1425 1586
1426/* 1587/*
1427 * user interface for building/deleting and otherwise managing menus 1588 * user interface for building/deleting and otherwise managing menus
1428 */ 1589 */
1429void 1590void
1430rxvt_term::menubar_dispatch (char *str) 1591rxvt_term::menubar_dispatch (char *str)
1431{ 1592{
1432 int n, cmd; 1593 int n, cmd;
1433 char *path, *name, *name2; 1594 char *path, *name, *name2;
1434 1595
1435 if (menubar_visible(r) && ActiveMenu != NULL) 1596 if (menubar_visible () && ActiveMenu != NULL)
1436 menubar_expose (); 1597 menubar_expose ();
1437 else 1598 else
1438 ActiveMenu = NULL; 1599 ActiveMenu = NULL;
1439 1600
1440 cmd = *str; 1601 cmd = *str;
1441 switch (cmd) { 1602 switch (cmd)
1603 {
1442 case '.': 1604 case '.':
1443 case '/': /* absolute & relative path */ 1605 case '/': /* absolute & relative path */
1444 case MENUITEM_BEG: /* menuitem */ 1606 case MENUITEM_BEG: /* menuitem */
1445 /* add `+' prefix for these cases */ 1607 /* add `+' prefix for these cases */
1446 cmd = '+'; 1608 cmd = '+';
1447 break; 1609 break;
1448 1610
1449 case '+': 1611 case '+':
1450 case '-': 1612 case '-':
1451 str++; /* skip cmd character */ 1613 str++; /* skip cmd character */
1452 break; 1614 break;
1453 1615
1454 case '<': 1616 case '<':
1455#if (MENUBAR_MAX > 1) 1617#if (MENUBAR_MAX > 1)
1456 if (CurrentBar == NULL) 1618 if (CurrentBar == NULL)
1457 break; 1619 break;
1458#endif /* (MENUBAR_MAX > 1) */ 1620#endif /* (MENUBAR_MAX > 1) */
1459 if (str[1] && str[2] == '>') /* arrow commands */ 1621 if (str[1] && str[2] == '>') /* arrow commands */
1460 menuarrow_add (str); 1622 menuarrow_add (str);
1461 break; 1623 break;
1462 1624
1463 case '[': /* extended command */ 1625 case '[': /* extended command */
1464 while (str[0] == '[') { 1626 while (str[0] == '[')
1627 {
1465 char *next = (++str); /* skip leading '[' */ 1628 char *next = (++str); /* skip leading '[' */
1466 1629
1467 if (str[0] == ':') { /* [:command:] */
1468 do {
1469 next++;
1470 if ((next = STRCHR(next, ':')) == NULL)
1471 return; /* parse error */
1472 }
1473 while (next[1] != ']');
1474 /* remove and skip ':]' */
1475 *next = '\0';
1476 next += 2;
1477 } else {
1478 if ((next = STRCHR(next, ']')) == NULL)
1479 return; /* parse error */
1480 /* remove and skip ']' */
1481 *next = '\0';
1482 next++;
1483 }
1484
1485 if (str[0] == ':') { 1630 if (str[0] == ':')
1486 int saved; 1631 { /* [:command:] */
1632 do
1633 {
1634 next++;
1635 if ((next = strchr (next, ':')) == NULL)
1636 return; /* parse error */
1637 }
1638 while (next[1] != ']');
1639 /* remove and skip ':]' */
1640 *next = '\0';
1641 next += 2;
1642 }
1643 else
1644 {
1645 if ((next = strchr (next, ']')) == NULL)
1646 return; /* parse error */
1647 /* remove and skip ']' */
1648 *next = '\0';
1649 next++;
1650 }
1487 1651
1652 if (str[0] == ':')
1653 {
1654 int saved;
1655
1488 /* try and dispatch it, regardless of read/write status */ 1656 /* try and dispatch it, regardless of read/write status */
1489 saved = menu_readonly; 1657 saved = menu_readonly;
1490 menu_readonly = 0; 1658 menu_readonly = 0;
1491 menubar_dispatch (str + 1); 1659 menubar_dispatch (str + 1);
1492 menu_readonly = saved; 1660 menu_readonly = saved;
1493 } 1661 }
1494 /* these ones don't require menu stacking */ 1662 /* these ones don't require menu stacking */
1495 else if (!STRCMP(str, "clear")) { 1663 else if (!strcmp (str, "clear"))
1496 menubar_clear (); 1664 {
1665 menubar_clear ();
1666 }
1497 } else if (!STRCMP(str, "done") || rxvt_Str_match(str, "done:")) { 1667 else if (!strcmp (str, "done") || rxvt_Str_match (str, "done:"))
1498 menu_readonly = 1; 1668 {
1499 } else if (!STRCMP(str, "show")) { 1669 menu_readonly = 1;
1500 map_menuBar (1); 1670 }
1501 menu_readonly = 1; 1671 else if (!strcmp (str, "show"))
1502 } else if (!STRCMP(str, "hide")) { 1672 {
1503 map_menuBar (0); 1673 map_menuBar (1);
1504 menu_readonly = 1; 1674 menu_readonly = 1;
1675 }
1676 else if (!strcmp (str, "hide"))
1677 {
1678 map_menuBar (0);
1679 menu_readonly = 1;
1680 }
1505 } else if ((n = rxvt_Str_match(str, "read:")) != 0) { 1681 else if ((n = rxvt_Str_match (str, "read:")) != 0)
1682 {
1506 /* read in a menu from a file */ 1683 /* read in a menu from a file */
1507 str += n; 1684 str += n;
1508 menubar_read (str); 1685 menubar_read (str);
1686 }
1509 } else if ((n = rxvt_Str_match(str, "title:")) != 0) { 1687 else if ((n = rxvt_Str_match (str, "title:")) != 0)
1510 str += n; 1688 {
1689 str += n;
1511 if (CurrentBar != NULL && !menu_readonly) { 1690 if (CurrentBar != NULL && !menu_readonly)
1512 if (*str) { 1691 {
1513 name = rxvt_realloc(CurrentBar->title, 1692 if (*str)
1514 STRLEN(str) + 1); 1693 {
1515 if (name != NULL) { 1694 name = (char *)rxvt_realloc (CurrentBar->title, strlen (str) + 1);
1516 STRCPY(name, str); 1695 if (name != NULL)
1517 CurrentBar->title = name; 1696 {
1518 } 1697 strcpy (name, str);
1519 menubar_expose (); 1698 CurrentBar->title = name;
1520 } else { 1699 }
1521 free(CurrentBar->title); 1700 menubar_expose ();
1522 CurrentBar->title = NULL; 1701 }
1523 } 1702 else
1524 } 1703 {
1704 free (CurrentBar->title);
1705 CurrentBar->title = NULL;
1706 }
1707 }
1708 }
1525 } else if ((n = rxvt_Str_match(str, "pixmap:")) != 0) { 1709 else if ((n = rxvt_Str_match (str, "pixmap:")) != 0)
1526 str += n; 1710 {
1711 str += n;
1527 xterm_seq (XTerm_Pixmap, str, CHAR_ST); 1712 process_xterm_seq (XTerm_Pixmap, str, CHAR_ST);
1528 } 1713 }
1529#if (MENUBAR_MAX > 1) 1714#if (MENUBAR_MAX > 1)
1530 else if ((n = rxvt_Str_match(str, "rm")) != 0) { 1715 else if ((n = rxvt_Str_match (str, "rm")) != 0)
1531 str += n; 1716 {
1532 switch (str[0]) { 1717 str += n;
1533 case ':': 1718 switch (str[0])
1534 str++; 1719 {
1535 /* FALLTHROUGH */ 1720 case ':':
1536 case '\0': 1721 str++;
1537 /* FALLTHROUGH */ 1722 /* FALLTHROUGH */
1538 case '*': 1723 case '\0':
1539 menubar_remove (str); 1724 /* FALLTHROUGH */
1540 break; 1725 case '*':
1541 } 1726 menubar_remove (str);
1542 menu_readonly = 1; 1727 break;
1728 }
1729 menu_readonly = 1;
1730 }
1543 } else if ((n = rxvt_Str_match(str, "menu")) != 0) { 1731 else if ((n = rxvt_Str_match (str, "menu")) != 0)
1544 str += n; 1732 {
1545 switch (str[0]) { 1733 str += n;
1546 case ':': 1734 switch (str[0])
1547 str++; 1735 {
1548 /* add/access menuBar */ 1736 case ':':
1737 str++;
1738 /* add/access menuBar */
1549 if (*str != '\0' && *str != '*') 1739 if (*str != '\0' && *str != '*')
1550 menubar_push (str); 1740 menubar_push (str);
1551 break; 1741 break;
1552 default: 1742 default:
1553 if (CurrentBar == NULL) { 1743 if (CurrentBar == NULL)
1554 menubar_push ("default"); 1744 {
1555 } 1745 menubar_push ("default");
1556 } 1746 }
1747 }
1557 1748
1558 if (CurrentBar != NULL) 1749 if (CurrentBar != NULL)
1559 menu_readonly = 0; /* allow menu build commands */ 1750 menu_readonly = 0; /* allow menu build commands */
1560 } else if (!STRCMP(str, "dump")) { 1751 }
1752 else if (!strcmp (str, "dump"))
1753 {
1561 /* dump current menubars to a file */ 1754 /* dump current menubars to a file */
1562 FILE *fp; 1755 FILE *fp;
1563 1756
1564 /* enough space to hold the results */ 1757 /* enough space to hold the results */
1565 char buffer[32]; 1758 char buffer[32];
1566 1759
1567 sprintf(buffer, "/tmp/" APL_SUBCLASS "-%u", 1760 sprintf (buffer, "/tmp/" RESCLASS "-%u",
1568 (unsigned int)getpid()); 1761 (unsigned int)getpid ());
1569 1762
1570 if ((fp = fopen(buffer, "wb")) != NULL) { 1763 if ((fp = fopen (buffer, "wb")) != NULL)
1571 xterm_seq (XTerm_title, buffer, CHAR_ST); 1764 {
1572 menubar_dump (fp); 1765 process_xterm_seq (XTerm_title, buffer, CHAR_ST);
1573 fclose(fp); 1766 menubar_dump (fp);
1574 } 1767 fclose (fp);
1575 } else if (!STRCMP(str, "next")) { 1768 }
1576 if (CurrentBar) { 1769 }
1770 else if (!strcmp (str, "next"))
1771 {
1772 if (CurrentBar)
1773 {
1577 CurrentBar = CurrentBar->next; 1774 CurrentBar = CurrentBar->next;
1578 menu_readonly = 1; 1775 menu_readonly = 1;
1579 } 1776 }
1580 } else if (!STRCMP(str, "prev")) { 1777 }
1581 if (CurrentBar) { 1778 else if (!strcmp (str, "prev"))
1779 {
1780 if (CurrentBar)
1781 {
1582 CurrentBar = CurrentBar->prev; 1782 CurrentBar = CurrentBar->prev;
1583 menu_readonly = 1; 1783 menu_readonly = 1;
1584 } 1784 }
1585 } else if (!STRCMP(str, "swap")) { 1785 }
1586 /* swap the top 2 menus */ 1786 else if (!strcmp (str, "swap"))
1587 if (CurrentBar) { 1787 {
1788 /* swap the top 2 menus */
1789 if (CurrentBar)
1790 {
1588 bar_t *cbprev = CurrentBar->prev; 1791 bar_t *cbprev = CurrentBar->prev;
1589 bar_t *cbnext = CurrentBar->next; 1792 bar_t *cbnext = CurrentBar->next;
1590 1793
1591 cbprev->next = cbnext; 1794 cbprev->next = cbnext;
1592 cbnext->prev = cbprev; 1795 cbnext->prev = cbprev;
1593 1796
1594 CurrentBar->next = cbprev; 1797 CurrentBar->next = cbprev;
1595 CurrentBar->prev = cbprev->prev; 1798 CurrentBar->prev = cbprev->prev;
1596 1799
1597 cbprev->prev->next = CurrentBar; 1800 cbprev->prev->next = CurrentBar;
1598 cbprev->prev = CurrentBar; 1801 cbprev->prev = CurrentBar;
1599 1802
1600 CurrentBar = cbprev; 1803 CurrentBar = cbprev;
1601 menu_readonly = 1; 1804 menu_readonly = 1;
1602 } 1805 }
1603 } 1806 }
1604#endif /* (MENUBAR_MAX > 1) */ 1807#endif /* (MENUBAR_MAX > 1) */
1605 str = next; 1808 str = next;
1606 1809
1607 BuildMenu = ActiveMenu = NULL; 1810 BuildMenu = ActiveMenu = NULL;
1608 menubar_expose (); 1811 menubar_expose ();
1609#ifdef DEBUG_MENUBAR_STACKING 1812#ifdef DEBUG_MENUBAR_STACKING
1610 fprintf(stderr, "menus are read%s\n", 1813 fprintf (stderr, "menus are read%s\n",
1611 menu_readonly ? "only" : "/write"); 1814 menu_readonly ? "only" : "/write");
1612#endif 1815#endif
1613 } 1816
1614 return; 1817 }
1615 break; 1818 return;
1819 break;
1616 } 1820 }
1617 1821
1618#if (MENUBAR_MAX > 1) 1822#if (MENUBAR_MAX > 1)
1619 if (CurrentBar == NULL) 1823 if (CurrentBar == NULL)
1620 return; 1824 return;
1621 if (menu_readonly) { 1825 if (menu_readonly)
1826 {
1622#ifdef DEBUG_MENUBAR_STACKING 1827#ifdef DEBUG_MENUBAR_STACKING
1623 fprintf(stderr, "menus are read%s\n", 1828 fprintf (stderr, "menus are read%s\n",
1624 menu_readonly ? "only" : "/write"); 1829 menu_readonly ? "only" : "/write");
1625#endif 1830#endif
1626 return; 1831 return;
1627 } 1832 }
1628#endif /* (MENUBAR_MAX > 1) */ 1833#endif /* (MENUBAR_MAX > 1) */
1629 1834
1630 switch (cmd) { 1835 switch (cmd)
1836 {
1631 case '+': 1837 case '+':
1632 case '-': 1838 case '-':
1633 path = name = str; 1839 path = name = str;
1634 1840
1635 name2 = NULL; 1841 name2 = NULL;
1636 /* parse STR, allow spaces inside (name) */ 1842 /* parse STR, allow spaces inside (name) */
1637 if (path[0] != '\0') { 1843 if (path[0] != '\0')
1638 name = STRCHR(path, MENUITEM_BEG); 1844 {
1639 str = STRCHR(path, MENUITEM_END); 1845 name = strchr (path, MENUITEM_BEG);
1846 str = strchr (path, MENUITEM_END);
1640 if (name != NULL || str != NULL) { 1847 if (name != NULL || str != NULL)
1848 {
1641 if (name == NULL || str == NULL || str <= (name + 1) 1849 if (name == NULL || str == NULL || str <= (name + 1)
1642 || (name > path && name[-1] != '/')) { 1850 || (name > path && name[-1] != '/'))
1643 rxvt_print_error("menu error <%s>\n", path); 1851 {
1644 break; 1852 rxvt_warn ("menu error A<%s>, continuing.\n", path);
1645 } 1853 break;
1646 if (str[1] == MENUITEM_BEG) { 1854 }
1647 name2 = (str + 2); 1855 if (str[1] == MENUITEM_BEG)
1648 str = STRCHR(name2, MENUITEM_END); 1856 {
1857 name2 = (str + 2);
1858 str = strchr (name2, MENUITEM_END);
1649 1859
1650 if (str == NULL) { 1860 if (str == NULL)
1651 rxvt_print_error("menu error <%s>\n", path); 1861 {
1652 break; 1862 rxvt_warn ("menu error B<%s>, continuing.\n", path);
1653 } 1863 break;
1864 }
1654 name2[-2] = '\0'; /* remove prev MENUITEM_END */ 1865 name2[-2] = '\0'; /* remove prev MENUITEM_END */
1655 } 1866 }
1656 if (name > path && name[-1] == '/') 1867 if (name > path && name[-1] == '/')
1657 name[-1] = '\0'; 1868 name[-1] = '\0';
1658 1869
1659 *name++ = '\0'; /* delimit */ 1870 *name++ = '\0'; /* delimit */
1660 *str++ = '\0'; /* delimit */ 1871 *str++ = '\0'; /* delimit */
1661 1872
1662 while (isspace(*str)) 1873 while (isspace (*str))
1663 str++; /* skip space */ 1874 str++; /* skip space */
1664 } 1875 }
1665#ifdef DEBUG_MENU 1876#ifdef DEBUG_MENU
1666 fprintf(stderr, 1877 fprintf (stderr,
1667 "`%c' path = <%s>, name = <%s>, name2 = <%s>, action = <%s>\n", 1878 "`%c' path = <%s>, name = <%s>, name2 = <%s>, action = <%s>\n",
1668 cmd, (path ? path : "(nil)"), (name ? name : "(nil)"), 1879 cmd, (path ? path : " (nil)"), (name ? name : " (nil)"),
1669 (name2 ? name2 : "(nil)"), (str ? str : "(nil)") 1880 (name2 ? name2 : " (nil)"), (str ? str : " (nil)")
1670 ); 1881 );
1671#endif 1882#endif
1672 } 1883
1884 }
1673 /* process the different commands */ 1885 /* process the different commands */
1674 switch (cmd) { 1886 switch (cmd)
1887 {
1675 case '+': /* add/replace existing menu or menuitem */ 1888 case '+': /* add/replace existing menu or menuitem */
1676 if (path[0] != '\0') { 1889 if (path[0] != '\0')
1677 int len; 1890 {
1891 int len;
1678 1892
1679 path = menu_find_base (&(BuildMenu), path); 1893 path = menu_find_base (& (BuildMenu), path);
1680 len = STRLEN(path); 1894 len = strlen (path);
1681 1895
1682 /* don't allow menus called `*' */ 1896 /* don't allow menus called `*' */
1683 if (path[0] == '*') { 1897 if (path[0] == '*')
1684 menu_clear (BuildMenu); 1898 {
1685 break; 1899 menu_clear (BuildMenu);
1686 } else if (len >= 2 && !STRCMP((path + len - 2), "/*")) { 1900 break;
1687 path[len - 2] = '\0'; 1901 }
1688 } 1902 else if (len >= 2 && !strcmp ((path + len - 2), "/*"))
1689 if (path[0] != '\0') 1903 {
1904 path[len - 2] = '\0';
1905 }
1906 if (path[0] != '\0')
1690 BuildMenu = menu_add (BuildMenu, path); 1907 BuildMenu = menu_add (BuildMenu, path);
1691 } 1908 }
1692 if (name != NULL && name[0] != '\0') 1909 if (name != NULL && name[0] != '\0')
1693 rxvt_menuitem_add(BuildMenu, 1910 rxvt_menuitem_add (BuildMenu,
1694 (STRCMP(name, SEPARATOR_NAME) ? name : ""), 1911 (strcmp (name, SEPARATOR_NAME) ? name : ""),
1695 name2, str); 1912 name2, str);
1696 break; 1913 break;
1697 1914
1698 case '-': /* delete menu entry */ 1915 case '-': /* delete menu entry */
1699 if (!STRCMP(path, "/*") && (name == NULL || name[0] == '\0')) { 1916 if (!strcmp (path, "/*") && (name == NULL || name[0] == '\0'))
1700 menubar_clear (); 1917 {
1701 BuildMenu = NULL; 1918 menubar_clear ();
1702 menubar_expose (); 1919 BuildMenu = NULL;
1703 break; 1920 menubar_expose ();
1704 } else if (path[0] != '\0') { 1921 break;
1705 int len; 1922 }
1923 else if (path[0] != '\0')
1924 {
1925 int len;
1706 menu_t *menu = BuildMenu; 1926 menu_t *menu = BuildMenu;
1707 1927
1708 path = menu_find_base (&menu, path); 1928 path = menu_find_base (&menu, path);
1709 len = STRLEN(path); 1929 len = strlen (path);
1710 1930
1711 /* submenu called `*' clears all menu items */ 1931 /* submenu called `*' clears all menu items */
1712 if (path[0] == '*') { 1932 if (path[0] == '*')
1713 menu_clear (menu); 1933 {
1714 break; /* done */ 1934 menu_clear (menu);
1715 } else if (len >= 2 && !STRCMP(&path[len - 2], "/*")) { 1935 break; /* done */
1716 /* done */ 1936 }
1717 break; 1937 else if (len >= 2 && !strcmp (&path[len - 2], "/*"))
1718 } else if (path[0] != '\0') { 1938 {
1719 BuildMenu = NULL; 1939 /* done */
1720 break; 1940 break;
1721 } else 1941 }
1722 BuildMenu = menu; 1942 else if (path[0] != '\0')
1723 } 1943 {
1944 BuildMenu = NULL;
1945 break;
1946 }
1947 else
1948 BuildMenu = menu;
1949 }
1950
1724 if (BuildMenu != NULL) { 1951 if (BuildMenu != NULL)
1952 {
1725 if (name == NULL || name[0] == '\0') 1953 if (name == NULL || name[0] == '\0')
1726 BuildMenu = menu_delete (BuildMenu); 1954 BuildMenu = menu_delete (BuildMenu);
1727 else { 1955 else
1728 const char *n1; 1956 {
1729 menuitem_t *item; 1957 const char *n1;
1730 menu_t *BuildMenu = BuildMenu; 1958 menuitem_t *item;
1731 1959
1732 n1 = STRCMP(name, SEPARATOR_NAME) ? name : ""; 1960 n1 = strcmp (name, SEPARATOR_NAME) ? name : "";
1733 item = rxvt_menuitem_find(BuildMenu, n1); 1961 item = rxvt_menuitem_find (BuildMenu, n1);
1734 if (item != NULL && item->entry.type != MenuSubMenu) { 1962 if (item != NULL && item->entry.type != MenuSubMenu)
1735 menuitem_free (BuildMenu, item); 1963 {
1964 menuitem_free (BuildMenu, item);
1736 1965
1737 /* fix up the width */ 1966 /* fix up the width */
1738 BuildMenu->width = 0; 1967 BuildMenu->width = 0;
1739 for (item = BuildMenu->head; item != NULL; 1968 for (item = BuildMenu->head; item != NULL;
1740 item = item->next) { 1969 item = item->next)
1970 {
1741 short l = item->len + item->len2; 1971 short l = item->len + item->len2;
1742 1972
1743 MAX_IT(BuildMenu->width, l); 1973 max_it (BuildMenu->width, l);
1744 } 1974 }
1745 } 1975 }
1746 } 1976 }
1747 menubar_expose (); 1977
1748 } 1978 menubar_expose ();
1979 }
1980 break;
1981 }
1749 break; 1982 break;
1750 }
1751 break;
1752 } 1983 }
1753} 1984}
1754 1985
1755void 1986void
1756rxvt_term::draw_Arrows (int name, int state) 1987rxvt_term::draw_Arrows (int name, int state)
1757{ 1988{
1758 GC top, bot; 1989 GC top, bot;
1759 1990
1760 int i; 1991 int i;
1761 1992
1762#ifdef MENU_SHADOW_IN 1993#ifdef MENU_SHADOW_IN
1763 state = -state; 1994 state = -state;
1764#endif 1995#endif
1765 switch (state) { 1996 switch (state)
1997 {
1766 case +1: 1998 case +1:
1767 top = topShadowGC; 1999 top = topShadowGC;
1768 bot = botShadowGC; 2000 bot = botShadowGC;
1769 break; /* SHADOW_OUT */ 2001 break; /* SHADOW_OUT */
1770 case -1: 2002 case -1:
1771 top = botShadowGC; 2003 top = botShadowGC;
1772 bot = topShadowGC; 2004 bot = topShadowGC;
1773 break; /* SHADOW_IN */ 2005 break; /* SHADOW_IN */
1774 default: 2006 default:
1775 top = bot = scrollbarGC; 2007 top = bot = scrollbarGC;
1776 break; /* neutral */ 2008 break; /* neutral */
1777 } 2009 }
1778 2010
1779 if (!Arrows_x) 2011 if (!Arrows_x)
1780 return; 2012 return;
1781 2013
1782 for (i = 0; i < NARROWS; i++) { 2014 for (i = 0; i < NARROWS; i++)
2015 {
1783 const int w = Width2Pixel(1); 2016 const int w = Width2Pixel (1);
1784 const int y = (menuBar_TotalHeight() - w) / 2; 2017 const int y = (menuBar_TotalHeight () - w) / 2;
1785 int x = Arrows_x + (5 * Width2Pixel(i)) / 4; 2018 int x = Arrows_x + (5 * Width2Pixel (i)) / 4;
1786 2019
1787 if (!name || name == Arrows[i].name) 2020 if (!name || name == Arrows[i].name)
1788 rxvt_Draw_Triangle(Xdisplay, menuBar.win, top, bot, x, y, w, 2021 rxvt_Draw_Triangle (display->display, menuBar.win, top, bot, x, y, w,
1789 Arrows[i].name); 2022 Arrows[i].name);
1790 } 2023 }
1791 XFlush(Xdisplay); 2024 XFlush (display->display);
1792} 2025}
1793 2026
1794void 2027void
1795rxvt_term::menubar_expose () 2028rxvt_term::menubar_expose ()
1796{ 2029{
1797 menu_t *menu; 2030 menu_t *menu;
1798 int x; 2031 int x;
1799 2032
1800 if (!menubar_visible(r) || menuBar.win == 0) 2033 if (!menubar_visible () || menuBar.win == 0)
1801 return; 2034 return;
1802 2035
1803 if (menubarGC == None) { 2036 if (menubarGC == None)
2037 {
1804 /* Create the graphics context */ 2038 /* Create the graphics context */
1805 XGCValues gcvalue; 2039 XGCValues gcvalue;
1806 2040
1807 gcvalue.font = TermWin.font->fid; 2041 gcvalue.foreground = (display->depth <= 2 ? pix_colors[Color_fg]
1808 2042 : pix_colors[Color_Black]);
1809 gcvalue.foreground = (XDEPTH <= 2 ? PixColors[Color_fg]
1810 : PixColors[Color_Black]);
1811 menubarGC = XCreateGC(Xdisplay, menuBar.win, 2043 menubarGC = XCreateGC (display->display, menuBar.win,
1812 GCForeground | GCFont, &gcvalue); 2044 GCForeground, &gcvalue);
1813 2045
1814 } 2046 }
1815/* make sure the font is correct */ 2047 /* make sure the font is correct */
1816 XSetFont(Xdisplay, menubarGC, TermWin.font->fid);
1817 XSetFont(Xdisplay, botShadowGC, TermWin.font->fid);
1818 XClearWindow(Xdisplay, menuBar.win); 2048 XClearWindow (display->display, menuBar.win);
1819 2049
1820 menu_hide_all (); 2050 menu_hide_all ();
1821 2051
1822 x = 0; 2052 x = 0;
1823 if (CurrentBar != NULL) { 2053 if (CurrentBar != NULL)
2054 {
1824 for (menu = CurrentBar->head; menu != NULL; menu = menu->next) { 2055 for (menu = CurrentBar->head; menu != NULL; menu = menu->next)
2056 {
1825 int len = menu->len; 2057 int len = menu->len;
1826 2058
1827 x = (menu->x + menu->len + HSPACE); 2059 x = (menu->x + menu->len + HSPACE);
1828 2060
1829#ifdef DEBUG_MENU_LAYOUT 2061#ifdef DEBUG_MENU_LAYOUT
1830 rxvt_print_menu_descendants(menu); 2062 rxvt_print_menu_descendants (menu);
1831#endif 2063#endif
1832 2064
1833 if (x >= TermWin.ncol) 2065 if (x >= ncol)
1834 len = (TermWin.ncol - (menu->x + HSPACE)); 2066 len = (ncol - (menu->x + HSPACE));
1835 2067
1836 drawbox_menubar (menu->x, len, +1); 2068 drawbox_menubar (menu->x, len, +1);
1837#ifdef USE_XIM 2069 draw_string (*menuBar.drawable, menubarGC, fontset[0],
1838 if (TermWin.fontset)
1839 XmbDrawString(Xdisplay,
1840 menuBar.win, TermWin.fontset,
1841 menubarGC,
1842 (Width2Pixel(menu->x) + Width2Pixel(HSPACE) / 2), 2070 (Width2Pixel (menu->x) + Width2Pixel (HSPACE) / 2),
1843 menuBar_height() - SHADOW, menu->name, len); 2071 MENU_SHADOW, menu->name, len);
1844 else
1845#endif
1846 XDrawString(Xdisplay, menuBar.win, menubarGC,
1847 (Width2Pixel(menu->x) + Width2Pixel(HSPACE) / 2),
1848 menuBar_height() - SHADOW, menu->name, len);
1849 2072
1850 if (x >= TermWin.ncol) 2073 if (x >= ncol)
1851 break; 2074 break;
1852 } 2075 }
1853 } 2076 }
1854 drawbox_menubar (x, TermWin.ncol, (CurrentBar ? +1 : -1)); 2077 drawbox_menubar (x, ncol, (CurrentBar ? +1 : -1));
1855 2078
1856/* add the menuBar title, if it exists and there's plenty of room */ 2079 /* add the menuBar title, if it exists and there's plenty of room */
1857 Arrows_x = 0; 2080 Arrows_x = 0;
1858 if (x < TermWin.ncol) { 2081 if (x < ncol)
2082 {
1859 const char *str; 2083 const char *str;
1860 int ncol;
1861 unsigned int len; 2084 unsigned int len;
1862 char title[256]; 2085 char title[256];
1863 2086
1864 ncol = (int)TermWin.ncol;
1865 if (x < (ncol - (NARROWS + 1))) { 2087 if (x < (ncol - (NARROWS + 1)))
2088 {
1866 ncol -= (NARROWS + 1); 2089 ncol -= (NARROWS + 1);
1867 Arrows_x = Width2Pixel(ncol); 2090 Arrows_x = Width2Pixel (ncol);
1868 } 2091 }
2092
1869 draw_Arrows (0, +1); 2093 draw_Arrows (0, +1);
1870 2094
1871 str = (CurrentBar 2095 str = (CurrentBar
1872 && CurrentBar->title) ? CurrentBar->title : "%n-%v"; 2096 && CurrentBar->title) ? CurrentBar->title : "%n-%v";
1873 for (len = 0; str[0] && len < sizeof(title) - 1; str++) { 2097 for (len = 0; str[0] && len < sizeof (title) - 1; str++)
2098 {
1874 const char *s = NULL; 2099 const char *s = NULL;
1875 2100
1876 switch (str[0]) { 2101 switch (str[0])
1877 case '%': 2102 {
1878 str++; 2103 case '%':
1879 switch (str[0]) { 2104 str++;
1880 case 'n': 2105 switch (str[0])
1881 s = rs[Rs_name]; 2106 {
2107 case 'n':
2108 s = rs[Rs_name];
1882 break; /* resource name */ 2109 break; /* resource name */
1883 case 'v': 2110 case 'v':
1884 s = VERSION; 2111 s = VERSION;
1885 break; /* version number */ 2112 break; /* version number */
1886 case '%': 2113 case '%':
1887 s = "%"; 2114 s = "%";
1888 break; /* literal '%' */ 2115 break; /* literal '%' */
1889 } 2116 }
1890 if (s != NULL) 2117 if (s != NULL)
1891 while (*s && len < sizeof(title) - 1) 2118 while (*s && len < sizeof (title) - 1)
1892 title[len++] = *s++; 2119 title[len++] = *s++;
1893 break; 2120 break;
1894 2121
1895 default: 2122 default:
1896 title[len++] = str[0]; 2123 title[len++] = str[0];
1897 break; 2124 break;
1898 } 2125 }
1899 } 2126 }
1900 title[len] = '\0'; 2127 title[len] = '\0';
1901 2128
1902 ncol -= (x + len + HSPACE); 2129 ncol -= (x + len + HSPACE);
1903 if (len > 0 && ncol >= 0) { 2130 if (len > 0 && ncol >= 0)
1904#ifdef USE_XIM 2131 draw_string (*menuBar.drawable, menubarGC, fontset[0],
1905 if (TermWin.fontset)
1906 XmbDrawString(Xdisplay,
1907 menuBar.win, TermWin.fontset,
1908 menubarGC,
1909 Width2Pixel(x) + Width2Pixel(ncol + HSPACE) / 2, 2132 Width2Pixel (x) + Width2Pixel (ncol + HSPACE) / 2,
1910 menuBar_height() - SHADOW, title, len); 2133 MENU_SHADOW, title, len);
1911 else
1912#endif
1913 XDrawString(Xdisplay, menuBar.win, menubarGC,
1914 Width2Pixel(x) + Width2Pixel(ncol + HSPACE) / 2,
1915 menuBar_height() - SHADOW, title, len);
1916 }
1917 } 2134 }
1918} 2135}
1919 2136
1920int 2137int
1921rxvt_term::menubar_mapping (int map) 2138rxvt_term::menubar_mapping (int map)
1922{ 2139{
1923 int change = 0; 2140 int change = 0;
1924 2141
1925 if (map && !menubar_visible(r)) { 2142 if (map && !menubar_visible ())
2143 {
1926 menuBar.state = 1; 2144 menuBar.state = 1;
1927 if (menuBar.win == 0) 2145 if (menuBar.win == 0)
1928 return 0; 2146 return 0;
1929 XMapWindow(Xdisplay, menuBar.win); 2147 XMapWindow (display->display, menuBar.win);
1930 change = 1; 2148 change = 1;
2149 }
1931 } else if (!map && menubar_visible(r)) { 2150 else if (!map && menubar_visible ())
2151 {
2152 menubar_expose ();
2153 menuBar.state = 0;
2154 XUnmapWindow (display->display, menuBar.win);
2155 change = 1;
2156 }
2157 else
1932 menubar_expose (); 2158 menubar_expose ();
1933 menuBar.state = 0;
1934 XUnmapWindow(Xdisplay, menuBar.win);
1935 change = 1;
1936 } else
1937 menubar_expose ();
1938 2159
1939 return change; 2160 return change;
1940} 2161}
1941 2162
1942int 2163int
1943rxvt_term::menu_select (XButtonEvent *ev) 2164rxvt_term::menu_select (XButtonEvent &ev)
1944{ 2165{
1945 menuitem_t *thisitem, *item = NULL; 2166 menuitem_t *thisitem, *item = NULL;
1946 int this_y, y; 2167 int this_y, y;
1947 menu_t *ActiveMenu = ActiveMenu;
1948 2168
1949 Window unused_root, unused_child; 2169 Window unused_root, unused_child;
1950 int unused_root_x, unused_root_y; 2170 int unused_root_x, unused_root_y;
1951 unsigned int unused_mask; 2171 unsigned int unused_mask;
1952 2172
1953 if (ActiveMenu == NULL) 2173 if (ActiveMenu == NULL)
1954 return 0; 2174 return 0;
1955 2175
1956 XQueryPointer(Xdisplay, ActiveMenu->win, 2176 XQueryPointer (display->display, ActiveMenu->win,
1957 &unused_root, &unused_child, 2177 &unused_root, &unused_child,
1958 &unused_root_x, &unused_root_y, 2178 &unused_root_x, &unused_root_y,
1959 &(ev->x), &(ev->y), &unused_mask); 2179 &ev.x, &ev.y, &unused_mask);
1960 2180
1961 if (ActiveMenu->parent != NULL && (ev->x < 0 || ev->y < 0)) { 2181 if (ActiveMenu->parent != NULL && (ev.x < 0 || ev.y < 0))
1962 menu_hide ();
1963 return 1;
1964 } 2182 {
2183 menu_hide ();
2184 return 1;
2185 }
2186
1965/* determine the menu item corresponding to the Y index */ 2187 /* determine the menu item corresponding to the Y index */
1966 y = SHADOW; 2188 y = MENU_SHADOW;
1967 if (ev->x >= 0 && ev->x <= (ActiveMenu->w - SHADOW)) { 2189 if (ev.x >= 0 && ev.x <= (ActiveMenu->w - MENU_SHADOW))
2190 {
1968 for (item = ActiveMenu->head; item != NULL; item = item->next) { 2191 for (item = ActiveMenu->head; item != NULL; item = item->next)
2192 {
1969 int h = HEIGHT_TEXT + 2 * SHADOW; 2193 int h = HEIGHT_TEXT + 2 * MENU_SHADOW;
1970 2194
1971 if (isSeparator(item->name)) 2195 if (isSeparator (item->name))
1972 h = HEIGHT_SEPARATOR; 2196 h = HEIGHT_SEPARATOR;
1973 else if (ev->y >= y && ev->y < (y + h)) 2197 else if (ev.y >= y && ev.y < (y + h))
1974 break; 2198 break;
2199
1975 y += h; 2200 y += h;
1976 } 2201 }
1977 } 2202 }
2203
1978 if (item == NULL && ev->type == ButtonRelease) { 2204 if (item == NULL && ev.type == ButtonRelease)
2205 {
1979 menu_hide_all (); 2206 menu_hide_all ();
1980 return 0; 2207 return 0;
1981 } 2208 }
2209
1982 thisitem = item; 2210 thisitem = item;
1983 this_y = y - SHADOW; 2211 this_y = y - MENU_SHADOW;
1984 2212
1985/* erase the last item */ 2213 /* erase the last item */
1986 if (ActiveMenu->item != NULL) { 2214 if (ActiveMenu->item != NULL)
2215 {
1987 if (ActiveMenu->item != thisitem) { 2216 if (ActiveMenu->item != thisitem)
2217 {
1988 for (y = 0, item = ActiveMenu->head; item != NULL; 2218 for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next)
1989 item = item->next) { 2219 {
1990 int h; 2220 int h;
1991 2221
1992 if (isSeparator(item->name)) 2222 if (isSeparator (item->name))
1993 h = HEIGHT_SEPARATOR; 2223 h = HEIGHT_SEPARATOR;
1994 else if (item == ActiveMenu->item) { 2224 else if (item == ActiveMenu->item)
2225 {
1995 /* erase old menuitem */ 2226 /* erase old menuitem */
1996 drawbox_menuitem (y, 0); /* No Shadow */ 2227 drawbox_menuitem (y, 0); /* No Shadow */
1997 if (item->entry.type == MenuSubMenu) 2228 if (item->entry.type == MenuSubMenu)
1998 drawtriangle (ActiveMenu->w, y, +1); 2229 drawtriangle (ActiveMenu->w, y, +1);
1999 break; 2230
2000 } else 2231 break;
2232 }
2233 else
2001 h = HEIGHT_TEXT + 2 * SHADOW; 2234 h = HEIGHT_TEXT + 2 * MENU_SHADOW;
2002 y += h; 2235
2003 } 2236 y += h;
2004 } else { 2237 }
2238 }
2239 else
2240 {
2005 switch (ev->type) { 2241 switch (ev.type)
2242 {
2006 case ButtonRelease: 2243 case ButtonRelease:
2007 switch (item->entry.type) { 2244 switch (item->entry.type)
2008 case MenuLabel: 2245 {
2009 case MenuSubMenu: 2246 case MenuLabel:
2010 menu_hide_all (); 2247 case MenuSubMenu:
2011 break; 2248 menu_hide_all ();
2249 break;
2012 2250
2013 case MenuAction: 2251 case MenuAction:
2014 case MenuTerminalAction: 2252 case MenuTerminalAction:
2015 drawbox_menuitem (_y, -1); 2253 drawbox_menuitem (this_y, -1);
2016 { 2254 rxvt_usleep (MENU_DELAY_USEC);
2017#ifdef HAVE_NANOSLEEP
2018 struct timespec rqt;
2019
2020 rqt.tv_sec = 0;
2021 rqt.tv_nsec = MENU_DELAY_USEC * 1000;
2022 nanosleep(&rqt, NULL);
2023#else
2024 /* use select for timing */
2025 struct timeval tv;
2026
2027 tv.tv_sec = 0;
2028 tv.tv_usec = MENU_DELAY_USEC;
2029 select(0, NULL, NULL, NULL, &tv);
2030#endif
2031 }
2032 /* remove menu before sending keys to the application */ 2255 /* remove menu before sending keys to the application */
2033 menu_hide_all (); 2256 menu_hide_all ();
2034#ifndef DEBUG_MENU 2257#ifndef DEBUG_MENU
2035 action_dispatch (&(item->entry.action)); 2258 action_dispatch (& (item->entry.action));
2036#else /* DEBUG_MENU */ 2259#else /* DEBUG_MENU */
2037 fprintf(stderr, "%s: %s\n", item->name, 2260 fprintf (stderr, "%s: %s\n", item->name,
2038 item->entry.action.str); 2261 item->entry.action.str);
2039#endif /* DEBUG_MENU */ 2262#endif /* DEBUG_MENU */
2040 break; 2263 break;
2041 } 2264 }
2042 break; 2265 break;
2043 2266
2044 default: 2267 default:
2045 if (item->entry.type == MenuSubMenu) 2268 if (item->entry.type == MenuSubMenu)
2046 goto DoMenu; 2269 goto DoMenu;
2047 break; 2270 break;
2271 }
2272 return 0;
2273 }
2048 } 2274 }
2049 return 0; 2275
2050 }
2051 }
2052 DoMenu: 2276DoMenu:
2053 ActiveMenu->item = thisitem; 2277 ActiveMenu->item = thisitem;
2054 y = this_y; 2278 y = this_y;
2279
2055 if (item != NULL) { 2280 if (thisitem != NULL)
2281 {
2056 item = ActiveMenu->item; 2282 item = ActiveMenu->item;
2057 if (item->entry.type != MenuLabel) 2283 if (item->entry.type != MenuLabel)
2058 drawbox_menuitem (y, +1); 2284 drawbox_menuitem (y, +1);
2285
2059 if (item->entry.type == MenuSubMenu) { 2286 if (item->entry.type == MenuSubMenu)
2060 int x; 2287 {
2288 int x;
2061 2289
2062 drawtriangle (ActiveMenu->w, y, -1); 2290 drawtriangle (ActiveMenu->w, y, -1);
2063 2291
2064 x = ev->x + (ActiveMenu->parent 2292 x = ev.x + (ActiveMenu->parent
2065 ? ActiveMenu->x 2293 ? ActiveMenu->x
2066 : Width2Pixel(ActiveMenu->x)); 2294 : Width2Pixel (ActiveMenu->x));
2067 2295
2068 if (x >= item->entry.submenu.menu->x) { 2296 if (x >= item->entry.submenu.menu->x)
2297 {
2069 ActiveMenu = item->entry.submenu.menu; 2298 ActiveMenu = item->entry.submenu.menu;
2070 menu_show (); 2299 menu_show ();
2071 return 1; 2300 return 1;
2301 }
2302 }
2072 } 2303 }
2073 }
2074 }
2075 return 0; 2304 return 0;
2076} 2305}
2077 2306
2078void 2307void
2079rxvt_term::menubar_select (XButtonEvent *ev) 2308rxvt_term::menubar_select (XButtonEvent &ev)
2080{ 2309{
2081 menu_t *menu = NULL; 2310 menu_t *menu = NULL;
2082 2311
2083/* determine the pulldown menu corresponding to the X index */ 2312 /* determine the pulldown menu corresponding to the X index */
2084 if (ev->y >= 0 && ev->y <= menuBar_height() && CurrentBar != NULL) { 2313 if (ev.y >= 0 && ev.y <= menuBar_height () && CurrentBar != NULL)
2314 {
2085 for (menu = CurrentBar->head; menu != NULL; menu = menu->next) { 2315 for (menu = CurrentBar->head; menu != NULL; menu = menu->next)
2316 {
2086 int x = Width2Pixel(menu->x); 2317 int x = Width2Pixel (menu->x);
2087 int w = Width2Pixel(menu->len + HSPACE); 2318 int w = Width2Pixel (menu->len + HSPACE);
2088 2319
2089 if ((ev->x >= x && ev->x < x + w)) 2320 if ((ev.x >= x && ev.x < x + w))
2090 break; 2321 break;
2091 } 2322 }
2092 } 2323 }
2093 switch (ev->type) { 2324 switch (ev.type)
2325 {
2094 case ButtonRelease: 2326 case ButtonRelease:
2095 menu_hide_all (); 2327 menu_hide_all ();
2096 break; 2328 break;
2097 2329
2098 case ButtonPress: 2330 case ButtonPress:
2099 if (menu == NULL && Arrows_x && ev->x >= Arrows_x) { 2331 if (menu == NULL && Arrows_x && ev.x >= Arrows_x)
2332 {
2100 int i; 2333 int i;
2101 2334
2102 for (i = 0; i < NARROWS; i++) { 2335 for (i = 0; i < NARROWS; i++)
2336 {
2103 if (ev->x >= (Arrows_x + (Width2Pixel(4 * i + i)) / 4) 2337 if (ev.x >= (Arrows_x + (Width2Pixel (4 * i + i)) / 4)
2104 && ev->x < (Arrows_x 2338 && ev.x < (Arrows_x
2105 + (Width2Pixel(4 * i + i + 4)) / 4)) { 2339 + (Width2Pixel (4 * i + i + 4)) / 4))
2340 {
2106 draw_Arrows (Arrows[i].name, -1); 2341 draw_Arrows (Arrows[i].name, -1);
2107 { 2342 rxvt_usleep (MENU_DELAY_USEC);
2108#ifdef HAVE_NANOSLEEP
2109 struct timespec rqt;
2110
2111 rqt.tv_sec = 0;
2112 rqt.tv_nsec = MENU_DELAY_USEC * 1000;
2113 nanosleep(&rqt, NULL);
2114#else
2115 /* use select for timing */
2116 struct timeval tv;
2117
2118 tv.tv_sec = 0;
2119 tv.tv_usec = MENU_DELAY_USEC;
2120 select(0, NULL, NULL, NULL, &tv);
2121#endif
2122 }
2123 draw_Arrows (Arrows[i].name, +1); 2343 draw_Arrows (Arrows[i].name, +1);
2124#ifdef DEBUG_MENUARROWS 2344#ifdef DEBUG_MENUARROWS
2125 fprintf(stderr, "'%c': ", Arrows[i].name); 2345 fprintf (stderr, "'%c': ", Arrows[i].name);
2126 2346
2127 if (CurrentBar == NULL 2347 if (CurrentBar == NULL
2128 || (CurrentBar->arrows[i].type != MenuAction 2348 || (CurrentBar->arrows[i].type != MenuAction
2129 && CurrentBar->arrows[i].type != 2349 && CurrentBar->arrows[i].type !=
2130 MenuTerminalAction)) { 2350 MenuTerminalAction))
2351 {
2131 if (Arrows[i].str != NULL && Arrows[i].str[0]) 2352 if (Arrows[i].str != NULL && Arrows[i].str[0])
2132 fprintf(stderr, "(default) \\033%s\n", 2353 fprintf (stderr, " (default) \\033%s\n",
2133 &(Arrows[i].str[2])); 2354 & (Arrows[i].str[2]));
2134 } else { 2355 }
2135 fprintf(stderr, "%s\n", 2356 else
2136 CurrentBar->arrows[i].str); 2357 {
2137 } 2358 fprintf (stderr, "%s\n",
2359 CurrentBar->arrows[i].str);
2360 }
2138#else /* DEBUG_MENUARROWS */ 2361#else /* DEBUG_MENUARROWS */
2139 if (CurrentBar == NULL 2362 if (CurrentBar == NULL || action_dispatch (&CurrentBar->arrows[i]))
2140 || rxvt_action_dispatch(r, 2363 {
2141 &(CurrentBar->arrows[i]))
2142 ) {
2143 if (Arrows[i].str != NULL && Arrows[i].str[0] != 0) 2364 if (Arrows[i].str != NULL && Arrows[i].str[0] != 0)
2144 tt_write ((Arrows[i].str + 1), 2365 tt_write ((Arrows[i].str + 1),
2145 Arrows[i].str[0]); 2366 Arrows[i].str[0]);
2146 } 2367 }
2147#endif /* DEBUG_MENUARROWS */ 2368#endif /* DEBUG_MENUARROWS */
2148 return; 2369 return;
2149 } 2370 }
2150 } 2371 }
2151 } 2372 }
2152 /* FALLTHROUGH */ 2373 /* FALLTHROUGH */
2153 2374
2154 default: 2375 default:
2155 /* 2376 /*
2156 * press menubar or move to a new entry 2377 * press menubar or move to a new entry
2157 */ 2378 */
2158 if (menu != NULL && menu != ActiveMenu) { 2379 if (menu != NULL && menu != ActiveMenu)
2380 {
2159 menu_hide_all (); /* pop down old menu */ 2381 menu_hide_all (); /* pop down old menu */
2160 ActiveMenu = menu; 2382 ActiveMenu = menu;
2161 menu_show (); /* pop up new menu */ 2383 menu_show (); /* pop up new menu */
2162 } 2384 }
2163 break; 2385 break;
2164 } 2386 }
2165} 2387}
2166 2388
2167/* 2389/*
2168 * general dispatch routine, 2390 * general dispatch routine,
2169 * it would be nice to have `sticky' menus 2391 * it would be nice to have `sticky' menus
2170 */ 2392 */
2171void 2393void
2172rxvt_term::menubar_control (XButtonEvent *ev) 2394rxvt_term::menubar_control (XButtonEvent &ev)
2173{ 2395{
2174 switch (ev->type) { 2396 switch (ev.type)
2397 {
2175 case ButtonPress: 2398 case ButtonPress:
2176 if (ev->button == Button1) 2399 if (ev.button == Button1)
2177 menubar_select (ev); 2400 menubar_select (ev);
2178 break; 2401 break;
2179 2402
2180 case ButtonRelease: 2403 case ButtonRelease:
2181 if (ev->button == Button1) 2404 if (ev.button == Button1)
2182 menu_select (ev); 2405 menu_select (ev);
2183 break; 2406 break;
2184 2407
2185 case MotionNotify: 2408 case MotionNotify:
2186 while (XCheckTypedWindowEvent(Xdisplay, TermWin.parent[0], 2409 while (XCheckTypedWindowEvent (display->display, parent[0],
2187 MotionNotify, (XEvent *) ev)) ; 2410 MotionNotify, (XEvent *)&ev));
2188 2411
2189 if (ActiveMenu) 2412 if (ActiveMenu)
2190 while (menu_select (ev)) ; 2413 while (menu_select (ev)) ;
2191 else 2414 else
2192 ev->y = -1; 2415 ev.y = -1;
2193 if (ev->y < 0) { 2416 if (ev.y < 0)
2417 {
2194 Window unused_root, unused_child; 2418 Window unused_root, unused_child;
2195 int unused_root_x, unused_root_y; 2419 int unused_root_x, unused_root_y;
2196 unsigned int unused_mask; 2420 unsigned int unused_mask;
2197 2421
2198 XQueryPointer(Xdisplay, menuBar.win, 2422 XQueryPointer (display->display, menuBar.win,
2199 &unused_root, &unused_child, 2423 &unused_root, &unused_child,
2200 &unused_root_x, &unused_root_y, 2424 &unused_root_x, &unused_root_y,
2201 &(ev->x), &(ev->y), &unused_mask); 2425 &ev.x, &ev.y, &unused_mask);
2202 menubar_select (ev); 2426 menubar_select (ev);
2203 } 2427 }
2204 break; 2428 break;
2205 } 2429 }
2206} 2430}
2207 2431
2208void 2432void
2209rxvt_term::map_menuBar (int map) 2433rxvt_term::map_menuBar (int map)
2210{ 2434{
2211 if (menubar_mapping (map)) 2435 if (menubar_mapping (map))
2212 resize_all_windows (0, 0, 0); 2436 resize_all_windows (0, 0, 0);
2213} 2437}
2214#endif 2438#endif
2215/*----------------------- end-of-file (C source) -----------------------*/ 2439/*----------------------- end-of-file (C source) -----------------------*/

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines