OpenClonk
C4DrawGLMac.mm
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
5  *
6  * Distributed under the terms of the ISC license; see accompanying file
7  * "COPYING" for details.
8  *
9  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
10  * See accompanying file "TRADEMARK" for details.
11  *
12  * To redistribute this file separately, substitute the full license texts
13  * for the above references.
14  */
15 
16 #define GL_SILENCE_DEPRECATION
17 #include <epoxy/gl.h>
18 #include "C4Include.h"
19 #include "game/C4GraphicsSystem.h"
20 #include "gui/C4MouseControl.h"
21 #include "gui/C4Gui.h"
22 #include "game/C4Game.h"
23 #include "game/C4Viewport.h"
25 #include "editor/C4Console.h"
26 #include "game/C4FullScreen.h"
27 #include "player/C4PlayerList.h"
28 #include "gui/C4Gui.h"
29 #include "landscape/C4Landscape.h"
30 
31 #include "graphics/C4DrawGL.h"
32 
33 #import "graphics/C4DrawGLMac.h"
36 
37 #ifdef USE_COCOA
38 
39 @implementation C4OpenGLView
40 
41 @synthesize context;
42 
43 - (BOOL) isOpaque {return YES;}
44 
45 
46 - (id) initWithFrame:(NSRect)frameRect
47 {
48  self = [super initWithFrame:frameRect];
49  if (self != nil) {
50  [[NSNotificationCenter defaultCenter]
51  addObserver:self
52  selector:@selector(_surfaceNeedsUpdate:)
53  name:NSViewGlobalFrameDidChangeNotification
54  object:self];
55  }
56  return self;
57 }
58 
59 - (void) awakeFromNib
60 {
61  [self enableEvents];
62 }
63 
64 - (void) enableEvents
65 {
66  [[self window] makeFirstResponder:self];
67  [[self window] setAcceptsMouseMovedEvents:YES];
68 
69  [self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
70 }
71 
72 - (BOOL) acceptsFirstResponder {return YES;}
73 
74 - (void) resetCursorRects
75 {
76  [super resetCursorRects];
77  if ([self shouldHideMouseCursor])
78  {
79  static NSCursor* cursor;
80  if (!cursor)
81  {
82  cursor = [[NSCursor alloc] initWithImage:[[NSImage alloc] initWithSize:NSMakeSize(1, 1)] hotSpot:NSMakePoint(0, 0)];
83  }
84  [self addCursorRect:self.bounds cursor:cursor];
85  }
86 }
87 
88 - (void) _surfaceNeedsUpdate:(NSNotification*)notification
89 {
90  [self update];
91 }
92 
93 - (void) lockFocus
94 {
95  NSOpenGLContext* ctx = [self context];
96  [super lockFocus];
97  if ([ctx view] != self) {
98  [ctx setView:self];
99  }
100  [ctx makeCurrentContext];
101  if (!Application.isEditor)
102  {
103  /*int swapInterval = 1;
104  [ctx setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; */
105  }
106 }
107 
108 - (void) viewDidMoveToWindow
109 {
110  [super viewDidMoveToWindow];
111  if ([self window] == nil)
112  [context clearDrawable];
113 }
114 
115 - (void) drawRect:(NSRect)rect
116 {
117  // better not to draw anything when the game has already finished
119  return;
120 
121 #ifdef __MAC_10_9
122  // don't draw if tab-switched away from fullscreen
123  if ([NSApp respondsToSelector:@selector(occlusionState)])
124  {
125  // Mavericks - query app occlusion state
126  if (([NSApp occlusionState] & NSApplicationOcclusionStateVisible) == 0)
127  return;
128  }
129 #endif
130 
131  if ([self.controller isFullScreenConsideringLionFullScreen] && ![NSApp isActive])
132  return;
133  if ([self.window isMiniaturized] || ![self.window isVisible])
134  return;
135 
136  C4Window* stdWindow = self.controller.stdWindow;
137 
138  if (stdWindow)
139  stdWindow->PerformUpdate();
140  else
141  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
142 }
143 
144 - (C4WindowController*) controller {return (C4WindowController*)[self.window delegate];}
145 
146 int32_t mouseButtonFromEvent(NSEvent* event, DWORD* modifierFlags)
147 {
148  *modifierFlags = [event modifierFlags]; // should be compatible since MK_* constants mirror the NS* constants
149  if ([event modifierFlags] & NSEventModifierFlagCommand)
150  {
151  // treat cmd and ctrl the same
152  *modifierFlags |= NSEventModifierFlagControl;
153  }
154  switch (event.type)
155  {
156  case NSEventTypeLeftMouseDown:
157  return [event clickCount] > 1 ? C4MC_Button_LeftDouble : C4MC_Button_LeftDown;
158  case NSEventTypeLeftMouseUp:
159  return C4MC_Button_LeftUp;
160  case NSEventTypeRightMouseDown:
161  return [event clickCount] > 1 ? C4MC_Button_RightDouble : C4MC_Button_RightDown;
162  case NSEventTypeRightMouseUp:
163  return C4MC_Button_RightUp;
164  case NSEventTypeLeftMouseDragged: case NSEventTypeRightMouseDragged:
165  return C4MC_Button_None; // sending mouse downs all the time when dragging is not the right thing to do
166  case NSEventTypeOtherMouseDown:
167  return C4MC_Button_MiddleDown;
168  case NSEventTypeOtherMouseUp:
169  return C4MC_Button_MiddleUp;
170  case NSEventTypeScrollWheel:
171  return C4MC_Button_Wheel;
172  default:
173  break;
174  }
175  return C4MC_Button_None;
176 }
177 
178 - (BOOL) shouldHideMouseCursor
179 {
180  return !Application.isEditor || (self.controller.viewport && Console.EditCursor.GetMode() == C4CNS_ModePlay && ValidPlr(self.controller.viewport->GetPlayer()));
181 }
182 
183 - (void) showCursor
184 {
185  if ([self shouldHideMouseCursor])
186  [NSCursor unhide];
187 }
188 
189 - (void) hideCursor
190 {
191  if ([self shouldHideMouseCursor])
192  [NSCursor hide];
193 }
194 
195 - (void) mouseEvent:(NSEvent*)event
196 {
197  DWORD flags = 0;
198  int32_t button = mouseButtonFromEvent(event, &flags);
199  int actualSizeX = Application.isEditor ? self.frame.size.width : ActualFullscreenX;
200  int actualSizeY = Application.isEditor ? self.frame.size.height : ActualFullscreenY;
201  CGPoint mouse = [self convertPoint:[self.window mouseLocationOutsideOfEventStream] fromView:nil];
202  if (!Application.isEditor)
203  {
204  mouse.x *= ActualFullscreenX/self.frame.size.width;
205  mouse.y *= ActualFullscreenY/self.frame.size.height;
206  }
207  mouse.x = fmin(fmax(mouse.x, 0), actualSizeX);
208  mouse.y = fmin(fmax(mouse.y, 0), actualSizeY);
209  int x = mouse.x;
210  int y = actualSizeY - mouse.y;
211 
212  C4Viewport* viewport = self.controller.viewport;
214  {
215  DWORD keyMask = flags;
216  if ([event type] == NSEventTypeScrollWheel)
217  {
218  // TODO: We could evaluate the full smooth scrolling
219  // information, but zoom and inventory scrolling don't
220  // do very well with that at the moment.
221  if ([event deltaY] > 0)
222  keyMask |= (+32) << 16;
223  else
224  keyMask |= (-32) << 16;
225  }
226 
227  ::C4GUI::MouseMove(button, x, y, keyMask, Application.isEditor ? viewport : NULL);
228  }
229  else if (viewport)
230  {
231  switch (button)
232  {
234  Console.EditCursor.Move(viewport->GetViewX()+x/viewport->GetZoom(), viewport->GetViewY()+y/viewport->GetZoom(), viewport->GetZoom(), flags);
236  break;
237  case C4MC_Button_LeftUp:
239  break;
242  break;
243  case C4MC_Button_RightUp:
245  break;
246  case C4MC_Button_None:
247  Console.EditCursor.Move(viewport->GetViewX()+x/viewport->GetZoom(),viewport->GetViewY()+y/viewport->GetZoom(), viewport->GetZoom(), flags);
248  break;
249  }
250  }
251 
252 }
253 
254 - (void) magnifyWithEvent:(NSEvent *)event
255 {
256  if (Game.IsRunning && (event.modifierFlags & NSEventModifierFlagOption) == 0)
257  {
258  C4Viewport* viewport = self.controller.viewport;
259  if (viewport)
260  {
261  viewport->SetZoom(viewport->GetZoom()+[event magnification], true);
262  }
263  }
264  else
265  {
266  if (lionAndBeyond())
267  [self.window toggleFullScreen:self];
268  else
269  [self.controller setFullscreen:[event magnification] > 0];
270  }
271 
272 }
273 
274 - (void) swipeWithEvent:(NSEvent*)event
275 {
276  // swiping left triggers going back in startup dialogs
277  if (event.deltaX > 0)
278  [C4AppDelegate.instance simulateKeyPressed:K_LEFT];
279  else
280  [C4AppDelegate.instance simulateKeyPressed:K_RIGHT];
281 }
282 
283 - (void)insertText:(id)insertString
284 {
285  if (::pGUI)
286  {
287  NSString* str = [insertString isKindOfClass:[NSAttributedString class]] ? [(NSAttributedString*)insertString string] : (NSString*)insertString;
288  const char* cstr = [str cStringUsingEncoding:NSUTF8StringEncoding];
289  ::pGUI->CharIn(cstr);
290  }
291 }
292 
293 - (void)doCommandBySelector:(SEL)selector
294 {
295  // ignore to not trigger the annoying beep sound
296 }
297 
298 - (void)keyEvent:(NSEvent*)event withKeyEventType:(C4KeyEventType)type
299 {
301  [event keyCode]+CocoaKeycodeOffset, // offset keycode by some value to distinguish between those special key defines
302  type,
303  [event modifierFlags] & NSEventModifierFlagOption,
304  ([event modifierFlags] & NSEventModifierFlagControl) || ([event modifierFlags] & NSEventModifierFlagCommand),
305  [event modifierFlags] & NSEventModifierFlagShift,
306  false, NULL
307  );
308 
309  C4Window* stdWindow = self.controller.stdWindow;
310  if (stdWindow->eKind == C4ConsoleGUI::W_Viewport)
311  {
312  if (type == KEYEV_Down)
313  Console.EditCursor.KeyDown([event keyCode]+CocoaKeycodeOffset, [event modifierFlags]);
314  else
315  Console.EditCursor.KeyUp([event keyCode]+CocoaKeycodeOffset, [event modifierFlags]);
316  }
317 }
318 
319 - (void)keyDown:(NSEvent*)event
320 {
321  [self interpretKeyEvents:[NSArray arrayWithObject:event]]; // call this to route character input to insertText:
322  [self keyEvent:event withKeyEventType:KEYEV_Down];
323 }
324 
325 - (void)keyUp:(NSEvent*)event
326 {
327  [self keyEvent:event withKeyEventType:KEYEV_Up];
328 }
329 
330 - (void)flagsChanged:(NSEvent*)event
331 {
332  // Send keypress/release events for relevant modifier keys
333  // keyDown() is not called for modifier keys.
334  C4KeyCode key = (C4KeyCode)([event keyCode] + CocoaKeycodeOffset);
335  int modifier = 0;
336  if (key == K_SHIFT_L || key == K_SHIFT_R)
337  modifier = NSEventModifierFlagShift;
338  if (key == K_CONTROL_L || key == K_CONTROL_R)
339  modifier = NSEventModifierFlagControl;
340  if (key == K_COMMAND_L || key == K_COMMAND_R)
341  modifier = NSEventModifierFlagCommand;
342  if (key == K_ALT_L || key == K_ALT_R)
343  modifier = NSEventModifierFlagOption;
344 
345  if (modifier != 0)
346  {
347  int modifierMask = [event modifierFlags];
348  if (modifierMask & modifier)
349  [self keyEvent:event withKeyEventType:KEYEV_Down];
350  else
351  [self keyEvent:event withKeyEventType:KEYEV_Up];
352  }
353 }
354 
355 - (NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender
356 {
357  return NSDragOperationCopy;
358 }
359 
360 - (NSDragOperation) draggingUpdated:(id<NSDraggingInfo>)sender
361 {
362  return NSDragOperationCopy;
363 }
364 
365 - (BOOL) prepareForDragOperation:(id<NSDraggingInfo>)sender
366 {
367  return YES;
368 }
369 
370 - (BOOL) performDragOperation:(id<NSDraggingInfo>)sender
371 {
372  NSPasteboard* pasteboard = [sender draggingPasteboard];
373  if ([[pasteboard types] containsObject:NSFilenamesPboardType])
374  {
375  NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType];
376  C4Viewport* viewport = self.controller.viewport;
377  if (viewport)
378  {
379  for (NSString* fileName in files)
380  {
381  auto loc = NSMakePoint([sender draggingLocation].x, self.bounds.size.height - [sender draggingLocation].y);
382  viewport->DropFile([fileName cStringUsingEncoding:NSUTF8StringEncoding], loc.x, loc.y);
383  }
384  }
385  }
386  return YES;
387 }
388 
389 - (void )concludeDragOperation:(id<NSDraggingInfo>)sender
390 {
391 }
392 
393 // respaghettisize :D
394 
395 - (void) scrollWheel:(NSEvent *)event
396 {
397  // Scroll viewport in editor mode
398  C4Viewport* viewport = self.controller.viewport;
399  if (Application.isEditor && viewport && !viewport->GetPlayerLock())
400  {
401  NSScrollView* scrollView = self.controller.scrollView;
402  NSPoint p = NSMakePoint(2*-[event deltaX]/abs(::Landscape.GetWidth()-viewport->ViewWdt), 2*-[event deltaY]/abs(::Landscape.GetHeight()-viewport->ViewHgt));
403  [scrollView.horizontalScroller setDoubleValue:scrollView.horizontalScroller.doubleValue+p.x];
404  [scrollView.verticalScroller setDoubleValue:scrollView.verticalScroller.doubleValue+p.y];
405  viewport->ViewPositionByScrollBars();
406  [self display];
407  }
408  else
409  {
410  // If player lock is enabled or fullscreen: handle scroll
411  // event in-game.
412  [self mouseEvent:event];
413  }
414 }
415 
416 - (void) mouseDown: (NSEvent *)event {[self mouseEvent:event];}
417 - (void) rightMouseDown: (NSEvent *)event {[self mouseEvent:event];}
418 - (void) rightMouseUp: (NSEvent *)event {[self mouseEvent:event];}
419 - (void) otherMouseDown: (NSEvent *)event {[self mouseEvent:event];}
420 - (void) otherMouseUp: (NSEvent *)event {[self mouseEvent:event];}
421 - (void) mouseUp: (NSEvent *)event {[self mouseEvent:event];}
422 - (void) mouseMoved: (NSEvent *)event {[self mouseEvent:event];}
423 - (void) mouseDragged: (NSEvent *)event {[self mouseEvent:event];}
424 - (void) rightMouseDragged:(NSEvent *)event {[self mouseEvent:event];}
425 
426 - (void) update
427 {
428  [context update];
429 }
430 
431 + (CGDirectDisplayID) displayID
432 {
433  return (CGDirectDisplayID)[[[[[NSApp keyWindow] screen] deviceDescription] valueForKey:@"NSScreenNumber"] intValue];
434 }
435 
436 + (void) enumerateMultiSamples:(std::vector<int>&)samples
437 {
438  CGDirectDisplayID displayID = self.displayID;
439  CGOpenGLDisplayMask displayMask = CGDisplayIDToOpenGLDisplayMask(displayID);
440  int numRenderers = 0;
441  CGLRendererInfoObj obj = NULL;
442  GLint sampleModes;
443 
444  CGLQueryRendererInfo(displayMask, &obj, &numRenderers);
445  CGLDescribeRenderer(obj, 0, kCGLRPSampleModes, &sampleModes);
446  CGLDestroyRendererInfo(obj);
447 
448  if (sampleModes & kCGLMultisampleBit)
449  {
450  samples.push_back(1);
451  samples.push_back(2);
452  samples.push_back(4);
453  }
454 }
455 
456 + (void) setSurfaceBackingSizeOf:(NSOpenGLContext*) context width:(int)wdt height:(int)hgt
457 {
458  if (context && !Application.isEditor)
459  {
460  // Make back buffer size fixed ( http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_contexts/opengl_contexts.html )
461  GLint dim[2] = {wdt, hgt};
462  CGLContextObj ctx = (CGLContextObj)context.CGLContextObj;
463  CGLSetParameter(ctx, kCGLCPSurfaceBackingSize, dim);
464  CGLEnable (ctx, kCGLCESurfaceBackingSize);
465  }
466 }
467 
468 - (void) setContextSurfaceBackingSizeToOwnDimensions
469 {
470  [C4OpenGLView setSurfaceBackingSizeOf:self.context width:self.frame.size.width height:self.frame.size.height];
471 }
472 
473 static NSOpenGLContext* MainContext;
474 
475 + (NSOpenGLContext*) mainContext
476 {
477  return MainContext;
478 }
479 
480 + (NSOpenGLContext*) createContext:(CStdGLCtx*) pMainCtx
481 {
482  std::vector<NSOpenGLPixelFormatAttribute> attribs;
483  attribs.push_back(NSOpenGLPFAOpenGLProfile);
484  attribs.push_back(NSOpenGLProfileVersion3_2Core);
485  attribs.push_back(NSOpenGLPFADepthSize);
486  attribs.push_back(16);
488  {
489  std::vector<int> samples;
490  [self enumerateMultiSamples:samples];
491  if (!samples.empty())
492  {
493  attribs.push_back(NSOpenGLPFAMultisample);
494  attribs.push_back(NSOpenGLPFASampleBuffers);
495  attribs.push_back(1);
496  attribs.push_back(NSOpenGLPFASamples);
497  attribs.push_back(Config.Graphics.MultiSampling);
498  }
499  }
500  attribs.push_back(NSOpenGLPFANoRecovery);
501  //attribs.push_back(NSOpenGLPFADoubleBuffer);
502  //attribs.push_back(NSOpenGLPFAWindow); // cannot create a core profile with this
503  attribs.push_back(0);
504  NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]];
505  NSOpenGLContext* result = [[NSOpenGLContext alloc] initWithFormat:format shareContext:pMainCtx ? pMainCtx->objectiveCObject<NSOpenGLContext>() : nil];
506  if (!MainContext)
507  MainContext = result;
508  return result;
509 }
510 
511 - (IBAction) increaseZoom:(id)sender
512 {
513  if (Application.isEditor)
514  {
515  C4Viewport* v = self.controller.viewport;
516  v->SetZoom(v->GetZoom()*2, false);
517  }
518  else
520 }
521 
522 - (IBAction) decreaseZoom:(id)sender
523 {
524  if (Application.isEditor)
525  {
526  C4Viewport* v = self.controller.viewport;
527  v->SetZoom(v->GetZoom()/2, false);
528  }
529  else
531 }
532 
533 @end
534 
535 @implementation C4EditorOpenGLView
536 
537 - (void) copy:(id) sender
538 {
540 }
541 
542 - (void) delete:(id) sender
543 {
545 }
546 
547 - (IBAction) grabContents:(id) sender
548 {
550 }
551 
552 - (IBAction) resetZoom:(id) sender
553 {
554  self.controller.viewport->SetZoom(1, true);
555 }
556 
557 @end
558 
559 #pragma mark CStdGLCtx: Initialization
560 
561 CStdGLCtx::CStdGLCtx(): pWindow(0), this_context(contexts.end()) {}
562 
563 void CStdGLCtx::Clear(bool multisample_change)
564 {
565  Deselect();
566  setObjectiveCObject(nil);
567  pWindow = 0;
568 
569  if (this_context != contexts.end())
570  {
571  contexts.erase(this_context);
572  this_context = contexts.end();
573  }
574 }
575 
576 void C4Window::EnumerateMultiSamples(std::vector<int>& samples, int) const
577 {
578  [C4OpenGLView enumerateMultiSamples:samples];
579 }
580 
581 bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *)
582 {
583  // safety
584  if (!pGL) return false;
585  // store window
586  this->pWindow = pWindow;
587  // Create Context with sharing (if this is the main context, our ctx will be 0, so no sharing)
588  // try direct rendering first
589  NSOpenGLContext* ctx = [C4OpenGLView createContext:pGL->pMainCtx];
590  setObjectiveCObject(ctx);
591  // No luck at all?
592  if (!Select(true)) return pGL->Error(" gl: Unable to select context");
593  // set the openglview's context
594  auto controller = pWindow->objectiveCObject<C4WindowController>();
595  if (controller && controller.openGLView)
596  {
597  [controller.openGLView setContext:ctx];
598  [ctx setView:controller.openGLView];
599  }
600 
601  this_context = contexts.insert(contexts.end(), this);
602  return true;
603 }
604 
605 #pragma mark CStdGLCtx: Select/Deselect
606 
607 bool CStdGLCtx::Select(bool verbose)
608 {
609  [objectiveCObject<NSOpenGLContext>() makeCurrentContext];
610  SelectCommon();
611  // update clipper - might have been done by UpdateSize
612  // however, the wrong size might have been assumed
613  if (!pGL->UpdateClipper())
614  {
615  if (verbose) pGL->Error(" gl: UpdateClipper failed");
616  return false;
617  }
618  // success
619  return true;
620 }
621 
622 void CStdGLCtx::Deselect()
623 {
624  if (pGL && pGL->pCurrCtx == this)
625  {
626  pGL->pCurrCtx = 0;
627  }
628 }
629 
630 bool CStdGLCtx::PageFlip()
631 {
632  // flush GL buffer
633  glFlush();
634  if (!pWindow) return false;
635  //SDL_GL_SwapBuffers();
636  return true;
637 }
638 
639 int ActualFullscreenX = 0, ActualFullscreenY = 0;
640 
641 #endif
C4Config Config
Definition: C4Config.cpp:930
const int C4CNS_ModePlay
Definition: C4Console.h:30
CStdGL * pGL
Definition: C4DrawGL.cpp:907
C4Game Game
Definition: C4Globals.cpp:52
C4Console Console
Definition: C4Globals.cpp:45
C4Application Application
Definition: C4Globals.cpp:44
C4MouseControl MouseControl
Definition: C4Globals.cpp:47
C4GUIScreen * pGUI
Definition: C4Gui.cpp:1191
C4KeyEventType
@ KEYEV_Down
unsigned long C4KeyCode
C4Landscape Landscape
const int32_t C4MC_Button_None
const int32_t C4MC_Button_RightDown
const int32_t C4MC_Button_MiddleUp
const int32_t C4MC_Button_RightUp
const int32_t C4MC_Button_MiddleDown
const int32_t C4MC_Button_RightDouble
const int32_t C4MC_Button_LeftUp
const int32_t C4MC_Button_LeftDown
const int32_t C4MC_Button_LeftDouble
const int32_t C4MC_Button_Wheel
int32_t ValidPlr(int32_t plr)
C4ViewportList Viewports
bool lionAndBeyond()
uint32_t DWORD
bool fQuitMsgReceived
Definition: C4App.h:81
int32_t MultiSampling
Definition: C4Config.h:115
C4ConfigGraphics Graphics
Definition: C4Config.h:257
C4EditCursor EditCursor
Definition: C4Console.h:90
bool LeftButtonDown(DWORD dwKeyState)
int32_t GetMode()
bool KeyDown(C4KeyCode KeyCode, DWORD dwKeyState)
bool RightButtonDown(DWORD dwKeyState)
bool RightButtonUp(DWORD dwKeyState)
bool LeftButtonUp(DWORD dwKeyState)
bool Move(float iX, float iY, float zoom, DWORD dwKeyState)
bool KeyUp(C4KeyCode KeyCode, DWORD dwKeyState)
virtual bool CharIn(const char *c)
Definition: C4Gui.cpp:779
bool IsRunning
Definition: C4Game.h:140
bool DoKeyboardInput(C4KeyCode vk_code, C4KeyEventType event_type, bool alt, bool ctrl, bool shift, bool repeated, class C4GUI::Dialog *for_dialog=nullptr, bool fPlrCtrlOnly=false, int32_t strength=-1)
Definition: C4Game.cpp:2288
int32_t GetWidth() const
int32_t GetHeight() const
bool IsViewport(C4Viewport *pViewport)
bool GetPlayerLock()
Definition: C4Viewport.h:65
bool ViewPositionByScrollBars()
int32_t ViewWdt
Definition: C4Viewport.h:36
float GetViewY()
Definition: C4Viewport.h:78
int32_t ViewHgt
Definition: C4Viewport.h:37
float GetViewX()
Definition: C4Viewport.h:76
void DropFile(const char *filename, float x, float y)
Definition: C4Viewport.cpp:47
void SetZoom(float zoom_value)
Definition: C4Viewport.cpp:592
float GetZoom()
Definition: C4Viewport.h:48
bool ViewportZoomOut()
bool ViewportZoomIn()
virtual void EnumerateMultiSamples(std::vector< int > &samples, int min_expected=0) const
Definition: C4AppT.cpp:105
virtual void PerformUpdate()
Definition: C4App.cpp:85
WindowKind eKind
Definition: C4Window.h:276
@ W_Viewport
Definition: C4Window.h:267
void SelectCommon()
Definition: C4DrawGLCtx.cpp:35
virtual bool Init(C4Window *pWindow, C4AbstractApp *pApp)
virtual bool Select(bool verbose=false)
virtual void Clear(bool multisample_change=false)
virtual bool PageFlip()
static std::list< CStdGLCtx * > contexts
Definition: C4DrawGL.h:136
std::list< CStdGLCtx * >::iterator this_context
Definition: C4DrawGL.h:137
virtual void Deselect()
C4Window * pWindow
Definition: C4DrawGL.h:128
CStdGLCtx * pCurrCtx
Definition: C4DrawGL.h:180
bool Error(const char *szMsg) override
Definition: C4DrawGL.cpp:855
bool UpdateClipper() override
Definition: C4DrawGL.cpp:143
IBAction simulateKeyPressed:(C4KeyCode key)
void MouseMove(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam, class C4Viewport *pVP)
Definition: C4Gui.h:2832