links to this page:    
View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
Host Menus
Last updated at 9:25 pm UTC on 14 November 2006
As of this date (Oct 15 2004) there is an architecture description and reference alpha-quality implementations for Mac OS/X. This architecture is for the lowest levels of the system, the virtual machine and dungeon levels of the image.

John notes an example of usage can be found in the Sophie Application.

Some assumptions:
a) A window has a menubar, I'll note the macintosh has only one menu bar for all windows.
b) This code depends on Areithfa Ffenestri for multiple host window support,
c) The host OS VM needs to generate the needed menu events as a result of host operating system menu activity.

VM changes:
a) The VM can build the basic menu structure, and the smalltalk menu startup code must then revise and understand that, or VM can choose not to build any menus. Keep in mind issues with backward image/VM capabilities if you choose not to build any menus.

b) The VM must process a host OS menu event and generate a EventTypeMenu event record supplying the timestamp, a magic number indicating the menu invoked which the smalltalk code can use to find the smalltalk objects that manage the menu, a number indicating the menu item (1-N) picked, and finally the window index number.

Smalltalk code
The system has a sole instance of HostSystemMenus, which at image startup time rebuilds an instance of HostSystemMenusProxy (or subclass) which is responsible for interfacing to the host operating system by using a host system specific plugin. For supported systems a subclass of HostSystemMenusProxy is used, which one picked is done by having the subclass return true to the message send isActiveHostMenuProxyClass. The macintosh implementation builds a menu structure mimicing the VM installed menus. For os-x it also installs the Window menu and the disables the 'M' and 'H' cmd keys.

All method calls are referred to the menu proxy for resolution.

createMenuBar: - action depends on if VM has created a menubar for the window.
clearMenuBar: - clear the menus off the existing menu bar for the indicated window index.
defaultMenuBarForWindowIndex: Return proxy which manages menubar for window index.
disposeMenuBar: - delete the menubar for the indicated window index.
drawMenuBar: - draw the menubar for the indicated window index.
hideMenuBar: - hide the menubar for the indicated window index.
isMenuBarVisible: - return true if the menubar is visible, versus hidden for the indicated window index.
showMenuBar: - show the menubar for the indicated window index.

OS-9/OS-X specific calls
invalMenuBar. - invalidates the menu bar for a pending redraw event.

Menus - a menu is identified by a menuID or a menuHandle (yes this mimics the macintosh OS needs).

appendMenu:menuItems: - append these menu items onto the supplied menu handle
checkMenuItem:item:checked: - put a check mark, or not, on item N of menu handle
countMenuItems: - return number of menu items for the supplied menu handle
deleteMenu: - delete the menu based on the supplied menu handle
deleteMenuItem:item: - delete the menu item N for the supplied menu handle
disableMenuItem:item: - disable the menu item N for the supplied menu handle
enableMenuItem:item: - enable the menu item N for the supplied menu handle
getItemCmd:item: - get the menu item keyboard ascii code for item N for the supplied menu handle.
getItemIcon:item: - get the menu item icon value for item N for the supplied menu handle.
getItemMark:item: get the menu item ascii mark value for item N for the supplied menu handle.
getItemStyle:item: get the menu item style for item N for the supplied menu handle. This is platform specific?
getMenuHandle: - given a menu id number, return the magic handle
getMenuID: - given a magic menu handle, return the menu id number.
getMenuItemText:item: get the menu item ascii text for item N for the supplied menu
getMenuTitle: - get the menu ascii text for the title.
insertMenu:beforeID: Insert a new menu in the menubar before menu id number
insertMenuItem:item:afterItem: Insert a new menu item in the menu after item N
isMenuItemEnabled:item: return true if menu item N is enabled in the supplied menu
newMenu:menuTitle: Create a new menu, using menu id number and supplied title.
setItemCmd:item:cmdChar: Set the command ascii character for item N for the supplied menu
setItemMark:item:markChar: Set the mark ascii character for item N for the supplied menu
setItemStyle:item:style: Set the style for item N for the supplied menu
setMenuItemHierarchicalID:item:hierID: For supplied menu and item insert a sub menu
setMenuItemModifiers:item:inModifiers: Set the modifiers for item N for the supplied menu
setMenuTitle:title: Set the menu title for the supplied menu

