1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.menubar.internal; 18 19 import com.android.menubar.IMenuBarCallback; 20 import com.android.menubar.IMenuBarEnhancer; 21 22 import org.eclipse.swt.internal.Callback; 23 import org.eclipse.swt.internal.carbon.HICommand; 24 import org.eclipse.swt.internal.carbon.OS; 25 import org.eclipse.swt.widgets.Display; 26 import org.eclipse.swt.widgets.Menu; 27 28 29 /** 30 * Implementation of IMenuBarEnhancer for MacOS Carbon SWT. 31 */ 32 public final class MenuBarEnhancerCarbon implements IMenuBarEnhancer { 33 34 private static final int kHICommandPreferences = ('p'<<24) + ('r'<<16) + ('e'<<8) + 'f'; 35 private static final int kHICommandAbout = ('a'<<24) + ('b'<<16) + ('o'<<8) + 'u'; 36 private static final int kHICommandServices = ('s'<<24) + ('e'<<16) + ('r'<<8) + 'v'; 37 MenuBarEnhancerCarbon()38 public MenuBarEnhancerCarbon() { 39 } 40 getMenuBarMode()41 public MenuBarMode getMenuBarMode() { 42 return MenuBarMode.MAC_OS; 43 } 44 setupMenu( String appName, Display display, final IMenuBarCallback callbacks)45 public void setupMenu( 46 String appName, 47 Display display, 48 final IMenuBarCallback callbacks) { 49 50 // Callback target 51 Object target = new Object() { 52 @SuppressWarnings("unused") 53 int commandProc(int nextHandler, int theEvent, int userData) { 54 if (OS.GetEventKind(theEvent) == OS.kEventProcessCommand) { 55 HICommand command = new HICommand(); 56 OS.GetEventParameter( 57 theEvent, 58 OS.kEventParamDirectObject, 59 OS.typeHICommand, 60 null, 61 HICommand.sizeof, 62 null, 63 command); 64 switch (command.commandID) { 65 case kHICommandPreferences: 66 callbacks.onPreferencesMenuSelected(); 67 return OS.eventNotHandledErr; // TODO wrong 68 case kHICommandAbout: 69 callbacks.onAboutMenuSelected(); 70 return OS.eventNotHandledErr;// TODO wrong 71 default: 72 break; 73 } 74 } 75 return OS.eventNotHandledErr; 76 } 77 }; 78 79 final Callback commandCallback= new Callback(target, "commandProc", 3); //$NON-NLS-1$ 80 int commandProc = commandCallback.getAddress(); 81 if (commandProc == 0) { 82 commandCallback.dispose(); 83 log(callbacks, "%1$s: commandProc hook failed.", getClass().getSimpleName()); //$NON-NLS-1$ 84 return; // give up 85 } 86 87 // Install event handler for commands 88 int[] mask = new int[] { 89 OS.kEventClassCommand, OS.kEventProcessCommand 90 }; 91 OS.InstallEventHandler( 92 OS.GetApplicationEventTarget(), commandProc, mask.length / 2, mask, 0, null); 93 94 // create About Eclipse menu command 95 int[] outMenu = new int[1]; 96 short[] outIndex = new short[1]; 97 if (OS.GetIndMenuItemWithCommandID( 98 0, kHICommandPreferences, 1, outMenu, outIndex) == OS.noErr && outMenu[0] != 0) { 99 int menu = outMenu[0]; 100 101 // add About menu item (which isn't present by default) 102 String about = "About " + appName; 103 int l = about.length(); 104 char buffer[] = new char[l]; 105 about.getChars(0, l, buffer, 0); 106 int str = OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, buffer, l); 107 OS.InsertMenuItemTextWithCFString(menu, str, (short) 0, 0, kHICommandAbout); 108 OS.CFRelease(str); 109 110 // add separator between About & Preferences 111 OS.InsertMenuItemTextWithCFString(menu, 0, (short) 1, OS.kMenuItemAttrSeparator, 0); 112 113 // enable pref menu 114 OS.EnableMenuCommand(menu, kHICommandPreferences); 115 116 // disable services menu 117 OS.DisableMenuCommand(menu, kHICommandServices); 118 } 119 120 // schedule disposal of callback object 121 display.disposeExec( 122 new Runnable() { 123 public void run() { 124 commandCallback.dispose(); 125 } 126 } 127 ); 128 } 129 log(IMenuBarCallback callbacks, String format, Object... args)130 private void log(IMenuBarCallback callbacks, String format, Object... args) { 131 callbacks.printError(format , args); 132 } 133 134 } 135