留学生考试辅导 //======================================================================

//========================================================================
// GLFW 3.4 macOS – www.glfw.org
//————————————————————————
// Copyright (c) 2009-2019 Camilla Löwy

Copyright By PowCoder代写 加微信 powcoder

// This software is provided ‘as-is’, without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source
// distribution.
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================

#include “internal.h”

#include
#include

// Returns the style mask corresponding to the window settings
static NSUInteger getStyleMask(_GLFWwindow* window)
NSUInteger styleMask = NSWindowStyleMaskMiniaturizable;

if (window->monitor || !window->decorated)
styleMask |= NSWindowStyleMaskBorderless;
styleMask |= NSWindowStyleMaskTitled |
NSWindowStyleMaskClosable;

if (window->resizable)
styleMask |= NSWindowStyleMaskResizable;

return styleMask;

// Returns whether the cursor is in the content area of the specified window
static GLFWbool cursorInContentArea(_GLFWwindow* window)
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
return [window->ns.view mouse:pos inRect:[window->ns.view frame]];

// Hides the cursor if not already hidden
static void hideCursor(_GLFWwindow* window)
if (!_glfw.ns.cursorHidden)
[NSCursor hide];
_glfw.ns.cursorHidden = GLFW_TRUE;

// Shows the cursor if not already shown
static void showCursor(_GLFWwindow* window)
if (_glfw.ns.cursorHidden)
[NSCursor unhide];
_glfw.ns.cursorHidden = GLFW_FALSE;

// Updates the cursor image according to its cursor mode
static void updateCursorImage(_GLFWwindow* window)
if (window->cursorMode == GLFW_CURSOR_NORMAL)
showCursor(window);

if (window->cursor)
[(NSCursor*) window->cursor->ns.object set];
[[NSCursor arrowCursor] set];
hideCursor(window);

// Apply chosen cursor mode to a focused window
static void updateCursorMode(_GLFWwindow* window)
if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfw.ns.disabledCursorWindow = window;
_glfwGetCursorPosCocoa(window,
&_glfw.ns.restoreCursorPosX,
&_glfw.ns.restoreCursorPosY);
_glfwCenterCursorInContentArea(window);
CGAssociateMouseAndMouseCursorPosition(false);
else if (_glfw.ns.disabledCursorWindow == window)
_glfw.ns.disabledCursorWindow = NULL;
_glfwSetCursorPosCocoa(window,
_glfw.ns.restoreCursorPosX,
_glfw.ns.restoreCursorPosY);
// NOTE: The matching CGAssociateMouseAndMouseCursorPosition call is
// made in _glfwSetCursorPosCocoa as part of a workaround

if (cursorInContentArea(window))
updateCursorImage(window);

// Make the specified window and its video mode active on its monitor
static void acquireMonitor(_GLFWwindow* window)
_glfwSetVideoModeCocoa(window->monitor, &window->videoMode);
const CGRect bounds = CGDisplayBounds(window->monitor->ns.displayID);
const NSRect frame = NSMakeRect(bounds.origin.x,
_glfwTransformYCocoa(bounds.origin.y + bounds.size.height – 1),
bounds.size.width,
bounds.size.height);

[window->ns.object setFrame:frame display:YES];

_glfwInputMonitorWindow(window->monitor, window);

// Remove the window and restore the original video mode
static void releaseMonitor(_GLFWwindow* window)
if (window->monitor->window != window)

_glfwInputMonitorWindow(window->monitor, NULL);
_glfwRestoreVideoModeCocoa(window->monitor);

// Translates macOS key modifiers into GLFW ones
static int translateFlags(NSUInteger flags)
int mods = 0;

if (flags & NSEventModifierFlagShift)
mods |= GLFW_MOD_SHIFT;
if (flags & NSEventModifierFlagControl)
mods |= GLFW_MOD_CONTROL;
if (flags & NSEventModifierFlagOption)
mods |= GLFW_MOD_ALT;
if (flags & NSEventModifierFlagCommand)
mods |= GLFW_MOD_SUPER;
if (flags & NSEventModifierFlagCapsLock)
mods |= GLFW_MOD_CAPS_LOCK;

return mods;

