66 #include <X11/cursorfont.h> 70 #include <X11/keysymdef.h> 75 #include "pixmap_helper.h" 104 static int InternalPopulateMenuFromResource(
WBMenu *pMenu,
int iID,
const char *pszResource);
120 bzero(pRval,
sizeof(
WBMenu) + iReserveSpace);
123 pEnd = (
unsigned char *)(pRval + 1);
128 pEnd += iReserveSpace / 2;
146 while(*p1 && *p1 <=
' ')
150 while(*p1 && *p1 >
' ')
153 bzero(tbuf,
sizeof(tbuf));
155 memcpy(tbuf, p2,
sizeof(tbuf) - 1 < (p1 - p2) ?
sizeof(tbuf) - 1 : p1 - p2);
157 while(*p1 && *p1 !=
'\n')
167 if(!*tbuf || *p1 !=
'\n' ||
168 (iID = atoi(tbuf)) <= 0)
181 if(!InternalPopulateMenuFromResource(pRval,iID,pszResource))
196 WB_ERROR_PRINT(
"ERROR: %s - invalid menu pointer %p\n", __FUNCTION__, pMenu);
202 for(i1=0; i1 < pMenu->
nItems; i1++)
210 for(i1=0; i1 < pMenu->
nPopups; i1++)
235 WB_ERROR_PRINT(
"ERROR: %s - invalid WBMenu pointer %p\n", __FUNCTION__, pMenu);
258 WB_ERROR_PRINT(
"ERROR: %s - invalid WBMenuItem pointer %p\n", __FUNCTION__, pMenuItem);
271 WB_ERROR_PRINT(
"ERROR: %s - invalid menu item pointer %p\n", __FUNCTION__, pMenuItem);
284 WB_ERROR_PRINT(
"ERROR: %s - invalid menu pointer %p\n", __FUNCTION__, pMenu);
290 WB_ERROR_PRINT(
"ERROR: %s - invalid menu item pointer %p\n", __FUNCTION__, pItem);
301 WB_ERROR_PRINT(
"ERROR: %s - invalid menu pointer %p\n", __FUNCTION__, pMenu);
311 WB_ERROR_PRINT(
"ERROR: %s - invalid menu pointer %p\n", __FUNCTION__, pMenu);
317 WB_ERROR_PRINT(
"ERROR: %s - invalid menu pointer %p\n", __FUNCTION__, pPopupMenu);
330 WB_ERROR_PRINT(
"ERROR: %s - invalid menu pointer %p\n", __FUNCTION__, pMenu);
343 WB_ERROR_PRINT(
"ERROR: %s - invalid menu pointer %p\n", __FUNCTION__, pMenu);
357 WB_ERROR_PRINT(
"ERROR: %s - invalid menu pointer %p\n", __FUNCTION__, pMenu);
367 #define NEXT_LINE(X,Y) { while(*X && *X <= ' ' && *X != '\t' && *X != '\n') X++; Y=X; while(*X && *X != '\n') X++; if(*X=='\n') X++; } 368 #define NEXT_COL(X,Y,Z) { while(*X && *X <= ' ' && *X != '\t' && *X != '\n' && X < Z) X++; \ 369 Y=X; while(*X && *X != '\t' && *X != '\n' && X < Z) X++; if(*X == '\t' || *X == '\n') X++; } 371 static void InternalLocateMenuInResource(
const char *pszResource,
int *piID,
372 const char **ppStart,
const char **ppEnd)
375 const char *p1, *p2, *p3;
388 while(p3 < p1 && *p3 !=
'\n' && *p3 !=
'\t')
398 bzero(tbuf,
sizeof(tbuf));
399 memcpy(tbuf, p2, (
sizeof(tbuf) - 1) < (p1 - p2) ?
sizeof(tbuf) - 1 : (p1 - p2));
401 p4 = tbuf + strlen(tbuf);
403 while(p4 > tbuf && *(p4 - 1) <=
' ')
443 while(p3 < p1 && *p3 !=
'\n' && *p3 !=
'\t')
453 bzero(tbuf,
sizeof(tbuf));
454 memcpy(tbuf, p2, (
sizeof(tbuf) - 1) < (p1 - p2) ?
sizeof(tbuf) - 1 : (p1 - p2));
456 p4 = tbuf + strlen(tbuf);
458 while(p4 > tbuf && *(p4 - 1) <=
' ')
473 while(p1 > p2 && *(p1 - 1) !=
'\n')
485 static int InternalPopulateMenuFromResource(
WBMenu *pMenu,
int iID,
const char *pszResource)
494 InternalLocateMenuInResource(pszResource, &iID, &p1, &p2);
520 while(p1 < p2 && *p1 <=
' ' && *p1 !=
'\t')
528 for(i1=0; i1 < pMenu->
nItems; i1++)
558 WB_WARN_PRINT(
"%s - WARNING: Unable to create popup for %d\n",
567 #define ALT_HOTKEY 0x80000000L 568 #define CTRL_HOTKEY 0x40000000L 569 #define SHIFT_HOTKEY 0x20000000L 571 static int TranslateHotKeyText(
const char *szText)
573 if((szText[0] ==
'F' || szText[0] ==
'f') &&
574 szText[1] >=
'1' && szText[1] <=
'9')
576 int iF = szText[1] -
'0';
577 if(szText[2] >=
'0' && szText[2] <=
'9')
579 iF = iF * 10 + (szText[2] -
'0');
582 return (XK_F1 + iF - 1);
584 else if(!strncasecmp(szText,
"home", 4))
588 else if(!strncasecmp(szText,
"end", 3))
592 else if(!strncasecmp(szText,
"left", 4))
596 else if(!strncasecmp(szText,
"right", 5))
600 else if(!strncasecmp(szText,
"up", 2))
604 else if(!strncasecmp(szText,
"down", 4))
608 else if(!strncasecmp(szText,
"pgup", 4) || !strncasecmp(szText,
"prior", 5))
612 else if(!strncasecmp(szText,
"pgdown", 6) || !strncasecmp(szText,
"next", 4))
616 else if(!strncasecmp(szText,
"del", 3))
620 else if(!strncasecmp(szText,
"ins", 3))
628 static int ProcessHotKeyText(
const char *szText)
635 const char *p1 = strchr(szText,
'+');
640 int iLen = p1 - szText;
643 if((!strncasecmp(szText,
"alt", 3) && iLen == 3) ||
644 (!strncasecmp(szText,
"meta", 4) && iLen == 4))
648 else if((!strncasecmp(szText,
"ctrl", 4) && iLen == 4) ||
649 (!strncasecmp(szText,
"control", 7) && iLen == 7))
651 iBits |= CTRL_HOTKEY;
653 else if(!strncasecmp(szText,
"shift", 5) && iLen == 5)
655 iBits |= SHIFT_HOTKEY;
659 WB_WARN_PRINT(
"%s - Hotkey description %*s not defined\n", __FUNCTION__, iLen, szText);
664 p1 = strchr(szText,
'+');
667 return TranslateHotKeyText(szText) | iBits;
673 const char *p1, *p2, *p3, *p5;
685 NEXT_COL(p1, p3, p2);
697 NEXT_COL(p1, p3, p2);
704 NEXT_COL(p1, p3, p2);
716 NEXT_COL(p1, p3, p2);
747 p4 = (
char *)pRval->
data;
751 NEXT_COL(p1, p3, p2);
758 if(p1 > p3 && (*(p1 - 1) ==
'\t' || *(p1 - 1) ==
'\n'))
760 memcpy(p4, p3, (p1 - p3) - 1);
765 memcpy(p4, p3, p1 - p3);
771 while(*p5 && *p5 !=
'_')
790 NEXT_COL(p1, p3, p2);
794 bzero(tbuf,
sizeof(tbuf));
795 memcpy(tbuf, p3, (p1 - p3) > (
sizeof(tbuf) - 1) ?
sizeof(tbuf) - 1 : p1 - p3);
799 while(i1 > 0 && tbuf[i1 - 1] <=
' ')
804 if(!strcasecmp(tbuf,
"separator"))
808 else if(!strcasecmp(tbuf,
"dynamic"))
812 else if(!strcasecmp(tbuf,
"popup"))
829 if(pRval->
iAction == (
int)None)
831 WB_WARN_PRINT(
"%s - WARNING: cannot find menu message atom %s\n", __FUNCTION__, tbuf);
842 NEXT_COL(p1, p3, p2);
848 bzero(tbuf,
sizeof(tbuf));
849 memcpy(tbuf, p3, (p1 - p3) > (
sizeof(tbuf) - 1) ?
sizeof(tbuf) - 1 : p1 - p3);
851 while(tbuf[0] && tbuf[strlen(tbuf) - 1] <=
' ')
853 tbuf[strlen(tbuf) - 1] = 0;
868 if(p1 > p3 && *(p1 - 1) ==
'\t')
870 memcpy(p4, p3, (p1 - p3) - 1);
876 memcpy(p4, p3, p1 - p3);
882 while(i1 > 0 && p4[i1 - 1] <=
' ')
894 NEXT_COL(p1, p3, p2);
901 if(p1 > p3 && *(p1 - 1) ==
'\t')
903 memcpy(p4, p3, (p1 - p3) - 1);
911 memcpy(p4, p3, p1 - p3);
920 while(i1 > 0 && p4[i1 - 1] <=
' ')
935 if(p1 > p3 && *(p1 - 1) ==
'\t')
937 memcpy(p4, p3, (p1 - p3) - 1);
944 memcpy(p4, p3, p1 - p3);
953 while(i1 > 0 && p4[i1 - 1] <=
' ')
960 pRval->
nHotKey = ProcessHotKeyText(p4);
976 NEXT_COL(p1, p3, p2);
980 if(p1 > p3 && *(p1 - 1) ==
'\t')
982 memcpy(p4, p3, (p1 - p3) - 1);
989 memcpy(p4, p3, p1 - p3);
998 while(i1 > 0 && p4[i1 - 1] <=
' ')
1033 WBDebugPrint(
" POPUP MENU \"%s\" %d \"%s\" \"%s\" %-.2s\n",
1041 WBDebugPrint(
" POPUP MENU \"%s\" %d \"%s\" \"%s\" \"%s\"(%xH) %-.2s\n",
1062 WBDebugPrint(
" MENU ITEM \"%s\" %d \"%s\" \"%s\" %-.2s\n",
1070 WBDebugPrint(
" MENU ITEM \"%s\" %d \"%s\" \"%s\" \"%s\"(%xH) %-.2s\n",
1104 #include "menu_popup.h" 1106 static void __PostMenuActivateEvent(
WBMenu *pMenu,
WBMenuItem *pItem,
int iIndex,
int iIsPopup)
1108 XClientMessageEvent evt;
1118 bzero(&evt,
sizeof(evt));
1119 evt.type = ClientMessage;
1121 evt.window = pMB->
wSelf;
1125 evt.data.l[1] = iIndex;
1129 WB_DEBUG_PRINT(DebugLevel_Chatty | DebugSubSystem_Menu | DebugSubSystem_Keyboard,
1130 "%s - FOUND '%s', posting client event to menu bar\n",
1136 WB_DEBUG_PRINT(DebugLevel_Chatty | DebugSubSystem_Menu | DebugSubSystem_Keyboard,
1137 "%s - FOUND '%s', NOT posting client event to menu bar\n",
1149 bzero(&evt,
sizeof(evt));
1150 evt.type = ClientMessage;
1152 evt.window = pMP->wSelf;
1156 evt.data.l[1] = iIndex;
1160 WB_DEBUG_PRINT(DebugLevel_Chatty | DebugSubSystem_Menu | DebugSubSystem_Keyboard,
1161 "%s - FOUND '%s', posting client event to popup\n",
1167 WB_DEBUG_PRINT(DebugLevel_Chatty | DebugSubSystem_Menu | DebugSubSystem_Keyboard,
1168 "%s - FOUND '%s', NOT posting client event to popup\n",
1175 static WBMenuItem * __HotKeySearchRecurse(
WBMenu *pMenu,
int iHotKey,
int *piIndex,
int iLevel)
1180 for(i1=0; i1 < pMenu->
nItems; i1++)
1189 WB_DEBUG_PRINT(DebugLevel_Excessive | DebugSubSystem_Menu | DebugSubSystem_Keyboard,
1190 "%s - comparing %x to %x '%s' for %s\n",
1191 __FUNCTION__, iHotKey, pItem->
nHotKey,
1208 for(i1=0; i1 < pMenu->
nPopups; i1++)
1210 pRval = __HotKeySearchRecurse(pMenu->
ppPopups[i1], iHotKey, piIndex, iLevel + 1);
1212 if(pRval || *piIndex >= 0)
1221 static WBMenuItem * __HotKeySearch(
WBMenu *pMenu,
int iHotKey,
int *piIndex)
1225 return __HotKeySearchRecurse(pMenu, iHotKey, piIndex, 0);
1230 int iACS = 0, iKey, i1, iIsPopup, nChar;
1238 WB_ERROR_PRINT(
"ERROR: %s - invalid menu pointer %p\n", __FUNCTION__, pMenu);
1246 if(pEvent->type != KeyPress )
1248 WB_DEBUG_PRINT(DebugLevel_Excessive | DebugSubSystem_Event | DebugSubSystem_Menu | DebugSubSystem_Keyboard,
1249 "%s - event not KeyPress\n", __FUNCTION__);
1253 nChar =
sizeof(tbuf);
1259 if(iKey >= XK_Shift_L && iKey <= XK_Hyper_R)
1261 WB_DEBUG_PRINT(DebugLevel_Excessive | DebugSubSystem_Event | DebugSubSystem_Menu | DebugSubSystem_Keyboard,
1262 "%s - Key %d (%xH) within 'modifier key' range\n", __FUNCTION__, iKey, iKey);
1270 if((
unsigned int)iKey >=
' ' && (
unsigned int)iKey <= 0x7f)
1272 register int iKOld = iKey;
1274 iKey = toupper(iKOld);
1278 WB_DEBUG_PRINT(DebugLevel_Excessive | DebugSubSystem_Event | DebugSubSystem_Menu | DebugSubSystem_Keyboard,
1279 "%s - Converting Key %d (%xH) to %d (%xH)\n", __FUNCTION__, iKOld, iKOld, iKey, iKey);
1283 WB_DEBUG_PRINT(DebugLevel_Excessive | DebugSubSystem_Menu | DebugSubSystem_Keyboard,
1284 "%s - POSSIBLE MENU KEY PRESS for KEY %d (%xH) KEYCODE %d ACS=%xH\n",
1285 __FUNCTION__, iKey, iKey, ((XKeyEvent *)pEvent)->keycode, iACS);
1298 WB_DEBUG_PRINT(DebugLevel_Excessive | DebugSubSystem_Event | DebugSubSystem_Menu | DebugSubSystem_Keyboard,
1299 "%s - Key %d (%xH) ACS=%xH not valid for non-popup menu\n", __FUNCTION__, iKey, iKey, iACS);
1303 (iKey < 0xfd00 || iKey > 0xffff))
1323 WB_DEBUG_PRINT(DebugLevel_Excessive | DebugSubSystem_Menu | DebugSubSystem_Keyboard,
1324 "%s - menu has %d items\n", __FUNCTION__, pMenu->
nItems);
1326 for(i1=0; i1 < pMenu->
nItems; i1++)
1342 WB_ERROR_PRINT(
"TODO: %s - dynamic menu hotkey search not implemented\n", __FUNCTION__);
1360 __PostMenuActivateEvent(pMenu, pItem, i1, iIsPopup);
1379 iHotKey0 |= ALT_HOTKEY;
1383 if(iHotKey0 > 0 && iHotKey0 < 0x1f)
1388 iHotKey0 |= CTRL_HOTKEY;
1392 iHotKey0 |= SHIFT_HOTKEY;
1396 pItem = __HotKeySearch(pMenu, iHotKey0, &i1);
1409 __PostMenuActivateEvent(pMenu, pItem, i1, iIsPopup);
1413 XClientMessageEvent evt;
1414 Window wIDBar, wIDOwner;
1423 WB_WARN_PRINT(
"%s - menu bar window NULL, hotkey eaten\n", __FUNCTION__);
1427 wIDBar = pMB->
wSelf;
1436 WB_WARN_PRINT(
"%s - menu popup window NULL, hotkey eaten\n", __FUNCTION__);
1441 wIDOwner = pMP->wOwner;
1446 bzero(&evt,
sizeof(evt));
1447 evt.type = ClientMessage;
1449 evt.display = pDisplay;
1450 evt.window = wIDOwner;
1453 evt.data.l[0] = pItem->
iAction;
1455 evt.data.l[2] = wIDBar;
1461 WB_DEBUG_PRINT(DebugLevel_WARN | DebugSubSystem_Menu | DebugSubSystem_Event,
1462 "%s - Post Event: %08xH %08xH %pH %08xH\n", __FUNCTION__,
1464 pMenu, (
int)wIDBar);
'window helper' main header file for the X11workbench Toolkit API
#define WB_DEBUG_PRINT(L,...)
Preferred method of implementing conditional debug output.
int WBKeyEventProcessKey(const XKeyEvent *pEvent, char *pBuf, int *pcbLen, int *piAltCtrlShift)
Generic keyboard event translation utility.
#define WB_KEYEVENT_ALT
'AltCtrlShift' bit flag for ALT modifier for WBKeyEventProcessKey()
int WBPostPriorityEvent(Window wID, XEvent *pEvent)
Places a copy of the specified event at the end of the priority (internal) event queue.
static __inline__ Display * WBGetDefaultDisplay(void)
Returns the default Display.
'configuration helper' main header file for the X11 Work Bench Toolkit API
void * WBAlloc(int nSize)
High performance memory sub-allocator 'allocate'.
#define WB_ERROR_PRINT(...)
Preferred method of implementing an 'error level' debug message for all subsystems.
void WBFree(void *pBuf)
High performance memory sub-allocator 'free'.
int WBPostEvent(Window wID, XEvent *pEvent)
Places a copy of the specified event at the end of the regular (internal) event queue.
#define WB_KEYEVENT_SHIFT
'AltCtrlShift' bit flag for Shift modifier for WBKeyEventProcessKey()
int WBAllocUsableSize(void *pBuf)
High performance memory sub-allocator, similar to 'malloc_usable_size'.
Display * WBGetWindowDisplay(Window wID)
returns the Display associated with a window
void WBDebugPrint(const char *pFmt,...) __attribute__((format(printf
conditional debug message output
#define WB_KEYEVENT_CTRL
'AltCtrlShift' bit flag for Control modifier for WBKeyEventProcessKey()
#define WB_IF_DEBUG_LEVEL(L)
Preferred method of implementing conditional debug 'if block' code.
Frame Window API functions and definitions.
#define WB_WARN_PRINT(...)
Preferred method of implementing a 'warning level' debug message for all subsystems.