17 #include "graphics_win32.h"
19 #include "support/win32/ConvertUTF.h"
23 #ifdef HAVE_API_WIN32_CE
27 //#define FAST_TRANSPARENCY 1
29 #if defined(_WIN32_WCE) && _WIN32_WCE < 0x500 && !defined(__MINGW32CE__)
34 int SourceConstantAlpha;
39 #define AC_SRC_ALPHA 2
42 typedef BOOL (WINAPI *FP_AlphaBlend) ( HDC hdcDest,
52 BLENDFUNCTION blendFunction
55 typedef int (WINAPI *FP_SetStretchBltMode) (HDC dc,int mode);
65 HANDLE wnd_parent_handle;
68 struct callback_list *cbl;
69 enum draw_mode_num mode;
70 struct graphics_priv* parent;
71 struct graphics_priv *overlays;
72 struct graphics_priv *next;
73 struct color transparent_color;
78 HBITMAP hPrebuildBitmap;
80 HBITMAP hOldPrebuildBitmap;
81 FP_AlphaBlend AlphaBlend;
82 FP_SetStretchBltMode SetStretchBltMode;
83 BOOL WINAPI (*ChangeWindowMessageFilter)(UINT message, DWORD dwFlag);
84 BOOL WINAPI (*ChangeWindowMessageFilterEx)( HWND hWnd, UINT message, DWORD action, void *pChangeFilterStruct);
88 GHashTable *image_cache_hash;
96 static HWND g_hwnd = NULL;
98 #ifdef HAVE_API_WIN32_CE
99 static int fullscr = 0;
103 #ifndef GET_WHEEL_DELTA_WPARAM
104 #define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
108 HFONT EzCreateFont (HDC hdc, TCHAR * szFaceName, int iDeciPtHeight,
109 int iDeciPtWidth, int iAttributes, BOOL fLogRes) ;
111 #define EZ_ATTR_BOLD 1
112 #define EZ_ATTR_ITALIC 2
113 #define EZ_ATTR_UNDERLINE 4
114 #define EZ_ATTR_STRIKEOUT 8
116 HFONT EzCreateFont (HDC hdc, TCHAR * szFaceName, int iDeciPtHeight,
117 int iDeciPtWidth, int iAttributes, BOOL fLogRes)
127 #ifndef HAVE_API_WIN32_CE
128 SetGraphicsMode (hdc, GM_ADVANCED) ;
129 ModifyWorldTransform (hdc, NULL, MWT_IDENTITY) ;
131 SetViewportOrgEx (hdc, 0, 0, NULL) ;
132 #ifndef HAVE_API_WIN32_CE
133 SetWindowOrgEx (hdc, 0, 0, NULL) ;
138 cxDpi = (FLOAT) GetDeviceCaps (hdc, LOGPIXELSX) ;
139 cyDpi = (FLOAT) GetDeviceCaps (hdc, LOGPIXELSY) ;
143 cxDpi = (FLOAT) (25.4 * GetDeviceCaps (hdc, HORZRES) /
144 GetDeviceCaps (hdc, HORZSIZE)) ;
146 cyDpi = (FLOAT) (25.4 * GetDeviceCaps (hdc, VERTRES) /
147 GetDeviceCaps (hdc, VERTSIZE)) ;
150 pt.x = (int) (iDeciPtWidth * cxDpi / 72) ;
151 pt.y = (int) (iDeciPtHeight * cyDpi / 72) ;
153 #ifndef HAVE_API_WIN32_CE
154 DPtoLP (hdc, &pt, 1) ;
156 lf.lfHeight = - (int) (fabs (pt.y) / 10.0 + 0.5) ;
158 lf.lfEscapement = 0 ;
159 lf.lfOrientation = 0 ;
160 lf.lfWeight = iAttributes & EZ_ATTR_BOLD ? 700 : 0 ;
161 lf.lfItalic = iAttributes & EZ_ATTR_ITALIC ? 1 : 0 ;
162 lf.lfUnderline = iAttributes & EZ_ATTR_UNDERLINE ? 1 : 0 ;
163 lf.lfStrikeOut = iAttributes & EZ_ATTR_STRIKEOUT ? 1 : 0 ;
164 lf.lfCharSet = DEFAULT_CHARSET ;
165 lf.lfOutPrecision = 0 ;
166 lf.lfClipPrecision = 0 ;
168 lf.lfPitchAndFamily = 0 ;
170 lstrcpy (lf.lfFaceName, szFaceName) ;
172 hFont = CreateFontIndirect (&lf) ;
174 if (iDeciPtWidth != 0)
176 hFont = (HFONT) SelectObject (hdc, hFont) ;
178 GetTextMetrics (hdc, &tm) ;
180 DeleteObject (SelectObject (hdc, hFont)) ;
182 lf.lfWidth = (int) (tm.tmAveCharWidth *
183 fabs (pt.x) / fabs (pt.y) + 0.5) ;
185 hFont = CreateFontIndirect (&lf) ;
188 RestoreDC (hdc, -1) ;
192 struct graphics_image_priv
195 int width,height,row_bytes,channels;
196 unsigned char *png_pixels;
202 static void ErrorExit(LPTSTR lpszFunction)
204 // Retrieve the system error message for the last-error code
208 DWORD dw = GetLastError();
211 FORMAT_MESSAGE_ALLOCATE_BUFFER |
212 FORMAT_MESSAGE_FROM_SYSTEM |
213 FORMAT_MESSAGE_IGNORE_INSERTS,
216 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
220 lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
221 (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
222 _tprintf((LPTSTR)lpDisplayBuf, TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf);
224 dbg(0, "%s failed with error %d: %s", lpszFunction, dw, lpMsgBuf);
225 MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
228 LocalFree(lpDisplayBuf);
234 struct graphics_gc_priv
243 struct graphics_priv *gr;
247 static void create_memory_dc(struct graphics_priv *gr)
250 BITMAPINFO bOverlayInfo;
254 (void)SelectBitmap(gr->hMemDC, gr->hOldBitmap);
255 DeleteBitmap(gr->hBitmap);
256 DeleteDC(gr->hMemDC);
258 (void)SelectBitmap(gr->hPrebuildDC, gr->hOldPrebuildBitmap);
259 DeleteBitmap(gr->hPrebuildBitmap);
260 DeleteDC(gr->hPrebuildDC);
265 hdc = GetDC( gr->wnd_handle );
267 gr->hMemDC = CreateCompatibleDC(hdc);
268 dbg(0, "resize memDC to: %d %d \n", gr->width, gr->height );
271 #ifndef FAST_TRANSPARENCY
273 memset(&bOverlayInfo, 0, sizeof(BITMAPINFO));
274 bOverlayInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
275 bOverlayInfo.bmiHeader.biWidth = gr->width;
276 bOverlayInfo.bmiHeader.biHeight = -gr->height;
277 bOverlayInfo.bmiHeader.biBitCount = 32;
278 bOverlayInfo.bmiHeader.biCompression = BI_RGB;
279 bOverlayInfo.bmiHeader.biPlanes = 1;
280 gr->hPrebuildDC = CreateCompatibleDC(NULL);
281 gr->hPrebuildBitmap = CreateDIBSection(gr->hMemDC, &bOverlayInfo, DIB_RGB_COLORS , (void **)&gr->pPixelData, NULL, 0);
282 gr->hOldPrebuildBitmap = SelectBitmap(gr->hPrebuildDC, gr->hPrebuildBitmap);
285 gr->hBitmap = CreateCompatibleBitmap(hdc, gr->width, gr->height );
289 gr->hOldBitmap = SelectBitmap( gr->hMemDC, gr->hBitmap);
291 ReleaseDC( gr->wnd_handle, hdc );
294 static void HandleButtonClick( struct graphics_priv *gra_priv, int updown, int button, long lParam )
296 struct point pt = { LOWORD(lParam), HIWORD(lParam) };
297 callback_list_call_attr_3(gra_priv->cbl, attr_button, (void *)updown, (void *)button, (void *)&pt);
300 static void HandleKeyChar(struct graphics_priv *gra_priv, WPARAM wParam)
302 TCHAR key = (TCHAR) wParam;
305 dbg(1,"HandleKey %d\n",key);
313 callback_list_call_attr_1(gra_priv->cbl, attr_keypress, (void *)s);
316 static void HandleKeyDown(struct graphics_priv *gra_priv, WPARAM wParam)
318 int key = (int) wParam;
319 char up[]={NAVIT_KEY_UP,0};
320 char down[]={NAVIT_KEY_DOWN,0};
321 char left[]={NAVIT_KEY_LEFT,0};
322 char right[]={NAVIT_KEY_RIGHT,0};
324 dbg(1,"HandleKey %d\n",key);
340 callback_list_call_attr_1(gra_priv->cbl, attr_keypress, (void *)s);
344 static LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
347 struct graphics_priv* gra_priv = (struct graphics_priv*)GetWindowLongPtr( hwnd , DWLP_USER );
357 GetClientRect( hwnd, &rc );
358 gra_priv->width = rc.right;
359 gra_priv->height = rc.bottom;
360 create_memory_dc(gra_priv);
365 switch (LOWORD(wParam))
379 GetClientRect( hwnd, &rc );
380 gra_priv->width = rc.right;
381 gra_priv->height = rc.bottom;
383 create_memory_dc(gra_priv);
384 callback_list_call_attr_2(gra_priv->cbl, attr_resize, (void *)gra_priv->width, (void *)gra_priv->height);
389 struct callback_list *cbl = (struct callback_list*)wParam;
390 #ifdef HAVE_API_WIN32_CE
391 /* FIXME: Reset the idle timer need a better place */
392 SystemIdleTimerReset();
394 callback_list_call_0(cbl);
401 gra_priv->width = LOWORD( lParam );
402 gra_priv->height = HIWORD( lParam );
403 create_memory_dc(gra_priv);
404 dbg(0, "resize gfx to: %d %d \n", gra_priv->width, gra_priv->height );
405 callback_list_call_attr_2(gra_priv->cbl, attr_resize, (void *)gra_priv->width, (void *)gra_priv->height);
409 #ifdef HAVE_API_WIN32_CE
410 if ( gra_priv && gra_priv->window.priv )
412 struct window_priv *win_priv = gra_priv->window.priv;
413 if (win_priv->hBackLight)
415 ReleasePowerRequirement(win_priv->hBackLight);
422 if ( gra_priv && gra_priv->hMemDC)
424 struct graphics_priv* overlay;
425 PAINTSTRUCT ps = { 0 };
428 dbg(1, "WM_PAINT\n");
429 overlay = gra_priv->overlays;
431 #ifndef FAST_TRANSPARENCY
432 BitBlt( gra_priv->hPrebuildDC, 0, 0, gra_priv->width , gra_priv->height, gra_priv->hMemDC, 0, 0, SRCCOPY);
434 while ( !gra_priv->disabled && overlay)
436 if ( !overlay->disabled && overlay->p.x >= 0 &&
438 overlay->p.x < gra_priv->width &&
439 overlay->p.y < gra_priv->height )
442 int destPixel, srcPixel;
444 #ifdef FAST_TRANSPARENCY
445 if ( !overlay->hPrebuildDC )
447 overlay->hPrebuildBitmap = CreateBitmap(overlay->width,overlay->height,1,1,NULL);
448 overlay->hPrebuildDC = CreateCompatibleDC(NULL);
449 overlay->hOldPrebuildBitmap = SelectBitmap( overlay->hPrebuildDC, overlay->hPrebuildBitmap);
450 SetBkColor(overlay->hMemDC,RGB(overlay->transparent_color.r >> 8,overlay->transparent_color.g >> 8,overlay->transparent_color.b >> 8));
451 BitBlt(overlay->hPrebuildDC,0,0,overlay->width,overlay->height,overlay->hMemDC,0,0,SRCCOPY);
452 BitBlt(overlay->hMemDC,0,0,overlay->width,overlay->height,overlay->hPrebuildDC,0,0,SRCINVERT);
456 const COLORREF transparent_color = RGB(overlay->transparent_color.r >> 8,overlay->transparent_color.g >> 8,overlay->transparent_color.b >> 8);
458 BitBlt( overlay->hPrebuildDC, 0, 0, overlay->width , overlay->height, overlay->hMemDC, 0, 0, SRCCOPY);
462 if (w > gra_priv->width-overlay->p.x)
463 w=gra_priv->width-overlay->p.x;
464 if (h > gra_priv->height-overlay->p.y)
465 h=gra_priv->height-overlay->p.y;
466 for ( y = 0; y < h ;y++ )
468 for ( x = 0; x < w; x++ )
470 srcPixel = y*overlay->width+x;
471 destPixel = ((overlay->p.y + y) * gra_priv->width) + (overlay->p.x + x);
472 if ( overlay->pPixelData[srcPixel] == transparent_color )
474 destPixel = ((overlay->p.y + y) * gra_priv->width) + (overlay->p.x + x);
476 gra_priv->pPixelData[destPixel] = RGB ( ((65535 - overlay->transparent_color.a) * GetRValue(gra_priv->pPixelData[destPixel]) + overlay->transparent_color.a * GetRValue(overlay->pPixelData[srcPixel])) / 65535,
477 ((65535 - overlay->transparent_color.a) * GetGValue(gra_priv->pPixelData[destPixel]) + overlay->transparent_color.a * GetGValue(overlay->pPixelData[srcPixel])) / 65535,
478 ((65535 - overlay->transparent_color.a) * GetBValue(gra_priv->pPixelData[destPixel]) + overlay->transparent_color.a * GetBValue(overlay->pPixelData[srcPixel])) / 65535);
483 gra_priv->pPixelData[destPixel] = overlay->pPixelData[srcPixel];
490 overlay = overlay->next;
494 #ifndef FAST_TRANSPARENCY
495 hdc = BeginPaint(hwnd, &ps);
496 BitBlt( hdc, 0, 0, gra_priv->width , gra_priv->height, gra_priv->hPrebuildDC, 0, 0, SRCCOPY );
498 HDC hdc = BeginPaint(hwnd, &ps);
500 BitBlt( hdc, 0, 0, gra_priv->width , gra_priv->height, gra_priv->hMemDC, 0, 0, SRCCOPY );
502 overlay = gra_priv->overlays;
503 while ( !gra_priv->disabled && overlay && !overlay->disabled )
505 if ( overlay->p.x > 0 &&
507 overlay->p.x + overlay->width < gra_priv->width &&
508 overlay->p.y + overlay->height < gra_priv->height )
510 BitBlt(hdc,overlay->p.x,overlay->p.y,overlay->width,overlay->height,overlay->hPrebuildDC,0,0,SRCAND);
511 BitBlt(hdc,overlay->p.x,overlay->p.y,overlay->width,overlay->height,overlay->hMemDC,0,0,SRCPAINT);
513 overlay = overlay->next;
517 profile(0, "WM_PAINT\n");
522 struct point pt = { LOWORD(lParam), HIWORD(lParam) };
523 callback_list_call_attr_1(gra_priv->cbl, attr_motion, (void *)&pt);
529 dbg(1, "LBUTTONDOWN\n");
530 HandleButtonClick( gra_priv, 1, 1, lParam);
535 dbg(1, "LBUTTONUP\n");
536 HandleButtonClick( gra_priv, 0, 1, lParam);
540 HandleButtonClick( gra_priv, 1, 3,lParam );
543 HandleButtonClick( gra_priv, 0, 3,lParam );
545 case WM_LBUTTONDBLCLK:
546 dbg(1, "LBUTTONDBLCLK\n");
547 HandleButtonClick( gra_priv, 1, 6,lParam );
550 HandleKeyChar( gra_priv, wParam);
553 HandleKeyDown( gra_priv, wParam);
556 dbg(0,"got WM_COPYDATA\n");
557 callback_list_call_attr_2(gra_priv->cbl, attr_wm_copydata, (void *)wParam, (void*)lParam);
559 #ifdef HAVE_API_WIN32_CE
562 HWND hwndSip = FindWindow(L"MS_SIPBUTTON", NULL);
563 // deactivate the SIP button
564 ShowWindow(hwndSip, SW_HIDE);
569 HWND hwndSip = FindWindow(L"MS_SIPBUTTON", NULL);
570 // active the SIP button
571 ShowWindow(hwndSip, SW_SHOW);
576 return DefWindowProc(hwnd, Message, wParam, lParam);
581 static int fullscreen(struct window *win, int on)
584 #ifdef HAVE_API_WIN32_CE
585 HWND hwndTaskbar = FindWindow(L"HHTaskBar", NULL);
586 HWND hwndSip = FindWindow(L"MS_SIPBUTTON", NULL);
590 ShowWindow(hwndTaskbar, SW_HIDE);
591 MoveWindow(g_hwnd, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), FALSE);
593 // deactivate the SIP button
594 ShowWindow(hwndSip, SW_HIDE);
597 ShowWindow(hwndTaskbar, SW_SHOW);
598 GetWindowRect( hwndTaskbar, &taskbar_rect);
599 MoveWindow(g_hwnd, 0, taskbar_rect.bottom, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN) - taskbar_rect.bottom, FALSE);
601 // activate the SIP button
602 ShowWindow(hwndSip, SW_SHOW);
607 ShowWindow(g_hwnd, SW_MAXIMIZE);
609 ShowWindow(g_hwnd, SW_RESTORE);
617 extern void WINAPI SystemIdleTimerReset(void);
618 static struct event_timeout *
619 event_win32_add_timeout(int timeout, int multi, struct callback *cb);
621 static void disable_suspend(struct window *win)
623 #ifdef HAVE_API_WIN32_CE
624 struct window_priv *win_priv = win->priv;
625 if ( win_priv && !win_priv->hBackLight )
627 win_priv->hBackLight = SetPowerRequirement(TEXT("BKL1:"), 0, 0x01, NULL, 0);
628 event_win32_add_timeout(29000, 1, callback_new(SystemIdleTimerReset, 0, NULL));
631 SystemIdleTimerReset();
635 static const TCHAR g_szClassName[] = {'N','A','V','G','R','A','\0'};
637 static HANDLE CreateGraphicsWindows( struct graphics_priv* gr, HMENU hMenu )
639 int wStyle = WS_VISIBLE;
641 #ifdef HAVE_API_WIN32_CE
645 wc.cbSize = sizeof(WNDCLASSEX);
649 wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
650 wc.lpfnWndProc = WndProc;
653 wc.hInstance = GetModuleHandle(NULL);
655 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
656 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
657 wc.lpszMenuName = NULL;
658 wc.lpszClassName = g_szClassName;
661 #ifdef HAVE_API_WIN32_CE
662 gr->width = GetSystemMetrics(SM_CXSCREEN);
663 gr->height = GetSystemMetrics(SM_CYSCREEN);
666 HWND hwndTaskbar = FindWindow(L"HHTaskBar", NULL);
668 GetWindowRect( hwndTaskbar, &taskbar_rect);
670 gr->height -= taskbar_rect.bottom;
677 #ifdef HAVE_API_WIN32_CE
678 if (!RegisterClass(&wc))
680 if (!RegisterClassEx(&wc))
683 dbg(0, "Window registration failed\n");
691 wStyle = WS_OVERLAPPED|WS_VISIBLE;
694 #ifdef HAVE_API_WIN32_CE
695 g_hwnd = hwnd = CreateWindow(g_szClassName,
702 gr->wnd_parent_handle,
704 GetModuleHandle(NULL),
707 g_hwnd = hwnd = CreateWindow(g_szClassName,
714 gr->wnd_parent_handle,
716 GetModuleHandle(NULL),
721 dbg(0, "Window creation failed: %d\n", GetLastError());
724 /* For Vista, we need here ChangeWindowMessageFilter(WM_COPYDATA,MSGFLT_ADD); since Win7 we need above one or ChangeWindowMessageFilterEx (MSDN), both are
725 not avail for earlier Win and not present in my mingw :(. ChangeWindowMessageFilter may not be present in later Win versions. Welcome late binding!
727 if(gr->ChangeWindowMessageFilter)
728 gr->ChangeWindowMessageFilter(WM_COPYDATA,1 /*MSGFLT_ADD*/);
729 else if(gr->ChangeWindowMessageFilterEx)
730 gr->ChangeWindowMessageFilterEx(hwnd,WM_COPYDATA,1 /*MSGFLT_ALLOW*/,NULL);
732 gr->wnd_handle = hwnd;
734 callback_list_call_attr_2(gr->cbl, attr_resize, (void *)gr->width, (void *)gr->height);
735 create_memory_dc(gr);
737 SetWindowLongPtr( hwnd , DWLP_USER, (LONG_PTR)gr );
739 ShowWindow( hwnd, SW_SHOW );
740 UpdateWindow( hwnd );
742 PostMessage( gr->wnd_parent_handle, WM_USER + 1, 0, 0 );
749 static void graphics_destroy(struct graphics_priv *gr)
755 static void gc_destroy(struct graphics_gc_priv *gc)
757 DeleteObject( gc->hpen );
758 DeleteObject( gc->hbrush );
762 static void gc_set_linewidth(struct graphics_gc_priv *gc, int w)
764 DeleteObject (gc->hpen);
766 gc->hpen = CreatePen( PS_SOLID, gc->line_width, gc->fg_color );
769 static void gc_set_dashes(struct graphics_gc_priv *gc, int width, int offset, unsigned char dash_list[], int n)
771 // gdk_gc_set_dashes(gc->gc, 0, (gint8 *)dash_list, n);
772 // gdk_gc_set_line_attributes(gc->gc, 1, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND);
776 static void gc_set_foreground(struct graphics_gc_priv *gc, struct color *c)
778 gc->fg_color = RGB( c->r >> 8, c->g >> 8, c->b >> 8);
781 DeleteObject (gc->hpen);
782 DeleteObject (gc->hbrush);
783 gc->hpen = CreatePen( PS_SOLID, gc->line_width, gc->fg_color );
784 gc->hbrush = CreateSolidBrush( gc->fg_color );
785 if ( gc->gr && c->a < 0xFFFF )
787 gc->gr->transparent_color = *c;
792 static void gc_set_background(struct graphics_gc_priv *gc, struct color *c)
794 gc->bg_color = RGB( c->r >> 8, c->g >> 8, c->b >> 8);
795 if ( gc->gr && gc->gr->hMemDC )
796 SetBkColor( gc->gr->hMemDC, gc->bg_color );
800 static struct graphics_gc_methods gc_methods =
807 NULL, //gc_set_stipple
810 static struct graphics_gc_priv *gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth)
812 struct graphics_gc_priv *gc=g_new(struct graphics_gc_priv, 1);
814 gc->hwnd = gr->wnd_handle;
816 gc->fg_color = RGB( 0,0,0 );
817 gc->bg_color = RGB( 255,255,255 );
818 gc->hpen = CreatePen( PS_SOLID, gc->line_width, gc->fg_color );
819 gc->hbrush = CreateSolidBrush( gc->fg_color );
825 static void draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
829 HPEN hpenold = SelectObject( gr->hMemDC, gc->hpen );
832 for ( i = 0; i< count; i++ )
837 MoveToEx( gr->hMemDC, p[0].x, p[0].y, NULL );
841 LineTo( gr->hMemDC, p[i].x, p[i].y );
845 SelectObject( gr->hMemDC, hpenold);
848 static void draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
850 HPEN holdpen = SelectObject( gr->hMemDC, gc->hpen );
851 HBRUSH holdbrush = SelectObject( gr->hMemDC, gc->hbrush );
852 if (sizeof(POINT) != sizeof(struct point)) {
854 POINT* points=g_alloca(sizeof(POINT)*count);
855 for ( i=0;i< count; i++ )
857 points[i].x = p[i].x;
858 points[i].y = p[i].y;
860 Polygon( gr->hMemDC, points,count );
862 Polygon( gr->hMemDC, (POINT *)p, count);
863 SelectObject( gr->hMemDC, holdbrush);
864 SelectObject( gr->hMemDC, holdpen);
868 static void draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h)
870 HPEN holdpen = SelectObject( gr->hMemDC, gc->hpen );
871 HBRUSH holdbrush = SelectObject( gr->hMemDC, gc->hbrush );
873 Rectangle(gr->hMemDC, p->x, p->y, p->x+w, p->y+h);
875 SelectObject( gr->hMemDC, holdbrush);
876 SelectObject( gr->hMemDC, holdpen);
879 static void draw_circle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int r)
881 HPEN holdpen = SelectObject( gr->hMemDC, gc->hpen );
882 HBRUSH holdbrush = SelectObject( gr->hMemDC, GetStockObject(NULL_BRUSH));
886 Ellipse( gr->hMemDC, p->x - r, p->y -r, p->x + r, p->y + r );
888 SelectObject( gr->hMemDC, holdbrush);
889 SelectObject( gr->hMemDC, holdpen);
894 static void draw_restore(struct graphics_priv *gr, struct point *p, int w, int h)
896 InvalidateRect( gr->wnd_handle, NULL, FALSE );
899 static void draw_drag(struct graphics_priv *gr, struct point *p)
906 if ( p->x < 0 || p->y < 0 ||
907 ( gr->parent && ((p->x + gr->width > gr->parent->width) || (p->y + gr->height > gr->parent->height) )))
913 gr->disabled = FALSE;
918 static void draw_mode(struct graphics_priv *gr, enum draw_mode_num mode)
920 dbg( 1, "set draw_mode to %x, %d\n", gr, (int)mode );
922 if ( mode == draw_mode_begin )
924 if ( gr->wnd_handle == NULL )
926 CreateGraphicsWindows( gr, (HMENU)ID_CHILD_GFX );
928 if ( gr->mode != draw_mode_begin )
932 dbg(1, "Erase dc: %x, w: %d, h: %d, bg_color: %x\n", gr, gr->width, gr->height, gr->bg_color);
933 #ifdef FAST_TRANSPARENCY
934 if ( gr->hPrebuildDC )
936 (void)SelectBitmap(gr->hPrebuildDC, gr->hOldPrebuildBitmap );
937 DeleteBitmap(gr->hPrebuildBitmap);
938 DeleteDC(gr->hPrebuildDC);
944 #ifdef FAST_TRANSPARENCY
945 else if ( gr->hPrebuildDC )
947 (void)SelectBitmap(gr->hPrebuildDC, gr->hOldPrebuildBitmap );
948 DeleteBitmap(gr->hPrebuildBitmap);
949 DeleteDC(gr->hPrebuildDC);
956 if (mode == draw_mode_end && gr->mode == draw_mode_begin)
958 InvalidateRect( gr->wnd_handle, NULL, FALSE );
965 static void * get_data(struct graphics_priv *this_, const char *type)
967 if ( strcmp( "wnd_parent_handle_ptr", type ) == 0 )
969 return &( this_->wnd_parent_handle );
971 if ( strcmp( "START_CLIENT", type ) == 0 )
973 CreateGraphicsWindows( this_, (HMENU)ID_CHILD_GFX );
976 if (!strcmp(type, "window"))
978 CreateGraphicsWindows( this_ , NULL);
980 this_->window.fullscreen = fullscreen;
981 this_->window.disable_suspend = disable_suspend;
983 this_->window.priv=g_new0(struct window_priv, 1);
985 return &this_->window;
991 static void background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc)
993 RECT rcClient = { 0, 0, gr->width, gr->height };
996 bgBrush = CreateSolidBrush( gc->bg_color );
997 gr->bg_color = gc->bg_color;
999 FillRect( gr->hMemDC, &rcClient, bgBrush );
1000 DeleteObject( bgBrush );
1003 struct graphics_font_priv
1010 static void draw_text(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct graphics_font_priv *font, char *text, struct point *p, int dx, int dy)
1017 GetClientRect( gr->wnd_handle, &rcClient );
1019 SetTextColor(gr->hMemDC, fg->fg_color);
1020 prevBkMode = SetBkMode( gr->hMemDC, TRANSPARENT );
1022 if ( NULL == font->hfont )
1024 #ifdef WIN_USE_SYSFONT
1025 font->hfont = (HFONT) GetStockObject (SYSTEM_FONT);
1026 GetObject (font->hfont, sizeof (LOGFONT), &font->lf);
1028 font->hfont = EzCreateFont (gr->hMemDC, TEXT ("Arial"), font->size/2, 0, 0, TRUE);
1029 GetObject ( font->hfont, sizeof (LOGFONT), &font->lf) ;
1034 angle = -atan2( dy, dx ) * 180 / 3.14159 ;
1038 SetTextAlign (gr->hMemDC, TA_BASELINE) ;
1039 SetViewportOrgEx (gr->hMemDC, p->x, p->y, NULL) ;
1040 font->lf.lfEscapement = font->lf.lfOrientation = ( angle * 10 ) ;
1041 DeleteObject (font->hfont) ;
1043 font->hfont = CreateFontIndirect (&font->lf);
1044 hOldFont = SelectObject(gr->hMemDC, font->hfont );
1047 wchar_t utf16[1024];
1048 const UTF8 *utf8 = (UTF8 *)text;
1049 UTF16 *utf16p = (UTF16 *) utf16;
1050 SetBkMode (gr->hMemDC, TRANSPARENT);
1051 if (ConvertUTF8toUTF16(&utf8, utf8+strlen(text),
1052 &utf16p, utf16p+sizeof(utf16),
1053 lenientConversion) == conversionOK)
1055 ExtTextOutW(gr->hMemDC, 0, 0, 0, NULL,
1056 utf16, (wchar_t*) utf16p - utf16, NULL);
1061 SelectObject(gr->hMemDC, hOldFont);
1062 DeleteObject (font->hfont) ;
1064 SetBkMode( gr->hMemDC, prevBkMode );
1066 SetViewportOrgEx (gr->hMemDC, 0, 0, NULL) ;
1069 static void font_destroy(struct graphics_font_priv *font)
1073 DeleteObject(font->hfont);
1078 static struct graphics_font_methods font_methods =
1083 static struct graphics_font_priv *font_new(struct graphics_priv *gr, struct graphics_font_methods *meth, char *name, int size, int flags)
1085 struct graphics_font_priv *font=g_new(struct graphics_font_priv, 1);
1086 *meth = font_methods;
1097 pngdecode(struct graphics_priv *gr, char *name, struct graphics_image_priv *img)
1099 png_struct *png_ptr = NULL;
1100 png_info *info_ptr = NULL;
1102 png_byte **row_pointers = NULL;
1113 dbg(1,"enter %s\n",name);
1114 png_file=fopen(name, "rb");
1117 dbg(1,"failed to open %s\n",name);
1122 /* read and check signature in PNG file */
1123 ret = fread (buf, 1, 8, png_file);
1130 ret = png_check_sig (buf, 8);
1137 /* create png and info structures */
1139 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
1144 return FALSE; /* out of memory */
1147 info_ptr = png_create_info_struct (png_ptr);
1151 png_destroy_read_struct (&png_ptr, NULL, NULL);
1152 return FALSE; /* out of memory */
1155 if (setjmp (png_jmpbuf(png_ptr)))
1158 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
1162 /* set up the input control for C streams */
1163 png_init_io (png_ptr, png_file);
1164 png_set_sig_bytes (png_ptr, 8); /* we already read the 8 signature bytes */
1166 /* read the file information */
1167 png_read_info (png_ptr, info_ptr);
1169 /* get size and bit-depth of the PNG-image */
1170 png_get_IHDR (png_ptr, info_ptr,
1171 (png_uint_32*)&img->width, (png_uint_32*)&img->height, &bit_depth, &color_type,
1174 /* set-up the transformations */
1176 /* transform paletted images into full-color rgb */
1177 if (color_type == PNG_COLOR_TYPE_PALETTE)
1178 png_set_palette_to_rgb(png_ptr);
1180 /* expand images to bit-depth 8 (only applicable for grayscale images) */
1181 if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA && bit_depth < 8)
1182 png_set_gray_1_2_4_to_8(png_ptr);
1184 /* Expand grayscale to rgb */
1185 if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1186 png_set_gray_to_rgb(png_ptr);
1188 /* expand colored images to bit-depth 8 */
1189 if (color_type == PNG_COLOR_TYPE_RGB && bit_depth < 8)
1190 png_set_packing(png_ptr);
1192 /* transform transparency maps into full alpha-channel */
1193 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
1194 png_set_tRNS_to_alpha(png_ptr);
1196 /* Add opaque alpha channel if no alpha channel exist */
1197 if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE)
1198 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
1200 /* Strip the pixels down to 8 bit */
1201 if (bit_depth == 16)
1202 png_set_strip_16(png_ptr);
1204 png_set_bgr(png_ptr);
1206 /* all transformations have been registered; now update info_ptr data,
1207 * get rowbytes, and allocate image memory */
1209 png_read_update_info (png_ptr, info_ptr);
1214 /* row_bytes is the width x number of channels x (bit-depth / 8) */
1215 img->row_bytes = png_get_rowbytes (png_ptr, info_ptr);
1217 memset(&pnginfo, 0, sizeof(pnginfo));
1218 pnginfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1219 pnginfo.bmiHeader.biWidth = img->width;
1220 pnginfo.bmiHeader.biHeight = -img->height;
1221 pnginfo.bmiHeader.biBitCount = 32;
1222 pnginfo.bmiHeader.biCompression = BI_RGB;
1223 pnginfo.bmiHeader.biPlanes = 1;
1224 dc = CreateCompatibleDC(NULL);
1225 img->hBitmap = CreateDIBSection(dc, &pnginfo, DIB_RGB_COLORS , (void **)&img->png_pixels, NULL, 0);
1228 if ((row_pointers = (png_byte **) g_malloc (img->height * sizeof (png_bytep))) == NULL)
1231 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
1232 g_free (img->png_pixels);
1233 img->png_pixels = NULL;
1234 img->hBitmap = NULL;
1238 /* set the individual row_pointers to point at the correct offsets */
1239 for (i = 0; i < (img->height); i++)
1240 row_pointers[i] = img->png_pixels + i * img->row_bytes;
1242 /* now we can go ahead and just read the whole image */
1243 png_read_image (png_ptr, row_pointers);
1245 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
1246 png_read_end (png_ptr, info_ptr);
1248 /* clean up after the read, and free any memory allocated - REQUIRED */
1249 png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp) NULL);
1251 if (row_pointers != (unsigned char**) NULL)
1252 g_free (row_pointers);
1253 img->hot.x=img->width/2-1;
1254 img->hot.y=img->height/2-1;
1259 } /* end of source */
1261 static void pngscale(struct graphics_image_priv *img, struct graphics_priv *gr, int width, int height)
1266 png_byte *origPixels;
1268 origBmp=img->hBitmap;
1269 origPixels=img->png_pixels;
1271 memset(&pnginfo, 0, sizeof(pnginfo));
1272 pnginfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1273 pnginfo.bmiHeader.biWidth = width;
1274 pnginfo.bmiHeader.biHeight = -height;
1275 pnginfo.bmiHeader.biBitCount = 32;
1276 pnginfo.bmiHeader.biCompression = BI_RGB;
1277 pnginfo.bmiHeader.biPlanes = 1;
1278 dc1 = CreateCompatibleDC(NULL);
1279 dc2 = CreateCompatibleDC(NULL);
1280 img->hBitmap = CreateDIBSection(dc1, &pnginfo, DIB_RGB_COLORS , (void **)&(img->png_pixels), NULL, 0);
1282 if(gr->SetStretchBltMode) {
1283 gr->SetStretchBltMode(dc1,STRETCH_HALFTONE);
1284 SetBrushOrgEx(dc1,0,0,NULL);
1287 SelectBitmap(dc1,img->hBitmap);
1288 SelectBitmap(dc2,origBmp);
1290 StretchBlt(dc1,0,0,width, height, dc2, 0,0, img->width, img->height,SRCCOPY);
1293 img->hot.x=width/2-1;
1294 img->hot.y=height/2-1;
1298 DeleteObject(origBmp);
1303 pngrender(struct graphics_image_priv *img, struct graphics_priv *gr, int x0, int y0)
1305 if (gr->AlphaBlend && img->hBitmap)
1309 BLENDFUNCTION blendFunction ;
1310 blendFunction.BlendOp = AC_SRC_OVER;
1311 blendFunction.BlendFlags = 0;
1312 blendFunction.SourceConstantAlpha = 255;
1313 blendFunction.AlphaFormat = AC_SRC_ALPHA;
1314 hdc = CreateCompatibleDC(NULL);
1315 oldBitmap = SelectBitmap(hdc, img->hBitmap);
1316 gr->AlphaBlend(gr->hMemDC, x0, y0, img->width, img->height, hdc, 0, 0, img->width, img->height, blendFunction);
1317 (void)SelectBitmap(hdc, oldBitmap);
1324 png_byte *pix_ptr = img->png_pixels;
1325 COLORREF *pixeldata;
1332 memset(&pnginfo, 0, sizeof(pnginfo));
1333 pnginfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1334 pnginfo.bmiHeader.biWidth = img->width;
1335 pnginfo.bmiHeader.biHeight = -img->height;
1336 pnginfo.bmiHeader.biBitCount = 32;
1337 pnginfo.bmiHeader.biCompression = BI_RGB;
1338 pnginfo.bmiHeader.biPlanes = 1;
1339 dc = CreateCompatibleDC(NULL);
1340 bitmap = CreateDIBSection(hdc, &pnginfo, DIB_RGB_COLORS, (void **)&pixeldata, NULL, 0);
1341 oldBitmap = SelectBitmap(dc, bitmap);
1342 BitBlt(dc, 0, 0, img->width, img->height, hdc, x0, y0, SRCCOPY);
1343 for (y=0 ; y < img->width ; y++)
1345 for (x=0 ; x < img->height ; x++)
1355 r = (r * a + ((p >> 16) & 0xff) * ai) / 255;
1356 g = (g * a + ((p >> 8) & 0xff) * ai) / 255;
1357 b = (b * a + ((p >> 0) & 0xff) * ai) / 255;
1359 *pixeldata++ = (r << 16) | (g << 8) | b;
1360 pix_ptr+=img->channels;
1364 BitBlt(hdc, x0, y0, img->width, img->height, dc, 0, 0, SRCCOPY);
1365 (void)SelectBitmap(dc, oldBitmap);
1366 DeleteBitmap(bitmap);
1372 xpmdecode(char *name, struct graphics_image_priv *img)
1374 img->pxpm = Xpm2bmp_new();
1375 if (Xpm2bmp_load( img->pxpm, name ) != 0)
1380 img->width=img->pxpm->size_x;
1381 img->height=img->pxpm->size_y;
1382 img->hot.x=img->pxpm->hotspot_x;
1383 img->hot.y=img->pxpm->hotspot_y;
1389 static struct graphics_image_priv *image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *name, int *w, int *h, struct point *hot, int rotation)
1391 struct graphics_image_priv* ret;
1393 char* hash_key = g_strdup_printf("%s_%d_%d_%d",name,*w,*h,rotation);
1395 if ( !g_hash_table_lookup_extended( gr->image_cache_hash, hash_key, NULL, (gpointer)&ret) )
1397 int len=strlen(name);
1403 dbg(2, "loading image '%s'\n", name );
1404 ret = g_new0( struct graphics_image_priv, 1 );
1406 if (!strcmp(ext,".xpm")) {
1407 rc=xpmdecode(name, ret);
1408 } else if (!strcmp(ext,".png")) {
1409 rc=pngdecode(gr, name, ret);
1413 dbg(1, "failed loading '%s'\n", name );
1418 g_hash_table_insert(gr->image_cache_hash, hash_key, (gpointer)ret );
1419 /* Hash_key will be freed ater the hash table, so set it to NULL here to disable freing it on this function return */
1426 if (*w!=ret->width || *h!=ret->height) {
1427 if(ret->png_pixels && ret->hBitmap)
1428 pngscale(ret, gr, *w, *h);
1443 static void draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img)
1446 Xpm2bmp_paint( img->pxpm , gr->hMemDC, p->x, p->y );
1447 if (img->png_pixels)
1448 pngrender(img, gr, p->x, p->y);
1451 static struct graphics_priv *
1452 graphics_win32_new_helper(struct graphics_methods *meth);
1454 static void overlay_resize(struct graphics_priv *gr, struct point *p, int w, int h, int alpha, int wraparound)
1456 dbg(1, "resize overlay: %x, x: %d, y: %d, w: %d, h: %d, alpha: %x, wraparound: %d\n", gr, p->x, p->y, w, h, alpha, wraparound);
1458 if ( gr->width != w || gr->height != h )
1462 create_memory_dc(gr);
1470 static struct graphics_priv *
1471 overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h, int alpha, int wraparound)
1473 struct graphics_priv *this=graphics_win32_new_helper(meth);
1474 dbg(1, "overlay: %x, x: %d, y: %d, w: %d, h: %d, alpha: %x, wraparound: %d\n", this, p->x, p->y, w, h, alpha, wraparound);
1481 this->hPrebuildDC = 0;
1482 this->AlphaBlend = gr->AlphaBlend;
1483 this->image_cache_hash = gr->image_cache_hash;
1485 this->next = gr->overlays;
1486 gr->overlays = this;
1487 this->wnd_handle = gr->wnd_handle;
1493 this->p.x += gr->width;
1498 this->p.y += gr->height;
1502 create_memory_dc(this);
1506 static void overlay_disable(struct graphics_priv *gr, int disable)
1508 dbg(1, "overlay: %x, disable: %d\n", gr, disable);
1509 gr->disabled = disable;
1512 static void get_text_bbox(struct graphics_priv *gr, struct graphics_font_priv *font, char *text, int dx, int dy, struct point *ret, int estimate)
1514 int len = g_utf8_strlen(text, -1);
1517 int yMax = 13*font->size/256;
1518 int xMax = 9*font->size*len/256;
1520 dbg(2, "Get bbox for %s\n", text);
1533 static struct graphics_methods graphics_methods =
1544 NULL, // draw_image_warp,
1563 static struct graphics_priv *
1564 graphics_win32_new_helper(struct graphics_methods *meth)
1566 struct graphics_priv *this_=g_new0(struct graphics_priv,1);
1567 *meth=graphics_methods;
1572 static void bind_late(struct graphics_priv* gra_priv)
1574 #if HAVE_API_WIN32_CE
1575 gra_priv->hCoreDll = LoadLibrary(TEXT("coredll.dll"));
1577 gra_priv->hCoreDll = LoadLibrary(TEXT("msimg32.dll"));
1578 gra_priv->hGdi32Dll = LoadLibrary(TEXT("gdi32.dll"));
1579 gra_priv->hUser32Dll = GetModuleHandle("user32.dll");
1581 if ( gra_priv->hCoreDll )
1583 gra_priv->AlphaBlend = (FP_AlphaBlend)GetProcAddress(gra_priv->hCoreDll, TEXT("AlphaBlend") );
1584 if (!gra_priv->AlphaBlend)
1586 dbg(1, "AlphaBlend not supported\n");
1588 #if HAVE_API_WIN32_CE
1589 gra_priv->SetStretchBltMode= (FP_SetStretchBltMode)GetProcAddress(gra_priv->hCoreDll, TEXT("SetStretchBltMode") );
1591 gra_priv->SetStretchBltMode= (FP_SetStretchBltMode)GetProcAddress(gra_priv->hGdi32Dll, TEXT("SetStretchBltMode") );
1593 if (!gra_priv->SetStretchBltMode)
1595 dbg(1, "SetStretchBltMode not supported\n");
1600 dbg(0, "Error loading coredll\n");
1603 if(gra_priv->hUser32Dll) {
1604 gra_priv->ChangeWindowMessageFilterEx=GetProcAddress(gra_priv->hUser32Dll,"ChangeWindowMessageFilterEx");
1605 gra_priv->ChangeWindowMessageFilter=GetProcAddress(gra_priv->hUser32Dll,"ChangeWindowMessageFilter");
1611 static struct graphics_priv*
1612 graphics_win32_new( struct navit *nav, struct graphics_methods *meth, struct attr **attrs, struct callback_list *cbl)
1616 struct graphics_priv* this_;
1618 if (!event_request_system("win32","graphics_win32"))
1620 this_=graphics_win32_new_helper(meth);
1623 if ((attr=attr_search(attrs, NULL, attr_w)))
1624 this_->width=attr->u.num;
1626 if ((attr=attr_search(attrs, NULL, attr_h)))
1627 this_->height=attr->u.num;
1628 this_->overlays = NULL;
1630 this_->parent = NULL;
1631 this_->window.priv = NULL;
1632 this_->image_cache_hash = g_hash_table_new(g_str_hash, g_str_equal);
1641 event_win32_main_loop_run(void)
1646 while (GetMessage(&msg, 0, 0, 0))
1648 TranslateMessage(&msg); /* Keyboard input. */
1649 DispatchMessage(&msg);
1654 static void event_win32_main_loop_quit(void)
1656 #ifdef HAVE_API_WIN32_CE
1663 #ifdef HAVE_API_WIN32_CE
1664 hwndTaskbar = FindWindow(L"HHTaskBar", NULL);
1665 hwndSip = FindWindow(L"MS_SIPBUTTON", NULL);
1666 // activate the SIP button
1667 ShowWindow(hwndSip, SW_SHOW);
1668 ShowWindow(hwndTaskbar, SW_SHOW);
1671 DestroyWindow(g_hwnd);
1674 static struct event_watch *
1675 event_win32_add_watch(void *h, enum event_watch_cond cond, struct callback *cb)
1682 event_win32_remove_watch(struct event_watch *ev)
1687 static GList *timers;
1688 struct event_timeout
1692 struct callback *cb;
1693 struct event_timeout *next;
1696 static void run_timer(UINT_PTR idEvent)
1699 struct event_timeout *t;
1704 if (t->timer_id == idEvent)
1706 struct callback *cb = t->cb;
1707 dbg(2, "Timer %d (multi: %d)\n", t->timer_id, t->multi);
1710 KillTimer(NULL, t->timer_id);
1711 timers = g_list_remove(timers, t);
1714 callback_call_0(cb);
1719 dbg(0, "timer %d not found\n", idEvent);
1722 static VOID CALLBACK win32_timer_cb(HWND hwnd, UINT uMsg,
1729 static struct event_timeout *
1730 event_win32_add_timeout(int timeout, int multi, struct callback *cb)
1732 struct event_timeout *t;
1733 t = g_new0(struct event_timeout, 1);
1737 timers = g_list_prepend(timers, t);
1739 t->timer_id = SetTimer(NULL, 0, timeout, win32_timer_cb);
1740 dbg(1, "Started timer %d for %d (multi: %d)\n", t->timer_id, timeout, multi);
1745 event_win32_remove_timeout(struct event_timeout *to)
1750 struct event_timeout *t=NULL;
1751 dbg(1, "Try stopping timer %d\n", to->timer_id);
1756 /* Use the pointer not the ID, IDs are reused */
1759 KillTimer(NULL, t->timer_id);
1760 timers = g_list_remove(timers, t);
1766 dbg(0, "Timer %d not found\n", to->timer_id);
1771 static struct event_idle *
1772 event_win32_add_idle(int priority, struct callback *cb)
1774 return (struct event_idle *)event_win32_add_timeout(1, 1, cb);
1778 event_win32_remove_idle(struct event_idle *ev)
1780 event_win32_remove_timeout((struct event_timeout *)ev);
1784 event_win32_call_callback(struct callback_list *cb)
1786 PostMessage(g_hwnd, WM_USER+2, (WPARAM)cb , (LPARAM)0);
1789 static struct event_methods event_win32_methods =
1791 event_win32_main_loop_run,
1792 event_win32_main_loop_quit,
1793 event_win32_add_watch,
1794 event_win32_remove_watch,
1795 event_win32_add_timeout,
1796 event_win32_remove_timeout,
1797 event_win32_add_idle,
1798 event_win32_remove_idle,
1799 event_win32_call_callback,
1802 static struct event_priv *
1803 event_win32_new(struct event_methods *meth)
1805 *meth=event_win32_methods;
1812 plugin_register_graphics_type("win32", graphics_win32_new);
1813 plugin_register_event_type("win32", event_win32_new);