// Translates a macOS keycode to a GLFW keycode
static int translateKey(unsigned int key)
if (key >= sizeof(_glfw.ns.keycodes) / sizeof(_glfw.ns.keycodes[0]))
return GLFW_KEY_UNKNOWN;

return _glfw.ns.keycodes[key];

// Translate a GLFW keycode to a Cocoa modifier flag
static NSUInteger translateKeyToModifierFlag(int key)
switch (key)
case GLFW_KEY_LEFT_SHIFT:
case GLFW_KEY_RIGHT_SHIFT:
return NSEventModifierFlagShift;
case GLFW_KEY_LEFT_CONTROL:
case GLFW_KEY_RIGHT_CONTROL:
return NSEventModifierFlagControl;
case GLFW_KEY_LEFT_ALT:
case GLFW_KEY_RIGHT_ALT:
return NSEventModifierFlagOption;
case GLFW_KEY_LEFT_SUPER:
case GLFW_KEY_RIGHT_SUPER:
return NSEventModifierFlagCommand;
case GLFW_KEY_CAPS_LOCK:
return NSEventModifierFlagCapsLock;

// Defines a constant for empty ranges in NSTextInputClient
static const NSRange kEmptyRange = { NSNotFound, 0 };

//————————————————————————
// Delegate for window related notifications
//————————————————————————

@interface GLFWWindowDelegate : NSObject
_GLFWwindow* window;

– (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow;

@implementation GLFWWindowDelegate

– (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow
self = [super init];
if (self != nil)
window = initWindow;

return self;

– (BOOL)windowShouldClose:(id)sender
_glfwInputWindowCloseRequest(window);
return NO;

– (void)windowDidResize:(NSNotification *)notification
if (window->context.source == GLFW_NATIVE_CONTEXT_API)
[window->context.nsgl.object update];

if (_glfw.ns.disabledCursorWindow == window)
_glfwCenterCursorInContentArea(window);

const int maximized = [window->ns.object isZoomed];
if (window->ns.maximized != maximized)
window->ns.maximized = maximized;
_glfwInputWindowMaximize(window, maximized);

const NSRect contentRect = [window->ns.view frame];
const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];

if (fbRect.size.width != window->ns.fbWidth ||
fbRect.size.height != window->ns.fbHeight)
window->ns.fbWidth = fbRect.size.width;
window->ns.fbHeight = fbRect.size.height;
_glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);

if (contentRect.size.width != window->ns.width ||
contentRect.size.height != window->ns.height)
window->ns.width = contentRect.size.width;
window->ns.height = contentRect.size.height;
_glfwInputWindowSize(window, contentRect.size.width, contentRect.size.height);

– (void)windowDidMove:(NSNotification *)notification
if (window->context.source == GLFW_NATIVE_CONTEXT_API)
[window->context.nsgl.object update];

if (_glfw.ns.disabledCursorWindow == window)
_glfwCenterCursorInContentArea(window);

_glfwGetWindowPosCocoa(window, &x, &y);
_glfwInputWindowPos(window, x, y);

– (void)windowDidMiniaturize:(NSNotification *)notification
if (window->monitor)
releaseMonitor(window);

_glfwInputWindowIconify(window, GLFW_TRUE);

– (void)windowDidDeminiaturize:(NSNotification *)notification
if (window->monitor)
acquireMonitor(window);

_glfwInputWindowIconify(window, GLFW_FALSE);

– (void)windowDidBecomeKey:(NSNotification *)notification
if (_glfw.ns.disabledCursorWindow == window)
_glfwCenterCursorInContentArea(window);

_glfwInputWindowFocus(window, GLFW_TRUE);
updateCursorMode(window);

– (void)windowDidResignKey:(NSNotification *)notification
if (window->monitor && window->autoIconify)
_glfwIconifyWindowCocoa(window);

_glfwInputWindowFocus(window, GLFW_FALSE);

– (void)windowDidChangeOcclusionState:(NSNotification* )notification
if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)
window->ns.occluded = GLFW_FALSE;
window->ns.occluded = GLFW_TRUE;

//————————————————————————
// Content view class for the GLFW window
//————————————————————————

@interface GLFWContentView : NSView
_GLFWwindow* window;
NSTrackingArea* trackingArea;
NSMutableAttributedString* markedText;

