📄 menus.c
字号:
y = 0; MenuY = y; XMoveWindow(dpy, menu->w, x, y); XMapRaised(dpy, menu->w); menu->in_use = True; return True;}/* * unhighlight the current menu selection and take down the menus */static voidpop_down_menu(ScreenInfo *scr){ if (ActiveMenu == NULL) return; menu_on--; if (ActiveItem) ActiveItem->state = 0; XUnmapWindow(dpy, ActiveMenu->w); COLOR_PopRootColorMap(scr); XFlush(dpy); if (scr->event_context & (C_WINDOW | C_FRAME | C_TITLE | C_FRAME)) menuFromFrameOrWindowOrTitlebar = True; else menuFromFrameOrWindowOrTitlebar = False; ActiveMenu->in_use = False;}/* * Updates menu display to reflect the highlighted item * * Returns: * 0 on error condition * 1 on return from submenu to parent menu * 2 on button release return */static intupdate_menu(ScreenInfo *scr, MwmWindow *tmp){ int done, func; int retval; MenuRoot *actual_mr; XEvent oevent; int x, y; find_entry(scr, tmp); while (True) { /* block until there is an event */ XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask | ExposureMask | KeyPressMask | VisibilityChangeMask | ButtonMotionMask, &oevent); MISC_StashEventTime(&oevent); done = 0; if (oevent.type == MotionNotify) { /* discard any extra motion events before a release */ while ((XCheckMaskEvent(dpy, ButtonMotionMask | ButtonReleaseMask, &oevent)) && (oevent.type != ButtonRelease)); } /* Handle a limited number of key press events to allow mouseless * operation */ if (oevent.type == KeyPress) menu_shortcuts(scr, &oevent); switch (oevent.type) { case ButtonRelease: /* The following lines holds the menu when the button is released */ if (!ActiveItem && (menu_on > 1)) { XQueryPointer(dpy, scr->root_win, &JunkRoot, &JunkChild, &JunkX, &JunkY, &x, &y, &JunkMask); if ((XFindContext(dpy, JunkChild, MenuContext, (XPointer *)&actual_mr) != XCNOENT) && (actual_mr != ActiveMenu)) { done = 1; break; } } pop_down_menu(scr); if (ActiveItem) { func = ActiveItem->func; done = 1; if (scr->mwm_event) { FUNC_Execute(scr, func, ActiveItem->action, scr->mwm_event->frame, scr->mwm_event, &oevent, scr->event_context, ActiveItem->val1, ActiveItem->val2, ActiveItem->val1_unit, ActiveItem->val2_unit, ActiveItem->menu); } else { FUNC_Execute(scr, func, ActiveItem->action, None, None, &oevent, scr->event_context, ActiveItem->val1, ActiveItem->val2, ActiveItem->val1_unit, ActiveItem->val2_unit, ActiveItem->menu); } } ActiveItem = NULL; ActiveMenu = NULL; menuFromFrameOrWindowOrTitlebar = False; return MENU_DONE; case ButtonPress: XQueryPointer(dpy, scr->root_win, &JunkRoot, &JunkChild, &JunkX, &JunkY, &x, &y, &JunkMask); if ((XFindContext(dpy, JunkChild, MenuContext, (XPointer *)&actual_mr) == XCNOENT)) { pop_down_menu(scr); ActiveItem = NULL; ActiveMenu = NULL; menuFromFrameOrWindowOrTitlebar = False; XPutBackEvent(dpy, &oevent); return MENU_DONE; } done = 1; break; case KeyPress: case VisibilityNotify: done = 1; break; case MotionNotify: done = 1; retval = find_entry(scr, tmp); if ((retval == MENU_DONE) || (retval == SUBMENU_DONE)) { pop_down_menu(scr); ActiveItem = NULL; ActiveMenu = NULL; menuFromFrameOrWindowOrTitlebar = False; } if (retval == MENU_DONE) return MENU_DONE; else if (retval == SUBMENU_DONE) return MENU_NOP; break; case Expose: /* grab our expose events, let the rest go through */ if ((XFindContext(dpy, oevent.xany.window, MenuContext, (XPointer *)&actual_mr) != XCNOENT)) { paint_menu(scr, tmp, actual_mr, &oevent); done = 1; } break; default: break; } if (!done) EVENT_Dispatch(&oevent); XFlush(dpy); }}/* * Look for hotkey markers in a MenuItem (pete@tecc.co.uk) */voidMENU_FindHotKey(MenuItem *it, KeySym key){ char *str, *ptr; if (key != AnyKey) { str = XKeysymToString(key); for (ptr = it->item; ptr && *ptr && *ptr != *str; ptr++) ; if (ptr) { if (!*ptr) it->hotkey = 0; else it->hotkey = ptr - it->item + 1; } else it->hotkey = 0; } else it->hotkey = 0;}/* * create a new menu root */MenuRoot *MENU_Create(const char *name){ MenuRoot *tmp; tmp = (MenuRoot *) XtMalloc(sizeof(MenuRoot)); tmp->name = XtNewString(name); tmp->first = NULL; tmp->last = NULL; tmp->items = 0; tmp->width = 0; tmp->width2 = 0; tmp->w = None; return (tmp);}/* * add a menu to the menu list */voidMENU_Add(ScreenInfo *scr, MenuRoot * menu){ if (scr->max_popups == 0) { scr->max_popups = 8; scr->num_popups = 0; scr->popups = (MenuRoot **) XtMalloc(scr->max_popups * sizeof(MenuRoot *)); } else if (scr->num_popups == scr->max_popups) { scr->max_popups *= 2; scr->popups = (MenuRoot **) XtRealloc((char *)scr->popups, scr->max_popups * sizeof(MenuRoot *)); } scr->popups[scr->num_popups] = menu; scr->num_popups++;}/* * remove a menu from the screen's list of popups */voidMENU_Remove(ScreenInfo *scr, MenuRoot * menu){ int i; for (i = 0; i < scr->num_popups; i++) { if (menu == scr->popups[i]) { if (scr->num_popups != (i + 1)) memmove(&scr->popups[i], &scr->popups[i + 1], (scr->num_popups - i - 1) * sizeof(MenuRoot *)); scr->num_popups--; } }}/* * add an item to a root menu */voidMENU_AddItem(ScreenInfo *scr, MenuRoot * menu, char *item, char *item2, char *action, int func, long func_val_1, long func_val_2, char unit_1, char unit_2){ MenuItem *tmp; int width; if (item == NULL) return; tmp = (MenuItem *)XtMalloc(sizeof(MenuItem)); if (menu->first == NULL) { menu->first = tmp; tmp->prev = NULL; } else { menu->last->next = tmp; tmp->prev = menu->last; } menu->last = tmp; tmp->item = item; if (item != (char *)0) { MENU_FindHotKey(tmp, AnyKey); tmp->strlen = strlen(item); } else tmp->strlen = 0; tmp->item2 = item2; if (item2) tmp->strlen2 = strlen(item2); else tmp->strlen2 = 0; tmp->menu = 0; if (func == F_POPUP) { int i; if (action != (char *)0) { for (i = 0; i < scr->num_popups; i++)#if 0 /* amai: it seems we don't ever use this catch!?! */ if (strcasecmp(scr->popups[i]->name, action) == 0)#else if (strcmp(scr->popups[i]->name, action) == 0)#endif { tmp->menu = scr->popups[i]; break; } } if (tmp->menu == (MenuRoot *) 0) { fprintf(stderr, "No popup menu %s.", action); func = F_NOP; } } tmp->action = action; tmp->next = NULL; tmp->state = 0; tmp->func = func; tmp->val1 = func_val_1; tmp->val2 = func_val_2; if ((unit_1 == 'p') || (unit_1 == 'P')) tmp->val1_unit = 100; else tmp->val1_unit = scr->d_width; if ((unit_2 == 'p') || (unit_2 == 'P')) tmp->val2_unit = 100; else tmp->val2_unit = scr->d_height; width = XTextWidth(scr->components[MWM_MENU].font, item, tmp->strlen); if (tmp->func == F_POPUP) width += 15; if (width <= 0) width = 1; if (width > menu->width) menu->width = width; width = XTextWidth(scr->components[MWM_MENU].font, item2, tmp->strlen2); if (width < 0) width = 0; if (width > menu->width2) menu->width2 = width; if ((width == 0) && (tmp->strlen2 > 0)) menu->width2 = 1; menu->items++;}/* * Generates the window for a menu */voidMENU_Realize(ScreenInfo *scr, MenuRoot * mr){ MenuItem *cur; unsigned long valuemask; XSetWindowAttributes attributes; int y; /* lets first size the window accordingly */ mr->width += 10; if (mr->width2 > 0) mr->width += 5; /* allow two pixels for top border */ for (y = 2, cur = mr->first; cur != NULL; cur = cur->next) { cur->y_offset = y; cur->x = 5; if (cur->func == F_TITLE) { /* Title */ if (cur->strlen2 == 0) cur->x = (mr->width - XTextWidth(scr->components[MWM_MENU].font, cur->item, cur->strlen)) >> 1; cur->y_height = scr->components[MWM_MENU].f_height + HEIGHT_EXTRA + HEIGHT_EXTRA_TITLE; } else if (cur->func == F_NOP && *cur->item == 0) /* Separator */ cur->y_height = HEIGHT_SEPARATOR; else /* Normal text entry */ cur->y_height = scr->components[MWM_MENU].f_height + HEIGHT_EXTRA; y += cur->y_height; if (mr->width2 == 0) { cur->x2 = cur->x; } else { cur->x2 = mr->width - 5; } } mr->in_use = 0; mr->height = y + 2; valuemask = (CWBackPixel | CWEventMask | CWCursor | CWSaveUnder); attributes.background_pixel = scr->components[MWM_MENU].background; attributes.event_mask = (ExposureMask | EnterWindowMask); attributes.cursor = scr->cursors[MENU_CURS]; attributes.save_under = True; mr->width = mr->width + mr->width2; mr->w = XCreateWindow(dpy, scr->root_win, 0, 0, (unsigned int)(mr->width), (unsigned int)mr->height, (unsigned int)0, CopyFromParent, (unsigned int)InputOutput, (Visual *)CopyFromParent, valuemask, &attributes); XSaveContext(dpy, mr->w, MenuContext, (XPointer)mr);}/* * realize all the menus */voidMENU_RealizeMenus(ScreenInfo *scr){ int i; for (i = 0; i < scr->num_popups; i++) MENU_Realize(scr, scr->popups[i]);}/* * menu ordering isn't required by mwm (meaning you can use f.menu <menu-name> * before <menu-name> has been declared). Therefore, we have to defer linking * menus together until after the parse phase. */voidMENU_LinkUp(ScreenInfo *scr){ int i, k; MenuRoot *mr = NULL; MenuItem *mi = NULL; FuncKey *fk = NULL; MouseButton *mb = NULL; for (i = 0; i < scr->num_popups; i++) { mr = scr->popups[i]; mi = mr->first; while (mi != NULL) { if (mi->func == F_POPUP) { for (k = 0; k < scr->num_popups; k++) { if (strcmp(scr->popups[k]->name, mi->action) == 0) { mi->menu = scr->popups[k]; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -