12 #include "../stdafx.h" 13 #include "../openttd.h" 14 #include "../gfx_func.h" 15 #include "../os/windows/win32.h" 17 #include "../blitter/factory.hpp" 18 #include "../network/network.h" 19 #include "../core/math_func.hpp" 20 #include "../core/random_func.hpp" 21 #include "../texteff.hpp" 22 #include "../thread/thread.h" 23 #include "../progress.h" 24 #include "../window_gui.h" 25 #include "../window_func.h" 30 #include "../safeguards.h" 33 #ifndef MAPVK_VK_TO_CHAR 34 #define MAPVK_VK_TO_CHAR (2) 38 #define PM_QS_INPUT 0x20000 56 bool _force_full_redraw;
57 bool _window_maximize;
60 #if !defined(WINCE) || _WIN32_WCE >= 0x400 77 static void MakePalette()
79 LOGPALETTE *pal = (LOGPALETTE*)alloca(
sizeof(LOGPALETTE) + (256 - 1) *
sizeof(PALETTEENTRY));
81 pal->palVersion = 0x300;
82 pal->palNumEntries = 256;
84 for (uint i = 0; i != 256; i++) {
88 pal->palPalEntry[i].peFlags = 0;
91 _wnd.gdi_palette = CreatePalette(pal);
92 if (_wnd.gdi_palette == NULL)
usererror(
"CreatePalette failed!\n");
99 static void UpdatePalette(HDC dc, uint start, uint count)
104 for (i = 0; i != count; i++) {
105 rgb[i].rgbRed = _local_palette.
palette[start + i].r;
106 rgb[i].rgbGreen = _local_palette.
palette[start + i].g;
107 rgb[i].rgbBlue = _local_palette.
palette[start + i].b;
108 rgb[i].rgbReserved = 0;
111 SetDIBColorTable(dc, start, count, rgb);
114 bool VideoDriver_Win32::ClaimMousePointer()
116 MyShowCursor(
false,
true);
126 #define AS(x, z) {x, 0, z} 127 #define AM(x, y, z, w) {x, y - x, z} 131 AM(VK_PRIOR, VK_DOWN, WKC_PAGEUP, WKC_DOWN),
133 AM(
'A',
'Z',
'A',
'Z'),
134 AM(
'0',
'9',
'0',
'9'),
136 AS(VK_ESCAPE, WKC_ESC),
137 AS(VK_PAUSE, WKC_PAUSE),
138 AS(VK_BACK, WKC_BACKSPACE),
139 AM(VK_INSERT, VK_DELETE, WKC_INSERT, WKC_DELETE),
141 AS(VK_SPACE, WKC_SPACE),
142 AS(VK_RETURN, WKC_RETURN),
146 AM(VK_F1, VK_F12, WKC_F1, WKC_F12),
149 AM(VK_NUMPAD0, VK_NUMPAD9,
'0',
'9'),
150 AS(VK_DIVIDE, WKC_NUM_DIV),
151 AS(VK_MULTIPLY, WKC_NUM_MUL),
152 AS(VK_SUBTRACT, WKC_NUM_MINUS),
153 AS(VK_ADD, WKC_NUM_PLUS),
154 AS(VK_DECIMAL, WKC_NUM_DECIMAL),
170 static uint MapWindowsKey(uint sym)
175 for (map = _vk_mapping; map !=
endof(_vk_mapping); ++map) {
176 if ((uint)(sym - map->vk_from) <= map->vk_count) {
177 key = sym - map->vk_from + map->map_to;
182 if (GetAsyncKeyState(VK_SHIFT) < 0) key |= WKC_SHIFT;
183 if (GetAsyncKeyState(VK_CONTROL) < 0) key |= WKC_CTRL;
184 if (GetAsyncKeyState(VK_MENU) < 0) key |= WKC_ALT;
188 static bool AllocateDibSection(
int w,
int h,
bool force =
false);
190 static void ClientSizeChanged(
int w,
int h)
193 if (AllocateDibSection(w, h)) {
208 int RedrawScreenDebug()
213 HPALETTE old_palette;
217 dc = GetDC(_wnd.main_wnd);
218 dc2 = CreateCompatibleDC(dc);
220 old_bmp = (HBITMAP)SelectObject(dc2, _wnd.dib_sect);
221 old_palette = SelectPalette(dc, _wnd.gdi_palette, FALSE);
222 BitBlt(dc, 0, 0, _wnd.width, _wnd.height, dc2, 0, 0, SRCCOPY);
223 SelectPalette(dc, old_palette, TRUE);
224 SelectObject(dc2, old_bmp);
226 ReleaseDC(_wnd.main_wnd, dc);
233 #if !defined(WM_MOUSELEAVE) 234 #define WM_MOUSELEAVE 0x02A3 236 #define TID_POLLMOUSE 1 237 #define MOUSE_POLL_DELAY 75 239 static void CALLBACK TrackMouseTimerProc(HWND hwnd, UINT msg, UINT event, DWORD time)
247 GetClientRect(hwnd, &rc);
248 MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT)(LPRECT)&rc, 2);
251 if (!PtInRect(&rc, pt) || (WindowFromPoint(pt) != hwnd)) {
252 KillTimer(hwnd, event);
253 PostMessage(hwnd, WM_MOUSELEAVE, 0, 0L);
264 _fullscreen = full_screen;
267 if ((full_screen || _wnd.fullscreen) && _wnd.main_wnd) {
268 DestroyWindow(_wnd.main_wnd);
278 memset(&settings, 0,
sizeof(settings));
279 settings.dmSize =
sizeof(settings);
284 (_display_hz != 0 ? DM_DISPLAYFREQUENCY : 0);
286 settings.dmPelsWidth = _wnd.width_org;
287 settings.dmPelsHeight = _wnd.height_org;
288 settings.dmDisplayFrequency = _display_hz;
291 if (settings.dmBitsPerPel == 8 &&
292 (_support8bpp !=
S8BPP_HARDWARE || ChangeDisplaySettings(&settings, CDS_FULLSCREEN | CDS_TEST) != DISP_CHANGE_SUCCESSFUL)) {
293 settings.dmBitsPerPel = 32;
297 if (ChangeDisplaySettings(&settings, CDS_FULLSCREEN | CDS_TEST) != DISP_CHANGE_SUCCESSFUL) {
299 GetWindowRect(GetDesktopWindow(), &r);
302 if ((
int)settings.dmPelsWidth != r.right - r.left || (
int)settings.dmPelsHeight != r.bottom - r.top) {
307 if (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
311 }
else if (_wnd.fullscreen) {
313 ChangeDisplaySettings(NULL, 0);
315 _wnd.width = _bck_resolution.width;
316 _wnd.height = _bck_resolution.height;
322 DWORD style, showstyle;
325 showstyle = SW_SHOWNORMAL;
326 _wnd.fullscreen = full_screen;
327 if (_wnd.fullscreen) {
329 SetRect(&r, 0, 0, _wnd.width_org, _wnd.height_org);
331 style = WS_OVERLAPPEDWINDOW;
333 if (_window_maximize) showstyle = SW_SHOWMAXIMIZED;
334 SetRect(&r, 0, 0, _wnd.width, _wnd.height);
338 AdjustWindowRect(&r, style, FALSE);
340 w = r.right - r.left;
341 h = r.bottom - r.top;
343 if (_wnd.main_wnd != NULL) {
344 if (!_window_maximize) SetWindowPos(_wnd.main_wnd, 0, 0, 0, w, h, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
346 TCHAR Windowtitle[50];
347 int x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
348 int y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
350 _sntprintf(Windowtitle,
lengthof(Windowtitle), _T(
"OpenTTD %s"), MB_TO_WIDE(_openttd_revision));
352 _wnd.main_wnd = CreateWindow(_T(
"OTTD"), Windowtitle, style, x, y, w, h, 0, 0, GetModuleHandle(NULL), 0);
353 if (_wnd.main_wnd == NULL)
usererror(
"CreateWindow failed");
354 ShowWindow(_wnd.main_wnd, showstyle);
367 HDC dc2 = CreateCompatibleDC(dc);
368 HBITMAP old_bmp = (HBITMAP)SelectObject(dc2, _wnd.dib_sect);
369 HPALETTE old_palette = SelectPalette(dc, _wnd.gdi_palette, FALSE);
392 BitBlt(dc, 0, 0, _wnd.width, _wnd.height, dc2, 0, 0, SRCCOPY);
393 SelectPalette(dc, old_palette, TRUE);
394 SelectObject(dc2, old_bmp);
398 static void PaintWindowThread(
void *)
410 ClientToScreen(_wnd.main_wnd, &pt);
411 OffsetRect(&_wnd.update_rect, pt.x, pt.y);
415 HRGN rgn = CreateRectRgnIndirect(&_wnd.update_rect);
416 HDC dc = GetDCEx(_wnd.main_wnd, rgn, DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_INTERSECTRGN);
421 SetRectEmpty(&_wnd.update_rect);
422 ReleaseDC(_wnd.main_wnd, dc);
431 _draw_thread->
Exit();
437 #if !defined(UNICODE) 438 static char prev_char = 0;
440 char input[2] = {(char)charcode, 0};
443 if (prev_char != 0) {
445 input[0] = prev_char;
446 input[1] = (char)charcode;
448 }
else if (IsDBCSLeadByte(charcode)) {
450 prev_char = charcode;
456 int len = MultiByteToWideChar(CP_ACP, 0, input, input_len, w, 2);
467 DEBUG(driver, 1,
"Invalid DBCS character sequence encountered, dropping input");
472 static WChar prev_char = 0;
476 if (prev_char != 0)
DEBUG(driver, 1,
"Got two UTF-16 lead surrogates, dropping the first one");
477 prev_char = charcode;
482 if (prev_char != 0) {
486 DEBUG(driver, 1,
"Got an UTF-16 lead surrogate without a trail surrogate, dropping the lead surrogate");
497 #if !defined(WINCE) || _WIN32_WCE >= 0x400 501 return (_imm_props & IME_PROP_AT_CARET) && !(_imm_props & IME_PROP_SPECIAL_UI);
507 HIMC hIMC = ImmGetContext(hwnd);
510 cf.dwStyle = CFS_POINT;
515 cf.ptCurrentPos.x = _focused_window->
left + pt.x;
516 cf.ptCurrentPos.y = _focused_window->
top + pt.y;
518 cf.ptCurrentPos.x = 0;
519 cf.ptCurrentPos.y = 0;
521 ImmSetCompositionWindow(hIMC, &cf);
523 ImmReleaseContext(hwnd, hIMC);
529 HIMC hIMC = ImmGetContext(hwnd);
533 cf.dwStyle = CFS_EXCLUDE;
537 cf.ptCurrentPos.x = _focused_window->
left + pt.x;
538 cf.ptCurrentPos.y = _focused_window->
top + pt.y;
540 cf.rcArea.left = _focused_window->
left;
541 cf.rcArea.top = _focused_window->
top;
542 cf.rcArea.right = _focused_window->
left + _focused_window->
width;
543 cf.rcArea.bottom = _focused_window->
top + _focused_window->
height;
551 cf.ptCurrentPos.x = 0;
552 cf.ptCurrentPos.y = 0;
553 SetRectEmpty(&cf.rcArea);
555 ImmSetCandidateWindow(hIMC, &cf);
557 ImmReleaseContext(hwnd, hIMC);
563 HIMC hIMC = ImmGetContext(hwnd);
566 if (lParam & GCS_RESULTSTR) {
568 LONG len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);
569 TCHAR *str = (TCHAR *)_alloca(len +
sizeof(TCHAR));
570 len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, str, len);
571 str[len /
sizeof(TCHAR)] =
'\0';
581 lParam &= ~(GCS_RESULTSTR | GCS_RESULTCLAUSE | GCS_RESULTREADCLAUSE | GCS_RESULTREADSTR);
586 LONG len = ImmGetCompositionString(hIMC, GCS_COMPSTR, NULL, 0);
587 TCHAR *str = (TCHAR *)_alloca(len +
sizeof(TCHAR));
588 len = ImmGetCompositionString(hIMC, GCS_COMPSTR, str, len);
589 str[len /
sizeof(TCHAR)] =
'\0';
592 static char utf8_buf[1024];
596 LONG caret_bytes = ImmGetCompositionString(hIMC, GCS_CURSORPOS, NULL, 0);
597 const char *caret = utf8_buf;
598 for (
const TCHAR *c = str; *c !=
'\0' && *caret !=
'\0' && caret_bytes > 0; c++, caret_bytes--) {
603 if (IsDBCSLeadByte(*c)) {
616 lParam &= ~(GCS_COMPSTR | GCS_COMPATTR | GCS_COMPCLAUSE | GCS_CURSORPOS | GCS_DELTASTART);
619 ImmReleaseContext(hwnd, hIMC);
621 return lParam != 0 ? DefWindowProc(hwnd, WM_IME_COMPOSITION, wParam, lParam) : 0;
627 HIMC hIMC = ImmGetContext(hwnd);
628 if (hIMC != NULL) ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
629 ImmReleaseContext(hwnd, hIMC);
643 static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
645 static uint32 keycode = 0;
646 static bool console =
false;
647 static bool in_sizemove =
false;
651 SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
653 #if !defined(WINCE) || _WIN32_WCE >= 0x400 658 case WM_ENTERSIZEMOVE:
662 case WM_EXITSIZEMOVE:
670 GetUpdateRect(hwnd, &r, FALSE);
671 UnionRect(&_wnd.update_rect, &_wnd.update_rect, &r);
674 ValidateRect(hwnd, NULL);
679 BeginPaint(hwnd, &ps);
685 case WM_PALETTECHANGED:
686 if ((HWND)wParam == hwnd)
return 0;
689 case WM_QUERYNEWPALETTE: {
690 HDC hDC = GetWindowDC(hwnd);
691 HPALETTE hOldPalette = SelectPalette(hDC, _wnd.gdi_palette, FALSE);
692 UINT nChanged = RealizePalette(hDC);
694 SelectPalette(hDC, hOldPalette, TRUE);
695 ReleaseDC(hwnd, hDC);
696 if (nChanged != 0) InvalidateRect(hwnd, NULL, FALSE);
701 HandleExitGameRequest();
742 int x = (int16)LOWORD(lParam);
743 int y = (int16)HIWORD(lParam);
750 SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
757 while (PeekMessage(&m, hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE | PM_NOYIELD | PM_QS_INPUT)) {
758 x = (int16)LOWORD(m.lParam);
759 y = (int16)HIWORD(m.lParam);
765 pt.x = _cursor.
pos.x;
766 pt.y = _cursor.
pos.y;
767 ClientToScreen(hwnd, &pt);
768 SetCursorPos(pt.x, pt.y);
775 #if !defined(WINCE) || _WIN32_WCE >= 0x400 776 case WM_INPUTLANGCHANGE:
780 case WM_IME_SETCONTEXT:
785 case WM_IME_STARTCOMPOSITION:
790 case WM_IME_COMPOSITION:
793 case WM_IME_ENDCOMPOSITION:
803 #if !defined(UNICODE) 805 if (
GB(wParam, 8, 8) != 0) {
815 console =
GB(lParam, 16, 8) == 41;
819 uint scancode =
GB(lParam, 16, 8);
820 uint charcode = wParam;
824 if (console && scancode == 41) {
831 uint cur_keycode = keycode;
839 uint scancode =
GB(lParam, 16, 8);
840 keycode = scancode == 41 ? (uint)WKC_BACKQUOTE : MapWindowsKey(wParam);
844 if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
845 if ((msg.message == WM_CHAR || msg.message == WM_DEADCHAR) &&
GB(lParam, 16, 8) ==
GB(msg.lParam, 16, 8)) {
850 uint charcode = MapVirtualKey(wParam, MAPVK_VK_TO_CHAR);
859 if (
HasBit(charcode, 31) && !console) {
860 if (scancode == 41) {
869 uint cur_keycode = keycode;
879 ToggleFullScreen(!_wnd.fullscreen);
896 if (wParam != SIZE_MINIMIZED) {
899 _window_maximize = (wParam == SIZE_MAXIMIZED || (_window_maximize && _fullscreen));
900 if (_window_maximize || _fullscreen) _bck_resolution =
_cur_resolution;
901 ClientSizeChanged(LOWORD(lParam), HIWORD(lParam));
907 RECT *r = (RECT*)lParam;
911 SetRect(&r2, 0, 0, 0, 0);
912 AdjustWindowRect(&r2, GetWindowLong(hwnd, GWL_STYLE), FALSE);
914 w = r->right - r->left - (r2.right - r2.left);
915 h = r->bottom - r->top - (r2.bottom - r2.top);
918 SetRect(&r2, 0, 0, w, h);
920 AdjustWindowRect(&r2, GetWindowLong(hwnd, GWL_STYLE), FALSE);
921 w = r2.right - r2.left;
922 h = r2.bottom - r2.top;
926 r->bottom = r->top + h;
929 case WMSZ_BOTTOMLEFT:
930 r->bottom = r->top + h;
931 r->left = r->right - w;
934 case WMSZ_BOTTOMRIGHT:
935 r->bottom = r->top + h;
936 r->right = r->left + w;
940 r->left = r->right - w;
944 r->right = r->left + w;
948 r->top = r->bottom - h;
952 r->top = r->bottom - h;
953 r->left = r->right - w;
957 r->top = r->bottom - h;
958 r->right = r->left + w;
966 #if !defined(WM_MOUSEWHEEL) 967 # define WM_MOUSEWHEEL 0x020A 969 #if !defined(GET_WHEEL_DELTA_WPARAM) 970 # define GET_WHEEL_DELTA_WPARAM(wparam) ((short)HIWORD(wparam)) 973 case WM_MOUSEWHEEL: {
974 int delta = GET_WHEEL_DELTA_WPARAM(wParam);
978 }
else if (delta > 0) {
986 _wnd.has_focus =
true;
991 _wnd.has_focus =
false;
997 if (_exit_game)
break;
999 bool active = (LOWORD(wParam) != WA_INACTIVE);
1000 bool minimized = (HIWORD(wParam) != 0);
1001 if (_wnd.fullscreen) {
1002 if (active && minimized) {
1004 ShowWindow(hwnd, SW_RESTORE);
1006 }
else if (!active && !minimized) {
1008 ShowWindow(hwnd, SW_MINIMIZE);
1009 ChangeDisplaySettings(NULL, 0);
1017 return DefWindowProc(hwnd, msg, wParam, lParam);
1020 static void RegisterWndClass()
1022 static bool registered =
false;
1025 HINSTANCE hinst = GetModuleHandle(NULL);
1032 LoadIcon(hinst, MAKEINTRESOURCE(100)),
1033 LoadCursor(NULL, IDC_ARROW),
1040 if (!RegisterClass(&wnd))
usererror(
"RegisterClass failed");
1044 static bool AllocateDibSection(
int w,
int h,
bool force)
1053 if (bpp == 0)
usererror(
"Can't use a blitter that blits 0 bpp for normal visuals");
1055 if (!force && w == _screen.width && h == _screen.height)
return false;
1057 bi = (BITMAPINFO*)alloca(
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * 256);
1058 memset(bi, 0,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * 256);
1059 bi->bmiHeader.biSize =
sizeof(BITMAPINFOHEADER);
1061 bi->bmiHeader.biWidth = _wnd.width = w;
1062 bi->bmiHeader.biHeight = -(_wnd.height = h);
1064 bi->bmiHeader.biPlanes = 1;
1066 bi->bmiHeader.biCompression = BI_RGB;
1068 if (_wnd.dib_sect) DeleteObject(_wnd.dib_sect);
1071 _wnd.dib_sect = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (VOID**)&_wnd.buffer_bits, NULL, 0);
1072 if (_wnd.dib_sect == NULL)
usererror(
"CreateDIBSection failed");
1076 _screen.pitch = (bpp == 8) ?
Align(w, 4) : w;
1078 _screen.dst_ptr = _wnd.buffer_bits;
1083 static const Dimension default_resolutions[] = {
1097 static void FindResolutions()
1113 for (i = 0; EnumDisplaySettingsA(NULL, i, &dm) != 0; i++) {
1114 if (dm.dmBitsPerPel == bpp &&
1115 dm.dmPelsWidth >= 640 && dm.dmPelsHeight >= 480) {
1118 for (j = 0; j < n; j++) {
1137 memcpy(
_resolutions, default_resolutions,
sizeof(default_resolutions));
1149 memset(&_wnd, 0,
sizeof(_wnd));
1175 DeleteObject(_wnd.gdi_palette);
1176 DeleteObject(_wnd.dib_sect);
1177 DestroyWindow(_wnd.main_wnd);
1180 if (_wnd.fullscreen) ChangeDisplaySettings(NULL, 0);
1187 RECT r = { left, top, left + width, top + height };
1189 InvalidateRect(_wnd.main_wnd, &r, FALSE);
1192 static void CheckPaletteAnim()
1197 InvalidateRect(_wnd.main_wnd, NULL, FALSE);
1203 uint32 cur_ticks = GetTickCount();
1204 uint32 last_cur_ticks = cur_ticks;
1225 DEBUG(driver, 1,
"Threaded drawing enabled");
1233 _wnd.running =
true;
1237 uint32 prev_cur_ticks = cur_ticks;
1239 while (PeekMessage(&mesg, NULL, 0, 0, PM_REMOVE)) {
1240 InteractiveRandom();
1243 DispatchMessage(&mesg);
1245 if (_exit_game)
return;
1248 if (_wnd.has_focus && GetAsyncKeyState(VK_SHIFT) < 0 &&
1251 if (_wnd.has_focus && GetAsyncKeyState(VK_TAB) < 0 && GetAsyncKeyState(VK_MENU) >= 0 &&
1255 }
else if (_fast_forward & 2) {
1259 cur_ticks = GetTickCount();
1260 if (cur_ticks >= next_tick || (_fast_forward && !
_pause_mode) || cur_ticks < prev_cur_ticks) {
1262 last_cur_ticks = cur_ticks;
1267 _ctrl_pressed = _wnd.has_focus && GetAsyncKeyState(VK_CONTROL)<0;
1271 if (_wnd.has_focus) {
1273 (GetAsyncKeyState(VK_LEFT) < 0 ? 1 : 0) +
1274 (GetAsyncKeyState(VK_UP) < 0 ? 2 : 0) +
1275 (GetAsyncKeyState(VK_RIGHT) < 0 ? 4 : 0) +
1276 (GetAsyncKeyState(VK_DOWN) < 0 ? 8 : 0);
1320 _draw_thread->
Join();
1331 if (_window_maximize) ShowWindow(_wnd.main_wnd, SW_SHOWNORMAL);
1333 _wnd.width = _wnd.width_org = w;
1334 _wnd.height = _wnd.height_org = h;
1337 if (_draw_mutex != NULL) _draw_mutex->
EndCritical(
true);
1345 if (_draw_mutex != NULL) _draw_mutex->
EndCritical(
true);
1351 return AllocateDibSection(_screen.width, _screen.height,
true) && this->
MakeWindow(_fullscreen);
1361 if (_draw_mutex != NULL) _draw_mutex->
EndCritical(
true);
1370 if (_draw_mutex != NULL) _draw_mutex->
EndCritical(
true);
static LRESULT HandleCharMsg(uint keycode, WChar charcode)
Forward key presses to the window system.
const char * GetDriverParam(const char *const *parm, const char *name)
Get a string parameter the list of parameters.
void HandleTextInput(const char *str, bool marked=false, const char *caret=NULL, const char *insert_location=NULL, const char *replacement_end=NULL)
Handle text input.
static bool _draw_threaded
Whether the drawing is/may be done in a separate thread.
bool _networking
are we in networking mode?
void MainLoop()
Perform the actual drawing.
uint32 _realtime_tick
The real time in the game.
const NWidgetCore * nested_focus
Currently focused nested widget, or NULL if no nested widget has focus.
Point pos
logical mouse position
const char * FS2OTTD(const TCHAR *name)
Convert to OpenTTD's encoding from that of the local environment.
Information about the currently used palette.
static HANDLE _draw_thread_initialized
Event that is signaled when the drawing thread has finished initializing.
int left
x position of left edge of the window
The factory for Windows' video driver.
bool ChangeResolution(int w, int h)
Change the resolution of the window.
bool _right_button_down
Is right mouse button pressed?
Colour palette[256]
Current palette. Entry 0 has to be always fully transparent!
int top
y position of top edge of the window
Dimension _cur_resolution
The current resolution.
int _num_resolutions
The number of resolutions.
static volatile bool _draw_continue
Should we keep continue drawing?
How all blitters should look like.
char * convert_from_fs(const TCHAR *name, char *utf8_buf, size_t buflen)
Convert to OpenTTD's encoding from that of the environment in UNICODE.
static T max(const T a, const T b)
Returns the maximum of two values.
virtual void EndCritical(bool allow_recursive=false)=0
End of the critical section.
virtual void PostResize()
Post resize event.
Palette animation should be done by video backend (8bpp only!)
virtual void SendSignal()=0
Send a signal and wake the 'thread' that was waiting for it.
bool _left_button_clicked
Is left mouse button clicked?
bool _ctrl_pressed
Is Ctrl pressed?
bool ToggleFullscreen(bool fullscreen)
Change the full screen setting.
bool _right_button_clicked
Is right mouse button clicked?
static T Align(const T x, uint n)
Return the smallest multiple of n equal or greater than x.
The blitter takes care of the palette animation.
virtual void PaletteAnimate(const Palette &palette)=0
Called when the 8bpp palette is changed; you should redraw all pixels on the screen that are equal to...
bool _left_button_down
Is left mouse button pressed?
void GetKeyboardLayout()
Retrieve keyboard layout from language string or (if set) config file.
static bool DrawIMECompositionString()
Should we draw the composition string ourself, i.e is this a normal IME?
void CDECL usererror(const char *s,...)
Error handling for fatal user errors.
int wheel
mouse wheel movement
bool UpdateCursorPosition(int x, int y, bool queued_warp)
Update cursor position on mouse movement.
static const uint MILLISECONDS_PER_TICK
The number of milliseconds per game tick.
static ThreadMutex * New()
Create a new mutex.
void HandleKeypress(uint keycode, WChar key)
Handle keyboard input.
byte _dirkeys
1 = left, 2 = up, 4 = right, 8 = down
static ThreadObject * _draw_thread
Thread used to 'draw' to the screen, i.e.
bool fix_at
mouse is moving, but cursor is not (used for scrolling)
void HandleMouseEvents()
Handle a mouse event from the video driver.
#define lengthof(x)
Return the length of an fixed size array.
PauseModeByte _pause_mode
The current pause mode.
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
int first_dirty
The first dirty element.
bool AfterBlitterChange()
Callback invoked after the blitter was changed.
static WChar Utf16DecodeSurrogate(uint lead, uint trail)
Convert an UTF-16 surrogate pair to the corresponding Unicode character.
Palette _cur_palette
Current palette.
bool _shift_pressed
Is Shift pressed?
#define DEBUG(name, level,...)
Output a line of debugging information.
Dimension _resolutions[32]
List of resolutions.
virtual Blitter::PaletteAnimation UsePaletteAnimation()=0
Check if the blitter uses palette animation at all.
static void PaintWindow(HDC dc)
Do palette animation and blit to the window.
void Stop()
Stop this driver.
The video driver for windows.
const char * Start(const char *const *param)
Start this driver.
static bool Utf16IsTrailSurrogate(uint c)
Is the given character a lead surrogate code point?
void AcquireBlitterLock()
Acquire any lock(s) required to be held when changing blitters.
void HandleCtrlChanged()
State of CONTROL key has changed.
virtual void Join()=0
Join this thread.
void EditBoxLostFocus()
An edit box lost the input focus.
bool EditBoxInGlobalFocus()
Check if an edit box is in global focus.
Base of the Windows video driver.
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam)
Handle WM_IME_COMPOSITION messages.
void MakeDirty(int left, int top, int width, int height)
Mark a particular area dirty.
static void SetCandidatePos(HWND hwnd)
Set the position of the candidate window.
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
void NetworkDrawChatMessage()
Draw the chat message-box.
static Palette _local_palette
Local copy of the palette for use in the drawing thread.
#define endof(x)
Get the end element of an fixed size array.
bool in_window
mouse inside this window, determines drawing logic
void ReleaseBlitterLock()
Release any lock(s) required to be held when changing blitters.
bool MakeWindow(bool full_screen)
Instantiate a new window.
Coordinates of a point in 2D.
virtual void WaitForSignal()=0
Wait for a signal to be send.
virtual uint8 GetScreenDepth()=0
Get the screen depth this blitter works for.
#define AS(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview)
AirportSpec definition for airports with at least one depot.
uint GetCPUCoreCount()
Get number of processor cores in the system, including HyperThreading or similar. ...
static bool Utf16IsLeadSurrogate(uint c)
Is the given character a lead surrogate code point?
void GameSizeChanged()
Size of the application screen changed.
int width
width of the window (number of pixels to the right in x direction)
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
WindowClass window_class
Window class.
virtual void BeginCritical(bool allow_recursive=false)=0
Begin the critical section.
virtual bool Exit()=0
Exit this thread.
int count_dirty
The number of dirty elements.
static void CancelIMEComposition(HWND hwnd)
Clear the current composition string.
virtual Point GetCaretPosition() const
Get the current caret position if an edit box has the focus.
uint32 WChar
Type for wide characters, i.e.
static ThreadMutex * _draw_mutex
Mutex to keep the access to the shared memory controlled.
A Thread Object which works on all our supported OSes.
static bool New(OTTDThreadFunc proc, void *param, ThreadObject **thread=NULL, const char *name=NULL)
Create a thread; proc will be called as first function inside the thread, with optional params...
static void SetCompositionPos(HWND hwnd)
Set position of the composition window to the caret position.
Dimensions (a width and height) of a rectangle in 2D.
Full 8bpp support by OS and hardware.
static bool HasModalProgress()
Check if we are currently in a modal progress state.
int height
Height of the window (number of pixels down in y direction)
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
void UpdateWindows()
Update the continuously changing contents of the windows, such as the viewports.