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.2 by pcg, Mon Nov 24 17:31:27 2003 UTC vs.
Revision 1.17 by root, Sat Jul 31 15:32:50 2004 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines