Blender  V3.3
GHOST_WindowWin32.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include "GHOST_WindowWin32.h"
9 #include "GHOST_ContextD3D.h"
10 #include "GHOST_ContextNone.h"
11 #include "GHOST_DropTargetWin32.h"
12 #include "GHOST_SystemWin32.h"
13 #include "GHOST_WindowManager.h"
14 #include "utf_winfunc.h"
15 #include "utfconv.h"
16 
17 #include "GHOST_ContextWGL.h"
18 
19 #include <Dwmapi.h>
20 
21 #include <assert.h>
22 #include <math.h>
23 #include <shellscalingapi.h>
24 #include <string.h>
25 #include <windowsx.h>
26 
27 #ifndef GET_POINTERID_WPARAM
28 # define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
29 #endif // GET_POINTERID_WPARAM
30 
31 const wchar_t *GHOST_WindowWin32::s_windowClassName = L"GHOST_WindowClass";
32 const int GHOST_WindowWin32::s_maxTitleLength = 128;
33 
34 /* force NVidia Optimus to used dedicated graphics */
35 extern "C" {
36 __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
37 }
38 
40  const char *title,
41  int32_t left,
42  int32_t top,
47  bool wantStereoVisual,
48  bool alphaBackground,
49  GHOST_WindowWin32 *parentwindow,
50  bool is_debug,
51  bool dialog)
52  : GHOST_Window(width, height, state, wantStereoVisual, false),
53  m_mousePresent(false),
54  m_inLiveResize(false),
55  m_system(system),
56  m_dropTarget(NULL),
57  m_hWnd(0),
58  m_hDC(0),
59  m_isDialog(dialog),
60  m_hasMouseCaptured(false),
61  m_hasGrabMouse(false),
62  m_nPressedButtons(0),
63  m_customCursor(0),
64  m_wantAlphaBackground(alphaBackground),
65  m_Bar(NULL),
66  m_wintab(NULL),
67  m_lastPointerTabletData(GHOST_TABLET_DATA_NONE),
68  m_normal_state(GHOST_kWindowStateNormal),
69  m_user32(::LoadLibrary("user32.dll")),
70  m_parentWindowHwnd(parentwindow ? parentwindow->m_hWnd : HWND_DESKTOP),
71  m_directManipulationHelper(NULL),
72  m_debug_context(is_debug)
73 {
74  DWORD style = parentwindow ?
75  WS_POPUPWINDOW | WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX :
76  WS_OVERLAPPEDWINDOW;
77 
79  style |= WS_MAXIMIZE;
80  }
81 
82  /* Forces owned windows onto taskbar and allows minimization. */
83  DWORD extended_style = parentwindow ? WS_EX_APPWINDOW : 0;
84 
85  if (dialog) {
86  /* When we are ready to make windows of this type:
87  * style = WS_POPUPWINDOW | WS_CAPTION
88  * extended_style = WS_EX_DLGMODALFRAME | WS_EX_TOPMOST
89  */
90  }
91 
92  RECT win_rect = {left, top, (long)(left + width), (long)(top + height)};
93  adjustWindowRectForClosestMonitor(&win_rect, style, extended_style);
94 
95  wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
96  m_hWnd = ::CreateWindowExW(extended_style, // window extended style
97  s_windowClassName, // pointer to registered class name
98  title_16, // pointer to window name
99  style, // window style
100  win_rect.left, // horizontal position of window
101  win_rect.top, // vertical position of window
102  win_rect.right - win_rect.left, // window width
103  win_rect.bottom - win_rect.top, // window height
104  m_parentWindowHwnd, // handle to parent or owner window
105  0, // handle to menu or child-window identifier
106  ::GetModuleHandle(0), // handle to application instance
107  0); // pointer to window-creation data
108  free(title_16);
109 
110  if (m_hWnd == NULL) {
111  return;
112  }
113 
114  /* Store the device context. */
115  m_hDC = ::GetDC(m_hWnd);
116 
117  if (!setDrawingContextType(type)) {
118  const char *title = "Blender - Unsupported Graphics Card Configuration";
119  const char *text =
120  "A graphics card and driver with support for OpenGL 3.3 or higher is "
121  "required.\n\nInstalling the latest driver for your graphics card might resolve the "
122  "issue.";
123  if (GetSystemMetrics(SM_CMONITORS) > 1) {
124  text =
125  "A graphics card and driver with support for OpenGL 3.3 or higher is "
126  "required.\n\nPlugging all monitors into your primary graphics card might resolve "
127  "this issue. Installing the latest driver for your graphics card could also help.";
128  }
129  MessageBox(m_hWnd, text, title, MB_OK | MB_ICONERROR);
130  ::ReleaseDC(m_hWnd, m_hDC);
131  ::DestroyWindow(m_hWnd);
132  m_hWnd = NULL;
133  if (!parentwindow) {
134  exit(0);
135  }
136  return;
137  }
138 
139  RegisterTouchWindow(m_hWnd, 0);
140 
141  /* Register as drop-target. #OleInitialize(0) required first, done in GHOST_SystemWin32. */
142  m_dropTarget = new GHOST_DropTargetWin32(this, m_system);
143  ::RegisterDragDrop(m_hWnd, m_dropTarget);
144 
145  /* Store a pointer to this class in the window structure. */
146  ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR)this);
147 
148  if (!m_system->m_windowFocus) {
149  /* If we don't want focus then lower to bottom. */
150  ::SetWindowPos(m_hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
151  }
152 
153  if (parentwindow) {
154  /* Release any parent capture to allow immediate interaction (T90110). */
155  ::ReleaseCapture();
156  parentwindow->lostMouseCapture();
157  }
158 
159  /* Show the window. */
160  int nCmdShow;
161  switch (state) {
163  nCmdShow = SW_SHOWMAXIMIZED;
164  break;
166  nCmdShow = (m_system->m_windowFocus) ? SW_SHOWMINIMIZED : SW_SHOWMINNOACTIVE;
167  break;
169  default:
170  nCmdShow = (m_system->m_windowFocus) ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
171  break;
172  }
173 
174  ThemeRefresh();
175 
176  ::ShowWindow(m_hWnd, nCmdShow);
177 
178 #ifdef WIN32_COMPOSITING
179  if (alphaBackground && parentwindowhwnd == 0) {
180 
181  HRESULT hr = S_OK;
182 
183  /* Create and populate the Blur Behind structure. */
184  DWM_BLURBEHIND bb = {0};
185 
186  /* Enable Blur Behind and apply to the entire client area. */
187  bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
188  bb.fEnable = true;
189  bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
190 
191  /* Apply Blur Behind. */
192  hr = DwmEnableBlurBehindWindow(m_hWnd, &bb);
193  DeleteObject(bb.hRgnBlur);
194  }
195 #endif
196 
197  /* Force an initial paint of the window. */
198  ::UpdateWindow(m_hWnd);
199 
200  /* Initialize Wintab. */
201  if (system->getTabletAPI() != GHOST_kTabletWinPointer) {
203  }
204 
205  /* Allow the showing of a progress bar on the taskbar. */
206  CoCreateInstance(
207  CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID *)&m_Bar);
208 
209  /* Initialize Direct Manipulation. */
210  m_directManipulationHelper = GHOST_DirectManipulationHelper::create(m_hWnd, getDPIHint());
211 }
212 
214 {
215  if (!m_directManipulationHelper) {
216  return;
217  }
218 
219  m_directManipulationHelper->update();
220 }
221 
223 {
224  /* Only DM_POINTERHITTEST can be the first message of input sequence of touchpad input. */
225 
226  if (!m_directManipulationHelper) {
227  return;
228  }
229 
230  UINT32 pointerId = GET_POINTERID_WPARAM(wParam);
231  POINTER_INPUT_TYPE pointerType;
232  if (GetPointerType(pointerId, &pointerType) && pointerType == PT_TOUCHPAD) {
233  m_directManipulationHelper->onPointerHitTest(pointerId);
234  }
235 }
236 
238 {
239  if (!m_directManipulationHelper) {
240  return {0, 0, 0};
241  }
242 
243  return m_directManipulationHelper->getTrackpadInfo();
244 }
245 
247 {
248  if (m_Bar) {
249  m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS);
250  m_Bar->Release();
251  m_Bar = NULL;
252  }
253 
254  closeWintab();
255 
256  if (m_user32) {
257  FreeLibrary(m_user32);
258  m_user32 = NULL;
259  }
260 
261  if (m_customCursor) {
262  DestroyCursor(m_customCursor);
263  m_customCursor = NULL;
264  }
265 
266  if (m_hWnd != NULL && m_hDC != NULL && releaseNativeHandles()) {
267  ::ReleaseDC(m_hWnd, m_hDC);
268  m_hDC = NULL;
269  }
270 
271  if (m_hWnd) {
272  /* If this window is referenced by others as parent, clear that relation or windows will free
273  * the handle while we still reference it. */
274  for (GHOST_IWindow *iter_win : m_system->getWindowManager()->getWindows()) {
275  GHOST_WindowWin32 *iter_winwin = (GHOST_WindowWin32 *)iter_win;
276  if (iter_winwin->m_parentWindowHwnd == m_hWnd) {
277  ::SetWindowLongPtr(iter_winwin->m_hWnd, GWLP_HWNDPARENT, NULL);
278  iter_winwin->m_parentWindowHwnd = 0;
279  }
280  }
281 
282  if (m_dropTarget) {
283  // Disable DragDrop
284  RevokeDragDrop(m_hWnd);
285  // Release our reference of the DropTarget and it will delete itself eventually.
286  m_dropTarget->Release();
287  m_dropTarget = NULL;
288  }
289  ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, NULL);
290  ::DestroyWindow(m_hWnd);
291  m_hWnd = 0;
292  }
293 
294  delete m_directManipulationHelper;
295  m_directManipulationHelper = NULL;
296 }
297 
299  DWORD dwStyle,
300  DWORD dwExStyle)
301 {
302  /* Get Details of the closest monitor. */
303  HMONITOR hmonitor = MonitorFromRect(win_rect, MONITOR_DEFAULTTONEAREST);
304  MONITORINFOEX monitor;
305  monitor.cbSize = sizeof(MONITORINFOEX);
306  monitor.dwFlags = 0;
307  GetMonitorInfo(hmonitor, &monitor);
308 
309  /* Constrain requested size and position to fit within this monitor. */
310  LONG width = min(monitor.rcWork.right - monitor.rcWork.left, win_rect->right - win_rect->left);
311  LONG height = min(monitor.rcWork.bottom - monitor.rcWork.top, win_rect->bottom - win_rect->top);
312  win_rect->left = min(max(monitor.rcWork.left, win_rect->left), monitor.rcWork.right - width);
313  win_rect->right = win_rect->left + width;
314  win_rect->top = min(max(monitor.rcWork.top, win_rect->top), monitor.rcWork.bottom - height);
315  win_rect->bottom = win_rect->top + height;
316 
317  /* With Windows 10 and newer we can adjust for chrome that differs with DPI and scale. */
318  GHOST_WIN32_AdjustWindowRectExForDpi fpAdjustWindowRectExForDpi = nullptr;
319  if (m_user32) {
320  fpAdjustWindowRectExForDpi = (GHOST_WIN32_AdjustWindowRectExForDpi)::GetProcAddress(
321  m_user32, "AdjustWindowRectExForDpi");
322  }
323 
324  /* Adjust to allow for caption, borders, shadows, scaling, etc. Resulting values can be
325  * correctly outside of monitor bounds. NOTE: You cannot specify #WS_OVERLAPPED when calling. */
326  if (fpAdjustWindowRectExForDpi) {
327  UINT dpiX, dpiY;
328  GetDpiForMonitor(hmonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
329  fpAdjustWindowRectExForDpi(win_rect, dwStyle & ~WS_OVERLAPPED, FALSE, dwExStyle, dpiX);
330  }
331  else {
332  AdjustWindowRectEx(win_rect, dwStyle & ~WS_OVERLAPPED, FALSE, dwExStyle);
333  }
334 
335  /* But never allow a top position that can hide part of the title bar. */
336  win_rect->top = max(monitor.rcWork.top, win_rect->top);
337 }
338 
340 {
341  return GHOST_Window::getValid() && m_hWnd != 0 && m_hDC != 0;
342 }
343 
345 {
346  return m_hWnd;
347 }
348 
349 void GHOST_WindowWin32::setTitle(const char *title)
350 {
351  wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
352  ::SetWindowTextW(m_hWnd, (wchar_t *)title_16);
353  free(title_16);
354 }
355 
356 std::string GHOST_WindowWin32::getTitle() const
357 {
358  std::wstring wtitle(::GetWindowTextLengthW(m_hWnd) + 1, L'\0');
359  ::GetWindowTextW(m_hWnd, &wtitle[0], wtitle.capacity());
360 
361  std::string title(count_utf_8_from_16(wtitle.c_str()) + 1, '\0');
362  conv_utf_16_to_8(wtitle.c_str(), &title[0], title.capacity());
363 
364  return title;
365 }
366 
368 {
369  RECT rect;
370  ::GetWindowRect(m_hWnd, &rect);
371  bounds.m_b = rect.bottom;
372  bounds.m_l = rect.left;
373  bounds.m_r = rect.right;
374  bounds.m_t = rect.top;
375 }
376 
378 {
379  RECT rect;
380  POINT coord;
381  if (!IsIconic(m_hWnd)) {
382  ::GetClientRect(m_hWnd, &rect);
383 
384  coord.x = rect.left;
385  coord.y = rect.top;
386  ::ClientToScreen(m_hWnd, &coord);
387 
388  bounds.m_l = coord.x;
389  bounds.m_t = coord.y;
390 
391  coord.x = rect.right;
392  coord.y = rect.bottom;
393  ::ClientToScreen(m_hWnd, &coord);
394 
395  bounds.m_r = coord.x;
396  bounds.m_b = coord.y;
397  }
398  else {
399  bounds.m_b = 0;
400  bounds.m_l = 0;
401  bounds.m_r = 0;
402  bounds.m_t = 0;
403  }
404 }
405 
407 {
408  GHOST_TSuccess success;
409  GHOST_Rect cBnds, wBnds;
410  getClientBounds(cBnds);
411  if (cBnds.getWidth() != (int32_t)width) {
412  getWindowBounds(wBnds);
413  int cx = wBnds.getWidth() + width - cBnds.getWidth();
414  int cy = wBnds.getHeight();
415  success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
418  }
419  else {
420  success = GHOST_kSuccess;
421  }
422  return success;
423 }
424 
426 {
427  GHOST_TSuccess success;
428  GHOST_Rect cBnds, wBnds;
429  getClientBounds(cBnds);
430  if (cBnds.getHeight() != (int32_t)height) {
431  getWindowBounds(wBnds);
432  int cx = wBnds.getWidth();
433  int cy = wBnds.getHeight() + height - cBnds.getHeight();
434  success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
437  }
438  else {
439  success = GHOST_kSuccess;
440  }
441  return success;
442 }
443 
445 {
446  GHOST_TSuccess success;
447  GHOST_Rect cBnds, wBnds;
448  getClientBounds(cBnds);
449  if ((cBnds.getWidth() != (int32_t)width) || (cBnds.getHeight() != (int32_t)height)) {
450  getWindowBounds(wBnds);
451  int cx = wBnds.getWidth() + width - cBnds.getWidth();
452  int cy = wBnds.getHeight() + height - cBnds.getHeight();
453  success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
456  }
457  else {
458  success = GHOST_kSuccess;
459  }
460  return success;
461 }
462 
464 {
465  if (::IsIconic(m_hWnd)) {
467  }
468  else if (::IsZoomed(m_hWnd)) {
469  LONG_PTR result = ::GetWindowLongPtr(m_hWnd, GWL_STYLE);
471  }
473 }
474 
476  int32_t inY,
477  int32_t &outX,
478  int32_t &outY) const
479 {
480  POINT point = {inX, inY};
481  ::ScreenToClient(m_hWnd, &point);
482  outX = point.x;
483  outY = point.y;
484 }
485 
487  int32_t inY,
488  int32_t &outX,
489  int32_t &outY) const
490 {
491  POINT point = {inX, inY};
492  ::ClientToScreen(m_hWnd, &point);
493  outX = point.x;
494  outY = point.y;
495 }
496 
498 {
499  GHOST_TWindowState curstate = getState();
500  LONG_PTR style = GetWindowLongPtr(m_hWnd, GWL_STYLE) | WS_CAPTION;
501  WINDOWPLACEMENT wp;
502  wp.length = sizeof(WINDOWPLACEMENT);
503  ::GetWindowPlacement(m_hWnd, &wp);
504 
505  switch (state) {
507  wp.showCmd = SW_MINIMIZE;
508  break;
510  wp.showCmd = SW_SHOWMAXIMIZED;
511  break;
513  if (curstate != state && curstate != GHOST_kWindowStateMinimized) {
514  m_normal_state = curstate;
515  }
516  wp.showCmd = SW_SHOWMAXIMIZED;
517  wp.ptMaxPosition.x = 0;
518  wp.ptMaxPosition.y = 0;
519  style &= ~(WS_CAPTION | WS_MAXIMIZE);
520  break;
522  default:
523  if (curstate == GHOST_kWindowStateFullScreen &&
524  m_normal_state == GHOST_kWindowStateMaximized) {
525  wp.showCmd = SW_SHOWMAXIMIZED;
526  m_normal_state = GHOST_kWindowStateNormal;
527  }
528  else {
529  wp.showCmd = SW_SHOWNORMAL;
530  }
531  break;
532  }
533  ::SetWindowLongPtr(m_hWnd, GWL_STYLE, style);
534  /* SetWindowLongPtr Docs: frame changes not visible until SetWindowPos with SWP_FRAMECHANGED. */
535  ::SetWindowPos(m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
536  return ::SetWindowPlacement(m_hWnd, &wp) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
537 }
538 
540 {
541  HWND hWndInsertAfter, hWndToRaise;
542 
544  hWndInsertAfter = HWND_BOTTOM;
545  hWndToRaise = ::GetWindow(m_hWnd, GW_HWNDNEXT); /* the window to raise */
546  }
547  else {
550  }
551  hWndInsertAfter = HWND_TOP;
552  hWndToRaise = NULL;
553  }
554 
555  if (::SetWindowPos(m_hWnd, hWndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == FALSE) {
556  return GHOST_kFailure;
557  }
558 
559  if (hWndToRaise &&
560  ::SetWindowPos(hWndToRaise, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == FALSE) {
561  return GHOST_kFailure;
562  }
563  return GHOST_kSuccess;
564 }
565 
567 {
568  GHOST_TSuccess success;
569  if (m_hWnd) {
570  success = ::InvalidateRect(m_hWnd, 0, FALSE) != 0 ? GHOST_kSuccess : GHOST_kFailure;
571  }
572  else {
573  success = GHOST_kFailure;
574  }
575  return success;
576 }
577 
578 GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType type)
579 {
582 
583 #if defined(WITH_GL_PROFILE_CORE)
584  /* - AMD and Intel give us exactly this version
585  * - NVIDIA gives at least this version <-- desired behavior
586  * So we ask for 4.5, 4.4 ... 3.3 in descending order
587  * to get the best version on the user's system. */
588  for (int minor = 5; minor >= 0; --minor) {
590  m_wantAlphaBackground,
591  m_hWnd,
592  m_hDC,
593  WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
594  4,
595  minor,
596  (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
598 
599  if (context->initializeDrawingContext()) {
600  return context;
601  }
602  else {
603  delete context;
604  }
605  }
607  m_wantAlphaBackground,
608  m_hWnd,
609  m_hDC,
610  WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
611  3,
612  3,
613  (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
615 
616  if (context && !context->initializeDrawingContext()) {
617  delete context;
618  context = nullptr;
619  }
620 
621  return context;
622 
623 #elif defined(WITH_GL_PROFILE_COMPAT)
624  // ask for 2.1 context, driver gives any GL version >= 2.1
625  // (hopefully the latest compatibility profile)
626  // 2.1 ignores the profile bit & is incompatible with core profile
628  m_wantAlphaBackground,
629  m_hWnd,
630  m_hDC,
631  0, // no profile bit
632  2,
633  1,
634  (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
636 
637  if (context->initializeDrawingContext()) {
638  return context;
639  }
640  else {
641  delete context;
642  }
643 #else
644 # error // must specify either core or compat at build time
645 #endif
646  }
647  else if (type == GHOST_kDrawingContextTypeD3D) {
649 
650  context = new GHOST_ContextD3D(false, m_hWnd);
651  if (context->initializeDrawingContext()) {
652  return context;
653  }
654  else {
655  delete context;
656  }
657 
658  return context;
659  }
660 
661  return NULL;
662 }
663 
665 {
666  if (m_hasMouseCaptured) {
667  m_hasGrabMouse = false;
668  m_nPressedButtons = 0;
669  m_hasMouseCaptured = false;
670  }
671 }
672 
674 {
675  return m_isDialog;
676 }
677 
679 {
680  switch (event) {
681  case MousePressed:
682  m_nPressedButtons++;
683  break;
684  case MouseReleased:
685  if (m_nPressedButtons)
686  m_nPressedButtons--;
687  break;
688  case OperatorGrab:
689  m_hasGrabMouse = true;
690  break;
691  case OperatorUngrab:
692  m_hasGrabMouse = false;
693  break;
694  }
695 
696  if (!m_nPressedButtons && !m_hasGrabMouse && m_hasMouseCaptured) {
697  ::ReleaseCapture();
698  m_hasMouseCaptured = false;
699  }
700  else if ((m_nPressedButtons || m_hasGrabMouse) && !m_hasMouseCaptured) {
701  ::SetCapture(m_hWnd);
702  m_hasMouseCaptured = true;
703  }
704 }
705 
707 {
708  // Convert GHOST cursor to Windows OEM cursor
709  HANDLE cursor = NULL;
710  HMODULE module = ::GetModuleHandle(0);
711  uint32_t flags = LR_SHARED | LR_DEFAULTSIZE;
712  int cx = 0, cy = 0;
713 
714  switch (shape) {
716  if (m_customCursor) {
717  return m_customCursor;
718  }
719  else {
720  return NULL;
721  }
723  cursor = ::LoadImage(module, "arrowright_cursor", IMAGE_CURSOR, cx, cy, flags);
724  break;
726  cursor = ::LoadImage(module, "arrowleft_cursor", IMAGE_CURSOR, cx, cy, flags);
727  break;
729  cursor = ::LoadImage(module, "arrowup_cursor", IMAGE_CURSOR, cx, cy, flags);
730  break;
732  cursor = ::LoadImage(module, "arrowdown_cursor", IMAGE_CURSOR, cx, cy, flags);
733  break;
735  cursor = ::LoadImage(module, "splitv_cursor", IMAGE_CURSOR, cx, cy, flags);
736  break;
738  cursor = ::LoadImage(module, "splith_cursor", IMAGE_CURSOR, cx, cy, flags);
739  break;
741  cursor = ::LoadImage(module, "knife_cursor", IMAGE_CURSOR, cx, cy, flags);
742  break;
744  cursor = ::LoadImage(module, "eyedropper_cursor", IMAGE_CURSOR, cx, cy, flags);
745  break;
747  cursor = ::LoadImage(module, "zoomin_cursor", IMAGE_CURSOR, cx, cy, flags);
748  break;
750  cursor = ::LoadImage(module, "zoomout_cursor", IMAGE_CURSOR, cx, cy, flags);
751  break;
753  cursor = ::LoadImage(module, "handopen_cursor", IMAGE_CURSOR, cx, cy, flags);
754  break;
756  cursor = ::LoadImage(module, "scrollnsew_cursor", IMAGE_CURSOR, cx, cy, flags);
757  break;
759  cursor = ::LoadImage(module, "scrollns_cursor", IMAGE_CURSOR, cx, cy, flags);
760  break;
762  cursor = ::LoadImage(module, "scrollew_cursor", IMAGE_CURSOR, cx, cy, flags);
763  break;
765  cursor = ::LoadImage(NULL, IDC_HELP, IMAGE_CURSOR, cx, cy, flags);
766  break; // Arrow and question mark
768  cursor = ::LoadImage(NULL, IDC_WAIT, IMAGE_CURSOR, cx, cy, flags);
769  break; // Hourglass
771  cursor = ::LoadImage(NULL, IDC_IBEAM, IMAGE_CURSOR, cx, cy, flags);
772  break; // I-beam
774  cursor = ::LoadImage(module, "cross_cursor", IMAGE_CURSOR, cx, cy, flags);
775  break; // Standard Cross
777  cursor = ::LoadImage(module, "crossA_cursor", IMAGE_CURSOR, cx, cy, flags);
778  break; // Crosshair A
780  cursor = ::LoadImage(module, "crossB_cursor", IMAGE_CURSOR, cx, cy, flags);
781  break; // Diagonal Crosshair B
783  cursor = ::LoadImage(module, "crossC_cursor", IMAGE_CURSOR, cx, cy, flags);
784  break; // Minimal Crosshair C
787  cursor = ::LoadImage(module, "movens_cursor", IMAGE_CURSOR, cx, cy, flags);
788  break; // Double-pointed arrow pointing north and south
791  cursor = ::LoadImage(module, "moveew_cursor", IMAGE_CURSOR, cx, cy, flags);
792  break; // Double-pointed arrow pointing west and east
794  cursor = ::LoadImage(NULL, IDC_UPARROW, IMAGE_CURSOR, cx, cy, flags);
795  break; // Vertical arrow
797  cursor = ::LoadImage(NULL, IDC_SIZENWSE, IMAGE_CURSOR, cx, cy, flags);
798  break;
800  cursor = ::LoadImage(NULL, IDC_SIZENESW, IMAGE_CURSOR, cx, cy, flags);
801  break;
803  cursor = ::LoadImage(NULL, IDC_SIZENWSE, IMAGE_CURSOR, cx, cy, flags);
804  break;
806  cursor = ::LoadImage(NULL, IDC_SIZENESW, IMAGE_CURSOR, cx, cy, flags);
807  break;
809  cursor = ::LoadImage(module, "pencil_cursor", IMAGE_CURSOR, cx, cy, flags);
810  break;
812  cursor = ::LoadImage(module, "eraser_cursor", IMAGE_CURSOR, cx, cy, flags);
813  break;
816  cursor = ::LoadImage(module, "forbidden_cursor", IMAGE_CURSOR, cx, cy, flags);
817  break; // Slashed circle
819  cursor = NULL;
820  break;
821  default:
822  return NULL;
823  }
824 
825  if (cursor == NULL) {
826  cursor = ::LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, cx, cy, flags);
827  }
828 
829  return (HCURSOR)cursor;
830 }
831 
833 {
834  if (!visible) {
835  while (::ShowCursor(FALSE) >= 0)
836  ;
837  }
838  else {
839  while (::ShowCursor(TRUE) < 0)
840  ;
841  }
842 
843  HCURSOR cursor = getStandardCursor(shape);
844  if (cursor == NULL) {
846  }
847  ::SetCursor(cursor);
848 }
849 
850 GHOST_TSuccess GHOST_WindowWin32::setWindowCursorVisibility(bool visible)
851 {
852  if (::GetForegroundWindow() == m_hWnd) {
853  loadCursor(visible, getCursorShape());
854  }
855 
856  return GHOST_kSuccess;
857 }
858 
859 GHOST_TSuccess GHOST_WindowWin32::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
860 {
861  if (mode != GHOST_kGrabDisable) {
862  if (mode != GHOST_kGrabNormal) {
864  setCursorGrabAccum(0, 0);
865 
866  if (mode == GHOST_kGrabHide)
867  setWindowCursorVisibility(false);
868  }
870  }
871  else {
872  if (m_cursorGrab == GHOST_kGrabHide) {
874  setWindowCursorVisibility(true);
875  }
877  /* use to generate a mouse move event, otherwise the last event
878  * blender gets can be outside the screen causing menus not to show
879  * properly unless the user moves the mouse */
880  int32_t pos[2];
881  m_system->getCursorPosition(pos[0], pos[1]);
882  m_system->setCursorPosition(pos[0], pos[1]);
883  }
884 
885  /* Almost works without but important otherwise the mouse GHOST location
886  * can be incorrect on exit. */
887  setCursorGrabAccum(0, 0);
888  m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
890  }
891 
892  return GHOST_kSuccess;
893 }
894 
895 GHOST_TSuccess GHOST_WindowWin32::setWindowCursorShape(GHOST_TStandardCursor cursorShape)
896 {
897  if (::GetForegroundWindow() == m_hWnd) {
898  loadCursor(getCursorVisibility(), cursorShape);
899  }
900 
901  return GHOST_kSuccess;
902 }
903 
904 GHOST_TSuccess GHOST_WindowWin32::hasCursorShape(GHOST_TStandardCursor cursorShape)
905 {
906  return (getStandardCursor(cursorShape)) ? GHOST_kSuccess : GHOST_kFailure;
907 }
908 
910  std::vector<GHOST_PointerInfoWin32> &outPointerInfo, WPARAM wParam, LPARAM lParam)
911 {
912  int32_t pointerId = GET_POINTERID_WPARAM(wParam);
913  int32_t isPrimary = IS_POINTER_PRIMARY_WPARAM(wParam);
915  uint32_t outCount = 0;
916 
917  if (!(GetPointerPenInfoHistory(pointerId, &outCount, NULL))) {
918  return GHOST_kFailure;
919  }
920 
921  std::vector<POINTER_PEN_INFO> pointerPenInfo(outCount);
922  outPointerInfo.resize(outCount);
923 
924  if (!(GetPointerPenInfoHistory(pointerId, &outCount, pointerPenInfo.data()))) {
925  return GHOST_kFailure;
926  }
927 
928  for (uint32_t i = 0; i < outCount; i++) {
929  POINTER_INFO pointerApiInfo = pointerPenInfo[i].pointerInfo;
930  // Obtain the basic information from the event
931  outPointerInfo[i].pointerId = pointerId;
932  outPointerInfo[i].isPrimary = isPrimary;
933 
934  switch (pointerApiInfo.ButtonChangeType) {
935  case POINTER_CHANGE_FIRSTBUTTON_DOWN:
936  case POINTER_CHANGE_FIRSTBUTTON_UP:
937  outPointerInfo[i].buttonMask = GHOST_kButtonMaskLeft;
938  break;
939  case POINTER_CHANGE_SECONDBUTTON_DOWN:
940  case POINTER_CHANGE_SECONDBUTTON_UP:
941  outPointerInfo[i].buttonMask = GHOST_kButtonMaskRight;
942  break;
943  case POINTER_CHANGE_THIRDBUTTON_DOWN:
944  case POINTER_CHANGE_THIRDBUTTON_UP:
945  outPointerInfo[i].buttonMask = GHOST_kButtonMaskMiddle;
946  break;
947  case POINTER_CHANGE_FOURTHBUTTON_DOWN:
948  case POINTER_CHANGE_FOURTHBUTTON_UP:
949  outPointerInfo[i].buttonMask = GHOST_kButtonMaskButton4;
950  break;
951  case POINTER_CHANGE_FIFTHBUTTON_DOWN:
952  case POINTER_CHANGE_FIFTHBUTTON_UP:
953  outPointerInfo[i].buttonMask = GHOST_kButtonMaskButton5;
954  break;
955  default:
956  break;
957  }
958 
959  outPointerInfo[i].pixelLocation = pointerApiInfo.ptPixelLocation;
960  outPointerInfo[i].tabletData.Active = GHOST_kTabletModeStylus;
961  outPointerInfo[i].tabletData.Pressure = 1.0f;
962  outPointerInfo[i].tabletData.Xtilt = 0.0f;
963  outPointerInfo[i].tabletData.Ytilt = 0.0f;
964  outPointerInfo[i].time = system->performanceCounterToMillis(pointerApiInfo.PerformanceCount);
965 
966  if (pointerPenInfo[i].penMask & PEN_MASK_PRESSURE) {
967  outPointerInfo[i].tabletData.Pressure = pointerPenInfo[i].pressure / 1024.0f;
968  }
969 
970  if (pointerPenInfo[i].penFlags & PEN_FLAG_ERASER) {
971  outPointerInfo[i].tabletData.Active = GHOST_kTabletModeEraser;
972  }
973 
974  if (pointerPenInfo[i].penMask & PEN_MASK_TILT_X) {
975  outPointerInfo[i].tabletData.Xtilt = fmin(fabs(pointerPenInfo[i].tiltX / 90.0f), 1.0f);
976  }
977 
978  if (pointerPenInfo[i].penMask & PEN_MASK_TILT_Y) {
979  outPointerInfo[i].tabletData.Ytilt = fmin(fabs(pointerPenInfo[i].tiltY / 90.0f), 1.0f);
980  }
981  }
982 
983  if (!outPointerInfo.empty()) {
984  m_lastPointerTabletData = outPointerInfo.back().tabletData;
985  }
986 
987  return GHOST_kSuccess;
988 }
989 
991 {
992  m_lastPointerTabletData = GHOST_TABLET_DATA_NONE;
993 }
994 
996 {
997  return m_wintab;
998 }
999 
1001 {
1002  if (!m_wintab) {
1003  WINTAB_PRINTF("Loading Wintab for window %p\n", m_hWnd);
1004  if (m_wintab = GHOST_Wintab::loadWintab(m_hWnd)) {
1005  if (enable) {
1006  m_wintab->enable();
1007 
1008  /* Focus Wintab if cursor is inside this window. This ensures Wintab is enabled when the
1009  * tablet is used to change the Tablet API. */
1010  int32_t x, y;
1011  if (m_system->getCursorPosition(x, y)) {
1012  GHOST_Rect rect;
1013  getClientBounds(rect);
1014 
1015  if (rect.isInside(x, y)) {
1016  m_wintab->gainFocus();
1017  }
1018  }
1019  }
1020  }
1021  }
1022 }
1023 
1025 {
1026  WINTAB_PRINTF("Closing Wintab for window %p\n", m_hWnd);
1027  delete m_wintab;
1028  m_wintab = NULL;
1029 }
1030 
1032 {
1033  if (m_system->getTabletAPI() == api) {
1034  return true;
1035  }
1036  else if (m_system->getTabletAPI() == GHOST_kTabletAutomatic) {
1037  if (m_wintab && m_wintab->devicesPresent()) {
1038  return api == GHOST_kTabletWintab;
1039  }
1040  else {
1041  return api == GHOST_kTabletWinPointer;
1042  }
1043  }
1044  else {
1045  return false;
1046  }
1047 }
1048 
1050 {
1052  return m_wintab ? m_wintab->getLastTabletData() : GHOST_TABLET_DATA_NONE;
1053  }
1054  else {
1055  return m_lastPointerTabletData;
1056  }
1057 }
1058 
1060 {
1061  DWORD lightMode;
1062  DWORD pcbData = sizeof(lightMode);
1063  if (RegGetValueW(HKEY_CURRENT_USER,
1064  L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize\\",
1065  L"AppsUseLightTheme",
1066  RRF_RT_REG_DWORD,
1067  NULL,
1068  &lightMode,
1069  &pcbData) == ERROR_SUCCESS) {
1070  BOOL DarkMode = !lightMode;
1071 
1072  /* 20 == DWMWA_USE_IMMERSIVE_DARK_MODE in Windows 11 SDK. This value was undocumented for
1073  * Windows 10 versions 2004 and later, supported for Windows 11 Build 22000 and later. */
1074  DwmSetWindowAttribute(this->m_hWnd, 20, &DarkMode, sizeof(DarkMode));
1075  }
1076 }
1077 
1079 {
1080  if (m_directManipulationHelper) {
1081  m_directManipulationHelper->setDPI(getDPIHint());
1082  }
1083 }
1084 
1086 {
1087  if (m_user32) {
1088  GHOST_WIN32_GetDpiForWindow fpGetDpiForWindow = (GHOST_WIN32_GetDpiForWindow)::GetProcAddress(
1089  m_user32, "GetDpiForWindow");
1090 
1091  if (fpGetDpiForWindow) {
1092  return fpGetDpiForWindow(this->m_hWnd);
1093  }
1094  }
1095 
1096  return USER_DEFAULT_SCREEN_DPI;
1097 }
1098 
1101 {
1102  ch = ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA);
1103  ch = ((ch >> 2) & 0x33) | ((ch << 2) & 0xCC);
1104  ch = ((ch >> 4) & 0x0F) | ((ch << 4) & 0xF0);
1105  return ch;
1106 }
1107 
1108 #if 0 /* UNUSED */
1110 static uint16_t uns16ReverseBits(uint16_t shrt)
1111 {
1112  shrt = ((shrt >> 1) & 0x5555) | ((shrt << 1) & 0xAAAA);
1113  shrt = ((shrt >> 2) & 0x3333) | ((shrt << 2) & 0xCCCC);
1114  shrt = ((shrt >> 4) & 0x0F0F) | ((shrt << 4) & 0xF0F0);
1115  shrt = ((shrt >> 8) & 0x00FF) | ((shrt << 8) & 0xFF00);
1116  return shrt;
1117 }
1118 #endif
1119 
1120 GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(
1121  uint8_t *bitmap, uint8_t *mask, int sizeX, int sizeY, int hotX, int hotY, bool canInvertColor)
1122 {
1123  uint32_t andData[32];
1124  uint32_t xorData[32];
1125  uint32_t fullBitRow, fullMaskRow;
1126  int x, y, cols;
1127 
1128  cols = sizeX / 8; /* Number of whole bytes per row (width of bitmap/mask). */
1129  if (sizeX % 8)
1130  cols++;
1131 
1132  if (m_customCursor) {
1133  DestroyCursor(m_customCursor);
1134  m_customCursor = NULL;
1135  }
1136 
1137  memset(&andData, 0xFF, sizeof(andData));
1138  memset(&xorData, 0, sizeof(xorData));
1139 
1140  for (y = 0; y < sizeY; y++) {
1141  fullBitRow = 0;
1142  fullMaskRow = 0;
1143  for (x = cols - 1; x >= 0; x--) {
1144  fullBitRow <<= 8;
1145  fullMaskRow <<= 8;
1146  fullBitRow |= uns8ReverseBits(bitmap[cols * y + x]);
1147  fullMaskRow |= uns8ReverseBits(mask[cols * y + x]);
1148  }
1149  xorData[y] = fullBitRow & fullMaskRow;
1150  andData[y] = ~fullMaskRow;
1151  }
1152 
1153  m_customCursor = ::CreateCursor(::GetModuleHandle(0), hotX, hotY, 32, 32, andData, xorData);
1154  if (!m_customCursor) {
1155  return GHOST_kFailure;
1156  }
1157 
1158  if (::GetForegroundWindow() == m_hWnd) {
1160  }
1161 
1162  return GHOST_kSuccess;
1163 }
1164 
1166 {
1167  /* #SetProgressValue sets state to #TBPF_NORMAL automatically. */
1168  if (m_Bar && S_OK == m_Bar->SetProgressValue(m_hWnd, 10000 * progress, 10000))
1169  return GHOST_kSuccess;
1170 
1171  return GHOST_kFailure;
1172 }
1173 
1175 {
1176  if (m_Bar && S_OK == m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS))
1177  return GHOST_kSuccess;
1178 
1179  return GHOST_kFailure;
1180 }
1181 
1182 #ifdef WITH_INPUT_IME
1183 void GHOST_WindowWin32::beginIME(int32_t x, int32_t y, int32_t w, int32_t h, bool completed)
1184 {
1185  m_imeInput.BeginIME(m_hWnd, GHOST_Rect(x, y - h, x, y), completed);
1186 }
1187 
1188 void GHOST_WindowWin32::endIME()
1189 {
1190  m_imeInput.EndIME(m_hWnd);
1191 }
1192 #endif /* WITH_INPUT_IME */
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:102
#define FALSE
Definition: GHOST_C-Test.c:17
#define GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY
@ TBPF_NOPROGRESS
const GUID CLSID_TaskbarList
GHOST_TWindowState
Definition: GHOST_Types.h:129
@ GHOST_kWindowStateMinimized
Definition: GHOST_Types.h:132
@ GHOST_kWindowStateMaximized
Definition: GHOST_Types.h:131
@ GHOST_kWindowStateNormal
Definition: GHOST_Types.h:130
@ GHOST_kWindowStateFullScreen
Definition: GHOST_Types.h:133
GHOST_TStandardCursor
Definition: GHOST_Types.h:214
@ GHOST_kStandardCursorBottomLeftCorner
Definition: GHOST_Types.h:252
@ GHOST_kStandardCursorZoomIn
Definition: GHOST_Types.h:236
@ GHOST_kStandardCursorVerticalSplit
Definition: GHOST_Types.h:231
@ GHOST_kStandardCursorHelp
Definition: GHOST_Types.h:221
@ GHOST_kStandardCursorWait
Definition: GHOST_Types.h:222
@ GHOST_kStandardCursorHorizontalSplit
Definition: GHOST_Types.h:232
@ GHOST_kStandardCursorTopSide
Definition: GHOST_Types.h:245
@ GHOST_kStandardCursorStop
Definition: GHOST_Types.h:242
@ GHOST_kStandardCursorCrosshair
Definition: GHOST_Types.h:224
@ GHOST_kStandardCursorCustom
Definition: GHOST_Types.h:254
@ GHOST_kStandardCursorNSEWScroll
Definition: GHOST_Types.h:239
@ GHOST_kStandardCursorLeftRight
Definition: GHOST_Types.h:244
@ GHOST_kStandardCursorPencil
Definition: GHOST_Types.h:228
@ GHOST_kStandardCursorNSScroll
Definition: GHOST_Types.h:240
@ GHOST_kStandardCursorCrosshairA
Definition: GHOST_Types.h:225
@ GHOST_kStandardCursorUpDown
Definition: GHOST_Types.h:243
@ GHOST_kStandardCursorUpArrow
Definition: GHOST_Types.h:229
@ GHOST_kStandardCursorBottomSide
Definition: GHOST_Types.h:246
@ GHOST_kStandardCursorTopLeftCorner
Definition: GHOST_Types.h:249
@ GHOST_kStandardCursorEyedropper
Definition: GHOST_Types.h:235
@ GHOST_kStandardCursorKnife
Definition: GHOST_Types.h:234
@ GHOST_kStandardCursorMove
Definition: GHOST_Types.h:238
@ GHOST_kStandardCursorCrosshairB
Definition: GHOST_Types.h:226
@ GHOST_kStandardCursorBottomRightCorner
Definition: GHOST_Types.h:251
@ GHOST_kStandardCursorDownArrow
Definition: GHOST_Types.h:230
@ GHOST_kStandardCursorEraser
Definition: GHOST_Types.h:233
@ GHOST_kStandardCursorDefault
Definition: GHOST_Types.h:216
@ GHOST_kStandardCursorEWScroll
Definition: GHOST_Types.h:241
@ GHOST_kStandardCursorRightArrow
Definition: GHOST_Types.h:217
@ GHOST_kStandardCursorTopRightCorner
Definition: GHOST_Types.h:250
@ GHOST_kStandardCursorDestroy
Definition: GHOST_Types.h:220
@ GHOST_kStandardCursorCrosshairC
Definition: GHOST_Types.h:227
@ GHOST_kStandardCursorZoomOut
Definition: GHOST_Types.h:237
@ GHOST_kStandardCursorLeftSide
Definition: GHOST_Types.h:247
@ GHOST_kStandardCursorText
Definition: GHOST_Types.h:223
@ GHOST_kStandardCursorLeftArrow
Definition: GHOST_Types.h:218
static const GHOST_TabletData GHOST_TABLET_DATA_NONE
Definition: GHOST_Types.h:104
@ GHOST_kTabletModeEraser
Definition: GHOST_Types.h:86
@ GHOST_kTabletModeStylus
Definition: GHOST_Types.h:85
GHOST_TDrawingContextType
Definition: GHOST_Types.h:148
@ GHOST_kDrawingContextTypeOpenGL
Definition: GHOST_Types.h:150
GHOST_TWindowOrder
Definition: GHOST_Types.h:146
@ GHOST_kWindowOrderBottom
Definition: GHOST_Types.h:146
GHOST_TSuccess
Definition: GHOST_Types.h:74
@ GHOST_kFailure
Definition: GHOST_Types.h:74
@ GHOST_kSuccess
Definition: GHOST_Types.h:74
GHOST_TGrabCursorMode
Definition: GHOST_Types.h:404
@ GHOST_kGrabDisable
Definition: GHOST_Types.h:406
@ GHOST_kGrabHide
Definition: GHOST_Types.h:415
@ GHOST_kGrabNormal
Definition: GHOST_Types.h:408
@ GHOST_kButtonMaskRight
Definition: GHOST_Types.h:160
@ GHOST_kButtonMaskButton4
Definition: GHOST_Types.h:161
@ GHOST_kButtonMaskLeft
Definition: GHOST_Types.h:158
@ GHOST_kButtonMaskButton5
Definition: GHOST_Types.h:162
@ GHOST_kButtonMaskMiddle
Definition: GHOST_Types.h:159
GHOST_TTabletAPI
Definition: GHOST_Types.h:89
@ GHOST_kTabletAutomatic
Definition: GHOST_Types.h:90
@ GHOST_kTabletWinPointer
Definition: GHOST_Types.h:93
@ GHOST_kTabletWintab
Definition: GHOST_Types.h:94
static uint16_t uns16ReverseBits(uint16_t shrt)
#define GET_POINTERID_WPARAM(wParam)
static uint8_t uns8ReverseBits(uint8_t ch)
__declspec(dllexport) DWORD NvOptimusEnablement=0x00000001
BOOL(API * GHOST_WIN32_AdjustWindowRectExForDpi)(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi)
GHOST_MouseCaptureEventWin32
@ MousePressed
@ OperatorUngrab
@ MouseReleased
@ OperatorGrab
typedef UINT(API *GHOST_WIN32_GetDpiForWindow)(HWND)
#define WINTAB_PRINTF(x,...)
Definition: GHOST_Wintab.h:29
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble top
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint order
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition: btDbvt.cpp:299
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
void onPointerHitTest(UINT32 pointerId)
static GHOST_DirectManipulationHelper * create(HWND hWnd, uint16_t dpi)
ULONG __stdcall Release(void)
static GHOST_ISystem * getSystem()
virtual bool isInside(int32_t x, int32_t y) const
Definition: GHOST_Rect.h:274
int32_t m_l
Definition: GHOST_Rect.h:156
int32_t m_r
Definition: GHOST_Rect.h:160
virtual int32_t getHeight() const
Definition: GHOST_Rect.h:174
virtual int32_t getWidth() const
Definition: GHOST_Rect.h:169
GHOST_TSuccess setCursorPosition(int32_t x, int32_t y)
GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const
uint64_t performanceCounterToMillis(__int64 perf_ticks) const
GHOST_WindowManager * getWindowManager() const
Definition: GHOST_System.h:432
GHOST_TTabletAPI getTabletAPI(void)
bool m_windowFocus
Definition: GHOST_System.h:162
const std::vector< GHOST_IWindow * > & getWindows() const
GHOST_TSuccess invalidate()
GHOST_TSuccess setOrder(GHOST_TWindowOrder order)
uint16_t getDPIHint() override
GHOST_TTrackpadInfo getTrackpadInfo()
GHOST_TSuccess setProgressBar(float progress)
void setTitle(const char *title)
std::string getTitle() const
GHOST_TSuccess setClientSize(uint32_t width, uint32_t height)
void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const
bool usingTabletAPI(GHOST_TTabletAPI api) const
GHOST_TSuccess getPointerInfo(std::vector< GHOST_PointerInfoWin32 > &outPointerInfo, WPARAM wParam, LPARAM lParam)
GHOST_TSuccess setClientHeight(uint32_t height)
void loadWintab(bool enable)
GHOST_TabletData getTabletData()
GHOST_Wintab * getWintab() const
HCURSOR getStandardCursor(GHOST_TStandardCursor shape) const
void updateMouseCapture(GHOST_MouseCaptureEventWin32 event)
GHOST_TSuccess setClientWidth(uint32_t width)
GHOST_TSuccess setState(GHOST_TWindowState state)
void getWindowBounds(GHOST_Rect &bounds) const
void getClientBounds(GHOST_Rect &bounds) const
void onPointerHitTest(WPARAM wParam)
GHOST_WindowWin32(GHOST_SystemWin32 *system, const char *title, int32_t left, int32_t top, uint32_t width, uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type=GHOST_kDrawingContextTypeNone, bool wantStereoVisual=false, bool alphaBackground=false, GHOST_WindowWin32 *parentWindow=0, bool is_debug=false, bool dialog=false)
void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const
GHOST_TSuccess endProgressBar()
GHOST_TWindowState getState() const
void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const
void adjustWindowRectForClosestMonitor(LPRECT win_rect, DWORD dwStyle, DWORD dwExStyle)
GHOST_Rect m_cursorGrabBounds
Definition: GHOST_Window.h:371
bool getCursorVisibility() const
Definition: GHOST_Window.h:408
void setCursorGrabAccum(int32_t x, int32_t y)
Definition: GHOST_Window.h:440
GHOST_TGrabCursorMode m_cursorGrab
Definition: GHOST_Window.h:359
bool m_wantStereoVisual
Definition: GHOST_Window.h:389
int32_t m_cursorGrabInitPos[2]
Definition: GHOST_Window.h:365
GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type)
GHOST_TSuccess releaseNativeHandles()
virtual bool getValid() const
Definition: GHOST_Window.h:75
GHOST_TStandardCursor getCursorShape() const
Definition: GHOST_Window.h:446
GHOST_TabletData getLastTabletData()
bool devicesPresent()
static GHOST_Wintab * loadWintab(HWND hwnd)
virtual HRESULT STDMETHODCALLTYPE SetProgressState(HWND hwnd, TBPFLAG tbpFlags)=0
virtual HRESULT STDMETHODCALLTYPE SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal)=0
uint pos
const int state
ccl_device_inline float2 fabs(const float2 &a)
Definition: math_float2.h:222
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static int left
#define L
static const VertexNature POINT
Definition: Nature.h:20
static struct PyModuleDef module
Definition: python.cpp:972
#define min(a, b)
Definition: sort.c:35
unsigned short uint16_t
Definition: stdint.h:79
unsigned int uint32_t
Definition: stdint.h:80
signed int int32_t
Definition: stdint.h:77
unsigned char uint8_t
Definition: stdint.h:78
float max
size_t count_utf_8_from_16(const wchar_t *string16)
Definition: utfconv.c:10
wchar_t * alloc_utf16_from_8(const char *in8, size_t add)
Definition: utfconv.c:291
int conv_utf_16_to_8(const wchar_t *in16, char *out8, size_t size8)
Definition: utfconv.c:115