– (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow;

@implementation GLFWContentView

– (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow
self = [super init];
if (self != nil)
window = initWindow;
trackingArea = nil;
markedText = [[NSMutableAttributedString alloc] init];

[self updateTrackingAreas];
// NOTE: kUTTypeURL corresponds to NSPasteboardTypeURL but is available
// on 10.7 without having been deprecated yet
[self NSString*) kUTTypeURL]];

return self;

– (void)dealloc
[trackingArea release];
[markedText release];
[super dealloc];

– (BOOL)isOpaque
return [window->ns.object isOpaque];

– (BOOL)canBecomeKeyView
return YES;

– (BOOL)acceptsFirstResponder
return YES;

– (BOOL)wantsUpdateLayer
return YES;

– (void)updateLayer
if (window->context.source == GLFW_NATIVE_CONTEXT_API)
[window->context.nsgl.object update];

_glfwInputWindowDamage(window);

– (void)cursorUpdate:(NSEvent *)event
updateCursorImage(window);

– (BOOL)acceptsFirstMouse:(NSEvent *)event
return YES;

– (void)mouseDown:(NSEvent *)event
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_LEFT,
GLFW_PRESS,
translateFlags([event modifierFlags]));

– (void)mouseDragged:(NSEvent *)event
[self mouseMoved:event];

– (void)mouseUp:(NSEvent *)event
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_LEFT,
GLFW_RELEASE,
translateFlags([event modifierFlags]));

– (void)mouseMoved:(NSEvent *)event
if (window->cursorMode == GLFW_CURSOR_DISABLED)
const double dx = [event deltaX] – window->ns.cursorWarpDeltaX;
const double dy = [event deltaY] – window->ns.cursorWarpDeltaY;

_glfwInputCursorPos(window,
window->virtualCursorPosX + dx,
window->virtualCursorPosY + dy);
const NSRect contentRect = [window->ns.view frame];
// NOTE: The returned location uses base 0,1 not 0,0
const NSPoint pos = [event locationInWindow];

_glfwInputCursorPos(window, pos.x, contentRect.size.height – pos.y);

window->ns.cursorWarpDeltaX = 0;
window->ns.cursorWarpDeltaY = 0;

– (void)rightMouseDown:(NSEvent *)event
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_RIGHT,
GLFW_PRESS,
translateFlags([event modifierFlags]));

– (void)rightMouseDragged:(NSEvent *)event
[self mouseMoved:event];

– (void)rightMouseUp:(NSEvent *)event
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_RIGHT,
GLFW_RELEASE,
translateFlags([event modifierFlags]));

– (void)otherMouseDown:(NSEvent *)event
_glfwInputMouseClick(window,
(int) [event buttonNumber],
GLFW_PRESS,
translateFlags([event modifierFlags]));

– (void)otherMouseDragged:(NSEvent *)event
[self mouseMoved:event];

– (void)otherMouseUp:(NSEvent *)event
_glfwInputMouseClick(window,
(int) [event buttonNumber],
GLFW_RELEASE,
translateFlags([event modifierFlags]));

– (void)mouseExited:(NSEvent *)event
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
showCursor(window);

_glfwInputCursorEnter(window, GLFW_FALSE);

– (void)mouseEntered:(NSEvent *)event
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
hideCursor(window);

_glfwInputCursorEnter(window, GLFW_TRUE);

– (void)viewDidChangeBackingProperties
const NSRect contentRect = [window->ns.view frame];
const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];
const float xscale = fbRect.size.width / contentRect.size.width;
const float yscale = fbRect.size.height / contentRect.size.height;

if (xscale != window->ns.xscale || yscale != window->ns.yscale)
if (window->ns.retina && window->ns.layer)
[window->ns.layer setContentsScale:[window->ns.object backingScaleFactor]];

window->ns.xscale = xscale;
window->ns.yscale = yscale;
_glfwInputWindowContentScale(window, xscale, yscale);

if (fbRect.size.width != window->ns.fbWidth ||
fbRect.size.height != window->ns.fbHeight)
window->ns.fbWidth = fbRect.size.width;
window->ns.fbHeight = fbRect.size.height;
_glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);

– (void)drawRect:(NSRect)rect
_glfwInputWindowDamage(window);

