17# define _WIN32_IE 0x0501
24#include <shellscalingapi.h>
45#ifdef WITH_OPENGL_BACKEND
48#ifdef WITH_VULKAN_BACKEND
61# define VK_SEMICOLON 0xBA
64# define VK_PERIOD 0xBE
70# define VK_BACK_QUOTE 0xC0
76# define VK_BACK_SLASH 0xDC
79# define VK_EQUALS 0xBB
81#ifndef VK_OPEN_BRACKET
82# define VK_OPEN_BRACKET 0xDB
84#ifndef VK_CLOSE_BRACKET
85# define VK_CLOSE_BRACKET 0xDD
88# define VK_GR_LESS 0xE2
101#define BROKEN_PEEK_TOUCHPAD
134#ifdef WITH_INPUT_NDOF
135# define DEVICE_COUNT 2
137# define DEVICE_COUNT 1
141 memset(devices, 0,
DEVICE_COUNT *
sizeof(RAWINPUTDEVICE));
145 devices[0].usUsagePage = 0x01;
146 devices[0].usUsage = 0x06;
148#ifdef WITH_INPUT_NDOF
150 devices[1].usUsagePage = 0x01;
151 devices[1].usUsage = 0x08;
154 if (RegisterRawInputDevices(devices,
DEVICE_COUNT,
sizeof(RAWINPUTDEVICE))) {
158 GHOST_PRINTF(
"could not register for RawInput: %d\n",
int(GetLastError()));
171 SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
175 SetCurrentProcessExplicitAppUserModelID(BLENDER_WIN_APPID_16);
185#ifdef WITH_INPUT_NDOF
207 __int64 delta = perf_ticks * 1000;
217 return ::GetTickCount64();
222 ::QueryPerformanceCounter((LARGE_INTEGER *)&
count);
235 int64_t t_delta = GetMessageTime() - GetTickCount();
248 return ::GetSystemMetrics(SM_CMONITORS);
253 width = ::GetSystemMetrics(SM_CXSCREEN);
254 height = ::GetSystemMetrics(SM_CYSCREEN);
259 width = ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
260 height = ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
271 const bool is_dialog,
294 GHOST_PRINT(
"GHOST_SystemWin32::createWindow(): window invalid\n");
313#ifdef WITH_VULKAN_BACKEND
314 case GHOST_kDrawingContextTypeVulkan: {
317 if (context->initializeDrawingContext()) {
325#ifdef WITH_OPENGL_BACKEND
326 case GHOST_kDrawingContextTypeOpenGL: {
329 HWND wnd = CreateWindowA(
"STATIC",
331 WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
338 GetModuleHandle(
nullptr),
341 HDC mHDC = GetDC(wnd);
342 HDC prev_hdc = wglGetCurrentDC();
343 HGLRC prev_context = wglGetCurrentContext();
345 for (
int minor = 6; minor >= 3; --minor) {
347 context_params_offscreen,
351 WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
354 (context_params_offscreen.
is_debug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
357 if (context->initializeDrawingContext()) {
358 wglMakeCurrent(prev_hdc, prev_context);
363 wglMakeCurrent(prev_hdc, prev_context);
394 HWND wnd = CreateWindowA(
"STATIC",
396 WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
403 GetModuleHandle(
nullptr),
407 if (context->initializeDrawingContext()) {
424 bool hasEventHandled =
false;
429 if (waitForEvent && !::PeekMessage(&msg,
nullptr, 0, 0, PM_NOREMOVE)) {
439 else if (maxSleep >= 0.0) {
440 ::SetTimer(
nullptr, 0, maxSleep,
nullptr);
442 ::KillTimer(
nullptr, 0);
448 hasEventHandled =
true;
454 while (::PeekMessageW(&msg,
nullptr, 0, 0, PM_REMOVE) != 0) {
457 ::TranslateMessage(&msg);
458 ::DispatchMessageW(&msg);
459 hasEventHandled =
true;
469 }
while (waitForEvent && !hasEventHandled);
471 return hasEventHandled;
477 if (::GetCursorPos(&point)) {
487 if (!::GetActiveWindow()) {
496 if (!GetCursorPos(&point)) {
500 HDC dc = GetDC(NULL);
505 COLORREF color = GetPixel(dc, point.x, point.y);
508 if (color == CLR_INVALID) {
512 r_color[0] = GetRValue(color) / 255.0f;
513 r_color[1] = GetGValue(color) / 255.0f;
514 r_color[2] = GetBValue(color) / 255.0f;
523 if (RegOpenKeyEx(HKEY_CURRENT_USER,
"Control Panel\\Cursors", 0, KEY_READ, &hKey) ==
526 DWORD cursorSizeSetting;
527 DWORD setting_size =
sizeof(cursorSizeSetting);
528 if (RegQueryValueEx(hKey,
532 reinterpret_cast<BYTE *
>(&cursorSizeSetting),
533 &setting_size) == ERROR_SUCCESS &&
534 setting_size ==
sizeof(cursorSizeSetting))
536 size = cursorSizeSetting;
542 size = GetSystemMetrics(SM_CXCURSOR);
557 if (!GetCursorPos(&point)) {
561 HWND win = WindowFromPoint(point);
566 return window_manager_->getWindowAssociatedWithOSWindow((
const void *)win);
574 bool down = HIBYTE(::GetAsyncKeyState(VK_LSHIFT)) != 0;
576 down = HIBYTE(::GetAsyncKeyState(VK_RSHIFT)) != 0;
579 down = HIBYTE(::GetAsyncKeyState(VK_LMENU)) != 0;
581 down = HIBYTE(::GetAsyncKeyState(VK_RMENU)) != 0;
584 down = HIBYTE(::GetAsyncKeyState(VK_LCONTROL)) != 0;
586 down = HIBYTE(::GetAsyncKeyState(VK_RCONTROL)) != 0;
589 down = HIBYTE(::GetAsyncKeyState(VK_LWIN)) != 0;
591 down = HIBYTE(::GetAsyncKeyState(VK_RWIN)) != 0;
602 bool swapped = ::GetSystemMetrics(SM_SWAPBUTTON) == TRUE;
604 bool down = HIBYTE(::GetAsyncKeyState(VK_LBUTTON)) != 0;
607 down = HIBYTE(::GetAsyncKeyState(VK_MBUTTON)) != 0;
610 down = HIBYTE(::GetAsyncKeyState(VK_RBUTTON)) != 0;
633 InitCommonControls();
636 SetProcessDPIAware();
644 wc.style = CS_HREDRAW | CS_VREDRAW;
648 wc.hInstance = ::GetModuleHandle(0);
649 wc.hIcon = ::LoadIcon(wc.hInstance,
"APPICON");
652 ::LoadIcon(
nullptr, IDI_APPLICATION);
654 wc.hCursor = ::LoadCursor(0, IDC_ARROW);
655 wc.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
657 wc.lpszClassName =
L"GHOST_WindowClass";
660 if (::RegisterClassW(&wc) == 0) {
672 ::UnregisterClassW(
L"GHOST_WindowClass", ::GetModuleHandle(0));
679 uint msg = raw.data.keyboard.Message;
680 *r_key_down = !(raw.data.keyboard.Flags & RI_KEY_BREAK) && msg != WM_KEYUP && msg != WM_SYSKEYUP;
682 return this->
convertKey(raw.data.keyboard.VKey,
683 raw.data.keyboard.MakeCode,
684 (raw.data.keyboard.Flags & (RI_KEY_E1 | RI_KEY_E0)));
701 char ch = char(MapVirtualKeyA(vKey, MAPVK_VK_TO_CHAR));
722 if (vKey == VK_OEM_7) {
725 else if (vKey == VK_OEM_8) {
726 if (PRIMARYLANGID(
lang_id_) == LANG_FRENCH) {
741 if ((vKey >=
'0') && (vKey <=
'9')) {
745 else if ((vKey >=
'A') && (vKey <=
'Z')) {
749 else if ((vKey >= VK_F1) && (vKey <= VK_F24)) {
871 if (scanCode == 0x36) {
874 else if (scanCode == 0x2a) {
908 case VK_MEDIA_PLAY_PAUSE:
914 case VK_MEDIA_PREV_TRACK:
917 case VK_MEDIA_NEXT_TRACK:
943 DWORD msgPos = ::GetMessagePos();
944 int msgPosX = GET_X_LPARAM(msgPos);
945 int msgPosY = GET_Y_LPARAM(msgPos);
970 std::vector<GHOST_WintabInfoWin32> wintabInfo;
979 bool mouseMoveHandled;
1000 switch (info.button) {
1002 message = WM_LBUTTONDOWN;
1005 message = WM_RBUTTONDOWN;
1008 message = WM_MBUTTONDOWN;
1018 if (PeekMessage(&msg, window->
getHWND(), message, message, PM_NOYIELD) &&
1019 msg.message != WM_QUIT)
1023 useWintabPos = wt->
testCoordinates(msg.pt.x, msg.pt.y, info.x, info.y);
1024 if (!useWintabPos) {
1025 WINTAB_PRINTF(
" ... but associated system button mismatched position\n");
1032 PeekMessage(&msg, window->
getHWND(), message, message, PM_REMOVE | PM_NOYIELD);
1042 new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
1044 mouseMoveHandled =
true;
1053 if (!useWintabPos) {
1059 switch (info.button) {
1061 message = WM_LBUTTONUP;
1064 message = WM_RBUTTONUP;
1067 message = WM_MBUTTONUP;
1077 if (PeekMessage(&msg, window->
getHWND(), message, message, PM_REMOVE | PM_NOYIELD) &&
1078 msg.message != WM_QUIT)
1084 new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
1097 if (!mouseMoveHandled) {
1098 DWORD
pos = GetMessagePos();
1099 int x = GET_X_LPARAM(
pos);
1100 int y = GET_Y_LPARAM(
pos);
1118 std::vector<GHOST_PointerInfoWin32> pointerInfo;
1125 case WM_POINTERUPDATE: {
1128 for (uint32_t
i = pointerInfo.size();
i-- > 0;) {
1132 pointerInfo[
i].pixelLocation.x,
1133 pointerInfo[
i].pixelLocation.y,
1134 pointerInfo[
i].tabletData));
1141 case WM_POINTERDOWN: {
1146 pointerInfo[0].pixelLocation.x,
1147 pointerInfo[0].pixelLocation.y,
1148 pointerInfo[0].tabletData));
1152 pointerInfo[0].buttonMask,
1153 pointerInfo[0].tabletData));
1157 eventHandled =
true;
1161 case WM_POINTERUP: {
1165 pointerInfo[0].buttonMask,
1166 pointerInfo[0].tabletData));
1170 eventHandled =
true;
1190 int32_t x_screen = screen_co[0], y_screen = screen_co[1];
1195 static bool is_warping_x =
false;
1196 static bool is_warping_y =
false;
1224 bounds.wrapPoint(x_new, y_new, bounds_margin, bounds_axis);
1228 if (x_new != x_screen || y_new != y_screen) {
1232 if (!is_warping_x) {
1233 is_warping_x = x_new != x_screen;
1235 x_accum += (x_screen - x_new);
1239 if (!is_warping_y) {
1240 is_warping_y = y_new != y_screen;
1242 y_accum += (y_screen - y_new);
1252 is_warping_x =
false;
1253 is_warping_y =
false;
1254 x_screen += x_accum;
1255 y_screen += y_accum;
1273 int delta = GET_WHEEL_DELTA_WPARAM(wParam);
1275 if (acc * delta < 0) {
1280 int direction = (acc >= 0) ? 1 : -1;
1283 while (acc >= WHEEL_DELTA) {
1299 int delta = GET_WHEEL_DELTA_WPARAM(wParam);
1301 if (acc * delta < 0) {
1306 int direction = (acc >= 0) ? 1 : -1;
1309 while (acc >= WHEEL_DELTA) {
1319 const char vk = raw.data.keyboard.VKey;
1320 bool key_down =
false;
1327 constexpr USHORT ALTGR_MAKE_CODE = 0x38;
1332 if (system->
has_alt_gr_ && vk == VK_CONTROL && raw.data.keyboard.MakeCode == ALTGR_MAKE_CODE &&
1333 (raw.data.keyboard.Flags & RI_KEY_E0))
1344 bool is_repeat =
false;
1345 bool is_repeated_modifier =
false;
1347 if (HIBYTE(::GetKeyState(vk)) != 0) {
1357 if (!is_repeated_modifier) {
1358 char utf8_char[6] = {0};
1360 const BOOL has_state = GetKeyboardState((PBYTE)
state);
1361 const bool ctrl_pressed = has_state &&
state[VK_CONTROL] & 0x80;
1362 const bool alt_pressed = has_state &&
state[VK_MENU] & 0x80;
1363 const bool win_pressed = has_state && (
state[VK_LWIN] |
state[VK_RWIN]) & 0x80;
1368 if (ctrl_pressed && !alt_pressed) {
1371 else if (win_pressed) {
1377 else if (MapVirtualKeyW(vk, MAPVK_VK_TO_CHAR) != 0) {
1378 wchar_t utf16[3] = {0};
1382 if ((r = ToUnicodeEx(
1383 vk, raw.data.keyboard.MakeCode,
state, utf16, 2, 0, system->
keylayout_)))
1385 if ((r > 0 && r < 3)) {
1390 utf8_char[0] =
'\0';
1395 utf8_char[0] =
'\0';
1399#ifdef WITH_INPUT_IME
1400 if (key_down && ((utf8_char[0] & 0x80) == 0)) {
1401 const char ascii = utf8_char[0];
1402 if (window->getImeInput()->IsImeKeyEvent(ascii, key)) {
1457#ifdef WITH_INPUT_IME
1476 getMessageTime(system), eventType, draggedObjectType, window, mouseX, mouseY,
data));
1512 minmax->ptMinTrackSize.x = 320;
1513 minmax->ptMinTrackSize.y = 240;
1516#ifdef WITH_INPUT_NDOF
1517bool GHOST_SystemWin32::processNDOF(RAWINPUT
const &raw)
1519 bool eventSent =
false;
1522 RID_DEVICE_INFO info;
1523 unsigned infoSize =
sizeof(RID_DEVICE_INFO);
1524 info.cbSize = infoSize;
1526 GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICEINFO, &info, &infoSize);
1528 if (info.dwType == RIM_TYPEHID) {
1529 ndof_manager_->setDevice(info.hid.dwVendorId, info.hid.dwProductId);
1532 GHOST_PRINT(
"<!> not a HID device... mouse/kb perhaps?\n");
1539 BYTE
const *
data = raw.data.hid.bRawData;
1541 BYTE packetType =
data[0];
1542 switch (packetType) {
1544 const short *axis = (
short *)(
data + 1);
1546 const int t[3] = {axis[0], -axis[2], axis[1]};
1547 ndof_manager_->updateTranslation(t, now);
1549 if (raw.data.hid.dwSizeHid == 13) {
1551 const int r[3] = {-axis[3], axis[5], -axis[4]};
1552 ndof_manager_->updateRotation(r, now);
1561 const short *axis = (
short *)(
data + 1);
1562 const int r[3] = {-axis[0], axis[2], -axis[1]};
1563 ndof_manager_->updateRotation(r, now);
1568 memcpy(&button_bits,
data + 1,
sizeof(button_bits));
1569 ndof_manager_->updateButtonsBitmask(button_bits, now);
1575 for (
int i = 0;
i < buttons.size();
i++) {
1584 for (
int i = 0;
i < buttons.size();
i++) {
1599 if (active_window) {
1609 if (!active_window) {
1619 if (trackpad_info.
x != 0 || trackpad_info.
y != 0) {
1629 if (trackpad_info.
scale != 0) {
1635 trackpad_info.
scale,
1644 bool eventHandled =
false;
1646 LRESULT lResult = 0;
1648#ifdef WITH_INPUT_IME
1651 GHOST_ASSERT(system,
"GHOST_SystemWin32::s_wndProc(): system not initialized");
1655 if (msg == WM_NCCREATE) {
1658 HMODULE user32_ = ::LoadLibrary(
"User32.dll");
1662 "EnableNonClientDpiScaling");
1663 if (fpEnableNonClientDpiScaling) {
1664 fpEnableNonClientDpiScaling(hwnd);
1673 case WM_INPUTLANGCHANGE: {
1675#ifdef WITH_INPUT_IME
1676 window->getImeInput()->UpdateInputLanguage();
1677 window->getImeInput()->UpdateConversionStatus(hwnd);
1686 RAWINPUT *raw_ptr = &raw;
1687 uint rawSize =
sizeof(RAWINPUT);
1689 GetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw_ptr, &rawSize,
sizeof(RAWINPUTHEADER));
1691 switch (raw.header.dwType) {
1692 case RIM_TYPEKEYBOARD: {
1695 GHOST_PRINT(
"GHOST_SystemWin32::wndProc: key event ");
1701#ifdef WITH_INPUT_NDOF
1703 if (system->processNDOF(raw)) {
1704 eventHandled =
true;
1712#ifdef WITH_INPUT_IME
1716 case WM_IME_NOTIFY: {
1718 if (wParam == IMN_SETOPENSTATUS || wParam == IMN_SETCONVERSIONMODE) {
1719 window->getImeInput()->UpdateConversionStatus(hwnd);
1723 case WM_IME_SETCONTEXT: {
1724 GHOST_ImeWin32 *ime = window->getImeInput();
1725 ime->UpdateInputLanguage();
1726 ime->UpdateConversionStatus(hwnd);
1727 ime->CreateImeWindow(hwnd);
1728 ime->CleanupComposition(hwnd);
1729 ime->CheckFirst(hwnd);
1732 case WM_IME_STARTCOMPOSITION: {
1733 GHOST_ImeWin32 *ime = window->getImeInput();
1734 eventHandled =
true;
1735 ime->CreateImeWindow(hwnd);
1736 ime->ResetComposition(hwnd);
1740 case WM_IME_COMPOSITION: {
1741 GHOST_ImeWin32 *ime = window->getImeInput();
1742 eventHandled =
true;
1743 ime->UpdateImeWindow(hwnd);
1744 ime->UpdateInfo(hwnd);
1745 if (ime->eventImeData.result.size()) {
1752 case WM_IME_ENDCOMPOSITION: {
1753 GHOST_ImeWin32 *ime = window->getImeInput();
1754 eventHandled =
true;
1757 ime->ResetComposition(hwnd);
1758 ime->DestroyImeWindow(hwnd);
1784 case WM_SYSDEADCHAR:
1797 case WM_SYSCOMMAND: {
1805 switch (wParam & 0xFFF0) {
1807 eventHandled =
true;
1811 ::ShowWindow(hwnd, SW_RESTORE);
1819 eventHandled =
true;
1844 case WT_CSRCHANGE: {
1850 eventHandled =
true;
1853 case WT_PROXIMITY: {
1855 if (LOWORD(lParam)) {
1861 if (HIWORD(lParam)) {
1862 WINTAB_PRINTF(
" Cursor entering or leaving hardware proximity.\n");
1865 WINTAB_PRINTF(
" Cursor neither entering nor leaving hardware proximity.\n");
1870 bool inRange = LOWORD(lParam);
1879 eventHandled =
true;
1882 case WT_INFOCHANGE: {
1892 eventHandled =
true;
1897 eventHandled =
true;
1911 case WT_CTXUPDATE: {
1915 case WT_CTXOVERLAP: {
1918 case CXS_DISABLED: {
1922 case CXS_OBSCURED: {
1936 case WM_POINTERUPDATE:
1937 case WM_POINTERDOWN:
1938 case WM_POINTERUP: {
1942 case WM_POINTERLEAVE: {
1944 POINTER_INFO pointerInfo;
1945 if (!GetPointerInfo(pointerId, &pointerInfo)) {
1950 if (pointerInfo.pointerType == PT_PEN) {
1952 eventHandled =
true;
1959 case WM_LBUTTONDOWN: {
1963 case WM_MBUTTONDOWN: {
1967 case WM_RBUTTONDOWN: {
1971 case WM_XBUTTONDOWN: {
1972 if (
short(HIWORD(wParam)) == XBUTTON1) {
1975 else if (
short(HIWORD(wParam)) == XBUTTON2) {
1980 case WM_LBUTTONUP: {
1984 case WM_MBUTTONUP: {
1988 case WM_RBUTTONUP: {
1992 case WM_XBUTTONUP: {
1993 if (
short(HIWORD(wParam)) == XBUTTON1) {
1996 else if (
short(HIWORD(wParam)) == XBUTTON2) {
2001 case WM_MOUSEMOVE: {
2004 TRACKMOUSEEVENT tme = {
sizeof(tme)};
2006 tme.dwFlags = TME_LEAVE;
2009 tme.dwFlags |= TME_HOVER;
2010 tme.dwHoverTime = 100;
2012 tme.hwndTrack = hwnd;
2013 TrackMouseEvent(&tme);
2021 const int32_t window_co[2] = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
2028 case WM_MOUSEHOVER: {
2034 HWND old_hwnd = ::GetFocus();
2035 if (old_hwnd && hwnd != old_hwnd) {
2036 HWND new_parent = ::GetParent(hwnd);
2037 HWND old_parent = ::GetParent(old_hwnd);
2038 if (hwnd == old_parent || old_hwnd == new_parent) {
2042 else if (new_parent != HWND_DESKTOP && new_parent == old_parent) {
2046 else if (!new_parent && !old_parent) {
2048 RECT new_rect, old_rect, dest_rect;
2051 DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &new_rect,
sizeof(RECT));
2052 ::InflateRect(&new_rect, -1, -1);
2053 DwmGetWindowAttribute(
2054 old_hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &old_rect,
sizeof(RECT));
2055 ::InflateRect(&old_rect, -1, -1);
2057 if (!IntersectRect(&dest_rect, &new_rect, &old_rect)) {
2064 case WM_MOUSEWHEEL: {
2073 eventHandled =
true;
2074#ifdef BROKEN_PEEK_TOUCHPAD
2075 PostMessage(hwnd, WM_USER, 0, 0);
2079 case WM_MOUSEHWHEEL: {
2081 eventHandled =
true;
2084 case WM_SETCURSOR: {
2091 if (LOWORD(lParam) == HTCLIENT) {
2103 case WM_MOUSELEAVE: {
2108 int32_t screen_co[2] = {0, 0};
2121 case WM_NCMOUSEMOVE: {
2127 case WM_NCHITTEST: {
2141 if (IsIconic(hwnd)) {
2142 ShowWindow(hwnd, SW_RESTORE);
2161 if (LOWORD(wParam) == WA_INACTIVE) {
2168 lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
2171 case WM_ENTERSIZEMOVE: {
2182 case WM_EXITSIZEMOVE: {
2196 ::ValidateRect(hwnd,
nullptr);
2199 eventHandled =
true;
2203 case WM_GETMINMAXINFO: {
2227 case WM_CAPTURECHANGED: {
2254 case WM_DPICHANGED: {
2261 RECT *
const suggestedWindowRect = (RECT *)lParam;
2266 eventHandled =
true;
2271 suggestedWindowRect->left,
2272 suggestedWindowRect->top,
2273 suggestedWindowRect->right - suggestedWindowRect->left,
2274 suggestedWindowRect->bottom - suggestedWindowRect->top,
2275 SWP_NOZORDER | SWP_NOACTIVATE);
2280 case WM_DISPLAYCHANGE: {
2288 case WM_KILLFOCUS: {
2292 if (!wParam && hwnd == ::GetActiveWindow()) {
2297 case WM_SETTINGCHANGE: {
2300 if (((
void *)lParam !=
nullptr) && (wcscmp(LPCWSTR(lParam),
L"ImmersiveColorSet") == 0))
2310 case WM_WINDOWPOSCHANGED:
2324 HBRUSH bgBrush = (HBRUSH)GetClassLongPtr(hwnd, GCLP_HBRBACKGROUND);
2327 GetClientRect(hwnd, &rect);
2328 FillRect((HDC)(wParam), &rect, bgBrush);
2331 SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND, (LONG_PTR)
nullptr);
2347 case WM_NCDESTROY: {
2358 case WM_WINDOWPOSCHANGING:
2373 case WM_ACTIVATEAPP:
2389 case DM_POINTERHITTEST: {
2402 GHOST_PRINT(
"GHOST_SystemWin32::wndProc: GHOST window event before creation\n");
2414 GHOST_PRINT(
"GHOST_SystemWin32::wndProc: event without window\n");
2419 eventHandled =
true;
2422 if (!eventHandled) {
2423 lResult = ::DefWindowProcW(hwnd, msg, wParam, lParam);
2431 if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(
nullptr)) {
2433 HANDLE hData = GetClipboardData(CF_UNICODETEXT);
2434 if (hData ==
nullptr) {
2438 buffer = (
wchar_t *)GlobalLock(hData);
2448 GlobalUnlock(hData);
2453 if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(
nullptr)) {
2456 HANDLE hData = GetClipboardData(CF_TEXT);
2457 if (hData ==
nullptr) {
2461 buffer = (
char *)GlobalLock(hData);
2467 len = strlen(buffer);
2468 char *temp_buff = (
char *)malloc(
len + 1);
2469 memcpy(temp_buff, buffer,
len + 1);
2473 GlobalUnlock(hData);
2483 if (selection || !buffer) {
2487 if (OpenClipboard(
nullptr)) {
2493 HGLOBAL clipbuffer = GlobalAlloc(GMEM_MOVEABLE,
sizeof(
wchar_t) *
len);
2495 wchar_t *
data = (
wchar_t *)GlobalLock(clipbuffer);
2499 GlobalUnlock(clipbuffer);
2500 SetClipboardData(CF_UNICODETEXT, clipbuffer);
2509 if (IsClipboardFormatAvailable(CF_DIBV5) ||
2510 IsClipboardFormatAvailable(RegisterClipboardFormat(
"PNG")))
2517 if (IsClipboardFormatAvailable(CF_HDROP)) {
2518 if (OpenClipboard(
nullptr)) {
2519 if (HANDLE hGlobal = GetClipboardData(CF_HDROP)) {
2520 if (HDROP hDrop =
static_cast<HDROP
>(GlobalLock(hGlobal))) {
2521 UINT fileCount = DragQueryFile(hDrop, 0xffffffff,
nullptr, 0);
2522 if (fileCount == 1) {
2523 WCHAR lpszFile[MAX_PATH] = {0};
2524 DragQueryFileW(hDrop, 0, lpszFile, MAX_PATH);
2534 GlobalUnlock(hGlobal);
2545 char *filepath =
nullptr;
2547 if (OpenClipboard(
nullptr)) {
2548 if (HANDLE hGlobal = GetClipboardData(CF_HDROP)) {
2549 if (HDROP hDrop =
static_cast<HDROP
>(GlobalLock(hGlobal))) {
2550 UINT fileCount = DragQueryFile(hDrop, 0xffffffff,
nullptr, 0);
2551 if (fileCount == 1) {
2552 WCHAR lpszFile[MAX_PATH] = {0};
2553 DragQueryFileW(hDrop, 0, lpszFile, MAX_PATH);
2556 GlobalUnlock(hGlobal);
2567 *r_height = ibuf->
y;
2569 uint *rgba =
static_cast<uint *
>(malloc(byte_count));
2583 HANDLE hGlobal = GetClipboardData(CF_DIBV5);
2584 if (hGlobal ==
nullptr) {
2588 BITMAPV5HEADER *bitmapV5Header = (BITMAPV5HEADER *)GlobalLock(hGlobal);
2589 if (bitmapV5Header ==
nullptr) {
2593 int offset = bitmapV5Header->bV5Size + bitmapV5Header->bV5ClrUsed *
sizeof(RGBQUAD);
2595 BYTE *buffer = (BYTE *)bitmapV5Header + offset;
2596 int bitcount = bitmapV5Header->bV5BitCount;
2597 int width = bitmapV5Header->bV5Width;
2598 int height = bitmapV5Header->bV5Height;
2602 if (
uint64_t(width) *
uint64_t(height) > (std::numeric_limits<DWORD>::max() / 4)) {
2603 GlobalUnlock(hGlobal);
2610 DWORD ColorMasks[4];
2611 ColorMasks[0] = bitmapV5Header->bV5RedMask ? bitmapV5Header->bV5RedMask : 0xff;
2612 ColorMasks[1] = bitmapV5Header->bV5GreenMask ? bitmapV5Header->bV5GreenMask : 0xff00;
2613 ColorMasks[2] = bitmapV5Header->bV5BlueMask ? bitmapV5Header->bV5BlueMask : 0xff0000;
2614 ColorMasks[3] = bitmapV5Header->bV5AlphaMask ? bitmapV5Header->bV5AlphaMask : 0xff000000;
2617 DWORD ColorShifts[4];
2618 for (
int i = 0;
i < 4;
i++) {
2619 _BitScanForward(&ColorShifts[
i], ColorMasks[
i]);
2624 uint8_t *target = (uint8_t *)rgba;
2626 if (bitmapV5Header->bV5Compression == BI_BITFIELDS && bitcount == 32) {
2627 for (
int h = 0; h < height; h++) {
2628 for (
int w = 0;
w < width;
w++, target += 4, source += 4) {
2629 DWORD *pix = (DWORD *)source;
2630 target[0] = uint8_t((*pix & ColorMasks[0]) >> ColorShifts[0]);
2631 target[1] = uint8_t((*pix & ColorMasks[1]) >> ColorShifts[1]);
2632 target[2] = uint8_t((*pix & ColorMasks[2]) >> ColorShifts[2]);
2633 target[3] = uint8_t((*pix & ColorMasks[3]) >> ColorShifts[3]);
2637 else if (bitmapV5Header->bV5Compression == BI_RGB && bitcount == 32) {
2638 for (
int h = 0; h < height; h++) {
2639 for (
int w = 0;
w < width;
w++, target += 4, source += 4) {
2640 RGBQUAD *
quad = (RGBQUAD *)source;
2641 target[0] = uint8_t(
quad->rgbRed);
2642 target[1] = uint8_t(
quad->rgbGreen);
2643 target[2] = uint8_t(
quad->rgbBlue);
2644 target[3] = (bitmapV5Header->bV5AlphaMask) ? uint8_t(
quad->rgbReserved) : 255;
2648 else if (bitmapV5Header->bV5Compression == BI_RGB && bitcount == 24) {
2649 int bytes_per_row = ((((width * bitcount) + 31) & ~31) >> 3);
2650 int slack = bytes_per_row - (width * 3);
2651 for (
int h = 0; h < height; h++, source += slack) {
2652 for (
int w = 0;
w < width;
w++, target += 4, source += 3) {
2653 RGBTRIPLE *
triple = (RGBTRIPLE *)source;
2654 target[0] = uint8_t(
triple->rgbtRed);
2655 target[1] = uint8_t(
triple->rgbtGreen);
2656 target[2] = uint8_t(
triple->rgbtBlue);
2662 GlobalUnlock(hGlobal);
2669 HANDLE hGlobal = GetClipboardData(
format);
2670 if (hGlobal ==
nullptr) {
2674 LPVOID pMem = GlobalLock(hGlobal);
2679 uint *rgba =
nullptr;
2686 *r_height = ibuf->
y;
2688 rgba = (
uint *)malloc(byte_count);
2693 GlobalUnlock(hGlobal);
2699 if (IsClipboardFormatAvailable(CF_HDROP)) {
2703 if (!OpenClipboard(
nullptr)) {
2708 UINT cfPNG = RegisterClipboardFormat(
"PNG");
2710 for (
int cf = EnumClipboardFormats(0); cf; cf = EnumClipboardFormats(cf)) {
2711 if (
ELEM(cf, CF_DIBV5, cfPNG)) {
2714 if (cf == CF_DIBV5 || (cf == CF_BITMAP &&
format == cfPNG)) {
2719 uint *rgba =
nullptr;
2721 if (
format == CF_DIBV5) {
2724 else if (
format == cfPNG) {
2741 if (
uint64_t(width) *
uint64_t(height) > (std::numeric_limits<DWORD>::max() / 4)) {
2745 DWORD size_pixels = width * height * 4;
2747 HGLOBAL hMem = GlobalAlloc(GHND,
sizeof(BITMAPV5HEADER) + size_pixels);
2752 BITMAPV5HEADER *hdr = (BITMAPV5HEADER *)GlobalLock(hMem);
2758 hdr->bV5Size =
sizeof(BITMAPV5HEADER);
2759 hdr->bV5Width = width;
2760 hdr->bV5Height = height;
2762 hdr->bV5BitCount = 32;
2763 hdr->bV5SizeImage = size_pixels;
2764 hdr->bV5Compression = BI_BITFIELDS;
2765 hdr->bV5RedMask = 0x000000ff;
2766 hdr->bV5GreenMask = 0x0000ff00;
2767 hdr->bV5BlueMask = 0x00ff0000;
2768 hdr->bV5AlphaMask = 0xff000000;
2769 hdr->bV5CSType = LCS_sRGB;
2770 hdr->bV5Intent = LCS_GM_IMAGES;
2771 hdr->bV5ClrUsed = 0;
2773 memcpy((
char *)hdr +
sizeof(BITMAPV5HEADER), rgba, size_pixels);
2777 if (!SetClipboardData(CF_DIBV5, hMem)) {
2787 UINT cf = RegisterClipboardFormat(
"PNG");
2804 LPVOID pMem = GlobalLock(hMem);
2816 if (!SetClipboardData(cf, hMem)) {
2826 if (!OpenClipboard(
nullptr) || !EmptyClipboard()) {
2843 const char *message,
2844 const char *help_label,
2845 const char *continue_label,
2854 int nButtonPressed = 0;
2855 TASKDIALOGCONFIG config = {0};
2856 const TASKDIALOG_BUTTON buttons[] = {{IDOK, help_label_16}, {IDCONTINUE, continue_label_16}};
2858 config.cbSize =
sizeof(config);
2859 config.hInstance = 0;
2860 config.dwCommonButtons = 0;
2863 TD_INFORMATION_ICON);
2864 config.pszWindowTitle =
L"Blender";
2865 config.pszMainInstruction = title_16;
2866 config.pszContent = message_16;
2867 const bool has_link = link && strlen(link);
2868 config.pButtons = has_link ? buttons : buttons + 1;
2869 config.cButtons = has_link ? 2 : 1;
2871 TaskDialogIndirect(&config, &nButtonPressed,
nullptr,
nullptr);
2872 switch (nButtonPressed) {
2874 ShellExecute(
nullptr,
"open", link,
nullptr,
nullptr, SW_SHOWNORMAL);
2882 free((
void *)title_16);
2883 free((
void *)message_16);
2884 free((
void *)help_label_16);
2885 free((
void *)continue_label_16);
2895 PROCESSENTRY32 pe32 = {0};
2896 DWORD ppid = 0, pid = GetCurrentProcessId();
2897 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
2898 if (snapshot == INVALID_HANDLE_VALUE) {
2901 pe32.dwSize =
sizeof(pe32);
2902 if (!Process32First(snapshot, &pe32)) {
2903 CloseHandle(snapshot);
2907 if (pe32.th32ProcessID == pid) {
2908 ppid = pe32.th32ParentProcessID;
2911 }
while (Process32Next(snapshot, &pe32));
2912 CloseHandle(snapshot);
2919 HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, pid);
2921 GetModuleFileNameEx(handle, 0, buffer, max_len);
2924 CloseHandle(handle);
2930 HWND hwnd = GetConsoleWindow();
2933 DWORD pid = (DWORD)-1;
2935 char parent_name[MAX_PATH];
2936 bool start_from_launcher =
false;
2938 GetWindowThreadProcessId(hwnd, &pid);
2940 char *filename = strrchr(parent_name,
'\\');
2941 if (filename !=
nullptr) {
2942 start_from_launcher = strstr(filename,
"blender.exe") !=
nullptr;
2947 if (pid != (start_from_launcher ? ppid : GetCurrentProcessId())) {
2957 HWND wnd = GetConsoleWindow();
2962 ShowWindow(wnd, SW_HIDE);
2968 ShowWindow(wnd, SW_HIDE);
2973 ShowWindow(wnd, SW_SHOW);
2975 DeleteMenu(GetSystemMenu(wnd,
FALSE), SC_CLOSE, MF_BYCOMMAND);
2984 DeleteMenu(GetSystemMenu(wnd,
FALSE), SC_CLOSE, MF_BYCOMMAND);
void BLI_kdtree_nd_ free(KDTree *tree)
#define GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY
#define GHOST_PRINTF(x,...)
#define GHOST_ASSERT(x, info)
std::array< GHOST_NDOF_ButtonT, 6 > NDOF_Button_Array
static uint * getClipboardImageFilepath(int *r_width, int *r_height)
static void initRawInput()
static bool putClipboardImageDibV5(uint *rgba, int width, int height)
static uint * getClipboardImageImBuf(int *r_width, int *r_height, UINT format)
static const std::map< uint16_t, GHOST_NDOF_ButtonT > longButtonHIDsToGHOST_NDOFButtons
static GHOST_NDOF_ButtonT translateLongButtonToNDOFButton(uint16_t longKey)
BOOL(API * GHOST_WIN32_EnableNonClientDpiScaling)(HWND)
static bool isStartedFromCommandPrompt()
static uint * getClipboardImageDibV5(int *r_width, int *r_height)
static bool putClipboardImagePNG(uint *rgba, int width, int height)
static uint64_t getMessageTime(GHOST_SystemWin32 *system)
static DWORD GetParentProcessID(void)
static bool getProcessName(int pid, char *buffer, int max_len)
@ GHOST_kEventWheelAxisVertical
@ GHOST_kEventWheelAxisHorizontal
@ GHOST_kTrackpadEventMagnify
@ GHOST_kTrackpadEventScroll
@ GHOST_kWindowStateMinimized
@ GHOST_kStandardCursorDefault
@ GHOST_NDOF_BUTTON_TILT_CCW
@ GHOST_NDOF_BUTTON_SAVE_V1
@ GHOST_NDOF_BUTTON_ROLL_CCW
@ GHOST_NDOF_BUTTON_SPIN_CCW
@ GHOST_NDOF_BUTTON_SAVE_V3
@ GHOST_NDOF_BUTTON_SAVE_V2
@ GHOST_NDOF_BUTTON_BOTTOM
@ GHOST_kEventWindowClose
@ GHOST_kEventImeComposition
@ GHOST_kEventWindowActivate
@ GHOST_kEventWindowUpdate
@ GHOST_kEventWindowDeactivate
@ GHOST_kEventImeCompositionStart
@ GHOST_kEventImeCompositionEnd
@ GHOST_kEventWindowDPIHintChanged
static const GHOST_TabletData GHOST_TABLET_DATA_NONE
#define GHOST_KEY_MODIFIER_CHECK(key)
@ GHOST_kCapabilityClipboardPrimary
@ GHOST_kCapabilityKeyboardHyperKey
@ GHOST_kCapabilityCursorGenerator
#define GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS(gpu_settings)
#define GHOST_CAPABILITY_FLAG_ALL
@ GHOST_kKeyNumpadAsterisk
@ GHOST_kModifierKeyRightControl
@ GHOST_kModifierKeyLeftControl
@ GHOST_kModifierKeyRightAlt
@ GHOST_kModifierKeyRightShift
@ GHOST_kModifierKeyLeftAlt
@ GHOST_kModifierKeyLeftShift
@ GHOST_kModifierKeyLeftOS
@ GHOST_kModifierKeyRightOS
#define GHOST_CONTEXT_PARAMS_NONE
#define GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS_OFFSCREEN(gpu_settings)
@ GHOST_kButtonMaskButton4
@ GHOST_kButtonMaskButton5
@ GHOST_kButtonMaskMiddle
GHOST_TConsoleWindowState
@ GHOST_kConsoleWindowStateShow
@ GHOST_kConsoleWindowStateHideForNonConsoleLaunch
@ GHOST_kConsoleWindowStateHide
@ GHOST_kConsoleWindowStateToggle
@ GHOST_kTabletWinPointer
#define GET_POINTERID_WPARAM(wParam)
#define WINTAB_PRINTF(x,...)
ImBuf * IMB_load_image_from_filepath(const char *filepath, const int flags, char r_colorspace[IM_MAX_SPACE]=nullptr)
ImBuf * IMB_load_image_from_memory(const unsigned char *mem, const size_t size, const int flags, const char *descr, const char *filepath=nullptr, char r_colorspace[IM_MAX_SPACE]=nullptr)
ImBuf * IMB_allocFromBuffer(const uint8_t *byte_buffer, const float *float_buffer, unsigned int w, unsigned int h, unsigned int channels)
void IMB_freeImBuf(ImBuf *ibuf)
bool IMB_save_image(ImBuf *ibuf, const char *filepath, const int flags)
BMesh const char void * data
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
SIMD_FORCE_INLINE btScalar triple(const btVector3 &v1, const btVector3 &v2) const
void removeTypeEvents(GHOST_TEventType type, const GHOST_IWindow *window=nullptr)
static GHOST_ISystem * getSystem()
GHOST_TKey hardKey(RAWINPUT const &raw, bool *r_key_down)
void setTabletAPI(GHOST_TTabletAPI api) override
GHOST_TSuccess putClipboardImage(uint *rgba, int width, int height) const override
GHOST_IWindow * createWindow(const char *title, int32_t left, int32_t top, uint32_t width, uint32_t height, GHOST_TWindowState state, GHOST_GPUSettings gpu_settings, const bool exclusive=false, const bool is_dialog=false, const GHOST_IWindow *parent_window=nullptr) override
static GHOST_EventButton * processButtonEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TButton mask)
GHOST_TKey processSpecialKey(short vKey, short scanCode) const
static GHOST_Event * processWindowSizeEvent(GHOST_WindowWin32 *window)
GHOST_TKey convertKey(short vKey, short ScanCode, short extend) const
GHOST_TSuccess setCursorPosition(int32_t x, int32_t y) override
int wheel_delta_accum_horizontal_
GHOST_TSuccess showMessageBox(const char *title, const char *message, const char *help_label, const char *continue_label, const char *link, GHOST_DialogOptions dialog_options) const override
static void processWheelEventHorizontal(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam)
static GHOST_EventCursor * processCursorEvent(GHOST_WindowWin32 *window, const int32_t screen_co[2])
void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const override
static GHOST_ContextD3D * createOffscreenContextD3D()
static GHOST_TSuccess disposeContextD3D(GHOST_ContextD3D *context)
GHOST_TSuccess hasClipboardImage() const override
static void processWintabEvent(GHOST_WindowWin32 *window)
bool has_performance_counter_
uint64_t performanceCounterToMillis(__int64 perf_ticks) const
uint * getClipboardImage(int *r_width, int *r_height) const override
GHOST_TCapabilityFlag getCapabilities() const override
static GHOST_EventKey * processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const &raw)
void initDebug(GHOST_Debug debug) override
char * getClipboard(bool selection) const override
GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const override
uint8_t getNumDisplays() const override
GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const override
static void processMinMaxInfo(MINMAXINFO *minmax)
static void processWheelEventVertical(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam)
void putClipboard(const char *buffer, bool selection) const override
uint32_t getCursorPreferredLogicalSize() const override
static GHOST_Event * processWindowEvent(GHOST_TEventType type, GHOST_WindowWin32 *window)
void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const override
GHOST_TSuccess init() override
bool setConsoleWindowState(GHOST_TConsoleWindowState action) override
GHOST_TSuccess exit() override
bool processEvents(bool waitForEvent) override
static void processPointerEvent(UINT type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool &eventhandled)
~GHOST_SystemWin32() override
uint64_t getMilliSeconds() const override
void handleKeyboardChange()
int wheel_delta_accum_vertical_
GHOST_IWindow * getWindowUnderCursor(int32_t, int32_t) override
GHOST_TSuccess getPixelAtCursor(float r_color[3]) const override
static LRESULT WINAPI s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, GHOST_WindowWin32 *window, int mouseX, int mouseY, void *data)
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const override
GHOST_TSuccess disposeContext(GHOST_IContext *context) override
GHOST_IContext * createOffscreenContext(GHOST_GPUSettings gpu_settings) override
GHOST_EventManager * getEventManager() const
GHOST_WindowManager * getWindowManager() const
GHOST_WindowManager * window_manager_
GHOST_TSuccess pushEvent(const GHOST_IEvent *event)
GHOST_TSuccess init() override
GHOST_TimerManager * getTimerManager() const
void initDebug(GHOST_Debug debug) override
void setTabletAPI(GHOST_TTabletAPI api) override
bool multitouch_gestures_
GHOST_TSuccess exit() override
GHOST_EventManager * event_manager_
void dispatchEvents() override
bool fireTimers(uint64_t time)
const std::vector< GHOST_IWindow * > & getWindows() const
GHOST_IWindow * getActiveWindow() const
GHOST_TSuccess setActiveWindow(GHOST_IWindow *window)
void setWindowInactive(const GHOST_IWindow *window)
void resetPointerPenInfo()
GHOST_TTrackpadInfo getTrackpadInfo()
void updateDirectManipulation()
bool usingTabletAPI(GHOST_TTabletAPI api) const
GHOST_TSuccess getPointerInfo(std::vector< GHOST_PointerInfoWin32 > &outPointerInfo, WPARAM wParam, LPARAM lParam)
void loadWintab(bool enable)
GHOST_TabletData getTabletData()
GHOST_Wintab * getWintab() const
void updateMouseCapture(GHOST_MouseCaptureEventWin32 event)
GHOST_TSuccess setState(GHOST_TWindowState state)
void getClientBounds(GHOST_Rect &bounds) const
void onPointerHitTest(WPARAM wParam)
void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const
GHOST_TWindowState getState() const
void loadCursor(bool visible, GHOST_TStandardCursor cursor_shape) const
GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) const override
void setCursorGrabAccum(int32_t x, int32_t y)
GHOST_TAxisFlag getCursorGrabAxis() const
GHOST_TStandardCursor getCursorShape() const override
bool getCursorVisibility() const override
GHOST_TGrabCursorMode getCursorGrabMode() const
bool getCursorGrabModeIsWarp() const
void getCursorGrabAccum(int32_t &x, int32_t &y) const
void mapWintabToSysCoordinates(int x_in, int y_in, int &x_out, int &y_out)
GHOST_TabletData getLastTabletData()
void getInput(std::vector< GHOST_WintabInfoWin32 > &outWintabInfo)
void processInfoChange(LPARAM lParam)
bool testCoordinates(int sysX, int sysY, int wtX, int wtY)
static void setDebug(bool debug)
blender::gpu::Batch * quad
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
GHOST_TDrawingContextType context_type
GHOST_GPUDevice preferred_device
void set(GHOST_TModifierKey mask, bool down)
bool isScrollDirectionInverted
ImbFormatOptions foptions
ImBufByteBuffer byte_buffer
unsigned int encoded_buffer_size
ImBufByteBuffer encoded_buffer
wchar_t * alloc_utf16_from_8(const char *in8, size_t add)
char * alloc_utf_8_from_16(const wchar_t *in16, size_t add)
int conv_utf_8_to_16(const char *in8, wchar_t *out16, size_t size16)
int conv_utf_16_to_8(const wchar_t *in16, char *out8, size_t size8)
size_t count_utf_16_from_8(const char *string8)
#define UTF16_ENCODE(in8str)
#define UTF16_UN_ENCODE(in8str)