FILE COMPARISON
Produced: 2/18/2011 1:40:52 AM
   
Mode:  All Lines  
Left base folder: C:\Documents and Settings\krollins\My Documents\Admin\OpenSource\eRCP\eSWT\eSWT-1.2.orig  
Right base folder: C:\Documents and Settings\krollins\My Documents\Admin\OpenSource\eRCP\eSWT\eSWT-1.2.today  
   
File: org.eclipse.ercp.swt.core.win\win-native\impl\Display.c  
1 /******************************************************************************* = 1 /*******************************************************************************
2 * Copyright (c) 2000, 2005 IBM Corporation and others.   2 * Copyright (c) 2000, 2005 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials   3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0   4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at   5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html   6 * http://www.eclipse.org/legal/epl-v10.html
7 *   7 *
8 * Contributors:   8 * Contributors:
9 *     IBM Corporation - initial API and implementation   9 *     IBM Corporation - initial API and implementation
10 *******************************************************************************/   10 *******************************************************************************/
    <> 11  
      12 /*******************************************************************************
      13 * Additions/modifications to this source file by Oracle America, Inc. 2011
      14 *******************************************************************************/
      15  
11 #define _WIN32_WINNT 0x0500 = 16 #define _WIN32_WINNT 0x0500
12     17  
13 #include "ugl_win32.h"   18 #include "ugl_win32.h"
14     19  
15 #include "Callback.h"   20 #include "Callback.h"
16 #include "UGL_Win32_DC.h"   21 #include "UGL_Win32_DC.h"
17 #include "UGL_Win32_Display.h"   22 #include "UGL_Win32_Display.h"
18 #include "UGL_Win32_Widget.h"   23 #include "UGL_Win32_Widget.h"
19 #include "UGL_Win32_Menu.h"   24 #include "UGL_Win32_Menu.h"
20 #include "UGL_Win32_Tray.h"   25 #include "UGL_Win32_Tray.h"
21 #include "KeyUtils.h"   26 #include "KeyUtils.h"
22     27  
23 #include "Shell.h"   28 #include "Shell.h"
24 #include "Color.h"   29 #include "Color.h"
25 #include "Button.h"   30 #include "Button.h"
26 #include "Label.h"   31 #include "Label.h"
27 #include "TextArea.h"   32 #include "TextArea.h"
28 #include "Composite.h"   33 #include "Composite.h"
29 #include "List.h"   34 #include "List.h"
30 #include "Combo.h"   35 #include "Combo.h"
31 #include "Device.h"   36 #include "Device.h"
32     37  
33 #include "Display.h"   38 #include "Display.h"
34 #include <stdio.h>   39 #include <stdio.h>
35 #include <shlwapi.h>   40 #include <shlwapi.h>
36     41  
37 static LRESULT CALLBACK creationProc(HWND, UINT, WPARAM, LPARAM);   42 static LRESULT CALLBACK creationProc(HWND, UINT, WPARAM, LPARAM);
38     43  
39 static VOID CALLBACK _Timer_Proc(HWND, UINT, UINT_PTR, DWORD);   44 static VOID CALLBACK _Timer_Proc(HWND, UINT, UINT_PTR, DWORD);
40 void _Dispose_Display(UGL_Int handle, UGL_Error uglError);   45 void _Dispose_Display(UGL_Int handle, UGL_Error uglError);
41     46  
42 #define MENU_ITEMS_INCREMENT 4   47 #define MENU_ITEMS_INCREMENT 4
43     48  
44 /**   49 /**
45 * Strange behavior happens when menu IDs less than 108 are used.  The   50 * Strange behavior happens when menu IDs less than 108 are used.  The
46 * PocketPC will display some system menus when certian low IDs are used.   51 * PocketPC will display some system menus when certian low IDs are used.
47 * This offset is the difference between the menu item index in the global   52 * This offset is the difference between the menu item index in the global
48 * list and the value of the id.   53 * list and the value of the id.
49 */   54 */
50 #define MENU_ITEM_ID_OFFSET 108   55 #define MENU_ITEM_ID_OFFSET 108
51     56  
52 HINSTANCE g_hInstance = NULL;   57 HINSTANCE g_hInstance = NULL;
53 BOOL WINAPI DllMain(HANDLE hInstDLL, DWORD dwReason, LPVOID lpvReserved)   58 BOOL WINAPI DllMain(HANDLE hInstDLL, DWORD dwReason, LPVOID lpvReserved)
54 {   59 {
55     if (dwReason == DLL_PROCESS_ATTACH) {   60     if (dwReason == DLL_PROCESS_ATTACH) {
56         if (g_hInstance == NULL) g_hInstance = hInstDLL;   61         if (g_hInstance == NULL) g_hInstance = hInstDLL;
57     }   62     }
58     return TRUE;   63     return TRUE;
59 }   64 }
60     65  
61 //========================================================================================   66 //========================================================================================
62     67  
63 CallbackLookup* Display_GetCallbacks(UGL_Int displayHandle) {   68 CallbackLookup* Display_GetCallbacks(UGL_Int displayHandle) {
64     PUGL_Display display = UGL_DISPLAY(displayHandle);   69     PUGL_Display display = UGL_DISPLAY(displayHandle);
65     return display->callback_lookup;   70     return display->callback_lookup;
66 }   71 }
67 //========================================================================================   72 //========================================================================================
68     73  
69 void Display_SetCallbacks(UGL_Int displayHandle, CallbackLookup* callbacks) {   74 void Display_SetCallbacks(UGL_Int displayHandle, CallbackLookup* callbacks) {
70     PUGL_Display display = UGL_DISPLAY(displayHandle);   75     PUGL_Display display = UGL_DISPLAY(displayHandle);
71     display->callback_lookup = callbacks;   76     display->callback_lookup = callbacks;
72 }   77 }
73     78  
74 //========================================================================================   79 //========================================================================================
75     80  
76 void Display_StartTimer(UGL_Int handle, UGL_Int milliseconds, UGL_Int timerId, UGL_Error uglError) {   81 void Display_StartTimer(UGL_Int handle, UGL_Int milliseconds, UGL_Int timerId, UGL_Error uglError) {
77     PUGL_Display ugl_display = UGL_DISPLAY(handle);   82     PUGL_Display ugl_display = UGL_DISPLAY(handle);
78     83  
79     // Although the MSDN documentation does not mention this, SetTimer will fail on   84     // Although the MSDN documentation does not mention this, SetTimer will fail on
80     // PocketPC when a timerId of 0 is used.  Bumping the timerId by 1 will avoid the   85     // PocketPC when a timerId of 0 is used.  Bumping the timerId by 1 will avoid the
81     // failure, but it is important that the 1 be subtracted from the id before being   86     // failure, but it is important that the 1 be subtracted from the id before being
82     // sent back to Java.  See _Timer_Proc to see the id being bumped down.   87     // sent back to Java.  See _Timer_Proc to see the id being bumped down.
83     int newTimer = SetTimer(ugl_display->creation_hWnd, timerId+1, milliseconds, _Timer_Proc);   88     int newTimer = SetTimer(ugl_display->creation_hWnd, timerId+1, milliseconds, _Timer_Proc);
84     if (newTimer == 0) {   89     if (newTimer == 0) {
85         Win32Error_SetError(uglError, GetLastError(), _T("Failed to create timer"));   90         Win32Error_SetError(uglError, GetLastError(), _T("Failed to create timer"));
86     }   91     }
87 }   92 }
88     93  
89 //========================================================================================   94 //========================================================================================
90     95  
91 UGL_Int Display_New(UGL_Error uglError) {   96 UGL_Int Display_New(UGL_Error uglError) {
92     PUGL_Device ugl_device;   97     PUGL_Device ugl_device;
93     PUGL_Display ugl_display = NULL;   98     PUGL_Display ugl_display = NULL;
94     99  
95     WNDCLASS staticClass;   100     WNDCLASS staticClass;
96     WNDCLASS wndClass;   101     WNDCLASS wndClass;
97     HWND creation_hWnd = NULL;   102     HWND creation_hWnd = NULL;
    -+ 103 #ifdef _WIN32_WCE
      104     TCHAR oemInfo[256];
      105 #endif // #ifdef _WIN32_WCE
98   = 106  
99     if (GetClassInfo(g_hInstance, _T("STATIC"), &staticClass) == FALSE) {   107     if (GetClassInfo(g_hInstance, _T("STATIC"), &staticClass) == FALSE) {
100         Win32Error_SetError(uglError, GetLastError(), _T("Unable get \"STATIC\" class data"));   108         Win32Error_SetError(uglError, GetLastError(), _T("Unable get \"STATIC\" class data"));
101         return 0;   109         return 0;
102     }   110     }
103     111  
104     memset(&wndClass, 0, sizeof(WNDCLASS));   112     memset(&wndClass, 0, sizeof(WNDCLASS));
105     113  
106     wndClass.hInstance          = g_hInstance;   114     wndClass.hInstance          = g_hInstance;
107     wndClass.lpfnWndProc        = (WNDPROC)DefWindowProc;   115     wndClass.lpfnWndProc        = (WNDPROC)DefWindowProc;
108 #ifdef _WIN32_WCE   116 #ifdef _WIN32_WCE
109     wndClass.style              = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;   117     wndClass.style              = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
110 #else   118 #else
111     wndClass.style              = CS_BYTEALIGNWINDOW | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;   119     wndClass.style              = CS_BYTEALIGNWINDOW | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
112 #endif   120 #endif
113     wndClass.hCursor            = staticClass.hCursor;   121     wndClass.hCursor            = staticClass.hCursor;
114     wndClass.lpszClassName      = WINDOW_CLASS_NAME;   122     wndClass.lpszClassName      = WINDOW_CLASS_NAME;
115     wndClass.hbrBackground      = staticClass.hbrBackground;   123     wndClass.hbrBackground      = staticClass.hbrBackground;
116     RegisterClass (&wndClass);   124     RegisterClass (&wndClass);
117     125  
118     126  
119     ugl_display = UGL_DISPLAY(calloc(sizeof(UGL_Display), 1));   127     ugl_display = UGL_DISPLAY(calloc(sizeof(UGL_Display), 1));
120     128  
121     ugl_device = UGL_DEVICE(ugl_display);   129     ugl_device = UGL_DEVICE(ugl_display);
122     ugl_device->device_dispose = _Dispose_Display;   130     ugl_device->device_dispose = _Dispose_Display;
123     131  
124     // message only window that will be called to create UI on the display thread   132     // message only window that will be called to create UI on the display thread
125     creation_hWnd = CreateWindowEx(0, WINDOW_CLASS_NAME, NULL, WS_OVERLAPPED, 0, 0, 0, 0, 0, NULL, g_hInstance, NULL);   133     creation_hWnd = CreateWindowEx(0, WINDOW_CLASS_NAME, NULL, WS_OVERLAPPED, 0, 0, 0, 0, 0, NULL, g_hInstance, NULL);
126     if (!creation_hWnd) {   134     if (!creation_hWnd) {
127         free(ugl_display);   135         free(ugl_display);
128         Win32Error_SetError(uglError, GetLastError(), _T("Unable to create message/creation window"));   136         Win32Error_SetError(uglError, GetLastError(), _T("Unable to create message/creation window"));
129         return NULL_HANDLE;   137         return NULL_HANDLE;
130     }   138     }
131     139  
132     SetWindowLong(creation_hWnd, GWL_WNDPROC, (LONG)creationProc);   140     SetWindowLong(creation_hWnd, GWL_WNDPROC, (LONG)creationProc);
133     SetWindowLong(creation_hWnd, GWL_USERDATA, (LONG)ugl_display);   141     SetWindowLong(creation_hWnd, GWL_USERDATA, (LONG)ugl_display);
134     142  
135     ugl_display->callback_lookup = NULL;   143     ugl_display->callback_lookup = NULL;
136     ugl_display->creation_hWnd = creation_hWnd;   144     ugl_display->creation_hWnd = creation_hWnd;
137     ugl_display->processID = GetCurrentProcessId();   145     ugl_display->processID = GetCurrentProcessId();
138     ugl_display->threadID = GetCurrentThreadId();   146     ugl_display->threadID = GetCurrentThreadId();
139     ugl_display->hInstance = g_hInstance;   147     ugl_display->hInstance = g_hInstance;
140     148  
141     ugl_display->menuItemsLength = 0;   149     ugl_display->menuItemsLength = 0;
142     ugl_display->menuItemCount = 0;   150     ugl_display->menuItemCount = 0;
143     ugl_display->menuItems = NULL;   151     ugl_display->menuItems = NULL;
    <> 152    
      153     ugl_display->isEmulator = FALSE;
      154  
      155 #ifdef _WIN32_WCE
      156     // now check to see if we are running on the emulator
      157     SystemParametersInfo(SPI_GETOEMINFO, 256, oemInfo, 0);
      158     if(_tcsicmp(oemInfo, L"Microsoft DeviceEmulator") == 0) {
      159         ugl_display->isEmulator = TRUE;
      160     }
      161 #endif // #ifdef _WIN32_WCE
144   = 162  
145     return (UGL_Int)ugl_display;   163     return (UGL_Int)ugl_display;
146 }   164 }
147 void _Display_AddMenu(PUGL_Display display, UGL_Int menuHandle, HMENU hMenu, UGL_Error uglError) {   165 void _Display_AddMenu(PUGL_Display display, UGL_Int menuHandle, HMENU hMenu, UGL_Error uglError) {
148     PMenuList menuList, endMenuList;   166     PMenuList menuList, endMenuList;
149     if (display->menus == NULL) {   167     if (display->menus == NULL) {
150         menuList =  (PMenuList)calloc(sizeof(MenuList), 1);   168         menuList =  (PMenuList)calloc(sizeof(MenuList), 1);
151         display->menus = menuList;   169         display->menus = menuList;
152     } else {   170     } else {
153         menuList = display->menus;   171         menuList = display->menus;
154         while (menuList != NULL) {   172         while (menuList != NULL) {
155             endMenuList = menuList;   173             endMenuList = menuList;
156             menuList = menuList->next;   174             menuList = menuList->next;
157         }   175         }
158         menuList = (PMenuList)calloc(sizeof(MenuList), 1);   176         menuList = (PMenuList)calloc(sizeof(MenuList), 1);
159         endMenuList->next = menuList;   177         endMenuList->next = menuList;
160     }   178     }
161     menuList->menuHandle = menuHandle;   179     menuList->menuHandle = menuHandle;
162     menuList->hMenu = hMenu;   180     menuList->hMenu = hMenu;
163 }   181 }
164 void _Display_RemoveMenu(PUGL_Display display, UGL_Int menuHandle, UGL_Error uglError) {   182 void _Display_RemoveMenu(PUGL_Display display, UGL_Int menuHandle, UGL_Error uglError) {
165     PMenuList menuList = display->menus;   183     PMenuList menuList = display->menus;
166     PMenuList prevMenu;   184     PMenuList prevMenu;
167     if (menuList->menuHandle == menuHandle) {   185     if (menuList->menuHandle == menuHandle) {
168         display->menus = menuList->next;   186         display->menus = menuList->next;
169     } else {   187     } else {
170         prevMenu = menuList;   188         prevMenu = menuList;
171         menuList = menuList->next;   189         menuList = menuList->next;
172         while (menuList != NULL) {   190         while (menuList != NULL) {
173             if (menuList->menuHandle == menuHandle) break;   191             if (menuList->menuHandle == menuHandle) break;
174             prevMenu = menuList;   192             prevMenu = menuList;
175             menuList = menuList->next;   193             menuList = menuList->next;
176         }   194         }
177         if (menuList == NULL) return;   195         if (menuList == NULL) return;
178         prevMenu->next = menuList->next;   196         prevMenu->next = menuList->next;
179     }   197     }
180     free(menuList);   198     free(menuList);
181 }   199 }
182 UGL_Int _Display_FindMenu(PUGL_Display display, HMENU hMenu) {   200 UGL_Int _Display_FindMenu(PUGL_Display display, HMENU hMenu) {
183     PMenuList menuList = display->menus;   201     PMenuList menuList = display->menus;
184     while (menuList != NULL) {   202     while (menuList != NULL) {
185         if (menuList->hMenu == hMenu) return menuList->menuHandle;   203         if (menuList->hMenu == hMenu) return menuList->menuHandle;
186         menuList = menuList->next;   204         menuList = menuList->next;
187     }   205     }
188     return 0;   206     return 0;
189 }   207 }
190 PUGL_Shell _Display_FindClosestShell(HWND child) {   208 PUGL_Shell _Display_FindClosestShell(HWND child) {
191     while (child != NULL) {   209     while (child != NULL) {
192         LONG style = GetWindowLong(child, GWL_STYLE);   210         LONG style = GetWindowLong(child, GWL_STYLE);
193         if ((style & WS_CHILD) != WS_CHILD) {   211         if ((style & WS_CHILD) != WS_CHILD) {
194             PUGL_Shell shell = (PUGL_Shell)GetWindowLong(child, GWL_USERDATA);   212             PUGL_Shell shell = (PUGL_Shell)GetWindowLong(child, GWL_USERDATA);
195             return shell;   213             return shell;
196         }   214         }
197         child = GetParent(child);   215         child = GetParent(child);
198     }   216     }
199     return NULL;   217     return NULL;
200 }   218 }
201 int _Display_GetComCtrlMajorVersion(PUGL_Display display, UGL_Error uglError) {   219 int _Display_GetComCtrlMajorVersion(PUGL_Display display, UGL_Error uglError) {
202     HINSTANCE library;   220     HINSTANCE library;
203     DLLVERSIONINFO dvi;   221     DLLVERSIONINFO dvi;
204     222  
205     if (display->comCtrl32Major != 0) return display->comCtrl32Major;   223     if (display->comCtrl32Major != 0) return display->comCtrl32Major;
206     library = LoadLibrary(_T("comctl32.dll"));   224     library = LoadLibrary(_T("comctl32.dll"));
207     if (library == NULL) {   225     if (library == NULL) {
208         Win32Error_SetError(uglError, UGL_ERROR_OTHER, _T("Failed to load comctl32.dll"));   226         Win32Error_SetError(uglError, UGL_ERROR_OTHER, _T("Failed to load comctl32.dll"));
209         return 0;   227         return 0;
210     } else {   228     } else {
211         DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(library, "DllGetVersion");   229         DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(library, "DllGetVersion");
212         if (pDllGetVersion != NULL) {   230         if (pDllGetVersion != NULL) {
213             HRESULT result;   231             HRESULT result;
214             dvi.cbSize = sizeof(dvi);   232             dvi.cbSize = sizeof(dvi);
215             result = pDllGetVersion(&dvi);   233             result = pDllGetVersion(&dvi);
216             if(result == S_OK) {   234             if(result == S_OK) {
217                 display->comCtrl32Major = dvi.dwMajorVersion;   235                 display->comCtrl32Major = dvi.dwMajorVersion;
218                 display->comCtrl32Minor = dvi.dwMinorVersion;   236                 display->comCtrl32Minor = dvi.dwMinorVersion;
219                 FreeLibrary(library);   237                 FreeLibrary(library);
220                 return dvi.dwMajorVersion;   238                 return dvi.dwMajorVersion;
221             }   239             }
222         }   240         }
223         Win32Error_SetError(uglError, GetLastError(), _T("Unable to get comctrl version"));   241         Win32Error_SetError(uglError, GetLastError(), _T("Unable to get comctrl version"));
224         FreeLibrary(library);   242         FreeLibrary(library);
225     }   243     }
226     return 0;   244     return 0;
227 }   245 }
228     246  
229 BOOL _Display_FilterMessage(PUGL_Display display, LPMSG msg) {   247 BOOL _Display_FilterMessage(PUGL_Display display, LPMSG msg) {
230     /*   248     /*
231      * Although the MSDN documentation for TranslateAccelerator says that   249      * Although the MSDN documentation for TranslateAccelerator says that
232      * only WM_KEYDOWN/KEYUP/SYSKEYDOWN/SYSKEYUP messages are translated,   250      * only WM_KEYDOWN/KEYUP/SYSKEYDOWN/SYSKEYUP messages are translated,
233      * accelerators were not dispatched correctly unless ALL key messages were   251      * accelerators were not dispatched correctly unless ALL key messages were
234      * handled   252      * handled
235      */   253      */
236     if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST)) {   254     if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST)) {
237         PUGL_Shell shell = _Display_FindClosestShell(msg->hwnd);   255         PUGL_Shell shell = _Display_FindClosestShell(msg->hwnd);
238         if (shell != NULL) {   256         if (shell != NULL) {
239             HACCEL table = _Shell_GetAcceleratorTable(shell);   257             HACCEL table = _Shell_GetAcceleratorTable(shell);
240             if (table != 0) {   258             if (table != 0) {
241                 if (TranslateAccelerator(shell->scrollable.control.hWnd, table, msg) != 0) {   259                 if (TranslateAccelerator(shell->scrollable.control.hWnd, table, msg) != 0) {
242                     return TRUE;   260                     return TRUE;
243                 }   261                 }
244             }   262             }
245         }   263         }
246     }   264     }
247     return FALSE;   265     return FALSE;
248 }   266 }
249     267  
250 //========================================================================================   268 //========================================================================================
251     269  
252 UGL_Boolean Display_ReadAndDispatch(UGL_Int handle, UGL_Error uglError) {   270 UGL_Boolean Display_ReadAndDispatch(UGL_Int handle, UGL_Error uglError) {
253     PUGL_Display display = UGL_DISPLAY(handle);   271     PUGL_Display display = UGL_DISPLAY(handle);
254     MSG msg;   272     MSG msg;
255     273  
256     if (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) {   274     if (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) {
257         if (_Display_FilterMessage(display, &msg) == TRUE) return TRUE;   275         if (_Display_FilterMessage(display, &msg) == TRUE) return TRUE;
    <> 276  
      277 #ifdef _WIN32_WCE
      278         if (display->isEmulator) {
      279             // please see http://msdn.microsoft.com/en-us/library/aa912145.aspx
      280             // for information on this code:
      281             // "Although the IMM sets the virtual key value to VK_PROCESSKEY when
      282             // the IME processes a given virtual key, an application can recover
      283             // the original virtual key value with the ImmGetVirtualKey function.
      284             // This function is only used for key input messages containing the
      285             // VK_PROCESSKEY value. Applications can only get the original virtual
      286             // key by using this function after receiving the WM_KEYDOWN (VK_PROCESSKEY)
      287             // message, and before TranslateMessage is called in its own message loop."
      288             //
      289             // For some reason the emulator gets screwed up and stops properly sending virtual
      290             // keys. For instance, if you type in 0000 and then hit TAB, the keycode comes in
      291             // as VK_PROCESSKEY for WM_KeyDown but there is never a corresponding KeyDown
      292             // or KeyChar for the actual TAB character. This hack tries and fixes it.
      293             if (msg.message == WM_KEYDOWN || msg.message == WM_KEYUP)
      294             {
      295                 if (msg.wParam == VK_PROCESSKEY)
      296                 {
      297                     msg.wParam = ImmGetVirtualKey(msg.hwnd);
      298                 }
      299             }
      300         }
      301 #endif
      302  
258         TranslateMessage (&msg);   303         TranslateMessage (&msg);
259         DispatchMessage (&msg); = 304         DispatchMessage (&msg);
260         return TRUE;   305         return TRUE;
261     }   306     }
262     return FALSE;   307     return FALSE;
263 }   308 }
264 //========================================================================================   309 //========================================================================================
265     310  
266 void Display_Sleep(UGL_Int handle, UGL_Error uglError) {   311 void Display_Sleep(UGL_Int handle, UGL_Error uglError) {
267 #ifdef _WIN32_WCE   312 #ifdef _WIN32_WCE
268     MsgWaitForMultipleObjectsEx (0, 0, INFINITE, QS_ALLINPUT, MWMO_INPUTAVAILABLE);   313     MsgWaitForMultipleObjectsEx (0, 0, INFINITE, QS_ALLINPUT, MWMO_INPUTAVAILABLE);
269 #else   314 #else
270     MSG msg;   315     MSG msg;
271     316  
272     // According to MSDN, WaitMessage will not return immediately if   317     // According to MSDN, WaitMessage will not return immediately if
273     // there is a message already on the queue.  In PersonalProfile that is not a   318     // there is a message already on the queue.  In PersonalProfile that is not a
274     // problem because the event loop is not controled by the user, but in eSWT   319     // problem because the event loop is not controled by the user, but in eSWT
275     // it is possible to write an incorrect event loop.   320     // it is possible to write an incorrect event loop.
276     //   321     //
277     // If event loop sleeps after every event is read and dispatched then some   322     // If event loop sleeps after every event is read and dispatched then some
278     // events can be queued up and only processed after a new event comes in.    323     // events can be queued up and only processed after a new event comes in. 
279     //   324     //
280     // Checking for a pre-existing message will fix this problem   325     // Checking for a pre-existing message will fix this problem
281     if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) != 0) return;   326     if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) != 0) return;
282     WaitMessage();   327     WaitMessage();
283 #endif   328 #endif
284 }   329 }
285 //========================================================================================   330 //========================================================================================
286     331  
287 void Display_Wake(UGL_Int handle, UGL_Error uglError) {   332 void Display_Wake(UGL_Int handle, UGL_Error uglError) {
288     PUGL_Display ugl_display = UGL_DISPLAY(handle);   333     PUGL_Display ugl_display = UGL_DISPLAY(handle);
289 #ifdef _WIN32_WCE   334 #ifdef _WIN32_WCE
290     PostMessage (ugl_display->creation_hWnd, WM_NULL, 0, 0);   335     PostMessage (ugl_display->creation_hWnd, WM_NULL, 0, 0);
291 #else   336 #else
292     PostThreadMessage(ugl_display->threadID, WM_NULL, 0, 0);   337     PostThreadMessage(ugl_display->threadID, WM_NULL, 0, 0);
293 #endif   338 #endif
294 }   339 }
295 //========================================================================================   340 //========================================================================================
296     341  
297 UGL_Boolean Display_PostKeyEvent(UGL_Int handle, UGL_Int keyEventType, UGL_Int keyCode, UGL_Char character, UGL_Error uglError) {   342 UGL_Boolean Display_PostKeyEvent(UGL_Int handle, UGL_Int keyEventType, UGL_Int keyCode, UGL_Char character, UGL_Error uglError) {
298     343  
299     /*   344     /*
300      * This function doesn't work quite like one would imagine. For example, if I send a   345      * This function doesn't work quite like one would imagine. For example, if I send a
301      * shift down event followed by a key down event with the 's' key, I don't get the 'S'   346      * shift down event followed by a key down event with the 's' key, I don't get the 'S'
302      * char in the generated event, but another unrecognized character. This is the exact same   347      * char in the generated event, but another unrecognized character. This is the exact same
303      * behavior as SWT though.   348      * behavior as SWT though.
304      * Also note that whether the upper- or lower-case keycode for a character is passed,   349      * Also note that whether the upper- or lower-case keycode for a character is passed,
305      * the keybd_event() function will only take the keycode of the upper-case character, and   350      * the keybd_event() function will only take the keycode of the upper-case character, and
306      * the generated event will always have the keycode of the lower-case character.   351      * the generated event will always have the keycode of the lower-case character.
307      */   352      */
308       353    
309     if (keyCode > 96 && keyCode < 123) keyCode = keyCode - 32;   354     if (keyCode > 96 && keyCode < 123) keyCode = keyCode - 32;
310       355    
311     else {   356     else {
312         keyCode = KeyUtils_ConvertToNativeKeycode(keyCode);   357         keyCode = KeyUtils_ConvertToNativeKeycode(keyCode);
313     }   358     }
314     359  
315     if (keyEventType == UGL_EVENT_KEY_DOWN) {   360     if (keyEventType == UGL_EVENT_KEY_DOWN) {
316         keybd_event( keyCode, 0, KEYEVENTF_EXTENDEDKEY | 0, 0 );   361         keybd_event( keyCode, 0, KEYEVENTF_EXTENDEDKEY | 0, 0 );
317     }   362     }
318     else {   363     else {
319         keybd_event( keyCode, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0 );   364         keybd_event( keyCode, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0 );
320     }   365     }
321       366    
322     return TRUE;   367     return TRUE;
323     368  
324     369  
325 }   370 }
326 //========================================================================================   371 //========================================================================================
327     372  
328 LRESULT CALLBACK creationProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {   373 LRESULT CALLBACK creationProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
329     if (message >= WM_USER) {   374     if (message >= WM_USER) {
330     375  
331         switch (message) {   376         switch (message) {
332             case UI_NOTIFY_TRAY: {   377             case UI_NOTIFY_TRAY: {
333                 if(lParam == WM_LBUTTONUP) {   378                 if(lParam == WM_LBUTTONUP) {
334                     PUGL_Display ugl_display = UGL_DISPLAY(GetWindowLong(hWnd, GWL_USERDATA));   379                     PUGL_Display ugl_display = UGL_DISPLAY(GetWindowLong(hWnd, GWL_USERDATA));
335                     PUGL_TrayItem ugl_trayitem = Tray_GetTrayItem(ugl_display, (UINT)wParam);   380                     PUGL_TrayItem ugl_trayitem = Tray_GetTrayItem(ugl_display, (UINT)wParam);
336 #ifndef _WIN32_WCE   381 #ifndef _WIN32_WCE
337                     POINT point;   382                     POINT point;
338                     GetCursorPos(&point);   383                     GetCursorPos(&point);
339                     TrayItemCallback(UGL_WIDGET(ugl_trayitem)->callback_target, TRAYITEM_SELECTION, point.x, point.y);   384                     TrayItemCallback(UGL_WIDGET(ugl_trayitem)->callback_target, TRAYITEM_SELECTION, point.x, point.y);
340 #else   385 #else
341                     TrayItemCallback(UGL_WIDGET(ugl_trayitem)->callback_target, TRAYITEM_SELECTION, 0, 0);   386                     TrayItemCallback(UGL_WIDGET(ugl_trayitem)->callback_target, TRAYITEM_SELECTION, 0, 0);
342 #endif   387 #endif
343                 } else if(lParam == WM_LBUTTONDBLCLK) {   388                 } else if(lParam == WM_LBUTTONDBLCLK) {
344                     PUGL_Display ugl_display = UGL_DISPLAY(GetWindowLong(hWnd, GWL_USERDATA));   389                     PUGL_Display ugl_display = UGL_DISPLAY(GetWindowLong(hWnd, GWL_USERDATA));
345                     PUGL_TrayItem ugl_trayitem = Tray_GetTrayItem(ugl_display, (UINT)wParam);   390                     PUGL_TrayItem ugl_trayitem = Tray_GetTrayItem(ugl_display, (UINT)wParam);
346 #ifndef _WIN32_WCE   391 #ifndef _WIN32_WCE
347                     POINT point;   392                     POINT point;
348                     GetCursorPos(&point);   393                     GetCursorPos(&point);
349                     TrayItemCallback(UGL_WIDGET(ugl_trayitem)->callback_target, TRAYITEM_DEFAULT_SELECTION, point.x, point.y);   394                     TrayItemCallback(UGL_WIDGET(ugl_trayitem)->callback_target, TRAYITEM_DEFAULT_SELECTION, point.x, point.y);
350 #else   395 #else
351                     TrayItemCallback(UGL_WIDGET(ugl_trayitem)->callback_target, TRAYITEM_DEFAULT_SELECTION, 0, 0);   396                     TrayItemCallback(UGL_WIDGET(ugl_trayitem)->callback_target, TRAYITEM_DEFAULT_SELECTION, 0, 0);
352 #endif   397 #endif
353 #ifndef _WIN32_WCE   398 #ifndef _WIN32_WCE
354                 } else if(lParam == WM_RBUTTONUP) {   399                 } else if(lParam == WM_RBUTTONUP) {
355                     PUGL_Display ugl_display = UGL_DISPLAY(GetWindowLong(hWnd, GWL_USERDATA));   400                     PUGL_Display ugl_display = UGL_DISPLAY(GetWindowLong(hWnd, GWL_USERDATA));
356                     PUGL_TrayItem ugl_trayitem = Tray_GetTrayItem(ugl_display, (UINT)wParam);   401                     PUGL_TrayItem ugl_trayitem = Tray_GetTrayItem(ugl_display, (UINT)wParam);
357                     POINT point;   402                     POINT point;
358                     GetCursorPos(&point);   403                     GetCursorPos(&point);
359                     TrayItemCallback(UGL_WIDGET(ugl_trayitem)->callback_target, TRAYITEM_MENU_DETECT, point.x, point.y);   404                     TrayItemCallback(UGL_WIDGET(ugl_trayitem)->callback_target, TRAYITEM_MENU_DETECT, point.x, point.y);
360 #endif   405 #endif
361                 }   406                 }
362             } break;   407             } break;
363             case UI_CREATE_MENUBAR: {   408             case UI_CREATE_MENUBAR: {
364                 UGL_Error* error = (UGL_Error*)lParam;   409                 UGL_Error* error = (UGL_Error*)lParam;
365                 return (LRESULT)_MenuBar_New((PUGL_Control)wParam, *error);   410                 return (LRESULT)_MenuBar_New((PUGL_Control)wParam, *error);
366             }   411             }
367             case UI_CREATE_POPUP: {   412             case UI_CREATE_POPUP: {
368                 UGL_Error* error = (UGL_Error*)lParam;   413                 UGL_Error* error = (UGL_Error*)lParam;
369                 return  _PopupMenu_New(wParam, *error);   414                 return  _PopupMenu_New(wParam, *error);
370             }   415             }
371     416  
372             case UI_DESTROY_WINDOW: {   417             case UI_DESTROY_WINDOW: {
373                 return DestroyWindow((HWND)wParam);   418                 return DestroyWindow((HWND)wParam);
374             }   419             }
375     // ----------------------------------------------------   420     // ----------------------------------------------------
376             // we only have two possible messages defined. Create either a shell, or create   421             // we only have two possible messages defined. Create either a shell, or create
377             // a control.   422             // a control.
378             case UI_CREATE_SHELL: {   423             case UI_CREATE_SHELL: {
379                 PUGL_Display ugl_display = UGL_DISPLAY(GetWindowLong(hWnd, GWL_USERDATA));   424                 PUGL_Display ugl_display = UGL_DISPLAY(GetWindowLong(hWnd, GWL_USERDATA));
380                 UGL_Int *args = (UGL_Int *)lParam;   425                 UGL_Int *args = (UGL_Int *)lParam;
381                 UGL_Int parent_handle = args[0];   426                 UGL_Int parent_handle = args[0];
382                 UGL_Error uglError = (UGL_Error)args[1];   427                 UGL_Error uglError = (UGL_Error)args[1];
383                 UGL_Int ugl_style = (UGL_Int)wParam;   428                 UGL_Int ugl_style = (UGL_Int)wParam;
384                   429                
385                 UGL_Int shell_handle = 0;   430                 UGL_Int shell_handle = 0;
386                 if (parent_handle == 0) shell_handle = Shell_New((UGL_Int)ugl_display, ugl_style, uglError);   431                 if (parent_handle == 0) shell_handle = Shell_New((UGL_Int)ugl_display, ugl_style, uglError);
387                 else shell_handle = Shell_NewChild(parent_handle, ugl_style, uglError);   432                 else shell_handle = Shell_NewChild(parent_handle, ugl_style, uglError);
388     433  
389 #ifdef _WIN32_WCE   434 #ifdef _WIN32_WCE
390                 return (LRESULT)shell_handle;   435                 return (LRESULT)shell_handle;
391 #else   436 #else
392                 ReplyMessage(shell_handle);   437                 ReplyMessage(shell_handle);
393 #endif   438 #endif
394     439  
395                           } break;   440                           } break;
396     441  
397             // create a control   442             // create a control
398             case UI_CREATE_CONTROL: {   443             case UI_CREATE_CONTROL: {
399                 UGL_Int *args = (UGL_Int *)lParam;   444                 UGL_Int *args = (UGL_Int *)lParam;
400                 UGL_Int parentHandle = (UGL_Int)wParam;   445                 UGL_Int parentHandle = (UGL_Int)wParam;
401                 UGL_String control_class = (UGL_String)args[0];   446                 UGL_String control_class = (UGL_String)args[0];
402                 UGL_Int struct_size = args[1];   447                 UGL_Int struct_size = args[1];
403                 WNDPROC Control_Proc = (WNDPROC)args[2];   448                 WNDPROC Control_Proc = (WNDPROC)args[2];
404                 UGL_Int ugl_style = args[3];   449                 UGL_Int ugl_style = args[3];
405                 UGL_Int style = args[4];   450                 UGL_Int style = args[4];
406                 UGL_Int extended_style = args[5];   451                 UGL_Int extended_style = args[5];
407                 UGL_Error uglError = (UGL_Error)args[6];   452                 UGL_Error uglError = (UGL_Error)args[6];
408     453  
409                 PUGL_Control ugl_handle = _Control_New(control_class, struct_size, Control_Proc, parentHandle, ugl_style, style, extended_style, uglError);   454                 PUGL_Control ugl_handle = _Control_New(control_class, struct_size, Control_Proc, parentHandle, ugl_style, style, extended_style, uglError);
410 #ifdef _WIN32_WCE   455 #ifdef _WIN32_WCE
411                 return (LRESULT)ugl_handle;   456                 return (LRESULT)ugl_handle;
412 #else   457 #else
413                 ReplyMessage((LRESULT)ugl_handle);   458                 ReplyMessage((LRESULT)ugl_handle);
414 #endif   459 #endif
415             } break;   460             } break;
416     461  
417             case UI_SETCALLBACKTARGET: {   462             case UI_SETCALLBACKTARGET: {
418                 // Please see Widget_SetCallbackTarget for   463                 // Please see Widget_SetCallbackTarget for
419                 // a detailed description of why this   464                 // a detailed description of why this
420                 // must be done in the display thread   465                 // must be done in the display thread
421                 PUGL_Widget widget = UGL_WIDGET(wParam);   466                 PUGL_Widget widget = UGL_WIDGET(wParam);
422                 CallbackTarget* newTarget = (CallbackTarget*)lParam;   467                 CallbackTarget* newTarget = (CallbackTarget*)lParam;
423                 CallbackTarget* old_target = widget->callback_target;   468                 CallbackTarget* old_target = widget->callback_target;
424                 widget->callback_target = newTarget;   469                 widget->callback_target = newTarget;
425                 return (LRESULT)old_target;   470                 return (LRESULT)old_target;
426             }   471             }
427     472  
428         }   473         }
429         return 1;   474         return 1;
430     } else {   475     } else {
431         return DefWindowProc(hWnd, message, wParam, lParam);   476         return DefWindowProc(hWnd, message, wParam, lParam);
432     }   477     }
433 }   478 }
434 //========================================================================================   479 //========================================================================================
435     480  
436 UGL_Boolean Display_PostPointerEvent(UGL_Int handle, UGL_Int type, UGL_Int button, UGL_Error uglError) {   481 UGL_Boolean Display_PostPointerEvent(UGL_Int handle, UGL_Int type, UGL_Int button, UGL_Error uglError) {
437     INPUT inputs;   482     INPUT inputs;
438     UINT result;   483     UINT result;
439     ZeroMemory(&inputs, sizeof(INPUT));   484     ZeroMemory(&inputs, sizeof(INPUT));
440     inputs.type = INPUT_MOUSE;   485     inputs.type = INPUT_MOUSE;
441       486    
442     switch (button) {   487     switch (button) {
443         case UGL_POINTER_MASK_BUTTON1: {   488         case UGL_POINTER_MASK_BUTTON1: {
444             if (type == UGL_EVENT_POINTER_DOWN) inputs.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;   489             if (type == UGL_EVENT_POINTER_DOWN) inputs.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
445             else inputs.mi.dwFlags = MOUSEEVENTF_LEFTUP;   490             else inputs.mi.dwFlags = MOUSEEVENTF_LEFTUP;
446         } break;   491         } break;
447         case UGL_POINTER_MASK_BUTTON2: {   492         case UGL_POINTER_MASK_BUTTON2: {
448             if (type == UGL_EVENT_POINTER_DOWN) inputs.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;   493             if (type == UGL_EVENT_POINTER_DOWN) inputs.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
449             else inputs.mi.dwFlags = MOUSEEVENTF_MIDDLEUP;   494             else inputs.mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
450         } break;   495         } break;
451         case UGL_POINTER_MASK_BUTTON3: {   496         case UGL_POINTER_MASK_BUTTON3: {
452             if (type == UGL_EVENT_POINTER_DOWN) inputs.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;   497             if (type == UGL_EVENT_POINTER_DOWN) inputs.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
453             else inputs.mi.dwFlags = MOUSEEVENTF_RIGHTUP;   498             else inputs.mi.dwFlags = MOUSEEVENTF_RIGHTUP;
454         } break;   499         } break;
455         default: return FALSE;   500         default: return FALSE;
456     }   501     }
457     result = SendInput(1, &inputs, sizeof(INPUT));   502     result = SendInput(1, &inputs, sizeof(INPUT));
458     return result != 0;   503     return result != 0;
459 }   504 }
460 //========================================================================================   505 //========================================================================================
461     506  
462 UGL_Boolean Display_PostPointerMoveEvent(UGL_Int handle, UGL_Int x, UGL_Int y, UGL_Error uglError) {   507 UGL_Boolean Display_PostPointerMoveEvent(UGL_Int handle, UGL_Int x, UGL_Int y, UGL_Error uglError) {
463     INPUT inputs;   508     INPUT inputs;
464     UINT result;   509     UINT result;
465     int screenWidth = GetSystemMetrics(SM_CXSCREEN) - 1;   510     int screenWidth = GetSystemMetrics(SM_CXSCREEN) - 1;
466     int screenHeight = GetSystemMetrics(SM_CYSCREEN) - 1;   511     int screenHeight = GetSystemMetrics(SM_CYSCREEN) - 1;
467     512  
468     ZeroMemory(&inputs, sizeof(INPUT));   513     ZeroMemory(&inputs, sizeof(INPUT));
469     inputs.type = INPUT_MOUSE;   514     inputs.type = INPUT_MOUSE;
470     inputs.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;   515     inputs.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
471     inputs.mi.dx = (x * 65535) / screenWidth;   516     inputs.mi.dx = (x * 65535) / screenWidth;
472     inputs.mi.dy = (y * 65535) / screenHeight;   517     inputs.mi.dy = (y * 65535) / screenHeight;
473     518  
474     result = SendInput(1, &inputs, sizeof(INPUT));   519     result = SendInput(1, &inputs, sizeof(INPUT));
475     return result != 0;   520     return result != 0;
476 }   521 }
477     522  
478     523  
479 //========================================================================================   524 //========================================================================================
480 void Display_Beep(UGL_Int handle, UGL_Error uglError) {   525 void Display_Beep(UGL_Int handle, UGL_Error uglError) {
481     MessageBeep(MB_OK);   526     MessageBeep(MB_OK);
482 }   527 }
483     528  
484 //========================================================================================   529 //========================================================================================
485     530  
486 UGL_Int Display_GetSystemColor(UGL_Int handle, UGL_Int id, UGL_Error uglError) {   531 UGL_Int Display_GetSystemColor(UGL_Int handle, UGL_Int id, UGL_Error uglError) {
487     int pixel = 0x02000000;   532     int pixel = 0x02000000;
488     UGL_Int ugl_color = 0;   533     UGL_Int ugl_color = 0;
489     534  
490     switch (id) {     535     switch (id) {  
491         case UGL_COLOR_CONTROL_SHADOW_DARK:         pixel = GetSysColor (COLOR_3DDKSHADOW); break;        536         case UGL_COLOR_CONTROL_SHADOW_DARK:         pixel = GetSysColor (COLOR_3DDKSHADOW); break;     
492         case UGL_COLOR_CONTROL_SHADOW_NORMAL:       pixel = GetSysColor(COLOR_3DSHADOW);    break;   537         case UGL_COLOR_CONTROL_SHADOW_NORMAL:       pixel = GetSysColor(COLOR_3DSHADOW);    break;
493         case UGL_COLOR_CONTROL_HIGHLIGHT_NORMAL:    pixel = GetSysColor(COLOR_3DLIGHT);     break;   538         case UGL_COLOR_CONTROL_HIGHLIGHT_NORMAL:    pixel = GetSysColor(COLOR_3DLIGHT);     break;
494         case UGL_COLOR_CONTROL_BACKGROUND:          pixel = GetSysColor(COLOR_3DFACE);      break;   539         case UGL_COLOR_CONTROL_BACKGROUND:          pixel = GetSysColor(COLOR_3DFACE);      break;
495         case UGL_COLOR_CONTROL_FOREGROUND:          pixel = GetSysColor(COLOR_WINDOWTEXT);  break;   540         case UGL_COLOR_CONTROL_FOREGROUND:          pixel = GetSysColor(COLOR_WINDOWTEXT);  break;
496     541  
497     542  
498         case UGL_COLOR_TEXT_HIGHLIGHT_BACKGROUND:   pixel = GetSysColor(COLOR_HIGHLIGHT);   break;   543         case UGL_COLOR_TEXT_HIGHLIGHT_BACKGROUND:   pixel = GetSysColor(COLOR_HIGHLIGHT);   break;
499         case UGL_COLOR_TEXT_HIGHLIGHT_FOREGROUND:   pixel = GetSysColor(COLOR_HIGHLIGHTTEXT); break;   544         case UGL_COLOR_TEXT_HIGHLIGHT_FOREGROUND:   pixel = GetSysColor(COLOR_HIGHLIGHTTEXT); break;
500     545  
501         case UGL_COLOR_TITLE_BACKGROUND:            pixel = GetSysColor(COLOR_ACTIVECAPTION); break;   546         case UGL_COLOR_TITLE_BACKGROUND:            pixel = GetSysColor(COLOR_ACTIVECAPTION); break;
502         case UGL_COLOR_TITLE_FOREGROUND:            pixel = GetSysColor(COLOR_CAPTIONTEXT); break;   547         case UGL_COLOR_TITLE_FOREGROUND:            pixel = GetSysColor(COLOR_CAPTIONTEXT); break;
503     548  
504         case UGL_COLOR_INFO_FOREGROUND:             pixel = GetSysColor(COLOR_INFOTEXT);    break;   549         case UGL_COLOR_INFO_FOREGROUND:             pixel = GetSysColor(COLOR_INFOTEXT);    break;
505         case UGL_COLOR_INFO_BACKGROUND:             pixel = GetSysColor(COLOR_INFOBK);      break;   550         case UGL_COLOR_INFO_BACKGROUND:             pixel = GetSysColor(COLOR_INFOBK);      break;
506     551  
507         case UGL_COLOR_INACTIVE_CAPTION_FOREGROUND:     pixel = GetSysColor(COLOR_INACTIVECAPTIONTEXT); break;   552         case UGL_COLOR_INACTIVE_CAPTION_FOREGROUND:     pixel = GetSysColor(COLOR_INACTIVECAPTIONTEXT); break;
508         case UGL_COLOR_INACTIVE_CAPTION_BACKGROUND:     pixel = GetSysColor(COLOR_INACTIVECAPTION);     break;   553         case UGL_COLOR_INACTIVE_CAPTION_BACKGROUND:     pixel = GetSysColor(COLOR_INACTIVECAPTION);     break;
509         default: {   554         default: {
510             Win32Error_SetError(uglError, UGL_ERROR_OTHER, _T("Unrecognized color ID"));   555             Win32Error_SetError(uglError, UGL_ERROR_OTHER, _T("Unrecognized color ID"));
511             return NULL_HANDLE;   556             return NULL_HANDLE;
512                  } break;   557                  } break;
513               558            
514     }   559     }
515     560  
516     ugl_color = Color_New(handle, GetRValue(pixel), GetGValue(pixel), GetBValue(pixel), uglError);   561     ugl_color = Color_New(handle, GetRValue(pixel), GetGValue(pixel), GetBValue(pixel), uglError);
517     return ugl_color;   562     return ugl_color;
518 }   563 }
519     564  
520 //========================================================================================   565 //========================================================================================
521     566  
522 /**   567 /**
523 * Adds a control to the list of controls.   568 * Adds a control to the list of controls.
524 */   569 */
525 BOOL ControlList_AddControl(PControlList* list, struct UGL_Control* control) {   570 BOOL ControlList_AddControl(PControlList* list, struct UGL_Control* control) {
526     // It is important that new controls be added to the front of the list so that   571     // It is important that new controls be added to the front of the list so that
527     // the topmost control is always in the front of the list.    572     // the topmost control is always in the front of the list. 
528     PControlList element;   573     PControlList element;
529     for (element = *list; element != NULL; element = element->next) {   574     for (element = *list; element != NULL; element = element->next) {
530         // It is possible that the control is already in the list and it   575         // It is possible that the control is already in the list and it
531         // should not be added twice   576         // should not be added twice
532         if (element->control == control) return TRUE;   577         if (element->control == control) return TRUE;
533     }   578     }
534     579  
535     element = (PControlList)calloc(sizeof(ControlList), 1);   580     element = (PControlList)calloc(sizeof(ControlList), 1);
536     if (element == NULL) return FALSE;   581     if (element == NULL) return FALSE;
537     element->control = control;   582     element->control = control;
538     element->next = *list;   583     element->next = *list;
539     584  
540     *list = element;   585     *list = element;
541     return TRUE;   586     return TRUE;
542 }   587 }
543     588  
544 BOOL ControlList_RemoveControl(PControlList* list, struct UGL_Control* control) {   589 BOOL ControlList_RemoveControl(PControlList* list, struct UGL_Control* control) {
545     if (*list == NULL) {   590     if (*list == NULL) {
546         return FALSE;  // The control is not in the empty list   591         return FALSE;  // The control is not in the empty list
547     }   592     }
548     593  
549     if ((*list)->control == control) {   594     if ((*list)->control == control) {
550         PControlList nextList = (*list)->next;   595         PControlList nextList = (*list)->next;
551         free(*list);   596         free(*list);
552         *list = nextList;   597         *list = nextList;
553         return TRUE;   598         return TRUE;
554     } else {   599     } else {
555         return ControlList_RemoveControl(&((*list)->next), control);   600         return ControlList_RemoveControl(&((*list)->next), control);
556     }   601     }
557 }   602 }
558     603  
559 BOOL IsChildOfShell(struct UGL_Control* shell, struct UGL_Control* child) {   604 BOOL IsChildOfShell(struct UGL_Control* shell, struct UGL_Control* child) {
560     // If there is a modal dialog currently displayed then   605     // If there is a modal dialog currently displayed then
561     // we need to ignore all mouse events on windows that are   606     // we need to ignore all mouse events on windows that are
562     // not owned by that dialog   607     // not owned by that dialog
563     struct UGL_Control* test = child;   608     struct UGL_Control* test = child;
564     609  
565     // In PPro it is possible for a modal dialog to open other   610     // In PPro it is possible for a modal dialog to open other
566     // windows which should still be usable.  The solution it to   611     // windows which should still be usable.  The solution it to
567     // walk the whole list of shells until the top-most shell checking   612     // walk the whole list of shells until the top-most shell checking
568     // if any are the modal dialog   613     // if any are the modal dialog
569     while (test != shell) {   614     while (test != shell) {
570         if (test == NULL) return FALSE; // None of the parents were the modal dialog   615         if (test == NULL) return FALSE; // None of the parents were the modal dialog
571         test = test->parent;   616         test = test->parent;
572     };   617     };
573     618  
574     return TRUE;   619     return TRUE;
575 }   620 }
576     621  
577 /**   622 /**
578 * Run through the list of shell's that want to be enable and adjust their   623 * Run through the list of shell's that want to be enable and adjust their
579 * enabled status based on the current modal dialog.   624 * enabled status based on the current modal dialog.
580 */   625 */
581 void UpdateEnabledShells(PUGL_Display display) {   626 void UpdateEnabledShells(PUGL_Display display) {
582     struct UGL_Control* topmostModalShell = display->modalShells == NULL ? NULL : display->modalShells->control;   627     struct UGL_Control* topmostModalShell = display->modalShells == NULL ? NULL : display->modalShells->control;
583       628    
584     PControlList element;   629     PControlList element;
585     for (element = display->enabledShells; element != NULL; element = element->next) {   630     for (element = display->enabledShells; element != NULL; element = element->next) {
586         BOOL enabled;   631         BOOL enabled;
587         struct UGL_Control* shell = element->control;   632         struct UGL_Control* shell = element->control;
588     633  
589         // Shells that are children of the modal shell do not need to be   634         // Shells that are children of the modal shell do not need to be
590         // disabled when the modal shell is shown.   635         // disabled when the modal shell is shown.
591         if ((topmostModalShell == NULL) || IsChildOfShell(topmostModalShell, shell)) {   636         if ((topmostModalShell == NULL) || IsChildOfShell(topmostModalShell, shell)) {
592             enabled = TRUE;   637             enabled = TRUE;
593         } else {   638         } else {
594             enabled = FALSE;   639             enabled = FALSE;
595         }   640         }
596     641  
597         // It is important that we don't call Control_SetEnabled() to do the work because   642         // It is important that we don't call Control_SetEnabled() to do the work because
598         // that will result in the shell being removed from the list of shells that would   643         // that will result in the shell being removed from the list of shells that would
599         // prefer to be enabled   644         // prefer to be enabled
600         EnableWindow(shell->hWnd, enabled);   645         EnableWindow(shell->hWnd, enabled);
601     }   646     }
602 }   647 }
603     648  
604 /**   649 /**
605 * When a modal shell is added to the display all other visible shell's are disabled. When   650 * When a modal shell is added to the display all other visible shell's are disabled. When
606 * the last modal shell is removed from the display all shells that want to be enabled   651 * the last modal shell is removed from the display all shells that want to be enabled
607 * will be re-enabled   652 * will be re-enabled
608 */   653 */
609 void Display_UpdateModalShellVisibility(PUGL_Display display, struct UGL_Control* modalShell, BOOL visible, UGL_Error error) {   654 void Display_UpdateModalShellVisibility(PUGL_Display display, struct UGL_Control* modalShell, BOOL visible, UGL_Error error) {
610     if (visible) {   655     if (visible) {
611         ControlList_AddControl(&(display->modalShells), modalShell);   656         ControlList_AddControl(&(display->modalShells), modalShell);
612     } else {   657     } else {
613         ControlList_RemoveControl(&(display->modalShells), modalShell);   658         ControlList_RemoveControl(&(display->modalShells), modalShell);
614     }   659     }
615     UpdateEnabledShells(display);   660     UpdateEnabledShells(display);
616 }   661 }
617     662  
618 /**   663 /**
619 * This method will track the new shell and manage it's enabled state   664 * This method will track the new shell and manage it's enabled state
620 * based on the current modal shell.   665 * based on the current modal shell.
621 */   666 */
622 void Display_AddShell(PUGL_Display display, struct UGL_Control* shell, UGL_Error error) {   667 void Display_AddShell(PUGL_Display display, struct UGL_Control* shell, UGL_Error error) {
623     // Only shells that are enabled need to be tracked,  if the shell   668     // Only shells that are enabled need to be tracked,  if the shell
624     // become enabled in the future it will go through Display_EnableShell   669     // become enabled in the future it will go through Display_EnableShell
625     // and be added to the list then.   670     // and be added to the list then.
626     if (IsWindowEnabled(shell->hWnd)) {   671     if (IsWindowEnabled(shell->hWnd)) {
627         if (ControlList_AddControl(&(display->enabledShells), shell)) {   672         if (ControlList_AddControl(&(display->enabledShells), shell)) {
628             // If there is a current modal shell and the new shell is not a child of   673             // If there is a current modal shell and the new shell is not a child of
629             // that shell then it needs to be disabled to reflect the modal status.   674             // that shell then it needs to be disabled to reflect the modal status.
630             if ((display->modalShells != NULL) && !IsChildOfShell(display->modalShells->control, shell)) {   675             if ((display->modalShells != NULL) && !IsChildOfShell(display->modalShells->control, shell)) {
631                 // It is important that we don't call Control_SetEnabled() to do the work because   676                 // It is important that we don't call Control_SetEnabled() to do the work because
632                 // that will result in the shell being removed from the list of shells that would   677                 // that will result in the shell being removed from the list of shells that would
633                 // prefer to be enabled   678                 // prefer to be enabled
634                 EnableWindow(shell->hWnd, FALSE);   679                 EnableWindow(shell->hWnd, FALSE);
635             }   680             }
636         } else {   681         } else {
637             Win32Error_SetError(error, UGL_ERROR_OTHER, _T("Could not add control to control list"));   682             Win32Error_SetError(error, UGL_ERROR_OTHER, _T("Could not add control to control list"));
638         }   683         }
639     }   684     }
640 }   685 }
641     686  
642 /**   687 /**
643 * Stops tracking the specified shell.  This should only be called   688 * Stops tracking the specified shell.  This should only be called
644 * when a shell is being disposed.   689 * when a shell is being disposed.
645 */   690 */
646 void Display_RemoveShell(PUGL_Display display, struct UGL_Control* shell) {   691 void Display_RemoveShell(PUGL_Display display, struct UGL_Control* shell) {
647     ControlList_RemoveControl(&(display->enabledShells), shell);   692     ControlList_RemoveControl(&(display->enabledShells), shell);
648 }   693 }
649     694  
650 /**   695 /**
651 * Returns TRUE if the shell needs to be updated with the new   696 * Returns TRUE if the shell needs to be updated with the new
652 * enabled status.  It will return FALSE if the shell already has the   697 * enabled status.  It will return FALSE if the shell already has the
653 * style specified.  For example, If the this method is called to enable a shell while   698 * style specified.  For example, If the this method is called to enable a shell while
654 * a modal shell is visible it will return FALSE, since the shell must remain   699 * a modal shell is visible it will return FALSE, since the shell must remain
655 * disabled while the dialog is visible, but when the modal shell is hidden the desired   700 * disabled while the dialog is visible, but when the modal shell is hidden the desired
656 * enabled state will be remembered and updated.   701 * enabled state will be remembered and updated.
657 */   702 */
658 BOOL Display_EnableShell(PUGL_Display display, struct UGL_Control* shell, BOOL enable) {   703 BOOL Display_EnableShell(PUGL_Display display, struct UGL_Control* shell, BOOL enable) {
659     if (enable) {   704     if (enable) {
660         ControlList_AddControl(&(display->enabledShells), shell);   705         ControlList_AddControl(&(display->enabledShells), shell);
661     } else {   706     } else {
662         ControlList_RemoveControl(&(display->enabledShells), shell);   707         ControlList_RemoveControl(&(display->enabledShells), shell);
663     }   708     }
664     709  
665     if ((display->modalShells != NULL) && !IsChildOfShell(display->modalShells->control, shell)) {   710     if ((display->modalShells != NULL) && !IsChildOfShell(display->modalShells->control, shell)) {
666         // Since there is either no modal shell or the specified shell is a child of the modal shell   711         // Since there is either no modal shell or the specified shell is a child of the modal shell
667         // it can do whatever it would like.   712         // it can do whatever it would like.
668         return TRUE;   713         return TRUE;
669     } else {   714     } else {
670         return FALSE;   715         return FALSE;
671     }   716     }
672 }   717 }
673     718  
674     719  
675 void _Dispose_Display(UGL_Int handle, UGL_Error uglError) {   720 void _Dispose_Display(UGL_Int handle, UGL_Error uglError) {
676     PUGL_Display ugl_display = UGL_DISPLAY(handle);   721     PUGL_Display ugl_display = UGL_DISPLAY(handle);
677     722  
678     // destroy creation window   723     // destroy creation window
679     724  
680     if (ugl_display->defaultControlFont != NULL) {   725     if (ugl_display->defaultControlFont != NULL) {
681         Font_Dispose((UGL_Int)ugl_display->defaultControlFont, uglError);   726         Font_Dispose((UGL_Int)ugl_display->defaultControlFont, uglError);
682     }   727     }
683     728  
684     DestroyWindow(ugl_display->creation_hWnd);   729     DestroyWindow(ugl_display->creation_hWnd);
685     730  
686     if (!UnregisterClass(WINDOW_CLASS_NAME, ugl_display->hInstance)) {   731     if (!UnregisterClass(WINDOW_CLASS_NAME, ugl_display->hInstance)) {
687         free(ugl_display);   732         free(ugl_display);
688 //      Win32Error_SetError(uglError, GetLastError(), _T("Unable to unregister class for device"));   733 //      Win32Error_SetError(uglError, GetLastError(), _T("Unable to unregister class for device"));
689         return;   734         return;
690     }   735     }
691     736  
692     ugl_display->callback_lookup = NULL;   737     ugl_display->callback_lookup = NULL;
693     738  
694     if (ugl_display->menuItems != NULL) {   739     if (ugl_display->menuItems != NULL) {
695         free(ugl_display->menuItems);   740         free(ugl_display->menuItems);
696     }   741     }
697     742  
698     free(ugl_display);   743     free(ugl_display);
699 }   744 }
700     745  
701     746  
702     747  
703 //========================================================================================   748 //========================================================================================
704     749  
705 void Display_GetIconSize(UGL_Int handle, UGL_Int* returnX, UGL_Int* returnY, UGL_Error uglError) {    750 void Display_GetIconSize(UGL_Int handle, UGL_Int* returnX, UGL_Int* returnY, UGL_Error uglError) { 
706     *returnX = GetSystemMetrics(SM_CXICON);   751     *returnX = GetSystemMetrics(SM_CXICON);
707     *returnY = GetSystemMetrics(SM_CYICON);   752     *returnY = GetSystemMetrics(SM_CYICON);
708 }   753 }
709 //========================================================================================   754 //========================================================================================
710     755  
711 UGL_Int Display_GetDoubleClickTime(UGL_Int handle, UGL_Error uglError) {   756 UGL_Int Display_GetDoubleClickTime(UGL_Int handle, UGL_Error uglError) {
712     return GetDoubleClickTime();   757     return GetDoubleClickTime();
713 }   758 }
714 //========================================================================================   759 //========================================================================================
715     760  
716 void Display_SetAppName(UGL_String name, UGL_Error uglError) {   761 void Display_SetAppName(UGL_String name, UGL_Error uglError) {
717     // Nothing to do on Windows   762     // Nothing to do on Windows
718 }   763 }
719     764  
720 //========================================================================================   765 //========================================================================================
721     766  
722 void CALLBACK _Timer_Proc(HWND hwnd, UINT msg, UINT_PTR timer_ID, DWORD dwTime) {   767 void CALLBACK _Timer_Proc(HWND hwnd, UINT msg, UINT_PTR timer_ID, DWORD dwTime) {
723     PUGL_Display ugl_display = UGL_DISPLAY(GetWindowLong(hwnd, GWL_USERDATA));   768     PUGL_Display ugl_display = UGL_DISPLAY(GetWindowLong(hwnd, GWL_USERDATA));
724       769    
725     // Because of PocketPC not liking timerIds with a value of 0, the id that   770     // Because of PocketPC not liking timerIds with a value of 0, the id that
726     // Java is expecting will be 1 less then the one comming into this method.   771     // Java is expecting will be 1 less then the one comming into this method.
727     // See Display_StartTimer() for me details.   772     // See Display_StartTimer() for me details.
728     DisplayTimerCallback((UGL_Int)ugl_display, (UGL_Int)timer_ID-1);   773     DisplayTimerCallback((UGL_Int)ugl_display, (UGL_Int)timer_ID-1);
729 }   774 }
730     775  
731 void Display_AddMenuItem(struct UGL_MenuItem *menuItem) {   776 void Display_AddMenuItem(struct UGL_MenuItem *menuItem) {
732     PUGL_Display display = UGL_WIDGET(menuItem)->display;   777     PUGL_Display display = UGL_WIDGET(menuItem)->display;
733     struct UGL_MenuItem **menuItems;   778     struct UGL_MenuItem **menuItems;
734     int index;    779     int index; 
735 #ifdef _WIN32_WCE   780 #ifdef _WIN32_WCE
736     if (menuItem->parent_menu->hwndCB != 0) {   781     if (menuItem->parent_menu->hwndCB != 0) {
737         display->menuItemCount+=1;   782         display->menuItemCount+=1;
738     }   783     }
739 #endif   784 #endif
740     for (index = 0; index < display->menuItemsLength; index++) {   785     for (index = 0; index < display->menuItemsLength; index++) {
741         if (display->menuItems[index] == NULL) {   786         if (display->menuItems[index] == NULL) {
742             display->menuItems[index] = menuItem;   787             display->menuItems[index] = menuItem;
743             menuItem->id = index + MENU_ITEM_ID_OFFSET;   788             menuItem->id = index + MENU_ITEM_ID_OFFSET;
744             return;   789             return;
745         }   790         }
746     }   791     }
747     menuItems = display->menuItems;   792     menuItems = display->menuItems;
748     display->menuItems = calloc(display->menuItemsLength + MENU_ITEMS_INCREMENT, sizeof(PUGL_MenuItem));   793     display->menuItems = calloc(display->menuItemsLength + MENU_ITEMS_INCREMENT, sizeof(PUGL_MenuItem));
749     memcpy(display->menuItems, menuItems, display->menuItemsLength * sizeof(PUGL_MenuItem));   794     memcpy(display->menuItems, menuItems, display->menuItemsLength * sizeof(PUGL_MenuItem));
750     if (menuItems != NULL) {   795     if (menuItems != NULL) {
751         free(menuItems);   796         free(menuItems);
752     }   797     }
753     display->menuItems[display->menuItemsLength] = menuItem;   798     display->menuItems[display->menuItemsLength] = menuItem;
754     menuItem->id = display->menuItemsLength + MENU_ITEM_ID_OFFSET;   799     menuItem->id = display->menuItemsLength + MENU_ITEM_ID_OFFSET;
755     display->menuItemsLength += MENU_ITEMS_INCREMENT;   800     display->menuItemsLength += MENU_ITEMS_INCREMENT;
756 }   801 }
757     802  
758 PUGL_MenuItem Display_GetMenuItem(PUGL_Display display, int id) {   803 PUGL_MenuItem Display_GetMenuItem(PUGL_Display display, int id) {
759     PUGL_MenuItem menuItem = NULL;   804     PUGL_MenuItem menuItem = NULL;
760     int index = id - MENU_ITEM_ID_OFFSET;   805     int index = id - MENU_ITEM_ID_OFFSET;
761     806  
762     if (index >= 0 && index < display->menuItemsLength) {   807     if (index >= 0 && index < display->menuItemsLength) {
763         menuItem = display->menuItems[index];   808         menuItem = display->menuItems[index];
764     }   809     }
765     return menuItem;   810     return menuItem;
766 }   811 }
767     812  
768 void Display_RemoveMenuItem(struct UGL_MenuItem *menuItem) {   813 void Display_RemoveMenuItem(struct UGL_MenuItem *menuItem) {
769     PUGL_Display display = UGL_WIDGET(menuItem)->display;   814     PUGL_Display display = UGL_WIDGET(menuItem)->display;
770     int menuItemIndex = menuItem->id - MENU_ITEM_ID_OFFSET;   815     int menuItemIndex = menuItem->id - MENU_ITEM_ID_OFFSET;
771     816  
772     if (menuItemIndex >= 0 && menuItemIndex < display->menuItemsLength) {   817     if (menuItemIndex >= 0 && menuItemIndex < display->menuItemsLength) {
773         display->menuItems[menuItemIndex] = NULL;   818         display->menuItems[menuItemIndex] = NULL;
774         menuItemIndex = -1;   819         menuItemIndex = -1;
775     }   820     }
776 #ifdef _WIN32_WCE   821 #ifdef _WIN32_WCE
777     if (menuItem->parent_menu->hwndCB != 0) {   822     if (menuItem->parent_menu->hwndCB != 0) {
778         display->menuItemCount -= 1;   823         display->menuItemCount -= 1;
779     }   824     }
780 #endif   825 #endif
781 }   826 }
782     827  
783 #ifdef _WIN32_WCE   828 #ifdef _WIN32_WCE
784 // this function finds the menuitem in the main menu (top level menu) at index (index)   829 // this function finds the menuitem in the main menu (top level menu) at index (index)
785 /*   830 /*
786 PUGL_MenuItem Display_FindMenuItem(PUGL_Display display, int index) {   831 PUGL_MenuItem Display_FindMenuItem(PUGL_Display display, int index) {
787     int i;   832     int i;
788       833    
789     for(i=0; i<display->menuItemsLength; i++){   834     for(i=0; i<display->menuItemsLength; i++){
790         if(display->menuItems[i] != NULL){   835         if(display->menuItems[i] != NULL){
791             if(display->menuItems[i]->index == index){   836             if(display->menuItems[i]->index == index){
792                 if(display->menuItems[i]->parent_menu->hwndCB != 0) {   837                 if(display->menuItems[i]->parent_menu->hwndCB != 0) {
793                     return display->menuItems[i];   838                     return display->menuItems[i];
794                 }   839                 }
795             }   840             }
796         }   841         }
797     }   842     }
798     843  
799     return NULL;   844     return NULL;
800 }   845 }
801 */   846 */
802     847  
803 PUGL_MenuItem Display_FindMenuItem(PUGL_Display display, HWND hwndCB, int index) {   848 PUGL_MenuItem Display_FindMenuItem(PUGL_Display display, HWND hwndCB, int index) {
804     int i;   849     int i;
805     for(i=0; i<display->menuItemsLength; i++){   850     for(i=0; i<display->menuItemsLength; i++){
806         if(display->menuItems[i] != NULL){   851         if(display->menuItems[i] != NULL){
807             if (display->menuItems[i]->parent_menu->hwndCB != hwndCB) continue;   852             if (display->menuItems[i]->parent_menu->hwndCB != hwndCB) continue;
808             if(display->menuItems[i]->index == index){   853             if(display->menuItems[i]->index == index){
809                 if(display->menuItems[i]->parent_menu->hwndCB != 0) {   854                 if(display->menuItems[i]->parent_menu->hwndCB != 0) {
810                     return display->menuItems[i];   855                     return display->menuItems[i];
811                 }   856                 }
812             }   857             }
813         }   858         }
814     }   859     }
815     return NULL;   860     return NULL;
816 }   861 }
817     862  
818     863  
819 // this function decrements the index of menuitems in the main menu (top level menu) starting at index (start)   864 // this function decrements the index of menuitems in the main menu (top level menu) starting at index (start)
820 // for example, when we remove menuItem index 3 we would wish to decrement the index of all menuitems greater than 3 by one   865 // for example, when we remove menuItem index 3 we would wish to decrement the index of all menuitems greater than 3 by one
821 /*   866 /*
822 void Display_DecMenuItemIndex(PUGL_Display display, HWND hwndCB, int start){   867 void Display_DecMenuItemIndex(PUGL_Display display, HWND hwndCB, int start){
823     // new for softkey, maintain the menuitem order   868     // new for softkey, maintain the menuitem order
824     int index;   869     int index;
825         for (index = 0; index < display->menuItemsLength; index++) {   870         for (index = 0; index < display->menuItemsLength; index++) {
826               871            
827             if (display->menuItems[index] != NULL) {   872             if (display->menuItems[index] != NULL) {
828                 if(display->menuItems[index]->parent_menu->hwndCB != 0){   873                 if(display->menuItems[index]->parent_menu->hwndCB != 0){
829                     //Fix duplicate menuItem problem.   874                     //Fix duplicate menuItem problem.
830                     if(start == display->menuItems[index]->index) {   875                     if(start == display->menuItems[index]->index) {
831                      display->menuItems[index]->index = -1 ;   876                      display->menuItems[index]->index = -1 ;
832                     }   877                     }
833                     if(start < display->menuItems[index]->index){   878                     if(start < display->menuItems[index]->index){
834                         display->menuItems[index]->index--;           879                         display->menuItems[index]->index--;        
835                     }   880                     }
836                 }   881                 }
837             }   882             }
838         }   883         }
839 }   884 }
840 */   885 */
841     886  
842     887  
843 void Display_DecMenuItemIndex(PUGL_Display display, HWND hwndCB, int start){   888 void Display_DecMenuItemIndex(PUGL_Display display, HWND hwndCB, int start){
844     // new for softkey, maintain the menuitem order   889     // new for softkey, maintain the menuitem order
845     int index;   890     int index;
846         for (index = 0; index < display->menuItemsLength; index++) {   891         for (index = 0; index < display->menuItemsLength; index++) {
847             if (display->menuItems[index] != NULL) {   892             if (display->menuItems[index] != NULL) {
848                 if (display->menuItems[index]->parent_menu->hwndCB != hwndCB) continue;   893                 if (display->menuItems[index]->parent_menu->hwndCB != hwndCB) continue;
849                 if(display->menuItems[index]->parent_menu->hwndCB != 0){   894                 if(display->menuItems[index]->parent_menu->hwndCB != 0){
850                     //Fix duplicate menuItem problem.   895                     //Fix duplicate menuItem problem.
851                     if(start == display->menuItems[index]->index) {   896                     if(start == display->menuItems[index]->index) {
852                      display->menuItems[index]->index = -1 ;   897                      display->menuItems[index]->index = -1 ;
853                     }   898                     }
854                     if(start < display->menuItems[index]->index){   899                     if(start < display->menuItems[index]->index){
855                         display->menuItems[index]->index--;           900                         display->menuItems[index]->index--;        
856                     }   901                     }
857                 }   902                 }
858             }   903             }
859         }   904         }
860 }   905 }
861     906  
862 // this function increments the index of menuitems in the main menu (top level menu) starting at index (start)   907 // this function increments the index of menuitems in the main menu (top level menu) starting at index (start)
863 // for example, when we add menuItem index 3 we would wish to increment the index of all menuitems greater than or equal to 3 by one   908 // for example, when we add menuItem index 3 we would wish to increment the index of all menuitems greater than or equal to 3 by one
864 void Display_IncMenuItemIndex(PUGL_Display display, HWND hwndCB, int start){   909 void Display_IncMenuItemIndex(PUGL_Display display, HWND hwndCB, int start){
865     // new for softkey, maintain the menuitem order   910     // new for softkey, maintain the menuitem order
866     int index;   911     int index;
867     FILE * pFile;   912     FILE * pFile;
868         for (index = 0; index < display->menuItemsLength; index++) {   913         for (index = 0; index < display->menuItemsLength; index++) {
869             if (display->menuItems[index] != NULL) {   914             if (display->menuItems[index] != NULL) {
870                 if (display->menuItems[index]->parent_menu->hwndCB != hwndCB) continue;   915                 if (display->menuItems[index]->parent_menu->hwndCB != hwndCB) continue;
871                 if(display->menuItems[index]->parent_menu->hwndCB != 0){   916                 if(display->menuItems[index]->parent_menu->hwndCB != 0){
872                     if(start <= display->menuItems[index]->index){   917                     if(start <= display->menuItems[index]->index){
873                         display->menuItems[index]->index++;           918                         display->menuItems[index]->index++;        
874                     }   919                     }
875                 }   920                 }
876             }   921             }
877         }   922         }
878 }   923 }
879     924  
880 // this function returns the menuitem count associated with specific menu hwndCB   925 // this function returns the menuitem count associated with specific menu hwndCB
881 int Display_MenuItemCount(PUGL_Display display, HWND hwndCB){   926 int Display_MenuItemCount(PUGL_Display display, HWND hwndCB){
882     int index;   927     int index;
883     int count=0;   928     int count=0;
884         for (index = 0; index < display->menuItemsLength; index++) {   929         for (index = 0; index < display->menuItemsLength; index++) {
885             if (display->menuItems[index] == NULL) continue;   930             if (display->menuItems[index] == NULL) continue;
886             if (display->menuItems[index]->parent_menu->hwndCB != hwndCB) continue;   931             if (display->menuItems[index]->parent_menu->hwndCB != hwndCB) continue;
887             count ++;   932             count ++;
888         }   933         }
889     return count;   934     return count;
890 }   935 }
891     936  
892 #endif   937 #endif
893     938  
894 //========================================================================================   939 //========================================================================================
895     940  
896 /**   941 /**
897 * Returns the insets of the display identified by <code>handle</code>.   942 * Returns the insets of the display identified by <code>handle</code>.
898 * This is the portion of the screen that is unusable for drawing,   943 * This is the portion of the screen that is unusable for drawing,
899 * such as a task bar.   944 * such as a task bar.
900 *   945 *
901 * @ingroup Display   946 * @ingroup Display
902 *   947 *
903 * @param handle the display handle   948 * @param handle the display handle
904 * @param returnLeft (out) the left inset   949 * @param returnLeft (out) the left inset
905 * @param returnTop (out) the top inset   950 * @param returnTop (out) the top inset
906 * @param returnRight (out) the right inset   951 * @param returnRight (out) the right inset
907 * @param returnBottom (out) the bottom inset   952 * @param returnBottom (out) the bottom inset
908 * @param error the error status of the call   953 * @param error the error status of the call
909 */   954 */
910 void Display_GetInsets(UGL_Int handle, UGL_Int* returnLeft, UGL_Int* returnTop, UGL_Int* returnRight, UGL_Int* returnBottom, UGL_Error error) {   955 void Display_GetInsets(UGL_Int handle, UGL_Int* returnLeft, UGL_Int* returnTop, UGL_Int* returnRight, UGL_Int* returnBottom, UGL_Error error) {
911     int left = 0;   956     int left = 0;
912     int top = 0;   957     int top = 0;
913     int right = 0;   958     int right = 0;
914     int bottom = 0;   959     int bottom = 0;
915     960  
916     RECT workarea;   961     RECT workarea;
917     int boundsX, boundsY, boundsWidth, boundsHeight;   962     int boundsX, boundsY, boundsWidth, boundsHeight;
918     963  
919     SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea, 0);      964     SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea, 0);   
920     Device_GetBounds(handle, &boundsX, &boundsY, &boundsWidth, &boundsHeight, error);   965     Device_GetBounds(handle, &boundsX, &boundsY, &boundsWidth, &boundsHeight, error);
921       966    
922     *returnLeft = workarea.left - boundsX;   967     *returnLeft = workarea.left - boundsX;
923     *returnTop = workarea.top - boundsY;   968     *returnTop = workarea.top - boundsY;
924     *returnRight = boundsX + boundsWidth - workarea.right;   969     *returnRight = boundsX + boundsWidth - workarea.right;
925     *returnBottom = boundsY + boundsHeight - workarea.bottom;   970     *returnBottom = boundsY + boundsHeight - workarea.bottom;
926 }   971 }
927     972