8 #include "graphics_win32.h"
18 #include "navit_nls.h"
24 static int ce_backlight = 1;
25 static int ce_fullscreen;
29 //static GHashTable *popup_callback_hash = NULL;
30 static GArray *popup_menu_array;
33 const TCHAR g_szClassName[] = TEXT("navit_gui_class");
36 static UINT_PTR menu_id = 0;
39 static gboolean message_pump( gpointer data )
45 if (GetMessage (&messages, NULL, 0, 0))
47 TranslateMessage(&messages);
48 DispatchMessage(&messages);
56 static BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
61 idChild = GetWindowLong(hwndChild, GWL_ID);
63 if ( idChild == ID_CHILD_GFX )
65 rcParent = (LPRECT) lParam;
67 MoveWindow( hwndChild, 0, 0, rcParent->right, rcParent->bottom, TRUE );
68 PostMessage( hwndChild, WM_USER+1, 0, 0 );
75 #ifndef GET_WHEEL_DELTA_WPARAM
76 #define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
79 static void CreateToolBar(HWND hwnd)
85 #if 0 /* def _WIN32_WCE */
86 /* Have to initialize common controls under CE */
87 INITCOMMONCONTROLSEX iccex;
88 iccex.dwSize = sizeof (INITCOMMONCONTROLSEX);
89 iccex.dwICC = ICC_BAR_CLASSES;
90 InitCommonControlsEx (&iccex);
95 hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
96 hwnd, (HMENU)ID_CHILD_TOOLBAR, GetModuleHandle(NULL), NULL);
99 MessageBox(hwnd, TEXT("Could not create tool bar."), TEXT("Error"), MB_OK | MB_ICONERROR);
101 SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
103 tbab.hInst = GetModuleHandle(NULL);
104 tbab.nID = IDB_NAVITTOOLBAR;
105 int iImageOffset = SendMessage(hTool, TB_ADDBITMAP, 10, (LPARAM) &tbab);
109 ZeroMemory(tbb, sizeof(tbb));
111 tbb[0].iBitmap = iImageOffset;
112 tbb[0].fsState = TBSTATE_ENABLED;
113 tbb[0].fsStyle = TBSTYLE_BUTTON;
114 tbb[0].idCommand = ID_DISPLAY_ZOOMIN;
115 iStr = SendMessage(hTool, TB_ADDSTRINGW, 0, (LPARAM) L"ZoomIn" );
116 tbb[0].iString = iStr;
118 tbb[1].iBitmap = iImageOffset+1;
119 tbb[1].fsState = TBSTATE_ENABLED;
120 tbb[1].fsStyle = TBSTYLE_BUTTON;
121 tbb[1].idCommand = ID_DISPLAY_ZOOMOUT;
122 iStr = SendMessage(hTool, TB_ADDSTRINGW, 0, (LPARAM) L"ZoomOut" );
123 tbb[1].iString = iStr;
125 tbb[2].iBitmap = iImageOffset+4;
126 tbb[2].fsState = TBSTATE_ENABLED;
127 tbb[2].fsStyle = TBSTYLE_BUTTON;
128 tbb[2].idCommand = ID_DISPLAY_REFRESH;
129 iStr = SendMessage(hTool, TB_ADDSTRINGW, 0, (LPARAM) L"Refresh" );
130 tbb[2].iString = iStr;
132 tbb[3].iBitmap = iImageOffset+2;
133 tbb[3].fsState = TBSTATE_ENABLED;
134 tbb[3].fsStyle = TBSTYLE_BUTTON;
135 tbb[3].idCommand = ID_DISPLAY_ZOOMIN;
136 iStr = SendMessage(hTool, TB_ADDSTRINGW, 0, (LPARAM) L"Cursor" );
137 tbb[3].iString = iStr;
139 tbb[4].iBitmap = iImageOffset+5;
140 tbb[4].fsState = TBSTATE_ENABLED;
141 tbb[4].fsStyle = TBSTYLE_BUTTON;
142 tbb[4].idCommand = ID_DISPLAY_ORIENT;
143 iStr = SendMessage(hTool, TB_ADDSTRINGW, 0, (LPARAM) L"Orientation" );
144 tbb[4].iString = iStr;
146 tbb[5].iBitmap = iImageOffset+8;
147 tbb[5].fsState = TBSTATE_ENABLED;
148 tbb[5].fsStyle = TBSTYLE_BUTTON;
149 tbb[5].idCommand = ID_DISPLAY_ZOOMIN;
150 iStr= SendMessage(hTool, TB_ADDSTRINGW, 0, (LPARAM) L"Destination" );
151 tbb[5].iString = iStr;
153 tbb[6].iBitmap = iImageOffset+3;
154 tbb[6].fsState = TBSTATE_ENABLED;
155 tbb[6].fsStyle = TBSTYLE_BUTTON;
156 tbb[6].idCommand = ID_DISPLAY_ZOOMIN;
157 iStr= SendMessage(hTool, TB_ADDSTRINGW, 0, (LPARAM) L"Roadbook" );
158 tbb[6].iString = iStr;
160 tbb[7].iBitmap = iImageOffset+9;
161 tbb[7].fsState = TBSTATE_ENABLED;
162 tbb[7].fsStyle = TBSTYLE_BUTTON;
163 tbb[7].idCommand = ID_FILE_EXIT;
164 iStr= SendMessage(hTool, TB_ADDSTRINGW, 0, (LPARAM) L"_Quit" );
165 tbb[7].iString = iStr;
167 SendMessage(hTool, TB_ADDBUTTONS, sizeof(tbb)/sizeof(TBBUTTON), (LPARAM)&tbb);
170 static void window_layout( HWND hwnd )
172 #ifndef HAVE_API_WIN32_CE
177 HWND hChild = GetDlgItem(hwnd, ID_CHILD_TOOLBAR);
178 SendMessage(hChild, TB_AUTOSIZE, 0, 0);
180 GetWindowRect(hChild, &rcTool);
181 iToolHeight = rcTool.bottom - rcTool.top;
183 GetClientRect(hwnd, &rcClient);
184 //printf( "BEFORE resize gui to: %d %d %d %d \n", rcClient.left, rcClient.right, rcClient.top, rcClient.bottom );
186 rcClient.top += iToolHeight;
188 dbg(0, "resize gui to: %d %d %d %d \n", rcClient.left, rcClient.right, rcClient.top, rcClient.bottom );
191 hChild = GetDlgItem(hwnd, ID_CHILD_GFX);
194 MoveWindow( hChild, rcClient.left, rcClient.top, rcClient.right- rcClient.left, rcClient.bottom - rcClient.top, TRUE );
195 PostMessage( hChild, WM_USER+1, 0, 0 );
200 static void toggle_fullscreen(HWND mWnd)
202 if (SHFullScreenPtr) {
203 if (!ce_fullscreen) {
204 (*SHFullScreenPtr)(mWnd, SHFS_HIDETASKBAR |
205 SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON);
207 (*SHFullScreenPtr)(mWnd, SHFS_HIDESIPBUTTON);
209 ce_fullscreen = !ce_fullscreen;
213 static void toggle_backlight(void)
216 if (CeEnableBacklight(FALSE))
219 if (CeEnableBacklight(TRUE))
224 static LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
228 // printf( "PARENT %d %d %d \n", Message, wParam, lParam );
234 HMENU hMenu, hSubMenu;
236 CreateToolBar( hwnd );
238 hMenu = CreateMenu();
239 // g_this_->hwnd = hwnd;
241 hSubMenu = CreatePopupMenu();
243 AppendMenuW(hSubMenu, MF_STRING, ID_DISPLAY_ZOOMIN, L"ZoomIn" );
244 AppendMenuW(hSubMenu, MF_STRING, ID_DISPLAY_ZOOMOUT, L"ZoomOut" );
245 AppendMenuW(hSubMenu, MF_STRING, ID_DISPLAY_REFRESH, L"Refresh" );
246 AppendMenuW(hSubMenu, MF_SEPARATOR, 0, NULL );
247 AppendMenuW(hSubMenu, MF_STRING, ID_FILE_EXIT, L"_Quit" );
249 AppendMenuW(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, L"Display" );
250 hSubMenu = CreatePopupMenu();
251 AppendMenu(hSubMenu, MF_STRING, ID_STUFF_GO, TEXT("&Go"));
252 AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, TEXT("&Stuff"));
254 #ifndef HAVE_API_WIN32_CE
255 SetMenu(hwnd, hMenu);
258 window_layout( hwnd );
264 printf( "WM_COMMAND %d\n", LOWORD(wParam) );
265 struct gui_priv* gui = (struct gui_priv*)GetWindowLongPtr( hwnd , DWLP_USER );
268 switch(LOWORD(wParam))
270 case ID_DISPLAY_ZOOMIN:
271 navit_zoom_in(gui->nav, 2, NULL);
274 case ID_DISPLAY_ZOOMOUT:
275 navit_zoom_out(gui->nav, 2, NULL);
278 case ID_DISPLAY_REFRESH:
279 navit_draw(gui->nav);
282 case ID_DISPLAY_CURSOR:
285 attr.type=attr_cursor;
286 // TODO attr.u.num=gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(w));
287 if(!navit_set_attr(gui->nav, &attr)) {
288 dbg(0, "Failed to set attr_cursor\n");
293 case ID_DISPLAY_ORIENT:
297 attr.type=attr_orientation;
298 // attr.u.num=gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(w));
299 attr.u.num = 0; // TODO
300 if(!navit_set_attr(gui->nav, &attr)) {
301 dbg(0, "Failed to set attr_orientation\n");
307 PostMessage(hwnd, WM_CLOSE, 0, 0);
312 if ( popup_menu_array )
314 struct menu_priv* priv = (struct menu_priv*)g_array_index( popup_menu_array, gint, LOWORD(wParam) - POPUP_MENU_OFFSET );
318 struct callback* cb = priv->cb;
321 callback_call_0( priv->cb );
330 GetClientRect(hwnd, &rcClient);
331 printf( "resize gui to: %d %d \n", rcClient.right, rcClient.bottom );
333 window_layout( hwnd );
334 //EnumChildWindows(hwnd, EnumChildProc, (LPARAM) &rcClient);
341 window_layout( hwnd );
351 struct gui_priv* gui = (struct gui_priv*)GetWindowLongPtr( hwnd , DWLP_USER );
353 short delta = GET_WHEEL_DELTA_WPARAM( wParam );
356 navit_zoom_in(gui->nav, 2, NULL);
359 navit_zoom_out(gui->nav, 2, NULL);
363 #ifdef HAVE_API_WIN32_CE
368 struct gui_priv* gui = (struct gui_priv*)GetWindowLongPtr( hwnd , DWLP_USER );
369 transform_get_size(navit_get_trans(gui->nav), &w, &h);
371 if (wParam == VK_LEFT || wParam == '4') {
374 navit_set_center_screen(gui->nav, &p, 1);
375 } else if (wParam == VK_RIGHT || wParam == '6') {
378 navit_set_center_screen(gui->nav, &p, 1);
379 } else if (wParam == VK_UP || wParam == '2') {
382 navit_set_center_screen(gui->nav, &p, 1);
383 } else if (wParam == VK_DOWN || wParam == '8') {
386 navit_set_center_screen(gui->nav, &p, 1);
387 } else if (wParam == '1') {
388 navit_zoom_in(gui->nav, 2, NULL);
389 } else if (wParam == '3') {
390 navit_zoom_out(gui->nav, 2, NULL);
391 } else if (wParam == '7') {
395 } else if (wParam == '9') {
397 toggle_fullscreen(hwnd);
404 return DefWindowProc(hwnd, Message, wParam, lParam);
409 static HANDLE CreateWin32Window( void )
411 #ifdef HAVE_API_WIN32_CE
415 wc.cbSize = sizeof(WNDCLASSEX);
416 wc.hIconSm = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_NAVIT));
422 wc.lpfnWndProc = WndProc;
426 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
427 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
428 wc.lpszMenuName = NULL;
429 wc.lpszClassName = g_szClassName;
430 wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_NAVIT));
432 #ifdef HAVE_API_WIN32_CE
433 if(!RegisterClass(&wc))
435 if(!RegisterClassEx(&wc))
439 MessageBox(NULL, TEXT("Window Registration Failed!"), TEXT("Error!"), MB_ICONEXCLAMATION | MB_OK);
443 hwnd = CreateWindowEx(
447 #ifdef HAVE_API_WIN32_CE
448 WS_SYSMENU | WS_CLIPCHILDREN,
449 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
452 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
453 CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
455 NULL, NULL, NULL, NULL);
459 MessageBox(NULL, TEXT("Window Creation Failed!"), TEXT("Error!"), MB_ICONEXCLAMATION | MB_OK);
463 ShowWindow(hwnd, TRUE);
467 g_idle_add (message_pump, NULL);
474 static int win32_gui_set_graphics(struct gui_priv *this_, struct graphics *gra)
476 HANDLE* wndHandle_ptr = graphics_get_data(gra, "wnd_parent_handle_ptr");
477 *wndHandle_ptr = this_->hwnd;
478 graphics_get_data(gra, "START_CLIENT");
483 static void win32_gui_add_bookmark_do(struct gui_priv *gui)
485 // navit_add_bookmark(gui->nav, &gui->dialog_coord, gtk_entry_get_text(GTK_ENTRY(gui->dialog_entry)));
486 // gtk_widget_destroy(gui->dialog_win);
489 static int win32_gui_add_bookmark(struct gui_priv *gui, struct pcoord *c, char *description)
495 static struct menu_methods menu_methods;
498 static struct menu_priv *add_menu( struct menu_priv *menu,
499 struct menu_methods *meth,
504 struct menu_priv* ret = NULL;
506 ret = g_new0(struct menu_priv, 1);
509 *meth = menu_methods;
511 TCHAR *menuname = newSysString(name);
513 if ( type == menu_type_submenu )
515 HMENU hSubMenu = NULL;
516 hSubMenu = CreatePopupMenu();
517 AppendMenu(menu->hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, menuname );
518 ret->hMenu = hSubMenu;
522 AppendMenu( menu->hMenu, MF_STRING, menu_id, name );
525 // g_hash_table_insert( popup_callback_hash, GINT_TO_POINTER( menu_id ), (gpointer)cb );
527 g_array_append_val( popup_menu_array, ret );
538 static void set_toggle(struct menu_priv *menu, int active)
540 // gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(menu->action), active);
543 static int get_toggle(struct menu_priv *menu)
545 // return gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(menu->action));
549 static struct menu_methods menu_methods = {
555 static void popup_activate(struct menu_priv *menu)
558 GetCursorPos( &pnt );
562 TrackPopupMenu( menu->hMenu, 0, pnt.x, pnt.y, 0, menu->wnd_handle, NULL );
563 DestroyMenu( menu->hMenu );
568 static void popup_deactivate( struct menu_priv *menu )
570 DestroyMenu( menu->hMenu );
573 static struct menu_priv* win32_gui_popup_new(struct gui_priv *this_, struct menu_methods *meth)
575 struct menu_priv* ret = NULL;
577 ret = g_new0(struct menu_priv, 1);
578 *meth = menu_methods;
580 menu_id = POPUP_MENU_OFFSET;
583 if ( popup_menu_array )
585 g_array_free (popup_menu_array, TRUE);
586 popup_menu_array = NULL;
589 popup_menu_array = g_array_new (FALSE, FALSE, sizeof (gint));
593 ret->hMenu = CreatePopupMenu();
594 ret->wnd_handle = this_->hwnd;
595 meth->popup=popup_activate;
597 printf( "create popup menu %d \n", ret->hMenu );
602 struct gui_methods win32_gui_methods = {
603 NULL, // win32_gui_menubar_new,
605 win32_gui_set_graphics,
607 NULL, // win32_gui_datawindow_new,
608 win32_gui_add_bookmark,
613 static struct gui_priv *win32_gui_new( struct navit *nav, struct gui_methods *meth, struct attr **attrs)
615 struct gui_priv *this_;
616 #ifdef HAVE_API_WIN32_CE
617 /* Do not run multiple instances under CE */
619 prev = FindWindow(g_szClassName, NULL);
621 ShowWindow(prev, SW_RESTORE);
622 SetForegroundWindow(prev);
623 InvalidateRect (prev, NULL, FALSE);
629 *meth=win32_gui_methods;
631 this_=g_new0(struct gui_priv, 1);
634 this_->hwnd = CreateWin32Window();
635 SetWindowLongPtr( this_->hwnd , DWLP_USER, (LONG_PTR)this_ );
640 void plugin_init(void)
642 plugin_register_gui_type("win32", win32_gui_new);