Blender  V2.93
GHOST_WindowWin32.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #define _USE_MATH_DEFINES
25 
26 #include "GHOST_WindowWin32.h"
27 #include "GHOST_ContextD3D.h"
28 #include "GHOST_ContextNone.h"
29 #include "GHOST_DropTargetWin32.h"
30 #include "GHOST_SystemWin32.h"
31 #include "GHOST_WindowManager.h"
32 #include "utf_winfunc.h"
33 #include "utfconv.h"
34 
35 #if defined(WITH_GL_EGL)
36 # include "GHOST_ContextEGL.h"
37 #else
38 # include "GHOST_ContextWGL.h"
39 #endif
40 #ifdef WIN32_COMPOSITING
41 # include <Dwmapi.h>
42 #endif
43 
44 #include <assert.h>
45 #include <math.h>
46 #include <string.h>
47 #include <windowsx.h>
48 
49 #ifndef GET_POINTERID_WPARAM
50 # define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
51 #endif // GET_POINTERID_WPARAM
52 
53 const wchar_t *GHOST_WindowWin32::s_windowClassName = L"GHOST_WindowClass";
54 const int GHOST_WindowWin32::s_maxTitleLength = 128;
55 
56 /* force NVidia Optimus to used dedicated graphics */
57 extern "C" {
58 __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
59 }
60 
62  const char *title,
69  bool wantStereoVisual,
70  bool alphaBackground,
71  GHOST_WindowWin32 *parentwindow,
72  bool is_debug,
73  bool dialog)
74  : GHOST_Window(width, height, state, wantStereoVisual, false),
75  m_tabletInRange(false),
76  m_inLiveResize(false),
77  m_system(system),
78  m_hDC(0),
79  m_isDialog(dialog),
80  m_hasMouseCaptured(false),
81  m_hasGrabMouse(false),
82  m_nPressedButtons(0),
83  m_customCursor(0),
84  m_wantAlphaBackground(alphaBackground),
85  m_normal_state(GHOST_kWindowStateNormal),
86  m_user32(NULL),
87  m_fpGetPointerInfoHistory(NULL),
88  m_fpGetPointerPenInfoHistory(NULL),
89  m_fpGetPointerTouchInfoHistory(NULL),
90  m_parentWindowHwnd(parentwindow ? parentwindow->m_hWnd : HWND_DESKTOP),
91  m_debug_context(is_debug)
92 {
93  wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
94  RECT win_rect = {left, top, (long)(left + width), (long)(top + height)};
95 
96  // Initialize tablet variables
97  memset(&m_wintab, 0, sizeof(m_wintab));
98  m_tabletData = GHOST_TABLET_DATA_NONE;
99 
100  DWORD style = parentwindow ?
101  WS_POPUPWINDOW | WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX :
102  WS_OVERLAPPEDWINDOW;
103 
105  style |= WS_MAXIMIZE;
106  }
107 
108  /* Forces owned windows onto taskbar and allows minimization. */
109  DWORD extended_style = parentwindow ? WS_EX_APPWINDOW : 0;
110 
111  if (dialog) {
112  /* When we are ready to make windows of this type:
113  * style = WS_POPUPWINDOW | WS_CAPTION
114  * extended_style = WS_EX_DLGMODALFRAME | WS_EX_TOPMOST
115  */
116  }
117 
118  /* Monitor details. */
119  MONITORINFOEX monitor;
120  monitor.cbSize = sizeof(MONITORINFOEX);
121  monitor.dwFlags = 0;
122  GetMonitorInfo(MonitorFromRect(&win_rect, MONITOR_DEFAULTTONEAREST), &monitor);
123 
124  /* Adjust our requested size to allow for caption and borders and constrain to monitor. */
125  AdjustWindowRectEx(&win_rect, WS_CAPTION, FALSE, 0);
126  width = min(monitor.rcWork.right - monitor.rcWork.left, win_rect.right - win_rect.left);
127  left = min(max(monitor.rcWork.left, win_rect.left), monitor.rcWork.right - width);
128  height = min(monitor.rcWork.bottom - monitor.rcWork.top, win_rect.bottom - win_rect.top);
129  top = min(max(monitor.rcWork.top, win_rect.top), monitor.rcWork.bottom - height);
130 
131  m_hWnd = ::CreateWindowExW(extended_style, // window extended style
132  s_windowClassName, // pointer to registered class name
133  title_16, // pointer to window name
134  style, // window style
135  left, // horizontal position of window
136  top, // vertical position of window
137  width, // window width
138  height, // window height
139  m_parentWindowHwnd, // handle to parent or owner window
140  0, // handle to menu or child-window identifier
141  ::GetModuleHandle(0), // handle to application instance
142  0); // pointer to window-creation data
143  free(title_16);
144 
145  m_user32 = ::LoadLibrary("user32.dll");
146 
147  if (m_hWnd) {
148  if (m_user32) {
149  // Touch enabled screens with pen support by default have gestures
150  // enabled, which results in a delay between the pointer down event
151  // and the first move when using the stylus. RegisterTouchWindow
152  // disables the new gesture architecture enabling the events to be
153  // sent immediately to the application rather than being absorbed by
154  // the gesture API.
156  GetProcAddress(m_user32, "RegisterTouchWindow");
157  if (pRegisterTouchWindow) {
158  pRegisterTouchWindow(m_hWnd, 0);
159  }
160  }
161 
162  // Register this window as a droptarget. Requires m_hWnd to be valid.
163  // Note that OleInitialize(0) has to be called prior to this. Done in GHOST_SystemWin32.
164  m_dropTarget = new GHOST_DropTargetWin32(this, m_system);
165  if (m_dropTarget) {
166  ::RegisterDragDrop(m_hWnd, m_dropTarget);
167  }
168 
169  // Store a pointer to this class in the window structure
170  ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR)this);
171 
172  if (!m_system->m_windowFocus) {
173  // Lower to bottom and don't activate if we don't want focus
174  ::SetWindowPos(m_hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
175  }
176 
177  // Store the device context
178  m_hDC = ::GetDC(m_hWnd);
179 
181 
182  if (success) {
183  // Show the window
184  int nCmdShow;
185  switch (state) {
187  nCmdShow = SW_SHOWMAXIMIZED;
188  break;
190  nCmdShow = (m_system->m_windowFocus) ? SW_SHOWMINIMIZED : SW_SHOWMINNOACTIVE;
191  break;
193  default:
194  nCmdShow = (m_system->m_windowFocus) ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
195  break;
196  }
197 
198  ::ShowWindow(m_hWnd, nCmdShow);
199 #ifdef WIN32_COMPOSITING
200  if (alphaBackground && parentwindowhwnd == 0) {
201 
202  HRESULT hr = S_OK;
203 
204  // Create and populate the Blur Behind structure
205  DWM_BLURBEHIND bb = {0};
206 
207  // Enable Blur Behind and apply to the entire client area
208  bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
209  bb.fEnable = true;
210  bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
211 
212  // Apply Blur Behind
213  hr = DwmEnableBlurBehindWindow(m_hWnd, &bb);
214  DeleteObject(bb.hRgnBlur);
215  }
216 #endif
217  // Force an initial paint of the window
218  ::UpdateWindow(m_hWnd);
219  }
220  else {
221  // invalidate the window
222  ::DestroyWindow(m_hWnd);
223  m_hWnd = NULL;
224  }
225  }
226 
227  // Initialize Windows Ink
228  if (m_user32) {
229  m_fpGetPointerInfoHistory = (GHOST_WIN32_GetPointerInfoHistory)::GetProcAddress(
230  m_user32, "GetPointerInfoHistory");
231  m_fpGetPointerPenInfoHistory = (GHOST_WIN32_GetPointerPenInfoHistory)::GetProcAddress(
232  m_user32, "GetPointerPenInfoHistory");
233  m_fpGetPointerTouchInfoHistory = (GHOST_WIN32_GetPointerTouchInfoHistory)::GetProcAddress(
234  m_user32, "GetPointerTouchInfoHistory");
235  }
236 
237  // Initialize Wintab
238  m_wintab.handle = ::LoadLibrary("Wintab32.dll");
239  if (m_wintab.handle && m_system->getTabletAPI() != GHOST_kTabletNative) {
240  // Get API functions
241  m_wintab.info = (GHOST_WIN32_WTInfo)::GetProcAddress(m_wintab.handle, "WTInfoA");
242  m_wintab.open = (GHOST_WIN32_WTOpen)::GetProcAddress(m_wintab.handle, "WTOpenA");
243  m_wintab.close = (GHOST_WIN32_WTClose)::GetProcAddress(m_wintab.handle, "WTClose");
244  m_wintab.packet = (GHOST_WIN32_WTPacket)::GetProcAddress(m_wintab.handle, "WTPacket");
245  m_wintab.enable = (GHOST_WIN32_WTEnable)::GetProcAddress(m_wintab.handle, "WTEnable");
246  m_wintab.overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(m_wintab.handle, "WTOverlap");
247 
248  // Let's see if we can initialize tablet here.
249  // Check if WinTab available by getting system context info.
250  LOGCONTEXT lc = {0};
251  lc.lcOptions |= CXO_SYSTEM;
252  if (m_wintab.open && m_wintab.info && m_wintab.info(WTI_DEFSYSCTX, 0, &lc)) {
253  // Now init the tablet
254  /* The maximum tablet size, pressure and orientation (tilt) */
255  AXIS TabletX, TabletY, Pressure, Orientation[3];
256 
257  // Open a Wintab context
258 
259  // Open the context
260  lc.lcPktData = PACKETDATA;
261  lc.lcPktMode = PACKETMODE;
262  lc.lcOptions |= CXO_MESSAGES;
263  lc.lcMoveMask = PACKETDATA;
264 
265  /* Set the entire tablet as active */
266  m_wintab.info(WTI_DEVICES, DVC_X, &TabletX);
267  m_wintab.info(WTI_DEVICES, DVC_Y, &TabletY);
268 
269  /* get the max pressure, to divide into a float */
270  BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
271  if (pressureSupport)
272  m_wintab.maxPressure = Pressure.axMax;
273  else
274  m_wintab.maxPressure = 0;
275 
276  /* get the max tilt axes, to divide into floats */
277  BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
278  if (tiltSupport) {
279  /* does the tablet support azimuth ([0]) and altitude ([1]) */
280  if (Orientation[0].axResolution && Orientation[1].axResolution) {
281  /* all this assumes the minimum is 0 */
282  m_wintab.maxAzimuth = Orientation[0].axMax;
283  m_wintab.maxAltitude = Orientation[1].axMax;
284  }
285  else { /* No so don't do tilt stuff. */
286  m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
287  }
288  }
289 
290  // The Wintab spec says we must open the context disabled if we are using cursor masks.
291  m_wintab.tablet = m_wintab.open(m_hWnd, &lc, FALSE);
292  if (m_wintab.enable && m_wintab.tablet) {
293  m_wintab.enable(m_wintab.tablet, TRUE);
294  }
295  }
296  }
297  CoCreateInstance(
298  CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID *)&m_Bar);
299 }
300 
302 {
303  if (m_Bar) {
304  m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS);
305  m_Bar->Release();
306  m_Bar = NULL;
307  }
308 
309  if (m_wintab.handle) {
310  if (m_wintab.close && m_wintab.tablet) {
311  m_wintab.close(m_wintab.tablet);
312  }
313 
314  FreeLibrary(m_wintab.handle);
315  memset(&m_wintab, 0, sizeof(m_wintab));
316  }
317 
318  if (m_user32) {
319  FreeLibrary(m_user32);
320  m_user32 = NULL;
321  m_fpGetPointerInfoHistory = NULL;
322  m_fpGetPointerPenInfoHistory = NULL;
323  m_fpGetPointerTouchInfoHistory = NULL;
324  }
325 
326  if (m_customCursor) {
327  DestroyCursor(m_customCursor);
328  m_customCursor = NULL;
329  }
330 
331  if (m_hWnd != NULL && m_hDC != NULL && releaseNativeHandles()) {
332  ::ReleaseDC(m_hWnd, m_hDC);
333  m_hDC = NULL;
334  }
335 
336  if (m_hWnd) {
337  /* If this window is referenced by others as parent, clear that relation or windows will free
338  * the handle while we still reference it. */
339  for (GHOST_IWindow *iter_win : m_system->getWindowManager()->getWindows()) {
340  GHOST_WindowWin32 *iter_winwin = (GHOST_WindowWin32 *)iter_win;
341  if (iter_winwin->m_parentWindowHwnd == m_hWnd) {
342  ::SetWindowLongPtr(iter_winwin->m_hWnd, GWLP_HWNDPARENT, NULL);
343  iter_winwin->m_parentWindowHwnd = 0;
344  }
345  }
346 
347  if (m_dropTarget) {
348  // Disable DragDrop
349  RevokeDragDrop(m_hWnd);
350  // Release our reference of the DropTarget and it will delete itself eventually.
351  m_dropTarget->Release();
352  m_dropTarget = NULL;
353  }
354  ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, NULL);
355  ::DestroyWindow(m_hWnd);
356  m_hWnd = 0;
357  }
358 }
359 
361 {
362  return GHOST_Window::getValid() && m_hWnd != 0 && m_hDC != 0;
363 }
364 
366 {
367  return m_hWnd;
368 }
369 
370 void GHOST_WindowWin32::setTitle(const char *title)
371 {
372  wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
373  ::SetWindowTextW(m_hWnd, (wchar_t *)title_16);
374  free(title_16);
375 }
376 
377 std::string GHOST_WindowWin32::getTitle() const
378 {
379  std::wstring wtitle(::GetWindowTextLengthW(m_hWnd) + 1, L'\0');
380  ::GetWindowTextW(m_hWnd, &wtitle[0], wtitle.capacity());
381 
382  std::string title(count_utf_8_from_16(wtitle.c_str()) + 1, '\0');
383  conv_utf_16_to_8(wtitle.c_str(), &title[0], title.capacity());
384 
385  return title;
386 }
387 
389 {
390  RECT rect;
391  ::GetWindowRect(m_hWnd, &rect);
392  bounds.m_b = rect.bottom;
393  bounds.m_l = rect.left;
394  bounds.m_r = rect.right;
395  bounds.m_t = rect.top;
396 }
397 
399 {
400  RECT rect;
401  POINT coord;
402  if (!IsIconic(m_hWnd)) {
403  ::GetClientRect(m_hWnd, &rect);
404 
405  coord.x = rect.left;
406  coord.y = rect.top;
407  ::ClientToScreen(m_hWnd, &coord);
408 
409  bounds.m_l = coord.x;
410  bounds.m_t = coord.y;
411 
412  coord.x = rect.right;
413  coord.y = rect.bottom;
414  ::ClientToScreen(m_hWnd, &coord);
415 
416  bounds.m_r = coord.x;
417  bounds.m_b = coord.y;
418  }
419  else {
420  bounds.m_b = 0;
421  bounds.m_l = 0;
422  bounds.m_r = 0;
423  bounds.m_t = 0;
424  }
425 }
426 
428 {
429  GHOST_TSuccess success;
430  GHOST_Rect cBnds, wBnds;
431  getClientBounds(cBnds);
432  if (cBnds.getWidth() != (GHOST_TInt32)width) {
433  getWindowBounds(wBnds);
434  int cx = wBnds.getWidth() + width - cBnds.getWidth();
435  int cy = wBnds.getHeight();
436  success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
439  }
440  else {
441  success = GHOST_kSuccess;
442  }
443  return success;
444 }
445 
447 {
448  GHOST_TSuccess success;
449  GHOST_Rect cBnds, wBnds;
450  getClientBounds(cBnds);
451  if (cBnds.getHeight() != (GHOST_TInt32)height) {
452  getWindowBounds(wBnds);
453  int cx = wBnds.getWidth();
454  int cy = wBnds.getHeight() + height - cBnds.getHeight();
455  success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
458  }
459  else {
460  success = GHOST_kSuccess;
461  }
462  return success;
463 }
464 
466 {
467  GHOST_TSuccess success;
468  GHOST_Rect cBnds, wBnds;
469  getClientBounds(cBnds);
470  if ((cBnds.getWidth() != (GHOST_TInt32)width) || (cBnds.getHeight() != (GHOST_TInt32)height)) {
471  getWindowBounds(wBnds);
472  int cx = wBnds.getWidth() + width - cBnds.getWidth();
473  int cy = wBnds.getHeight() + height - cBnds.getHeight();
474  success = ::SetWindowPos(m_hWnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER) ?
477  }
478  else {
479  success = GHOST_kSuccess;
480  }
481  return success;
482 }
483 
485 {
486  if (::IsIconic(m_hWnd)) {
488  }
489  else if (::IsZoomed(m_hWnd)) {
490  LONG_PTR result = ::GetWindowLongPtr(m_hWnd, GWL_STYLE);
492  }
494 }
495 
497  GHOST_TInt32 inY,
498  GHOST_TInt32 &outX,
499  GHOST_TInt32 &outY) const
500 {
501  POINT point = {inX, inY};
502  ::ScreenToClient(m_hWnd, &point);
503  outX = point.x;
504  outY = point.y;
505 }
506 
508  GHOST_TInt32 inY,
509  GHOST_TInt32 &outX,
510  GHOST_TInt32 &outY) const
511 {
512  POINT point = {inX, inY};
513  ::ClientToScreen(m_hWnd, &point);
514  outX = point.x;
515  outY = point.y;
516 }
517 
519 {
520  GHOST_TWindowState curstate = getState();
521  LONG_PTR style = GetWindowLongPtr(m_hWnd, GWL_STYLE) | WS_CAPTION;
522  WINDOWPLACEMENT wp;
523  wp.length = sizeof(WINDOWPLACEMENT);
524  ::GetWindowPlacement(m_hWnd, &wp);
525 
526  switch (state) {
528  wp.showCmd = SW_MINIMIZE;
529  break;
531  wp.showCmd = SW_SHOWMAXIMIZED;
532  break;
534  if (curstate != state && curstate != GHOST_kWindowStateMinimized) {
535  m_normal_state = curstate;
536  }
537  wp.showCmd = SW_SHOWMAXIMIZED;
538  wp.ptMaxPosition.x = 0;
539  wp.ptMaxPosition.y = 0;
540  style &= ~(WS_CAPTION | WS_MAXIMIZE);
541  break;
543  default:
544  if (curstate == GHOST_kWindowStateFullScreen &&
545  m_normal_state == GHOST_kWindowStateMaximized) {
546  wp.showCmd = SW_SHOWMAXIMIZED;
547  m_normal_state = GHOST_kWindowStateNormal;
548  }
549  else {
550  wp.showCmd = SW_SHOWNORMAL;
551  }
552  break;
553  }
554  ::SetWindowLongPtr(m_hWnd, GWL_STYLE, style);
555  /* SetWindowLongPtr Docs: frame changes not visible until SetWindowPos with SWP_FRAMECHANGED. */
556  ::SetWindowPos(m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
557  return ::SetWindowPlacement(m_hWnd, &wp) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
558 }
559 
561 {
562  HWND hWndInsertAfter, hWndToRaise;
563 
565  hWndInsertAfter = HWND_BOTTOM;
566  hWndToRaise = ::GetWindow(m_hWnd, GW_HWNDNEXT); /* the window to raise */
567  }
568  else {
571  }
572  hWndInsertAfter = HWND_TOP;
573  hWndToRaise = NULL;
574  }
575 
576  if (::SetWindowPos(m_hWnd, hWndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == FALSE) {
577  return GHOST_kFailure;
578  }
579 
580  if (hWndToRaise &&
581  ::SetWindowPos(hWndToRaise, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) == FALSE) {
582  return GHOST_kFailure;
583  }
584  return GHOST_kSuccess;
585 }
586 
588 {
589  GHOST_TSuccess success;
590  if (m_hWnd) {
591  success = ::InvalidateRect(m_hWnd, 0, FALSE) != 0 ? GHOST_kSuccess : GHOST_kFailure;
592  }
593  else {
594  success = GHOST_kFailure;
595  }
596  return success;
597 }
598 
599 GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType type)
600 {
603 
604 #if defined(WITH_GL_PROFILE_CORE)
605  /* - AMD and Intel give us exactly this version
606  * - NVIDIA gives at least this version <-- desired behavior
607  * So we ask for 4.5, 4.4 ... 3.3 in descending order
608  * to get the best version on the user's system. */
609  for (int minor = 5; minor >= 0; --minor) {
611  m_wantAlphaBackground,
612  m_hWnd,
613  m_hDC,
614  WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
615  4,
616  minor,
617  (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
619 
620  if (context->initializeDrawingContext()) {
621  return context;
622  }
623  else {
624  delete context;
625  }
626  }
628  m_wantAlphaBackground,
629  m_hWnd,
630  m_hDC,
631  WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
632  3,
633  3,
634  (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
636 
637  if (context->initializeDrawingContext()) {
638  return context;
639  }
640  else {
641  MessageBox(m_hWnd,
642  "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n"
643  "Installing the latest driver for your graphics card may resolve the issue.\n\n"
644  "The program will now close.",
645  "Blender - Unsupported Graphics Card or Driver",
646  MB_OK | MB_ICONERROR);
647  delete context;
648  exit(0);
649  }
650 
651 #elif defined(WITH_GL_PROFILE_COMPAT)
652  // ask for 2.1 context, driver gives any GL version >= 2.1
653  // (hopefully the latest compatibility profile)
654  // 2.1 ignores the profile bit & is incompatible with core profile
656  m_wantAlphaBackground,
657  m_hWnd,
658  m_hDC,
659  0, // no profile bit
660  2,
661  1,
662  (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
664 
665  if (context->initializeDrawingContext()) {
666  return context;
667  }
668  else {
669  delete context;
670  }
671 #else
672 # error // must specify either core or compat at build time
673 #endif
674  }
675  else if (type == GHOST_kDrawingContextTypeD3D) {
677 
678  context = new GHOST_ContextD3D(false, m_hWnd);
679  if (context->initializeDrawingContext()) {
680  return context;
681  }
682  else {
683  delete context;
684  }
685 
686  return context;
687  }
688 
689  return NULL;
690 }
691 
693 {
694  if (m_hasMouseCaptured) {
695  m_hasGrabMouse = false;
696  m_nPressedButtons = 0;
697  m_hasMouseCaptured = false;
698  }
699 }
700 
702 {
703  return m_isDialog;
704 }
705 
707 {
708  switch (event) {
709  case MousePressed:
710  m_nPressedButtons++;
711  break;
712  case MouseReleased:
713  if (m_nPressedButtons)
714  m_nPressedButtons--;
715  break;
716  case OperatorGrab:
717  m_hasGrabMouse = true;
718  break;
719  case OperatorUngrab:
720  m_hasGrabMouse = false;
721  break;
722  }
723 
724  if (!m_nPressedButtons && !m_hasGrabMouse && m_hasMouseCaptured) {
725  ::ReleaseCapture();
726  m_hasMouseCaptured = false;
727  }
728  else if ((m_nPressedButtons || m_hasGrabMouse) && !m_hasMouseCaptured) {
729  ::SetCapture(m_hWnd);
730  m_hasMouseCaptured = true;
731  }
732 }
733 
735 {
736  // Convert GHOST cursor to Windows OEM cursor
737  HANDLE cursor = NULL;
738  HMODULE module = ::GetModuleHandle(0);
739  GHOST_TUns32 flags = LR_SHARED | LR_DEFAULTSIZE;
740  int cx = 0, cy = 0;
741 
742  switch (shape) {
744  if (m_customCursor) {
745  return m_customCursor;
746  }
747  else {
748  return NULL;
749  }
751  cursor = ::LoadImage(module, "arrowright_cursor", IMAGE_CURSOR, cx, cy, flags);
752  break;
754  cursor = ::LoadImage(module, "arrowleft_cursor", IMAGE_CURSOR, cx, cy, flags);
755  break;
757  cursor = ::LoadImage(module, "arrowup_cursor", IMAGE_CURSOR, cx, cy, flags);
758  break;
760  cursor = ::LoadImage(module, "arrowdown_cursor", IMAGE_CURSOR, cx, cy, flags);
761  break;
763  cursor = ::LoadImage(module, "splitv_cursor", IMAGE_CURSOR, cx, cy, flags);
764  break;
766  cursor = ::LoadImage(module, "splith_cursor", IMAGE_CURSOR, cx, cy, flags);
767  break;
769  cursor = ::LoadImage(module, "knife_cursor", IMAGE_CURSOR, cx, cy, flags);
770  break;
772  cursor = ::LoadImage(module, "eyedropper_cursor", IMAGE_CURSOR, cx, cy, flags);
773  break;
775  cursor = ::LoadImage(module, "zoomin_cursor", IMAGE_CURSOR, cx, cy, flags);
776  break;
778  cursor = ::LoadImage(module, "zoomout_cursor", IMAGE_CURSOR, cx, cy, flags);
779  break;
781  cursor = ::LoadImage(module, "handopen_cursor", IMAGE_CURSOR, cx, cy, flags);
782  break;
784  cursor = ::LoadImage(module, "scrollnsew_cursor", IMAGE_CURSOR, cx, cy, flags);
785  break;
787  cursor = ::LoadImage(module, "scrollns_cursor", IMAGE_CURSOR, cx, cy, flags);
788  break;
790  cursor = ::LoadImage(module, "scrollew_cursor", IMAGE_CURSOR, cx, cy, flags);
791  break;
793  cursor = ::LoadImage(NULL, IDC_HELP, IMAGE_CURSOR, cx, cy, flags);
794  break; // Arrow and question mark
796  cursor = ::LoadImage(NULL, IDC_WAIT, IMAGE_CURSOR, cx, cy, flags);
797  break; // Hourglass
799  cursor = ::LoadImage(NULL, IDC_IBEAM, IMAGE_CURSOR, cx, cy, flags);
800  break; // I-beam
802  cursor = ::LoadImage(module, "cross_cursor", IMAGE_CURSOR, cx, cy, flags);
803  break; // Standard Cross
805  cursor = ::LoadImage(module, "crossA_cursor", IMAGE_CURSOR, cx, cy, flags);
806  break; // Crosshair A
808  cursor = ::LoadImage(module, "crossB_cursor", IMAGE_CURSOR, cx, cy, flags);
809  break; // Diagonal Crosshair B
811  cursor = ::LoadImage(module, "crossC_cursor", IMAGE_CURSOR, cx, cy, flags);
812  break; // Minimal Crosshair C
815  cursor = ::LoadImage(module, "movens_cursor", IMAGE_CURSOR, cx, cy, flags);
816  break; // Double-pointed arrow pointing north and south
819  cursor = ::LoadImage(module, "moveew_cursor", IMAGE_CURSOR, cx, cy, flags);
820  break; // Double-pointed arrow pointing west and east
822  cursor = ::LoadImage(NULL, IDC_UPARROW, IMAGE_CURSOR, cx, cy, flags);
823  break; // Vertical arrow
825  cursor = ::LoadImage(NULL, IDC_SIZENWSE, IMAGE_CURSOR, cx, cy, flags);
826  break;
828  cursor = ::LoadImage(NULL, IDC_SIZENESW, IMAGE_CURSOR, cx, cy, flags);
829  break;
831  cursor = ::LoadImage(NULL, IDC_SIZENWSE, IMAGE_CURSOR, cx, cy, flags);
832  break;
834  cursor = ::LoadImage(NULL, IDC_SIZENESW, IMAGE_CURSOR, cx, cy, flags);
835  break;
837  cursor = ::LoadImage(module, "pencil_cursor", IMAGE_CURSOR, cx, cy, flags);
838  break;
840  cursor = ::LoadImage(module, "eraser_cursor", IMAGE_CURSOR, cx, cy, flags);
841  break;
844  cursor = ::LoadImage(module, "forbidden_cursor", IMAGE_CURSOR, cx, cy, flags);
845  break; // Slashed circle
847  cursor = NULL;
848  break;
849  default:
850  return NULL;
851  }
852 
853  if (cursor == NULL) {
854  cursor = ::LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, cx, cy, flags);
855  }
856 
857  return (HCURSOR)cursor;
858 }
859 
861 {
862  if (!visible) {
863  while (::ShowCursor(FALSE) >= 0)
864  ;
865  }
866  else {
867  while (::ShowCursor(TRUE) < 0)
868  ;
869  }
870 
871  HCURSOR cursor = getStandardCursor(shape);
872  if (cursor == NULL) {
874  }
875  ::SetCursor(cursor);
876 }
877 
878 GHOST_TSuccess GHOST_WindowWin32::setWindowCursorVisibility(bool visible)
879 {
880  if (::GetForegroundWindow() == m_hWnd) {
881  loadCursor(visible, getCursorShape());
882  }
883 
884  return GHOST_kSuccess;
885 }
886 
887 GHOST_TSuccess GHOST_WindowWin32::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
888 {
889  if (mode != GHOST_kGrabDisable) {
890  if (mode != GHOST_kGrabNormal) {
892  setCursorGrabAccum(0, 0);
893 
894  if (mode == GHOST_kGrabHide)
895  setWindowCursorVisibility(false);
896  }
898  }
899  else {
900  if (m_cursorGrab == GHOST_kGrabHide) {
902  setWindowCursorVisibility(true);
903  }
905  /* use to generate a mouse move event, otherwise the last event
906  * blender gets can be outside the screen causing menus not to show
907  * properly unless the user moves the mouse */
908  GHOST_TInt32 pos[2];
909  m_system->getCursorPosition(pos[0], pos[1]);
910  m_system->setCursorPosition(pos[0], pos[1]);
911  }
912 
913  /* Almost works without but important otherwise the mouse GHOST location
914  * can be incorrect on exit. */
915  setCursorGrabAccum(0, 0);
916  m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
918  }
919 
920  return GHOST_kSuccess;
921 }
922 
923 GHOST_TSuccess GHOST_WindowWin32::setWindowCursorShape(GHOST_TStandardCursor cursorShape)
924 {
925  if (::GetForegroundWindow() == m_hWnd) {
926  loadCursor(getCursorVisibility(), cursorShape);
927  }
928 
929  return GHOST_kSuccess;
930 }
931 
932 GHOST_TSuccess GHOST_WindowWin32::hasCursorShape(GHOST_TStandardCursor cursorShape)
933 {
934  return (getStandardCursor(cursorShape)) ? GHOST_kSuccess : GHOST_kFailure;
935 }
936 
938  std::vector<GHOST_PointerInfoWin32> &outPointerInfo, WPARAM wParam, LPARAM lParam)
939 {
941  return GHOST_kFailure;
942  }
943 
944  GHOST_TInt32 pointerId = GET_POINTERID_WPARAM(wParam);
945  GHOST_TInt32 isPrimary = IS_POINTER_PRIMARY_WPARAM(wParam);
947  GHOST_TUns32 outCount;
948 
949  if (!(m_fpGetPointerInfoHistory && m_fpGetPointerInfoHistory(pointerId, &outCount, NULL))) {
950  return GHOST_kFailure;
951  }
952 
953  auto pointerPenInfo = std::vector<POINTER_PEN_INFO>(outCount);
954  outPointerInfo.resize(outCount);
955 
956  if (!(m_fpGetPointerPenInfoHistory &&
957  m_fpGetPointerPenInfoHistory(pointerId, &outCount, pointerPenInfo.data()))) {
958  return GHOST_kFailure;
959  }
960 
961  for (GHOST_TUns32 i = 0; i < outCount; i++) {
962  POINTER_INFO pointerApiInfo = pointerPenInfo[i].pointerInfo;
963  // Obtain the basic information from the event
964  outPointerInfo[i].pointerId = pointerId;
965  outPointerInfo[i].isPrimary = isPrimary;
966 
967  switch (pointerApiInfo.ButtonChangeType) {
970  outPointerInfo[i].buttonMask = GHOST_kButtonMaskLeft;
971  break;
974  outPointerInfo[i].buttonMask = GHOST_kButtonMaskRight;
975  break;
978  outPointerInfo[i].buttonMask = GHOST_kButtonMaskMiddle;
979  break;
982  outPointerInfo[i].buttonMask = GHOST_kButtonMaskButton4;
983  break;
986  outPointerInfo[i].buttonMask = GHOST_kButtonMaskButton5;
987  break;
988  default:
989  break;
990  }
991 
992  outPointerInfo[i].pixelLocation = pointerApiInfo.ptPixelLocation;
993  outPointerInfo[i].tabletData.Active = GHOST_kTabletModeStylus;
994  outPointerInfo[i].tabletData.Pressure = 1.0f;
995  outPointerInfo[i].tabletData.Xtilt = 0.0f;
996  outPointerInfo[i].tabletData.Ytilt = 0.0f;
997  outPointerInfo[i].time = system->performanceCounterToMillis(pointerApiInfo.PerformanceCount);
998 
999  if (pointerPenInfo[i].penMask & PEN_MASK_PRESSURE) {
1000  outPointerInfo[i].tabletData.Pressure = pointerPenInfo[i].pressure / 1024.0f;
1001  }
1002 
1003  if (pointerPenInfo[i].penFlags & PEN_FLAG_ERASER) {
1004  outPointerInfo[i].tabletData.Active = GHOST_kTabletModeEraser;
1005  }
1006 
1007  if (pointerPenInfo[i].penMask & PEN_MASK_TILT_X) {
1008  outPointerInfo[i].tabletData.Xtilt = fmin(fabs(pointerPenInfo[i].tiltX / 90.0f), 1.0f);
1009  }
1010 
1011  if (pointerPenInfo[i].penMask & PEN_MASK_TILT_Y) {
1012  outPointerInfo[i].tabletData.Ytilt = fmin(fabs(pointerPenInfo[i].tiltY / 90.0f), 1.0f);
1013  }
1014  }
1015 
1016  return GHOST_kSuccess;
1017 }
1018 
1020 {
1022  return;
1023  }
1024 
1025  if (m_wintab.enable && m_wintab.tablet) {
1026  m_wintab.enable(m_wintab.tablet, state);
1027 
1028  if (m_wintab.overlap && state) {
1029  m_wintab.overlap(m_wintab.tablet, TRUE);
1030  }
1031  }
1032 }
1033 
1035 {
1036  if (m_system->getTabletAPI() == api) {
1037  return true;
1038  }
1039  else if (m_system->getTabletAPI() == GHOST_kTabletAutomatic) {
1040  if (m_wintab.tablet)
1041  return api == GHOST_kTabletWintab;
1042  else
1043  return api == GHOST_kTabletNative;
1044  }
1045  else {
1046  return false;
1047  }
1048 }
1049 
1051 {
1053  return;
1054  }
1055 
1056  // Let's see if we can initialize tablet here
1057  if (m_wintab.info && m_wintab.tablet) {
1058  AXIS Pressure, Orientation[3]; /* The maximum tablet size */
1059 
1060  BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
1061  if (pressureSupport)
1062  m_wintab.maxPressure = Pressure.axMax;
1063  else
1064  m_wintab.maxPressure = 0;
1065 
1066  BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
1067  if (tiltSupport) {
1068  /* does the tablet support azimuth ([0]) and altitude ([1]) */
1069  if (Orientation[0].axResolution && Orientation[1].axResolution) {
1070  m_wintab.maxAzimuth = Orientation[0].axMax;
1071  m_wintab.maxAltitude = Orientation[1].axMax;
1072  }
1073  else { /* No so don't do tilt stuff. */
1074  m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
1075  }
1076  }
1077  }
1078 
1079  m_tabletData.Active = GHOST_kTabletModeNone;
1080 }
1081 
1082 void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
1083 {
1085  return;
1086  }
1087 
1088  if (m_wintab.packet && m_wintab.tablet) {
1089  PACKET pkt;
1090  if (m_wintab.packet((HCTX)lParam, wParam, &pkt)) {
1091  switch (pkt.pkCursor % 3) { /* % 3 for multiple devices ("DualTrack") */
1092  case 0:
1093  m_tabletData.Active = GHOST_kTabletModeNone; /* puck - not yet supported */
1094  break;
1095  case 1:
1096  m_tabletData.Active = GHOST_kTabletModeStylus; /* stylus */
1097  break;
1098  case 2:
1099  m_tabletData.Active = GHOST_kTabletModeEraser; /* eraser */
1100  break;
1101  }
1102 
1103  if (m_wintab.maxPressure > 0) {
1104  m_tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure;
1105  }
1106  else {
1107  m_tabletData.Pressure = 1.0f;
1108  }
1109 
1110  if ((m_wintab.maxAzimuth > 0) && (m_wintab.maxAltitude > 0)) {
1111  ORIENTATION ort = pkt.pkOrientation;
1112  float vecLen;
1113  float altRad, azmRad; /* in radians */
1114 
1115  /*
1116  * from the wintab spec:
1117  * orAzimuth Specifies the clockwise rotation of the
1118  * cursor about the z axis through a full circular range.
1119  *
1120  * orAltitude Specifies the angle with the x-y plane
1121  * through a signed, semicircular range. Positive values
1122  * specify an angle upward toward the positive z axis;
1123  * negative values specify an angle downward toward the negative z axis.
1124  *
1125  * wintab.h defines .orAltitude as a UINT but documents .orAltitude
1126  * as positive for upward angles and negative for downward angles.
1127  * WACOM uses negative altitude values to show that the pen is inverted;
1128  * therefore we cast .orAltitude as an (int) and then use the absolute value.
1129  */
1130 
1131  /* convert raw fixed point data to radians */
1132  altRad = (float)((fabs((float)ort.orAltitude) / (float)m_wintab.maxAltitude) * M_PI / 2.0);
1133  azmRad = (float)(((float)ort.orAzimuth / (float)m_wintab.maxAzimuth) * M_PI * 2.0);
1134 
1135  /* find length of the stylus' projected vector on the XY plane */
1136  vecLen = cos(altRad);
1137 
1138  /* from there calculate X and Y components based on azimuth */
1139  m_tabletData.Xtilt = sin(azmRad) * vecLen;
1140  m_tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
1141  }
1142  else {
1143  m_tabletData.Xtilt = 0.0f;
1144  m_tabletData.Ytilt = 0.0f;
1145  }
1146  }
1147  }
1148 }
1149 
1151 {
1153  return;
1154  }
1155 
1156  if (m_wintab.overlap && m_wintab.tablet) {
1157  m_wintab.overlap(m_wintab.tablet, TRUE);
1158  }
1159 }
1160 
1162 {
1163  if (m_user32) {
1164  GHOST_WIN32_GetDpiForWindow fpGetDpiForWindow = (GHOST_WIN32_GetDpiForWindow)::GetProcAddress(
1165  m_user32, "GetDpiForWindow");
1166 
1167  if (fpGetDpiForWindow) {
1168  return fpGetDpiForWindow(this->m_hWnd);
1169  }
1170  }
1171 
1172  return USER_DEFAULT_SCREEN_DPI;
1173 }
1174 
1177 {
1178  ch = ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA);
1179  ch = ((ch >> 2) & 0x33) | ((ch << 2) & 0xCC);
1180  ch = ((ch >> 4) & 0x0F) | ((ch << 4) & 0xF0);
1181  return ch;
1182 }
1183 
1184 #if 0 /* UNUSED */
1187 {
1188  shrt = ((shrt >> 1) & 0x5555) | ((shrt << 1) & 0xAAAA);
1189  shrt = ((shrt >> 2) & 0x3333) | ((shrt << 2) & 0xCCCC);
1190  shrt = ((shrt >> 4) & 0x0F0F) | ((shrt << 4) & 0xF0F0);
1191  shrt = ((shrt >> 8) & 0x00FF) | ((shrt << 8) & 0xFF00);
1192  return shrt;
1193 }
1194 #endif
1195 
1196 GHOST_TSuccess GHOST_WindowWin32::setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
1197  GHOST_TUns8 *mask,
1198  int sizeX,
1199  int sizeY,
1200  int hotX,
1201  int hotY,
1202  bool canInvertColor)
1203 {
1204  GHOST_TUns32 andData[32];
1205  GHOST_TUns32 xorData[32];
1206  GHOST_TUns32 fullBitRow, fullMaskRow;
1207  int x, y, cols;
1208 
1209  cols = sizeX / 8; /* Number of whole bytes per row (width of bitmap/mask). */
1210  if (sizeX % 8)
1211  cols++;
1212 
1213  if (m_customCursor) {
1214  DestroyCursor(m_customCursor);
1215  m_customCursor = NULL;
1216  }
1217 
1218  memset(&andData, 0xFF, sizeof(andData));
1219  memset(&xorData, 0, sizeof(xorData));
1220 
1221  for (y = 0; y < sizeY; y++) {
1222  fullBitRow = 0;
1223  fullMaskRow = 0;
1224  for (x = cols - 1; x >= 0; x--) {
1225  fullBitRow <<= 8;
1226  fullMaskRow <<= 8;
1227  fullBitRow |= uns8ReverseBits(bitmap[cols * y + x]);
1228  fullMaskRow |= uns8ReverseBits(mask[cols * y + x]);
1229  }
1230  xorData[y] = fullBitRow & fullMaskRow;
1231  andData[y] = ~fullMaskRow;
1232  }
1233 
1234  m_customCursor = ::CreateCursor(::GetModuleHandle(0), hotX, hotY, 32, 32, andData, xorData);
1235  if (!m_customCursor) {
1236  return GHOST_kFailure;
1237  }
1238 
1239  if (::GetForegroundWindow() == m_hWnd) {
1241  }
1242 
1243  return GHOST_kSuccess;
1244 }
1245 
1247 {
1248  /* #SetProgressValue sets state to #TBPF_NORMAL automatically. */
1249  if (m_Bar && S_OK == m_Bar->SetProgressValue(m_hWnd, 10000 * progress, 10000))
1250  return GHOST_kSuccess;
1251 
1252  return GHOST_kFailure;
1253 }
1254 
1256 {
1257  if (m_Bar && S_OK == m_Bar->SetProgressState(m_hWnd, TBPF_NOPROGRESS))
1258  return GHOST_kSuccess;
1259 
1260  return GHOST_kFailure;
1261 }
1262 
1263 #ifdef WITH_INPUT_IME
1264 void GHOST_WindowWin32::beginIME(
1265  GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed)
1266 {
1267  m_imeInput.BeginIME(m_hWnd, GHOST_Rect(x, y - h, x, y), (bool)completed);
1268 }
1269 
1270 void GHOST_WindowWin32::endIME()
1271 {
1272  m_imeInput.EndIME(m_hWnd);
1273 }
1274 #endif /* WITH_INPUT_IME */
typedef float(TangentPoint)[2]
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:116
#define M_PI
Definition: BLI_math_base.h:38
#define FALSE
Definition: GHOST_C-Test.c:33
#define GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY
#define USER_DEFAULT_SCREEN_DPI
@ TBPF_NOPROGRESS
const GUID CLSID_TaskbarList
GHOST_TWindowState
Definition: GHOST_Types.h:144
@ GHOST_kWindowStateMinimized
Definition: GHOST_Types.h:147
@ GHOST_kWindowStateMaximized
Definition: GHOST_Types.h:146
@ GHOST_kWindowStateNormal
Definition: GHOST_Types.h:145
@ GHOST_kWindowStateFullScreen
Definition: GHOST_Types.h:148
GHOST_TStandardCursor
Definition: GHOST_Types.h:222
@ GHOST_kStandardCursorBottomLeftCorner
Definition: GHOST_Types.h:260
@ GHOST_kStandardCursorZoomIn
Definition: GHOST_Types.h:244
@ GHOST_kStandardCursorVerticalSplit
Definition: GHOST_Types.h:239
@ GHOST_kStandardCursorHelp
Definition: GHOST_Types.h:229
@ GHOST_kStandardCursorWait
Definition: GHOST_Types.h:230
@ GHOST_kStandardCursorHorizontalSplit
Definition: GHOST_Types.h:240
@ GHOST_kStandardCursorTopSide
Definition: GHOST_Types.h:253
@ GHOST_kStandardCursorStop
Definition: GHOST_Types.h:250
@ GHOST_kStandardCursorCrosshair
Definition: GHOST_Types.h:232
@ GHOST_kStandardCursorCustom
Definition: GHOST_Types.h:262
@ GHOST_kStandardCursorNSEWScroll
Definition: GHOST_Types.h:247
@ GHOST_kStandardCursorLeftRight
Definition: GHOST_Types.h:252
@ GHOST_kStandardCursorPencil
Definition: GHOST_Types.h:236
@ GHOST_kStandardCursorNSScroll
Definition: GHOST_Types.h:248
@ GHOST_kStandardCursorCrosshairA
Definition: GHOST_Types.h:233
@ GHOST_kStandardCursorUpDown
Definition: GHOST_Types.h:251
@ GHOST_kStandardCursorUpArrow
Definition: GHOST_Types.h:237
@ GHOST_kStandardCursorBottomSide
Definition: GHOST_Types.h:254
@ GHOST_kStandardCursorTopLeftCorner
Definition: GHOST_Types.h:257
@ GHOST_kStandardCursorEyedropper
Definition: GHOST_Types.h:243
@ GHOST_kStandardCursorKnife
Definition: GHOST_Types.h:242
@ GHOST_kStandardCursorMove
Definition: GHOST_Types.h:246
@ GHOST_kStandardCursorCrosshairB
Definition: GHOST_Types.h:234
@ GHOST_kStandardCursorBottomRightCorner
Definition: GHOST_Types.h:259
@ GHOST_kStandardCursorDownArrow
Definition: GHOST_Types.h:238
@ GHOST_kStandardCursorEraser
Definition: GHOST_Types.h:241
@ GHOST_kStandardCursorDefault
Definition: GHOST_Types.h:224
@ GHOST_kStandardCursorEWScroll
Definition: GHOST_Types.h:249
@ GHOST_kStandardCursorRightArrow
Definition: GHOST_Types.h:225
@ GHOST_kStandardCursorTopRightCorner
Definition: GHOST_Types.h:258
@ GHOST_kStandardCursorDestroy
Definition: GHOST_Types.h:228
@ GHOST_kStandardCursorCrosshairC
Definition: GHOST_Types.h:235
@ GHOST_kStandardCursorZoomOut
Definition: GHOST_Types.h:245
@ GHOST_kStandardCursorLeftSide
Definition: GHOST_Types.h:255
@ GHOST_kStandardCursorText
Definition: GHOST_Types.h:231
@ GHOST_kStandardCursorLeftArrow
Definition: GHOST_Types.h:226
unsigned int GHOST_TUns32
Definition: GHOST_Types.h:64
static const GHOST_TabletData GHOST_TABLET_DATA_NONE
Definition: GHOST_Types.h:119
int GHOST_TInt32
Definition: GHOST_Types.h:63
@ GHOST_kTabletModeEraser
Definition: GHOST_Types.h:103
@ GHOST_kTabletModeStylus
Definition: GHOST_Types.h:102
@ GHOST_kTabletModeNone
Definition: GHOST_Types.h:101
unsigned short GHOST_TUns16
Definition: GHOST_Types.h:62
GHOST_TDrawingContextType
Definition: GHOST_Types.h:156
@ GHOST_kDrawingContextTypeOpenGL
Definition: GHOST_Types.h:158
@ GHOST_kButtonMaskRight
Definition: GHOST_Types.h:168
@ GHOST_kButtonMaskButton4
Definition: GHOST_Types.h:169
@ GHOST_kButtonMaskLeft
Definition: GHOST_Types.h:166
@ GHOST_kButtonMaskButton5
Definition: GHOST_Types.h:170
@ GHOST_kButtonMaskMiddle
Definition: GHOST_Types.h:167
GHOST_TWindowOrder
Definition: GHOST_Types.h:154
@ GHOST_kWindowOrderBottom
Definition: GHOST_Types.h:154
GHOST_TSuccess
Definition: GHOST_Types.h:91
@ GHOST_kFailure
Definition: GHOST_Types.h:91
@ GHOST_kSuccess
Definition: GHOST_Types.h:91
GHOST_TGrabCursorMode
Definition: GHOST_Types.h:412
@ GHOST_kGrabDisable
Definition: GHOST_Types.h:414
@ GHOST_kGrabHide
Definition: GHOST_Types.h:420
@ GHOST_kGrabNormal
Definition: GHOST_Types.h:416
unsigned char GHOST_TUns8
Definition: GHOST_Types.h:60
GHOST_TTabletAPI
Definition: GHOST_Types.h:106
@ GHOST_kTabletNative
Definition: GHOST_Types.h:108
@ GHOST_kTabletAutomatic
Definition: GHOST_Types.h:107
@ GHOST_kTabletWintab
Definition: GHOST_Types.h:109
static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt)
static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
__declspec(dllexport) DWORD NvOptimusEnablement=0x00000001
BOOL(API * GHOST_WIN32_WTOverlap)(HCTX, BOOL)
BOOL(API * GHOST_WIN32_WTEnable)(HCTX, BOOL)
UINT(API * GHOST_WIN32_GetDpiForWindow)(HWND)
#define IS_POINTER_PRIMARY_WPARAM(wParam)
#define PACKETMODE
HCTX(API * GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL)
BOOL(API * GHOST_WIN32_WTClose)(HCTX)
#define PEN_MASK_TILT_Y
#define GET_POINTERID_WPARAM(wParam)
#define PEN_MASK_TILT_X
@ POINTER_CHANGE_THIRDBUTTON_UP
@ POINTER_CHANGE_FIFTHBUTTON_UP
@ POINTER_CHANGE_FIRSTBUTTON_DOWN
@ POINTER_CHANGE_SECONDBUTTON_DOWN
@ POINTER_CHANGE_FOURTHBUTTON_DOWN
@ POINTER_CHANGE_FIFTHBUTTON_DOWN
@ POINTER_CHANGE_FOURTHBUTTON_UP
@ POINTER_CHANGE_THIRDBUTTON_DOWN
@ POINTER_CHANGE_SECONDBUTTON_UP
@ POINTER_CHANGE_FIRSTBUTTON_UP
#define PACKETDATA
BOOL(WINAPI * GHOST_WIN32_GetPointerPenInfoHistory)(UINT32 pointerId, UINT32 *entriesCount, POINTER_PEN_INFO *penInfo)
BOOL(WINAPI * GHOST_WIN32_GetPointerInfoHistory)(UINT32 pointerId, UINT32 *entriesCount, POINTER_INFO *pointerInfo)
BOOL(API * GHOST_WIN32_RegisterTouchWindow)(HWND hwnd, ULONG ulFlags)
GHOST_MouseCaptureEventWin32
@ MousePressed
@ OperatorUngrab
@ MouseReleased
@ OperatorGrab
#define PEN_MASK_PRESSURE
#define PEN_FLAG_ERASER
typedef LPVOID
BOOL(API * GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID)
BOOL(WINAPI * GHOST_WIN32_GetPointerTouchInfoHistory)(UINT32 pointerId, UINT32 *entriesCount, POINTER_TOUCH_INFO *touchInfo)
_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 type
_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 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
static struct PyModuleDef module
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
ULONG __stdcall Release(void)
static GHOST_ISystem * getSystem()
virtual GHOST_TInt32 getWidth() const
Definition: GHOST_Rect.h:182
GHOST_TInt32 m_l
Definition: GHOST_Rect.h:169
GHOST_TInt32 m_r
Definition: GHOST_Rect.h:173
virtual GHOST_TInt32 getHeight() const
Definition: GHOST_Rect.h:187
GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const
GHOST_TUns64 performanceCounterToMillis(__int64 perf_ticks) const
GHOST_WindowManager * getWindowManager() const
Definition: GHOST_System.h:417
GHOST_TTabletAPI getTabletAPI(void)
bool m_windowFocus
Definition: GHOST_System.h:174
const std::vector< GHOST_IWindow * > & getWindows() const
GHOST_TSuccess invalidate()
GHOST_TUns16 getDPIHint() override
GHOST_WindowWin32(GHOST_SystemWin32 *system, const char *title, GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 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 processWin32TabletActivateEvent(WORD state)
GHOST_TSuccess setOrder(GHOST_TWindowOrder order)
GHOST_TSuccess setProgressBar(float progress)
void setTitle(const char *title)
std::string getTitle() const
void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const
GHOST_TSuccess getPointerInfo(std::vector< GHOST_PointerInfoWin32 > &outPointerInfo, WPARAM wParam, LPARAM lParam)
GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
void processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
HCURSOR getStandardCursor(GHOST_TStandardCursor shape) const
void updateMouseCapture(GHOST_MouseCaptureEventWin32 event)
GHOST_TSuccess setState(GHOST_TWindowState state)
void getWindowBounds(GHOST_Rect &bounds) const
void getClientBounds(GHOST_Rect &bounds) const
void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32 &outX, GHOST_TInt32 &outY) const
GHOST_TSuccess setClientHeight(GHOST_TUns32 height)
GHOST_TSuccess endProgressBar()
GHOST_TWindowState getState() const
void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32 &outX, GHOST_TInt32 &outY) const
bool useTabletAPI(GHOST_TTabletAPI api) const
GHOST_TSuccess setClientWidth(GHOST_TUns32 width)
GHOST_Rect m_cursorGrabBounds
Definition: GHOST_Window.h:378
bool getCursorVisibility() const
Definition: GHOST_Window.h:415
GHOST_TGrabCursorMode m_cursorGrab
Definition: GHOST_Window.h:366
bool m_wantStereoVisual
Definition: GHOST_Window.h:396
GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type)
GHOST_TSuccess releaseNativeHandles()
GHOST_TInt32 m_cursorGrabInitPos[2]
Definition: GHOST_Window.h:372
virtual bool getValid() const
Definition: GHOST_Window.h:92
void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y)
Definition: GHOST_Window.h:447
GHOST_TStandardCursor getCursorShape() const
Definition: GHOST_Window.h:453
virtual HRESULT STDMETHODCALLTYPE SetProgressState(HWND hwnd, TBPFLAG tbpFlags)=0
virtual HRESULT STDMETHODCALLTYPE SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal)=0
uint pos
static ulong state[N]
static int left
#define L
static const VertexNature POINT
Definition: Nature.h:34
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:311
struct SELECTID_Context context
Definition: select_engine.c:47
#define min(a, b)
Definition: sort.c:51
GHOST_TTabletMode Active
Definition: GHOST_Types.h:113
POINTER_BUTTON_CHANGE_TYPE ButtonChangeType
float max
size_t count_utf_8_from_16(const wchar_t *string16)
Definition: utfconv.c:23
wchar_t * alloc_utf16_from_8(const char *in8, size_t add)
Definition: utfconv.c:296
int conv_utf_16_to_8(const wchar_t *in16, char *out8, size_t size8)
Definition: utfconv.c:127
ccl_device_inline float2 fabs(const float2 &a)
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)