x11_simple_menu.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. /* =============================================================================
  2. * PROGRAM: CODE LIBRARY
  3. * FILENAME: x11_simple_menu.c
  4. *
  5. * DESCRIPTION:
  6. * This module provides a simple menu capability for X11 programs.
  7. * It can currently only handle a single window/menu at a time.
  8. * To use this library in an application:
  9. * 1. Create the widow to contain the menu.
  10. * 2. Call XMENU_SetMenu to set the menu to be displayed in that window.
  11. * This must provide a pointer to a function to repaint the windows
  12. * that may be obscured by the menu.
  13. * 3. Call XMENU_GetMenuHeight to get the height of the menu bar.
  14. * The application should be acreful not to draw in this area.
  15. * 4. Add XMENU_EVENT_MASK to the menu window's X event mask.
  16. * 5. When processing an X event the main event loop should call
  17. * XMENU_HandleEvent.
  18. * This function will return either:
  19. * . -1 if the menu didn't handle this event, in which case the
  20. * application needs to handle it, or
  21. * . The selected menu item id if the event was handled by the menu.
  22. * In this case the application shouldn't process this event, but should
  23. * act on the returned menu selection id.
  24. * 6. Call XMENU_Redraw whenever the window containing the menu gets an
  25. * expose event.
  26. *
  27. * =============================================================================
  28. * COPYRIGHT:
  29. *
  30. * Copyright (c) 2003, Julian Olds
  31. * All rights reserved.
  32. *
  33. * Redistribution and use in source and binary forms, with or without
  34. * modification, are permitted provided that the following conditions
  35. * are met:
  36. *
  37. * . Redistributions of source code must retain the above copyright notice,
  38. * this list of conditions and the following disclaimer.
  39. *
  40. * . Redistributions in binary form must reproduce the above copyright
  41. * notice, this list of conditions and the following disclaimer in the
  42. * documentation and/or other materials provided with the distribution.
  43. *
  44. * The name of the author may not be used to endorse or promote products
  45. * derived from this software without specific prior written permission.
  46. *
  47. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  48. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  49. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  50. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  51. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  52. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  53. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  54. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  55. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  56. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  57. * THE POSSIBILITY OF SUCH DAMAGE.
  58. *
  59. * =============================================================================
  60. * EXPORTED VARIABLES
  61. *
  62. * None.
  63. *
  64. * =============================================================================
  65. * EXPORTED FUNCTIONS
  66. *
  67. * XMENU_SetMenu - Set the menu and menu dislay window
  68. * XMENU_SetCheck - Set the checkmark state for a menu item
  69. * XMENU_GetMenuHeight - Get the menu height in pixels
  70. * XMENU_Redraw - Redraw the menu
  71. * XMENU_HandleEvent - Process input events for the menu selection
  72. *
  73. * =============================================================================
  74. */
  75. #include <stdio.h>
  76. #include <string.h>
  77. #include "checkmark.bm"
  78. #include "x11_simple_menu.h"
  79. /* =============================================================================
  80. * Local variables
  81. */
  82. static char *menu_default_font = "*-helvetica-medium-r-*-12-*";
  83. static Display *MenuDisplay;
  84. static Window MenuWindow;
  85. static GC menu_gc;
  86. static XGCValues menu_gc_values;
  87. static unsigned long menu_gc_values_mask;
  88. static XFontStruct *menu_font_info;
  89. static char *menu_font_name = NULL;
  90. static Pixmap CheckPixmap = None;
  91. static unsigned long menu_white_pixel;
  92. static unsigned long menu_black_pixel;
  93. static struct XMENU_Menu *The_Menu;
  94. static void (*RepaintWindow)(void);
  95. /* Current popup menu size */
  96. static Window Popup;
  97. static int PopupWidth;
  98. static int PopupHeight;
  99. static int ItemHeight;
  100. /* =============================================================================
  101. * Local functions
  102. */
  103. /* =============================================================================
  104. * FUNCTION: XMENU_PaintPopup
  105. *
  106. * DESCRIPTION:
  107. * Paints the popup menu window with the items of a menu.
  108. *
  109. * PARAMETERS:
  110. *
  111. * Popup : The popup window to be painted.
  112. *
  113. * Menu : The menu for the popup window.
  114. *
  115. * RETURN VALUE:
  116. *
  117. * None.
  118. */
  119. static void XMENU_PaintPopup(Window Popup, struct XMENU_Menu *Menu) {
  120. struct XMENU_Item *Item;
  121. int Top;
  122. XSetForeground(MenuDisplay, menu_gc, menu_white_pixel);
  123. XFillRectangle(MenuDisplay, Popup, menu_gc, 0, 0, PopupWidth, PopupHeight);
  124. XSetForeground(MenuDisplay, menu_gc, menu_black_pixel);
  125. XSetBackground(MenuDisplay, menu_gc, menu_white_pixel);
  126. Top = 0;
  127. Item = Menu->ItemList;
  128. while (Item != NULL) {
  129. if (Item->Checked) {
  130. XCopyPlane(MenuDisplay, CheckPixmap, Popup, menu_gc, 0, 0,
  131. checkmark_width, checkmark_height,
  132. menu_font_info->max_bounds.width / 2,
  133. Top + (ItemHeight / 2) - (checkmark_height / 2), 1);
  134. }
  135. XDrawString(MenuDisplay, Popup, menu_gc,
  136. checkmark_width + menu_font_info->max_bounds.width,
  137. Top + menu_font_info->max_bounds.ascent + 2, Item->Text,
  138. strlen(Item->Text));
  139. Top += ItemHeight;
  140. Item = Item->Next;
  141. }
  142. }
  143. /* =============================================================================
  144. * FUNCTION: XMENU_HighlightItem
  145. *
  146. * DESCRIPTION:
  147. * Highlight a menu item on a popup.
  148. *
  149. * PARAMETERS:
  150. *
  151. * Popup : The popup menu window
  152. *
  153. * ItemId : The item to be (un)highlighted
  154. *
  155. * Highlight : True if the highlight is to be drawn,
  156. * False if the highlight is to be removed.
  157. *
  158. * RETURN VALUE:
  159. *
  160. * None.
  161. */
  162. static void XMENU_HighlightItem(Window Popup, struct XMENU_Menu *Menu,
  163. int ItemId, int Highlight) {
  164. struct XMENU_Item *Item;
  165. int Count;
  166. Item = Menu->ItemList;
  167. Count = 0;
  168. while ((Item != NULL) && (Item->ItemId != ItemId)) {
  169. Count++;
  170. Item = Item->Next;
  171. }
  172. if (Item == NULL)
  173. return;
  174. if (Highlight)
  175. XSetForeground(MenuDisplay, menu_gc, menu_black_pixel);
  176. else
  177. XSetForeground(MenuDisplay, menu_gc, menu_white_pixel);
  178. XDrawRectangle(MenuDisplay, Popup, menu_gc, 0, Count * ItemHeight,
  179. PopupWidth - 1, ItemHeight - 1);
  180. XFlush(MenuDisplay);
  181. XSync(MenuDisplay, 0);
  182. }
  183. /* =============================================================================
  184. * FUNCTION: XMENU_ItemHit
  185. *
  186. * DESCRIPTION:
  187. * Determine which menu item in the current popup menu is at location x, y
  188. *
  189. * PARAMETERS:
  190. *
  191. * Menu : The currently active popup menu
  192. *
  193. * x : The x coordinate to test.
  194. *
  195. * y : The y coordinate to test.
  196. *
  197. * RETURN VALUE:
  198. *
  199. * The ItemId of the menu item at (x, y) or XMENU_NUMMID if none.
  200. */
  201. static int XMENU_ItemHit(struct XMENU_Menu *Menu, int x, int y) {
  202. struct XMENU_Item *Item;
  203. int ItemNo;
  204. if ((x < 0) || (x > PopupWidth) || (y < 0) || (y > PopupHeight))
  205. return XMENU_NULLID;
  206. ItemNo = y / ItemHeight;
  207. Item = Menu->ItemList;
  208. while ((Item != NULL) && (ItemNo > 0)) {
  209. Item = Item->Next;
  210. ItemNo--;
  211. }
  212. if (Item != NULL)
  213. return Item->ItemId;
  214. else
  215. return XMENU_NULLID;
  216. }
  217. /* =============================================================================
  218. * FUNCTION: XMENU_MenuHit
  219. *
  220. * DESCRIPTION:
  221. * Identify which menu is at location x, y.
  222. *
  223. * PARAMETERS:
  224. *
  225. * Menu : A pointer to the menu structure
  226. *
  227. * x : The x coordinate to test.
  228. *
  229. * y : The y coordinate to test.
  230. *
  231. * RETURN VALUE:
  232. *
  233. * A pointer to the menu on the menu bar at (x, y) or NULL if none.
  234. */
  235. static struct XMENU_Menu *XMENU_MenuHit(struct XMENU_Menu *Menu, int x, int y) {
  236. struct XMENU_Menu *Pos;
  237. int FoundHit;
  238. Pos = Menu;
  239. FoundHit = 0;
  240. while ((Pos != NULL) && !FoundHit) {
  241. if ((x >= Pos->HitLeft) && (x < Pos->HitLeft + Pos->HitWidth) &&
  242. (y >= Pos->HitTop) && (y < Pos->HitTop + Pos->HitHeight))
  243. FoundHit = 1;
  244. else
  245. Pos = Pos->Next;
  246. }
  247. return Pos;
  248. }
  249. /* =============================================================================
  250. * FUNCTION: XMENU_ActivatePopup
  251. *
  252. * DESCRIPTION:
  253. * Create the popup menu window.
  254. *
  255. * PARAMETERS:
  256. *
  257. * Menu : The popup menu to activate.
  258. *
  259. * RETURN VALUE:
  260. *
  261. * None.
  262. */
  263. static void XMENU_ActivatePopup(struct XMENU_Menu *Menu) {
  264. int Direction, Ascent, Descent;
  265. XCharStruct Extents;
  266. XSetWindowAttributes Attributes;
  267. struct XMENU_Item *Item;
  268. int rc;
  269. Window Root;
  270. Window Child;
  271. int winx, winy;
  272. int winwidth, winheight;
  273. int winborder, windepth;
  274. /* Calculate the popup menu size */
  275. PopupWidth = 0;
  276. PopupHeight = 0;
  277. Item = Menu->ItemList;
  278. while (Item != NULL) {
  279. XTextExtents(menu_font_info, Item->Text, strlen(Item->Text), &Direction,
  280. &Ascent, &Descent, &Extents);
  281. if (Extents.width > PopupWidth)
  282. PopupWidth = Extents.width;
  283. PopupHeight += ItemHeight;
  284. Item = Item->Next;
  285. }
  286. PopupWidth += checkmark_width + menu_font_info->max_bounds.width * 2;
  287. /* Find the popup menu position */
  288. rc = XGetGeometry(MenuDisplay, MenuWindow, &Root, &winx, &winy, &winwidth,
  289. &winheight, &winborder, &windepth);
  290. winx = 0;
  291. winy = 0;
  292. XTranslateCoordinates(MenuDisplay, MenuWindow, Root, winx, winy, &winx, &winy,
  293. &Child);
  294. /* Create the popup menu window */
  295. Attributes.border_pixel = menu_black_pixel;
  296. Attributes.backing_pixel = menu_white_pixel;
  297. Attributes.backing_store = WhenMapped;
  298. Attributes.save_under = 1;
  299. Attributes.override_redirect = 1;
  300. Popup = XCreateWindow(
  301. MenuDisplay, RootWindow(MenuDisplay, DefaultScreen(MenuDisplay)),
  302. winx + Menu->HitLeft, winy + Menu->HitTop + Menu->HitHeight, PopupWidth,
  303. PopupHeight, 1, /* Border width */
  304. CopyFromParent, /* Depth */
  305. InputOutput, /* Class */
  306. DefaultVisual(MenuDisplay, DefaultScreen(MenuDisplay)),
  307. CWBorderPixel | CWBackingStore | CWSaveUnder | CWOverrideRedirect,
  308. &Attributes);
  309. XSelectInput(MenuDisplay, Popup,
  310. ExposureMask | ButtonPressMask | ButtonReleaseMask |
  311. Button1MotionMask);
  312. XMapRaised(MenuDisplay, Popup);
  313. XFlush(MenuDisplay);
  314. XSync(MenuDisplay, 0);
  315. }
  316. /* =============================================================================
  317. * FUNCTION: XMENU_HandleSelection
  318. *
  319. * DESCRIPTION:
  320. * Handle the selection from the menu.
  321. * This actiivates the initially selected menu and processes all x events until
  322. * either a menu item is selected or the menu is deactivated.
  323. *
  324. * PARAMETERS:
  325. *
  326. * Menu : A pointer to the menu structure for the menus.
  327. *
  328. * x : The x coordinate of the initial selection
  329. *
  330. * y : The y coordinate of the initial selection
  331. *
  332. * RETURN VALUE:
  333. *
  334. * The ItemId of the menu item selected or XMENU_NULLID if none.
  335. */
  336. static int XMENU_HandleSelection(struct XMENU_Menu *Menu, int x, int y) {
  337. struct XMENU_Menu *Current;
  338. struct XMENU_Menu *NewMenu;
  339. int Done;
  340. int Dragging;
  341. Window Child;
  342. int winx, winy;
  343. XEvent xevent;
  344. int SelectId;
  345. int OldId;
  346. /* Activate the Popup menu for the initially selected menu */
  347. Current = XMENU_MenuHit(Menu, x, y);
  348. if (Current != NULL)
  349. XMENU_ActivatePopup(Current);
  350. /* Prepare for event handling */
  351. Done = 0;
  352. Dragging = 0;
  353. SelectId = XMENU_NULLID;
  354. /*
  355. * Handle events until either a menu item is selected of the menu is
  356. * Deactivated.
  357. */
  358. while (!Done) {
  359. XNextEvent(MenuDisplay, &xevent);
  360. switch (xevent.type) {
  361. case Expose:
  362. if (xevent.xexpose.window == Popup)
  363. XMENU_PaintPopup(Popup, Current);
  364. else if (xevent.xexpose.window == MenuWindow)
  365. RepaintWindow();
  366. break;
  367. case ButtonPress:
  368. winx = xevent.xbutton.x;
  369. winy = xevent.xbutton.y;
  370. if (xevent.xbutton.window != Popup) {
  371. XTranslateCoordinates(MenuDisplay, xevent.xbutton.window, Popup, winx,
  372. winy, &winx, &winy, &Child);
  373. }
  374. SelectId = XMENU_ItemHit(Current, winx, winy);
  375. if (SelectId != XMENU_NULLID)
  376. XMENU_HighlightItem(Popup, Current, SelectId, 1);
  377. else {
  378. winx = xevent.xmotion.x;
  379. winy = xevent.xmotion.y;
  380. if (xevent.xmotion.window != MenuWindow) {
  381. XTranslateCoordinates(MenuDisplay, xevent.xmotion.window, MenuWindow,
  382. winx, winy, &winx, &winy, &Child);
  383. }
  384. NewMenu = XMENU_MenuHit(The_Menu, winx, winy);
  385. if ((NewMenu != Current) && (NewMenu != NULL)) {
  386. XUnmapWindow(MenuDisplay, Popup);
  387. XDestroyWindow(MenuDisplay, Popup);
  388. Current = NewMenu;
  389. XMENU_ActivatePopup(Current);
  390. } else
  391. Done = 1;
  392. }
  393. break;
  394. case ButtonRelease:
  395. if (Dragging)
  396. Done = 1;
  397. else if (SelectId != XMENU_NULLID)
  398. Done = 1;
  399. break;
  400. case MotionNotify:
  401. Dragging = 1;
  402. winx = xevent.xmotion.x;
  403. winy = xevent.xmotion.y;
  404. if (xevent.xmotion.window != Popup) {
  405. XTranslateCoordinates(MenuDisplay, xevent.xmotion.window, Popup, winx,
  406. winy, &winx, &winy, &Child);
  407. }
  408. OldId = SelectId;
  409. SelectId = XMENU_ItemHit(Current, winx, winy);
  410. if (SelectId != OldId) {
  411. XMENU_HighlightItem(Popup, Current, OldId, 0);
  412. if (SelectId != XMENU_NULLID)
  413. XMENU_HighlightItem(Popup, Current, SelectId, 1);
  414. }
  415. if (SelectId == XMENU_NULLID) {
  416. /* Pointer not over a menu item, so check for menu change */
  417. winx = xevent.xmotion.x;
  418. winy = xevent.xmotion.y;
  419. if (xevent.xmotion.window != MenuWindow) {
  420. XTranslateCoordinates(MenuDisplay, xevent.xmotion.window, MenuWindow,
  421. winx, winy, &winx, &winy, &Child);
  422. }
  423. NewMenu = XMENU_MenuHit(The_Menu, winx, winy);
  424. if ((NewMenu != Current) && (NewMenu != NULL)) {
  425. XUnmapWindow(MenuDisplay, Popup);
  426. XDestroyWindow(MenuDisplay, Popup);
  427. Current = NewMenu;
  428. XMENU_ActivatePopup(Current);
  429. }
  430. }
  431. break;
  432. default:
  433. break;
  434. }
  435. }
  436. XDestroyWindow(MenuDisplay, Popup);
  437. return SelectId;
  438. }
  439. /* =============================================================================
  440. * Exported functions
  441. */
  442. /* =============================================================================
  443. * FUNCTION: XMENU_SetMenu
  444. */
  445. void XMENU_SetMenu(Display *dpy, Window win, struct XMENU_Menu *Menu,
  446. char *FontSpec, void (*Repaint)(void)) {
  447. int screen_num;
  448. MenuDisplay = dpy;
  449. MenuWindow = win;
  450. The_Menu = Menu;
  451. RepaintWindow = Repaint;
  452. menu_gc_values.cap_style = CapButt;
  453. menu_gc_values.join_style = JoinBevel;
  454. menu_gc_values_mask = GCCapStyle | GCJoinStyle;
  455. menu_gc =
  456. XCreateGC(MenuDisplay, MenuWindow, menu_gc_values_mask, &menu_gc_values);
  457. if (CheckPixmap == None) {
  458. CheckPixmap = XCreateBitmapFromData(MenuDisplay, MenuWindow, checkmark_bits,
  459. checkmark_width, checkmark_height);
  460. }
  461. screen_num = DefaultScreen(MenuDisplay);
  462. menu_white_pixel = WhitePixel(MenuDisplay, screen_num);
  463. menu_black_pixel = BlackPixel(MenuDisplay, screen_num);
  464. if (FontSpec != NULL)
  465. menu_font_name = FontSpec;
  466. else
  467. menu_font_name = menu_default_font;
  468. menu_font_info = XLoadQueryFont(MenuDisplay, menu_font_name);
  469. if (!menu_font_info) {
  470. fprintf(stderr, "Error: XLoadQueryFont: failed loading font '%s'\n",
  471. menu_font_name);
  472. return;
  473. }
  474. XSetFont(MenuDisplay, menu_gc, menu_font_info->fid);
  475. ItemHeight = menu_font_info->max_bounds.ascent +
  476. menu_font_info->max_bounds.descent + 4;
  477. /* Draw the menu */
  478. XMENU_Redraw();
  479. }
  480. /* =============================================================================
  481. * FUNCTION: XMENU_SetCheck
  482. */
  483. void XMENU_SetCheck(int ItemId, XMENU_CheckState CheckState) {
  484. struct XMENU_Menu *Menu;
  485. struct XMENU_Item *Item;
  486. int Found;
  487. Found = False;
  488. Menu = The_Menu;
  489. while ((Menu != NULL) && !Found) {
  490. Item = Menu->ItemList;
  491. while ((Item != NULL) && !Found) {
  492. if (Item->ItemId == ItemId) {
  493. Item->Checked = CheckState;
  494. Found = 1;
  495. }
  496. Item = Item->Next;
  497. }
  498. Menu = Menu->Next;
  499. }
  500. }
  501. /* =============================================================================
  502. * FUNCTION: XMENU_GetMenuHeight
  503. */
  504. int XMENU_GetMenuHeight(void) {
  505. int CharHeight;
  506. CharHeight =
  507. menu_font_info->max_bounds.ascent + menu_font_info->max_bounds.descent;
  508. return CharHeight + 10;
  509. }
  510. /* =============================================================================
  511. * FUNCTION: XMENU_Redraw
  512. */
  513. void XMENU_Redraw(void) {
  514. struct XMENU_Menu *Pos;
  515. XWindowAttributes win_attr;
  516. XCharStruct Extents;
  517. int MenuWidth;
  518. int MenuHeight;
  519. int MenuLeft;
  520. int MenuTop;
  521. int Direction;
  522. int Ascent;
  523. int Descent;
  524. Status rc;
  525. rc = XGetWindowAttributes(MenuDisplay, MenuWindow, &win_attr);
  526. MenuWidth = win_attr.width;
  527. MenuHeight = XMENU_GetMenuHeight();
  528. /* Clear the menu area */
  529. XSetForeground(MenuDisplay, menu_gc, menu_white_pixel);
  530. XFillRectangle(MenuDisplay, MenuWindow, menu_gc, 0, 0, MenuWidth, MenuHeight);
  531. /* Draw the menu bottom line */
  532. XSetForeground(MenuDisplay, menu_gc, menu_black_pixel);
  533. XFillRectangle(MenuDisplay, MenuWindow, menu_gc, 0, MenuHeight - 2, MenuWidth,
  534. 2);
  535. Pos = The_Menu;
  536. MenuLeft = 8;
  537. MenuTop = 4;
  538. while (Pos != NULL) {
  539. XDrawString(MenuDisplay, MenuWindow, menu_gc, MenuLeft,
  540. MenuTop + menu_font_info->max_bounds.ascent, Pos->Text,
  541. strlen(Pos->Text));
  542. XTextExtents(menu_font_info, Pos->Text, strlen(Pos->Text), &Direction,
  543. &Ascent, &Descent, &Extents);
  544. Pos->HitLeft = MenuLeft;
  545. Pos->HitTop = MenuTop;
  546. Pos->HitWidth = Extents.width;
  547. Pos->HitHeight =
  548. menu_font_info->max_bounds.ascent + menu_font_info->max_bounds.descent;
  549. MenuLeft += Extents.width + 8;
  550. Pos = Pos->Next;
  551. }
  552. }
  553. /* =============================================================================
  554. * FUNCTION: XMENU_HandleEvent
  555. */
  556. int XMENU_HandleEvent(XEvent *Event) {
  557. int Selected;
  558. int x, y;
  559. Selected = XMENU_NULLID;
  560. switch (Event->type) {
  561. case ButtonPress:
  562. x = Event->xbutton.x;
  563. y = Event->xbutton.y;
  564. if (Event->xbutton.button != Button1)
  565. return 0;
  566. if (XMENU_MenuHit(The_Menu, x, y) != NULL)
  567. Selected = XMENU_HandleSelection(The_Menu, x, y);
  568. return Selected;
  569. default:
  570. break;
  571. }
  572. return -1;
  573. }