– (void)updateTrackingAreas
if (trackingArea != nil)
[self removeTrackingArea:trackingArea];
[trackingArea release];

const NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited |
NSTrackingActiveInKeyWindow |
NSTrackingEnabledDuringMouseDrag |
NSTrackingCursorUpdate |
NSTrackingInVisibleRect |
NSTrackingAssumeInside;

trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
options:options
owner:self
userInfo:nil];

[self addTrackingArea:trackingArea];
[super updateTrackingAreas];

– (void)keyDown:(NSEvent *)event
const int key = translateKey([event keyCode]);
const int mods = translateFlags([event modifierFlags]);

_glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);

– (void)flagsChanged:(NSEvent *)event
int action;
const unsigned int modifierFlags =
[event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
const int key = translateKey([event keyCode]);
const int mods = translateFlags(modifierFlags);
const NSUInteger keyFlag = translateKeyToModifierFlag(key);

if (keyFlag & modifierFlags)
if (window->keys[key] == GLFW_PRESS)
action = GLFW_RELEASE;
action = GLFW_PRESS;
action = GLFW_RELEASE;

_glfwInputKey(window, key, [event keyCode], action, mods);

– (void)keyUp:(NSEvent *)event
const int key = translateKey([event keyCode]);
const int mods = translateFlags([event modifierFlags]);
_glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods);

– (void)scrollWheel:(NSEvent *)event
double deltaX = [event scrollingDeltaX];
double deltaY = [event scrollingDeltaY];

if ([event hasPreciseScrollingDeltas])
deltaX *= 0.1;
deltaY *= 0.1;

if (fabs(deltaX) > 0.0 || fabs(deltaY) > 0.0)
_glfwInputScroll(window, deltaX, deltaY);

– (NSDragOperation)draggingEntered:(id )sender
// HACK: We don’t know what to say here because we don’t know what the
// application wants to do with the paths
return NSDragOperationGeneric;

– (BOOL)performDragOperation:(id )sender
const NSRect contentRect = [window->ns.view frame];
// NOTE: The returned location uses base 0,1 not 0,0
const NSPoint pos = [sender draggingLocation];
_glfwInputCursorPos(window, pos.x, contentRect.size.height – pos.y);

NSPasteboard* pasteboard = [sender draggingPasteboard];
NSDictionary* options =
NSArray* urls = [pasteboard class]]
options:options];
const NSUInteger count = [urls count];
if (count)
char** paths = _glfw_calloc(count, sizeof(char*));

for (NSUInteger i = 0; i < count; i++) paths[i] = _glfw_strdup([urls[i] fileSystemRepresentation]); _glfwInputDrop(window, (int) count, (const char**) paths); for (NSUInteger i = 0; i < count; i++) _glfw_free(paths[i]); _glfw_free(paths); return YES; - (BOOL)hasMarkedText return [markedText length] > 0;

– (NSRange)markedRange
if ([markedText length] > 0)
return NSMakeRange(0, [markedText length] – 1);
return kEmptyRange;

– (NSRange)selectedRange
return kEmptyRange;

– (void)setMarkedText:(id)string
selectedRange:(NSRange)selectedRange
replacementRange:(NSRange)replacementRange
[markedText release];
if ([string isKindOfClass:[NSAttributedString class]])
markedText = [[NSMutableAttributedString alloc] initWithAttributedString:string];
markedText = [[NSMutableAttributedString alloc] initWithString:string];

– (void)unmarkText
[[markedText mutableString]

– (NSArray*)validAttributesForMarkedText
return [NSArray array];

– (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range
actualRange:(NSRangePointer)actualRange
return nil;

– (NSUInteger)characterIndexForPoint:(NSPoint)point

– (NSRect)firstRectForCharacterRange:(NSRange)range
actualRange:(NSRangePointer)actualRange
const NSRect frame = [window->ns.view frame];
return NSMakeRect(frame.origin.x, frame.origin.y, 0.0, 0.0);

– (void)insertText:(id)string replacementRange:(NSRange)replacementRange
NSString* characters;
NSEvent* event = [NSApp currentEvent];
const int mods = translateFlags([event modifierFlags]);
const int plain = !(mods & GLFW_MOD_SUPER);

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com