OS-9 specific methods
appendMenuItemText:data: - Append the text to the indicated menu item.
getMenuItemCommandID:item: - Get the command id number for the indicated menu item
getMenuItemFontID:item: - Get the font id number
getMenuItemHierarchicalID:item: - Get the hiearchical ID for the menu item which is a submenu.
getMenuItemKeyGlyph:item: - Get the key glyph value
getMenuItemModifiers:item: - Get the modifier data
getMenuItemText:item: - Get the menu item text
getMenuItemTextEncoding:item: - Get the menu item text encoding
insertFontResMenu:afterItem:scriptFilter: - Insert the Font menu into the menubar
setMenuItemCommandID:item:menuCommand: - Set commandID for menu item
setMenuItemFontID:item:fontID: - Set Font id for the menu item
setMenuItemKeyGlyph:item:glyph: - Set the key glyph for the menu item
setMenuItemModifiers:item:inModifiers: - set the modifier for the menu item
setMenuItemText:item:itemString: - set the menu item text for the menu item
setMenuItemTextEncoding:item:inScriptID: - set the encoding for the menu item

bold, italic, underline, outline, shadow.

OS9 menu data strings
Follows standards from classic mac menu strings
^ defines icon

defines mark

/ defines command
( defines disable

OS-X menus
appendStandardWindowMenu: - This method builds a menu structure mimicing the VM build menus, it also removes the cmd-H key (hide) and builds a Window menu so the user can cycle between windows, as part of this processing it removes the cmd-M key (minimize).

createStandardWIndowMenu: - Asks the mac to build a standard Window menu. However this will create a menu with a 'M' cmd key which you must disable.
disableMenuCommand:command: - Disable menu item with this commandID.
enableMenuCommand:command: - Enable menu item with this commandID.
getIndMenuItemWithCommandID:item: - Get menu item number with this commandID.
getIndMenuWithCommandID:item: - Get menu handle with this commandID

Menu Events

When menu events are passed up from the VM by a VM that actually generates the events, they are processed in EventSensor>>processMenuEvent: which calls HostSystemMenus>>defaultMenuBarForWindowIndex: N. This returns the proxy that handles the interface to the menu bar for the window that has windowIndex N. It then invokes HostSystemMenuProxy>>getHandlerForMenu:item: to get a block that will act on the invocation of menu N, menu Item M. See HostSystemMenusMenuItem class>>fakeKeyboardEventBlockascii:unicode:
for the default blocks definition which defaults to insert the command key keyboard stroke into the event queue. This then mimics command key usage which is being watched for by Morphic/Tweak widgets. Two creation methods are used to assist in this effort.

| items menuBar |

HostSystemMenus defaultMenuBarForWindowIndex: 1.
menuBar := interface menuBar.
secondaryMenu := interface newMenu: 4 menuTitle: "Foobar'.
interface insertMenu: secondaryMenu beforeID: 0.
items := OrderedCollection with: (HostSystemMenusMenuItem menuString: 'one')
with: (HostSystemMenusMenuItem menuString: 'two' keyboardKey: $a).
interface appendMenu: secondaryMenu menuItems: items.

" This example creates a Foobar menu with menuID 4. It has two menu items, 'one' and 'two' where 'two' has a cmd key of $a"

This creation method actually invokes
HostSystemMenusMenuItem>> text:cmd:handler:
where the handler is
HostSystemMenusMenuItem>>fakeKeyboardEventBlockascii: aKey unicode: aKey
Note the usage of both ascii and unicode.