forked from AuroraMiddleware/gtk
Merge branch 'wip/chergert/quartz4u' into 'master'
Merge GDK macOS branch See merge request GNOME/gtk!2272
This commit is contained in:
commit
2e07fcd680
@ -12,6 +12,7 @@ G_BEGIN_DECLS
|
||||
|
||||
#mesondefine GDK_WINDOWING_X11
|
||||
#mesondefine GDK_WINDOWING_BROADWAY
|
||||
#mesondefine GDK_WINDOWING_MACOS
|
||||
#mesondefine GDK_WINDOWING_WAYLAND
|
||||
#mesondefine GDK_WINDOWING_WIN32
|
||||
|
||||
|
@ -875,7 +875,7 @@ init (void)
|
||||
|
||||
g_slist_free (formats);
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
#if defined(G_OS_UNIX) && !defined(__APPLE__)
|
||||
file_transfer_portal_register ();
|
||||
#endif
|
||||
|
||||
|
@ -907,7 +907,7 @@ init (void)
|
||||
|
||||
g_slist_free (formats);
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
#if defined(G_OS_UNIX) && !defined(__APPLE__)
|
||||
file_transfer_portal_register ();
|
||||
#endif
|
||||
|
||||
|
@ -50,6 +50,10 @@
|
||||
#include "broadway/gdkprivate-broadway.h"
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_MACOS
|
||||
#include "macos/gdkmacosdisplay-private.h"
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_WIN32
|
||||
#include "win32/gdkwin32.h"
|
||||
#include "win32/gdkprivate-win32.h"
|
||||
@ -262,6 +266,9 @@ static GdkBackend gdk_backends[] = {
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
{ "quartz", _gdk_quartz_display_open },
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_MACOS
|
||||
{ "macos", _gdk_macos_display_open },
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_WIN32
|
||||
{ "win32", _gdk_win32_display_open },
|
||||
#endif
|
||||
|
718
gdk/macos/GdkMacosBaseView.c
Normal file
718
gdk/macos/GdkMacosBaseView.c
Normal file
@ -0,0 +1,718 @@
|
||||
/* GdkMacosBaseView.c
|
||||
*
|
||||
* Copyright 2005-2007 Imendio AB
|
||||
* Copyright 2011 Hiroyuki Yamamoto
|
||||
* Copyright 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#import "GdkMacosBaseView.h"
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
/* Text Input Client */
|
||||
#define TIC_MARKED_TEXT "tic-marked-text"
|
||||
#define TIC_SELECTED_POS "tic-selected-pos"
|
||||
#define TIC_SELECTED_LEN "tic-selected-len"
|
||||
#define TIC_INSERT_TEXT "tic-insert-text"
|
||||
#define TIC_IN_KEY_DOWN "tic-in-key-down"
|
||||
|
||||
/* GtkIMContext */
|
||||
#define GIC_CURSOR_RECT "gic-cursor-rect"
|
||||
#define GIC_FILTER_KEY "gic-filter-key"
|
||||
#define GIC_FILTER_PASSTHRU 0
|
||||
#define GIC_FILTER_FILTERED 1
|
||||
|
||||
@implementation GdkMacosBaseView
|
||||
|
||||
-(id)initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
if ((self = [super initWithFrame: frameRect]))
|
||||
{
|
||||
NSRect rect = NSMakeRect (0, 0, 0, 0);
|
||||
NSTrackingAreaOptions options;
|
||||
|
||||
markedRange = NSMakeRange (NSNotFound, 0);
|
||||
selectedRange = NSMakeRange (0, 0);
|
||||
[self setValue: @(YES) forKey: @"postsFrameChangedNotifications"];
|
||||
|
||||
options = (NSTrackingMouseEnteredAndExited |
|
||||
NSTrackingMouseMoved |
|
||||
NSTrackingInVisibleRect |
|
||||
NSTrackingActiveAlways);
|
||||
trackingArea = [[NSTrackingArea alloc] initWithRect:rect
|
||||
options:options
|
||||
owner:(id)self
|
||||
userInfo:nil];
|
||||
[self addTrackingArea:trackingArea];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)setNeedsDisplay:(BOOL)needsDisplay
|
||||
{
|
||||
for (id child in [self subviews])
|
||||
[child setNeedsDisplay:needsDisplay];
|
||||
}
|
||||
|
||||
-(void)setOpaqueRegion:(cairo_region_t *)region
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
-(BOOL)acceptsFirstMouse
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)mouseDownCanMoveWindow
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(BOOL)acceptsFirstResponder
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("acceptsFirstResponder"));
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)becomeFirstResponder
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("becomeFirstResponder"));
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)resignFirstResponder
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("resignFirstResponder"));
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)setNeedsInvalidateShadow: (BOOL)invalidate
|
||||
{
|
||||
needsInvalidateShadow = invalidate;
|
||||
}
|
||||
|
||||
-(NSTrackingArea *)trackingArea
|
||||
{
|
||||
return trackingArea;
|
||||
}
|
||||
|
||||
-(GdkMacosSurface *)gdkSurface
|
||||
{
|
||||
return [(GdkMacosWindow *)[self window] gdkSurface];
|
||||
}
|
||||
|
||||
-(GdkMacosDisplay *)gdkDisplay
|
||||
{
|
||||
GdkMacosSurface *surface = [self gdkSurface];
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (surface));
|
||||
|
||||
return GDK_MACOS_DISPLAY (display);
|
||||
}
|
||||
|
||||
-(void)keyDown:(NSEvent *)theEvent
|
||||
{
|
||||
/* NOTE: When user press Cmd+A, interpretKeyEvents: will call noop:
|
||||
* method. When user press and hold A to show the accented char window,
|
||||
* it consumed repeating key down events for key 'A' do NOT call
|
||||
* any other method. We use this behavior to determine if this key
|
||||
* down event is filtered by interpretKeyEvents.
|
||||
*/
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_FILTERED));
|
||||
|
||||
GDK_NOTE (EVENTS, g_message ("keyDown"));
|
||||
[self interpretKeyEvents: [NSArray arrayWithObject: theEvent]];
|
||||
}
|
||||
|
||||
-(void)flagsChanged: (NSEvent *)theEvent
|
||||
{
|
||||
}
|
||||
|
||||
-(NSUInteger)characterIndexForPoint:(NSPoint)aPoint
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("characterIndexForPoint"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
-(NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange: (NSRangePointer)actualRange
|
||||
{
|
||||
GdkRectangle *rect;
|
||||
|
||||
GDK_NOTE (EVENTS, g_message ("firstRectForCharacterRange"));
|
||||
|
||||
if ((rect = g_object_get_data (G_OBJECT ([self gdkSurface]), GIC_CURSOR_RECT)))
|
||||
{
|
||||
GdkMacosDisplay *display = [self gdkDisplay];
|
||||
int ns_x, ns_y;
|
||||
|
||||
_gdk_macos_display_to_display_coords (display,
|
||||
rect->x, rect->y + rect->height,
|
||||
&ns_x, &ns_y);
|
||||
|
||||
return NSMakeRect (ns_x, ns_y, rect->width, rect->height);
|
||||
}
|
||||
|
||||
return NSMakeRect (0, 0, 0, 0);
|
||||
}
|
||||
|
||||
-(NSArray *)validAttributesForMarkedText
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("validAttributesForMarkedText"));
|
||||
return [NSArray arrayWithObjects: NSUnderlineStyleAttributeName, nil];
|
||||
}
|
||||
|
||||
-(NSAttributedString *)attributedSubstringForProposedRange: (NSRange)aRange actualRange: (NSRangePointer)actualRange
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("attributedSubstringForProposedRange"));
|
||||
return nil;
|
||||
}
|
||||
|
||||
-(BOOL)hasMarkedText
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("hasMarkedText"));
|
||||
return markedRange.location != NSNotFound && markedRange.length != 0;
|
||||
}
|
||||
|
||||
-(NSRange)markedRange
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("markedRange"));
|
||||
return markedRange;
|
||||
}
|
||||
|
||||
-(NSRange)selectedRange
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("selectedRange"));
|
||||
return selectedRange;
|
||||
}
|
||||
|
||||
-(void)unmarkText
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("unmarkText"));
|
||||
|
||||
selectedRange = NSMakeRange (0, 0);
|
||||
markedRange = NSMakeRange (NSNotFound, 0);
|
||||
|
||||
g_object_set_data_full (G_OBJECT ([self gdkSurface]), TIC_MARKED_TEXT, NULL, g_free);
|
||||
}
|
||||
|
||||
-(void)setMarkedText:(id)aString selectedRange: (NSRange)newSelection replacementRange: (NSRange)replacementRange
|
||||
{
|
||||
const char *str;
|
||||
|
||||
GDK_NOTE (EVENTS, g_message ("setMarkedText"));
|
||||
|
||||
if (replacementRange.location == NSNotFound)
|
||||
{
|
||||
markedRange = NSMakeRange (newSelection.location, [aString length]);
|
||||
selectedRange = NSMakeRange (newSelection.location, newSelection.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
markedRange = NSMakeRange (replacementRange.location, [aString length]);
|
||||
selectedRange = NSMakeRange (replacementRange.location + newSelection.location, newSelection.length);
|
||||
}
|
||||
|
||||
if ([aString isKindOfClass: [NSAttributedString class]])
|
||||
str = [[aString string] UTF8String];
|
||||
else
|
||||
str = [aString UTF8String];
|
||||
|
||||
g_object_set_data_full (G_OBJECT ([self gdkSurface]), TIC_MARKED_TEXT, g_strdup (str), g_free);
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
TIC_SELECTED_POS,
|
||||
GUINT_TO_POINTER (selectedRange.location));
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
TIC_SELECTED_LEN,
|
||||
GUINT_TO_POINTER (selectedRange.length));
|
||||
|
||||
GDK_NOTE (EVENTS, g_message ("setMarkedText: set %s (%p, nsview %p): %s",
|
||||
TIC_MARKED_TEXT, [self gdkSurface], self,
|
||||
str ? str : "(empty)"));
|
||||
|
||||
/* handle text input changes by mouse events */
|
||||
if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT ([self gdkSurface]), TIC_IN_KEY_DOWN)))
|
||||
_gdk_macos_surface_synthesize_null_key ([self gdkSurface]);
|
||||
}
|
||||
|
||||
-(void)doCommandBySelector:(SEL)aSelector
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("doCommandBySelector"));
|
||||
|
||||
if ([self respondsToSelector: aSelector])
|
||||
[self performSelector: aSelector];
|
||||
}
|
||||
|
||||
-(void)insertText:(id)aString replacementRange: (NSRange)replacementRange
|
||||
{
|
||||
const char *str;
|
||||
NSString *string;
|
||||
|
||||
GDK_NOTE (EVENTS, g_message ("insertText"));
|
||||
|
||||
if ([self hasMarkedText])
|
||||
[self unmarkText];
|
||||
|
||||
if ([aString isKindOfClass: [NSAttributedString class]])
|
||||
string = [aString string];
|
||||
else
|
||||
string = aString;
|
||||
|
||||
NSCharacterSet *ctrlChars = [NSCharacterSet controlCharacterSet];
|
||||
NSCharacterSet *wsnlChars = [NSCharacterSet whitespaceAndNewlineCharacterSet];
|
||||
if ([string rangeOfCharacterFromSet:ctrlChars].length &&
|
||||
[string rangeOfCharacterFromSet:wsnlChars].length == 0)
|
||||
{
|
||||
/* discard invalid text input with Chinese input methods */
|
||||
str = "";
|
||||
[self unmarkText];
|
||||
[[NSTextInputContext currentInputContext] discardMarkedText];
|
||||
}
|
||||
else
|
||||
{
|
||||
str = [string UTF8String];
|
||||
}
|
||||
|
||||
g_object_set_data_full (G_OBJECT ([self gdkSurface]), TIC_INSERT_TEXT, g_strdup (str), g_free);
|
||||
GDK_NOTE (EVENTS, g_message ("insertText: set %s (%p, nsview %p): %s",
|
||||
TIC_INSERT_TEXT, [self gdkSurface], self,
|
||||
str ? str : "(empty)"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_FILTERED));
|
||||
|
||||
/* handle text input changes by mouse events */
|
||||
if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT ([self gdkSurface]), TIC_IN_KEY_DOWN)))
|
||||
_gdk_macos_surface_synthesize_null_key ([self gdkSurface]);
|
||||
}
|
||||
|
||||
-(void)deleteBackward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteBackward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteForward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteForward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteToBeginningOfLine:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteToBeginningOfLine"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteToEndOfLine:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteToEndOfLine"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteWordBackward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteWordBackward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteWordForward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteWordForward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)insertBacktab:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("insertBacktab"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)insertNewline:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("insertNewline"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)insertTab:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("insertTab"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveBackward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveBackward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveBackwardAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveBackwardAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveDown:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveDown"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveDownAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveDownAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveForward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveForward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveForwardAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveForwardAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveLeft:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveLeft"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveLeftAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveLeftAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveRight:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveRight"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveRightAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveRightAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToBeginningOfDocument:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToBeginningOfDocument"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToBeginningOfDocumentAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToBeginningOfDocumentAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToBeginningOfLine:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToBeginningOfLine"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToBeginningOfLineAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToBeginningOfLineAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToEndOfDocument:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToEndOfDocument"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToEndOfDocumentAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToEndOfDocumentAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToEndOfLine:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToEndOfLine"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToEndOfLineAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToEndOfLineAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveUp:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveUp"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveUpAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveUpAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordBackward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordBackward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordBackwardAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordBackwardAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordForward:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordForward"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordForwardAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordForwardAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordLeft:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordLeft"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordLeftAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordLeftAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordRight:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordRight"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordRightAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordRightAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)pageDown:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("pageDown"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)pageDownAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("pageDownAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)pageUp:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("pageUp"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)pageUpAndModifySelection:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("pageUpAndModifySelection"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)selectAll:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("selectAll"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)selectLine:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("selectLine"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)selectWord:(id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("selectWord"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)noop: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("noop"));
|
||||
|
||||
g_object_set_data (G_OBJECT ([self gdkSurface]),
|
||||
GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
@end
|
@ -1,6 +1,7 @@
|
||||
/* GdkQuartzView.h
|
||||
/* GdkMacosBaseView.h
|
||||
*
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -14,36 +15,32 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#include "gdk/gdk.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/* Text Input Client */
|
||||
#define TIC_MARKED_TEXT "tic-marked-text"
|
||||
#define TIC_SELECTED_POS "tic-selected-pos"
|
||||
#define TIC_SELECTED_LEN "tic-selected-len"
|
||||
#define TIC_INSERT_TEXT "tic-insert-text"
|
||||
#define TIC_IN_KEY_DOWN "tic-in-key-down"
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
/* GtkIMContext */
|
||||
#define GIC_CURSOR_RECT "gic-cursor-rect"
|
||||
#define GIC_FILTER_KEY "gic-filter-key"
|
||||
#define GIC_FILTER_PASSTHRU 0
|
||||
#define GIC_FILTER_FILTERED 1
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacossurface.h"
|
||||
|
||||
@interface GdkQuartzView : NSView <NSTextInputClient>
|
||||
#define GDK_IS_MACOS_BASE_VIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosBaseView class]])
|
||||
|
||||
@interface GdkMacosBaseView : NSView <NSTextInputClient>
|
||||
{
|
||||
GdkSurface *gdk_surface;
|
||||
NSTrackingRectTag trackingRect;
|
||||
NSTrackingArea *trackingArea;
|
||||
BOOL needsInvalidateShadow;
|
||||
NSRange markedRange;
|
||||
NSRange selectedRange;
|
||||
}
|
||||
|
||||
- (void)setGdkSurface: (GdkSurface *)window;
|
||||
- (GdkSurface *)gdkSurface;
|
||||
- (NSTrackingRectTag)trackingRect;
|
||||
- (void)setNeedsInvalidateShadow: (BOOL)invalidate;
|
||||
-(GdkMacosSurface *)gdkSurface;
|
||||
-(GdkMacosDisplay *)gdkDisplay;
|
||||
-(void)setNeedsInvalidateShadow: (BOOL)invalidate;
|
||||
-(NSTrackingArea *)trackingArea;
|
||||
-(void)setOpaqueRegion:(cairo_region_t *)region;
|
||||
|
||||
@end
|
171
gdk/macos/GdkMacosCairoSubview.c
Normal file
171
gdk/macos/GdkMacosCairoSubview.c
Normal file
@ -0,0 +1,171 @@
|
||||
/* GdkMacosCairoSubview.c
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <cairo-quartz.h>
|
||||
|
||||
#include "gdkinternals.h"
|
||||
|
||||
#import "GdkMacosCairoSubview.h"
|
||||
#import "GdkMacosCairoView.h"
|
||||
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
@implementation GdkMacosCairoSubview
|
||||
|
||||
-(BOOL)isOpaque
|
||||
{
|
||||
return _isOpaque;
|
||||
}
|
||||
|
||||
-(BOOL)isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(GdkSurface *)gdkSurface
|
||||
{
|
||||
return GDK_SURFACE ([(GdkMacosBaseView *)[self superview] gdkSurface]);
|
||||
}
|
||||
|
||||
-(void)drawRect:(NSRect)rect
|
||||
{
|
||||
CGContextRef cgContext;
|
||||
GdkSurface *gdk_surface;
|
||||
cairo_surface_t *dest;
|
||||
const NSRect *rects = NULL;
|
||||
NSView *root_view;
|
||||
NSInteger n_rects = 0;
|
||||
NSRect abs_bounds;
|
||||
cairo_t *cr;
|
||||
CGSize scale;
|
||||
int scale_factor;
|
||||
|
||||
if (self->cairoSurface == NULL)
|
||||
return;
|
||||
|
||||
/* Acquire everything we need to do translations, drawing, etc */
|
||||
gdk_surface = [self gdkSurface];
|
||||
scale_factor = gdk_surface_get_scale_factor (gdk_surface);
|
||||
root_view = [[self window] contentView];
|
||||
cgContext = [[NSGraphicsContext currentContext] CGContext];
|
||||
abs_bounds = [self convertRect:[self bounds] toView:root_view];
|
||||
|
||||
CGContextSaveGState (cgContext);
|
||||
|
||||
/* Translate scaling to remove HiDPI scaling from CGContext as
|
||||
* cairo will be doing that for us already.
|
||||
*/
|
||||
scale = CGSizeMake (1.0, 1.0);
|
||||
scale = CGContextConvertSizeToDeviceSpace (cgContext, scale);
|
||||
CGContextScaleCTM (cgContext, 1.0 / scale.width, 1.0 / scale.height);
|
||||
|
||||
/* Create the cairo surface to draw to the CGContext and translate
|
||||
* coordinates so we can pretend we are in the same coordinate system
|
||||
* as the GDK surface.
|
||||
*/
|
||||
dest = cairo_quartz_surface_create_for_cg_context (cgContext,
|
||||
gdk_surface->width * scale_factor,
|
||||
gdk_surface->height * scale_factor);
|
||||
cairo_surface_set_device_scale (dest, scale_factor, scale_factor);
|
||||
|
||||
/* Create cairo context and translate things into the origin of
|
||||
* the topmost contentView so that we just draw at 0,0 with a
|
||||
* clip region to paint the surface.
|
||||
*/
|
||||
cr = cairo_create (dest);
|
||||
cairo_translate (cr, -abs_bounds.origin.x, -abs_bounds.origin.y);
|
||||
|
||||
/* Clip the cairo context based on the rectangles to be drawn
|
||||
* within the bounding box :rect.
|
||||
*/
|
||||
[self getRectsBeingDrawn:&rects count:&n_rects];
|
||||
for (NSInteger i = 0; i < n_rects; i++)
|
||||
{
|
||||
NSRect area = [self convertRect:rects[i] toView:root_view];
|
||||
cairo_rectangle (cr,
|
||||
area.origin.x, area.origin.y,
|
||||
area.size.width, area.size.height);
|
||||
}
|
||||
cairo_clip (cr);
|
||||
|
||||
/* Now paint the surface (without blending) as we do not need
|
||||
* any compositing here. The transparent regions (like shadows)
|
||||
* are already on non-opaque layers.
|
||||
*/
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_surface (cr, self->cairoSurface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
|
||||
/* Cleanup state, flush the surface to the backing layer, and
|
||||
* restore GState for future use.
|
||||
*/
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_flush (dest);
|
||||
cairo_surface_destroy (dest);
|
||||
CGContextRestoreGState (cgContext);
|
||||
}
|
||||
|
||||
-(void)setCairoSurface:(cairo_surface_t *)surface
|
||||
withDamage:(cairo_region_t *)region
|
||||
{
|
||||
if (surface != self->cairoSurface)
|
||||
{
|
||||
g_clear_pointer (&self->cairoSurface, cairo_surface_destroy);
|
||||
if (surface != NULL)
|
||||
self->cairoSurface = cairo_surface_reference (surface);
|
||||
}
|
||||
|
||||
if (region != NULL)
|
||||
{
|
||||
NSView *root_view = [[self window] contentView];
|
||||
NSRect abs_bounds = [self convertRect:[self bounds] toView:root_view];
|
||||
guint n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
NSRect nsrect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
nsrect = NSMakeRect (rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
if (NSIntersectsRect (abs_bounds, nsrect))
|
||||
{
|
||||
nsrect.origin.x -= abs_bounds.origin.x;
|
||||
nsrect.origin.y -= abs_bounds.origin.y;
|
||||
[self setNeedsDisplayInRect:nsrect];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (id view in [self subviews])
|
||||
[(GdkMacosCairoSubview *)view setCairoSurface:surface
|
||||
withDamage:region];
|
||||
}
|
||||
|
||||
-(void)setOpaque:(BOOL)opaque
|
||||
{
|
||||
self->_isOpaque = opaque;
|
||||
}
|
||||
|
||||
@end
|
35
gdk/macos/GdkMacosCairoSubview.h
Normal file
35
gdk/macos/GdkMacosCairoSubview.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* GdkMacosCairoSubview.h
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#define GDK_IS_MACOS_CAIRO_SUBVIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosCairoSubview class]])
|
||||
|
||||
@interface GdkMacosCairoSubview : NSView
|
||||
{
|
||||
BOOL _isOpaque;
|
||||
cairo_surface_t *cairoSurface;
|
||||
}
|
||||
|
||||
-(void)setOpaque:(BOOL)opaque;
|
||||
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
|
||||
withDamage:(cairo_region_t *)region;
|
||||
|
||||
@end
|
170
gdk/macos/GdkMacosCairoView.c
Normal file
170
gdk/macos/GdkMacosCairoView.c
Normal file
@ -0,0 +1,170 @@
|
||||
/* GdkMacosCairoView.c
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <cairo-quartz.h>
|
||||
|
||||
#include "gdkinternals.h"
|
||||
|
||||
#import "GdkMacosCairoView.h"
|
||||
#import "GdkMacosCairoSubview.h"
|
||||
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
@implementation GdkMacosCairoView
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_clear_pointer (&self->opaque, g_ptr_array_unref);
|
||||
self->transparent = NULL;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(BOOL)isOpaque
|
||||
{
|
||||
if ([self window])
|
||||
return [[self window] isOpaque];
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
|
||||
withDamage:(cairo_region_t *)cairoRegion
|
||||
{
|
||||
for (id view in [self subviews])
|
||||
[(GdkMacosCairoSubview *)view setCairoSurface:cairoSurface
|
||||
withDamage:cairoRegion];
|
||||
}
|
||||
|
||||
-(void)removeOpaqueChildren
|
||||
{
|
||||
[[self->transparent subviews]
|
||||
makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
|
||||
if (self->opaque->len)
|
||||
g_ptr_array_remove_range (self->opaque, 0, self->opaque->len);
|
||||
}
|
||||
|
||||
-(void)setOpaqueRegion:(cairo_region_t *)region
|
||||
{
|
||||
NSRect abs_bounds;
|
||||
guint n_rects;
|
||||
|
||||
if (region == NULL)
|
||||
return;
|
||||
|
||||
abs_bounds = [self convertRect:[self bounds] toView:nil];
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
/* The common case (at least for opaque windows and CSD) is that we will
|
||||
* have either one or two opaque rectangles. If we detect that the same
|
||||
* number of them are available as the previous, we can just resize the
|
||||
* previous ones to avoid adding/removing views at a fast rate while
|
||||
* resizing.
|
||||
*/
|
||||
if (n_rects == self->opaque->len)
|
||||
{
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
GdkMacosCairoSubview *child;
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
child = g_ptr_array_index (self->opaque, i);
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
|
||||
[child setFrame:NSMakeRect (rect.x - abs_bounds.origin.x,
|
||||
rect.y - abs_bounds.origin.y,
|
||||
rect.width,
|
||||
rect.height)];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
[self removeOpaqueChildren];
|
||||
for (guint i = 0; i < n_rects; i++)
|
||||
{
|
||||
GdkMacosCairoSubview *child;
|
||||
cairo_rectangle_int_t rect;
|
||||
NSRect nsrect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
nsrect = NSMakeRect (rect.x - abs_bounds.origin.x,
|
||||
rect.y - abs_bounds.origin.y,
|
||||
rect.width,
|
||||
rect.height);
|
||||
|
||||
child = [[GdkMacosCairoSubview alloc] initWithFrame:nsrect];
|
||||
[child setOpaque:YES];
|
||||
[child setWantsLayer:YES];
|
||||
[self->transparent addSubview:child];
|
||||
g_ptr_array_add (self->opaque, child);
|
||||
}
|
||||
}
|
||||
|
||||
-(NSView *)initWithFrame:(NSRect)frame
|
||||
{
|
||||
if ((self = [super initWithFrame:frame]))
|
||||
{
|
||||
/* An array to track all the opaque children placed into
|
||||
* the child self->transparent. This allows us to reuse them
|
||||
* when we receive a new opaque area instead of discarding
|
||||
* them on each draw.
|
||||
*/
|
||||
self->opaque = g_ptr_array_new ();
|
||||
|
||||
/* Setup our primary subview which will render all content that is not
|
||||
* within an opaque region (such as shadows for CSD windows). For opaque
|
||||
* windows, this will all be obscurred by other views, so it doesn't
|
||||
* matter much to have it here.
|
||||
*/
|
||||
self->transparent = [[GdkMacosCairoSubview alloc] initWithFrame:frame];
|
||||
[self addSubview:self->transparent];
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)setFrame:(NSRect)rect
|
||||
{
|
||||
[super setFrame:rect];
|
||||
[self->transparent setFrame:NSMakeRect (0, 0, rect.size.width, rect.size.height)];
|
||||
}
|
||||
|
||||
-(BOOL)acceptsFirstMouse
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)mouseDownCanMoveWindow
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
@ -1,7 +1,7 @@
|
||||
/* gdkdevicemanager-quartz.h
|
||||
/* GdkMacosCairoView.h
|
||||
*
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
* Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -15,28 +15,23 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_DEVICE_MANAGER_CORE__
|
||||
#define __GDK_QUARTZ_DEVICE_MANAGER_CORE__
|
||||
#include <cairo.h>
|
||||
|
||||
#include <gdkdevicemanagerprivate.h>
|
||||
#include "gdkquartzdevicemanager-core.h"
|
||||
#import "GdkMacosBaseView.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define GDK_IS_MACOS_CAIRO_VIEW(obj) ((obj) && [obj isKindOfClass:[GdkMacosCairoView class]])
|
||||
|
||||
struct _GdkQuartzDeviceManagerCore
|
||||
@interface GdkMacosCairoView : GdkMacosBaseView
|
||||
{
|
||||
GObject parent_object;
|
||||
GdkDevice *core_pointer;
|
||||
GdkDevice *core_keyboard;
|
||||
};
|
||||
NSView *transparent;
|
||||
GPtrArray *opaque;
|
||||
}
|
||||
|
||||
struct _GdkQuartzDeviceManagerCoreClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
-(void)setCairoSurface:(cairo_surface_t *)cairoSurface
|
||||
withDamage:(cairo_region_t *)region;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_DEVICE_MANAGER__ */
|
||||
@end
|
157
gdk/macos/GdkMacosGLLayer.c
Normal file
157
gdk/macos/GdkMacosGLLayer.c
Normal file
@ -0,0 +1,157 @@
|
||||
/* GdkMacosGLLayer.c
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/* Based on Chromium image_transport_surface_calayer_mac.mm
|
||||
* See the BSD-style license above.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <OpenGL/gl.h>
|
||||
|
||||
#import "GdkMacosGLLayer.h"
|
||||
|
||||
@implementation GdkMacosGLLayer
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
-(id)initWithContext:(NSOpenGLContext *)shared
|
||||
{
|
||||
[super init];
|
||||
_shared = [shared retain];
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
[_shared release];
|
||||
_shared = nil;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void)setContentsRect:(NSRect)bounds
|
||||
{
|
||||
_pixelSize = bounds.size;
|
||||
[super setContentsRect:bounds];
|
||||
}
|
||||
|
||||
-(CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask
|
||||
{
|
||||
return CGLRetainPixelFormat ([[_shared pixelFormat] CGLPixelFormatObj]);
|
||||
}
|
||||
|
||||
-(CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat
|
||||
{
|
||||
CGLContextObj context = NULL;
|
||||
CGLCreateContext (pixelFormat, [_shared CGLContextObj], &context);
|
||||
return context;
|
||||
}
|
||||
|
||||
-(BOOL)canDrawInCGLContext:(CGLContextObj)glContext
|
||||
pixelFormat:(CGLPixelFormatObj)pixelFormat
|
||||
forLayerTime:(CFTimeInterval)timeInterval
|
||||
displayTime:(const CVTimeStamp*)timeStamp
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)drawInCGLContext:(CGLContextObj)glContext
|
||||
pixelFormat:(CGLPixelFormatObj)pixelFormat
|
||||
forLayerTime:(CFTimeInterval)timeInterval
|
||||
displayTime:(const CVTimeStamp*)timeStamp
|
||||
{
|
||||
if (_texture == 0)
|
||||
return;
|
||||
|
||||
glClearColor (1, 0, 1, 1);
|
||||
glClear (GL_COLOR_BUFFER_BIT);
|
||||
GLint viewport[4] = {0, 0, 0, 0};
|
||||
glGetIntegerv (GL_VIEWPORT, viewport);
|
||||
NSSize viewportSize = NSMakeSize (viewport[2], viewport[3]);
|
||||
|
||||
/* Set the coordinate system to be one-to-one with pixels. */
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
glOrtho (0, viewportSize.width, 0, viewportSize.height, -1, 1);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glLoadIdentity ();
|
||||
|
||||
/* Draw a fullscreen quad. */
|
||||
glColor4f (1, 1, 1, 1);
|
||||
glEnable (GL_TEXTURE_RECTANGLE_ARB);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, _texture);
|
||||
glBegin (GL_QUADS);
|
||||
{
|
||||
glTexCoord2f (0, 0);
|
||||
glVertex2f (0, 0);
|
||||
glTexCoord2f (0, _pixelSize.height);
|
||||
glVertex2f (0, _pixelSize.height);
|
||||
glTexCoord2f (_pixelSize.width, _pixelSize.height);
|
||||
glVertex2f (_pixelSize.width, _pixelSize.height);
|
||||
glTexCoord2f (_pixelSize.width, 0);
|
||||
glVertex2f (_pixelSize.width, 0);
|
||||
}
|
||||
glEnd ();
|
||||
glBindTexture (0, _texture);
|
||||
glDisable (GL_TEXTURE_RECTANGLE_ARB);
|
||||
[super drawInCGLContext:glContext
|
||||
pixelFormat:pixelFormat
|
||||
forLayerTime:timeInterval
|
||||
displayTime:timeStamp];
|
||||
}
|
||||
|
||||
-(void)setTexture:(GLuint)texture
|
||||
{
|
||||
_texture = texture;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
@end
|
@ -1,6 +1,6 @@
|
||||
/* gdkscreen-quartz.h
|
||||
/* GdkMacosGLLayer.h
|
||||
*
|
||||
* Copyright (C) 2009,2010 Kristian Rietveld <kris@gtk.org>
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -14,36 +14,27 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_SCREEN__
|
||||
#define __GDK_QUARTZ_SCREEN__
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define GDK_IS_MACOS_GL_LAYER(obj) ((obj) && [obj isKindOfClass:[GdkMacosGLLayer class]])
|
||||
|
||||
struct _GdkQuartzScreen
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
@interface GdkMacosGLLayer : CAOpenGLLayer
|
||||
{
|
||||
GObject parent_instance;
|
||||
NSOpenGLContext *_shared;
|
||||
GLuint _texture;
|
||||
NSSize _pixelSize;
|
||||
}
|
||||
|
||||
GdkDisplay *display;
|
||||
-(id)initWithContext:(NSOpenGLContext *)shared;
|
||||
-(void)setTexture:(GLuint)texture;
|
||||
|
||||
/* Origin of "root window" in Cocoa coordinates */
|
||||
gint min_x;
|
||||
gint min_y;
|
||||
@end
|
||||
|
||||
gint width;
|
||||
gint height;
|
||||
|
||||
guint screen_changed_id;
|
||||
|
||||
guint emit_monitors_changed : 1;
|
||||
};
|
||||
|
||||
struct _GdkQuartzScreenClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_SCREEN__ */
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
732
gdk/macos/GdkMacosWindow.c
Normal file
732
gdk/macos/GdkMacosWindow.c
Normal file
@ -0,0 +1,732 @@
|
||||
/* GdkMacosWindow.m
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#import "GdkMacosBaseView.h"
|
||||
#import "GdkMacosCairoView.h"
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
#include "gdkmacospopupsurface-private.h"
|
||||
#include "gdkmacostoplevelsurface-private.h"
|
||||
|
||||
#include "gdkmonitorprivate.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
|
||||
@implementation GdkMacosWindow
|
||||
|
||||
-(BOOL)windowShouldClose:(id)sender
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkEvent *event;
|
||||
GList *node;
|
||||
|
||||
display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
|
||||
event = gdk_delete_event_new (GDK_SURFACE (gdk_surface));
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event,
|
||||
_gdk_display_get_next_serial (display));
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)windowWillMiniaturize:(NSNotification *)aNotification
|
||||
{
|
||||
if (GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface))
|
||||
_gdk_macos_toplevel_surface_detach_from_parent (GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface));
|
||||
else if (GDK_IS_MACOS_POPUP_SURFACE (gdk_surface))
|
||||
_gdk_macos_popup_surface_detach_from_parent (GDK_MACOS_POPUP_SURFACE (gdk_surface));
|
||||
}
|
||||
|
||||
-(void)windowDidMiniaturize:(NSNotification *)aNotification
|
||||
{
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), 0, GDK_SURFACE_STATE_MINIMIZED);
|
||||
}
|
||||
|
||||
-(void)windowDidDeminiaturize:(NSNotification *)aNotification
|
||||
{
|
||||
if (GDK_IS_MACOS_TOPLEVEL_SURFACE (gdk_surface))
|
||||
_gdk_macos_toplevel_surface_attach_to_parent (GDK_MACOS_TOPLEVEL_SURFACE (gdk_surface));
|
||||
else if (GDK_IS_MACOS_POPUP_SURFACE (gdk_surface))
|
||||
_gdk_macos_popup_surface_attach_to_parent (GDK_MACOS_POPUP_SURFACE (gdk_surface));
|
||||
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), GDK_SURFACE_STATE_MINIMIZED, 0);
|
||||
}
|
||||
|
||||
-(void)windowDidBecomeKey:(NSNotification *)aNotification
|
||||
{
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), 0, GDK_SURFACE_STATE_FOCUSED);
|
||||
_gdk_macos_display_surface_became_key ([self gdkDisplay], gdk_surface);
|
||||
}
|
||||
|
||||
-(void)windowDidResignKey:(NSNotification *)aNotification
|
||||
{
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), GDK_SURFACE_STATE_FOCUSED, 0);
|
||||
_gdk_macos_display_surface_resigned_key ([self gdkDisplay], gdk_surface);
|
||||
}
|
||||
|
||||
-(void)windowDidBecomeMain:(NSNotification *)aNotification
|
||||
{
|
||||
if (![self isVisible])
|
||||
{
|
||||
/* Note: This is a hack needed because for unknown reasons, hidden
|
||||
* windows get shown when clicking the dock icon when the application
|
||||
* is not already active.
|
||||
*/
|
||||
[self orderOut:nil];
|
||||
return;
|
||||
}
|
||||
|
||||
_gdk_macos_display_surface_became_main ([self gdkDisplay], gdk_surface);
|
||||
}
|
||||
|
||||
-(void)windowDidResignMain:(NSNotification *)aNotification
|
||||
{
|
||||
_gdk_macos_display_surface_resigned_main ([self gdkDisplay], gdk_surface);
|
||||
}
|
||||
|
||||
/* Used in combination with NSLeftMouseUp in sendEvent to keep track
|
||||
* of when the window is being moved with the mouse.
|
||||
*/
|
||||
-(void)windowWillMove:(NSNotification *)aNotification
|
||||
{
|
||||
inMove = YES;
|
||||
}
|
||||
|
||||
-(void)sendEvent:(NSEvent *)event
|
||||
{
|
||||
NSEventType event_type = [event type];
|
||||
|
||||
switch ((int)event_type)
|
||||
{
|
||||
case NSEventTypeLeftMouseUp: {
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
|
||||
double time = ((double)[event timestamp]) * 1000.0;
|
||||
|
||||
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), time);
|
||||
|
||||
inManualMove = NO;
|
||||
inManualResize = NO;
|
||||
inMove = NO;
|
||||
|
||||
/* We need to deliver the event to the proper drag gestures or we
|
||||
* will leave the window in inconsistent state that requires clicking
|
||||
* in the window to cancel the gesture.
|
||||
*
|
||||
* TODO: Can we improve grab breaking to fix this?
|
||||
*/
|
||||
_gdk_macos_display_send_button_event ([self gdkDisplay], event);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NSEventTypeLeftMouseDragged:
|
||||
if ([self trackManualMove] || [self trackManualResize])
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
[super sendEvent:event];
|
||||
}
|
||||
|
||||
-(BOOL)isInMove
|
||||
{
|
||||
return inMove;
|
||||
}
|
||||
|
||||
-(void)checkSendEnterNotify
|
||||
{
|
||||
/* When a new window has been created, and the mouse is in the window
|
||||
* area, we will not receive an NSEventTypeMouseEntered event.
|
||||
* Therefore, we synthesize an enter notify event manually.
|
||||
*/
|
||||
if (!initialPositionKnown)
|
||||
{
|
||||
initialPositionKnown = YES;
|
||||
|
||||
if (NSPointInRect ([NSEvent mouseLocation], [self frame]))
|
||||
{
|
||||
GdkMacosBaseView *view = (GdkMacosBaseView *)[self contentView];
|
||||
NSEvent *event;
|
||||
|
||||
event = [NSEvent enterExitEventWithType: NSEventTypeMouseEntered
|
||||
location: [self mouseLocationOutsideOfEventStream]
|
||||
modifierFlags: 0
|
||||
timestamp: [[NSApp currentEvent] timestamp]
|
||||
windowNumber: [self windowNumber]
|
||||
context: NULL
|
||||
eventNumber: 0
|
||||
trackingNumber: (NSInteger)[view trackingArea]
|
||||
userData: nil];
|
||||
|
||||
[NSApp postEvent:event atStart:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)windowDidUnmaximize
|
||||
{
|
||||
NSWindowStyleMask style_mask = [self styleMask];
|
||||
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), GDK_SURFACE_STATE_MAXIMIZED, 0);
|
||||
|
||||
/* If we are using CSD, then we transitioned to an opaque
|
||||
* window while we were maximized. Now we need to drop that
|
||||
* as we are leaving maximized state.
|
||||
*/
|
||||
if ((style_mask & NSWindowStyleMaskTitled) == 0 && [self isOpaque])
|
||||
[self setOpaque:NO];
|
||||
}
|
||||
|
||||
-(void)windowDidMove:(NSNotification *)aNotification
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (gdk_surface);
|
||||
gboolean maximized = (surface->state & GDK_SURFACE_STATE_MAXIMIZED) != 0;
|
||||
|
||||
/* In case the window is changed when maximized remove the maximized state */
|
||||
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
|
||||
[self windowDidUnmaximize];
|
||||
|
||||
_gdk_macos_surface_update_position (gdk_surface);
|
||||
_gdk_macos_surface_reposition_children (gdk_surface);
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(void)windowDidResize:(NSNotification *)aNotification
|
||||
{
|
||||
NSRect content_rect;
|
||||
GdkSurface *surface;
|
||||
GdkDisplay *display;
|
||||
GdkEvent *event;
|
||||
gboolean maximized;
|
||||
GList *node;
|
||||
|
||||
surface = GDK_SURFACE (gdk_surface);
|
||||
display = gdk_surface_get_display (surface);
|
||||
|
||||
content_rect = [self contentRectForFrameRect:[self frame]];
|
||||
maximized = (surface->state & GDK_SURFACE_STATE_MAXIMIZED) != 0;
|
||||
|
||||
/* see same in windowDidMove */
|
||||
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
|
||||
[self windowDidUnmaximize];
|
||||
|
||||
surface->width = content_rect.size.width;
|
||||
surface->height = content_rect.size.height;
|
||||
|
||||
/* Certain resize operations (e.g. going fullscreen), also move the
|
||||
* origin of the window.
|
||||
*/
|
||||
_gdk_macos_surface_update_position (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
[[self contentView] setFrame:NSMakeRect (0, 0, surface->width, surface->height)];
|
||||
|
||||
_gdk_surface_update_size (surface);
|
||||
|
||||
/* Synthesize a configure event */
|
||||
event = gdk_configure_event_new (surface,
|
||||
content_rect.size.width,
|
||||
content_rect.size.height);
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event,
|
||||
_gdk_display_get_next_serial (display));
|
||||
|
||||
_gdk_macos_surface_reposition_children (gdk_surface);
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(id)initWithContentRect:(NSRect)contentRect
|
||||
styleMask:(NSWindowStyleMask)styleMask
|
||||
backing:(NSBackingStoreType)backingType
|
||||
defer:(BOOL)flag
|
||||
screen:(NSScreen *)screen
|
||||
{
|
||||
GdkMacosCairoView *view;
|
||||
|
||||
self = [super initWithContentRect:contentRect
|
||||
styleMask:styleMask
|
||||
backing:backingType
|
||||
defer:flag
|
||||
screen:screen];
|
||||
|
||||
[self setAcceptsMouseMovedEvents:YES];
|
||||
[self setDelegate:(id<NSWindowDelegate>)self];
|
||||
[self setReleasedWhenClosed:YES];
|
||||
|
||||
view = [[GdkMacosCairoView alloc] initWithFrame:contentRect];
|
||||
[self setContentView:view];
|
||||
[view release];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(BOOL)canBecomeMainWindow
|
||||
{
|
||||
return GDK_IS_TOPLEVEL (gdk_surface);
|
||||
}
|
||||
|
||||
-(BOOL)canBecomeKeyWindow
|
||||
{
|
||||
return GDK_IS_TOPLEVEL (gdk_surface);
|
||||
}
|
||||
|
||||
-(void)showAndMakeKey:(BOOL)makeKey
|
||||
{
|
||||
inShowOrHide = YES;
|
||||
|
||||
if (makeKey && [self canBecomeKeyWindow])
|
||||
[self makeKeyAndOrderFront:nil];
|
||||
else
|
||||
[self orderFront:nil];
|
||||
|
||||
inShowOrHide = NO;
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(void)hide
|
||||
{
|
||||
inShowOrHide = YES;
|
||||
[self orderOut:nil];
|
||||
inShowOrHide = NO;
|
||||
|
||||
initialPositionKnown = NO;
|
||||
}
|
||||
|
||||
-(BOOL)trackManualMove
|
||||
{
|
||||
NSRect windowFrame;
|
||||
NSPoint currentLocation;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle geometry;
|
||||
GdkRectangle workarea;
|
||||
int shadow_top = 0;
|
||||
int shadow_left = 0;
|
||||
int shadow_right = 0;
|
||||
int shadow_bottom = 0;
|
||||
GdkRectangle window_gdk;
|
||||
GdkPoint pointer_position;
|
||||
GdkPoint new_origin;
|
||||
|
||||
if (!inManualMove)
|
||||
return NO;
|
||||
|
||||
/* Get our shadow so we can adjust the window position sans-shadow */
|
||||
_gdk_macos_surface_get_shadow (gdk_surface,
|
||||
&shadow_top,
|
||||
&shadow_right,
|
||||
&shadow_bottom,
|
||||
&shadow_left);
|
||||
|
||||
windowFrame = [self frame];
|
||||
currentLocation = [NSEvent mouseLocation];
|
||||
|
||||
/* Update the snapping geometry to match the current monitor */
|
||||
monitor = _gdk_macos_display_get_monitor_at_display_coords ([self gdkDisplay],
|
||||
currentLocation.x,
|
||||
currentLocation.y);
|
||||
gdk_monitor_get_geometry (monitor, &geometry);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
_edge_snapping_set_monitor (&self->snapping, &geometry, &workarea);
|
||||
|
||||
/* Convert origins to GDK coordinates */
|
||||
_gdk_macos_display_from_display_coords ([self gdkDisplay],
|
||||
currentLocation.x,
|
||||
currentLocation.y,
|
||||
&pointer_position.x,
|
||||
&pointer_position.y);
|
||||
_gdk_macos_display_from_display_coords ([self gdkDisplay],
|
||||
windowFrame.origin.x,
|
||||
windowFrame.origin.y + windowFrame.size.height,
|
||||
&window_gdk.x,
|
||||
&window_gdk.y);
|
||||
window_gdk.width = windowFrame.size.width;
|
||||
window_gdk.height = windowFrame.size.height;
|
||||
|
||||
/* Subtract our shadowin from the window */
|
||||
window_gdk.x += shadow_left;
|
||||
window_gdk.y += shadow_top;
|
||||
window_gdk.width = window_gdk.width - shadow_left - shadow_right;
|
||||
window_gdk.height = window_gdk.height - shadow_top - shadow_bottom;
|
||||
|
||||
/* Now place things on the monitor */
|
||||
_edge_snapping_motion (&self->snapping, &pointer_position, &window_gdk);
|
||||
|
||||
/* And add our shadow back to the frame */
|
||||
window_gdk.x -= shadow_left;
|
||||
window_gdk.y -= shadow_top;
|
||||
window_gdk.width += shadow_left + shadow_right;
|
||||
window_gdk.height += shadow_top + shadow_bottom;
|
||||
|
||||
/* Convert to quartz coordiantes */
|
||||
_gdk_macos_display_to_display_coords ([self gdkDisplay],
|
||||
window_gdk.x,
|
||||
window_gdk.y + window_gdk.height,
|
||||
&new_origin.x, &new_origin.y);
|
||||
windowFrame.origin.x = new_origin.x;
|
||||
windowFrame.origin.y = new_origin.y;
|
||||
|
||||
/* And now apply the frame to the window */
|
||||
[self setFrameOrigin:NSMakePoint(new_origin.x, new_origin.y)];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
/* Used by gdkmacosdisplay-translate.c to decide if our sendEvent() handler
|
||||
* above will see the event or if it will be subjected to standard processing
|
||||
* by GDK.
|
||||
*/
|
||||
-(BOOL)isInManualResizeOrMove
|
||||
{
|
||||
return inManualResize || inManualMove;
|
||||
}
|
||||
|
||||
-(void)beginManualMove
|
||||
{
|
||||
NSPoint initialMoveLocation;
|
||||
GdkPoint point;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle geometry;
|
||||
GdkRectangle area;
|
||||
GdkRectangle workarea;
|
||||
|
||||
if (inMove || inManualMove || inManualResize)
|
||||
return;
|
||||
|
||||
inManualMove = YES;
|
||||
|
||||
monitor = _gdk_macos_surface_get_best_monitor ([self gdkSurface]);
|
||||
gdk_monitor_get_geometry (monitor, &geometry);
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
initialMoveLocation = [NSEvent mouseLocation];
|
||||
|
||||
_gdk_macos_display_from_display_coords ([self gdkDisplay],
|
||||
initialMoveLocation.x,
|
||||
initialMoveLocation.y,
|
||||
&point.x,
|
||||
&point.y);
|
||||
|
||||
area.x = gdk_surface->root_x;
|
||||
area.y = gdk_surface->root_y;
|
||||
area.width = GDK_SURFACE (gdk_surface)->width;
|
||||
area.height = GDK_SURFACE (gdk_surface)->height;
|
||||
|
||||
_edge_snapping_init (&self->snapping,
|
||||
&geometry,
|
||||
&workarea,
|
||||
&point,
|
||||
&area);
|
||||
}
|
||||
|
||||
-(BOOL)trackManualResize
|
||||
{
|
||||
NSPoint mouse_location;
|
||||
NSRect new_frame;
|
||||
float mdx, mdy, dw, dh, dx, dy;
|
||||
NSSize min_size;
|
||||
|
||||
if (!inManualResize || inTrackManualResize)
|
||||
return NO;
|
||||
|
||||
inTrackManualResize = YES;
|
||||
|
||||
mouse_location = [self convertPointToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
mdx = initialResizeLocation.x - mouse_location.x;
|
||||
mdy = initialResizeLocation.y - mouse_location.y;
|
||||
|
||||
/* Set how a mouse location delta translates to changes in width,
|
||||
* height and position.
|
||||
*/
|
||||
dw = dh = dx = dy = 0.0;
|
||||
if (resizeEdge == GDK_SURFACE_EDGE_EAST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_NORTH_EAST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_SOUTH_EAST)
|
||||
{
|
||||
dw = -1.0;
|
||||
}
|
||||
if (resizeEdge == GDK_SURFACE_EDGE_NORTH ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_NORTH_WEST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_NORTH_EAST)
|
||||
{
|
||||
dh = -1.0;
|
||||
}
|
||||
if (resizeEdge == GDK_SURFACE_EDGE_SOUTH ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_SOUTH_WEST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_SOUTH_EAST)
|
||||
{
|
||||
dh = 1.0;
|
||||
dy = -1.0;
|
||||
}
|
||||
if (resizeEdge == GDK_SURFACE_EDGE_WEST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_NORTH_WEST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_SOUTH_WEST)
|
||||
{
|
||||
dw = 1.0;
|
||||
dx = -1.0;
|
||||
}
|
||||
|
||||
/* Apply changes to the frame captured when we started resizing */
|
||||
new_frame = initialResizeFrame;
|
||||
new_frame.origin.x += mdx * dx;
|
||||
new_frame.origin.y += mdy * dy;
|
||||
new_frame.size.width += mdx * dw;
|
||||
new_frame.size.height += mdy * dh;
|
||||
|
||||
/* In case the resulting window would be too small reduce the
|
||||
* change to both size and position.
|
||||
*/
|
||||
min_size = [self contentMinSize];
|
||||
|
||||
if (new_frame.size.width < min_size.width)
|
||||
{
|
||||
if (dx)
|
||||
new_frame.origin.x -= min_size.width - new_frame.size.width;
|
||||
new_frame.size.width = min_size.width;
|
||||
}
|
||||
|
||||
if (new_frame.size.height < min_size.height)
|
||||
{
|
||||
if (dy)
|
||||
new_frame.origin.y -= min_size.height - new_frame.size.height;
|
||||
new_frame.size.height = min_size.height;
|
||||
}
|
||||
|
||||
/* We could also apply aspect ratio:
|
||||
new_frame.size.height = new_frame.size.width / [self aspectRatio].width * [self aspectRatio].height;
|
||||
*/
|
||||
|
||||
[self setFrame:new_frame display:YES];
|
||||
|
||||
/* Let the resizing be handled by GTK+. */
|
||||
if (g_main_context_pending (NULL))
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
|
||||
inTrackManualResize = NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)beginManualResize:(GdkSurfaceEdge)edge
|
||||
{
|
||||
if (inMove || inManualMove || inManualResize)
|
||||
return;
|
||||
|
||||
inManualResize = YES;
|
||||
resizeEdge = edge;
|
||||
|
||||
initialResizeFrame = [self frame];
|
||||
initialResizeLocation = [self convertPointToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
}
|
||||
|
||||
-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
-(void)draggingEnded:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
}
|
||||
|
||||
-(void)draggingExited:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
}
|
||||
|
||||
-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)wantsPeriodicDraggingUpdates
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
|
||||
{
|
||||
}
|
||||
|
||||
-(void)setStyleMask:(NSWindowStyleMask)styleMask
|
||||
{
|
||||
gboolean was_fullscreen;
|
||||
gboolean is_fullscreen;
|
||||
gboolean was_opaque;
|
||||
gboolean is_opaque;
|
||||
|
||||
was_fullscreen = (([self styleMask] & NSWindowStyleMaskFullScreen) != 0);
|
||||
was_opaque = (([self styleMask] & NSWindowStyleMaskTitled) != 0);
|
||||
|
||||
[super setStyleMask:styleMask];
|
||||
|
||||
is_fullscreen = (([self styleMask] & NSWindowStyleMaskFullScreen) != 0);
|
||||
is_opaque = (([self styleMask] & NSWindowStyleMaskTitled) != 0);
|
||||
|
||||
if (was_fullscreen != is_fullscreen)
|
||||
_gdk_macos_surface_update_fullscreen_state (gdk_surface);
|
||||
|
||||
if (was_opaque != is_opaque)
|
||||
{
|
||||
[self setOpaque:is_opaque];
|
||||
|
||||
if (!is_opaque)
|
||||
[self setBackgroundColor:[NSColor clearColor]];
|
||||
}
|
||||
}
|
||||
|
||||
-(NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
|
||||
{
|
||||
GdkMacosSurface *surface = gdk_surface;
|
||||
NSRect rect;
|
||||
gint shadow_top;
|
||||
|
||||
/* Allow the window to move up "shadow_top" more than normally allowed
|
||||
* by the default impl. This makes it possible to move windows with
|
||||
* client side shadow right up to the screen's menu bar. */
|
||||
_gdk_macos_surface_get_shadow (surface, &shadow_top, NULL, NULL, NULL);
|
||||
rect = [super constrainFrameRect:frameRect toScreen:screen];
|
||||
if (frameRect.origin.y > rect.origin.y)
|
||||
rect.origin.y = MIN (frameRect.origin.y, rect.origin.y + shadow_top);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
-(NSRect)windowWillUseStandardFrame:(NSWindow *)nsWindow
|
||||
defaultFrame:(NSRect)newFrame
|
||||
{
|
||||
NSRect screenFrame = [[self screen] visibleFrame];
|
||||
GdkMacosSurface *surface = gdk_surface;
|
||||
gboolean maximized = GDK_SURFACE (surface)->state & GDK_SURFACE_STATE_MAXIMIZED;
|
||||
|
||||
if (!maximized)
|
||||
return screenFrame;
|
||||
else
|
||||
return lastUnmaximizedFrame;
|
||||
}
|
||||
|
||||
-(BOOL)windowShouldZoom:(NSWindow *)nsWindow
|
||||
toFrame:(NSRect)newFrame
|
||||
{
|
||||
GdkMacosSurface *surface = gdk_surface;
|
||||
GdkSurfaceState state = GDK_SURFACE (surface)->state;
|
||||
|
||||
if (state & GDK_SURFACE_STATE_MAXIMIZED)
|
||||
{
|
||||
lastMaximizedFrame = newFrame;
|
||||
[self windowDidUnmaximize];
|
||||
}
|
||||
else
|
||||
{
|
||||
lastUnmaximizedFrame = [nsWindow frame];
|
||||
gdk_synthesize_surface_state (GDK_SURFACE (gdk_surface), 0, GDK_SURFACE_STATE_MAXIMIZED);
|
||||
}
|
||||
|
||||
inMaximizeTransition = YES;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)windowDidEndLiveResize:(NSNotification *)aNotification
|
||||
{
|
||||
gboolean maximized = GDK_SURFACE (gdk_surface)->state & GDK_SURFACE_STATE_MAXIMIZED;
|
||||
|
||||
inMaximizeTransition = NO;
|
||||
|
||||
/* Even if this is CSD, we want to be opaque while maximized
|
||||
* to speed up compositing by allowing the display server to
|
||||
* avoid costly blends.
|
||||
*/
|
||||
if (maximized)
|
||||
[self setOpaque:YES];
|
||||
}
|
||||
|
||||
-(NSSize)window:(NSWindow *)window willUseFullScreenContentSize:(NSSize)proposedSize
|
||||
{
|
||||
return [[window screen] frame].size;
|
||||
}
|
||||
|
||||
-(void)windowWillEnterFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
lastUnfullscreenFrame = [self frame];
|
||||
}
|
||||
|
||||
-(void)windowWillExitFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
[self setFrame:lastUnfullscreenFrame display:YES];
|
||||
}
|
||||
|
||||
-(void)windowDidExitFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
}
|
||||
|
||||
-(void)windowDidChangeScreen:(NSNotification *)aNotification
|
||||
{
|
||||
_gdk_macos_surface_monitor_changed (gdk_surface);
|
||||
}
|
||||
|
||||
-(void)setGdkSurface:(GdkMacosSurface *)surface
|
||||
{
|
||||
self->gdk_surface = surface;
|
||||
}
|
||||
|
||||
-(void)setDecorated:(BOOL)decorated
|
||||
{
|
||||
NSWindowStyleMask style_mask = [self styleMask];
|
||||
|
||||
[self setHasShadow:decorated];
|
||||
|
||||
if (decorated)
|
||||
style_mask |= NSWindowStyleMaskTitled;
|
||||
else
|
||||
style_mask &= ~NSWindowStyleMaskTitled;
|
||||
|
||||
[self setStyleMask:style_mask];
|
||||
}
|
||||
|
||||
-(GdkMacosSurface *)gdkSurface
|
||||
{
|
||||
return self->gdk_surface;
|
||||
}
|
||||
|
||||
-(GdkMacosDisplay *)gdkDisplay
|
||||
{
|
||||
return GDK_MACOS_DISPLAY (GDK_SURFACE (self->gdk_surface)->display);
|
||||
}
|
||||
|
||||
-(BOOL)movableByWindowBackground
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
70
gdk/macos/GdkMacosWindow.h
Normal file
70
gdk/macos/GdkMacosWindow.h
Normal file
@ -0,0 +1,70 @@
|
||||
/* GdkMacosWindow.h
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
* Copyright © 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacossurface.h"
|
||||
#include "edgesnapping.h"
|
||||
|
||||
#define GDK_IS_MACOS_WINDOW(obj) ([obj isKindOfClass:[GdkMacosWindow class]])
|
||||
|
||||
@interface GdkMacosWindow : NSWindow {
|
||||
GdkMacosSurface *gdk_surface;
|
||||
|
||||
BOOL inMove;
|
||||
BOOL inShowOrHide;
|
||||
BOOL initialPositionKnown;
|
||||
|
||||
/* Manually triggered move/resize (not by the window manager) */
|
||||
BOOL inManualMove;
|
||||
BOOL inManualResize;
|
||||
BOOL inTrackManualResize;
|
||||
NSPoint initialResizeLocation;
|
||||
NSRect initialResizeFrame;
|
||||
GdkSurfaceEdge resizeEdge;
|
||||
|
||||
EdgeSnapping snapping;
|
||||
|
||||
NSRect lastUnmaximizedFrame;
|
||||
NSRect lastMaximizedFrame;
|
||||
NSRect lastUnfullscreenFrame;
|
||||
BOOL inMaximizeTransition;
|
||||
}
|
||||
|
||||
-(void)beginManualMove;
|
||||
-(void)beginManualResize:(GdkSurfaceEdge)edge;
|
||||
-(void)hide;
|
||||
-(BOOL)isInManualResizeOrMove;
|
||||
-(BOOL)isInMove;
|
||||
-(GdkMacosDisplay *)gdkDisplay;
|
||||
-(GdkMacosSurface *)gdkSurface;
|
||||
-(void)setGdkSurface:(GdkMacosSurface *)surface;
|
||||
-(void)setStyleMask:(NSWindowStyleMask)styleMask;
|
||||
-(void)showAndMakeKey:(BOOL)makeKey;
|
||||
-(BOOL)trackManualMove;
|
||||
-(BOOL)trackManualResize;
|
||||
-(void)setDecorated:(BOOL)decorated;
|
||||
|
||||
@end
|
229
gdk/macos/edgesnapping.c
Normal file
229
gdk/macos/edgesnapping.c
Normal file
@ -0,0 +1,229 @@
|
||||
/* edgesnapping.c
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkrectangle.h"
|
||||
#include "edgesnapping.h"
|
||||
|
||||
#define LEAVE_THRESHOLD 3.0
|
||||
#define ENTER_THRESHOLD 2.0
|
||||
|
||||
#define X1(r) ((r)->x)
|
||||
#define X2(r) ((r)->x + (r)->width)
|
||||
#define Y1(r) ((r)->y)
|
||||
#define Y2(r) ((r)->y + (r)->height)
|
||||
|
||||
void
|
||||
_edge_snapping_init (EdgeSnapping *self,
|
||||
const GdkRectangle *geometry,
|
||||
const GdkRectangle *workarea,
|
||||
const GdkPoint *pointer_position,
|
||||
const GdkRectangle *window)
|
||||
{
|
||||
g_assert (self != NULL);
|
||||
g_assert (geometry != NULL);
|
||||
g_assert (workarea != NULL);
|
||||
g_assert (pointer_position != NULL);
|
||||
|
||||
self->geometry = *geometry;
|
||||
self->workarea = *workarea;
|
||||
self->last_pointer_position = *pointer_position;
|
||||
self->pointer_offset_in_window.x = pointer_position->x - window->x;
|
||||
self->pointer_offset_in_window.y = pointer_position->y - window->y;
|
||||
}
|
||||
|
||||
static void
|
||||
edge_snapping_constrain_left (EdgeSnapping *self,
|
||||
int change,
|
||||
const GdkRectangle *geometry,
|
||||
GdkRectangle *window)
|
||||
{
|
||||
if (change < 0)
|
||||
{
|
||||
if (X1 (window) < X1 (geometry) &&
|
||||
X1 (window) > X1 (geometry) - LEAVE_THRESHOLD &&
|
||||
ABS (change) < LEAVE_THRESHOLD)
|
||||
window->x = geometry->x;
|
||||
}
|
||||
|
||||
/* We don't constrain when returning from left edge */
|
||||
}
|
||||
|
||||
static void
|
||||
edge_snapping_constrain_right (EdgeSnapping *self,
|
||||
int change,
|
||||
const GdkRectangle *geometry,
|
||||
GdkRectangle *window)
|
||||
{
|
||||
if (change > 0)
|
||||
{
|
||||
if (X2 (window) > X2 (geometry) &&
|
||||
X2 (window) < X2 (geometry) + LEAVE_THRESHOLD &&
|
||||
ABS (change) < LEAVE_THRESHOLD)
|
||||
window->x = X2 (geometry) - window->width;
|
||||
}
|
||||
|
||||
/* We don't constrain when returning from right edge */
|
||||
}
|
||||
|
||||
static void
|
||||
edge_snapping_constrain_top (EdgeSnapping *self,
|
||||
int change,
|
||||
const GdkRectangle *geometry,
|
||||
GdkRectangle *window)
|
||||
{
|
||||
if (change < 0)
|
||||
{
|
||||
if (Y1 (window) < Y1 (geometry))
|
||||
window->y = geometry->y;
|
||||
}
|
||||
|
||||
/* We don't constrain when returning from top edge */
|
||||
}
|
||||
|
||||
static void
|
||||
edge_snapping_constrain_bottom (EdgeSnapping *self,
|
||||
int change,
|
||||
const GdkRectangle *geometry,
|
||||
GdkRectangle *window)
|
||||
{
|
||||
if (change > 0)
|
||||
{
|
||||
if (Y2 (window) > Y2 (geometry) &&
|
||||
Y2 (window) < Y2 (geometry) + LEAVE_THRESHOLD &&
|
||||
ABS (change) < LEAVE_THRESHOLD)
|
||||
window->y = Y2 (geometry) - window->height;
|
||||
}
|
||||
else if (change < 0)
|
||||
{
|
||||
if (Y2 (window) < Y2 (geometry) &&
|
||||
Y2 (window) > Y2 (geometry) - ENTER_THRESHOLD &&
|
||||
ABS (change) < ENTER_THRESHOLD)
|
||||
window->y = Y2 (geometry) - window->height;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
edge_snapping_constrain_horizontal (EdgeSnapping *self,
|
||||
int change,
|
||||
const GdkRectangle *geometry,
|
||||
GdkRectangle *window)
|
||||
{
|
||||
g_assert (self != NULL);
|
||||
g_assert (geometry != NULL);
|
||||
g_assert (window != NULL);
|
||||
g_assert (change != 0);
|
||||
|
||||
if (ABS (X1 (geometry) - X1 (window)) < ABS (X2 (geometry)) - ABS (X2 (window)))
|
||||
edge_snapping_constrain_left (self, change, geometry, window);
|
||||
else
|
||||
edge_snapping_constrain_right (self, change, geometry, window);
|
||||
}
|
||||
|
||||
static void
|
||||
edge_snapping_constrain_vertical (EdgeSnapping *self,
|
||||
int change,
|
||||
const GdkRectangle *geometry,
|
||||
GdkRectangle *window,
|
||||
gboolean bottom_only)
|
||||
{
|
||||
g_assert (self != NULL);
|
||||
g_assert (geometry != NULL);
|
||||
g_assert (window != NULL);
|
||||
g_assert (change != 0);
|
||||
|
||||
if (!bottom_only &&
|
||||
ABS (Y1 (geometry) - Y1 (window)) < ABS (Y2 (geometry)) - ABS (Y2 (window)))
|
||||
edge_snapping_constrain_top (self, change, geometry, window);
|
||||
else
|
||||
edge_snapping_constrain_bottom (self, change, geometry, window);
|
||||
}
|
||||
|
||||
void
|
||||
_edge_snapping_motion (EdgeSnapping *self,
|
||||
const GdkPoint *pointer_position,
|
||||
GdkRectangle *window)
|
||||
{
|
||||
GdkRectangle new_window;
|
||||
GdkRectangle overlap;
|
||||
GdkPoint change;
|
||||
|
||||
g_assert (self != NULL);
|
||||
g_assert (pointer_position != NULL);
|
||||
|
||||
change.x = pointer_position->x - self->last_pointer_position.x;
|
||||
change.y = pointer_position->y - self->last_pointer_position.y;
|
||||
|
||||
self->last_pointer_position = *pointer_position;
|
||||
|
||||
window->x += change.x;
|
||||
window->y += change.y;
|
||||
|
||||
new_window = *window;
|
||||
|
||||
/* First constrain horizontal */
|
||||
if (change.x)
|
||||
{
|
||||
edge_snapping_constrain_horizontal (self, change.x, &self->workarea, &new_window);
|
||||
if (gdk_rectangle_equal (&new_window, window))
|
||||
edge_snapping_constrain_horizontal (self, change.x, &self->geometry, &new_window);
|
||||
}
|
||||
|
||||
/* Now constrain veritcally */
|
||||
if (change.y)
|
||||
{
|
||||
edge_snapping_constrain_vertical (self, change.y, &self->workarea, &new_window, FALSE);
|
||||
if (new_window.y == window->y)
|
||||
edge_snapping_constrain_vertical (self, change.y, &self->geometry, &new_window, TRUE);
|
||||
}
|
||||
|
||||
/* If the window is not placed in the monitor at all, then we need to
|
||||
* just move the window onto the new screen using the original offset
|
||||
* of the pointer within the window.
|
||||
*/
|
||||
if (!gdk_rectangle_intersect (&self->geometry, &new_window, &overlap))
|
||||
{
|
||||
new_window.x = pointer_position->x - self->pointer_offset_in_window.x;
|
||||
new_window.y = pointer_position->y - self->pointer_offset_in_window.y;
|
||||
}
|
||||
|
||||
/* And finally make sure we aren't underneath the top bar of the
|
||||
* particular monitor.
|
||||
*/
|
||||
if (Y1 (&new_window) < Y1 (&self->workarea))
|
||||
new_window.y = self->workarea.y;
|
||||
|
||||
*window = new_window;
|
||||
}
|
||||
|
||||
void
|
||||
_edge_snapping_set_monitor (EdgeSnapping *self,
|
||||
const GdkRectangle *geometry,
|
||||
const GdkRectangle *workarea)
|
||||
{
|
||||
g_assert (self != NULL);
|
||||
g_assert (geometry != NULL);
|
||||
g_assert (workarea != NULL);
|
||||
|
||||
self->geometry = *geometry;
|
||||
self->workarea = *workarea;
|
||||
}
|
50
gdk/macos/edgesnapping.h
Normal file
50
gdk/macos/edgesnapping.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* edgesnapping.h
|
||||
*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __EDGE_SNAPPING_H__
|
||||
#define __EDGE_SNAPPING_H__
|
||||
|
||||
#include "gdktypes.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkRectangle geometry;
|
||||
GdkRectangle workarea;
|
||||
GdkPoint last_pointer_position;
|
||||
GdkPoint pointer_offset_in_window;
|
||||
} EdgeSnapping;
|
||||
|
||||
void _edge_snapping_init (EdgeSnapping *self,
|
||||
const GdkRectangle *geometry,
|
||||
const GdkRectangle *workarea,
|
||||
const GdkPoint *pointer_position,
|
||||
const GdkRectangle *window);
|
||||
void _edge_snapping_motion (EdgeSnapping *self,
|
||||
const GdkPoint *pointer_position,
|
||||
GdkRectangle *window);
|
||||
void _edge_snapping_set_monitor (EdgeSnapping *self,
|
||||
const GdkRectangle *geometry,
|
||||
const GdkRectangle *workarea);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __EDGE_SNAPPING_H__ */
|
254
gdk/macos/gdkdisplaylinksource.c
Normal file
254
gdk/macos/gdkdisplaylinksource.c
Normal file
@ -0,0 +1,254 @@
|
||||
/* gdkdisplaylinksource.c
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Christian Hergert <christian@hergert.me>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
#include "gdkdisplaylinksource.h"
|
||||
|
||||
#include "gdkmacoseventsource-private.h"
|
||||
|
||||
static gint64 host_to_frame_clock_time (gint64 host_time);
|
||||
|
||||
static gboolean
|
||||
gdk_display_link_source_prepare (GSource *source,
|
||||
gint *timeout_)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = (GdkDisplayLinkSource *)source;
|
||||
gint64 now;
|
||||
|
||||
now = g_source_get_time (source);
|
||||
|
||||
if (now < impl->presentation_time)
|
||||
*timeout_ = (impl->presentation_time - now) / 1000L;
|
||||
else
|
||||
*timeout_ = -1;
|
||||
|
||||
return impl->needs_dispatch;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_display_link_source_check (GSource *source)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = (GdkDisplayLinkSource *)source;
|
||||
return impl->needs_dispatch;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_display_link_source_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = (GdkDisplayLinkSource *)source;
|
||||
gboolean ret = G_SOURCE_CONTINUE;
|
||||
|
||||
impl->needs_dispatch = FALSE;
|
||||
|
||||
if (callback != NULL)
|
||||
ret = callback (user_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_display_link_source_finalize (GSource *source)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = (GdkDisplayLinkSource *)source;
|
||||
|
||||
CVDisplayLinkStop (impl->display_link);
|
||||
CVDisplayLinkRelease (impl->display_link);
|
||||
}
|
||||
|
||||
static GSourceFuncs gdk_display_link_source_funcs = {
|
||||
gdk_display_link_source_prepare,
|
||||
gdk_display_link_source_check,
|
||||
gdk_display_link_source_dispatch,
|
||||
gdk_display_link_source_finalize
|
||||
};
|
||||
|
||||
void
|
||||
gdk_display_link_source_pause (GdkDisplayLinkSource *source)
|
||||
{
|
||||
CVDisplayLinkStop (source->display_link);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_link_source_unpause (GdkDisplayLinkSource *source)
|
||||
{
|
||||
CVDisplayLinkStart (source->display_link);
|
||||
}
|
||||
|
||||
static CVReturn
|
||||
gdk_display_link_source_frame_cb (CVDisplayLinkRef display_link,
|
||||
const CVTimeStamp *inNow,
|
||||
const CVTimeStamp *inOutputTime,
|
||||
CVOptionFlags flagsIn,
|
||||
CVOptionFlags *flagsOut,
|
||||
void *user_data)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = user_data;
|
||||
gint64 presentation_time;
|
||||
gboolean needs_wakeup;
|
||||
|
||||
needs_wakeup = !g_atomic_int_get (&impl->needs_dispatch);
|
||||
|
||||
presentation_time = host_to_frame_clock_time (inOutputTime->hostTime);
|
||||
|
||||
impl->presentation_time = presentation_time;
|
||||
impl->needs_dispatch = TRUE;
|
||||
|
||||
if (needs_wakeup)
|
||||
{
|
||||
NSEvent *event;
|
||||
|
||||
/* Post a message so we'll break out of the message loop.
|
||||
*
|
||||
* We don't use g_main_context_wakeup() here because that
|
||||
* would result in sending a message to the pipe(2) fd in
|
||||
* the select thread which would then send this message as
|
||||
* well. Lots of extra work.
|
||||
*/
|
||||
event = [NSEvent otherEventWithType: NSEventTypeApplicationDefined
|
||||
location: NSZeroPoint
|
||||
modifierFlags: 0
|
||||
timestamp: 0
|
||||
windowNumber: 0
|
||||
context: nil
|
||||
subtype: GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP
|
||||
data1: 0
|
||||
data2: 0];
|
||||
|
||||
[NSApp postEvent:event atStart:YES];
|
||||
}
|
||||
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_link_source_new:
|
||||
*
|
||||
* Creates a new #GSource that will activate the dispatch function upon
|
||||
* notification from a CVDisplayLink that a new frame should be drawn.
|
||||
*
|
||||
* Effort is made to keep the transition from the high-priority
|
||||
* CVDisplayLink thread into this GSource lightweight. However, this is
|
||||
* somewhat non-ideal since the best case would be to do the drawing
|
||||
* from the high-priority thread.
|
||||
*
|
||||
* Returns: (transfer full): A newly created #GSource.
|
||||
*/
|
||||
GSource *
|
||||
gdk_display_link_source_new (void)
|
||||
{
|
||||
GdkDisplayLinkSource *impl;
|
||||
GSource *source;
|
||||
CVReturn ret;
|
||||
double period;
|
||||
|
||||
source = g_source_new (&gdk_display_link_source_funcs, sizeof *impl);
|
||||
impl = (GdkDisplayLinkSource *)source;
|
||||
|
||||
/*
|
||||
* Create our link based on currently connected displays.
|
||||
* If there are multiple displays, this will be something that tries
|
||||
* to work for all of them. In the future, we may want to explore multiple
|
||||
* links based on the connected displays.
|
||||
*/
|
||||
ret = CVDisplayLinkCreateWithActiveCGDisplays (&impl->display_link);
|
||||
if (ret != kCVReturnSuccess)
|
||||
{
|
||||
g_warning ("Failed to initialize CVDisplayLink!");
|
||||
return source;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine our nominal period between frames.
|
||||
*/
|
||||
period = CVDisplayLinkGetActualOutputVideoRefreshPeriod (impl->display_link);
|
||||
if (period == 0.0)
|
||||
period = 1.0 / 60.0;
|
||||
impl->refresh_interval = period * 1000000L;
|
||||
impl->refresh_rate = 1.0 / period * 1000L;
|
||||
|
||||
/*
|
||||
* Wire up our callback to be executed within the high-priority thread.
|
||||
*/
|
||||
CVDisplayLinkSetOutputCallback (impl->display_link,
|
||||
gdk_display_link_source_frame_cb,
|
||||
source);
|
||||
|
||||
g_source_set_name (source, "[gdk] quartz frame clock");
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
static gint64
|
||||
host_to_frame_clock_time (gint64 host_time)
|
||||
{
|
||||
static mach_timebase_info_data_t timebase_info;
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
*
|
||||
* This code is taken from GLib to match g_get_monotonic_time().
|
||||
*/
|
||||
if (G_UNLIKELY (timebase_info.denom == 0))
|
||||
{
|
||||
/* This is a fraction that we must use to scale
|
||||
* mach_absolute_time() by in order to reach nanoseconds.
|
||||
*
|
||||
* We've only ever observed this to be 1/1, but maybe it could be
|
||||
* 1000/1 if mach time is microseconds already, or 1/1000 if
|
||||
* picoseconds. Try to deal nicely with that.
|
||||
*/
|
||||
mach_timebase_info (&timebase_info);
|
||||
|
||||
/* We actually want microseconds... */
|
||||
if (timebase_info.numer % 1000 == 0)
|
||||
timebase_info.numer /= 1000;
|
||||
else
|
||||
timebase_info.denom *= 1000;
|
||||
|
||||
/* We want to make the numer 1 to avoid having to multiply... */
|
||||
if (timebase_info.denom % timebase_info.numer == 0)
|
||||
{
|
||||
timebase_info.denom /= timebase_info.numer;
|
||||
timebase_info.numer = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We could just multiply by timebase_info.numer below, but why
|
||||
* bother for a case that may never actually exist...
|
||||
*
|
||||
* Plus -- performing the multiplication would risk integer
|
||||
* overflow. If we ever actually end up in this situation, we
|
||||
* should more carefully evaluate the correct course of action.
|
||||
*/
|
||||
mach_timebase_info (&timebase_info); /* Get a fresh copy for a better message */
|
||||
g_error ("Got weird mach timebase info of %d/%d. Please file a bug against GLib.",
|
||||
timebase_info.numer, timebase_info.denom);
|
||||
}
|
||||
}
|
||||
|
||||
return host_time / timebase_info.denom;
|
||||
}
|
49
gdk/macos/gdkdisplaylinksource.h
Normal file
49
gdk/macos/gdkdisplaylinksource.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* gdkdisplaylinksource.h
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Christian Hergert <christian@hergert.me>
|
||||
*/
|
||||
|
||||
#ifndef GDK_DISPLAY_LINK_SOURCE_H
|
||||
#define GDK_DISPLAY_LINK_SOURCE_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GSource source;
|
||||
|
||||
CVDisplayLinkRef display_link;
|
||||
gint64 refresh_interval;
|
||||
guint refresh_rate;
|
||||
|
||||
volatile gint64 presentation_time;
|
||||
volatile guint needs_dispatch;
|
||||
} GdkDisplayLinkSource;
|
||||
|
||||
GSource *gdk_display_link_source_new (void);
|
||||
void gdk_display_link_source_pause (GdkDisplayLinkSource *source);
|
||||
void gdk_display_link_source_unpause (GdkDisplayLinkSource *source);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GDK_DISPLAY_LINK_SOURCE_H */
|
32
gdk/macos/gdkmacos.h
Normal file
32
gdk/macos/gdkmacos.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_H__
|
||||
#define __GDK_MACOS_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkmacosdevice.h"
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacosglcontext.h"
|
||||
#include "gdkmacoskeymap.h"
|
||||
#include "gdkmacosmonitor.h"
|
||||
#include "gdkmacossurface.h"
|
||||
|
||||
#endif /* __GDK_MACOS_H__ */
|
38
gdk/macos/gdkmacoscairocontext-private.h
Normal file
38
gdk/macos/gdkmacoscairocontext-private.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_CAIRO_CONTEXT_PRIVATE_H__
|
||||
#define __GDK_MACOS_CAIRO_CONTEXT_PRIVATE_H__
|
||||
|
||||
#include "gdkcairocontextprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkMacosCairoContext GdkMacosCairoContext;
|
||||
typedef struct _GdkMacosCairoContextClass GdkMacosCairoContextClass;
|
||||
|
||||
#define GDK_TYPE_MACOS_CAIRO_CONTEXT (_gdk_macos_cairo_context_get_type())
|
||||
#define GDK_MACOS_CAIRO_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_CAIRO_CONTEXT, GdkMacosCairoContext))
|
||||
#define GDK_IS_MACOS_CAIRO_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_CAIRO_CONTEXT))
|
||||
|
||||
GType _gdk_macos_cairo_context_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_CAIRO_CONTEXT_PRIVATE_H__ */
|
155
gdk/macos/gdkmacoscairocontext.c
Normal file
155
gdk/macos/gdkmacoscairocontext.c
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright © 2016 Benjamin Otte
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkconfig.h"
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <cairo-quartz.h>
|
||||
|
||||
#import "GdkMacosCairoView.h"
|
||||
|
||||
#include "gdkmacoscairocontext-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
struct _GdkMacosCairoContext
|
||||
{
|
||||
GdkCairoContext parent_instance;
|
||||
|
||||
cairo_surface_t *window_surface;
|
||||
};
|
||||
|
||||
struct _GdkMacosCairoContextClass
|
||||
{
|
||||
GdkCairoContextClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosCairoContext, _gdk_macos_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
|
||||
|
||||
static cairo_surface_t *
|
||||
create_cairo_surface_for_surface (GdkSurface *surface)
|
||||
{
|
||||
cairo_surface_t *cairo_surface;
|
||||
int scale;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
scale = gdk_surface_get_scale_factor (surface);
|
||||
width = scale * gdk_surface_get_width (surface);
|
||||
height = scale * gdk_surface_get_height (surface);
|
||||
|
||||
cairo_surface = cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
||||
|
||||
if (cairo_surface != NULL)
|
||||
cairo_surface_set_device_scale (cairo_surface, scale, scale);
|
||||
|
||||
return cairo_surface;
|
||||
}
|
||||
|
||||
static cairo_t *
|
||||
_gdk_macos_cairo_context_cairo_create (GdkCairoContext *cairo_context)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)cairo_context;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
return cairo_create (self->window_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
|
||||
GdkSurface *surface;
|
||||
NSWindow *nswindow;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
surface = gdk_draw_context_get_surface (draw_context);
|
||||
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
if (self->window_surface == NULL)
|
||||
{
|
||||
self->window_surface = create_cairo_surface_for_surface (surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (![nswindow isOpaque])
|
||||
{
|
||||
cairo_t *cr = cairo_create (self->window_surface);
|
||||
gdk_cairo_region (cr, region);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 0);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_fill (cr);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
|
||||
GdkSurface *surface;
|
||||
NSView *nsview;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
g_assert (self->window_surface != NULL);
|
||||
|
||||
surface = gdk_draw_context_get_surface (draw_context);
|
||||
nsview = _gdk_macos_surface_get_view (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
if (GDK_IS_MACOS_CAIRO_VIEW (nsview))
|
||||
[(GdkMacosCairoView *)nsview setCairoSurface:self->window_surface
|
||||
withDamage:painted];
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_surface_resized (GdkDrawContext *draw_context)
|
||||
{
|
||||
GdkMacosCairoContext *self = (GdkMacosCairoContext *)draw_context;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (self));
|
||||
|
||||
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_class_init (GdkMacosCairoContextClass *klass)
|
||||
{
|
||||
GdkCairoContextClass *cairo_context_class = GDK_CAIRO_CONTEXT_CLASS (klass);
|
||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
||||
|
||||
draw_context_class->begin_frame = _gdk_macos_cairo_context_begin_frame;
|
||||
draw_context_class->end_frame = _gdk_macos_cairo_context_end_frame;
|
||||
draw_context_class->surface_resized = _gdk_macos_cairo_context_surface_resized;
|
||||
|
||||
cairo_context_class->cairo_create = _gdk_macos_cairo_context_cairo_create;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_cairo_context_init (GdkMacosCairoContext *self)
|
||||
{
|
||||
}
|
54
gdk/macos/gdkmacosclipboard-private.h
Normal file
54
gdk/macos/gdkmacosclipboard-private.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_CLIPBOARD_PRIVATE_H__
|
||||
#define __GDK_MACOS_CLIPBOARD_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkclipboardprivate.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_MACOS_CLIPBOARD (_gdk_macos_clipboard_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK, MACOS_CLIPBOARD, GdkClipboard)
|
||||
|
||||
GdkClipboard *_gdk_macos_clipboard_new (GdkMacosDisplay *display);
|
||||
void _gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self);
|
||||
NSPasteboardType _gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||
NSPasteboardType *alternate);
|
||||
const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
|
||||
|
||||
@interface GdkMacosClipboardDataProvider : NSObject <NSPasteboardItemDataProvider>
|
||||
{
|
||||
GCancellable *cancellable;
|
||||
GdkClipboard *clipboard;
|
||||
char **mimeTypes;
|
||||
}
|
||||
|
||||
-(id)initClipboard:(GdkClipboard *)gdkClipboard mimetypes:(const char * const *)mime_types;
|
||||
-(NSArray<NSPasteboardType> *)types;
|
||||
|
||||
@end
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_CLIPBOARD_PRIVATE_H__ */
|
576
gdk/macos/gdkmacosclipboard.c
Normal file
576
gdk/macos/gdkmacosclipboard.c
Normal file
@ -0,0 +1,576 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "gdkmacosclipboard-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
|
||||
struct _GdkMacosClipboard
|
||||
{
|
||||
GdkClipboard parent_instance;
|
||||
NSPasteboard *pasteboard;
|
||||
NSInteger last_change_count;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GMemoryOutputStream *stream;
|
||||
NSPasteboardItem *item;
|
||||
NSPasteboardType type;
|
||||
GMainContext *main_context;
|
||||
guint done : 1;
|
||||
} WriteRequest;
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK_TYPE_CLIPBOARD)
|
||||
|
||||
static void
|
||||
write_request_free (WriteRequest *wr)
|
||||
{
|
||||
g_clear_pointer (&wr->main_context, g_main_context_unref);
|
||||
g_clear_object (&wr->stream);
|
||||
[wr->item release];
|
||||
g_slice_free (WriteRequest, wr);
|
||||
}
|
||||
|
||||
const char *
|
||||
_gdk_macos_clipboard_from_ns_type (NSPasteboardType type)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([type isEqualToString:NSPasteboardTypeString] ||
|
||||
[type isEqualToString:NSStringPboardType])
|
||||
return g_intern_string ("text/plain;charset=utf-8");
|
||||
else if ([type isEqualToString:NSPasteboardTypeURL] ||
|
||||
[type isEqualToString:NSPasteboardTypeFileURL])
|
||||
return g_intern_string ("text/uri-list");
|
||||
else if ([type isEqualToString:NSPasteboardTypeColor])
|
||||
return g_intern_string ("application/x-color");
|
||||
else if ([type isEqualToString:NSPasteboardTypeTIFF])
|
||||
return g_intern_string ("image/tiff");
|
||||
else if ([type isEqualToString:NSPasteboardTypePNG])
|
||||
return g_intern_string ("image/png");
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSPasteboardType
|
||||
_gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||
NSPasteboardType *alternate)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = NULL;
|
||||
|
||||
if (g_strcmp0 (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
return NSPasteboardTypeString;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = NSPasteboardTypeURL;
|
||||
return NSPasteboardTypeFileURL;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
return NSPasteboardTypeColor;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
return NSPasteboardTypeTIFF;
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/png") == 0)
|
||||
{
|
||||
return NSPasteboardTypePNG;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
static void
|
||||
populate_content_formats (GdkContentFormatsBuilder *builder,
|
||||
NSPasteboardType type)
|
||||
{
|
||||
const char *mime_type;
|
||||
|
||||
g_return_if_fail (builder != NULL);
|
||||
g_return_if_fail (type != NULL);
|
||||
|
||||
mime_type = _gdk_macos_clipboard_from_ns_type (type);
|
||||
|
||||
if (mime_type != NULL)
|
||||
gdk_content_formats_builder_add_mime_type (builder, mime_type);
|
||||
}
|
||||
|
||||
static GdkContentFormats *
|
||||
load_offer_formats (GdkMacosClipboard *self)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkContentFormatsBuilder *builder;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
for (NSPasteboardType type in [self->pasteboard types])
|
||||
populate_content_formats (builder, type);
|
||||
formats = gdk_content_formats_builder_free_to_formats (builder);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&formats);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
NSInteger change_count;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
|
||||
change_count = [self->pasteboard changeCount];
|
||||
|
||||
formats = load_offer_formats (self);
|
||||
gdk_clipboard_claim_remote (GDK_CLIPBOARD (self), formats);
|
||||
gdk_content_formats_unref (formats);
|
||||
|
||||
self->last_change_count = change_count;
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
create_stream_from_nsdata (NSData *data)
|
||||
{
|
||||
const guint8 *bytes = [data bytes];
|
||||
gsize len = [data length];
|
||||
|
||||
return g_memory_input_stream_new_from_data (g_memdup (bytes, len), len, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkMacosClipboard *self = (GdkMacosClipboard *)clipboard;
|
||||
GdkContentFormats *offer_formats = NULL;
|
||||
const char *mime_type;
|
||||
GInputStream *stream = NULL;
|
||||
GTask *task = NULL;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
g_assert (formats != NULL);
|
||||
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, _gdk_macos_clipboard_read_async);
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
offer_formats = load_offer_formats (GDK_MACOS_CLIPBOARD (clipboard));
|
||||
mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
|
||||
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"%s",
|
||||
_("No compatible transfer format found"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
NSString *nsstr = [self->pasteboard stringForType:NSPasteboardTypeString];
|
||||
|
||||
if (nsstr != NULL)
|
||||
{
|
||||
const char *str = [nsstr UTF8String];
|
||||
stream = g_memory_input_stream_new_from_data (g_strdup (str),
|
||||
strlen (str) + 1,
|
||||
g_free);
|
||||
}
|
||||
}
|
||||
else if (strcmp (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([[self->pasteboard types] containsObject:NSPasteboardTypeFileURL])
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
NSArray *files = [self->pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
gsize n_files = [files count];
|
||||
char *data;
|
||||
guint len;
|
||||
|
||||
for (gsize i = 0; i < n_files; ++i)
|
||||
{
|
||||
NSString* uriString = [files objectAtIndex:i];
|
||||
uriString = [@"file://" stringByAppendingString:uriString];
|
||||
uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
g_string_append_printf (str,
|
||||
"%s\r\n",
|
||||
[uriString cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
}
|
||||
|
||||
len = str->len;
|
||||
data = g_string_free (str, FALSE);
|
||||
stream = g_memory_input_stream_new_from_data (data, len, g_free);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
else if (strcmp (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
NSColorSpace *colorspace;
|
||||
NSColor *nscolor;
|
||||
guint16 color[4];
|
||||
|
||||
colorspace = [NSColorSpace genericRGBColorSpace];
|
||||
nscolor = [[NSColor colorFromPasteboard:self->pasteboard]
|
||||
colorUsingColorSpace:colorspace];
|
||||
|
||||
color[0] = 0xffff * [nscolor redComponent];
|
||||
color[1] = 0xffff * [nscolor greenComponent];
|
||||
color[2] = 0xffff * [nscolor blueComponent];
|
||||
color[3] = 0xffff * [nscolor alphaComponent];
|
||||
|
||||
stream = g_memory_input_stream_new_from_data (g_memdup (&color, sizeof color),
|
||||
sizeof color,
|
||||
g_free);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:NSPasteboardTypeTIFF];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/png") == 0)
|
||||
{
|
||||
NSData *data = [self->pasteboard dataForType:NSPasteboardTypePNG];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
|
||||
if (stream != NULL)
|
||||
{
|
||||
g_task_set_task_data (task, g_strdup (mime_type), g_free);
|
||||
g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
_("Failed to decode contents with mime-type of '%s'"),
|
||||
mime_type);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
g_clear_object (&task);
|
||||
g_clear_pointer (&offer_formats, gdk_content_formats_unref);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
_gdk_macos_clipboard_read_finish (GdkClipboard *clipboard,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task = (GTask *)result;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (clipboard));
|
||||
g_assert (G_IS_TASK (task));
|
||||
|
||||
if (out_mime_type != NULL)
|
||||
*out_mime_type = g_strdup (g_task_get_task_data (task));
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_send_to_pasteboard (GdkMacosClipboard *self,
|
||||
GdkContentProvider *content)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkMacosClipboardDataProvider *dataProvider;
|
||||
GdkContentFormats *serializable;
|
||||
NSPasteboardItem *item;
|
||||
const char * const *mime_types;
|
||||
gsize n_mime_types;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
g_return_if_fail (GDK_IS_CONTENT_PROVIDER (content));
|
||||
|
||||
serializable = gdk_content_provider_ref_storable_formats (content);
|
||||
serializable = gdk_content_formats_union_serialize_mime_types (serializable);
|
||||
mime_types = gdk_content_formats_get_mime_types (serializable, &n_mime_types);
|
||||
|
||||
dataProvider = [[GdkMacosClipboardDataProvider alloc] initClipboard:GDK_CLIPBOARD (self)
|
||||
mimetypes:mime_types];
|
||||
item = [[NSPasteboardItem alloc] init];
|
||||
[item setDataProvider:dataProvider forTypes:[dataProvider types]];
|
||||
|
||||
[self->pasteboard clearContents];
|
||||
if ([self->pasteboard writeObjects:[NSArray arrayWithObject:item]] == NO)
|
||||
g_warning ("Failed to write object to pasteboard");
|
||||
|
||||
self->last_change_count = [self->pasteboard changeCount];
|
||||
|
||||
g_clear_pointer (&serializable, gdk_content_formats_unref);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gdk_macos_clipboard_claim (GdkClipboard *clipboard,
|
||||
GdkContentFormats *formats,
|
||||
gboolean local,
|
||||
GdkContentProvider *provider)
|
||||
{
|
||||
GdkMacosClipboard *self = (GdkMacosClipboard *)clipboard;
|
||||
gboolean ret;
|
||||
|
||||
g_assert (GDK_IS_CLIPBOARD (clipboard));
|
||||
g_assert (formats != NULL);
|
||||
g_assert (!provider || GDK_IS_CONTENT_PROVIDER (provider));
|
||||
|
||||
ret = GDK_CLIPBOARD_CLASS (_gdk_macos_clipboard_parent_class)->claim (clipboard, formats, local, provider);
|
||||
|
||||
if (local)
|
||||
_gdk_macos_clipboard_send_to_pasteboard (self, provider);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_constructed (GObject *object)
|
||||
{
|
||||
GdkMacosClipboard *self = (GdkMacosClipboard *)object;
|
||||
|
||||
if (self->pasteboard == nil)
|
||||
self->pasteboard = [[NSPasteboard generalPasteboard] retain];
|
||||
|
||||
G_OBJECT_CLASS (_gdk_macos_clipboard_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_finalize (GObject *object)
|
||||
{
|
||||
GdkMacosClipboard *self = (GdkMacosClipboard *)object;
|
||||
|
||||
if (self->pasteboard != nil)
|
||||
{
|
||||
[self->pasteboard release];
|
||||
self->pasteboard = nil;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (_gdk_macos_clipboard_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_class_init (GdkMacosClipboardClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkClipboardClass *clipboard_class = GDK_CLIPBOARD_CLASS (klass);
|
||||
|
||||
object_class->constructed = _gdk_macos_clipboard_constructed;
|
||||
object_class->finalize = _gdk_macos_clipboard_finalize;
|
||||
|
||||
clipboard_class->claim = _gdk_macos_clipboard_claim;
|
||||
clipboard_class->read_async = _gdk_macos_clipboard_read_async;
|
||||
clipboard_class->read_finish = _gdk_macos_clipboard_read_finish;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_init (GdkMacosClipboard *self)
|
||||
{
|
||||
}
|
||||
|
||||
GdkClipboard *
|
||||
_gdk_macos_clipboard_new (GdkMacosDisplay *display)
|
||||
{
|
||||
GdkMacosClipboard *self;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
|
||||
self = g_object_new (GDK_TYPE_MACOS_CLIPBOARD,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
_gdk_macos_clipboard_load_contents (self);
|
||||
|
||||
return GDK_CLIPBOARD (self);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
|
||||
if ([self->pasteboard changeCount] != self->last_change_count)
|
||||
_gdk_macos_clipboard_load_contents (self);
|
||||
}
|
||||
|
||||
@implementation GdkMacosClipboardDataProvider
|
||||
|
||||
-(id)initClipboard:(GdkClipboard *)gdkClipboard mimetypes:(const char * const *)mime_types;
|
||||
{
|
||||
[super init];
|
||||
|
||||
self->mimeTypes = g_strdupv ((char **)mime_types);
|
||||
self->clipboard = g_object_ref (gdkClipboard);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
|
||||
g_clear_pointer (&self->mimeTypes, g_strfreev);
|
||||
g_clear_object (&self->clipboard);
|
||||
g_clear_object (&self->cancellable);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void)pasteboardFinishedWithDataProvider:(NSPasteboard *)pasteboard
|
||||
{
|
||||
g_clear_object (&self->clipboard);
|
||||
}
|
||||
|
||||
-(NSArray<NSPasteboardType> *)types
|
||||
{
|
||||
NSMutableArray *ret = [[NSMutableArray alloc] init];
|
||||
|
||||
for (guint i = 0; self->mimeTypes[i]; i++)
|
||||
{
|
||||
const char *mime_type = self->mimeTypes[i];
|
||||
NSPasteboardType type;
|
||||
NSPasteboardType alternate = nil;
|
||||
|
||||
if ((type = _gdk_macos_clipboard_to_ns_type (mime_type, &alternate)))
|
||||
{
|
||||
[ret addObject:type];
|
||||
if (alternate)
|
||||
[ret addObject:alternate];
|
||||
}
|
||||
}
|
||||
|
||||
return g_steal_pointer (&ret);
|
||||
}
|
||||
|
||||
static void
|
||||
on_data_ready_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkClipboard *clipboard = (GdkClipboard *)object;
|
||||
WriteRequest *wr = user_data;
|
||||
GError *error = NULL;
|
||||
NSData *data = nil;
|
||||
|
||||
g_assert (GDK_IS_CLIPBOARD (clipboard));
|
||||
g_assert (G_IS_ASYNC_RESULT (result));
|
||||
g_assert (wr != NULL);
|
||||
g_assert (G_IS_MEMORY_OUTPUT_STREAM (wr->stream));
|
||||
g_assert ([wr->item isKindOfClass:[NSPasteboardItem class]]);
|
||||
|
||||
if (gdk_clipboard_write_finish (clipboard, result, &error))
|
||||
{
|
||||
gsize size;
|
||||
gpointer bytes;
|
||||
|
||||
g_output_stream_close (G_OUTPUT_STREAM (wr->stream), NULL, NULL);
|
||||
|
||||
size = g_memory_output_stream_get_size (wr->stream);
|
||||
bytes = g_memory_output_stream_steal_data (wr->stream);
|
||||
data = [[NSData alloc] initWithBytesNoCopy:bytes
|
||||
length:size
|
||||
deallocator:^(void *alloc, NSUInteger length) { g_free (alloc); }];
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to serialize clipboard contents: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
[wr->item setData:data forType:wr->type];
|
||||
|
||||
wr->done = TRUE;
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
-(void) pasteboard:(NSPasteboard *)pasteboard
|
||||
item:(NSPasteboardItem *)item
|
||||
provideDataForType:(NSPasteboardType)type
|
||||
{
|
||||
const char *mime_type = _gdk_macos_clipboard_from_ns_type (type);
|
||||
GMainContext *main_context = g_main_context_default ();
|
||||
WriteRequest *wr;
|
||||
|
||||
if (self->clipboard == NULL || mime_type == NULL)
|
||||
{
|
||||
[item setData:[NSData data] forType:type];
|
||||
return;
|
||||
}
|
||||
|
||||
wr = g_slice_new0 (WriteRequest);
|
||||
wr->item = [item retain];
|
||||
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
|
||||
wr->type = type;
|
||||
wr->main_context = g_main_context_ref (main_context);
|
||||
wr->done = FALSE;
|
||||
|
||||
gdk_clipboard_write_async (self->clipboard,
|
||||
mime_type,
|
||||
G_OUTPUT_STREAM (wr->stream),
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
on_data_ready_cb,
|
||||
wr);
|
||||
|
||||
/* We're forced to provide data synchronously via this API
|
||||
* so we must block on the main loop. Using another main loop
|
||||
* than the default tends to get us locked up here, so that is
|
||||
* what we'll do for now.
|
||||
*/
|
||||
while (!wr->done)
|
||||
g_main_context_iteration (wr->main_context, TRUE);
|
||||
|
||||
write_request_free (wr);
|
||||
}
|
||||
|
||||
@end
|
@ -1,7 +1,7 @@
|
||||
/* gdkdnd-quartz.h
|
||||
/* gdkmacoscursor-private.h
|
||||
*
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
* Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
* Copyright (C) 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -17,29 +17,16 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_DND__
|
||||
#define __GDK_QUARTZ_DND__
|
||||
|
||||
#include <gdkdndprivate.h>
|
||||
#include "gdkquartzdnd.h"
|
||||
#ifndef __GDK_MACOS_CURSOR_PRIVATE_H__
|
||||
#define __GDK_MACOS_CURSOR_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GdkQuartzDragContext
|
||||
{
|
||||
GdkDragContext context;
|
||||
|
||||
id <NSDraggingInfo> dragging_info;
|
||||
GdkDevice *device;
|
||||
};
|
||||
|
||||
struct _GdkQuartzDragContextClass
|
||||
{
|
||||
GdkDragContextClass context_class;
|
||||
};
|
||||
NSCursor *_gdk_macos_cursor_get_ns_cursor (GdkCursor *cursor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_DND__ */
|
||||
#endif /* __GDK_MACOS_CURSOR_PRIVATE_H__ */
|
181
gdk/macos/gdkmacoscursor.c
Normal file
181
gdk/macos/gdkmacoscursor.c
Normal file
@ -0,0 +1,181 @@
|
||||
/* gdkcursor-macos.c
|
||||
*
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
* Copyright (C) 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "gdkmacoscursor-private.h"
|
||||
|
||||
/* OS X only exports a number of cursor types in its public NSCursor interface.
|
||||
* By overriding the private _coreCursorType method, we can tell OS X to load
|
||||
* one of its internal cursors instead (since cursor images are loaded on demand
|
||||
* instead of in advance). WebKit does this too.
|
||||
*/
|
||||
|
||||
@interface gdkCoreCursor : NSCursor {
|
||||
@private
|
||||
int type;
|
||||
BOOL override;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation gdkCoreCursor
|
||||
|
||||
- (long long)_coreCursorType
|
||||
{
|
||||
if (self->override)
|
||||
return self->type;
|
||||
return [super _coreCursorType];
|
||||
}
|
||||
|
||||
#define CUSTOM_CURSOR_CTOR(name, id) \
|
||||
+ (gdkCoreCursor *)name \
|
||||
{ \
|
||||
gdkCoreCursor *obj; \
|
||||
obj = [self new]; \
|
||||
if (obj) { \
|
||||
obj->override = YES; \
|
||||
obj->type = id; \
|
||||
} \
|
||||
return obj; \
|
||||
}
|
||||
CUSTOM_CURSOR_CTOR(gdkHelpCursor, 40)
|
||||
CUSTOM_CURSOR_CTOR(gdkProgressCursor, 4)
|
||||
/* TODO OS X doesn't seem to have a way to get this. There is an undocumented
|
||||
* method +[NSCursor _waitCursor], but it doesn't actually return this cursor,
|
||||
* but rather some odd low-quality non-animating version of this cursor. Use
|
||||
* the progress cursor instead for now.
|
||||
*/
|
||||
CUSTOM_CURSOR_CTOR(gdkWaitCursor, 4)
|
||||
CUSTOM_CURSOR_CTOR(gdkAliasCursor, 2)
|
||||
CUSTOM_CURSOR_CTOR(gdkMoveCursor, 39)
|
||||
/* TODO OS X doesn't seem to provide one; copy the move cursor for now
|
||||
* since it looks similar to what we want. */
|
||||
CUSTOM_CURSOR_CTOR(gdkAllScrollCursor, 39)
|
||||
CUSTOM_CURSOR_CTOR(gdkNEResizeCursor, 29)
|
||||
CUSTOM_CURSOR_CTOR(gdkNWResizeCursor, 33)
|
||||
CUSTOM_CURSOR_CTOR(gdkSEResizeCursor, 35)
|
||||
CUSTOM_CURSOR_CTOR(gdkSWResizeCursor, 37)
|
||||
CUSTOM_CURSOR_CTOR(gdkEWResizeCursor, 28)
|
||||
CUSTOM_CURSOR_CTOR(gdkNSResizeCursor, 32)
|
||||
CUSTOM_CURSOR_CTOR(gdkNESWResizeCursor, 30)
|
||||
CUSTOM_CURSOR_CTOR(gdkNWSEResizeCursor, 34)
|
||||
CUSTOM_CURSOR_CTOR(gdkZoomInCursor, 42)
|
||||
CUSTOM_CURSOR_CTOR(gdkZoomOutCursor, 43)
|
||||
#undef CUSTOM_CURSOR_CTOR
|
||||
|
||||
@end
|
||||
|
||||
struct CursorsByName {
|
||||
const gchar *name;
|
||||
NSString *selector;
|
||||
};
|
||||
|
||||
static const struct CursorsByName cursors_by_name[] = {
|
||||
/* Link & Status */
|
||||
{ "context-menu", @"contextualMenuCursor" },
|
||||
{ "help", @"gdkHelpCursor" },
|
||||
{ "pointer", @"pointingHandCursor" },
|
||||
{ "progress", @"gdkProgressCursor" },
|
||||
{ "wait", @"gdkWaitCursor" },
|
||||
/* Selection */
|
||||
{ "cell", @"crosshairCursor" },
|
||||
{ "crosshair", @"crosshairCursor" },
|
||||
{ "text", @"IBeamCursor" },
|
||||
{ "vertical-text", @"IBeamCursorForVerticalLayout" },
|
||||
/* Drag & Drop */
|
||||
{ "alias", @"gdkAliasCursor" },
|
||||
{ "copy", @"dragCopyCursor" },
|
||||
{ "move", @"gdkMoveCursor" },
|
||||
{ "no-drop", @"operationNotAllowedCursor" },
|
||||
{ "not-allowed", @"operationNotAllowedCursor" },
|
||||
{ "grab", @"openHandCursor" },
|
||||
{ "grabbing", @"closedHandCursor" },
|
||||
/* Resize & Scrolling */
|
||||
{ "all-scroll", @"gdkAllScrollCursor" },
|
||||
{ "col-resize", @"resizeLeftRightCursor" },
|
||||
{ "row-resize", @"resizeUpDownCursor" },
|
||||
|
||||
/* Undocumented cursors to match native resizing */
|
||||
{ "e-resize", @"_windowResizeEastWestCursor" },
|
||||
{ "w-resize", @"_windowResizeEastWestCursor" },
|
||||
{ "n-resize", @"_windowResizeNorthSouthCursor" },
|
||||
{ "s-resize", @"_windowResizeNorthSouthCursor" },
|
||||
|
||||
{ "ne-resize", @"gdkNEResizeCursor" },
|
||||
{ "nw-resize", @"gdkNWResizeCursor" },
|
||||
{ "se-resize", @"gdkSEResizeCursor" },
|
||||
{ "sw-resize", @"gdkSWResizeCursor" },
|
||||
{ "ew-resize", @"gdkEWResizeCursor" },
|
||||
{ "ns-resize", @"gdkNSResizeCursor" },
|
||||
{ "nesw-resize", @"gdkNESWResizeCursor" },
|
||||
{ "nwse-resize", @"gdkNWSEResizeCursor" },
|
||||
/* Zoom */
|
||||
{ "zoom-in", @"gdkZoomInCursor" },
|
||||
{ "zoom-out", @"gdkZoomOutCursor" },
|
||||
};
|
||||
|
||||
static NSCursor *
|
||||
create_blank_cursor (void)
|
||||
{
|
||||
NSCursor *nscursor;
|
||||
NSImage *nsimage;
|
||||
NSSize size = { 1.0, 1.0 };
|
||||
|
||||
nsimage = [[NSImage alloc] initWithSize:size];
|
||||
nscursor = [[NSCursor alloc] initWithImage:nsimage
|
||||
hotSpot:NSMakePoint(0.0, 0.0)];
|
||||
[nsimage release];
|
||||
|
||||
return nscursor;
|
||||
}
|
||||
|
||||
NSCursor *
|
||||
_gdk_macos_cursor_get_ns_cursor (GdkCursor *cursor)
|
||||
{
|
||||
const char *name = NULL;
|
||||
NSCursor *nscursor;
|
||||
SEL selector = @selector(arrowCursor);
|
||||
|
||||
g_return_val_if_fail (!cursor || GDK_IS_CURSOR (cursor), NULL);
|
||||
|
||||
if (cursor != NULL)
|
||||
name = gdk_cursor_get_name (cursor);
|
||||
|
||||
if (name == NULL)
|
||||
goto load_cursor;
|
||||
|
||||
if (strcmp (name, "none") == 0)
|
||||
return create_blank_cursor ();
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (cursors_by_name); i++)
|
||||
{
|
||||
if (strcmp (cursors_by_name[i].name, name) == 0)
|
||||
{
|
||||
selector = NSSelectorFromString (cursors_by_name[i].selector);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
load_cursor:
|
||||
nscursor = [[gdkCoreCursor class] performSelector:selector];
|
||||
[nscursor retain];
|
||||
return nscursor;
|
||||
}
|
208
gdk/macos/gdkmacosdevice.c
Normal file
208
gdk/macos/gdkmacosdevice.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
* Copyright 2010 Kristian Rietveld <kris@gtk.org>
|
||||
* Copyright 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
|
||||
#include "gdkmacoscursor-private.h"
|
||||
#include "gdkmacosdevice.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
struct _GdkMacosDevice
|
||||
{
|
||||
GdkDevice parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkMacosDeviceClass
|
||||
{
|
||||
GdkDeviceClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosDevice, gdk_macos_device, GDK_TYPE_DEVICE)
|
||||
|
||||
static void
|
||||
gdk_macos_device_set_surface_cursor (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
NSCursor *nscursor;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DEVICE (device));
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
g_assert (!cursor || GDK_IS_CURSOR (cursor));
|
||||
|
||||
nscursor = _gdk_macos_cursor_get_ns_cursor (cursor);
|
||||
|
||||
if (nscursor != NULL)
|
||||
{
|
||||
[nscursor set];
|
||||
[nscursor release];
|
||||
}
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_macos_device_surface_at_position (GdkDevice *device,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *state)
|
||||
{
|
||||
GdkMacosDisplay *display;
|
||||
GdkMacosSurface *surface;
|
||||
NSPoint point;
|
||||
gint x;
|
||||
gint y;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DEVICE (device));
|
||||
g_assert (win_x != NULL);
|
||||
g_assert (win_y != NULL);
|
||||
|
||||
point = [NSEvent mouseLocation];
|
||||
display = GDK_MACOS_DISPLAY (gdk_device_get_display (device));
|
||||
|
||||
if (state != NULL)
|
||||
*state = (_gdk_macos_display_get_current_keyboard_modifiers (display) |
|
||||
_gdk_macos_display_get_current_mouse_modifiers (display));
|
||||
|
||||
surface = _gdk_macos_display_get_surface_at_display_coords (display, point.x, point.y, &x, &y);
|
||||
|
||||
*win_x = x;
|
||||
*win_y = y;
|
||||
|
||||
return GDK_SURFACE (surface);
|
||||
}
|
||||
|
||||
static GdkGrabStatus
|
||||
gdk_macos_device_grab (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
gboolean owner_events,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurface *confine_to,
|
||||
GdkCursor *cursor,
|
||||
guint32 time_)
|
||||
{
|
||||
/* Should remain empty */
|
||||
return GDK_GRAB_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_device_ungrab (GdkDevice *device,
|
||||
guint32 time_)
|
||||
{
|
||||
GdkMacosDevice *self = (GdkMacosDevice *)device;
|
||||
GdkDeviceGrabInfo *grab;
|
||||
GdkDisplay *display;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DEVICE (self));
|
||||
|
||||
display = gdk_device_get_display (device);
|
||||
grab = _gdk_display_get_last_device_grab (display, device);
|
||||
|
||||
if (grab != NULL)
|
||||
grab->serial_end = 0;
|
||||
|
||||
_gdk_display_device_grab_update (display, device, device, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_device_get_state (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
gdouble x_pos, y_pos;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DEVICE (device));
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
gdk_surface_get_device_position (surface, device, &x_pos, &y_pos, mask);
|
||||
|
||||
if (axes != NULL)
|
||||
{
|
||||
axes[0] = x_pos;
|
||||
axes[1] = y_pos;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_device_query_state (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
GdkSurface **child_surface,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
NSPoint point;
|
||||
int sx = 0;
|
||||
int sy = 0;
|
||||
int x_tmp;
|
||||
int y_tmp;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DEVICE (device));
|
||||
g_assert (!surface || GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
if (child_surface)
|
||||
*child_surface = surface;
|
||||
|
||||
display = gdk_device_get_display (device);
|
||||
point = [NSEvent mouseLocation];
|
||||
_gdk_macos_display_from_display_coords (GDK_MACOS_DISPLAY (display),
|
||||
point.x, point.y,
|
||||
&x_tmp, &y_tmp);
|
||||
|
||||
if (surface)
|
||||
_gdk_macos_surface_get_root_coords (GDK_MACOS_SURFACE (surface), &sx, &sy);
|
||||
|
||||
if (win_x)
|
||||
*win_x = x_tmp - sx;
|
||||
|
||||
if (win_y)
|
||||
*win_y = y_tmp - sy;
|
||||
|
||||
if (mask)
|
||||
*mask = _gdk_macos_display_get_current_keyboard_modifiers (GDK_MACOS_DISPLAY (display)) |
|
||||
_gdk_macos_display_get_current_mouse_modifiers (GDK_MACOS_DISPLAY (display));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_device_class_init (GdkMacosDeviceClass *klass)
|
||||
{
|
||||
GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
|
||||
|
||||
device_class->get_state = gdk_macos_device_get_state;
|
||||
device_class->grab = gdk_macos_device_grab;
|
||||
device_class->query_state = gdk_macos_device_query_state;
|
||||
device_class->set_surface_cursor = gdk_macos_device_set_surface_cursor;
|
||||
device_class->surface_at_position = gdk_macos_device_surface_at_position;
|
||||
device_class->ungrab = gdk_macos_device_ungrab;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_device_init (GdkMacosDevice *self)
|
||||
{
|
||||
_gdk_device_add_axis (GDK_DEVICE (self), GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (GDK_DEVICE (self), GDK_AXIS_Y, 0, 0, 1);
|
||||
}
|
43
gdk/macos/gdkmacosdevice.h
Normal file
43
gdk/macos/gdkmacosdevice.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_DEVICE_H__
|
||||
#define __GDK_MACOS_DEVICE_H__
|
||||
|
||||
#if !defined (__GDKMACOS_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/macos/gdkmacos.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkMacosDevice GdkMacosDevice;
|
||||
typedef struct _GdkMacosDeviceClass GdkMacosDeviceClass;
|
||||
|
||||
#define GDK_TYPE_MACOS_DEVICE (gdk_macos_device_get_type())
|
||||
#define GDK_MACOS_DEVICE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_DEVICE, GdkMacosDevice))
|
||||
#define GDK_IS_MACOS_DEVICE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DEVICE))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_macos_device_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_DEVICE_H__ */
|
154
gdk/macos/gdkmacosdisplay-private.h
Normal file
154
gdk/macos/gdkmacosdisplay-private.h
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_DISPLAY_PRIVATE_H__
|
||||
#define __GDK_MACOS_DISPLAY_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacoskeymap.h"
|
||||
#include "gdkmacossurface.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GdkMacosDisplay
|
||||
{
|
||||
GdkDisplay parent_instance;
|
||||
|
||||
char *name;
|
||||
GdkMacosKeymap *keymap;
|
||||
|
||||
/* An list of GdkMacosMonitor. The first instance is always the primary
|
||||
* monitor. This contains the 0,0 coordinate in quartz coordinates, but may
|
||||
* not be 0,0 in GDK coordinates.
|
||||
*/
|
||||
GListStore *monitors;
|
||||
|
||||
/* A queue of surfaces that have been made "main" so that we can update the
|
||||
* main status to the next surface when a window has lost main status (such
|
||||
* as when destroyed). This uses the GdkMacosSurface main link.
|
||||
*/
|
||||
GQueue main_surfaces;
|
||||
|
||||
/* A queue of surfaces sorted by their front-to-back ordering on the screen.
|
||||
* This is updated occasionally when we know that the data we have cached
|
||||
* has been invalidated. This uses the GdkMacosSurface.sorted link.
|
||||
*/
|
||||
GQueue sorted_surfaces;
|
||||
|
||||
/* Our CVDisplayLink based GSource which we use to freeze/thaw the
|
||||
* GdkFrameClock for the surface.
|
||||
*/
|
||||
GSource *frame_source;
|
||||
|
||||
/* A queue of surfaces which we know are awaiting frames to be drawn. This
|
||||
* uses the GdkMacosSurface.frame link.
|
||||
*/
|
||||
GQueue awaiting_frames;
|
||||
|
||||
/* The surface that is receiving keyboard events */
|
||||
GdkMacosSurface *keyboard_surface;
|
||||
|
||||
/* Used to translate from quartz coordinate space to GDK */
|
||||
int width;
|
||||
int height;
|
||||
int min_x;
|
||||
int min_y;
|
||||
int max_x;
|
||||
int max_y;
|
||||
};
|
||||
|
||||
struct _GdkMacosDisplayClass
|
||||
{
|
||||
GdkDisplayClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GdkDisplay *_gdk_macos_display_open (const gchar *display_name);
|
||||
int _gdk_macos_display_get_fd (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_queue_events (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_to_display_coords (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y,
|
||||
int *out_x,
|
||||
int *out_y);
|
||||
void _gdk_macos_display_from_display_coords (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y,
|
||||
int *out_x,
|
||||
int *out_y);
|
||||
NSScreen *_gdk_macos_display_get_screen_at_display_coords (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y);
|
||||
GdkMonitor *_gdk_macos_display_get_monitor_at_coords (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y);
|
||||
GdkMonitor *_gdk_macos_display_get_monitor_at_display_coords (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y);
|
||||
GdkEvent *_gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
NSEvent *event);
|
||||
void _gdk_macos_display_break_all_grabs (GdkMacosDisplay *self,
|
||||
guint32 time);
|
||||
GdkModifierType _gdk_macos_display_get_current_keyboard_modifiers (GdkMacosDisplay *self);
|
||||
GdkModifierType _gdk_macos_display_get_current_mouse_modifiers (GdkMacosDisplay *self);
|
||||
GdkMacosSurface *_gdk_macos_display_get_surface_at_display_coords (GdkMacosDisplay *self,
|
||||
double x,
|
||||
double y,
|
||||
int *surface_x,
|
||||
int *surface_y);
|
||||
void _gdk_macos_display_reload_monitors (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_surface_removed (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_add_frame_callback (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_remove_frame_callback (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_synthesize_motion (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
NSWindow *_gdk_macos_display_find_native_under_pointer (GdkMacosDisplay *self,
|
||||
int *x,
|
||||
int *y);
|
||||
gboolean _gdk_macos_display_get_setting (GdkMacosDisplay *self,
|
||||
const gchar *setting,
|
||||
GValue *value);
|
||||
void _gdk_macos_display_reload_settings (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_surface_resigned_main (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_surface_became_main (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_surface_resigned_key (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_surface_became_key (GdkMacosDisplay *self,
|
||||
GdkMacosSurface *surface);
|
||||
int _gdk_macos_display_get_nominal_refresh_rate (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_clear_sorting (GdkMacosDisplay *self);
|
||||
const GList *_gdk_macos_display_get_surfaces (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_send_button_event (GdkMacosDisplay *self,
|
||||
NSEvent *nsevent);
|
||||
void _gdk_macos_display_warp_pointer (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_DISPLAY_PRIVATE_H__ */
|
194
gdk/macos/gdkmacosdisplay-settings.c
Normal file
194
gdk/macos/gdkmacosdisplay-settings.c
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright © 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright © 1998-2002 Tor Lillqvist
|
||||
* Copyright © 2005-2008 Imendio AB
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *font_name;
|
||||
int xft_dpi;
|
||||
int double_click_time;
|
||||
int cursor_blink_timeout;
|
||||
guint enable_animations : 1;
|
||||
guint shell_shows_desktop : 1;
|
||||
guint shell_shows_menubar : 1;
|
||||
guint primary_button_warps_slider : 1;
|
||||
} GdkMacosSettings;
|
||||
|
||||
static GdkMacosSettings current_settings;
|
||||
static gboolean current_settings_initialized;
|
||||
|
||||
static void
|
||||
_gdk_macos_settings_load (GdkMacosSettings *settings)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString *name;
|
||||
NSInteger ival;
|
||||
float fval;
|
||||
char *str;
|
||||
int pt_size;
|
||||
|
||||
g_assert (settings != NULL);
|
||||
|
||||
settings->shell_shows_desktop = TRUE;
|
||||
settings->shell_shows_menubar = TRUE;
|
||||
settings->enable_animations = TRUE;
|
||||
settings->xft_dpi = 72 * 1024;
|
||||
|
||||
ival = [defaults integerForKey:@"NSTextInsertionPointBlinkPeriod"];
|
||||
if (ival > 0)
|
||||
settings->cursor_blink_timeout = ival;
|
||||
else
|
||||
settings->cursor_blink_timeout = 1000;
|
||||
|
||||
settings->primary_button_warps_slider =
|
||||
[[NSUserDefaults standardUserDefaults] boolForKey:@"AppleScrollerPagingBehavior"] == YES;
|
||||
|
||||
fval = [defaults floatForKey:@"com.apple.mouse.doubleClickThreshold"];
|
||||
if (fval == 0.0)
|
||||
fval = 0.5;
|
||||
settings->double_click_time = fval * 1000;
|
||||
|
||||
name = [[NSFont systemFontOfSize:0] familyName];
|
||||
pt_size = (gint)[[NSFont userFontOfSize:0] pointSize];
|
||||
/* Let's try to use the "views" font size (12pt) by default. This is
|
||||
* used for lists/text/other "content" which is the largest parts of
|
||||
* apps, using the "regular control" size (13pt) looks a bit out of
|
||||
* place. We might have to tweak this.
|
||||
*
|
||||
* The size has to be hardcoded as there doesn't seem to be a way to
|
||||
* get the views font size programmatically.
|
||||
*/
|
||||
str = g_strdup_printf ("%s %d", [name UTF8String], pt_size);
|
||||
settings->font_name = g_intern_string (str);
|
||||
g_free (str);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_display_get_setting (GdkMacosDisplay *self,
|
||||
const gchar *setting,
|
||||
GValue *value)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (self), FALSE);
|
||||
g_return_val_if_fail (setting != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
if (!current_settings_initialized)
|
||||
{
|
||||
_gdk_macos_settings_load (¤t_settings);
|
||||
current_settings_initialized = TRUE;
|
||||
}
|
||||
|
||||
if (FALSE) {}
|
||||
else if (strcmp (setting, "gtk-enable-animations") == 0)
|
||||
{
|
||||
g_value_set_boolean (value, current_settings.enable_animations);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-xft-dpi") == 0)
|
||||
{
|
||||
g_value_set_int (value, current_settings.xft_dpi);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-cursor-blink-timeout") == 0)
|
||||
{
|
||||
g_value_set_int (value, current_settings.cursor_blink_timeout);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-double-click-time") == 0)
|
||||
{
|
||||
g_value_set_int (value, current_settings.double_click_time);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-font-name") == 0)
|
||||
{
|
||||
g_value_set_static_string (value, current_settings.font_name);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-primary-button-warps-slider") == 0)
|
||||
{
|
||||
g_value_set_boolean (value, current_settings.primary_button_warps_slider);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-shell-shows-desktop") == 0)
|
||||
{
|
||||
g_value_set_boolean (value, current_settings.shell_shows_desktop);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (strcmp (setting, "gtk-shell-shows-menubar") == 0)
|
||||
{
|
||||
g_value_set_boolean (value, current_settings.shell_shows_menubar);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_reload_settings (GdkMacosDisplay *self)
|
||||
{
|
||||
GdkMacosSettings old_settings;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_DISPLAY (self));
|
||||
|
||||
old_settings = current_settings;
|
||||
_gdk_macos_settings_load (¤t_settings);
|
||||
current_settings_initialized = TRUE;
|
||||
|
||||
if (old_settings.xft_dpi != current_settings.xft_dpi)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-xft-dpi");
|
||||
|
||||
if (old_settings.double_click_time != current_settings.double_click_time)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-double-click-time");
|
||||
|
||||
if (old_settings.enable_animations != current_settings.enable_animations)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-enable-animations");
|
||||
|
||||
if (old_settings.font_name != current_settings.font_name)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-font-name");
|
||||
|
||||
if (old_settings.primary_button_warps_slider != current_settings.primary_button_warps_slider)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-primary-button-warps-slider");
|
||||
|
||||
if (old_settings.shell_shows_menubar != current_settings.shell_shows_menubar)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-shell-shows-menubar");
|
||||
|
||||
if (old_settings.shell_shows_desktop != current_settings.shell_shows_desktop)
|
||||
gdk_display_setting_changed (GDK_DISPLAY (self), "gtk-shell-shows-desktop");
|
||||
}
|
1219
gdk/macos/gdkmacosdisplay-translate.c
Normal file
1219
gdk/macos/gdkmacosdisplay-translate.c
Normal file
File diff suppressed because it is too large
Load Diff
1071
gdk/macos/gdkmacosdisplay.c
Normal file
1071
gdk/macos/gdkmacosdisplay.c
Normal file
File diff suppressed because it is too large
Load Diff
47
gdk/macos/gdkmacosdisplay.h
Normal file
47
gdk/macos/gdkmacosdisplay.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_DISPLAY_H__
|
||||
#define __GDK_MACOS_DISPLAY_H__
|
||||
|
||||
#if !defined (__GDKMACOS_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/macos/gdkmacos.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifdef GTK_COMPILATION
|
||||
typedef struct _GdkMacosDisplay GdkMacosDisplay;
|
||||
#else
|
||||
typedef GdkDisplay GdkMacosDisplay;
|
||||
#endif
|
||||
typedef struct _GdkMacosDisplayClass GdkMacosDisplayClass;
|
||||
|
||||
#define GDK_TYPE_MACOS_DISPLAY (gdk_macos_display_get_type())
|
||||
#define GDK_MACOS_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_DISPLAY, GdkMacosDisplay))
|
||||
#define GDK_IS_MACOS_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DISPLAY))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_macos_display_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_DISPLAY_H__ */
|
70
gdk/macos/gdkmacosdrag-private.h
Normal file
70
gdk/macos/gdkmacosdrag-private.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_DRAG_PRIVATE_H__
|
||||
#define __GDK_MACOS_DRAG_PRIVATE_H__
|
||||
|
||||
#include "gdkdragprivate.h"
|
||||
|
||||
#include "gdkmacosdragsurface-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_MACOS_DRAG (gdk_macos_drag_get_type ())
|
||||
#define GDK_MACOS_DRAG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_DRAG, GdkMacosDrag))
|
||||
#define GDK_MACOS_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_MACOS_DRAG, GdkMacosDragClass))
|
||||
#define GDK_IS_MACOS_DRAG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DRAG))
|
||||
#define GDK_IS_MACOS_DRAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_MACOS_DRAG))
|
||||
#define GDK_MACOS_DRAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_MACOS_DRAG, GdkMacosDragClass))
|
||||
|
||||
typedef struct _GdkMacosDrag GdkMacosDrag;
|
||||
typedef struct _GdkMacosDragClass GdkMacosDragClass;
|
||||
|
||||
struct _GdkMacosDrag
|
||||
{
|
||||
GdkDrag parent_instance;
|
||||
|
||||
GdkMacosDragSurface *drag_surface;
|
||||
GdkSeat *drag_seat;
|
||||
GdkCursor *cursor;
|
||||
|
||||
int hot_x;
|
||||
int hot_y;
|
||||
|
||||
int last_x;
|
||||
int last_y;
|
||||
|
||||
int start_x;
|
||||
int start_y;
|
||||
|
||||
guint did_update : 1;
|
||||
guint cancelled : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosDragClass
|
||||
{
|
||||
GdkDragClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_macos_drag_get_type (void) G_GNUC_CONST;
|
||||
gboolean _gdk_macos_drag_begin (GdkMacosDrag *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_DRAG_PRIVATE_H__ */
|
617
gdk/macos/gdkmacosdrag.c
Normal file
617
gdk/macos/gdkmacosdrag.c
Normal file
@ -0,0 +1,617 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkintl.h"
|
||||
|
||||
#include "gdkmacoscursor-private.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosdrag-private.h"
|
||||
#include "gdkmacosdragsurface-private.h"
|
||||
|
||||
#define BIG_STEP 20
|
||||
#define SMALL_STEP 1
|
||||
#define ANIM_TIME 500000 /* .5 seconds */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkMacosDrag *drag;
|
||||
GdkFrameClock *frame_clock;
|
||||
gint64 start_time;
|
||||
} GdkMacosZoomback;
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosDrag, gdk_macos_drag, GDK_TYPE_DRAG)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DRAG_SURFACE,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static double
|
||||
ease_out_cubic (double t)
|
||||
{
|
||||
double p = t - 1;
|
||||
return p * p * p + 1;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_zoomback_destroy (GdkMacosZoomback *zb)
|
||||
{
|
||||
gdk_surface_hide (GDK_SURFACE (zb->drag->drag_surface));
|
||||
g_clear_object (&zb->drag);
|
||||
g_slice_free (GdkMacosZoomback, zb);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_zoomback_timeout (gpointer data)
|
||||
{
|
||||
GdkMacosZoomback *zb = data;
|
||||
GdkFrameClock *frame_clock;
|
||||
GdkMacosDrag *drag;
|
||||
gint64 current_time;
|
||||
double f;
|
||||
double t;
|
||||
|
||||
g_assert (zb != NULL);
|
||||
g_assert (GDK_IS_MACOS_DRAG (zb->drag));
|
||||
|
||||
drag = zb->drag;
|
||||
frame_clock = zb->frame_clock;
|
||||
|
||||
if (!frame_clock)
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
current_time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
f = (current_time - zb->start_time) / (double) ANIM_TIME;
|
||||
if (f >= 1.0)
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
t = ease_out_cubic (f);
|
||||
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (drag->drag_surface),
|
||||
(drag->last_x - drag->hot_x) +
|
||||
(drag->start_x - drag->last_x) * t,
|
||||
(drag->last_y - drag->hot_y) +
|
||||
(drag->start_y - drag->last_y) * t);
|
||||
_gdk_macos_surface_set_opacity (GDK_MACOS_SURFACE (drag->drag_surface), 1.0 - f);
|
||||
|
||||
/* Make sure we're topmost */
|
||||
_gdk_macos_surface_show (GDK_MACOS_SURFACE (drag->drag_surface));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_macos_drag_get_drag_surface (GdkDrag *drag)
|
||||
{
|
||||
return GDK_SURFACE (GDK_MACOS_DRAG (drag)->drag_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_set_hotspot (GdkDrag *drag,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
int change_x;
|
||||
int change_y;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
change_x = hot_x - self->hot_x;
|
||||
change_y = hot_y - self->hot_y;
|
||||
|
||||
self->hot_x = hot_x;
|
||||
self->hot_y = hot_y;
|
||||
|
||||
if (change_x || change_y)
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self->drag_surface),
|
||||
GDK_SURFACE (self->drag_surface)->x + change_x,
|
||||
GDK_SURFACE (self->drag_surface)->y + change_y);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_drop_done (GdkDrag *drag,
|
||||
gboolean success)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
GdkMacosZoomback *zb;
|
||||
guint id;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
if (success)
|
||||
{
|
||||
gdk_surface_hide (GDK_SURFACE (self->drag_surface));
|
||||
g_object_unref (drag);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Apple HIG suggests doing a "zoomback" animation of the surface back
|
||||
* towards the original position.
|
||||
*/
|
||||
zb = g_slice_new0 (GdkMacosZoomback);
|
||||
zb->drag = g_object_ref (self);
|
||||
zb->frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self->drag_surface));
|
||||
zb->start_time = gdk_frame_clock_get_frame_time (zb->frame_clock);
|
||||
|
||||
id = g_timeout_add_full (G_PRIORITY_DEFAULT, 17,
|
||||
gdk_macos_zoomback_timeout,
|
||||
zb,
|
||||
(GDestroyNotify) gdk_macos_zoomback_destroy);
|
||||
g_source_set_name_by_id (id, "[gtk] gdk_macos_zoomback_timeout");
|
||||
g_object_unref (drag);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_set_cursor (GdkDrag *drag,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
NSCursor *nscursor;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
g_assert (!cursor || GDK_IS_CURSOR (cursor));
|
||||
|
||||
g_set_object (&self->cursor, cursor);
|
||||
|
||||
nscursor = _gdk_macos_cursor_get_ns_cursor (cursor);
|
||||
|
||||
if (nscursor != NULL)
|
||||
[nscursor set];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drag_grab (GdkMacosDrag *self)
|
||||
{
|
||||
GdkSeat *seat;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
seat = gdk_device_get_seat (gdk_drag_get_device (GDK_DRAG (self)));
|
||||
|
||||
if (gdk_seat_grab (seat,
|
||||
GDK_SURFACE (self->drag_surface),
|
||||
GDK_SEAT_CAPABILITY_ALL_POINTING,
|
||||
FALSE,
|
||||
self->cursor,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL) != GDK_GRAB_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
g_set_object (&self->drag_seat, seat);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_ungrab (GdkMacosDrag *self)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
display = gdk_drag_get_display (GDK_DRAG (self));
|
||||
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), GDK_CURRENT_TIME);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_cancel (GdkDrag *drag,
|
||||
GdkDragCancelReason reason)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
if (self->cancelled)
|
||||
return;
|
||||
|
||||
self->cancelled = TRUE;
|
||||
drag_ungrab (self);
|
||||
gdk_drag_drop_done (drag, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_drop_performed (GdkDrag *drag,
|
||||
guint32 time)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
drag_ungrab (self);
|
||||
g_signal_emit_by_name (drag, "dnd-finished");
|
||||
gdk_drag_drop_done (drag, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_get_current_actions (GdkModifierType state,
|
||||
gint button,
|
||||
GdkDragAction actions,
|
||||
GdkDragAction *suggested_action,
|
||||
GdkDragAction *possible_actions)
|
||||
{
|
||||
*suggested_action = 0;
|
||||
*possible_actions = 0;
|
||||
|
||||
if ((button == GDK_BUTTON_MIDDLE || button == GDK_BUTTON_SECONDARY) && (actions & GDK_ACTION_ASK))
|
||||
{
|
||||
*suggested_action = GDK_ACTION_ASK;
|
||||
*possible_actions = actions;
|
||||
}
|
||||
else if (state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK))
|
||||
{
|
||||
if ((state & GDK_SHIFT_MASK) && (state & GDK_CONTROL_MASK))
|
||||
{
|
||||
if (actions & GDK_ACTION_LINK)
|
||||
{
|
||||
*suggested_action = GDK_ACTION_LINK;
|
||||
*possible_actions = GDK_ACTION_LINK;
|
||||
}
|
||||
}
|
||||
else if (state & GDK_CONTROL_MASK)
|
||||
{
|
||||
if (actions & GDK_ACTION_COPY)
|
||||
{
|
||||
*suggested_action = GDK_ACTION_COPY;
|
||||
*possible_actions = GDK_ACTION_COPY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (actions & GDK_ACTION_MOVE)
|
||||
{
|
||||
*suggested_action = GDK_ACTION_MOVE;
|
||||
*possible_actions = GDK_ACTION_MOVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*possible_actions = actions;
|
||||
|
||||
if ((state & (GDK_ALT_MASK)) && (actions & GDK_ACTION_ASK))
|
||||
*suggested_action = GDK_ACTION_ASK;
|
||||
else if (actions & GDK_ACTION_COPY)
|
||||
*suggested_action = GDK_ACTION_COPY;
|
||||
else if (actions & GDK_ACTION_MOVE)
|
||||
*suggested_action = GDK_ACTION_MOVE;
|
||||
else if (actions & GDK_ACTION_LINK)
|
||||
*suggested_action = GDK_ACTION_LINK;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_update (GdkDrag *drag,
|
||||
gdouble x_root,
|
||||
gdouble y_root,
|
||||
GdkModifierType mods,
|
||||
guint32 evtime)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
GdkDragAction suggested_action;
|
||||
GdkDragAction possible_actions;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
self->last_x = x_root;
|
||||
self->last_y = y_root;
|
||||
|
||||
gdk_drag_get_current_actions (mods,
|
||||
GDK_BUTTON_PRIMARY,
|
||||
gdk_drag_get_actions (drag),
|
||||
&suggested_action,
|
||||
&possible_actions);
|
||||
|
||||
_gdk_macos_drag_surface_drag_motion (self->drag_surface,
|
||||
x_root - self->hot_x,
|
||||
y_root - self->hot_y,
|
||||
suggested_action,
|
||||
possible_actions,
|
||||
evtime);
|
||||
|
||||
if (!self->did_update)
|
||||
{
|
||||
self->start_x = self->last_x;
|
||||
self->start_y = self->last_y;
|
||||
self->did_update = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_motion_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
double x, y;
|
||||
int x_root, y_root;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (drag));
|
||||
g_assert (event != NULL);
|
||||
|
||||
/* Ignore motion while doing zoomback */
|
||||
if (GDK_MACOS_DRAG (drag)->cancelled)
|
||||
return FALSE;
|
||||
|
||||
gdk_event_get_position (event, &x, &y);
|
||||
x_root = event->surface->x + x;
|
||||
y_root = event->surface->y + y;
|
||||
gdk_drag_update (drag, x_root, y_root,
|
||||
gdk_event_get_modifier_state (event),
|
||||
gdk_event_get_time (event));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_grab_broken_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
|
||||
gboolean is_implicit = gdk_grab_broken_event_get_implicit (event);
|
||||
GdkSurface *grab_surface = gdk_grab_broken_event_get_grab_surface (event);
|
||||
|
||||
/* Don't cancel if we break the implicit grab from the initial button_press. */
|
||||
if (is_implicit || grab_surface == (GdkSurface *)self->drag_surface)
|
||||
return FALSE;
|
||||
|
||||
if (gdk_event_get_device (event) != gdk_drag_get_device (drag))
|
||||
return FALSE;
|
||||
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_ERROR);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_button_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
g_assert (event != NULL);
|
||||
|
||||
#if 0
|
||||
/* FIXME: Check the button matches */
|
||||
if (event->button != self->button)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
if (gdk_drag_get_selected_action (drag) != 0)
|
||||
g_signal_emit_by_name (drag, "drop-performed");
|
||||
else
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_key_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
|
||||
GdkModifierType state;
|
||||
GdkDevice *pointer;
|
||||
gint dx, dy;
|
||||
|
||||
dx = dy = 0;
|
||||
state = gdk_event_get_modifier_state (event);
|
||||
pointer = gdk_device_get_associated_device (gdk_event_get_device (event));
|
||||
|
||||
if (event->event_type == GDK_KEY_PRESS)
|
||||
{
|
||||
guint keyval = gdk_key_event_get_keyval (event);
|
||||
|
||||
switch (keyval)
|
||||
{
|
||||
case GDK_KEY_Escape:
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_USER_CANCELLED);
|
||||
return TRUE;
|
||||
|
||||
case GDK_KEY_space:
|
||||
case GDK_KEY_Return:
|
||||
case GDK_KEY_ISO_Enter:
|
||||
case GDK_KEY_KP_Enter:
|
||||
case GDK_KEY_KP_Space:
|
||||
if (gdk_drag_get_selected_action (drag) != 0)
|
||||
g_signal_emit_by_name (drag, "drop-performed");
|
||||
else
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
|
||||
|
||||
return TRUE;
|
||||
|
||||
case GDK_KEY_Up:
|
||||
case GDK_KEY_KP_Up:
|
||||
dy = (state & GDK_ALT_MASK) ? -BIG_STEP : -SMALL_STEP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Down:
|
||||
case GDK_KEY_KP_Down:
|
||||
dy = (state & GDK_ALT_MASK) ? BIG_STEP : SMALL_STEP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Left:
|
||||
case GDK_KEY_KP_Left:
|
||||
dx = (state & GDK_ALT_MASK) ? -BIG_STEP : -SMALL_STEP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Right:
|
||||
case GDK_KEY_KP_Right:
|
||||
dx = (state & GDK_ALT_MASK) ? BIG_STEP : SMALL_STEP;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The state is not yet updated in the event, so we need
|
||||
* to query it here. We could use XGetModifierMapping, but
|
||||
* that would be overkill.
|
||||
*/
|
||||
_gdk_device_query_state (pointer, NULL, NULL, NULL, NULL, &state);
|
||||
|
||||
if (dx != 0 || dy != 0)
|
||||
{
|
||||
GdkDisplay *display = gdk_event_get_display ((GdkEvent *)event);
|
||||
|
||||
self->last_x += dx;
|
||||
self->last_y += dy;
|
||||
|
||||
_gdk_macos_display_warp_pointer (GDK_MACOS_DISPLAY (display),
|
||||
self->last_x,
|
||||
self->last_y);
|
||||
}
|
||||
|
||||
gdk_drag_update (drag,
|
||||
self->last_x, self->last_y,
|
||||
state,
|
||||
gdk_event_get_time (event));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_drag_handle_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_DRAG (drag));
|
||||
g_assert (event != NULL);
|
||||
|
||||
switch ((guint) event->event_type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
return gdk_dnd_handle_motion_event (drag, event);
|
||||
|
||||
case GDK_BUTTON_RELEASE:
|
||||
return gdk_dnd_handle_button_event (drag, event);
|
||||
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
return gdk_dnd_handle_key_event (drag, event);
|
||||
|
||||
case GDK_GRAB_BROKEN:
|
||||
return gdk_dnd_handle_grab_broken_event (drag, event);
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_finalize (GObject *object)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)object;
|
||||
GdkMacosDragSurface *drag_surface = g_steal_pointer (&self->drag_surface);
|
||||
|
||||
g_clear_object (&self->cursor);
|
||||
g_clear_object (&self->drag_seat);
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_drag_parent_class)->finalize (object);
|
||||
|
||||
if (drag_surface)
|
||||
gdk_surface_destroy (GDK_SURFACE (drag_surface));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DRAG_SURFACE:
|
||||
g_value_set_object (value, self->drag_surface);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DRAG_SURFACE:
|
||||
self->drag_surface = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_class_init (GdkMacosDragClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDragClass *drag_class = GDK_DRAG_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_macos_drag_finalize;
|
||||
object_class->get_property = gdk_macos_drag_get_property;
|
||||
object_class->set_property = gdk_macos_drag_set_property;
|
||||
|
||||
drag_class->get_drag_surface = gdk_macos_drag_get_drag_surface;
|
||||
drag_class->set_hotspot = gdk_macos_drag_set_hotspot;
|
||||
drag_class->drop_done = gdk_macos_drag_drop_done;
|
||||
drag_class->set_cursor = gdk_macos_drag_set_cursor;
|
||||
drag_class->cancel = gdk_macos_drag_cancel;
|
||||
drag_class->drop_performed = gdk_macos_drag_drop_performed;
|
||||
drag_class->handle_event = gdk_macos_drag_handle_event;
|
||||
|
||||
properties [PROP_DRAG_SURFACE] =
|
||||
g_param_spec_object ("drag-surface",
|
||||
P_("Drag Surface"),
|
||||
P_("Drag Surface"),
|
||||
GDK_TYPE_MACOS_DRAG_SURFACE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_init (GdkMacosDrag *self)
|
||||
{
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_drag_begin (GdkMacosDrag *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DRAG (self), FALSE);
|
||||
|
||||
_gdk_macos_surface_show (GDK_MACOS_SURFACE (self->drag_surface));
|
||||
|
||||
return drag_grab (self);
|
||||
}
|
50
gdk/macos/gdkmacosdragsurface-private.h
Normal file
50
gdk/macos/gdkmacosdragsurface-private.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_DRAG_SURFACE_PRIVATE_H__
|
||||
#define __GDK_MACOS_DRAG_SURFACE_PRIVATE_H__
|
||||
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkMacosDragSurface GdkMacosDragSurface;
|
||||
typedef struct _GdkMacosDragSurfaceClass GdkMacosDragSurfaceClass;
|
||||
|
||||
#define GDK_TYPE_MACOS_DRAG_SURFACE (_gdk_macos_drag_surface_get_type())
|
||||
#define GDK_MACOS_DRAG_SURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_DRAG_SURFACE, GdkMacosDragSurface))
|
||||
#define GDK_IS_MACOS_DRAG_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DRAG_SURFACE))
|
||||
|
||||
GType _gdk_macos_drag_surface_get_type (void);
|
||||
GdkMacosSurface *_gdk_macos_drag_surface_new (GdkMacosDisplay *display,
|
||||
GdkFrameClock *frame_clock,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void _gdk_macos_drag_surface_drag_motion (GdkMacosDragSurface *self,
|
||||
int x_root,
|
||||
int y_root,
|
||||
GdkDragAction suggested_action,
|
||||
GdkDragAction possible_actions,
|
||||
guint32 evtime);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_DRAG_SURFACE_PRIVATE_H__ */
|
138
gdk/macos/gdkmacosdragsurface.c
Normal file
138
gdk/macos/gdkmacosdragsurface.c
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdragsurfaceprivate.h"
|
||||
|
||||
#include "gdkmacosdragsurface-private.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
|
||||
struct _GdkMacosDragSurface
|
||||
{
|
||||
GdkMacosSurface parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkMacosDragSurfaceClass
|
||||
{
|
||||
GdkMacosSurfaceClass parent_instance;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
_gdk_macos_drag_surface_present (GdkDragSurface *surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_SURFACE (surface));
|
||||
|
||||
_gdk_macos_surface_move_resize (GDK_MACOS_SURFACE (surface),
|
||||
-1, -1,
|
||||
width, height);
|
||||
|
||||
if (!GDK_SURFACE_IS_MAPPED (GDK_SURFACE (surface)))
|
||||
_gdk_macos_surface_show (GDK_MACOS_SURFACE (surface));
|
||||
|
||||
return GDK_SURFACE_IS_MAPPED (GDK_SURFACE (surface));
|
||||
}
|
||||
|
||||
static void
|
||||
drag_surface_iface_init (GdkDragSurfaceInterface *iface)
|
||||
{
|
||||
iface->present = _gdk_macos_drag_surface_present;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GdkMacosDragSurface, _gdk_macos_drag_surface, GDK_TYPE_MACOS_SURFACE,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_DRAG_SURFACE, drag_surface_iface_init))
|
||||
|
||||
static void
|
||||
_gdk_macos_drag_surface_class_init (GdkMacosDragSurfaceClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_drag_surface_init (GdkMacosDragSurface *self)
|
||||
{
|
||||
}
|
||||
|
||||
GdkMacosSurface *
|
||||
_gdk_macos_drag_surface_new (GdkMacosDisplay *display,
|
||||
GdkFrameClock *frame_clock,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkMacosWindow *window;
|
||||
GdkMacosSurface *self;
|
||||
NSScreen *screen;
|
||||
NSUInteger style_mask;
|
||||
NSRect content_rect;
|
||||
NSRect screen_rect;
|
||||
int nx;
|
||||
int ny;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
g_return_val_if_fail (!frame_clock || GDK_IS_FRAME_CLOCK (frame_clock), NULL);
|
||||
|
||||
style_mask = NSWindowStyleMaskBorderless;
|
||||
|
||||
_gdk_macos_display_to_display_coords (display, x, y, &nx, &ny);
|
||||
|
||||
screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
|
||||
screen_rect = [screen frame];
|
||||
nx -= screen_rect.origin.x;
|
||||
ny -= screen_rect.origin.y;
|
||||
content_rect = NSMakeRect (nx, ny - height, width, height);
|
||||
|
||||
window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
|
||||
styleMask:style_mask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO
|
||||
screen:screen];
|
||||
|
||||
[window setOpaque:NO];
|
||||
[window setBackgroundColor:[NSColor clearColor]];
|
||||
[window setDecorated:NO];
|
||||
|
||||
self = g_object_new (GDK_TYPE_MACOS_DRAG_SURFACE,
|
||||
"display", display,
|
||||
"frame-clock", frame_clock,
|
||||
"native", window,
|
||||
NULL);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&self);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_drag_surface_drag_motion (GdkMacosDragSurface *self,
|
||||
int x_root,
|
||||
int y_root,
|
||||
GdkDragAction suggested_action,
|
||||
GdkDragAction possible_actions,
|
||||
guint32 evtime)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DRAG_SURFACE (self));
|
||||
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self), x_root, y_root);
|
||||
}
|
40
gdk/macos/gdkmacoseventsource-private.h
Normal file
40
gdk/macos/gdkmacoseventsource-private.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_EVENT_SOURCE_PRIVATE_H__
|
||||
#define __GDK_MACOS_EVENT_SOURCE_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP,
|
||||
} GdkMacosEventSubType;
|
||||
|
||||
GSource *_gdk_macos_event_source_new (GdkMacosDisplay *display);
|
||||
NSEvent *_gdk_macos_event_source_get_pending (void);
|
||||
gboolean _gdk_macos_event_source_check_pending (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_EVENT_SOURCE_PRIVATE_H__ */
|
@ -1,3 +1,23 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
@ -6,10 +26,13 @@
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gdkprivate-quartz.h"
|
||||
#include <gdk/gdkdisplayprivate.h>
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
/*
|
||||
#include "gdkmacoseventsource-private.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
|
||||
/*
|
||||
* This file implementations integration between the GLib main loop and
|
||||
* the native system of the Core Foundation run loop and Cocoa event
|
||||
* handling. There are basically two different cases that we need to
|
||||
@ -55,16 +78,16 @@ static int current_loop_level = 0;
|
||||
/* Run loop level at which we acquired ownership of the GLib main
|
||||
* loop. See note in run_loop_entry(). -1 means that we don’t have
|
||||
* ownership
|
||||
*/
|
||||
*/
|
||||
static int acquired_loop_level = -1;
|
||||
|
||||
/* Between run_loop_before_waiting() and run_loop_after_waiting();
|
||||
* whether we need to call select_thread_collect_poll()
|
||||
* whether we we need to call select_thread_collect_poll()
|
||||
*/
|
||||
static gboolean run_loop_polling_async = FALSE;
|
||||
|
||||
/* Between run_loop_before_waiting() and run_loop_after_waiting();
|
||||
* max_priority to pass to g_main_loop_check()
|
||||
* max_prioritiy to pass to g_main_loop_check()
|
||||
*/
|
||||
static gint run_loop_max_priority;
|
||||
|
||||
@ -95,7 +118,7 @@ static GPollFD event_poll_fd;
|
||||
|
||||
/* Current NSEvents that we've gotten from Cocoa but haven't yet converted
|
||||
* to GdkEvents. We wait until our dispatch() function to do the conversion
|
||||
* since the conversion can conceivably cause signals to be emitted
|
||||
* since the conversion can conceivably cause signals to be emmitted
|
||||
* or other things that shouldn’t happen inside a poll function.
|
||||
*/
|
||||
static GQueue *current_events;
|
||||
@ -132,7 +155,7 @@ static gint getting_events = 0;
|
||||
************************************************************/
|
||||
|
||||
/* The states in our state machine, see comments in select_thread_func()
|
||||
* for descriptions of each state
|
||||
* for descriptiions of each state
|
||||
*/
|
||||
typedef enum {
|
||||
BEFORE_START,
|
||||
@ -220,93 +243,93 @@ static void *
|
||||
select_thread_func (void *arg)
|
||||
{
|
||||
char c;
|
||||
|
||||
|
||||
SELECT_THREAD_LOCK ();
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
switch (select_thread_state)
|
||||
{
|
||||
case BEFORE_START:
|
||||
/* The select thread has not been started yet
|
||||
*/
|
||||
g_assert_not_reached ();
|
||||
|
||||
case WAITING:
|
||||
/* Waiting for a set of file descriptors to be submitted by the main thread
|
||||
*
|
||||
* => POLLING_QUEUED: main thread submits a set of file descriptors
|
||||
*/
|
||||
SELECT_THREAD_WAIT ();
|
||||
break;
|
||||
|
||||
case POLLING_QUEUED:
|
||||
/* Waiting for a set of file descriptors to be submitted by the main thread
|
||||
*
|
||||
* => POLLING_DESCRIPTORS: select thread picks up the file descriptors to begin polling
|
||||
*/
|
||||
g_free (current_pollfds);
|
||||
|
||||
current_pollfds = next_pollfds;
|
||||
current_n_pollfds = next_n_pollfds;
|
||||
{
|
||||
case BEFORE_START:
|
||||
/* The select thread has not been started yet
|
||||
*/
|
||||
g_assert_not_reached ();
|
||||
|
||||
next_pollfds = NULL;
|
||||
next_n_pollfds = 0;
|
||||
case WAITING:
|
||||
/* Waiting for a set of file descriptors to be submitted by the main thread
|
||||
*
|
||||
* => POLLING_QUEUED: main thread thread submits a set of file descriptors
|
||||
*/
|
||||
SELECT_THREAD_WAIT ();
|
||||
break;
|
||||
|
||||
select_thread_set_state (POLLING_DESCRIPTORS);
|
||||
break;
|
||||
|
||||
case POLLING_RESTART:
|
||||
/* Select thread is currently polling a set of file descriptors, main thread has
|
||||
* began a new iteration with the same set of file descriptors. We don't want to
|
||||
* wake the select thread up and wait for it to restart immediately, but to avoid
|
||||
* a race (described below in select_thread_start_polling()) we need to recheck after
|
||||
* polling completes.
|
||||
*
|
||||
* => POLLING_DESCRIPTORS: select completes, main thread rechecks by polling again
|
||||
* => POLLING_QUEUED: main thread submits a new set of file descriptors to be polled
|
||||
*/
|
||||
select_thread_set_state (POLLING_DESCRIPTORS);
|
||||
break;
|
||||
case POLLING_QUEUED:
|
||||
/* Waiting for a set of file descriptors to be submitted by the main thread
|
||||
*
|
||||
* => POLLING_DESCRIPTORS: select thread picks up the file descriptors to begin polling
|
||||
*/
|
||||
g_free (current_pollfds);
|
||||
|
||||
case POLLING_DESCRIPTORS:
|
||||
/* In the process of polling the file descriptors
|
||||
*
|
||||
* => WAITING: polling completes when a file descriptor becomes active
|
||||
* => POLLING_QUEUED: main thread submits a new set of file descriptors to be polled
|
||||
* => POLLING_RESTART: main thread begins a new iteration with the same set file descriptors
|
||||
*/
|
||||
SELECT_THREAD_UNLOCK ();
|
||||
old_poll_func (current_pollfds, current_n_pollfds, -1);
|
||||
SELECT_THREAD_LOCK ();
|
||||
current_pollfds = next_pollfds;
|
||||
current_n_pollfds = next_n_pollfds;
|
||||
|
||||
read (select_thread_wakeup_pipe[0], &c, 1);
|
||||
next_pollfds = NULL;
|
||||
next_n_pollfds = 0;
|
||||
|
||||
if (select_thread_state == POLLING_DESCRIPTORS)
|
||||
{
|
||||
signal_main_thread ();
|
||||
select_thread_set_state (WAITING);
|
||||
}
|
||||
break;
|
||||
}
|
||||
select_thread_set_state (POLLING_DESCRIPTORS);
|
||||
break;
|
||||
|
||||
case POLLING_RESTART:
|
||||
/* Select thread is currently polling a set of file descriptors, main thread has
|
||||
* began a new iteration with the same set of file descriptors. We don't want to
|
||||
* wake the select thread up and wait for it to restart immediately, but to avoid
|
||||
* a race (described below in select_thread_start_polling()) we need to recheck after
|
||||
* polling completes.
|
||||
*
|
||||
* => POLLING_DESCRIPTORS: select completes, main thread rechecks by polling again
|
||||
* => POLLING_QUEUED: main thread submits a new set of file descriptors to be polled
|
||||
*/
|
||||
select_thread_set_state (POLLING_DESCRIPTORS);
|
||||
break;
|
||||
|
||||
case POLLING_DESCRIPTORS:
|
||||
/* In the process of polling the file descriptors
|
||||
*
|
||||
* => WAITING: polling completes when a file descriptor becomes active
|
||||
* => POLLING_QUEUED: main thread submits a new set of file descriptors to be polled
|
||||
* => POLLING_RESTART: main thread begins a new iteration with the same set file descriptors
|
||||
*/
|
||||
SELECT_THREAD_UNLOCK ();
|
||||
old_poll_func (current_pollfds, current_n_pollfds, -1);
|
||||
SELECT_THREAD_LOCK ();
|
||||
|
||||
read (select_thread_wakeup_pipe[0], &c, 1);
|
||||
|
||||
if (select_thread_state == POLLING_DESCRIPTORS)
|
||||
{
|
||||
signal_main_thread ();
|
||||
select_thread_set_state (WAITING);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
got_fd_activity (void *info)
|
||||
{
|
||||
NSEvent *event;
|
||||
|
||||
/* Post a message so we'll break out of the message loop */
|
||||
event = [NSEvent otherEventWithType: NSApplicationDefined
|
||||
location: NSZeroPoint
|
||||
modifierFlags: 0
|
||||
timestamp: 0
|
||||
windowNumber: 0
|
||||
context: nil
|
||||
subtype: GDK_QUARTZ_EVENT_SUBTYPE_EVENTLOOP
|
||||
data1: 0
|
||||
data2: 0];
|
||||
event = [NSEvent otherEventWithType: NSEventTypeApplicationDefined
|
||||
location: NSZeroPoint
|
||||
modifierFlags: 0
|
||||
timestamp: 0
|
||||
windowNumber: 0
|
||||
context: nil
|
||||
subtype: GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP
|
||||
data1: 0
|
||||
data2: 0];
|
||||
|
||||
[NSApp postEvent:event atStart:YES];
|
||||
}
|
||||
@ -315,21 +338,21 @@ static void
|
||||
select_thread_start (void)
|
||||
{
|
||||
g_return_if_fail (select_thread_state == BEFORE_START);
|
||||
|
||||
|
||||
pipe (select_thread_wakeup_pipe);
|
||||
fcntl (select_thread_wakeup_pipe[0], F_SETFL, O_NONBLOCK);
|
||||
|
||||
CFRunLoopSourceContext source_context = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, got_fd_activity };
|
||||
select_main_thread_source = CFRunLoopSourceCreate (NULL, 0, &source_context);
|
||||
|
||||
|
||||
CFRunLoopAddSource (main_thread_run_loop, select_main_thread_source, kCFRunLoopCommonModes);
|
||||
|
||||
select_thread_state = WAITING;
|
||||
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (pthread_create (&select_thread, NULL, select_thread_func, NULL) == 0)
|
||||
break;
|
||||
break;
|
||||
|
||||
g_warning ("Failed to create select thread, sleeping and trying again");
|
||||
sleep (1);
|
||||
@ -339,7 +362,7 @@ select_thread_start (void)
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static void
|
||||
dump_poll_result (GPollFD *ufds,
|
||||
guint nfds)
|
||||
guint nfds)
|
||||
{
|
||||
GString *s;
|
||||
gint i;
|
||||
@ -348,44 +371,44 @@ dump_poll_result (GPollFD *ufds,
|
||||
for (i = 0; i < nfds; i++)
|
||||
{
|
||||
if (ufds[i].fd >= 0 && ufds[i].revents)
|
||||
{
|
||||
{
|
||||
g_string_append_printf (s, " %d:", ufds[i].fd);
|
||||
if (ufds[i].revents & G_IO_IN)
|
||||
if (ufds[i].revents & G_IO_IN)
|
||||
g_string_append (s, " in");
|
||||
if (ufds[i].revents & G_IO_OUT)
|
||||
g_string_append (s, " out");
|
||||
if (ufds[i].revents & G_IO_PRI)
|
||||
g_string_append (s, " pri");
|
||||
g_string_append (s, "\n");
|
||||
}
|
||||
if (ufds[i].revents & G_IO_OUT)
|
||||
g_string_append (s, " out");
|
||||
if (ufds[i].revents & G_IO_PRI)
|
||||
g_string_append (s, " pri");
|
||||
g_string_append (s, "\n");
|
||||
}
|
||||
}
|
||||
g_message ("%s", s->str);
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
gboolean
|
||||
static gboolean
|
||||
pollfds_equal (GPollFD *old_pollfds,
|
||||
guint old_n_pollfds,
|
||||
GPollFD *new_pollfds,
|
||||
guint new_n_pollfds)
|
||||
guint old_n_pollfds,
|
||||
GPollFD *new_pollfds,
|
||||
guint new_n_pollfds)
|
||||
{
|
||||
gint i;
|
||||
|
||||
|
||||
if (old_n_pollfds != new_n_pollfds)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < old_n_pollfds; i++)
|
||||
{
|
||||
if (old_pollfds[i].fd != new_pollfds[i].fd ||
|
||||
old_pollfds[i].events != new_pollfds[i].events)
|
||||
return FALSE;
|
||||
old_pollfds[i].events != new_pollfds[i].events)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Begins a polling operation with the specified GPollFD array; the
|
||||
/* Begins a polling operation with the specified GPollFD array; the
|
||||
* timeout is used only to tell if the polling operation is blocking
|
||||
* or non-blocking.
|
||||
*
|
||||
@ -396,7 +419,8 @@ pollfds_equal (GPollFD *old_pollfds,
|
||||
*/
|
||||
static gint
|
||||
select_thread_start_poll (GPollFD *ufds,
|
||||
guint nfds, gint timeout)
|
||||
guint nfds,
|
||||
gint timeout)
|
||||
{
|
||||
gint n_ready;
|
||||
gboolean have_new_pollfds = FALSE;
|
||||
@ -406,10 +430,10 @@ select_thread_start_poll (GPollFD *ufds,
|
||||
for (i = 0; i < nfds; i++)
|
||||
if (ufds[i].fd == -1)
|
||||
{
|
||||
poll_fd_index = i;
|
||||
break;
|
||||
poll_fd_index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (nfds == 0 ||
|
||||
(nfds == 1 && poll_fd_index >= 0))
|
||||
{
|
||||
@ -431,35 +455,35 @@ select_thread_start_poll (GPollFD *ufds,
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if ((_gdk_debug_flags & GDK_DEBUG_EVENTLOOP) && n_ready > 0)
|
||||
{
|
||||
g_message ("EventLoop: Found ready file descriptors before waiting");
|
||||
dump_poll_result (ufds, nfds);
|
||||
}
|
||||
{
|
||||
g_message ("EventLoop: Found ready file descriptors before waiting");
|
||||
dump_poll_result (ufds, nfds);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return n_ready;
|
||||
}
|
||||
|
||||
|
||||
SELECT_THREAD_LOCK ();
|
||||
|
||||
if (select_thread_state == BEFORE_START)
|
||||
{
|
||||
select_thread_start ();
|
||||
}
|
||||
|
||||
|
||||
if (select_thread_state == POLLING_QUEUED)
|
||||
{
|
||||
/* If the select thread hasn't picked up the set of file descriptors yet
|
||||
* then we can simply replace an old stale set with a new set.
|
||||
*/
|
||||
if (!pollfds_equal (ufds, nfds, next_pollfds, next_n_pollfds - 1))
|
||||
{
|
||||
g_free (next_pollfds);
|
||||
next_pollfds = NULL;
|
||||
next_n_pollfds = 0;
|
||||
|
||||
have_new_pollfds = TRUE;
|
||||
}
|
||||
{
|
||||
g_free (next_pollfds);
|
||||
next_pollfds = NULL;
|
||||
next_n_pollfds = 0;
|
||||
|
||||
have_new_pollfds = TRUE;
|
||||
}
|
||||
}
|
||||
else if (select_thread_state == POLLING_RESTART || select_thread_state == POLLING_DESCRIPTORS)
|
||||
{
|
||||
@ -481,7 +505,7 @@ select_thread_start_poll (GPollFD *ufds,
|
||||
* Marks polling as complete
|
||||
* Wakes main thread
|
||||
* Receives old stale file descriptor state
|
||||
*
|
||||
*
|
||||
* To avoid this, when the new set of poll descriptors is the same as the current
|
||||
* one, we transition to the POLLING_RESTART stage at the point marked (*). When
|
||||
* the select thread wakes up from the poll because a file descriptor is active, if
|
||||
@ -498,13 +522,13 @@ select_thread_start_poll (GPollFD *ufds,
|
||||
* from a file descriptor that hangs.
|
||||
*/
|
||||
if (!pollfds_equal (ufds, nfds, current_pollfds, current_n_pollfds - 1))
|
||||
have_new_pollfds = TRUE;
|
||||
have_new_pollfds = TRUE;
|
||||
else
|
||||
{
|
||||
if (!((nfds == 1 && poll_fd_index < 0 && g_thread_supported ()) ||
|
||||
(nfds == 2 && poll_fd_index >= 0 && g_thread_supported ())))
|
||||
select_thread_set_state (POLLING_RESTART);
|
||||
}
|
||||
{
|
||||
if (!((nfds == 1 && poll_fd_index < 0 && g_thread_supported ()) ||
|
||||
(nfds == 2 && poll_fd_index >= 0 && g_thread_supported ())))
|
||||
select_thread_set_state (POLLING_RESTART);
|
||||
}
|
||||
}
|
||||
else
|
||||
have_new_pollfds = TRUE;
|
||||
@ -512,28 +536,28 @@ select_thread_start_poll (GPollFD *ufds,
|
||||
if (have_new_pollfds)
|
||||
{
|
||||
GDK_NOTE (EVENTLOOP, g_message ("EventLoop: Submitting a new set of file descriptor to the select thread"));
|
||||
|
||||
|
||||
g_assert (next_pollfds == NULL);
|
||||
|
||||
|
||||
next_n_pollfds = nfds + 1;
|
||||
next_pollfds = g_new (GPollFD, nfds + 1);
|
||||
memcpy (next_pollfds, ufds, nfds * sizeof (GPollFD));
|
||||
|
||||
|
||||
next_pollfds[nfds].fd = select_thread_wakeup_pipe[0];
|
||||
next_pollfds[nfds].events = G_IO_IN;
|
||||
|
||||
|
||||
if (select_thread_state != POLLING_QUEUED && select_thread_state != WAITING)
|
||||
{
|
||||
if (select_thread_wakeup_pipe[1])
|
||||
{
|
||||
char c = 'A';
|
||||
write (select_thread_wakeup_pipe[1], &c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (select_thread_wakeup_pipe[1])
|
||||
{
|
||||
char c = 'A';
|
||||
write (select_thread_wakeup_pipe[1], &c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
select_thread_set_state (POLLING_QUEUED);
|
||||
}
|
||||
|
||||
|
||||
SELECT_THREAD_UNLOCK ();
|
||||
|
||||
return -1;
|
||||
@ -553,32 +577,32 @@ select_thread_collect_poll (GPollFD *ufds, guint nfds)
|
||||
{
|
||||
gint i;
|
||||
gint n_ready = 0;
|
||||
|
||||
|
||||
SELECT_THREAD_LOCK ();
|
||||
|
||||
if (select_thread_state == WAITING) /* The poll completed */
|
||||
{
|
||||
for (i = 0; i < nfds; i++)
|
||||
{
|
||||
if (ufds[i].fd == -1)
|
||||
continue;
|
||||
|
||||
g_assert (ufds[i].fd == current_pollfds[i].fd);
|
||||
g_assert (ufds[i].events == current_pollfds[i].events);
|
||||
{
|
||||
if (ufds[i].fd == -1)
|
||||
continue;
|
||||
|
||||
g_assert (ufds[i].fd == current_pollfds[i].fd);
|
||||
g_assert (ufds[i].events == current_pollfds[i].events);
|
||||
|
||||
if (current_pollfds[i].revents)
|
||||
{
|
||||
ufds[i].revents = current_pollfds[i].revents;
|
||||
n_ready++;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_pollfds[i].revents)
|
||||
{
|
||||
ufds[i].revents = current_pollfds[i].revents;
|
||||
n_ready++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (_gdk_debug_flags & GDK_DEBUG_EVENTLOOP)
|
||||
{
|
||||
g_message ("EventLoop: Found ready file descriptors after waiting");
|
||||
dump_poll_result (ufds, nfds);
|
||||
}
|
||||
{
|
||||
g_message ("EventLoop: Found ready file descriptors after waiting");
|
||||
dump_poll_result (ufds, nfds);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -591,14 +615,20 @@ select_thread_collect_poll (GPollFD *ufds, guint nfds)
|
||||
********* Main Loop Source *********
|
||||
************************************************************/
|
||||
|
||||
typedef struct _GdkMacosEventSource
|
||||
{
|
||||
GSource source;
|
||||
GdkDisplay *display;
|
||||
} GdkMacosEventSource;
|
||||
|
||||
gboolean
|
||||
_gdk_quartz_event_loop_check_pending (void)
|
||||
_gdk_macos_event_source_check_pending (void)
|
||||
{
|
||||
return current_events && current_events->head;
|
||||
}
|
||||
|
||||
NSEvent*
|
||||
_gdk_quartz_event_loop_get_pending (void)
|
||||
NSEvent *
|
||||
_gdk_macos_event_source_get_pending (void)
|
||||
{
|
||||
NSEvent *event = NULL;
|
||||
|
||||
@ -608,16 +638,11 @@ _gdk_quartz_event_loop_get_pending (void)
|
||||
return event;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_quartz_event_loop_release_event (NSEvent *event)
|
||||
{
|
||||
[event release];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_event_prepare (GSource *source,
|
||||
gint *timeout)
|
||||
gdk_macos_event_source_prepare (GSource *source,
|
||||
gint *timeout)
|
||||
{
|
||||
GdkMacosEventSource *event_source = (GdkMacosEventSource *)source;
|
||||
gboolean retval;
|
||||
|
||||
/* The prepare stage is the stage before the main loop starts polling
|
||||
@ -647,55 +672,65 @@ gdk_event_prepare (GSource *source,
|
||||
|
||||
*timeout = -1;
|
||||
|
||||
if (_gdk_display->event_pause_count > 0)
|
||||
retval = _gdk_event_queue_find_first (_gdk_display) != NULL;
|
||||
if (event_source->display->event_pause_count > 0)
|
||||
retval = _gdk_event_queue_find_first (event_source->display) != NULL;
|
||||
else
|
||||
retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
|
||||
_gdk_quartz_event_loop_check_pending ());
|
||||
retval = (_gdk_event_queue_find_first (event_source->display) != NULL ||
|
||||
_gdk_macos_event_source_check_pending ());
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_event_check (GSource *source)
|
||||
gdk_macos_event_source_check (GSource *source)
|
||||
{
|
||||
GdkMacosEventSource *event_source = (GdkMacosEventSource *)source;
|
||||
gboolean retval;
|
||||
|
||||
if (_gdk_display->event_pause_count > 0)
|
||||
retval = _gdk_event_queue_find_first (_gdk_display) != NULL;
|
||||
if (event_source->display->event_pause_count > 0)
|
||||
retval = _gdk_event_queue_find_first (event_source->display) != NULL;
|
||||
else
|
||||
retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
|
||||
_gdk_quartz_event_loop_check_pending ());
|
||||
retval = (_gdk_event_queue_find_first (event_source->display) != NULL ||
|
||||
_gdk_macos_event_source_check_pending ());
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_event_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
gdk_macos_event_source_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkMacosEventSource *event_source = (GdkMacosEventSource *)source;
|
||||
GdkEvent *event;
|
||||
|
||||
_gdk_quartz_display_queue_events (_gdk_display);
|
||||
_gdk_macos_display_queue_events (GDK_MACOS_DISPLAY (event_source->display));
|
||||
|
||||
event = _gdk_event_unqueue (_gdk_display);
|
||||
event = _gdk_event_unqueue (event_source->display);
|
||||
|
||||
if (event)
|
||||
{
|
||||
_gdk_event_emit (event);
|
||||
|
||||
g_object_unref (event);
|
||||
gdk_event_unref (event);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_event_source_finalize (GSource *source)
|
||||
{
|
||||
GdkMacosEventSource *event_source = (GdkMacosEventSource *)source;
|
||||
|
||||
g_clear_object (&event_source->display);
|
||||
}
|
||||
|
||||
static GSourceFuncs event_funcs = {
|
||||
gdk_event_prepare,
|
||||
gdk_event_check,
|
||||
gdk_event_dispatch,
|
||||
NULL
|
||||
gdk_macos_event_source_prepare,
|
||||
gdk_macos_event_source_check,
|
||||
gdk_macos_event_source_dispatch,
|
||||
gdk_macos_event_source_finalize,
|
||||
};
|
||||
|
||||
/************************************************************
|
||||
@ -704,8 +739,8 @@ static GSourceFuncs event_funcs = {
|
||||
|
||||
static gint
|
||||
poll_func (GPollFD *ufds,
|
||||
guint nfds,
|
||||
gint timeout_)
|
||||
guint nfds,
|
||||
gint timeout_)
|
||||
{
|
||||
NSEvent *event;
|
||||
NSDate *limit_date;
|
||||
@ -727,9 +762,9 @@ poll_func (GPollFD *ufds,
|
||||
limit_date = [NSDate dateWithTimeIntervalSinceNow:timeout_/1000.0];
|
||||
|
||||
getting_events++;
|
||||
event = [NSApp nextEventMatchingMask: NSAnyEventMask
|
||||
untilDate: limit_date
|
||||
inMode: NSDefaultRunLoopMode
|
||||
event = [NSApp nextEventMatchingMask: NSEventMaskAny
|
||||
untilDate: limit_date
|
||||
inMode: NSDefaultRunLoopMode
|
||||
dequeue: YES];
|
||||
getting_events--;
|
||||
|
||||
@ -744,10 +779,10 @@ poll_func (GPollFD *ufds,
|
||||
*/
|
||||
if (last_ufds == ufds && n_ready < 0)
|
||||
n_ready = select_thread_collect_poll (ufds, nfds);
|
||||
|
||||
|
||||
if (event &&
|
||||
[event type] == NSApplicationDefined &&
|
||||
[event subtype] == GDK_QUARTZ_EVENT_SUBTYPE_EVENTLOOP)
|
||||
[event type] == NSEventTypeApplicationDefined &&
|
||||
[event subtype] == GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP)
|
||||
{
|
||||
/* Just used to wake us up; if an event and a FD arrived at the same
|
||||
* time; could have come from a previous iteration in some cases,
|
||||
@ -756,7 +791,7 @@ poll_func (GPollFD *ufds,
|
||||
event = NULL;
|
||||
}
|
||||
|
||||
if (event)
|
||||
if (event)
|
||||
{
|
||||
if (!current_events)
|
||||
current_events = g_queue_new ();
|
||||
@ -775,11 +810,11 @@ poll_func (GPollFD *ufds,
|
||||
*/
|
||||
static gint
|
||||
query_main_context (GMainContext *context,
|
||||
int max_priority,
|
||||
int *timeout)
|
||||
int max_priority,
|
||||
int *timeout)
|
||||
{
|
||||
gint nfds;
|
||||
|
||||
|
||||
if (!run_loop_pollfds)
|
||||
{
|
||||
run_loop_pollfds_size = RUN_LOOP_POLLFDS_INITIAL_SIZE;
|
||||
@ -787,8 +822,8 @@ query_main_context (GMainContext *context,
|
||||
}
|
||||
|
||||
while ((nfds = g_main_context_query (context, max_priority, timeout,
|
||||
run_loop_pollfds,
|
||||
run_loop_pollfds_size)) > run_loop_pollfds_size)
|
||||
run_loop_pollfds,
|
||||
run_loop_pollfds_size)) > run_loop_pollfds_size)
|
||||
{
|
||||
g_free (run_loop_pollfds);
|
||||
run_loop_pollfds_size = nfds;
|
||||
@ -804,24 +839,24 @@ run_loop_entry (void)
|
||||
if (acquired_loop_level == -1)
|
||||
{
|
||||
if (g_main_context_acquire (NULL))
|
||||
{
|
||||
GDK_NOTE (EVENTLOOP, g_message ("EventLoop: Beginning tracking run loop activity"));
|
||||
acquired_loop_level = current_loop_level;
|
||||
}
|
||||
{
|
||||
GDK_NOTE (EVENTLOOP, g_message ("EventLoop: Beginning tracking run loop activity"));
|
||||
acquired_loop_level = current_loop_level;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we fail to acquire the main context, that means someone is iterating
|
||||
* the main context in a different thread; we simply wait until this loop
|
||||
* exits and then try again at next entry. In general, iterating the loop
|
||||
* from a different thread is rare: it is only possible when GDK threading
|
||||
* is initialized and is not frequently used even then. So, we hope that
|
||||
* having GLib main loop iteration blocked in the combination of that and
|
||||
* a native modal operation is a minimal problem. We could imagine using a
|
||||
* thread that does g_main_context_wait() and then wakes us back up, but
|
||||
* the gain doesn't seem worth the complexity.
|
||||
*/
|
||||
GDK_NOTE (EVENTLOOP, g_message ("EventLoop: Can't acquire main loop; skipping tracking run loop activity"));
|
||||
}
|
||||
{
|
||||
/* If we fail to acquire the main context, that means someone is iterating
|
||||
* the main context in a different thread; we simply wait until this loop
|
||||
* exits and then try again at next entry. In general, iterating the loop
|
||||
* from a different thread is rare: it is only possible when GDK threading
|
||||
* is initialized and is not frequently used even then. So, we hope that
|
||||
* having GLib main loop iteration blocked in the combination of that and
|
||||
* a native modal operation is a minimal problem. We could imagine using a
|
||||
* thread that does g_main_context_wait() and then wakes us back up, but
|
||||
* the gain doesn't seem worth the complexity.
|
||||
*/
|
||||
GDK_NOTE (EVENTLOOP, g_message ("EventLoop: Can't acquire main loop; skipping tracking run loop activity"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -844,8 +879,8 @@ run_loop_before_sources (void)
|
||||
* sources are processed by the CFRunLoop, then processing will continue
|
||||
* on to the BeforeWaiting stage where we check for lower priority sources.
|
||||
*/
|
||||
|
||||
g_main_context_prepare (context, &max_priority);
|
||||
|
||||
g_main_context_prepare (context, &max_priority);
|
||||
max_priority = MIN (max_priority, G_PRIORITY_DEFAULT);
|
||||
|
||||
/* We ignore the timeout that query_main_context () returns since we'll
|
||||
@ -855,7 +890,7 @@ run_loop_before_sources (void)
|
||||
|
||||
if (nfds)
|
||||
old_poll_func (run_loop_pollfds, nfds, 0);
|
||||
|
||||
|
||||
if (g_main_context_check (context, max_priority, run_loop_pollfds, nfds))
|
||||
{
|
||||
GDK_NOTE (EVENTLOOP, g_message ("EventLoop: Dispatching high priority sources"));
|
||||
@ -865,7 +900,7 @@ run_loop_before_sources (void)
|
||||
|
||||
static void
|
||||
dummy_timer_callback (CFRunLoopTimerRef timer,
|
||||
void *info)
|
||||
void *info)
|
||||
{
|
||||
/* Nothing; won't normally even be called */
|
||||
}
|
||||
@ -883,9 +918,9 @@ run_loop_before_waiting (void)
|
||||
* go ahead and sleep. Before doing that, if there was a timeout from
|
||||
* GLib, we set up a CFRunLoopTimer to wake us up.
|
||||
*/
|
||||
|
||||
g_main_context_prepare (context, &run_loop_max_priority);
|
||||
|
||||
|
||||
g_main_context_prepare (context, &run_loop_max_priority);
|
||||
|
||||
run_loop_n_pollfds = query_main_context (context, run_loop_max_priority, &timeout);
|
||||
|
||||
n_ready = select_thread_start_poll (run_loop_pollfds, run_loop_n_pollfds, timeout);
|
||||
@ -902,18 +937,18 @@ run_loop_before_waiting (void)
|
||||
* after the wait wakes up.
|
||||
*/
|
||||
GDK_NOTE (EVENTLOOP, g_message ("EventLoop: Adding timer to wake us up in %d milliseconds", timeout));
|
||||
|
||||
|
||||
run_loop_timer = CFRunLoopTimerCreate (NULL, /* allocator */
|
||||
CFAbsoluteTimeGetCurrent () + timeout / 1000.,
|
||||
0, /* interval (0=does not repeat) */
|
||||
0, /* flags */
|
||||
0, /* order (priority) */
|
||||
dummy_timer_callback,
|
||||
NULL);
|
||||
CFAbsoluteTimeGetCurrent () + timeout / 1000.,
|
||||
0, /* interval (0=does not repeat) */
|
||||
0, /* flags */
|
||||
0, /* order (priority) */
|
||||
dummy_timer_callback,
|
||||
NULL);
|
||||
|
||||
CFRunLoopAddTimer (main_thread_run_loop, run_loop_timer, kCFRunLoopCommonModes);
|
||||
}
|
||||
|
||||
|
||||
run_loop_polling_async = n_ready < 0;
|
||||
}
|
||||
|
||||
@ -932,13 +967,13 @@ run_loop_after_waiting (void)
|
||||
CFRelease (run_loop_timer);
|
||||
run_loop_timer = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (run_loop_polling_async)
|
||||
{
|
||||
select_thread_collect_poll (run_loop_pollfds, run_loop_n_pollfds);
|
||||
run_loop_polling_async = FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (g_main_context_check (context, run_loop_max_priority, run_loop_pollfds, run_loop_n_pollfds))
|
||||
{
|
||||
GDK_NOTE (EVENTLOOP, g_message ("EventLoop: Dispatching after waiting"));
|
||||
@ -960,8 +995,8 @@ run_loop_exit (void)
|
||||
|
||||
static void
|
||||
run_loop_observer_callback (CFRunLoopObserverRef observer,
|
||||
CFRunLoopActivity activity,
|
||||
void *info)
|
||||
CFRunLoopActivity activity,
|
||||
void *info)
|
||||
{
|
||||
switch (activity)
|
||||
{
|
||||
@ -972,6 +1007,11 @@ run_loop_observer_callback (CFRunLoopObserverRef observer,
|
||||
g_return_if_fail (current_loop_level > 0);
|
||||
current_loop_level--;
|
||||
break;
|
||||
case kCFRunLoopBeforeTimers:
|
||||
case kCFRunLoopBeforeSources:
|
||||
case kCFRunLoopBeforeWaiting:
|
||||
case kCFRunLoopAfterWaiting:
|
||||
case kCFRunLoopAllActivities:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -999,6 +1039,8 @@ run_loop_observer_callback (CFRunLoopObserverRef observer,
|
||||
case kCFRunLoopExit:
|
||||
run_loop_exit ();
|
||||
break;
|
||||
case kCFRunLoopAllActivities:
|
||||
/* TODO: Do most of the above? */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1006,41 +1048,47 @@ run_loop_observer_callback (CFRunLoopObserverRef observer,
|
||||
|
||||
/************************************************************/
|
||||
|
||||
void
|
||||
_gdk_quartz_event_loop_init (void)
|
||||
GSource *
|
||||
_gdk_macos_event_source_new (GdkMacosDisplay *display)
|
||||
{
|
||||
GSource *source;
|
||||
CFRunLoopObserverRef observer;
|
||||
GdkMacosEventSource *event_source;
|
||||
GSource *source;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
|
||||
/* Hook into the GLib main loop */
|
||||
|
||||
event_poll_fd.events = G_IO_IN;
|
||||
event_poll_fd.fd = -1;
|
||||
|
||||
source = g_source_new (&event_funcs, sizeof (GSource));
|
||||
g_source_set_name (source, "GDK Quartz event source");
|
||||
source = g_source_new (&event_funcs, sizeof (GdkMacosEventSource));
|
||||
g_source_set_name (source, "GDK Quartz event source");
|
||||
g_source_add_poll (source, &event_poll_fd);
|
||||
g_source_set_priority (source, GDK_PRIORITY_EVENTS);
|
||||
g_source_set_can_recurse (source, TRUE);
|
||||
g_source_attach (source, NULL);
|
||||
|
||||
old_poll_func = g_main_context_get_poll_func (NULL);
|
||||
g_main_context_set_poll_func (NULL, poll_func);
|
||||
|
||||
|
||||
event_source = (GdkMacosEventSource *)source;
|
||||
event_source->display = g_object_ref (GDK_DISPLAY (display));
|
||||
|
||||
/* Hook into the the CFRunLoop for the main thread */
|
||||
|
||||
main_thread_run_loop = CFRunLoopGetCurrent ();
|
||||
|
||||
observer = CFRunLoopObserverCreate (NULL, /* default allocator */
|
||||
kCFRunLoopAllActivities,
|
||||
true, /* repeats: not one-shot */
|
||||
0, /* order (priority) */
|
||||
run_loop_observer_callback,
|
||||
NULL);
|
||||
|
||||
CFRunLoopAddObserver (main_thread_run_loop, observer, kCFRunLoopCommonModes);
|
||||
|
||||
/* Initialize our autorelease pool */
|
||||
kCFRunLoopAllActivities,
|
||||
true, /* repeats: not one-shot */
|
||||
0, /* order (priority) */
|
||||
run_loop_observer_callback,
|
||||
NULL);
|
||||
|
||||
CFRunLoopAddObserver (main_thread_run_loop, observer, kCFRunLoopCommonModes);
|
||||
|
||||
/* Initialize our autorelease pool */
|
||||
autorelease_pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
return source;
|
||||
}
|
60
gdk/macos/gdkmacosglcontext-private.h
Normal file
60
gdk/macos/gdkmacosglcontext-private.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* gdkmacosglcontext-private.h
|
||||
*
|
||||
* Copyright (C) 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
|
||||
#define __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
|
||||
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
#include "gdkmacosglcontext.h"
|
||||
#include "gdkmacossurface.h"
|
||||
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#import <OpenGL/gl.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GdkMacosGLContext
|
||||
{
|
||||
GdkGLContext parent_instance;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
NSOpenGLContext *gl_context;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
gboolean is_attached;
|
||||
};
|
||||
|
||||
struct _GdkMacosGLContextClass
|
||||
{
|
||||
GdkGLContextClass parent_class;
|
||||
};
|
||||
|
||||
GdkGLContext *_gdk_macos_gl_context_new (GdkMacosSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
gboolean _gdk_macos_gl_context_make_current (GdkMacosGLContext *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_GL_CONTEXT_PRIVATE_H__ */
|
153
gdk/macos/gdkmacosglcontext.c
Normal file
153
gdk/macos/gdkmacosglcontext.c
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkmacosglcontext-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkintl.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosGLContext, gdk_macos_gl_context, GDK_TYPE_GL_CONTEXT)
|
||||
|
||||
static void
|
||||
gdk_macos_gl_context_end_frame (GdkDrawContext *context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
|
||||
|
||||
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
|
||||
|
||||
[self->gl_context flushBuffer];
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_gl_context_dispose (GObject *gobject)
|
||||
{
|
||||
GdkMacosGLContext *context_macos = GDK_MACOS_GL_CONTEXT (gobject);
|
||||
|
||||
if (context_macos->gl_context != NULL)
|
||||
{
|
||||
[context_macos->gl_context clearDrawable];
|
||||
[context_macos->gl_context release];
|
||||
context_macos->gl_context = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_gl_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_gl_context_class_init (GdkMacosGLContextClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gdk_macos_gl_context_dispose;
|
||||
|
||||
draw_context_class->end_frame = gdk_macos_gl_context_end_frame;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_gl_context_init (GdkMacosGLContext *self)
|
||||
{
|
||||
}
|
||||
|
||||
GdkGLContext *
|
||||
_gdk_macos_gl_context_new (GdkMacosSurface *surface,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
{
|
||||
static const NSOpenGLPixelFormatAttribute attrs[] = {
|
||||
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFAColorSize, 24,
|
||||
NSOpenGLPFAAlphaSize, 8,
|
||||
0
|
||||
};
|
||||
|
||||
NSOpenGLPixelFormat *format;
|
||||
GdkMacosGLContext *context = NULL;
|
||||
NSOpenGLContext *ctx;
|
||||
GdkDisplay *display;
|
||||
NSView *nsview;
|
||||
GLint sync_to_framerate = 1;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_SURFACE (surface), NULL);
|
||||
g_return_val_if_fail (!share || GDK_IS_MACOS_GL_CONTEXT (share), NULL);
|
||||
|
||||
display = gdk_surface_get_display (GDK_SURFACE (surface));
|
||||
|
||||
if (!(format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]))
|
||||
{
|
||||
g_set_error_literal (error,
|
||||
GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Unable to create a GL pixel format"));
|
||||
goto failure;
|
||||
}
|
||||
|
||||
ctx = [[NSOpenGLContext alloc] initWithFormat:format
|
||||
shareContext:share ? GDK_MACOS_GL_CONTEXT (share)->gl_context : nil];
|
||||
if (ctx == NULL)
|
||||
{
|
||||
g_set_error_literal (error,
|
||||
GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Unable to create a GL context"));
|
||||
goto failure;
|
||||
}
|
||||
|
||||
nsview = _gdk_macos_surface_get_view (surface);
|
||||
[nsview setWantsBestResolutionOpenGLSurface:YES];
|
||||
[ctx setValues:&sync_to_framerate forParameter:NSOpenGLCPSwapInterval];
|
||||
[ctx setView:nsview];
|
||||
|
||||
GDK_NOTE (OPENGL,
|
||||
g_print ("Created NSOpenGLContext[%p]\n", ctx));
|
||||
|
||||
context = g_object_new (GDK_TYPE_MACOS_GL_CONTEXT,
|
||||
"surface", surface,
|
||||
"shared-context", share,
|
||||
NULL);
|
||||
|
||||
context->gl_context = ctx;
|
||||
context->is_attached = attached;
|
||||
|
||||
failure:
|
||||
if (format != NULL)
|
||||
[format release];
|
||||
|
||||
return GDK_GL_CONTEXT (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_gl_context_make_current (GdkMacosGLContext *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
|
||||
|
||||
[self->gl_context makeCurrentContext];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
43
gdk/macos/gdkmacosglcontext.h
Normal file
43
gdk/macos/gdkmacosglcontext.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_GL_CONTEXT_H__
|
||||
#define __GDK_MACOS_GL_CONTEXT_H__
|
||||
|
||||
#if !defined (__GDKMACOS_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/macos/gdkmacos.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_MACOS_GL_CONTEXT (gdk_macos_gl_context_get_type ())
|
||||
#define GDK_MACOS_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_MACOS_GL_CONTEXT, GdkMacosGLContext))
|
||||
#define GDK_IS_MACOS_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_MACOS_GL_CONTEXT))
|
||||
|
||||
typedef struct _GdkMacosGLContext GdkMacosGLContext;
|
||||
typedef struct _GdkMacosGLContextClass GdkMacosGLContextClass;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_macos_gl_context_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_GL_CONTEXT_H__ */
|
36
gdk/macos/gdkmacoskeymap-private.h
Normal file
36
gdk/macos/gdkmacoskeymap-private.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_KEYMAP_PRIVATE_H__
|
||||
#define __GDK_MACOS_KEYMAP_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacoskeymap.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GdkMacosKeymap *_gdk_macos_keymap_new (GdkMacosDisplay *display);
|
||||
GdkEventType _gdk_macos_keymap_get_event_type (NSEvent *event);
|
||||
gboolean _gdk_macos_keymap_is_modifier (guint keycode);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_KEYMAP_PRIVATE_H__ */
|
698
gdk/macos/gdkmacoskeymap.c
Normal file
698
gdk/macos/gdkmacoskeymap.c
Normal file
@ -0,0 +1,698 @@
|
||||
/*
|
||||
* Copyright © 2000-2020 Red Hat, Inc.
|
||||
* Copyright © 2005 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
/* Some parts of this code come from quartzKeyboard.c,
|
||||
* from the Apple X11 Server.
|
||||
*
|
||||
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
|
||||
* HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above
|
||||
* copyright holders shall not be used in advertising or otherwise to
|
||||
* promote the sale, use or other dealings in this Software without
|
||||
* prior written authorization.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkkeysprivate.h"
|
||||
#include "gdkkeysyms.h"
|
||||
#include "gdkmacoskeymap-private.h"
|
||||
|
||||
struct _GdkMacosKeymap
|
||||
{
|
||||
GdkKeymap parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkMacosKeymapClass
|
||||
{
|
||||
GdkKeymapClass parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosKeymap, gdk_macos_keymap, GDK_TYPE_KEYMAP)
|
||||
|
||||
/* This is a table of all keyvals. Each keycode gets KEYVALS_PER_KEYCODE entries.
|
||||
* TThere is 1 keyval per modifier (Nothing, Shift, Alt, Shift+Alt);
|
||||
*/
|
||||
static guint *keyval_array = NULL;
|
||||
|
||||
#define NUM_KEYCODES 128
|
||||
#define KEYVALS_PER_KEYCODE 4
|
||||
#define GET_KEYVAL(keycode, group, level) \
|
||||
(keyval_array[(keycode * KEYVALS_PER_KEYCODE + group * 2 + level)])
|
||||
|
||||
const static struct {
|
||||
guint keycode;
|
||||
guint keyval;
|
||||
unsigned int modmask; /* So we can tell when a mod key is pressed/released */
|
||||
} modifier_keys[] = {
|
||||
{ 54, GDK_KEY_Meta_R, NSEventModifierFlagCommand },
|
||||
{ 55, GDK_KEY_Meta_L, NSEventModifierFlagCommand },
|
||||
{ 56, GDK_KEY_Shift_L, NSEventModifierFlagShift },
|
||||
{ 57, GDK_KEY_Caps_Lock, NSEventModifierFlagCapsLock },
|
||||
{ 58, GDK_KEY_Alt_L, NSEventModifierFlagOption },
|
||||
{ 59, GDK_KEY_Control_L, NSEventModifierFlagControl },
|
||||
{ 60, GDK_KEY_Shift_R, NSEventModifierFlagShift },
|
||||
{ 61, GDK_KEY_Alt_R, NSEventModifierFlagOption },
|
||||
{ 62, GDK_KEY_Control_R, NSEventModifierFlagControl }
|
||||
};
|
||||
|
||||
const static struct {
|
||||
guint keycode;
|
||||
guint keyval;
|
||||
} function_keys[] = {
|
||||
{ 122, GDK_KEY_F1 },
|
||||
{ 120, GDK_KEY_F2 },
|
||||
{ 99, GDK_KEY_F3 },
|
||||
{ 118, GDK_KEY_F4 },
|
||||
{ 96, GDK_KEY_F5 },
|
||||
{ 97, GDK_KEY_F6 },
|
||||
{ 98, GDK_KEY_F7 },
|
||||
{ 100, GDK_KEY_F8 },
|
||||
{ 101, GDK_KEY_F9 },
|
||||
{ 109, GDK_KEY_F10 },
|
||||
{ 103, GDK_KEY_F11 },
|
||||
{ 111, GDK_KEY_F12 },
|
||||
{ 105, GDK_KEY_F13 },
|
||||
{ 107, GDK_KEY_F14 },
|
||||
{ 113, GDK_KEY_F15 },
|
||||
{ 106, GDK_KEY_F16 }
|
||||
};
|
||||
|
||||
const static struct {
|
||||
guint keycode;
|
||||
guint normal_keyval, keypad_keyval;
|
||||
} known_numeric_keys[] = {
|
||||
{ 65, GDK_KEY_period, GDK_KEY_KP_Decimal },
|
||||
{ 67, GDK_KEY_asterisk, GDK_KEY_KP_Multiply },
|
||||
{ 69, GDK_KEY_plus, GDK_KEY_KP_Add },
|
||||
{ 75, GDK_KEY_slash, GDK_KEY_KP_Divide },
|
||||
{ 76, GDK_KEY_Return, GDK_KEY_KP_Enter },
|
||||
{ 78, GDK_KEY_minus, GDK_KEY_KP_Subtract },
|
||||
{ 81, GDK_KEY_equal, GDK_KEY_KP_Equal },
|
||||
{ 82, GDK_KEY_0, GDK_KEY_KP_0 },
|
||||
{ 83, GDK_KEY_1, GDK_KEY_KP_1 },
|
||||
{ 84, GDK_KEY_2, GDK_KEY_KP_2 },
|
||||
{ 85, GDK_KEY_3, GDK_KEY_KP_3 },
|
||||
{ 86, GDK_KEY_4, GDK_KEY_KP_4 },
|
||||
{ 87, GDK_KEY_5, GDK_KEY_KP_5 },
|
||||
{ 88, GDK_KEY_6, GDK_KEY_KP_6 },
|
||||
{ 89, GDK_KEY_7, GDK_KEY_KP_7 },
|
||||
{ 91, GDK_KEY_8, GDK_KEY_KP_8 },
|
||||
{ 92, GDK_KEY_9, GDK_KEY_KP_9 }
|
||||
};
|
||||
|
||||
/* These values aren't covered by gdk_unicode_to_keyval */
|
||||
const static struct {
|
||||
gunichar ucs_value;
|
||||
guint keyval;
|
||||
} special_ucs_table [] = {
|
||||
{ 0x0001, GDK_KEY_Home },
|
||||
{ 0x0003, GDK_KEY_Return },
|
||||
{ 0x0004, GDK_KEY_End },
|
||||
{ 0x0008, GDK_KEY_BackSpace },
|
||||
{ 0x0009, GDK_KEY_Tab },
|
||||
{ 0x000b, GDK_KEY_Page_Up },
|
||||
{ 0x000c, GDK_KEY_Page_Down },
|
||||
{ 0x000d, GDK_KEY_Return },
|
||||
{ 0x001b, GDK_KEY_Escape },
|
||||
{ 0x001c, GDK_KEY_Left },
|
||||
{ 0x001d, GDK_KEY_Right },
|
||||
{ 0x001e, GDK_KEY_Up },
|
||||
{ 0x001f, GDK_KEY_Down },
|
||||
{ 0x007f, GDK_KEY_Delete },
|
||||
{ 0xf027, GDK_KEY_dead_acute },
|
||||
{ 0xf060, GDK_KEY_dead_grave },
|
||||
{ 0xf300, GDK_KEY_dead_grave },
|
||||
{ 0xf0b4, GDK_KEY_dead_acute },
|
||||
{ 0xf301, GDK_KEY_dead_acute },
|
||||
{ 0xf385, GDK_KEY_dead_acute },
|
||||
{ 0xf05e, GDK_KEY_dead_circumflex },
|
||||
{ 0xf2c6, GDK_KEY_dead_circumflex },
|
||||
{ 0xf302, GDK_KEY_dead_circumflex },
|
||||
{ 0xf07e, GDK_KEY_dead_tilde },
|
||||
{ 0xf2dc, GDK_KEY_dead_tilde },
|
||||
{ 0xf303, GDK_KEY_dead_tilde },
|
||||
{ 0xf342, GDK_KEY_dead_perispomeni },
|
||||
{ 0xf0af, GDK_KEY_dead_macron },
|
||||
{ 0xf304, GDK_KEY_dead_macron },
|
||||
{ 0xf2d8, GDK_KEY_dead_breve },
|
||||
{ 0xf306, GDK_KEY_dead_breve },
|
||||
{ 0xf2d9, GDK_KEY_dead_abovedot },
|
||||
{ 0xf307, GDK_KEY_dead_abovedot },
|
||||
{ 0xf0a8, GDK_KEY_dead_diaeresis },
|
||||
{ 0xf308, GDK_KEY_dead_diaeresis },
|
||||
{ 0xf2da, GDK_KEY_dead_abovering },
|
||||
{ 0xf30A, GDK_KEY_dead_abovering },
|
||||
{ 0xf022, GDK_KEY_dead_doubleacute },
|
||||
{ 0xf2dd, GDK_KEY_dead_doubleacute },
|
||||
{ 0xf30B, GDK_KEY_dead_doubleacute },
|
||||
{ 0xf2c7, GDK_KEY_dead_caron },
|
||||
{ 0xf30C, GDK_KEY_dead_caron },
|
||||
{ 0xf0be, GDK_KEY_dead_cedilla },
|
||||
{ 0xf327, GDK_KEY_dead_cedilla },
|
||||
{ 0xf2db, GDK_KEY_dead_ogonek },
|
||||
{ 0xf328, GDK_KEY_dead_ogonek },
|
||||
{ 0xfe5d, GDK_KEY_dead_iota },
|
||||
{ 0xf323, GDK_KEY_dead_belowdot },
|
||||
{ 0xf309, GDK_KEY_dead_hook },
|
||||
{ 0xf31B, GDK_KEY_dead_horn },
|
||||
{ 0xf02d, GDK_KEY_dead_stroke },
|
||||
{ 0xf335, GDK_KEY_dead_stroke },
|
||||
{ 0xf336, GDK_KEY_dead_stroke },
|
||||
{ 0xf313, GDK_KEY_dead_abovecomma },
|
||||
/* { 0xf313, GDK_KEY_dead_psili }, */
|
||||
{ 0xf314, GDK_KEY_dead_abovereversedcomma },
|
||||
/* { 0xf314, GDK_KEY_dead_dasia }, */
|
||||
{ 0xf30F, GDK_KEY_dead_doublegrave },
|
||||
{ 0xf325, GDK_KEY_dead_belowring },
|
||||
{ 0xf2cd, GDK_KEY_dead_belowmacron },
|
||||
{ 0xf331, GDK_KEY_dead_belowmacron },
|
||||
{ 0xf32D, GDK_KEY_dead_belowcircumflex },
|
||||
{ 0xf330, GDK_KEY_dead_belowtilde },
|
||||
{ 0xf32E, GDK_KEY_dead_belowbreve },
|
||||
{ 0xf324, GDK_KEY_dead_belowdiaeresis },
|
||||
{ 0xf311, GDK_KEY_dead_invertedbreve },
|
||||
{ 0xf02c, GDK_KEY_dead_belowcomma },
|
||||
{ 0xf326, GDK_KEY_dead_belowcomma }
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_macos_keymap_update (GdkMacosKeymap *self)
|
||||
{
|
||||
const void *chr_data = NULL;
|
||||
guint *p;
|
||||
int i;
|
||||
|
||||
TISInputSourceRef new_layout = TISCopyCurrentKeyboardLayoutInputSource ();
|
||||
CFDataRef layout_data_ref;
|
||||
|
||||
g_free (keyval_array);
|
||||
keyval_array = g_new0 (guint, NUM_KEYCODES * KEYVALS_PER_KEYCODE);
|
||||
|
||||
layout_data_ref = (CFDataRef)TISGetInputSourceProperty (new_layout, kTISPropertyUnicodeKeyLayoutData);
|
||||
|
||||
if (layout_data_ref)
|
||||
chr_data = CFDataGetBytePtr (layout_data_ref);
|
||||
|
||||
if (chr_data == NULL)
|
||||
{
|
||||
g_error ("cannot get keyboard layout data");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_KEYCODES; i++)
|
||||
{
|
||||
int j;
|
||||
UInt32 modifiers[] = {0, shiftKey, optionKey, shiftKey | optionKey};
|
||||
UniChar chars[4];
|
||||
UniCharCount nChars;
|
||||
|
||||
p = keyval_array + i * KEYVALS_PER_KEYCODE;
|
||||
|
||||
for (j = 0; j < KEYVALS_PER_KEYCODE; j++)
|
||||
{
|
||||
UInt32 state = 0;
|
||||
OSStatus err;
|
||||
UInt16 key_code;
|
||||
UniChar uc;
|
||||
|
||||
key_code = modifiers[j] | i;
|
||||
err = UCKeyTranslate (chr_data, i, kUCKeyActionDisplay,
|
||||
(modifiers[j] >> 8) & 0xFF,
|
||||
LMGetKbdType(),
|
||||
0,
|
||||
&state, 4, &nChars, chars);
|
||||
|
||||
/* FIXME: Theoretically, we can get multiple UTF-16
|
||||
* values; we should convert them to proper unicode and
|
||||
* figure out whether there are really keyboard layouts
|
||||
* that give us more than one character for one
|
||||
* keypress.
|
||||
*/
|
||||
if (err == noErr && nChars == 1)
|
||||
{
|
||||
int k;
|
||||
gboolean found = FALSE;
|
||||
|
||||
/* A few <Shift><Option>keys return two characters,
|
||||
* the first of which is U+00a0, which isn't
|
||||
* interesting; so we return the second. More
|
||||
* sophisticated handling is the job of a
|
||||
* GtkIMContext.
|
||||
*
|
||||
* If state isn't zero, it means that it's a dead
|
||||
* key of some sort. Some of those are enumerated in
|
||||
* the special_ucs_table with the high nibble set to
|
||||
* f to push it into the private use range. Here we
|
||||
* do the same.
|
||||
*/
|
||||
if (state != 0)
|
||||
chars[nChars - 1] |= 0xf000;
|
||||
uc = chars[nChars - 1];
|
||||
|
||||
for (k = 0; k < G_N_ELEMENTS (special_ucs_table); k++)
|
||||
{
|
||||
if (special_ucs_table[k].ucs_value == uc)
|
||||
{
|
||||
p[j] = special_ucs_table[k].keyval;
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Special-case shift-tab since GTK+ expects
|
||||
* GDK_KEY_ISO_Left_Tab for that.
|
||||
*/
|
||||
if (found && p[j] == GDK_KEY_Tab && modifiers[j] == shiftKey)
|
||||
p[j] = GDK_KEY_ISO_Left_Tab;
|
||||
|
||||
if (!found)
|
||||
p[j] = gdk_unicode_to_keyval (uc);
|
||||
}
|
||||
}
|
||||
|
||||
if (p[3] == p[2])
|
||||
p[3] = 0;
|
||||
if (p[2] == p[1])
|
||||
p[2] = 0;
|
||||
if (p[1] == p[0])
|
||||
p[1] = 0;
|
||||
if (p[0] == p[2] &&
|
||||
p[1] == p[3])
|
||||
p[2] = p[3] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (modifier_keys); i++)
|
||||
{
|
||||
p = keyval_array + modifier_keys[i].keycode * KEYVALS_PER_KEYCODE;
|
||||
|
||||
if (p[0] == 0 && p[1] == 0 &&
|
||||
p[2] == 0 && p[3] == 0)
|
||||
p[0] = modifier_keys[i].keyval;
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (function_keys); i++)
|
||||
{
|
||||
p = keyval_array + function_keys[i].keycode * KEYVALS_PER_KEYCODE;
|
||||
|
||||
p[0] = function_keys[i].keyval;
|
||||
p[1] = p[2] = p[3] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (known_numeric_keys); i++)
|
||||
{
|
||||
p = keyval_array + known_numeric_keys[i].keycode * KEYVALS_PER_KEYCODE;
|
||||
|
||||
if (p[0] == known_numeric_keys[i].normal_keyval)
|
||||
p[0] = known_numeric_keys[i].keypad_keyval;
|
||||
}
|
||||
|
||||
g_signal_emit_by_name (self, "keys-changed");
|
||||
}
|
||||
|
||||
static PangoDirection
|
||||
gdk_macos_keymap_get_direction (GdkKeymap *keymap)
|
||||
{
|
||||
return PANGO_DIRECTION_NEUTRAL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_keymap_have_bidi_layouts (GdkKeymap *keymap)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_keymap_get_caps_lock_state (GdkKeymap *keymap)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_keymap_get_num_lock_state (GdkKeymap *keymap)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_keymap_get_scroll_lock_state (GdkKeymap *keymap)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gdk_macos_keymap_lookup_key (GdkKeymap *keymap,
|
||||
const GdkKeymapKey *key)
|
||||
{
|
||||
GdkMacosKeymap *self = (GdkMacosKeymap *)keymap;
|
||||
|
||||
g_assert (GDK_IS_MACOS_KEYMAP (self));
|
||||
g_assert (key != NULL);
|
||||
|
||||
return GET_KEYVAL (key->keycode, key->group, key->level);
|
||||
}
|
||||
|
||||
static guint
|
||||
translate_keysym (guint hardware_keycode,
|
||||
gint group,
|
||||
GdkModifierType state,
|
||||
gint *effective_group,
|
||||
gint *effective_level)
|
||||
{
|
||||
gint level;
|
||||
guint tmp_keyval;
|
||||
|
||||
level = (state & GDK_SHIFT_MASK) ? 1 : 0;
|
||||
|
||||
if (!(GET_KEYVAL (hardware_keycode, group, 0) || GET_KEYVAL (hardware_keycode, group, 1)) &&
|
||||
(GET_KEYVAL (hardware_keycode, 0, 0) || GET_KEYVAL (hardware_keycode, 0, 1)))
|
||||
group = 0;
|
||||
|
||||
if (!GET_KEYVAL (hardware_keycode, group, level) &&
|
||||
GET_KEYVAL (hardware_keycode, group, 0))
|
||||
level = 0;
|
||||
|
||||
tmp_keyval = GET_KEYVAL (hardware_keycode, group, level);
|
||||
|
||||
if (state & GDK_LOCK_MASK)
|
||||
{
|
||||
guint upper = gdk_keyval_to_upper (tmp_keyval);
|
||||
if (upper != tmp_keyval)
|
||||
tmp_keyval = upper;
|
||||
}
|
||||
|
||||
if (effective_group)
|
||||
*effective_group = group;
|
||||
if (effective_level)
|
||||
*effective_level = level;
|
||||
|
||||
return tmp_keyval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_keymap_get_entries_for_keyval (GdkKeymap *keymap,
|
||||
guint keyval,
|
||||
GArray *keys)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_assert (GDK_IS_MACOS_KEYMAP (keymap));
|
||||
g_assert (keys != NULL);
|
||||
|
||||
for (guint i = 0; i < NUM_KEYCODES * KEYVALS_PER_KEYCODE; i++)
|
||||
{
|
||||
GdkKeymapKey key;
|
||||
|
||||
if (keyval_array[i] != keyval)
|
||||
continue;
|
||||
|
||||
key.keycode = i / KEYVALS_PER_KEYCODE;
|
||||
key.group = (i % KEYVALS_PER_KEYCODE) >= 2;
|
||||
key.level = i % 2;
|
||||
|
||||
g_array_append_val (keys, key);
|
||||
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_keymap_get_entries_for_keycode (GdkKeymap *keymap,
|
||||
guint hardware_keycode,
|
||||
GdkKeymapKey **keys,
|
||||
guint **keyvals,
|
||||
gint *n_entries)
|
||||
{
|
||||
GArray *keys_array;
|
||||
GArray *keyvals_array;
|
||||
guint *p;
|
||||
guint i;
|
||||
|
||||
g_assert (GDK_IS_MACOS_KEYMAP (keymap));
|
||||
g_assert (keyvals != NULL);
|
||||
g_assert (n_entries != NULL);
|
||||
|
||||
*keyvals = NULL;
|
||||
*n_entries = 0;
|
||||
|
||||
if (hardware_keycode > NUM_KEYCODES)
|
||||
return FALSE;
|
||||
|
||||
if (keys)
|
||||
keys_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
|
||||
else
|
||||
keys_array = NULL;
|
||||
|
||||
if (keyvals)
|
||||
keyvals_array = g_array_new (FALSE, FALSE, sizeof (guint));
|
||||
else
|
||||
keyvals_array = NULL;
|
||||
|
||||
p = keyval_array + hardware_keycode * KEYVALS_PER_KEYCODE;
|
||||
|
||||
for (i = 0; i < KEYVALS_PER_KEYCODE; i++)
|
||||
{
|
||||
if (!p[i])
|
||||
continue;
|
||||
|
||||
(*n_entries)++;
|
||||
|
||||
if (keyvals_array)
|
||||
g_array_append_val (keyvals_array, p[i]);
|
||||
|
||||
if (keys_array)
|
||||
{
|
||||
GdkKeymapKey key;
|
||||
|
||||
key.keycode = hardware_keycode;
|
||||
key.group = i >= 2;
|
||||
key.level = i % 2;
|
||||
|
||||
g_array_append_val (keys_array, key);
|
||||
}
|
||||
}
|
||||
|
||||
if (keys)
|
||||
*keys = (GdkKeymapKey *)(gpointer)g_array_free (keys_array, FALSE);
|
||||
|
||||
if (keyvals)
|
||||
*keyvals = (guint *)(gpointer)g_array_free (keyvals_array, FALSE);
|
||||
|
||||
return *n_entries > 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_keymap_translate_keyboard_state (GdkKeymap *keymap,
|
||||
guint hardware_keycode,
|
||||
GdkModifierType state,
|
||||
gint group,
|
||||
guint *keyval,
|
||||
gint *effective_group,
|
||||
gint *level,
|
||||
GdkModifierType *consumed_modifiers)
|
||||
{
|
||||
guint tmp_keyval;
|
||||
GdkModifierType bit;
|
||||
|
||||
g_assert (GDK_IS_MACOS_KEYMAP (keymap));
|
||||
|
||||
if (keyval)
|
||||
*keyval = 0;
|
||||
if (effective_group)
|
||||
*effective_group = 0;
|
||||
if (level)
|
||||
*level = 0;
|
||||
if (consumed_modifiers)
|
||||
*consumed_modifiers = 0;
|
||||
|
||||
if (hardware_keycode < 0 || hardware_keycode >= NUM_KEYCODES)
|
||||
return FALSE;
|
||||
|
||||
tmp_keyval = translate_keysym (hardware_keycode, group, state, level, effective_group);
|
||||
|
||||
/* Check if modifiers modify the keyval */
|
||||
if (consumed_modifiers)
|
||||
{
|
||||
guint tmp_modifiers = (state & GDK_MODIFIER_MASK);
|
||||
|
||||
for (bit = 1; bit <= tmp_modifiers; bit <<= 1)
|
||||
{
|
||||
if ((bit & tmp_modifiers) &&
|
||||
translate_keysym (hardware_keycode, group, state & ~bit,
|
||||
NULL, NULL) == tmp_keyval)
|
||||
tmp_modifiers &= ~bit;
|
||||
}
|
||||
|
||||
*consumed_modifiers = tmp_modifiers;
|
||||
}
|
||||
|
||||
if (keyval)
|
||||
*keyval = tmp_keyval;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
input_sources_changed_notification (CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo)
|
||||
{
|
||||
GdkMacosKeymap *self = observer;
|
||||
|
||||
g_assert (GDK_IS_MACOS_KEYMAP (self));
|
||||
|
||||
gdk_macos_keymap_update (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_keymap_finalize (GObject *object)
|
||||
{
|
||||
CFNotificationCenterRemoveObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
object,
|
||||
CFSTR ("AppleSelectedInputSourcesChangedNotification"),
|
||||
NULL);
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_keymap_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_keymap_class_init (GdkMacosKeymapClass *klass)
|
||||
{
|
||||
GdkKeymapClass *keymap_class = GDK_KEYMAP_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_macos_keymap_finalize;
|
||||
|
||||
keymap_class->get_caps_lock_state = gdk_macos_keymap_get_caps_lock_state;
|
||||
keymap_class->get_direction = gdk_macos_keymap_get_direction;
|
||||
keymap_class->get_entries_for_keycode = gdk_macos_keymap_get_entries_for_keycode;
|
||||
keymap_class->get_entries_for_keyval = gdk_macos_keymap_get_entries_for_keyval;
|
||||
keymap_class->get_num_lock_state = gdk_macos_keymap_get_num_lock_state;
|
||||
keymap_class->get_scroll_lock_state = gdk_macos_keymap_get_scroll_lock_state;
|
||||
keymap_class->have_bidi_layouts = gdk_macos_keymap_have_bidi_layouts;
|
||||
keymap_class->lookup_key = gdk_macos_keymap_lookup_key;
|
||||
keymap_class->translate_keyboard_state = gdk_macos_keymap_translate_keyboard_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_keymap_init (GdkMacosKeymap *self)
|
||||
{
|
||||
CFNotificationCenterAddObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
self,
|
||||
input_sources_changed_notification,
|
||||
CFSTR ("AppleSelectedInputSourcesChangedNotification"),
|
||||
NULL,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
gdk_macos_keymap_update (self);
|
||||
}
|
||||
|
||||
GdkMacosKeymap *
|
||||
_gdk_macos_keymap_new (GdkMacosDisplay *display)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
|
||||
return g_object_new (GDK_TYPE_MACOS_KEYMAP,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* What sort of key event is this? Returns one of
|
||||
* GDK_KEY_PRESS, GDK_KEY_RELEASE, GDK_NOTHING (should be ignored)
|
||||
*/
|
||||
GdkEventType
|
||||
_gdk_macos_keymap_get_event_type (NSEvent *event)
|
||||
{
|
||||
unsigned short keycode;
|
||||
unsigned int flags;
|
||||
|
||||
switch ((int)[event type])
|
||||
{
|
||||
case NSEventTypeKeyDown:
|
||||
return GDK_KEY_PRESS;
|
||||
case NSEventTypeKeyUp:
|
||||
return GDK_KEY_RELEASE;
|
||||
case NSEventTypeFlagsChanged:
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
/* For flags-changed events, we have to find the special key that caused the
|
||||
* event, and see if it's in the modifier mask. */
|
||||
keycode = [event keyCode];
|
||||
flags = [event modifierFlags];
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (modifier_keys); i++)
|
||||
{
|
||||
if (modifier_keys[i].keycode == keycode)
|
||||
{
|
||||
if (flags & modifier_keys[i].modmask)
|
||||
return GDK_KEY_PRESS;
|
||||
else
|
||||
return GDK_KEY_RELEASE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Some keypresses (eg: Expose' activations) seem to trigger flags-changed
|
||||
* events for no good reason. Ignore them! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_keymap_is_modifier (guint keycode)
|
||||
{
|
||||
for (guint i = 0; i < G_N_ELEMENTS (modifier_keys); i++)
|
||||
{
|
||||
if (modifier_keys[i].modmask == 0)
|
||||
break;
|
||||
|
||||
if (modifier_keys[i].keycode == keycode)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
43
gdk/macos/gdkmacoskeymap.h
Normal file
43
gdk/macos/gdkmacoskeymap.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_KEYMAP_H__
|
||||
#define __GDK_MACOS_KEYMAP_H__
|
||||
|
||||
#if !defined (__GDKMACOS_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/macos/gdkmacos.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkMacosKeymap GdkMacosKeymap;
|
||||
typedef struct _GdkMacosKeymapClass GdkMacosKeymapClass;
|
||||
|
||||
#define GDK_TYPE_MACOS_KEYMAP (gdk_macos_keymap_get_type())
|
||||
#define GDK_MACOS_KEYMAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_KEYMAP, GdkMacosKeymap))
|
||||
#define GDK_IS_MACOS_KEYMAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_KEYMAP))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_macos_keymap_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_KEYMAP_H__ */
|
39
gdk/macos/gdkmacosmonitor-private.h
Normal file
39
gdk/macos/gdkmacosmonitor-private.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_MONITOR_PRIVATE_H__
|
||||
#define __GDK_MACOS_MONITOR_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacosmonitor.h"
|
||||
|
||||
#include "gdkmonitorprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GdkMacosMonitor *_gdk_macos_monitor_new (GdkMacosDisplay *display,
|
||||
CGDirectDisplayID screen_id);
|
||||
CGDirectDisplayID _gdk_macos_monitor_get_screen_id (GdkMacosMonitor *self);
|
||||
gboolean _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_MONITOR_PRIVATE_H__ */
|
288
gdk/macos/gdkmacosmonitor.c
Normal file
288
gdk/macos/gdkmacosmonitor.c
Normal file
@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosmonitor-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
|
||||
struct _GdkMacosMonitor
|
||||
{
|
||||
GdkMonitor parent_instance;
|
||||
CGDirectDisplayID screen_id;
|
||||
NSRect workarea;
|
||||
guint has_opengl : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosMonitorClass
|
||||
{
|
||||
GdkMonitorClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosMonitor, gdk_macos_monitor, GDK_TYPE_MONITOR)
|
||||
|
||||
static void
|
||||
gdk_macos_monitor_get_workarea (GdkMonitor *monitor,
|
||||
GdkRectangle *geometry)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkMacosMonitor *self = (GdkMacosMonitor *)monitor;
|
||||
int x, y;
|
||||
|
||||
g_assert (GDK_IS_MACOS_MONITOR (self));
|
||||
g_assert (geometry != NULL);
|
||||
|
||||
x = self->workarea.origin.x;
|
||||
y = self->workarea.origin.y + self->workarea.size.height;
|
||||
|
||||
_gdk_macos_display_from_display_coords (GDK_MACOS_DISPLAY (monitor->display),
|
||||
x, y,
|
||||
&x, &y);
|
||||
|
||||
geometry->x = x;
|
||||
geometry->y = y;
|
||||
geometry->width = self->workarea.size.width;
|
||||
geometry->height = self->workarea.size.height;
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_monitor_class_init (GdkMacosMonitorClass *klass)
|
||||
{
|
||||
GdkMonitorClass *monitor_class = GDK_MONITOR_CLASS (klass);
|
||||
|
||||
monitor_class->get_workarea = gdk_macos_monitor_get_workarea;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_monitor_init (GdkMacosMonitor *self)
|
||||
{
|
||||
}
|
||||
|
||||
static GdkSubpixelLayout
|
||||
GetSubpixelLayout (CGDirectDisplayID screen_id)
|
||||
{
|
||||
#if 0
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkSubpixelLayout subpixel_layout = GDK_SUBPIXEL_LAYOUT_UNKNOWN;
|
||||
io_service_t iosvc;
|
||||
NSDictionary *dict;
|
||||
guint layout;
|
||||
gboolean rotation;
|
||||
|
||||
rotation = CGDisplayRotation (screen_id);
|
||||
iosvc = CGDisplayIOServicePort (screen_id);
|
||||
dict = (NSDictionary *)IODisplayCreateInfoDictionary (iosvc, kIODisplayOnlyPreferredName);
|
||||
layout = [[dict objectForKey:@kDisplaySubPixelLayout] unsignedIntValue];
|
||||
|
||||
switch (layout)
|
||||
{
|
||||
case kDisplaySubPixelLayoutRGB:
|
||||
if (rotation == 0.0)
|
||||
subpixel_layout = GDK_SUBPIXEL_LAYOUT_HORIZONTAL_RGB;
|
||||
else if (rotation == 90.0)
|
||||
subpixel_layout = GDK_SUBPIXEL_LAYOUT_VERTICAL_RGB;
|
||||
else if (rotation == 180.0 || rotation == -180.0)
|
||||
subpixel_layout = GDK_SUBPIXEL_LAYOUT_HORIZONTAL_BGR;
|
||||
else if (rotation == -90.0)
|
||||
subpixel_layout = GDK_SUBPIXEL_LAYOUT_VERTICAL_BGR;
|
||||
break;
|
||||
|
||||
case kDisplaySubPixelLayoutBGR:
|
||||
if (rotation == 0.0)
|
||||
subpixel_layout = GDK_SUBPIXEL_LAYOUT_HORIZONTAL_BGR;
|
||||
else if (rotation == 90.0)
|
||||
subpixel_layout = GDK_SUBPIXEL_LAYOUT_VERTICAL_BGR;
|
||||
else if (rotation == 180.0 || rotation == -180.0)
|
||||
subpixel_layout = GDK_SUBPIXEL_LAYOUT_HORIZONTAL_RGB;
|
||||
else if (rotation == -90.0 || rotation == 270.0)
|
||||
subpixel_layout = GDK_SUBPIXEL_LAYOUT_VERTICAL_RGB;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return subpixel_layout;
|
||||
#endif
|
||||
|
||||
return GDK_SUBPIXEL_LAYOUT_UNKNOWN;
|
||||
}
|
||||
|
||||
static char *
|
||||
GetLocalizedName (NSScreen *screen)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
NSString *str;
|
||||
char *name;
|
||||
|
||||
g_assert (screen);
|
||||
|
||||
str = [screen localizedName];
|
||||
name = g_strdup ([str UTF8String]);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&name);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
GetConnectorName (CGDirectDisplayID screen_id)
|
||||
{
|
||||
guint unit = CGDisplayUnitNumber (screen_id);
|
||||
return g_strdup_printf ("unit-%u", unit);
|
||||
}
|
||||
|
||||
static NSScreen *
|
||||
find_screen (CGDirectDisplayID screen_id)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
NSScreen *screen = NULL;
|
||||
|
||||
for (id obj in [NSScreen screens])
|
||||
{
|
||||
if (screen_id == [[[obj deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue])
|
||||
{
|
||||
screen = (NSScreen *)obj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return screen;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_monitor_reconfigure (GdkMacosMonitor *self)
|
||||
{
|
||||
GdkSubpixelLayout subpixel_layout;
|
||||
CGDisplayModeRef mode;
|
||||
GdkMacosDisplay *display;
|
||||
NSScreen *screen;
|
||||
GdkRectangle geom;
|
||||
gboolean has_opengl;
|
||||
CGSize size;
|
||||
CGRect bounds;
|
||||
size_t width;
|
||||
size_t pixel_width;
|
||||
gchar *connector;
|
||||
gchar *name;
|
||||
int refresh_rate;
|
||||
int scale_factor = 1;
|
||||
int width_mm;
|
||||
int height_mm;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_MONITOR (self), FALSE);
|
||||
|
||||
display = GDK_MACOS_DISPLAY (GDK_MONITOR (self)->display);
|
||||
|
||||
if (!(screen = find_screen (self->screen_id)) ||
|
||||
!(mode = CGDisplayCopyDisplayMode (self->screen_id)))
|
||||
return FALSE;
|
||||
|
||||
size = CGDisplayScreenSize (self->screen_id);
|
||||
bounds = [screen frame];
|
||||
width = CGDisplayModeGetWidth (mode);
|
||||
pixel_width = CGDisplayModeGetPixelWidth (mode);
|
||||
has_opengl = CGDisplayUsesOpenGLAcceleration (self->screen_id);
|
||||
subpixel_layout = GetSubpixelLayout (self->screen_id);
|
||||
name = GetLocalizedName (screen);
|
||||
connector = GetConnectorName (self->screen_id);
|
||||
|
||||
if (width != 0 && pixel_width != 0)
|
||||
scale_factor = MAX (1, pixel_width / width);
|
||||
|
||||
width_mm = size.width;
|
||||
height_mm = size.height;
|
||||
|
||||
geom.x = bounds.origin.x - display->min_x;
|
||||
geom.y = display->height - bounds.origin.y - bounds.size.height + display->min_y;
|
||||
geom.width = bounds.size.width;
|
||||
geom.height = bounds.size.height;
|
||||
|
||||
/* We will often get 0 back from CGDisplayModeGetRefreshRate(). We
|
||||
* can fallback by getting it from CoreVideo based on a CVDisplayLink
|
||||
* setting (which is also used by the frame clock).
|
||||
*/
|
||||
if (!(refresh_rate = CGDisplayModeGetRefreshRate (mode)))
|
||||
refresh_rate = _gdk_macos_display_get_nominal_refresh_rate (display);
|
||||
|
||||
gdk_monitor_set_connector (GDK_MONITOR (self), connector);
|
||||
gdk_monitor_set_model (GDK_MONITOR (self), name);
|
||||
gdk_monitor_set_geometry (GDK_MONITOR (self), &geom);
|
||||
gdk_monitor_set_physical_size (GDK_MONITOR (self), width_mm, height_mm);
|
||||
gdk_monitor_set_scale_factor (GDK_MONITOR (self), scale_factor);
|
||||
gdk_monitor_set_refresh_rate (GDK_MONITOR (self), refresh_rate);
|
||||
gdk_monitor_set_subpixel_layout (GDK_MONITOR (self), GDK_SUBPIXEL_LAYOUT_UNKNOWN);
|
||||
|
||||
self->workarea = [screen visibleFrame];
|
||||
|
||||
/* We might be able to use this at some point to change which GSK renderer
|
||||
* we use for surfaces on this monitor. For example, it might be better
|
||||
* to use cairo if we cannot use OpenGL (or it would be software) anyway.
|
||||
* Presumably that is more common in cases where macOS is running under
|
||||
* an emulator such as QEMU.
|
||||
*/
|
||||
self->has_opengl = !!has_opengl;
|
||||
|
||||
CGDisplayModeRelease (mode);
|
||||
g_free (name);
|
||||
g_free (connector);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GdkMacosMonitor *
|
||||
_gdk_macos_monitor_new (GdkMacosDisplay *display,
|
||||
CGDirectDisplayID screen_id)
|
||||
{
|
||||
GdkMacosMonitor *self;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
|
||||
self = g_object_new (GDK_TYPE_MACOS_MONITOR,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
self->screen_id = screen_id;
|
||||
|
||||
_gdk_macos_monitor_reconfigure (self);
|
||||
|
||||
return g_steal_pointer (&self);
|
||||
}
|
||||
|
||||
CGDirectDisplayID
|
||||
_gdk_macos_monitor_get_screen_id (GdkMacosMonitor *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MACOS_MONITOR (self), 0);
|
||||
|
||||
return self->screen_id;
|
||||
}
|
43
gdk/macos/gdkmacosmonitor.h
Normal file
43
gdk/macos/gdkmacosmonitor.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_MONITOR_H__
|
||||
#define __GDK_MACOS_MONITOR_H__
|
||||
|
||||
#if !defined (__GDKMACOS_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/macos/gdkmacos.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkMacosMonitor GdkMacosMonitor;
|
||||
typedef struct _GdkMacosMonitorClass GdkMacosMonitorClass;
|
||||
|
||||
#define GDK_TYPE_MACOS_MONITOR (gdk_macos_monitor_get_type())
|
||||
#define GDK_MACOS_MONITOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_MONITOR, GdkMacosMonitor))
|
||||
#define GDK_IS_MACOS_MONITOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_MONITOR))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_macos_monitor_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_MONITOR_H__ */
|
48
gdk/macos/gdkmacospopupsurface-private.h
Normal file
48
gdk/macos/gdkmacospopupsurface-private.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_POPUP_SURFACE_PRIVATE_H__
|
||||
#define __GDK_MACOS_POPUP_SURFACE_PRIVATE_H__
|
||||
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkMacosPopupSurface GdkMacosPopupSurface;
|
||||
typedef struct _GdkMacosPopupSurfaceClass GdkMacosPopupSurfaceClass;
|
||||
|
||||
#define GDK_TYPE_MACOS_POPUP_SURFACE (_gdk_macos_popup_surface_get_type())
|
||||
#define GDK_MACOS_POPUP_SURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_POPUP_SURFACE, GdkMacosPopupSurface))
|
||||
#define GDK_IS_MACOS_POPUP_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_POPUP_SURFACE))
|
||||
|
||||
GType _gdk_macos_popup_surface_get_type (void);
|
||||
GdkMacosSurface *_gdk_macos_popup_surface_new (GdkMacosDisplay *display,
|
||||
GdkSurface *parent,
|
||||
GdkFrameClock *frame_clock,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void _gdk_macos_popup_surface_attach_to_parent (GdkMacosPopupSurface *self);
|
||||
void _gdk_macos_popup_surface_detach_from_parent (GdkMacosPopupSurface *self);
|
||||
void _gdk_macos_popup_surface_reposition (GdkMacosPopupSurface *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_POPUP_SURFACE_PRIVATE_H__ */
|
378
gdk/macos/gdkmacospopupsurface.c
Normal file
378
gdk/macos/gdkmacospopupsurface.c
Normal file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkpopupprivate.h"
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacospopupsurface-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
|
||||
struct _GdkMacosPopupSurface
|
||||
{
|
||||
GdkMacosSurface parent_instance;
|
||||
GdkPopupLayout *layout;
|
||||
};
|
||||
|
||||
struct _GdkMacosPopupSurfaceClass
|
||||
{
|
||||
GdkMacosSurfaceClass parent_class;
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_macos_popup_surface_layout (GdkMacosPopupSurface *self,
|
||||
int width,
|
||||
int height,
|
||||
GdkPopupLayout *layout)
|
||||
{
|
||||
GdkRectangle final_rect;
|
||||
int x, y;
|
||||
|
||||
g_assert (GDK_IS_MACOS_POPUP_SURFACE (self));
|
||||
g_assert (layout != NULL);
|
||||
g_assert (GDK_SURFACE (self)->parent);
|
||||
|
||||
if (layout != self->layout)
|
||||
{
|
||||
g_clear_pointer (&self->layout, gdk_popup_layout_unref);
|
||||
self->layout = gdk_popup_layout_ref (layout);
|
||||
}
|
||||
|
||||
gdk_surface_layout_popup_helper (GDK_SURFACE (self),
|
||||
width,
|
||||
height,
|
||||
layout,
|
||||
&final_rect);
|
||||
|
||||
gdk_surface_get_origin (GDK_SURFACE (self)->parent, &x, &y);
|
||||
|
||||
x += final_rect.x;
|
||||
y += final_rect.y;
|
||||
|
||||
if (final_rect.width != GDK_SURFACE (self)->width ||
|
||||
final_rect.height != GDK_SURFACE (self)->height)
|
||||
_gdk_macos_surface_move_resize (GDK_MACOS_SURFACE (self),
|
||||
x,
|
||||
y,
|
||||
final_rect.width,
|
||||
final_rect.height);
|
||||
else if (x != GDK_MACOS_SURFACE (self)->root_x ||
|
||||
y != GDK_MACOS_SURFACE (self)->root_y)
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self), x, y);
|
||||
else
|
||||
return;
|
||||
|
||||
gdk_surface_invalidate_rect (GDK_SURFACE (self), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
show_popup (GdkMacosPopupSurface *self)
|
||||
{
|
||||
_gdk_macos_surface_show (GDK_MACOS_SURFACE (self));
|
||||
}
|
||||
|
||||
static void
|
||||
show_grabbing_popup (GdkSeat *seat,
|
||||
GdkSurface *surface,
|
||||
gpointer user_data)
|
||||
{
|
||||
show_popup (GDK_MACOS_POPUP_SURFACE (surface));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_popup_surface_present (GdkPopup *popup,
|
||||
int width,
|
||||
int height,
|
||||
GdkPopupLayout *layout)
|
||||
{
|
||||
GdkMacosPopupSurface *self = (GdkMacosPopupSurface *)popup;
|
||||
|
||||
g_assert (GDK_IS_MACOS_POPUP_SURFACE (self));
|
||||
|
||||
gdk_macos_popup_surface_layout (self, width, height, layout);
|
||||
|
||||
GDK_MACOS_SURFACE (self)->did_initial_present = TRUE;
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self)))
|
||||
return TRUE;
|
||||
|
||||
if (GDK_SURFACE (self)->autohide)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (popup));
|
||||
GdkSeat *seat = gdk_display_get_default_seat (display);
|
||||
|
||||
gdk_seat_grab (seat,
|
||||
GDK_SURFACE (self),
|
||||
GDK_SEAT_CAPABILITY_ALL,
|
||||
TRUE,
|
||||
NULL, NULL,
|
||||
show_grabbing_popup,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
show_popup (GDK_MACOS_POPUP_SURFACE (self));
|
||||
}
|
||||
|
||||
return GDK_SURFACE_IS_MAPPED (GDK_SURFACE (self));
|
||||
}
|
||||
|
||||
static GdkGravity
|
||||
gdk_macos_popup_surface_get_surface_anchor (GdkPopup *popup)
|
||||
{
|
||||
return GDK_SURFACE (popup)->popup.surface_anchor;
|
||||
}
|
||||
|
||||
static GdkGravity
|
||||
gdk_macos_popup_surface_get_rect_anchor (GdkPopup *popup)
|
||||
{
|
||||
return GDK_SURFACE (popup)->popup.rect_anchor;
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_macos_popup_surface_get_position_x (GdkPopup *popup)
|
||||
{
|
||||
return GDK_SURFACE (popup)->x;
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_macos_popup_surface_get_position_y (GdkPopup *popup)
|
||||
{
|
||||
return GDK_SURFACE (popup)->y;
|
||||
}
|
||||
|
||||
static void
|
||||
popup_interface_init (GdkPopupInterface *iface)
|
||||
{
|
||||
iface->present = gdk_macos_popup_surface_present;
|
||||
iface->get_surface_anchor = gdk_macos_popup_surface_get_surface_anchor;
|
||||
iface->get_rect_anchor = gdk_macos_popup_surface_get_rect_anchor;
|
||||
iface->get_position_x = gdk_macos_popup_surface_get_position_x;
|
||||
iface->get_position_y = gdk_macos_popup_surface_get_position_y;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GdkMacosPopupSurface, _gdk_macos_popup_surface, GDK_TYPE_MACOS_SURFACE,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_POPUP, popup_interface_init))
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
LAST_PROP,
|
||||
};
|
||||
|
||||
static void
|
||||
_gdk_macos_popup_surface_finalize (GObject *object)
|
||||
{
|
||||
GdkMacosPopupSurface *self = (GdkMacosPopupSurface *)object;
|
||||
|
||||
g_clear_object (&GDK_SURFACE (self)->parent);
|
||||
g_clear_pointer (&self->layout, gdk_popup_layout_unref);
|
||||
|
||||
G_OBJECT_CLASS (_gdk_macos_popup_surface_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_popup_surface_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case LAST_PROP + GDK_POPUP_PROP_PARENT:
|
||||
g_value_set_object (value, surface->parent);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_POPUP_PROP_AUTOHIDE:
|
||||
g_value_set_boolean (value, surface->autohide);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_popup_surface_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case LAST_PROP + GDK_POPUP_PROP_PARENT:
|
||||
surface->parent = g_value_dup_object (value);
|
||||
if (surface->parent)
|
||||
surface->parent->children = g_list_prepend (surface->parent->children, surface);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_POPUP_PROP_AUTOHIDE:
|
||||
surface->autohide = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_popup_surface_class_init (GdkMacosPopupSurfaceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = _gdk_macos_popup_surface_finalize;
|
||||
object_class->get_property = _gdk_macos_popup_surface_get_property;
|
||||
object_class->set_property = _gdk_macos_popup_surface_set_property;
|
||||
|
||||
gdk_popup_install_properties (object_class, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_popup_surface_init (GdkMacosPopupSurface *self)
|
||||
{
|
||||
}
|
||||
|
||||
GdkMacosSurface *
|
||||
_gdk_macos_popup_surface_new (GdkMacosDisplay *display,
|
||||
GdkSurface *parent,
|
||||
GdkFrameClock *frame_clock,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkMacosWindow *window;
|
||||
GdkMacosSurface *self;
|
||||
NSScreen *screen;
|
||||
NSUInteger style_mask;
|
||||
NSRect content_rect;
|
||||
NSRect screen_rect;
|
||||
int nx;
|
||||
int ny;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
g_return_val_if_fail (!frame_clock || GDK_IS_FRAME_CLOCK (frame_clock), NULL);
|
||||
g_return_val_if_fail (!parent || GDK_IS_MACOS_SURFACE (parent), NULL);
|
||||
|
||||
style_mask = NSWindowStyleMaskBorderless;
|
||||
|
||||
_gdk_macos_display_to_display_coords (display, x, y, &nx, &ny);
|
||||
|
||||
screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
|
||||
screen_rect = [screen frame];
|
||||
nx -= screen_rect.origin.x;
|
||||
ny -= screen_rect.origin.y;
|
||||
content_rect = NSMakeRect (nx, ny - height, width, height);
|
||||
|
||||
window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
|
||||
styleMask:style_mask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO
|
||||
screen:screen];
|
||||
|
||||
[window setOpaque:NO];
|
||||
[window setBackgroundColor:[NSColor clearColor]];
|
||||
[window setDecorated:NO];
|
||||
|
||||
#if 0
|
||||
/* NOTE: We could set these to be popup level, but then
|
||||
* [NSApp orderedWindows] would not give us the windows
|
||||
* back with the stacking order applied.
|
||||
*/
|
||||
[window setLevel:NSPopUpMenuWindowLevel];
|
||||
#endif
|
||||
|
||||
self = g_object_new (GDK_TYPE_MACOS_POPUP_SURFACE,
|
||||
"display", display,
|
||||
"frame-clock", frame_clock,
|
||||
"native", window,
|
||||
"parent", parent,
|
||||
NULL);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&self);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_popup_surface_attach_to_parent (GdkMacosPopupSurface *self)
|
||||
{
|
||||
GdkSurface *surface = (GdkSurface *)self;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_POPUP_SURFACE (self));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
if (surface->parent != NULL && !GDK_SURFACE_DESTROYED (surface->parent))
|
||||
{
|
||||
NSWindow *parent = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface->parent));
|
||||
NSWindow *window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
|
||||
[parent addChildWindow:window ordered:NSWindowAbove];
|
||||
|
||||
_gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (surface->display));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_popup_surface_detach_from_parent (GdkMacosPopupSurface *self)
|
||||
{
|
||||
GdkSurface *surface = (GdkSurface *)self;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_POPUP_SURFACE (self));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
if (surface->parent != NULL && !GDK_SURFACE_DESTROYED (surface->parent))
|
||||
{
|
||||
NSWindow *parent = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface->parent));
|
||||
NSWindow *window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
|
||||
[parent removeChildWindow:window];
|
||||
|
||||
_gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (surface->display));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_popup_surface_reposition (GdkMacosPopupSurface *self)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_POPUP_SURFACE (self));
|
||||
|
||||
if (self->layout == NULL ||
|
||||
!gdk_surface_get_mapped (GDK_SURFACE (self)) ||
|
||||
GDK_SURFACE (self)->parent == NULL)
|
||||
return;
|
||||
|
||||
gdk_macos_popup_surface_layout (self,
|
||||
GDK_SURFACE (self)->width,
|
||||
GDK_SURFACE (self)->height,
|
||||
self->layout);
|
||||
}
|
35
gdk/macos/gdkmacosseat-private.h
Normal file
35
gdk/macos/gdkmacosseat-private.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_SEAT_PRIVATE_H__
|
||||
#define __GDK_MACOS_SEAT_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
|
||||
#include "gdkseatprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GdkSeat *_gdk_macos_seat_new (GdkMacosDisplay *display);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_SEAT_PRIVATE_H__ */
|
65
gdk/macos/gdkmacosseat.c
Normal file
65
gdk/macos/gdkmacosseat.c
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkseatdefaultprivate.h"
|
||||
|
||||
#include "gdkmacosdevice.h"
|
||||
#include "gdkmacosseat-private.h"
|
||||
|
||||
GdkSeat *
|
||||
_gdk_macos_seat_new (GdkMacosDisplay *display)
|
||||
{
|
||||
GdkDevice *core_keyboard;
|
||||
GdkDevice *core_pointer;
|
||||
GdkSeat *seat;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
|
||||
core_pointer = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Pointer",
|
||||
"type", GDK_DEVICE_TYPE_LOGICAL,
|
||||
"source", GDK_SOURCE_MOUSE,
|
||||
"has-cursor", TRUE,
|
||||
"display", display,
|
||||
NULL);
|
||||
core_keyboard = g_object_new (GDK_TYPE_MACOS_DEVICE,
|
||||
"name", "Core Keyboard",
|
||||
"type", GDK_DEVICE_TYPE_LOGICAL,
|
||||
"source", GDK_SOURCE_KEYBOARD,
|
||||
"has-cursor", FALSE,
|
||||
"display", display,
|
||||
NULL);
|
||||
|
||||
_gdk_device_set_associated_device (GDK_DEVICE (core_pointer),
|
||||
GDK_DEVICE (core_keyboard));
|
||||
_gdk_device_set_associated_device (GDK_DEVICE (core_keyboard),
|
||||
GDK_DEVICE (core_pointer));
|
||||
|
||||
seat = gdk_seat_default_new_for_logical_pair (core_pointer, core_keyboard);
|
||||
|
||||
g_object_unref (core_pointer);
|
||||
g_object_unref (core_keyboard);
|
||||
|
||||
return g_steal_pointer (&seat);
|
||||
}
|
131
gdk/macos/gdkmacossurface-private.h
Normal file
131
gdk/macos/gdkmacossurface-private.h
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_SURFACE_PRIVATE_H__
|
||||
#define __GDK_MACOS_SURFACE_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <cairo.h>
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
|
||||
#include "gdkmacosdisplay.h"
|
||||
#include "gdkmacossurface.h"
|
||||
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_MACOS_SURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_MACOS_SURFACE, GdkMacosSurfaceClass))
|
||||
#define GDK_IS_MACOS_SURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_MACOS_SURFACE))
|
||||
#define GDK_MACOS_SURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_MACOS_SURFACE, GdkMacosSurfaceClass))
|
||||
|
||||
struct _GdkMacosSurface
|
||||
{
|
||||
GdkSurface parent_instance;
|
||||
|
||||
GList main;
|
||||
GList sorted;
|
||||
GList frame;
|
||||
|
||||
GdkMacosWindow *window;
|
||||
GPtrArray *monitors;
|
||||
cairo_region_t *input_region;
|
||||
char *title;
|
||||
|
||||
int root_x;
|
||||
int root_y;
|
||||
|
||||
int shadow_top;
|
||||
int shadow_right;
|
||||
int shadow_bottom;
|
||||
int shadow_left;
|
||||
|
||||
gint64 pending_frame_counter;
|
||||
|
||||
guint did_initial_present : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosSurfaceClass
|
||||
{
|
||||
GdkSurfaceClass parent_class;
|
||||
};
|
||||
|
||||
GdkMacosSurface *_gdk_macos_surface_new (GdkMacosDisplay *display,
|
||||
GdkSurfaceType surface_type,
|
||||
GdkSurface *parent,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
NSWindow *_gdk_macos_surface_get_native (GdkMacosSurface *self);
|
||||
CGDirectDisplayID _gdk_macos_surface_get_screen_id (GdkMacosSurface *self);
|
||||
const char *_gdk_macos_surface_get_title (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_set_title (GdkMacosSurface *self,
|
||||
const gchar *title);
|
||||
void _gdk_macos_surface_get_shadow (GdkMacosSurface *self,
|
||||
gint *top,
|
||||
gint *right,
|
||||
gint *bottom,
|
||||
gint *left);
|
||||
NSView *_gdk_macos_surface_get_view (GdkMacosSurface *self);
|
||||
gboolean _gdk_macos_surface_get_modal_hint (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_set_modal_hint (GdkMacosSurface *self,
|
||||
gboolean modal_hint);
|
||||
void _gdk_macos_surface_set_geometry_hints (GdkMacosSurface *self,
|
||||
const GdkGeometry *geometry,
|
||||
GdkSurfaceHints geom_mask);
|
||||
void _gdk_macos_surface_resize (GdkMacosSurface *self,
|
||||
int width,
|
||||
int height);
|
||||
void _gdk_macos_surface_update_fullscreen_state (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_update_position (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_show (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_thaw (GdkMacosSurface *self,
|
||||
gint64 predicted_presentation_time,
|
||||
gint64 refresh_interval);
|
||||
CGContextRef _gdk_macos_surface_acquire_context (GdkMacosSurface *self,
|
||||
gboolean clear_scale,
|
||||
gboolean antialias);
|
||||
void _gdk_macos_surface_release_context (GdkMacosSurface *self,
|
||||
CGContextRef cg_context);
|
||||
void _gdk_macos_surface_synthesize_null_key (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_move (GdkMacosSurface *self,
|
||||
int x,
|
||||
int y);
|
||||
void _gdk_macos_surface_move_resize (GdkMacosSurface *self,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
gboolean _gdk_macos_surface_is_tracking (GdkMacosSurface *self,
|
||||
NSTrackingArea *area);
|
||||
void _gdk_macos_surface_monitor_changed (GdkMacosSurface *self);
|
||||
GdkMonitor *_gdk_macos_surface_get_best_monitor (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_reposition_children (GdkMacosSurface *self);
|
||||
void _gdk_macos_surface_set_opacity (GdkMacosSurface *self,
|
||||
double opacity);
|
||||
void _gdk_macos_surface_get_root_coords (GdkMacosSurface *self,
|
||||
int *x,
|
||||
int *y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_SURFACE_PRIVATE_H__ */
|
1071
gdk/macos/gdkmacossurface.c
Normal file
1071
gdk/macos/gdkmacossurface.c
Normal file
File diff suppressed because it is too large
Load Diff
43
gdk/macos/gdkmacossurface.h
Normal file
43
gdk/macos/gdkmacossurface.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_SURFACE_H__
|
||||
#define __GDK_MACOS_SURFACE_H__
|
||||
|
||||
#if !defined (__GDKMACOS_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/macos/gdkmacos.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkMacosSurface GdkMacosSurface;
|
||||
typedef struct _GdkMacosSurfaceClass GdkMacosSurfaceClass;
|
||||
|
||||
#define GDK_TYPE_MACOS_SURFACE (gdk_macos_surface_get_type())
|
||||
#define GDK_MACOS_SURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_SURFACE, GdkMacosSurface))
|
||||
#define GDK_IS_MACOS_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_SURFACE))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_macos_surface_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_SURFACE_H__ */
|
47
gdk/macos/gdkmacostoplevelsurface-private.h
Normal file
47
gdk/macos/gdkmacostoplevelsurface-private.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_TOPLEVEL_SURFACE_PRIVATE_H__
|
||||
#define __GDK_MACOS_TOPLEVEL_SURFACE_PRIVATE_H__
|
||||
|
||||
#include "gdkmacossurface-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkMacosToplevelSurface GdkMacosToplevelSurface;
|
||||
typedef struct _GdkMacosToplevelSurfaceClass GdkMacosToplevelSurfaceClass;
|
||||
|
||||
#define GDK_TYPE_MACOS_TOPLEVEL_SURFACE (_gdk_macos_toplevel_surface_get_type())
|
||||
#define GDK_MACOS_TOPLEVEL_SURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_MACOS_TOPLEVEL_SURFACE, GdkMacosToplevelSurface))
|
||||
#define GDK_IS_MACOS_TOPLEVEL_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_TOPLEVEL_SURFACE))
|
||||
|
||||
GType _gdk_macos_toplevel_surface_get_type (void);
|
||||
GdkMacosSurface *_gdk_macos_toplevel_surface_new (GdkMacosDisplay *display,
|
||||
GdkSurface *parent,
|
||||
GdkFrameClock *frame_clock,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void _gdk_macos_toplevel_surface_attach_to_parent (GdkMacosToplevelSurface *self);
|
||||
void _gdk_macos_toplevel_surface_detach_from_parent (GdkMacosToplevelSurface *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_TOPLEVEL_SURFACE_PRIVATE_H__ */
|
581
gdk/macos/gdkmacostoplevelsurface.c
Normal file
581
gdk/macos/gdkmacostoplevelsurface.c
Normal file
@ -0,0 +1,581 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
#include "gdkinternals.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacostoplevelsurface-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
|
||||
struct _GdkMacosToplevelSurface
|
||||
{
|
||||
GdkMacosSurface parent_instance;
|
||||
guint decorated : 1;
|
||||
};
|
||||
|
||||
struct _GdkMacosToplevelSurfaceClass
|
||||
{
|
||||
GdkMacosSurfaceClass parent_instance;
|
||||
};
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_fullscreen (GdkMacosToplevelSurface *self)
|
||||
{
|
||||
NSWindow *window;
|
||||
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
|
||||
if (([window styleMask] & NSWindowStyleMaskFullScreen) == 0)
|
||||
[window toggleFullScreen:window];
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_unfullscreen (GdkMacosToplevelSurface *self)
|
||||
{
|
||||
NSWindow *window;
|
||||
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
|
||||
if (([window styleMask] & NSWindowStyleMaskFullScreen) != 0)
|
||||
[window toggleFullScreen:window];
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_maximize (GdkMacosToplevelSurface *self)
|
||||
{
|
||||
NSWindow *window;
|
||||
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
|
||||
if (![window isZoomed])
|
||||
[window zoom:window];
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_unmaximize (GdkMacosToplevelSurface *self)
|
||||
{
|
||||
NSWindow *window;
|
||||
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
|
||||
if ([window isZoomed])
|
||||
[window zoom:window];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gdk_macos_toplevel_surface_present (GdkToplevel *toplevel,
|
||||
int width,
|
||||
int height,
|
||||
GdkToplevelLayout *layout)
|
||||
{
|
||||
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)toplevel;
|
||||
NSWindow *nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
GdkGeometry geometry;
|
||||
GdkSurfaceHints mask;
|
||||
NSWindowStyleMask style_mask;
|
||||
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
g_assert (GDK_IS_MACOS_WINDOW (nswindow));
|
||||
|
||||
style_mask = [nswindow styleMask];
|
||||
|
||||
if (gdk_toplevel_layout_get_resizable (layout))
|
||||
{
|
||||
geometry.min_width = gdk_toplevel_layout_get_min_width (layout);
|
||||
geometry.min_height = gdk_toplevel_layout_get_min_height (layout);
|
||||
mask = GDK_HINT_MIN_SIZE;
|
||||
|
||||
/* Only set 'Resizable' mask to get native resize zones if the window is
|
||||
* titled, otherwise we do this internally for CSD and do not need
|
||||
* NSWindow to do it for us. Additionally, it can mess things up when
|
||||
* doing a window resize since it can cause mouseDown to get passed
|
||||
* through to the next window.
|
||||
*/
|
||||
if ((style_mask & NSWindowStyleMaskTitled) != 0)
|
||||
style_mask |= NSWindowStyleMaskResizable;
|
||||
else
|
||||
style_mask &= ~NSWindowStyleMaskResizable;
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry.max_width = geometry.min_width = width;
|
||||
geometry.max_height = geometry.min_height = height;
|
||||
mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
|
||||
|
||||
style_mask &= ~NSWindowStyleMaskResizable;
|
||||
}
|
||||
|
||||
if (style_mask != [nswindow styleMask])
|
||||
[nswindow setStyleMask:style_mask];
|
||||
|
||||
_gdk_macos_surface_set_geometry_hints (GDK_MACOS_SURFACE (self), &geometry, mask);
|
||||
gdk_surface_constrain_size (&geometry, mask, width, height, &width, &height);
|
||||
_gdk_macos_surface_resize (GDK_MACOS_SURFACE (self), width, height);
|
||||
|
||||
/* Maximized state */
|
||||
if (gdk_toplevel_layout_get_maximized (layout))
|
||||
_gdk_macos_toplevel_surface_maximize (self);
|
||||
else
|
||||
_gdk_macos_toplevel_surface_unmaximize (self);
|
||||
|
||||
/* Fullscreen state */
|
||||
if (gdk_toplevel_layout_get_fullscreen (layout))
|
||||
_gdk_macos_toplevel_surface_fullscreen (self);
|
||||
else
|
||||
_gdk_macos_toplevel_surface_unfullscreen (self);
|
||||
|
||||
if (GDK_SURFACE (self)->transient_for != NULL)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!self->decorated &&
|
||||
!GDK_MACOS_SURFACE (self)->did_initial_present &&
|
||||
GDK_SURFACE (self)->x == 0 &&
|
||||
GDK_SURFACE (self)->y == 0 &&
|
||||
(GDK_MACOS_SURFACE (self)->shadow_left ||
|
||||
GDK_MACOS_SURFACE (self)->shadow_top))
|
||||
{
|
||||
GdkMonitor *monitor = _gdk_macos_surface_get_best_monitor (GDK_MACOS_SURFACE (self));
|
||||
int x = GDK_SURFACE (self)->x;
|
||||
int y = GDK_SURFACE (self)->y;
|
||||
|
||||
if (monitor != NULL)
|
||||
{
|
||||
GdkRectangle visible;
|
||||
|
||||
gdk_monitor_get_workarea (monitor, &visible);
|
||||
|
||||
if (x < visible.x)
|
||||
x = visible.x;
|
||||
|
||||
if (y < visible.y)
|
||||
y = visible.y;
|
||||
}
|
||||
|
||||
x -= GDK_MACOS_SURFACE (self)->shadow_left;
|
||||
y -= GDK_MACOS_SURFACE (self)->shadow_top;
|
||||
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self), x, y);
|
||||
}
|
||||
}
|
||||
|
||||
_gdk_macos_surface_show (GDK_MACOS_SURFACE (self));
|
||||
|
||||
GDK_MACOS_SURFACE (self)->did_initial_present = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gdk_macos_toplevel_surface_minimize (GdkToplevel *toplevel)
|
||||
{
|
||||
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)toplevel;
|
||||
NSWindow *window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
[window miniaturize:window];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gdk_macos_toplevel_surface_lower (GdkToplevel *toplevel)
|
||||
{
|
||||
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)toplevel;
|
||||
NSWindow *window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
[window orderBack:window];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_focus (GdkToplevel *toplevel,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)toplevel;
|
||||
NSWindow *nswindow;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (self))
|
||||
return;
|
||||
|
||||
nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
[nswindow makeKeyAndOrderFront:nswindow];
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_begin_resize (GdkToplevel *toplevel,
|
||||
GdkSurfaceEdge edge,
|
||||
GdkDevice *device,
|
||||
int button,
|
||||
double root_x,
|
||||
double root_y,
|
||||
guint32 timestamp)
|
||||
{
|
||||
NSWindow *nswindow;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (toplevel));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (toplevel))
|
||||
return;
|
||||
|
||||
/* Release passive grab */
|
||||
if (button != 0)
|
||||
gdk_seat_ungrab (gdk_device_get_seat (device));
|
||||
|
||||
if ((nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (toplevel))))
|
||||
[(GdkMacosWindow *)nswindow beginManualResize:edge];
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_begin_move (GdkToplevel *toplevel,
|
||||
GdkDevice *device,
|
||||
int button,
|
||||
double root_x,
|
||||
double root_y,
|
||||
guint32 timestamp)
|
||||
{
|
||||
NSWindow *nswindow;
|
||||
|
||||
g_assert (GDK_IS_MACOS_SURFACE (toplevel));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (toplevel))
|
||||
return;
|
||||
|
||||
/* Release passive grab */
|
||||
if (button != 0)
|
||||
gdk_seat_ungrab (gdk_device_get_seat (device));
|
||||
|
||||
if ((nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (toplevel))))
|
||||
[(GdkMacosWindow *)nswindow beginManualMove];
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
toplevel_iface_init (GdkToplevelInterface *iface)
|
||||
{
|
||||
iface->present = _gdk_macos_toplevel_surface_present;
|
||||
iface->minimize = _gdk_macos_toplevel_surface_minimize;
|
||||
iface->lower = _gdk_macos_toplevel_surface_lower;
|
||||
iface->focus = _gdk_macos_toplevel_surface_focus;
|
||||
iface->begin_resize = _gdk_macos_toplevel_surface_begin_resize;
|
||||
iface->begin_move = _gdk_macos_toplevel_surface_begin_move;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GdkMacosToplevelSurface, _gdk_macos_toplevel_surface, GDK_TYPE_MACOS_SURFACE,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_TOPLEVEL, toplevel_iface_init))
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_set_transient_for (GdkMacosToplevelSurface *self,
|
||||
GdkMacosSurface *parent)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
g_assert (!parent || GDK_IS_MACOS_SURFACE (parent));
|
||||
|
||||
_gdk_macos_toplevel_surface_detach_from_parent (self);
|
||||
g_clear_object (&GDK_SURFACE (self)->transient_for);
|
||||
|
||||
if (g_set_object (&GDK_SURFACE (self)->transient_for, GDK_SURFACE (parent)))
|
||||
_gdk_macos_toplevel_surface_attach_to_parent (self);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_set_decorated (GdkMacosToplevelSurface *self,
|
||||
gboolean decorated)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
decorated = !!decorated;
|
||||
|
||||
if (decorated != self->decorated)
|
||||
{
|
||||
NSWindow *window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
self->decorated = decorated;
|
||||
[(GdkMacosWindow *)window setDecorated:(BOOL)decorated];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_hide (GdkSurface *surface)
|
||||
{
|
||||
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)surface;
|
||||
|
||||
_gdk_macos_toplevel_surface_detach_from_parent (self);
|
||||
|
||||
GDK_SURFACE_CLASS (_gdk_macos_toplevel_surface_parent_class)->hide (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_destroy (GdkSurface *surface,
|
||||
gboolean foreign_destroy)
|
||||
{
|
||||
GdkMacosToplevelSurface *self = (GdkMacosToplevelSurface *)surface;
|
||||
|
||||
g_clear_object (&GDK_SURFACE (self)->transient_for);
|
||||
|
||||
GDK_SURFACE_CLASS (_gdk_macos_toplevel_surface_parent_class)->destroy (surface, foreign_destroy);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (object);
|
||||
GdkMacosSurface *base = GDK_MACOS_SURFACE (surface);
|
||||
GdkMacosToplevelSurface *toplevel = GDK_MACOS_TOPLEVEL_SURFACE (base);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_STATE:
|
||||
g_value_set_flags (value, surface->state);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_TITLE:
|
||||
g_value_set_string (value, _gdk_macos_surface_get_title (base));
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_STARTUP_ID:
|
||||
g_value_set_string (value, "");
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_TRANSIENT_FOR:
|
||||
g_value_set_object (value, GDK_SURFACE (toplevel)->transient_for);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL:
|
||||
g_value_set_boolean (value, GDK_SURFACE (toplevel)->modal_hint);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST:
|
||||
g_value_set_pointer (value, NULL);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_DECORATED:
|
||||
g_value_set_boolean (value, toplevel->decorated);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_DELETABLE:
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_FULLSCREEN_MODE:
|
||||
g_value_set_enum (value, surface->fullscreen_mode);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_SHORTCUTS_INHIBITED:
|
||||
g_value_set_boolean (value, surface->shortcuts_inhibited);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (object);
|
||||
GdkMacosSurface *base = GDK_MACOS_SURFACE (surface);
|
||||
GdkMacosToplevelSurface *toplevel = GDK_MACOS_TOPLEVEL_SURFACE (base);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_TITLE:
|
||||
_gdk_macos_surface_set_title (base, g_value_get_string (value));
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), pspec);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_STARTUP_ID:
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_TRANSIENT_FOR:
|
||||
_gdk_macos_toplevel_surface_set_transient_for (toplevel, g_value_get_object (value));
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), pspec);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL:
|
||||
GDK_SURFACE (surface)->modal_hint = g_value_get_boolean (value);
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), pspec);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST:
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_DECORATED:
|
||||
_gdk_macos_toplevel_surface_set_decorated (toplevel, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_DELETABLE:
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_FULLSCREEN_MODE:
|
||||
surface->fullscreen_mode = g_value_get_enum (value);
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), pspec);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_SHORTCUTS_INHIBITED:
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_class_init (GdkMacosToplevelSurfaceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (klass);
|
||||
|
||||
object_class->get_property = _gdk_macos_toplevel_surface_get_property;
|
||||
object_class->set_property = _gdk_macos_toplevel_surface_set_property;
|
||||
|
||||
surface_class->destroy = _gdk_macos_toplevel_surface_destroy;
|
||||
surface_class->hide = _gdk_macos_toplevel_surface_hide;
|
||||
|
||||
gdk_toplevel_install_properties (object_class, LAST_PROP);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_toplevel_surface_init (GdkMacosToplevelSurface *self)
|
||||
{
|
||||
self->decorated = TRUE;
|
||||
}
|
||||
|
||||
GdkMacosSurface *
|
||||
_gdk_macos_toplevel_surface_new (GdkMacosDisplay *display,
|
||||
GdkSurface *parent,
|
||||
GdkFrameClock *frame_clock,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkMacosWindow *window;
|
||||
GdkMacosSurface *self;
|
||||
NSScreen *screen;
|
||||
NSUInteger style_mask;
|
||||
NSRect content_rect;
|
||||
NSRect screen_rect;
|
||||
int nx;
|
||||
int ny;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
|
||||
g_return_val_if_fail (!frame_clock || GDK_IS_FRAME_CLOCK (frame_clock), NULL);
|
||||
g_return_val_if_fail (!parent || GDK_IS_MACOS_SURFACE (parent), NULL);
|
||||
|
||||
style_mask = (NSWindowStyleMaskTitled |
|
||||
NSWindowStyleMaskClosable |
|
||||
NSWindowStyleMaskMiniaturizable |
|
||||
NSWindowStyleMaskResizable);
|
||||
|
||||
_gdk_macos_display_to_display_coords (display, x, y, &nx, &ny);
|
||||
|
||||
screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
|
||||
screen_rect = [screen visibleFrame];
|
||||
nx -= screen_rect.origin.x;
|
||||
ny -= screen_rect.origin.y;
|
||||
content_rect = NSMakeRect (nx, ny - height, width, height);
|
||||
|
||||
window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
|
||||
styleMask:style_mask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO
|
||||
screen:screen];
|
||||
|
||||
self = g_object_new (GDK_TYPE_MACOS_TOPLEVEL_SURFACE,
|
||||
"display", display,
|
||||
"frame-clock", frame_clock,
|
||||
"native", window,
|
||||
NULL);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&self);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_toplevel_surface_attach_to_parent (GdkMacosToplevelSurface *self)
|
||||
{
|
||||
GdkSurface *surface = (GdkSurface *)self;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
if (surface->transient_for != NULL &&
|
||||
!GDK_SURFACE_DESTROYED (surface->transient_for))
|
||||
{
|
||||
NSWindow *parent = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface->transient_for));
|
||||
NSWindow *window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
|
||||
[parent addChildWindow:window ordered:NSWindowAbove];
|
||||
|
||||
if (GDK_SURFACE (self)->modal_hint)
|
||||
[window setLevel:NSModalPanelWindowLevel];
|
||||
|
||||
_gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (surface->display));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_toplevel_surface_detach_from_parent (GdkMacosToplevelSurface *self)
|
||||
{
|
||||
GdkSurface *surface = (GdkSurface *)self;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_TOPLEVEL_SURFACE (self));
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
if (surface->transient_for != NULL &&
|
||||
!GDK_SURFACE_DESTROYED (surface->transient_for))
|
||||
{
|
||||
NSWindow *parent = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface->transient_for));
|
||||
NSWindow *window = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (self));
|
||||
|
||||
[parent removeChildWindow:window];
|
||||
[window setLevel:NSNormalWindowLevel];
|
||||
|
||||
_gdk_macos_display_clear_sorting (GDK_MACOS_DISPLAY (surface->display));
|
||||
}
|
||||
}
|
36
gdk/macos/gdkmacosutils-private.h
Normal file
36
gdk/macos/gdkmacosutils-private.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_UTILS_PRIVATE_H__
|
||||
#define __GDK_MACOS_UTILS_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#define GDK_BEGIN_MACOS_ALLOC_POOL NSAutoreleasePool *_pool = [[NSAutoreleasePool alloc] init]
|
||||
#define GDK_END_MACOS_ALLOC_POOL [_pool release]
|
||||
|
||||
static inline gboolean
|
||||
queue_contains (GQueue *queue,
|
||||
GList *link_)
|
||||
{
|
||||
return queue->head == link_ || link_->prev || link_->next;
|
||||
}
|
||||
|
||||
#endif /* __GDK_MACOS_UTILS_PRIVATE_H__ */
|
62
gdk/macos/meson.build
Normal file
62
gdk/macos/meson.build
Normal file
@ -0,0 +1,62 @@
|
||||
gdk_macos_sources = files([
|
||||
'edgesnapping.c',
|
||||
|
||||
'gdkdisplaylinksource.c',
|
||||
'gdkmacoscairocontext.c',
|
||||
'gdkmacosclipboard.c',
|
||||
'gdkmacoscursor.c',
|
||||
'gdkmacosdevice.c',
|
||||
'gdkmacosdisplay.c',
|
||||
'gdkmacosdisplay-settings.c',
|
||||
'gdkmacosdisplay-translate.c',
|
||||
'gdkmacosdrag.c',
|
||||
'gdkmacosdragsurface.c',
|
||||
'gdkmacosglcontext.c',
|
||||
'gdkmacoseventsource.c',
|
||||
'gdkmacoskeymap.c',
|
||||
'gdkmacosmonitor.c',
|
||||
'gdkmacospopupsurface.c',
|
||||
'gdkmacosseat.c',
|
||||
'gdkmacossurface.c',
|
||||
'gdkmacostoplevelsurface.c',
|
||||
|
||||
'GdkMacosBaseView.c',
|
||||
'GdkMacosCairoView.c',
|
||||
'GdkMacosCairoSubview.c',
|
||||
'GdkMacosGLLayer.c',
|
||||
'GdkMacosWindow.c',
|
||||
])
|
||||
|
||||
gdk_macos_public_headers = files([
|
||||
'gdkmacosdevice.h',
|
||||
'gdkmacosdisplay.h',
|
||||
'gdkmacosglcontext.h',
|
||||
'gdkmacoskeymap.h',
|
||||
'gdkmacosmonitor.h',
|
||||
'gdkmacossurface.h',
|
||||
])
|
||||
|
||||
install_headers(gdk_macos_public_headers, 'gdkmacos.h', subdir: 'gtk-4.0/gdk/macos/')
|
||||
|
||||
gdk_macos_frameworks = [
|
||||
'AppKit',
|
||||
'Carbon',
|
||||
'CoreVideo',
|
||||
'CoreServices',
|
||||
'OpenGL',
|
||||
'QuartzCore',
|
||||
]
|
||||
|
||||
gdk_macos_deps = [
|
||||
dependency('appleframeworks', modules: gdk_macos_frameworks)
|
||||
]
|
||||
|
||||
libgdk_c_args += ['-xobjective-c']
|
||||
|
||||
libgdk_macos = static_library('gdk-macos',
|
||||
gdk_macos_sources, gdkconfig, gdkenum_h,
|
||||
include_directories: [ confinc, gdkinc, ],
|
||||
c_args: libgdk_c_args + common_cflags,
|
||||
link_args: common_ldflags,
|
||||
link_with: [],
|
||||
dependencies: gdk_deps + gdk_macos_deps)
|
@ -143,6 +143,7 @@ gdkconfig_cdata.set('GDK_WINDOWING_X11', x11_enabled)
|
||||
gdkconfig_cdata.set('GDK_WINDOWING_WAYLAND', wayland_enabled)
|
||||
gdkconfig_cdata.set('GDK_WINDOWING_WIN32', win32_enabled)
|
||||
gdkconfig_cdata.set('GDK_WINDOWING_BROADWAY', broadway_enabled)
|
||||
gdkconfig_cdata.set('GDK_WINDOWING_MACOS', macos_enabled)
|
||||
gdkconfig_cdata.set('GDK_RENDERING_VULKAN', have_vulkan)
|
||||
|
||||
gdkconfig = configure_file(
|
||||
@ -216,9 +217,14 @@ if wayland_enabled or broadway_enabled
|
||||
endif
|
||||
endif
|
||||
|
||||
libgdk_c_args = [
|
||||
'-DGTK_COMPILATION',
|
||||
'-DG_LOG_DOMAIN="Gdk"',
|
||||
]
|
||||
|
||||
gdk_backends = []
|
||||
gdk_backends_gen_headers = [] # non-public generated headers
|
||||
foreach backend : ['broadway', 'quartz', 'wayland', 'win32', 'x11']
|
||||
foreach backend : ['broadway', 'quartz', 'wayland', 'win32', 'x11', 'macos']
|
||||
if get_variable('@0@_enabled'.format(backend))
|
||||
subdir(backend)
|
||||
gdk_deps += get_variable('gdk_@0@_deps'.format(backend))
|
||||
@ -235,16 +241,12 @@ if gdk_backends.length() == 0
|
||||
error('No backends enabled')
|
||||
endif
|
||||
|
||||
# FIXME: might have to add '-xobjective-c' to c_args for quartz backend?
|
||||
libgdk = static_library('gdk',
|
||||
sources: [gdk_sources, gdk_backends_gen_headers, gdkconfig],
|
||||
dependencies: gdk_deps + [libgtk_css_dep],
|
||||
link_with: [libgtk_css, ],
|
||||
include_directories: [confinc, gdkx11_inc, wlinc],
|
||||
c_args: [
|
||||
'-DGTK_COMPILATION',
|
||||
'-DG_LOG_DOMAIN="Gdk"',
|
||||
] + common_cflags,
|
||||
c_args: libgdk_c_args + common_cflags,
|
||||
link_whole: gdk_backends,
|
||||
link_args: common_ldflags)
|
||||
|
||||
|
@ -1,845 +0,0 @@
|
||||
/* GdkQuartzSurface.m
|
||||
*
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#import "GdkQuartzNSWindow.h"
|
||||
#include "gdkquartzsurface.h"
|
||||
#include "gdkdnd-quartz.h"
|
||||
#include "gdkprivate-quartz.h"
|
||||
|
||||
@implementation GdkQuartzNSWindow
|
||||
|
||||
- (void)windowWillClose:(NSNotification*)notification
|
||||
{
|
||||
// Clears the delegate when window is going to be closed; since EL
|
||||
// Capitan it is possible that the methods of delegate would get
|
||||
// called after the window has been closed.
|
||||
[self setDelegate:nil];
|
||||
}
|
||||
|
||||
-(BOOL)windowShouldClose:(id)sender
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_event_new (GDK_DELETE);
|
||||
|
||||
event->any.surface = g_object_ref (window);
|
||||
event->any.send_event = FALSE;
|
||||
|
||||
_gdk_event_queue_append (gdk_display_get_default (), event);
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)windowWillMiniaturize:(NSNotification *)aNotification
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
|
||||
_gdk_quartz_surface_detach_from_parent (window);
|
||||
}
|
||||
|
||||
-(void)windowDidMiniaturize:(NSNotification *)aNotification
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
|
||||
gdk_synthesize_surface_state (window, 0, GDK_SURFACE_STATE_MINIMIZED);
|
||||
}
|
||||
|
||||
-(void)windowDidDeminiaturize:(NSNotification *)aNotification
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
|
||||
_gdk_quartz_surface_attach_to_parent (window);
|
||||
|
||||
gdk_synthesize_surface_state (window, GDK_SURFACE_STATE_MINIMIZED, 0);
|
||||
}
|
||||
|
||||
-(void)windowDidBecomeKey:(NSNotification *)aNotification
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
|
||||
gdk_synthesize_surface_state (window, 0, GDK_SURFACE_STATE_FOCUSED);
|
||||
_gdk_quartz_events_update_focus_window (window, TRUE);
|
||||
}
|
||||
|
||||
-(void)windowDidResignKey:(NSNotification *)aNotification
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
|
||||
_gdk_quartz_events_update_focus_window (window, FALSE);
|
||||
gdk_synthesize_surface_state (window, GDK_SURFACE_STATE_FOCUSED, 0);
|
||||
}
|
||||
|
||||
-(void)windowDidBecomeMain:(NSNotification *)aNotification
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
|
||||
if (![self isVisible])
|
||||
{
|
||||
/* Note: This is a hack needed because for unknown reasons, hidden
|
||||
* windows get shown when clicking the dock icon when the application
|
||||
* is not already active.
|
||||
*/
|
||||
[self orderOut:nil];
|
||||
return;
|
||||
}
|
||||
|
||||
_gdk_quartz_surface_did_become_main (window);
|
||||
}
|
||||
|
||||
-(void)windowDidResignMain:(NSNotification *)aNotification
|
||||
{
|
||||
GdkSurface *window;
|
||||
|
||||
window = [[self contentView] gdkSurface];
|
||||
_gdk_quartz_surface_did_resign_main (window);
|
||||
}
|
||||
|
||||
/* Used in combination with NSLeftMouseUp in sendEvent to keep track
|
||||
* of when the window is being moved with the mouse.
|
||||
*/
|
||||
-(void)windowWillMove:(NSNotification *)aNotification
|
||||
{
|
||||
inMove = YES;
|
||||
}
|
||||
|
||||
-(void)sendEvent:(NSEvent *)event
|
||||
{
|
||||
switch ([event type])
|
||||
{
|
||||
case NSLeftMouseUp:
|
||||
{
|
||||
double time = ((double)[event timestamp]) * 1000.0;
|
||||
|
||||
_gdk_quartz_events_break_all_grabs (time);
|
||||
inManualMove = NO;
|
||||
inManualResize = NO;
|
||||
inMove = NO;
|
||||
break;
|
||||
}
|
||||
|
||||
case NSLeftMouseDragged:
|
||||
if ([self trackManualMove] || [self trackManualResize])
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
[super sendEvent:event];
|
||||
}
|
||||
|
||||
-(BOOL)isInMove
|
||||
{
|
||||
return inMove;
|
||||
}
|
||||
|
||||
-(void)checkSendEnterNotify
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
|
||||
|
||||
/* When a new window has been created, and the mouse
|
||||
* is in the window area, we will not receive an NSMouseEntered
|
||||
* event. Therefore, we synthesize an enter notify event manually.
|
||||
*/
|
||||
if (!initialPositionKnown)
|
||||
{
|
||||
initialPositionKnown = YES;
|
||||
|
||||
if (NSPointInRect ([NSEvent mouseLocation], [self frame]))
|
||||
{
|
||||
NSEvent *event;
|
||||
|
||||
event = [NSEvent enterExitEventWithType: NSMouseEntered
|
||||
location: [self mouseLocationOutsideOfEventStream]
|
||||
modifierFlags: 0
|
||||
timestamp: [[NSApp currentEvent] timestamp]
|
||||
windowNumber: [impl->toplevel windowNumber]
|
||||
context: NULL
|
||||
eventNumber: 0
|
||||
trackingNumber: [impl->view trackingRect]
|
||||
userData: nil];
|
||||
|
||||
[NSApp postEvent:event atStart:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)windowDidMove:(NSNotification *)aNotification
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
GdkEvent *event;
|
||||
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
|
||||
gboolean maximized = gdk_surface_get_state (window) & GDK_SURFACE_STATE_MAXIMIZED;
|
||||
|
||||
/* In case the window is changed when maximized remove the maximized state */
|
||||
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
|
||||
{
|
||||
gdk_synthesize_surface_state (window,
|
||||
GDK_SURFACE_STATE_MAXIMIZED,
|
||||
0);
|
||||
}
|
||||
|
||||
_gdk_quartz_surface_update_position (window);
|
||||
|
||||
/* Synthesize a configure event */
|
||||
event = gdk_event_new (GDK_CONFIGURE);
|
||||
event->configure.window = g_object_ref (window);
|
||||
event->configure.x = window->x;
|
||||
event->configure.y = window->y;
|
||||
event->configure.width = window->width;
|
||||
event->configure.height = window->height;
|
||||
|
||||
_gdk_event_queue_append (gdk_display_get_default (), event);
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(void)windowDidResize:(NSNotification *)aNotification
|
||||
{
|
||||
NSRect content_rect = [self contentRectForFrameRect:[self frame]];
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
GdkEvent *event;
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
|
||||
gboolean maximized = gdk_surface_get_state (window) & GDK_SURFACE_STATE_MAXIMIZED;
|
||||
|
||||
/* see same in windowDidMove */
|
||||
if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
|
||||
{
|
||||
gdk_synthesize_surface_state (window,
|
||||
GDK_SURFACE_STATE_MAXIMIZED,
|
||||
0);
|
||||
}
|
||||
|
||||
window->width = content_rect.size.width;
|
||||
window->height = content_rect.size.height;
|
||||
|
||||
/* Certain resize operations (e.g. going fullscreen), also move the
|
||||
* origin of the window.
|
||||
*/
|
||||
_gdk_quartz_surface_update_position (window);
|
||||
|
||||
[[self contentView] setFrame:NSMakeRect (0, 0, window->width, window->height)];
|
||||
|
||||
_gdk_surface_update_size (window);
|
||||
|
||||
/* Synthesize a configure event */
|
||||
event = gdk_event_new (GDK_CONFIGURE);
|
||||
event->configure.window = g_object_ref (window);
|
||||
event->configure.x = window->x;
|
||||
event->configure.y = window->y;
|
||||
event->configure.width = window->width;
|
||||
event->configure.height = window->height;
|
||||
|
||||
_gdk_event_queue_append (gdk_display_get_default (), event);
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
-(id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag screen:(NSScreen *)screen
|
||||
{
|
||||
self = [super initWithContentRect:contentRect
|
||||
styleMask:styleMask
|
||||
backing:backingType
|
||||
defer:flag
|
||||
screen:screen];
|
||||
|
||||
[self setAcceptsMouseMovedEvents:YES];
|
||||
[self setDelegate:self];
|
||||
[self setReleasedWhenClosed:YES];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(BOOL)canBecomeMainWindow
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
|
||||
|
||||
switch (impl->type_hint)
|
||||
{
|
||||
case GDK_SURFACE_TYPE_HINT_NORMAL:
|
||||
case GDK_SURFACE_TYPE_HINT_DIALOG:
|
||||
return YES;
|
||||
|
||||
case GDK_SURFACE_TYPE_HINT_MENU:
|
||||
case GDK_SURFACE_TYPE_HINT_TOOLBAR:
|
||||
case GDK_SURFACE_TYPE_HINT_SPLASHSCREEN:
|
||||
case GDK_SURFACE_TYPE_HINT_UTILITY:
|
||||
case GDK_SURFACE_TYPE_HINT_DOCK:
|
||||
case GDK_SURFACE_TYPE_HINT_DESKTOP:
|
||||
case GDK_SURFACE_TYPE_HINT_DROPDOWN_MENU:
|
||||
case GDK_SURFACE_TYPE_HINT_POPUP_MENU:
|
||||
case GDK_SURFACE_TYPE_HINT_TOOLTIP:
|
||||
case GDK_SURFACE_TYPE_HINT_NOTIFICATION:
|
||||
case GDK_SURFACE_TYPE_HINT_COMBO:
|
||||
case GDK_SURFACE_TYPE_HINT_DND:
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)canBecomeKeyWindow
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
|
||||
|
||||
if (!window->accept_focus)
|
||||
return NO;
|
||||
|
||||
/* Popup windows should not be able to get focused in the window
|
||||
* manager sense, it's only handled through grabs.
|
||||
*/
|
||||
if (window->surface_type == GDK_SURFACE_TEMP)
|
||||
return NO;
|
||||
|
||||
switch (impl->type_hint)
|
||||
{
|
||||
case GDK_SURFACE_TYPE_HINT_NORMAL:
|
||||
case GDK_SURFACE_TYPE_HINT_DIALOG:
|
||||
case GDK_SURFACE_TYPE_HINT_MENU:
|
||||
case GDK_SURFACE_TYPE_HINT_TOOLBAR:
|
||||
case GDK_SURFACE_TYPE_HINT_UTILITY:
|
||||
case GDK_SURFACE_TYPE_HINT_DOCK:
|
||||
case GDK_SURFACE_TYPE_HINT_DESKTOP:
|
||||
case GDK_SURFACE_TYPE_HINT_DROPDOWN_MENU:
|
||||
case GDK_SURFACE_TYPE_HINT_POPUP_MENU:
|
||||
case GDK_SURFACE_TYPE_HINT_COMBO:
|
||||
return YES;
|
||||
|
||||
case GDK_SURFACE_TYPE_HINT_SPLASHSCREEN:
|
||||
case GDK_SURFACE_TYPE_HINT_TOOLTIP:
|
||||
case GDK_SURFACE_TYPE_HINT_NOTIFICATION:
|
||||
case GDK_SURFACE_TYPE_HINT_DND:
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)showAndMakeKey:(BOOL)makeKey
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
|
||||
|
||||
inShowOrHide = YES;
|
||||
|
||||
if (makeKey)
|
||||
[impl->toplevel makeKeyAndOrderFront:impl->toplevel];
|
||||
else
|
||||
[impl->toplevel orderFront:nil];
|
||||
|
||||
inShowOrHide = NO;
|
||||
|
||||
[self checkSendEnterNotify];
|
||||
}
|
||||
|
||||
- (void)hide
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
|
||||
|
||||
inShowOrHide = YES;
|
||||
[impl->toplevel orderOut:nil];
|
||||
inShowOrHide = NO;
|
||||
|
||||
initialPositionKnown = NO;
|
||||
}
|
||||
|
||||
- (BOOL)trackManualMove
|
||||
{
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
|
||||
NSPoint currentLocation;
|
||||
NSPoint newOrigin;
|
||||
NSRect screenFrame = [[NSScreen mainScreen] visibleFrame];
|
||||
NSRect windowFrame = [self frame];
|
||||
|
||||
if (!inManualMove)
|
||||
return NO;
|
||||
|
||||
currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
newOrigin.x = currentLocation.x - initialMoveLocation.x;
|
||||
newOrigin.y = currentLocation.y - initialMoveLocation.y;
|
||||
|
||||
/* Clamp vertical position to below the menu bar. */
|
||||
if (newOrigin.y + windowFrame.size.height - impl->shadow_top > screenFrame.origin.y + screenFrame.size.height)
|
||||
newOrigin.y = screenFrame.origin.y + screenFrame.size.height - windowFrame.size.height + impl->shadow_top;
|
||||
|
||||
[self setFrameOrigin:newOrigin];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
/* Used by gdkevents-quartz.c to decide if our sendEvent() handler above
|
||||
* will see the event or if it will be subjected to standard processing
|
||||
* by GDK.
|
||||
*/
|
||||
-(BOOL)isInManualResizeOrMove
|
||||
{
|
||||
return inManualResize || inManualMove;
|
||||
}
|
||||
|
||||
-(void)beginManualMove
|
||||
{
|
||||
NSRect frame = [self frame];
|
||||
|
||||
if (inMove || inManualMove || inManualResize)
|
||||
return;
|
||||
|
||||
inManualMove = YES;
|
||||
|
||||
initialMoveLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
initialMoveLocation.x -= frame.origin.x;
|
||||
initialMoveLocation.y -= frame.origin.y;
|
||||
}
|
||||
|
||||
- (BOOL)trackManualResize
|
||||
{
|
||||
NSPoint mouse_location;
|
||||
NSRect new_frame;
|
||||
float mdx, mdy, dw, dh, dx, dy;
|
||||
NSSize min_size;
|
||||
|
||||
if (!inManualResize || inTrackManualResize)
|
||||
return NO;
|
||||
|
||||
inTrackManualResize = YES;
|
||||
|
||||
mouse_location = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
mdx = initialResizeLocation.x - mouse_location.x;
|
||||
mdy = initialResizeLocation.y - mouse_location.y;
|
||||
|
||||
/* Set how a mouse location delta translates to changes in width,
|
||||
* height and position.
|
||||
*/
|
||||
dw = dh = dx = dy = 0.0;
|
||||
if (resizeEdge == GDK_SURFACE_EDGE_EAST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_NORTH_EAST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_SOUTH_EAST)
|
||||
{
|
||||
dw = -1.0;
|
||||
}
|
||||
if (resizeEdge == GDK_SURFACE_EDGE_NORTH ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_NORTH_WEST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_NORTH_EAST)
|
||||
{
|
||||
dh = -1.0;
|
||||
}
|
||||
if (resizeEdge == GDK_SURFACE_EDGE_SOUTH ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_SOUTH_WEST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_SOUTH_EAST)
|
||||
{
|
||||
dh = 1.0;
|
||||
dy = -1.0;
|
||||
}
|
||||
if (resizeEdge == GDK_SURFACE_EDGE_WEST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_NORTH_WEST ||
|
||||
resizeEdge == GDK_SURFACE_EDGE_SOUTH_WEST)
|
||||
{
|
||||
dw = 1.0;
|
||||
dx = -1.0;
|
||||
}
|
||||
|
||||
/* Apply changes to the frame captured when we started resizing */
|
||||
new_frame = initialResizeFrame;
|
||||
new_frame.origin.x += mdx * dx;
|
||||
new_frame.origin.y += mdy * dy;
|
||||
new_frame.size.width += mdx * dw;
|
||||
new_frame.size.height += mdy * dh;
|
||||
|
||||
/* In case the resulting window would be too small reduce the
|
||||
* change to both size and position.
|
||||
*/
|
||||
min_size = [self contentMinSize];
|
||||
|
||||
if (new_frame.size.width < min_size.width)
|
||||
{
|
||||
if (dx)
|
||||
new_frame.origin.x -= min_size.width - new_frame.size.width;
|
||||
new_frame.size.width = min_size.width;
|
||||
}
|
||||
|
||||
if (new_frame.size.height < min_size.height)
|
||||
{
|
||||
if (dy)
|
||||
new_frame.origin.y -= min_size.height - new_frame.size.height;
|
||||
new_frame.size.height = min_size.height;
|
||||
}
|
||||
|
||||
/* We could also apply aspect ratio:
|
||||
new_frame.size.height = new_frame.size.width / [self aspectRatio].width * [self aspectRatio].height;
|
||||
*/
|
||||
|
||||
[self setFrame:new_frame display:YES];
|
||||
|
||||
/* Let the resizing be handled by GTK+. */
|
||||
if (g_main_context_pending (NULL))
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
|
||||
inTrackManualResize = NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)beginManualResize:(GdkSurfaceEdge)edge
|
||||
{
|
||||
if (inMove || inManualMove || inManualResize)
|
||||
return;
|
||||
|
||||
inManualResize = YES;
|
||||
resizeEdge = edge;
|
||||
|
||||
initialResizeFrame = [self frame];
|
||||
initialResizeLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
|
||||
}
|
||||
|
||||
|
||||
|
||||
static GdkDragContext *current_context = NULL;
|
||||
|
||||
static GdkDragAction
|
||||
drag_operation_to_drag_action (NSDragOperation operation)
|
||||
{
|
||||
GdkDragAction result = 0;
|
||||
|
||||
/* GDK and Quartz drag operations do not map 1:1.
|
||||
* This mapping represents about the best that we
|
||||
* can come up.
|
||||
*/
|
||||
|
||||
if (operation & NSDragOperationGeneric)
|
||||
result |= GDK_ACTION_MOVE;
|
||||
if (operation & NSDragOperationCopy)
|
||||
result |= GDK_ACTION_COPY;
|
||||
if (operation & NSDragOperationMove)
|
||||
result |= GDK_ACTION_MOVE;
|
||||
if (operation & NSDragOperationLink)
|
||||
result |= GDK_ACTION_LINK;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static NSDragOperation
|
||||
drag_action_to_drag_operation (GdkDragAction action)
|
||||
{
|
||||
NSDragOperation result = 0;
|
||||
|
||||
if (action & GDK_ACTION_COPY)
|
||||
result |= NSDragOperationCopy;
|
||||
if (action & GDK_ACTION_LINK)
|
||||
result |= NSDragOperationLink;
|
||||
if (action & GDK_ACTION_MOVE)
|
||||
result |= NSDragOperationMove;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
update_context_from_dragging_info (id <NSDraggingInfo> sender)
|
||||
{
|
||||
GdkDragAction action;
|
||||
|
||||
g_assert (current_context != NULL);
|
||||
|
||||
GDK_QUARTZ_DRAG_CONTEXT (current_context)->dragging_info = sender;
|
||||
action = drag_operation_to_drag_action ([sender draggingSourceOperationMask]);
|
||||
gdk_drag_context_set_actions (current_context, action, action);
|
||||
}
|
||||
|
||||
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
GdkEvent *event;
|
||||
GdkSurface *window;
|
||||
|
||||
if (current_context)
|
||||
g_object_unref (current_context);
|
||||
|
||||
current_context = g_object_new (GDK_TYPE_QUARTZ_DRAG_CONTEXT,
|
||||
"device", gdk_seat_get_pointer (gdk_display_get_default_seat (current_context->display)),
|
||||
NULL);
|
||||
update_context_from_dragging_info (sender);
|
||||
|
||||
window = [[self contentView] gdkSurface];
|
||||
|
||||
event = gdk_event_new (GDK_DRAG_ENTER);
|
||||
event->dnd.window = g_object_ref (window);
|
||||
event->dnd.send_event = FALSE;
|
||||
event->dnd.context = g_object_ref (current_context);
|
||||
event->dnd.time = GDK_CURRENT_TIME;
|
||||
|
||||
gdk_event_set_device (event, gdk_drag_context_get_device (current_context));
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (gdk_drag_context_get_device (current_context)));
|
||||
|
||||
_gdk_event_emit (event);
|
||||
|
||||
g_object_unref (event);
|
||||
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
- (void)draggingEnded:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
/* leave a note for the source about what action was taken */
|
||||
if (_gdk_quartz_drag_source_context && current_context)
|
||||
_gdk_quartz_drag_source_context->action = current_context->action;
|
||||
|
||||
if (current_context)
|
||||
g_object_unref (current_context);
|
||||
current_context = NULL;
|
||||
}
|
||||
|
||||
- (void)draggingExited:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_event_new (GDK_DRAG_LEAVE);
|
||||
event->dnd.window = g_object_ref ([[self contentView] gdkSurface]);
|
||||
event->dnd.send_event = FALSE;
|
||||
event->dnd.context = g_object_ref (current_context);
|
||||
event->dnd.time = GDK_CURRENT_TIME;
|
||||
|
||||
gdk_event_set_device (event, gdk_drag_context_get_device (current_context));
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (gdk_drag_context_get_device (current_context)));
|
||||
|
||||
_gdk_event_emit (event);
|
||||
|
||||
g_object_unref (event);
|
||||
|
||||
g_object_unref (current_context);
|
||||
current_context = NULL;
|
||||
}
|
||||
|
||||
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPoint point = [sender draggingLocation];
|
||||
NSPoint screen_point = [self convertBaseToScreen:point];
|
||||
GdkEvent *event;
|
||||
int gx, gy;
|
||||
|
||||
update_context_from_dragging_info (sender);
|
||||
_gdk_quartz_surface_nspoint_to_gdk_xy (screen_point, &gx, &gy);
|
||||
|
||||
event = gdk_event_new (GDK_DRAG_MOTION);
|
||||
event->dnd.window = g_object_ref ([[self contentView] gdkSurface]);
|
||||
event->dnd.send_event = FALSE;
|
||||
event->dnd.context = g_object_ref (current_context);
|
||||
event->dnd.time = GDK_CURRENT_TIME;
|
||||
event->dnd.x_root = gx;
|
||||
event->dnd.y_root = gy;
|
||||
|
||||
gdk_event_set_device (event, gdk_drag_context_get_device (current_context));
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (gdk_drag_context_get_device (current_context)));
|
||||
|
||||
_gdk_event_emit (event);
|
||||
|
||||
g_object_unref (event);
|
||||
|
||||
return drag_action_to_drag_operation (current_context->action);
|
||||
}
|
||||
|
||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPoint point = [sender draggingLocation];
|
||||
NSPoint screen_point = [self convertBaseToScreen:point];
|
||||
GdkEvent *event;
|
||||
int gy, gx;
|
||||
|
||||
update_context_from_dragging_info (sender);
|
||||
_gdk_quartz_surface_nspoint_to_gdk_xy (screen_point, &gx, &gy);
|
||||
|
||||
event = gdk_event_new (GDK_DROP_START);
|
||||
event->dnd.window = g_object_ref ([[self contentView] gdkSurface]);
|
||||
event->dnd.send_event = FALSE;
|
||||
event->dnd.context = g_object_ref (current_context);
|
||||
event->dnd.time = GDK_CURRENT_TIME;
|
||||
event->dnd.x_root = gx;
|
||||
event->dnd.y_root = gy;
|
||||
|
||||
gdk_event_set_device (event, gdk_drag_context_get_device (current_context));
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (gdk_drag_context_get_device (current_context)));
|
||||
|
||||
_gdk_event_emit (event);
|
||||
|
||||
g_object_unref (event);
|
||||
|
||||
g_object_unref (current_context);
|
||||
current_context = NULL;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)wantsPeriodicDraggingUpdates
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
|
||||
{
|
||||
GdkEvent *event;
|
||||
GdkDisplay *display;
|
||||
GdkDevice *device;
|
||||
|
||||
g_assert (_gdk_quartz_drag_source_context != NULL);
|
||||
|
||||
event = gdk_event_new (GDK_DROP_FINISHED);
|
||||
event->dnd.window = g_object_ref ([[self contentView] gdkSurface]);
|
||||
event->dnd.send_event = FALSE;
|
||||
event->dnd.context = g_object_ref (_gdk_quartz_drag_source_context);
|
||||
|
||||
display = gdk_surface_get_display (event->dnd.window);
|
||||
|
||||
if (display)
|
||||
{
|
||||
GList* windows, *list;
|
||||
gint gx, gy;
|
||||
|
||||
event->dnd.context->dest_surface = NULL;
|
||||
|
||||
windows = get_toplevels ();
|
||||
_gdk_quartz_surface_nspoint_to_gdk_xy (aPoint, &gx, &gy);
|
||||
|
||||
for (list = windows; list; list = list->next)
|
||||
{
|
||||
GdkSurface* win = (GdkSurface*) list->data;
|
||||
gint wx, wy;
|
||||
gint ww, wh;
|
||||
|
||||
gdk_surface_get_root_origin (win, &wx, &wy);
|
||||
ww = gdk_surface_get_width (win);
|
||||
wh = gdk_surface_get_height (win);
|
||||
|
||||
if (gx > wx && gy > wy && gx <= wx + ww && gy <= wy + wh)
|
||||
event->dnd.context->dest_surface = win;
|
||||
}
|
||||
}
|
||||
|
||||
device = gdk_drag_context_get_device (_gdk_quartz_drag_source_context);
|
||||
gdk_event_set_device (event, device);
|
||||
gdk_event_set_seat (event, gdk_device_get_seat (device));
|
||||
|
||||
_gdk_event_emit (event);
|
||||
|
||||
g_object_unref (event);
|
||||
|
||||
g_object_unref (_gdk_quartz_drag_source_context);
|
||||
_gdk_quartz_drag_source_context = NULL;
|
||||
}
|
||||
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER
|
||||
|
||||
- (void)setStyleMask:(NSUInteger)styleMask
|
||||
{
|
||||
gboolean was_fullscreen;
|
||||
gboolean is_fullscreen;
|
||||
|
||||
was_fullscreen = (([self styleMask] & NSFullScreenWindowMask) != 0);
|
||||
|
||||
[super setStyleMask:styleMask];
|
||||
|
||||
is_fullscreen = (([self styleMask] & NSFullScreenWindowMask) != 0);
|
||||
|
||||
if (was_fullscreen != is_fullscreen)
|
||||
_gdk_quartz_surface_update_fullscreen_state ([[self contentView] gdkSurface]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
|
||||
{
|
||||
NSRect rect;
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
|
||||
|
||||
/* Allow the window to move up "shadow_top" more than normally allowed
|
||||
* by the default impl. This makes it possible to move windows with
|
||||
* client side shadow right up to the screen's menu bar. */
|
||||
rect = [super constrainFrameRect:frameRect toScreen:screen];
|
||||
if (frameRect.origin.y > rect.origin.y)
|
||||
rect.origin.y = MIN (frameRect.origin.y, rect.origin.y + impl->shadow_top);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
- (NSRect)windowWillUseStandardFrame:(NSWindow *)nsWindow
|
||||
defaultFrame:(NSRect)newFrame
|
||||
{
|
||||
NSRect screenFrame = [[self screen] visibleFrame];
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
|
||||
gboolean maximized = gdk_surface_get_state (window) & GDK_SURFACE_STATE_MAXIMIZED;
|
||||
|
||||
if (!maximized)
|
||||
return screenFrame;
|
||||
else
|
||||
return lastUnmaximizedFrame;
|
||||
}
|
||||
|
||||
- (BOOL)windowShouldZoom:(NSWindow *)nsWindow
|
||||
toFrame:(NSRect)newFrame
|
||||
{
|
||||
|
||||
GdkSurface *window = [[self contentView] gdkSurface];
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
|
||||
gboolean maximized = gdk_surface_get_state (window) & GDK_SURFACE_STATE_MAXIMIZED;
|
||||
|
||||
if (maximized)
|
||||
{
|
||||
lastMaximizedFrame = newFrame;
|
||||
gdk_synthesize_surface_state (window,
|
||||
GDK_SURFACE_STATE_MAXIMIZED,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
lastUnmaximizedFrame = [nsWindow frame];
|
||||
gdk_synthesize_surface_state (window,
|
||||
0,
|
||||
GDK_SURFACE_STATE_MAXIMIZED);
|
||||
}
|
||||
|
||||
inMaximizeTransition = YES;
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)windowDidEndLiveResize:(NSNotification *)aNotification
|
||||
{
|
||||
inMaximizeTransition = NO;
|
||||
}
|
||||
|
||||
-(NSSize)window:(NSWindow *)window willUseFullScreenContentSize:(NSSize)proposedSize
|
||||
{
|
||||
return [[window screen] frame].size;
|
||||
}
|
||||
|
||||
-(void)windowWillEnterFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
lastUnfullscreenFrame = [self frame];
|
||||
}
|
||||
|
||||
-(void)windowWillExitFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
[self setFrame:lastUnfullscreenFrame display:YES];
|
||||
}
|
||||
|
||||
@end
|
@ -1,61 +0,0 @@
|
||||
/* GdkQuartzNSWindow.h
|
||||
*
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <glib.h>
|
||||
#include <gdk.h>
|
||||
|
||||
@interface GdkQuartzNSWindow : NSWindow {
|
||||
BOOL inMove;
|
||||
BOOL inShowOrHide;
|
||||
BOOL initialPositionKnown;
|
||||
|
||||
/* Manually triggered move/resize (not by the window manager) */
|
||||
BOOL inManualMove;
|
||||
BOOL inManualResize;
|
||||
BOOL inTrackManualResize;
|
||||
NSPoint initialMoveLocation;
|
||||
NSPoint initialResizeLocation;
|
||||
NSRect initialResizeFrame;
|
||||
GdkSurfaceEdge resizeEdge;
|
||||
|
||||
NSRect lastUnmaximizedFrame;
|
||||
NSRect lastMaximizedFrame;
|
||||
NSRect lastUnfullscreenFrame;
|
||||
BOOL inMaximizeTransition;
|
||||
}
|
||||
|
||||
-(BOOL)isInMove;
|
||||
-(void)beginManualMove;
|
||||
-(BOOL)trackManualMove;
|
||||
-(BOOL)isInManualResizeOrMove;
|
||||
-(void)beginManualResize:(GdkSurfaceEdge)edge;
|
||||
-(BOOL)trackManualResize;
|
||||
-(void)showAndMakeKey:(BOOL)makeKey;
|
||||
-(void)hide;
|
||||
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER
|
||||
-(void)setStyleMask:(NSUInteger)styleMask;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
@ -1,712 +0,0 @@
|
||||
/* GdkQuartzView.m
|
||||
*
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
* Copyright (C) 2011 Hiroyuki Yamamoto
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#import "GdkQuartzView.h"
|
||||
#include "gdkquartzsurface.h"
|
||||
#include "gdkprivate-quartz.h"
|
||||
#include "gdkquartz.h"
|
||||
|
||||
@implementation GdkQuartzView
|
||||
|
||||
-(id)initWithFrame: (NSRect)frameRect
|
||||
{
|
||||
if ((self = [super initWithFrame: frameRect]))
|
||||
{
|
||||
markedRange = NSMakeRange (NSNotFound, 0);
|
||||
selectedRange = NSMakeRange (NSNotFound, 0);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(BOOL)acceptsFirstResponder
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("acceptsFirstResponder"));
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)becomeFirstResponder
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("becomeFirstResponder"));
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)resignFirstResponder
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("resignFirstResponder"));
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void) keyDown: (NSEvent *) theEvent
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("keyDown"));
|
||||
[self interpretKeyEvents: [NSArray arrayWithObject: theEvent]];
|
||||
}
|
||||
|
||||
-(void)flagsChanged: (NSEvent *) theEvent
|
||||
{
|
||||
}
|
||||
|
||||
-(NSUInteger)characterIndexForPoint: (NSPoint)aPoint
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("characterIndexForPoint"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
-(NSRect)firstRectForCharacterRange: (NSRange)aRange actualRange: (NSRangePointer)actualRange
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("firstRectForCharacterRange"));
|
||||
gint ns_x, ns_y;
|
||||
GdkRectangle *rect;
|
||||
|
||||
rect = g_object_get_data (G_OBJECT (gdk_surface), GIC_CURSOR_RECT);
|
||||
if (rect)
|
||||
{
|
||||
_gdk_quartz_surface_gdk_xy_to_xy (rect->x, rect->y + rect->height,
|
||||
&ns_x, &ns_y);
|
||||
|
||||
return NSMakeRect (ns_x, ns_y, rect->width, rect->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NSMakeRect (0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
-(NSArray *)validAttributesForMarkedText
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("validAttributesForMarkedText"));
|
||||
return [NSArray arrayWithObjects: NSUnderlineStyleAttributeName, nil];
|
||||
}
|
||||
|
||||
-(NSAttributedString *)attributedSubstringForProposedRange: (NSRange)aRange actualRange: (NSRangePointer)actualRange
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("attributedSubstringForProposedRange"));
|
||||
return nil;
|
||||
}
|
||||
|
||||
-(BOOL)hasMarkedText
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("hasMarkedText"));
|
||||
return markedRange.location != NSNotFound && markedRange.length != 0;
|
||||
}
|
||||
|
||||
-(NSRange)markedRange
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("markedRange"));
|
||||
return markedRange;
|
||||
}
|
||||
|
||||
-(NSRange)selectedRange
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("selectedRange"));
|
||||
return selectedRange;
|
||||
}
|
||||
|
||||
-(void)unmarkText
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("unmarkText"));
|
||||
gchar *prev_str;
|
||||
markedRange = selectedRange = NSMakeRange (NSNotFound, 0);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (gdk_surface), TIC_MARKED_TEXT, NULL, g_free);
|
||||
}
|
||||
|
||||
-(void)setMarkedText: (id)aString selectedRange: (NSRange)newSelection replacementRange: (NSRange)replacementRange
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("setMarkedText"));
|
||||
const char *str;
|
||||
gchar *prev_str;
|
||||
|
||||
if (replacementRange.location == NSNotFound)
|
||||
{
|
||||
markedRange = NSMakeRange (newSelection.location, [aString length]);
|
||||
selectedRange = NSMakeRange (newSelection.location, newSelection.length);
|
||||
}
|
||||
else {
|
||||
markedRange = NSMakeRange (replacementRange.location, [aString length]);
|
||||
selectedRange = NSMakeRange (replacementRange.location + newSelection.location, newSelection.length);
|
||||
}
|
||||
|
||||
if ([aString isKindOfClass: [NSAttributedString class]])
|
||||
{
|
||||
str = [[aString string] UTF8String];
|
||||
}
|
||||
else {
|
||||
str = [aString UTF8String];
|
||||
}
|
||||
|
||||
g_object_set_data_full (G_OBJECT (gdk_surface), TIC_MARKED_TEXT, g_strdup (str), g_free);
|
||||
g_object_set_data (G_OBJECT (gdk_surface), TIC_SELECTED_POS,
|
||||
GUINT_TO_POINTER (selectedRange.location));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), TIC_SELECTED_LEN,
|
||||
GUINT_TO_POINTER (selectedRange.length));
|
||||
|
||||
GDK_NOTE (EVENTS, g_message ("setMarkedText: set %s (%p, nsview %p): %s",
|
||||
TIC_MARKED_TEXT, gdk_surface, self,
|
||||
str ? str : "(empty)"));
|
||||
|
||||
/* handle text input changes by mouse events */
|
||||
if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (gdk_surface),
|
||||
TIC_IN_KEY_DOWN)))
|
||||
{
|
||||
_gdk_quartz_synthesize_null_key_event(gdk_surface);
|
||||
}
|
||||
}
|
||||
|
||||
-(void)doCommandBySelector: (SEL)aSelector
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("doCommandBySelector"));
|
||||
if ([self respondsToSelector: aSelector])
|
||||
[self performSelector: aSelector];
|
||||
}
|
||||
|
||||
-(void)insertText: (id)aString replacementRange: (NSRange)replacementRange
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("insertText"));
|
||||
const char *str;
|
||||
NSString *string;
|
||||
gchar *prev_str;
|
||||
|
||||
if ([self hasMarkedText])
|
||||
[self unmarkText];
|
||||
|
||||
if ([aString isKindOfClass: [NSAttributedString class]])
|
||||
string = [aString string];
|
||||
else
|
||||
string = aString;
|
||||
|
||||
NSCharacterSet *ctrlChars = [NSCharacterSet controlCharacterSet];
|
||||
NSCharacterSet *wsnlChars = [NSCharacterSet whitespaceAndNewlineCharacterSet];
|
||||
if ([string rangeOfCharacterFromSet:ctrlChars].length &&
|
||||
[string rangeOfCharacterFromSet:wsnlChars].length == 0)
|
||||
{
|
||||
/* discard invalid text input with Chinese input methods */
|
||||
str = "";
|
||||
[self unmarkText];
|
||||
NSInputManager *currentInputManager = [NSInputManager currentInputManager];
|
||||
[currentInputManager markedTextAbandoned:self];
|
||||
}
|
||||
else
|
||||
{
|
||||
str = [string UTF8String];
|
||||
}
|
||||
|
||||
g_object_set_data_full (G_OBJECT (gdk_surface), TIC_INSERT_TEXT, g_strdup (str), g_free);
|
||||
GDK_NOTE (EVENTS, g_message ("insertText: set %s (%p, nsview %p): %s",
|
||||
TIC_INSERT_TEXT, gdk_surface, self,
|
||||
str ? str : "(empty)"));
|
||||
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_FILTERED));
|
||||
|
||||
/* handle text input changes by mouse events */
|
||||
if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (gdk_surface),
|
||||
TIC_IN_KEY_DOWN)))
|
||||
{
|
||||
_gdk_quartz_synthesize_null_key_event(gdk_surface);
|
||||
}
|
||||
}
|
||||
|
||||
-(void)deleteBackward: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteBackward"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteForward: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteForward"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteToBeginningOfLine: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteToBeginningOfLine"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteToEndOfLine: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteToEndOfLine"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteWordBackward: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteWordBackward"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)deleteWordForward: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("deleteWordForward"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)insertBacktab: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("insertBacktab"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)insertNewline: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("insertNewline"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY, GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)insertTab: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("insertTab"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveBackward: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveBackward"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveBackwardAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveBackwardAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveDown: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveDown"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveDownAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveDownAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveForward: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveForward"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveForwardAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveForwardAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveLeft: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveLeft"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveLeftAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveLeftAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveRight: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveRight"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveRightAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveRightAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToBeginningOfDocument: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToBeginningOfDocument"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToBeginningOfDocumentAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToBeginningOfDocumentAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToBeginningOfLine: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToBeginningOfLine"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToBeginningOfLineAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToBeginningOfLineAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToEndOfDocument: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToEndOfDocument"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToEndOfDocumentAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToEndOfDocumentAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToEndOfLine: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToEndOfLine"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveToEndOfLineAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveToEndOfLineAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveUp: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveUp"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveUpAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveUpAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordBackward: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordBackward"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordBackwardAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordBackwardAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordForward: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordForward"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordForwardAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordForwardAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordLeft: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordLeft"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordLeftAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordLeftAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordRight: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordRight"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)moveWordRightAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("moveWordRightAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)pageDown: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("pageDown"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)pageDownAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("pageDownAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)pageUp: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("pageUp"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)pageUpAndModifySelection: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("pageUpAndModifySelection"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)selectAll: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("selectAll"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)selectLine: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("selectLine"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)selectWord: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("selectWord"));
|
||||
g_object_set_data (G_OBJECT (gdk_surface), GIC_FILTER_KEY,
|
||||
GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
|
||||
}
|
||||
|
||||
-(void)noop: (id)sender
|
||||
{
|
||||
GDK_NOTE (EVENTS, g_message ("noop"));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------- */
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
if (trackingRect)
|
||||
{
|
||||
[self removeTrackingRect: trackingRect];
|
||||
trackingRect = 0;
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void)setGdkSurface: (GdkSurface *)window
|
||||
{
|
||||
gdk_surface = window;
|
||||
}
|
||||
|
||||
-(GdkSurface *)gdkSurface
|
||||
{
|
||||
return gdk_surface;
|
||||
}
|
||||
|
||||
-(NSTrackingRectTag)trackingRect
|
||||
{
|
||||
return trackingRect;
|
||||
}
|
||||
|
||||
-(BOOL)isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL)isOpaque
|
||||
{
|
||||
if (GDK_SURFACE_DESTROYED (gdk_surface))
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)drawRect: (NSRect)rect
|
||||
{
|
||||
GdkRectangle gdk_rect;
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (gdk_window->impl);
|
||||
const NSRect *drawn_rects;
|
||||
NSInteger count;
|
||||
int i;
|
||||
cairo_region_t *region;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (gdk_surface))
|
||||
return;
|
||||
|
||||
if (! (gdk_window->event_mask & GDK_EXPOSURE_MASK))
|
||||
return;
|
||||
|
||||
if (NSEqualRects (rect, NSZeroRect))
|
||||
return;
|
||||
|
||||
if (!GDK_SURFACE_IS_MAPPED (gdk_surface))
|
||||
{
|
||||
/* If the window is not yet mapped, clip_region_with_children
|
||||
* will be empty causing the usual code below to draw nothing.
|
||||
* To not see garbage on the screen, we draw an aesthetic color
|
||||
* here. The garbage would be visible if any widget enabled
|
||||
* the NSView's CALayer in order to add sublayers for custom
|
||||
* native rendering.
|
||||
*/
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
|
||||
[[NSColor windowBackgroundColor] setFill];
|
||||
[NSBezierPath fillRect: rect];
|
||||
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clear our own bookkeeping of regions that need display */
|
||||
if (impl->needs_display_region)
|
||||
{
|
||||
cairo_region_destroy (impl->needs_display_region);
|
||||
impl->needs_display_region = NULL;
|
||||
}
|
||||
|
||||
[self getRectsBeingDrawn: &drawn_rects count: &count];
|
||||
region = cairo_region_create ();
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
gdk_rect.x = drawn_rects[i].origin.x;
|
||||
gdk_rect.y = drawn_rects[i].origin.y;
|
||||
gdk_rect.width = drawn_rects[i].size.width;
|
||||
gdk_rect.height = drawn_rects[i].size.height;
|
||||
|
||||
cairo_region_union_rectangle (region, &gdk_rect);
|
||||
}
|
||||
|
||||
impl->in_paint_rect_count++;
|
||||
_gdk_surface_process_updates_recurse (gdk_surface, region);
|
||||
impl->in_paint_rect_count--;
|
||||
|
||||
cairo_region_destroy (region);
|
||||
|
||||
if (needsInvalidateShadow)
|
||||
{
|
||||
[[self window] invalidateShadow];
|
||||
needsInvalidateShadow = NO;
|
||||
}
|
||||
}
|
||||
|
||||
-(void)setNeedsInvalidateShadow: (BOOL)invalidate
|
||||
{
|
||||
needsInvalidateShadow = invalidate;
|
||||
}
|
||||
|
||||
/* For information on setting up tracking rects properly, see here:
|
||||
* http://developer.apple.com/documentation/Cocoa/Conceptual/EventOverview/EventOverview.pdf
|
||||
*/
|
||||
-(void)updateTrackingRect
|
||||
{
|
||||
GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (gdk_window->impl);
|
||||
NSRect rect;
|
||||
|
||||
if (!impl || !impl->toplevel)
|
||||
return;
|
||||
|
||||
if (trackingRect)
|
||||
{
|
||||
[self removeTrackingRect: trackingRect];
|
||||
trackingRect = 0;
|
||||
}
|
||||
|
||||
if (!impl->toplevel)
|
||||
return;
|
||||
|
||||
/* Note, if we want to set assumeInside we can use:
|
||||
* NSPointInRect ([[self window] convertScreenToBase:[NSEvent mouseLocation]], rect)
|
||||
*/
|
||||
|
||||
rect = [self bounds];
|
||||
trackingRect = [self addTrackingRect: rect
|
||||
owner: self
|
||||
userData: nil
|
||||
assumeInside: NO];
|
||||
}
|
||||
|
||||
-(void)viewDidMoveToWindow
|
||||
{
|
||||
if (![self window]) /* We are destroyed already */
|
||||
return;
|
||||
|
||||
[self updateTrackingRect];
|
||||
}
|
||||
|
||||
-(void)viewWillMoveToWindow: (NSWindow *)newWindow
|
||||
{
|
||||
if (newWindow == nil && trackingRect)
|
||||
{
|
||||
[self removeTrackingRect: trackingRect];
|
||||
trackingRect = 0;
|
||||
}
|
||||
}
|
||||
|
||||
-(void)setFrame: (NSRect)frame
|
||||
{
|
||||
[super setFrame: frame];
|
||||
|
||||
if ([self window])
|
||||
[self updateTrackingRect];
|
||||
}
|
||||
|
||||
@end
|
@ -1,36 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* Copyright © 2018 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkconfig.h"
|
||||
|
||||
#include "gdkcairocontext-quartz.h"
|
||||
|
||||
G_DEFINE_TYPE (GdkQuartzCairoContext, gdk_quartz_cairo_context, GDK_TYPE_CAIRO_CONTEXT)
|
||||
|
||||
static void
|
||||
gdk_quartz_cairo_context_class_init (GdkQuartzCairoContextClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_cairo_context_init (GdkQuartzCairoContext *self)
|
||||
{
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* Copyright © 2018 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_CAIRO_CONTEXT__
|
||||
#define __GDK_QUARTZ_CAIRO_CONTEXT__
|
||||
|
||||
#include "gdkconfig.h"
|
||||
|
||||
#include "gdkcairocontextprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_QUARTZ_CAIRO_CONTEXT (gdk_quartz_cairo_context_get_type ())
|
||||
#define GDK_QUARTZ_CAIRO_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_QUARTZ_CAIRO_CONTEXT, GdkQuartzCairoContext))
|
||||
#define GDK_IS_QUARTZ_CAIRO_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_QUARTZ_CAIRO_CONTEXT))
|
||||
#define GDK_QUARTZ_CAIRO_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_QUARTZ_CAIRO_CONTEXT, GdkQuartzCairoContextClass))
|
||||
#define GDK_IS_QUARTZ_CAIRO_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_QUARTZ_CAIRO_CONTEXT))
|
||||
#define GDK_QUARTZ_CAIRO_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_QUARTZ_CAIRO_CONTEXT, GdkQuartzCairoContextClass))
|
||||
|
||||
typedef struct _GdkQuartzCairoContext GdkQuartzCairoContext;
|
||||
typedef struct _GdkQuartzCairoContextClass GdkQuartzCairoContextClass;
|
||||
|
||||
struct _GdkQuartzCairoContext
|
||||
{
|
||||
GdkCairoContext parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkQuartzCairoContextClass
|
||||
{
|
||||
GdkCairoContextClass parent_class;
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_quartz_cairo_context_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_CAIRO_CONTEXT__ */
|
@ -1,482 +0,0 @@
|
||||
/* gdkcursor-quartz.c
|
||||
*
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkcursor.h"
|
||||
#include "gdkcursorprivate.h"
|
||||
#include "gdkquartzcursor.h"
|
||||
#include "gdkprivate-quartz.h"
|
||||
|
||||
#include "xcursors.h"
|
||||
|
||||
struct _GdkQuartzCursor
|
||||
{
|
||||
GdkCursor cursor;
|
||||
|
||||
NSCursor *nscursor;
|
||||
};
|
||||
|
||||
struct _GdkQuartzCursorClass
|
||||
{
|
||||
GdkCursorClass cursor_class;
|
||||
};
|
||||
|
||||
|
||||
static GdkCursor *cached_xcursors[G_N_ELEMENTS (xcursors)];
|
||||
|
||||
static GdkCursor *
|
||||
gdk_quartz_cursor_new_from_nscursor (NSCursor *nscursor,
|
||||
GdkCursorType cursor_type)
|
||||
{
|
||||
GdkQuartzCursor *private;
|
||||
|
||||
private = g_object_new (GDK_TYPE_QUARTZ_CURSOR,
|
||||
"cursor-type", cursor_type,
|
||||
"display", _gdk_display,
|
||||
NULL);
|
||||
private->nscursor = nscursor;
|
||||
|
||||
return GDK_CURSOR (private);
|
||||
}
|
||||
|
||||
static GdkCursor *
|
||||
create_blank_cursor (void)
|
||||
{
|
||||
NSCursor *nscursor;
|
||||
NSImage *nsimage;
|
||||
NSSize size = { 1.0, 1.0 };
|
||||
|
||||
nsimage = [[NSImage alloc] initWithSize:size];
|
||||
nscursor = [[NSCursor alloc] initWithImage:nsimage
|
||||
hotSpot:NSMakePoint(0.0, 0.0)];
|
||||
[nsimage release];
|
||||
|
||||
return gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_BLANK_CURSOR);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_bit (const guchar *data,
|
||||
gint width,
|
||||
gint height,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
gint bytes_per_line;
|
||||
const guchar *src;
|
||||
|
||||
if (x < 0 || y < 0 || x >= width || y >= height)
|
||||
return FALSE;
|
||||
|
||||
bytes_per_line = (width + 7) / 8;
|
||||
|
||||
src = &data[y * bytes_per_line];
|
||||
return ((src[x / 8] >> x % 8) & 1);
|
||||
}
|
||||
|
||||
static GdkCursor *
|
||||
create_builtin_cursor (GdkCursorType cursor_type)
|
||||
{
|
||||
GdkCursor *cursor;
|
||||
NSBitmapImageRep *bitmap_rep;
|
||||
NSInteger mask_width, mask_height;
|
||||
gint src_width, src_height;
|
||||
gint dst_stride;
|
||||
const guchar *mask_start, *src_start;
|
||||
gint dx, dy;
|
||||
gint x, y;
|
||||
NSPoint hotspot;
|
||||
NSImage *image;
|
||||
NSCursor *nscursor;
|
||||
|
||||
if (cursor_type >= G_N_ELEMENTS (xcursors) || cursor_type < 0)
|
||||
return NULL;
|
||||
|
||||
cursor = cached_xcursors[cursor_type];
|
||||
if (cursor)
|
||||
return cursor;
|
||||
|
||||
GDK_QUARTZ_ALLOC_POOL;
|
||||
|
||||
src_width = xcursors[cursor_type].width;
|
||||
src_height = xcursors[cursor_type].height;
|
||||
mask_width = xcursors[cursor_type+1].width;
|
||||
mask_height = xcursors[cursor_type+1].height;
|
||||
|
||||
bitmap_rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
||||
pixelsWide:mask_width pixelsHigh:mask_height
|
||||
bitsPerSample:8 samplesPerPixel:4
|
||||
hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
|
||||
bytesPerRow:0 bitsPerPixel:0];
|
||||
|
||||
dst_stride = [bitmap_rep bytesPerRow];
|
||||
|
||||
src_start = xcursors[cursor_type].bits;
|
||||
mask_start = xcursors[cursor_type+1].bits;
|
||||
|
||||
dx = xcursors[cursor_type+1].hotx - xcursors[cursor_type].hotx;
|
||||
dy = xcursors[cursor_type+1].hoty - xcursors[cursor_type].hoty;
|
||||
|
||||
for (y = 0; y < mask_height; y++)
|
||||
{
|
||||
guchar *dst = [bitmap_rep bitmapData] + y * dst_stride;
|
||||
|
||||
for (x = 0; x < mask_width; x++)
|
||||
{
|
||||
if (get_bit (mask_start, mask_width, mask_height, x, y))
|
||||
{
|
||||
if (get_bit (src_start, src_width, src_height, x - dx, y - dy))
|
||||
{
|
||||
*dst++ = 0;
|
||||
*dst++ = 0;
|
||||
*dst++ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst++ = 0xff;
|
||||
*dst++ = 0xff;
|
||||
*dst++ = 0xff;
|
||||
}
|
||||
|
||||
*dst++ = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst++ = 0;
|
||||
*dst++ = 0;
|
||||
*dst++ = 0;
|
||||
*dst++ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image = [[NSImage alloc] init];
|
||||
[image addRepresentation:bitmap_rep];
|
||||
[bitmap_rep release];
|
||||
|
||||
hotspot = NSMakePoint (xcursors[cursor_type+1].hotx,
|
||||
xcursors[cursor_type+1].hoty);
|
||||
|
||||
nscursor = [[NSCursor alloc] initWithImage:image hotSpot:hotspot];
|
||||
[image release];
|
||||
|
||||
cursor = gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_CURSOR_IS_PIXMAP);
|
||||
|
||||
cached_xcursors[cursor_type] = g_object_ref (cursor);
|
||||
|
||||
GDK_QUARTZ_RELEASE_POOL;
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
GdkCursor*
|
||||
_gdk_quartz_display_get_cursor_for_type (GdkDisplay *display,
|
||||
GdkCursorType cursor_type)
|
||||
{
|
||||
NSCursor *nscursor;
|
||||
|
||||
g_return_val_if_fail (display == gdk_display_get_default (), NULL);
|
||||
|
||||
switch (cursor_type)
|
||||
{
|
||||
case GDK_XTERM:
|
||||
nscursor = [NSCursor IBeamCursor];
|
||||
break;
|
||||
case GDK_SB_H_DOUBLE_ARROW:
|
||||
nscursor = [NSCursor resizeLeftRightCursor];
|
||||
break;
|
||||
case GDK_SB_V_DOUBLE_ARROW:
|
||||
nscursor = [NSCursor resizeUpDownCursor];
|
||||
break;
|
||||
case GDK_SB_UP_ARROW:
|
||||
case GDK_BASED_ARROW_UP:
|
||||
case GDK_BOTTOM_TEE:
|
||||
case GDK_TOP_SIDE:
|
||||
nscursor = [NSCursor resizeUpCursor];
|
||||
break;
|
||||
case GDK_SB_DOWN_ARROW:
|
||||
case GDK_BASED_ARROW_DOWN:
|
||||
case GDK_TOP_TEE:
|
||||
case GDK_BOTTOM_SIDE:
|
||||
nscursor = [NSCursor resizeDownCursor];
|
||||
break;
|
||||
case GDK_SB_LEFT_ARROW:
|
||||
case GDK_RIGHT_TEE:
|
||||
case GDK_LEFT_SIDE:
|
||||
nscursor = [NSCursor resizeLeftCursor];
|
||||
break;
|
||||
case GDK_SB_RIGHT_ARROW:
|
||||
case GDK_LEFT_TEE:
|
||||
case GDK_RIGHT_SIDE:
|
||||
nscursor = [NSCursor resizeRightCursor];
|
||||
break;
|
||||
case GDK_TCROSS:
|
||||
case GDK_CROSS:
|
||||
case GDK_CROSSHAIR:
|
||||
case GDK_DIAMOND_CROSS:
|
||||
nscursor = [NSCursor crosshairCursor];
|
||||
break;
|
||||
case GDK_HAND1:
|
||||
case GDK_HAND2:
|
||||
nscursor = [NSCursor pointingHandCursor];
|
||||
break;
|
||||
case GDK_CURSOR_IS_PIXMAP:
|
||||
return NULL;
|
||||
case GDK_BLANK_CURSOR:
|
||||
return create_blank_cursor ();
|
||||
default:
|
||||
return g_object_ref (create_builtin_cursor (cursor_type));
|
||||
}
|
||||
|
||||
[nscursor retain];
|
||||
return gdk_quartz_cursor_new_from_nscursor (nscursor, cursor_type);
|
||||
}
|
||||
|
||||
|
||||
GdkCursor *
|
||||
_gdk_quartz_display_get_cursor_for_surface (GdkDisplay *display,
|
||||
cairo_surface_t *surface,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
NSImage *image;
|
||||
NSCursor *nscursor;
|
||||
GdkCursor *cursor;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
GDK_QUARTZ_ALLOC_POOL;
|
||||
|
||||
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0,
|
||||
cairo_image_surface_get_width (surface),
|
||||
cairo_image_surface_get_height (surface));
|
||||
image = gdk_quartz_pixbuf_to_ns_image_libgtk_only (pixbuf);
|
||||
nscursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(x, y)];
|
||||
|
||||
cursor = gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_CURSOR_IS_PIXMAP);
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
GDK_QUARTZ_RELEASE_POOL;
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/* OS X only exports a number of cursor types in its public NSCursor interface.
|
||||
* By overriding the private _coreCursorType method, we can tell OS X to load
|
||||
* one of its internal cursors instead (since cursor images are loaded on demand
|
||||
* instead of in advance). WebKit does this too.
|
||||
*/
|
||||
|
||||
@interface gdkCoreCursor : NSCursor {
|
||||
@private
|
||||
int type;
|
||||
BOOL override;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation gdkCoreCursor
|
||||
|
||||
- (int)_coreCursorType
|
||||
{
|
||||
if (self->override)
|
||||
return self->type;
|
||||
return [super _coreCursorType];
|
||||
}
|
||||
|
||||
#define CUSTOM_CURSOR_CTOR(name, id) \
|
||||
+ (gdkCoreCursor *)name \
|
||||
{ \
|
||||
gdkCoreCursor *obj; \
|
||||
obj = [self new]; \
|
||||
if (obj) { \
|
||||
obj->override = YES; \
|
||||
obj->type = id; \
|
||||
} \
|
||||
return obj; \
|
||||
}
|
||||
CUSTOM_CURSOR_CTOR(gdkHelpCursor, 40)
|
||||
CUSTOM_CURSOR_CTOR(gdkProgressCursor, 4)
|
||||
/* TODO OS X doesn't seem to have a way to get this. There is an undocumented
|
||||
* method +[NSCursor _waitCursor], but it doesn't actually return this cursor,
|
||||
* but rather some odd low-quality non-animating version of this cursor. Use
|
||||
* the progress cursor instead for now.
|
||||
*/
|
||||
CUSTOM_CURSOR_CTOR(gdkWaitCursor, 4)
|
||||
CUSTOM_CURSOR_CTOR(gdkAliasCursor, 2)
|
||||
CUSTOM_CURSOR_CTOR(gdkMoveCursor, 39)
|
||||
/* TODO OS X doesn't seem to provide one; copy the move cursor for now
|
||||
* since it looks similar to what we want. */
|
||||
CUSTOM_CURSOR_CTOR(gdkAllScrollCursor, 39)
|
||||
CUSTOM_CURSOR_CTOR(gdkNEResizeCursor, 29)
|
||||
CUSTOM_CURSOR_CTOR(gdkNWResizeCursor, 33)
|
||||
CUSTOM_CURSOR_CTOR(gdkSEResizeCursor, 35)
|
||||
CUSTOM_CURSOR_CTOR(gdkSWResizeCursor, 37)
|
||||
CUSTOM_CURSOR_CTOR(gdkEWResizeCursor, 28)
|
||||
CUSTOM_CURSOR_CTOR(gdkNSResizeCursor, 32)
|
||||
CUSTOM_CURSOR_CTOR(gdkNESWResizeCursor, 30)
|
||||
CUSTOM_CURSOR_CTOR(gdkNWSEResizeCursor, 34)
|
||||
CUSTOM_CURSOR_CTOR(gdkZoomInCursor, 42)
|
||||
CUSTOM_CURSOR_CTOR(gdkZoomOutCursor, 43)
|
||||
|
||||
@end
|
||||
|
||||
struct CursorsByName {
|
||||
const gchar *name;
|
||||
NSString *selector;
|
||||
};
|
||||
|
||||
static const struct CursorsByName cursors_by_name[] = {
|
||||
/* Link & Status */
|
||||
{ "context-menu", @"contextualMenuCursor" },
|
||||
{ "help", @"gdkHelpCursor" },
|
||||
{ "pointer", @"pointingHandCursor" },
|
||||
{ "progress", @"gdkProgressCursor" },
|
||||
{ "wait", @"gdkWaitCursor" },
|
||||
/* Selection */
|
||||
{ "cell", @"crosshairCursor" },
|
||||
{ "crosshair", @"crosshairCursor" },
|
||||
{ "text", @"IBeamCursor" },
|
||||
{ "vertical-text", @"IBeamCursorForVerticalLayout" },
|
||||
/* Drag & Drop */
|
||||
{ "alias", @"gdkAliasCursor" },
|
||||
{ "copy", @"dragCopyCursor" },
|
||||
{ "move", @"gdkMoveCursor" },
|
||||
{ "no-drop", @"operationNotAllowedCursor" },
|
||||
{ "not-allowed", @"operationNotAllowedCursor" },
|
||||
{ "grab", @"openHandCursor" },
|
||||
{ "grabbing", @"closedHandCursor" },
|
||||
/* Resize & Scrolling */
|
||||
{ "all-scroll", @"gdkAllScrollCursor" },
|
||||
{ "col-resize", @"resizeLeftRightCursor" },
|
||||
{ "row-resize", @"resizeUpDownCursor" },
|
||||
{ "n-resize", @"resizeUpCursor" },
|
||||
{ "e-resize", @"resizeRightCursor" },
|
||||
{ "s-resize", @"resizeDownCursor" },
|
||||
{ "w-resize", @"resizeLeftCursor" },
|
||||
{ "ne-resize", @"gdkNEResizeCursor" },
|
||||
{ "nw-resize", @"gdkNWResizeCursor" },
|
||||
{ "se-resize", @"gdkSEResizeCursor" },
|
||||
{ "sw-resize", @"gdkSWResizeCursor" },
|
||||
{ "ew-resize", @"gdkEWResizeCursor" },
|
||||
{ "ns-resize", @"gdkNSResizeCursor" },
|
||||
{ "nesw-resize", @"gdkNESWResizeCursor" },
|
||||
{ "nwse-resize", @"gdkNWSEResizeCursor" },
|
||||
/* Zoom */
|
||||
{ "zoom-in", @"gdkZoomInCursor" },
|
||||
{ "zoom-out", @"gdkZoomOutCursor" },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
GdkCursor*
|
||||
_gdk_quartz_display_get_cursor_for_name (GdkDisplay *display,
|
||||
const gchar *name)
|
||||
{
|
||||
NSCursor *nscursor;
|
||||
const struct CursorsByName *test;
|
||||
SEL selector;
|
||||
|
||||
if (name == NULL || g_str_equal (name, "none"))
|
||||
return create_blank_cursor ();
|
||||
|
||||
// use this selector if nothing found
|
||||
selector = @selector(arrowCursor);
|
||||
for (test = cursors_by_name; test->name != NULL; test++)
|
||||
if (g_str_equal (name, test->name))
|
||||
{
|
||||
selector = NSSelectorFromString(test->selector);
|
||||
break;
|
||||
}
|
||||
nscursor = [[gdkCoreCursor class] performSelector:selector];
|
||||
|
||||
[nscursor retain];
|
||||
return gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_CURSOR_IS_PIXMAP);
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (GdkQuartzCursor, gdk_quartz_cursor, GDK_TYPE_CURSOR)
|
||||
|
||||
static void
|
||||
gdk_quartz_cursor_finalize (GObject *object)
|
||||
{
|
||||
GdkQuartzCursor *private = GDK_QUARTZ_CURSOR (object);
|
||||
|
||||
if (private->nscursor)
|
||||
[private->nscursor release];
|
||||
private->nscursor = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_cursor_class_init (GdkQuartzCursorClass *quartz_cursor_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (quartz_cursor_class);
|
||||
|
||||
object_class->finalize = gdk_quartz_cursor_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_cursor_init (GdkQuartzCursor *cursor)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
_gdk_quartz_display_supports_cursor_alpha (GdkDisplay *display)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_quartz_display_supports_cursor_color (GdkDisplay *display)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_quartz_display_get_default_cursor_size (GdkDisplay *display,
|
||||
guint *width,
|
||||
guint *height)
|
||||
{
|
||||
/* Mac OS X doesn't have the notion of a default size */
|
||||
*width = 32;
|
||||
*height = 32;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_quartz_display_get_maximal_cursor_size (GdkDisplay *display,
|
||||
guint *width,
|
||||
guint *height)
|
||||
{
|
||||
/* Cursor sizes in Mac OS X can be arbitrarily large */
|
||||
*width = 65536;
|
||||
*height = 65536;
|
||||
}
|
||||
|
||||
NSCursor *
|
||||
_gdk_quartz_cursor_get_ns_cursor (GdkCursor *cursor)
|
||||
{
|
||||
GdkQuartzCursor *cursor_private;
|
||||
|
||||
if (!cursor)
|
||||
return [NSCursor arrowCursor];
|
||||
|
||||
g_return_val_if_fail (GDK_IS_QUARTZ_CURSOR (cursor), NULL);
|
||||
|
||||
cursor_private = GDK_QUARTZ_CURSOR (cursor);
|
||||
|
||||
return cursor_private->nscursor;
|
||||
}
|
@ -1,347 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
* Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdkdeviceprivate.h>
|
||||
#include <gdk/gdkdisplayprivate.h>
|
||||
|
||||
#import "GdkQuartzView.h"
|
||||
#include "gdkquartzsurface.h"
|
||||
#include "gdkquartzcursor.h"
|
||||
#include "gdkprivate-quartz.h"
|
||||
#include "gdkquartzdevice-core.h"
|
||||
|
||||
struct _GdkQuartzDeviceCore
|
||||
{
|
||||
GdkDevice parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkQuartzDeviceCoreClass
|
||||
{
|
||||
GdkDeviceClass parent_class;
|
||||
};
|
||||
|
||||
static gboolean gdk_quartz_device_core_get_history (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
guint32 start,
|
||||
guint32 stop,
|
||||
GdkTimeCoord ***events,
|
||||
gint *n_events);
|
||||
static void gdk_quartz_device_core_get_state (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask);
|
||||
static void gdk_quartz_device_core_set_surface_cursor (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkCursor *cursor);
|
||||
static void gdk_quartz_device_core_warp (GdkDevice *device,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
static void gdk_quartz_device_core_query_state (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkSurface **root_window,
|
||||
GdkSurface **child_window,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask);
|
||||
static GdkGrabStatus gdk_quartz_device_core_grab (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
gboolean owner_events,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurface *confine_to,
|
||||
GdkCursor *cursor,
|
||||
guint32 time_);
|
||||
static void gdk_quartz_device_core_ungrab (GdkDevice *device,
|
||||
guint32 time_);
|
||||
static GdkSurface * gdk_quartz_device_core_surface_at_position (GdkDevice *device,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkQuartzDeviceCore, gdk_quartz_device_core, GDK_TYPE_DEVICE)
|
||||
|
||||
static void
|
||||
gdk_quartz_device_core_class_init (GdkQuartzDeviceCoreClass *klass)
|
||||
{
|
||||
GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
|
||||
|
||||
device_class->get_history = gdk_quartz_device_core_get_history;
|
||||
device_class->get_state = gdk_quartz_device_core_get_state;
|
||||
device_class->set_surface_cursor = gdk_quartz_device_core_set_surface_cursor;
|
||||
device_class->warp = gdk_quartz_device_core_warp;
|
||||
device_class->query_state = gdk_quartz_device_core_query_state;
|
||||
device_class->grab = gdk_quartz_device_core_grab;
|
||||
device_class->ungrab = gdk_quartz_device_core_ungrab;
|
||||
device_class->surface_at_position = gdk_quartz_device_core_surface_at_position;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_device_core_init (GdkQuartzDeviceCore *quartz_device_core)
|
||||
{
|
||||
GdkDevice *device;
|
||||
|
||||
device = GDK_DEVICE (quartz_device_core);
|
||||
|
||||
_gdk_device_add_axis (device, NULL, GDK_AXIS_X, 0, 0, 1);
|
||||
_gdk_device_add_axis (device, NULL, GDK_AXIS_Y, 0, 0, 1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_device_core_get_history (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
guint32 start,
|
||||
guint32 stop,
|
||||
GdkTimeCoord ***events,
|
||||
gint *n_events)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_device_core_get_state (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
gdouble x_pos, y_pos;
|
||||
|
||||
gdk_surface_get_device_position (window, device, &x_pos, &y_pos, mask);
|
||||
|
||||
if (axes)
|
||||
{
|
||||
axes[0] = x_pos;
|
||||
axes[1] = y_pos;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
translate_coords_to_child_coords (GdkSurface *parent,
|
||||
GdkSurface *child,
|
||||
gint *x,
|
||||
gint *y)
|
||||
{
|
||||
GdkSurface *current = child;
|
||||
|
||||
if (child == parent)
|
||||
return;
|
||||
|
||||
while (current != parent)
|
||||
{
|
||||
gint tmp_x, tmp_y;
|
||||
|
||||
gdk_surface_get_origin (current, &tmp_x, &tmp_y);
|
||||
|
||||
*x -= tmp_x;
|
||||
*y -= tmp_y;
|
||||
|
||||
current = gdk_surface_get_parent (current);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_device_core_set_surface_cursor (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
NSCursor *nscursor;
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
return;
|
||||
|
||||
nscursor = _gdk_quartz_cursor_get_ns_cursor (cursor);
|
||||
|
||||
[nscursor set];
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_device_core_warp (GdkDevice *device,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_quartz_device_core_query_state_helper (GdkSurface *window,
|
||||
GdkDevice *device,
|
||||
gdouble *x,
|
||||
gdouble *y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkSurface *toplevel;
|
||||
NSPoint point;
|
||||
gint x_tmp, y_tmp;
|
||||
GdkSurface *found_window;
|
||||
|
||||
g_return_val_if_fail (window == NULL || GDK_IS_SURFACE (window), NULL);
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (window))
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
*mask = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
toplevel = gdk_surface_get_toplevel (window);
|
||||
|
||||
if (mask)
|
||||
*mask = _gdk_quartz_events_get_current_keyboard_modifiers () |
|
||||
_gdk_quartz_events_get_current_mouse_modifiers ();
|
||||
|
||||
/* Get the y coordinate, needs to be flipped. */
|
||||
if (window == _gdk_root)
|
||||
{
|
||||
point = [NSEvent mouseLocation];
|
||||
_gdk_quartz_surface_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkSurfaceImplQuartz *impl;
|
||||
NSWindow *nswindow;
|
||||
|
||||
impl = GDK_SURFACE_IMPL_QUARTZ (toplevel->impl);
|
||||
nswindow = impl->toplevel;
|
||||
|
||||
point = [nswindow mouseLocationOutsideOfEventStream];
|
||||
|
||||
x_tmp = point.x;
|
||||
y_tmp = toplevel->height - point.y;
|
||||
|
||||
window = toplevel;
|
||||
}
|
||||
|
||||
found_window = _gdk_quartz_surface_find_child (window, x_tmp, y_tmp,
|
||||
FALSE);
|
||||
|
||||
if (found_window == _gdk_root)
|
||||
found_window = NULL;
|
||||
else if (found_window)
|
||||
translate_coords_to_child_coords (window, found_window,
|
||||
&x_tmp, &y_tmp);
|
||||
|
||||
if (x)
|
||||
*x = x_tmp;
|
||||
|
||||
if (y)
|
||||
*y = y_tmp;
|
||||
|
||||
return found_window;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_device_core_query_state (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
GdkSurface **child_window,
|
||||
gdouble *root_x,
|
||||
gdouble *root_y,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
GdkSurface *found_window;
|
||||
NSPoint point;
|
||||
gint x_tmp, y_tmp;
|
||||
|
||||
if (window == NULL)
|
||||
window = _gdk_root;
|
||||
|
||||
found_window = gdk_quartz_device_core_query_state_helper (window, device,
|
||||
win_x, win_y,
|
||||
mask);
|
||||
|
||||
if (root_window)
|
||||
*root_window = _gdk_root;
|
||||
|
||||
if (child_window)
|
||||
*child_window = found_window;
|
||||
|
||||
point = [NSEvent mouseLocation];
|
||||
_gdk_quartz_surface_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
|
||||
|
||||
if (root_x)
|
||||
*root_x = x_tmp;
|
||||
|
||||
if (root_y)
|
||||
*root_y = y_tmp;
|
||||
}
|
||||
|
||||
static GdkGrabStatus
|
||||
gdk_quartz_device_core_grab (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
gboolean owner_events,
|
||||
GdkEventMask event_mask,
|
||||
GdkSurface *confine_to,
|
||||
GdkCursor *cursor,
|
||||
guint32 time_)
|
||||
{
|
||||
/* Should remain empty */
|
||||
return GDK_GRAB_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_device_core_ungrab (GdkDevice *device,
|
||||
guint32 time_)
|
||||
{
|
||||
GdkDeviceGrabInfo *grab;
|
||||
|
||||
grab = _gdk_display_get_last_device_grab (_gdk_display, device);
|
||||
if (grab)
|
||||
grab->serial_end = 0;
|
||||
|
||||
_gdk_display_device_grab_update (_gdk_display, device, NULL, 0);
|
||||
}
|
||||
|
||||
static GdkSurface *
|
||||
gdk_quartz_device_core_surface_at_position (GdkDevice *device,
|
||||
gdouble *win_x,
|
||||
gdouble *win_y,
|
||||
GdkModifierType *mask,
|
||||
gboolean get_toplevel)
|
||||
{
|
||||
GdkSurface *found_window;
|
||||
NSPoint point;
|
||||
gint x_tmp, y_tmp;
|
||||
|
||||
/* Get mouse coordinates, find window under the mouse pointer */
|
||||
point = [NSEvent mouseLocation];
|
||||
_gdk_quartz_surface_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
|
||||
|
||||
found_window = _gdk_quartz_surface_find_child (_gdk_root, x_tmp, y_tmp, get_toplevel);
|
||||
|
||||
if (found_window)
|
||||
translate_coords_to_child_coords (_gdk_root, found_window, &x_tmp, &y_tmp);
|
||||
|
||||
if (win_x)
|
||||
*win_x = found_window ? x_tmp : -1;
|
||||
|
||||
if (win_y)
|
||||
*win_y = found_window ? y_tmp : -1;
|
||||
|
||||
if (mask)
|
||||
*mask = _gdk_quartz_events_get_current_keyboard_modifiers () |
|
||||
_gdk_quartz_events_get_current_mouse_modifiers ();
|
||||
|
||||
return found_window;
|
||||
}
|
||||
|
@ -1,119 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdevicemanager.h>
|
||||
#include <gdk/gdkdeviceprivate.h>
|
||||
#include <gdk/gdkseatdefaultprivate.h>
|
||||
#include <gdk/gdkdevicemanagerprivate.h>
|
||||
#include "gdkdevicemanager-core-quartz.h"
|
||||
#include "gdkquartzdevice-core.h"
|
||||
#include "gdkkeysyms.h"
|
||||
#include "gdkprivate-quartz.h"
|
||||
|
||||
|
||||
#define HAS_FOCUS(toplevel) \
|
||||
((toplevel)->has_focus || (toplevel)->has_pointer_focus)
|
||||
|
||||
static void gdk_quartz_device_manager_core_finalize (GObject *object);
|
||||
static void gdk_quartz_device_manager_core_constructed (GObject *object);
|
||||
|
||||
static GdkDevice * gdk_quartz_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkQuartzDeviceManagerCore, gdk_quartz_device_manager_core, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gdk_quartz_device_manager_core_class_init (GdkQuartzDeviceManagerCoreClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_quartz_device_manager_core_finalize;
|
||||
object_class->constructed = gdk_quartz_device_manager_core_constructed;
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
create_core_pointer (GdkQuartzDeviceManagerCore *device_manager,
|
||||
GdkDisplay *display)
|
||||
{
|
||||
return g_object_new (GDK_TYPE_QUARTZ_DEVICE_CORE,
|
||||
"name", "Core Pointer",
|
||||
"type", GDK_DEVICE_TYPE_LOGICAL,
|
||||
"input-source", GDK_SOURCE_MOUSE,
|
||||
"input-mode", GDK_MODE_SCREEN,
|
||||
"has-cursor", TRUE,
|
||||
"display", display,
|
||||
"device-manager", device_manager,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
create_core_keyboard (GdkQuartzDeviceManagerCore *device_manager,
|
||||
GdkDisplay *display)
|
||||
{
|
||||
return g_object_new (GDK_TYPE_QUARTZ_DEVICE_CORE,
|
||||
"name", "Core Keyboard",
|
||||
"type", GDK_DEVICE_TYPE_LOGICAL,
|
||||
"input-source", GDK_SOURCE_KEYBOARD,
|
||||
"input-mode", GDK_MODE_SCREEN,
|
||||
"has-cursor", FALSE,
|
||||
"display", display,
|
||||
"device-manager", device_manager,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_device_manager_core_init (GdkQuartzDeviceManagerCore *device_manager)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_device_manager_core_finalize (GObject *object)
|
||||
{
|
||||
GdkQuartzDeviceManagerCore *quartz_device_manager_core;
|
||||
|
||||
quartz_device_manager_core = GDK_QUARTZ_DEVICE_MANAGER_CORE (object);
|
||||
|
||||
g_object_unref (quartz_device_manager_core->core_pointer);
|
||||
g_object_unref (quartz_device_manager_core->core_keyboard);
|
||||
|
||||
G_OBJECT_CLASS (gdk_quartz_device_manager_core_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_device_manager_core_constructed (GObject *object)
|
||||
{
|
||||
GdkQuartzDeviceManagerCore *device_manager;
|
||||
GdkDisplay *display;
|
||||
GdkSeat *seat;
|
||||
|
||||
display = _gdk_display;
|
||||
|
||||
device_manager = GDK_QUARTZ_DEVICE_MANAGER_CORE (object);
|
||||
device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager), display);
|
||||
device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager), display);
|
||||
|
||||
_gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
|
||||
_gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
|
||||
|
||||
seat = gdk_seat_default_new_for_logical_pair (device_manager->core_pointer,
|
||||
device_manager->core_keyboard);
|
||||
gdk_display_add_seat (display, seat);
|
||||
g_object_unref (seat);
|
||||
}
|
@ -1,243 +0,0 @@
|
||||
/* gdkdisplay-quartz.c
|
||||
*
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkdisplayprivate.h>
|
||||
|
||||
#include "gdkprivate-quartz.h"
|
||||
#include "gdkquartzscreen.h"
|
||||
#include "gdkquartzsurface.h"
|
||||
#include "gdkquartzdisplay.h"
|
||||
#include "gdkquartzdevicemanager-core.h"
|
||||
#include "gdkmonitorprivate.h"
|
||||
#include "gdkdisplay-quartz.h"
|
||||
#include "gdkcairocontext-quartz.h"
|
||||
|
||||
|
||||
static GdkSurface *
|
||||
gdk_quartz_display_get_default_group (GdkDisplay *display)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
|
||||
/* FIXME: Implement */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GdkDeviceManager *
|
||||
_gdk_device_manager_new (GdkDisplay *display)
|
||||
{
|
||||
return g_object_new (GDK_TYPE_QUARTZ_DEVICE_MANAGER_CORE,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GdkDisplay *
|
||||
_gdk_quartz_display_open (const gchar *display_name)
|
||||
{
|
||||
if (_gdk_display != NULL)
|
||||
return NULL;
|
||||
|
||||
_gdk_display = g_object_new (gdk_quartz_display_get_type (), NULL);
|
||||
_gdk_device_manager = _gdk_device_manager_new (_gdk_display);
|
||||
|
||||
_gdk_screen = g_object_new (gdk_quartz_screen_get_type (), NULL);
|
||||
|
||||
_gdk_quartz_surface_init_windowing (_gdk_display);
|
||||
|
||||
_gdk_quartz_events_init ();
|
||||
|
||||
/* Initialize application */
|
||||
[NSApplication sharedApplication];
|
||||
#if 0
|
||||
/* FIXME: Remove the #if 0 when we have these functions */
|
||||
_gdk_quartz_dnd_init ();
|
||||
#endif
|
||||
|
||||
g_signal_emit_by_name (_gdk_display, "opened");
|
||||
|
||||
return _gdk_display;
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
gdk_quartz_display_get_name (GdkDisplay *display)
|
||||
{
|
||||
static gchar *display_name = NULL;
|
||||
|
||||
if (!display_name)
|
||||
{
|
||||
GDK_QUARTZ_ALLOC_POOL;
|
||||
display_name = g_strdup ([[[NSHost currentHost] name] UTF8String]);
|
||||
GDK_QUARTZ_RELEASE_POOL;
|
||||
}
|
||||
|
||||
return display_name;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_display_beep (GdkDisplay *display)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
|
||||
NSBeep();
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_display_sync (GdkDisplay *display)
|
||||
{
|
||||
/* Not supported. */
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_display_flush (GdkDisplay *display)
|
||||
{
|
||||
/* Not supported. */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_display_supports_shapes (GdkDisplay *display)
|
||||
{
|
||||
/* FIXME: Implement */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_display_supports_input_shapes (GdkDisplay *display)
|
||||
{
|
||||
/* FIXME: Implement */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gulong
|
||||
gdk_quartz_display_get_next_serial (GdkDisplay *display)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_display_notify_startup_complete (GdkDisplay *display,
|
||||
const gchar *startup_id)
|
||||
{
|
||||
/* FIXME: Implement? */
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_quartz_display_get_n_monitors (GdkDisplay *display)
|
||||
{
|
||||
GdkQuartzDisplay *quartz_display = GDK_QUARTZ_DISPLAY (display);
|
||||
|
||||
return quartz_display->monitors->len;
|
||||
}
|
||||
|
||||
|
||||
static GdkMonitor *
|
||||
gdk_quartz_display_get_monitor (GdkDisplay *display,
|
||||
int monitor_num)
|
||||
{
|
||||
GdkQuartzDisplay *quartz_display = GDK_QUARTZ_DISPLAY (display);
|
||||
|
||||
if (0 <= monitor_num || monitor_num < quartz_display->monitors->len)
|
||||
return (GdkMonitor *)quartz_display->monitors->pdata[monitor_num];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_display_get_setting (GdkDisplay *display,
|
||||
const gchar *name,
|
||||
GValue *value)
|
||||
{
|
||||
return _gdk_quartz_get_setting (name, value);
|
||||
}
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkQuartzDisplay, gdk_quartz_display, GDK_TYPE_DISPLAY)
|
||||
|
||||
static void
|
||||
gdk_quartz_display_init (GdkQuartzDisplay *display)
|
||||
{
|
||||
GDK_QUARTZ_ALLOC_POOL;
|
||||
|
||||
display->monitors = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
GDK_QUARTZ_RELEASE_POOL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_display_dispose (GObject *object)
|
||||
{
|
||||
GdkQuartzDisplay *display_quartz = GDK_QUARTZ_DISPLAY (object);
|
||||
|
||||
g_ptr_array_free (display_quartz->monitors, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (gdk_quartz_display_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_display_finalize (GObject *object)
|
||||
{
|
||||
GdkQuartzDisplay *display_quartz = GDK_QUARTZ_DISPLAY (object);
|
||||
|
||||
G_OBJECT_CLASS (gdk_quartz_display_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_display_class_init (GdkQuartzDisplayClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GdkDisplayClass *display_class = GDK_DISPLAY_CLASS (class);
|
||||
|
||||
object_class->finalize = gdk_quartz_display_finalize;
|
||||
object_class->dispose = gdk_quartz_display_dispose;
|
||||
|
||||
display_class->surface_type = GDK_TYPE_QUARTZ_SURFACE;
|
||||
display_class->cairo_context_type = GDK_TYPE_QUARTZ_CAIRO_CONTEXT;
|
||||
|
||||
display_class->get_name = gdk_quartz_display_get_name;
|
||||
display_class->beep = gdk_quartz_display_beep;
|
||||
display_class->sync = gdk_quartz_display_sync;
|
||||
display_class->flush = gdk_quartz_display_flush;
|
||||
display_class->queue_events = _gdk_quartz_display_queue_events;
|
||||
display_class->has_pending = _gdk_quartz_display_has_pending;
|
||||
display_class->get_default_group = gdk_quartz_display_get_default_group;
|
||||
display_class->supports_shapes = gdk_quartz_display_supports_shapes;
|
||||
display_class->supports_input_shapes = gdk_quartz_display_supports_input_shapes;
|
||||
display_class->get_default_cursor_size = _gdk_quartz_display_get_default_cursor_size;
|
||||
display_class->get_maximal_cursor_size = _gdk_quartz_display_get_maximal_cursor_size;
|
||||
display_class->supports_cursor_alpha = _gdk_quartz_display_supports_cursor_alpha;
|
||||
display_class->supports_cursor_color = _gdk_quartz_display_supports_cursor_color;
|
||||
|
||||
display_class->get_next_serial = gdk_quartz_display_get_next_serial;
|
||||
display_class->notify_startup_complete = gdk_quartz_display_notify_startup_complete;
|
||||
display_class->event_data_copy = _gdk_quartz_display_event_data_copy;
|
||||
display_class->event_data_free = _gdk_quartz_display_event_data_free;
|
||||
display_class->create_surface_impl = _gdk_quartz_display_create_surface_impl;
|
||||
display_class->get_keymap = _gdk_quartz_display_get_keymap;
|
||||
display_class->get_n_monitors = gdk_quartz_display_get_n_monitors;
|
||||
display_class->get_monitor = gdk_quartz_display_get_monitor;
|
||||
display_class->get_setting = gdk_quartz_display_get_setting;
|
||||
|
||||
ProcessSerialNumber psn = { 0, kCurrentProcess };
|
||||
|
||||
/* Make the current process a foreground application, i.e. an app
|
||||
* with a user interface, in case we're not running from a .app bundle
|
||||
*/
|
||||
TransformProcessType (&psn, kProcessTransformToForegroundApplication);
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* gdkdisplay-quartz.h
|
||||
*
|
||||
* Copyright 2017 Tom Schoonjans
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_DISPLAY__
|
||||
#define __GDK_QUARTZ_DISPLAY__
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkkeys.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
struct _GdkQuartzDisplay
|
||||
{
|
||||
GdkDisplay parent_instance;
|
||||
GPtrArray *monitors;
|
||||
};
|
||||
|
||||
struct _GdkQuartzDisplayClass
|
||||
{
|
||||
GdkDisplayClass parent_class;
|
||||
};
|
||||
|
||||
/* Display methods - events */
|
||||
void _gdk_quartz_display_queue_events (GdkDisplay *display);
|
||||
gboolean _gdk_quartz_display_has_pending (GdkDisplay *display);
|
||||
|
||||
void _gdk_quartz_display_event_data_copy (GdkDisplay *display,
|
||||
const GdkEvent *src,
|
||||
GdkEvent *dst);
|
||||
void _gdk_quartz_display_event_data_free (GdkDisplay *display,
|
||||
GdkEvent *event);
|
||||
|
||||
/* Display methods - cursor */
|
||||
gboolean _gdk_quartz_display_supports_cursor_alpha (GdkDisplay *display);
|
||||
gboolean _gdk_quartz_display_supports_cursor_color (GdkDisplay *display);
|
||||
void _gdk_quartz_display_get_default_cursor_size (GdkDisplay *display,
|
||||
guint *width,
|
||||
guint *height);
|
||||
void _gdk_quartz_display_get_maximal_cursor_size (GdkDisplay *display,
|
||||
guint *width,
|
||||
guint *height);
|
||||
|
||||
/* Display methods - window */
|
||||
void _gdk_quartz_display_before_process_all_updates (GdkDisplay *display);
|
||||
void _gdk_quartz_display_after_process_all_updates (GdkDisplay *display);
|
||||
void _gdk_quartz_display_create_surface_impl (GdkDisplay *display,
|
||||
GdkSurface *window,
|
||||
GdkSurface *real_parent,
|
||||
GdkSurfaceAttr *attributes);
|
||||
|
||||
/* Display methods - keymap */
|
||||
GdkKeymap * _gdk_quartz_display_get_keymap (GdkDisplay *display);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_DISPLAY__ */
|
||||
|
@ -1,61 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* gdkdisplaymanager-quartz.c
|
||||
*
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
* Copyright 2010 Red Hat, Inc.
|
||||
*
|
||||
* Author: Matthias clasen
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
#include "gdkquartzdisplay.h"
|
||||
#include "gdkquartzdisplaymanager.h"
|
||||
#include "gdkprivate-quartz.h"
|
||||
|
||||
#include "gdkdisplaymanagerprivate.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
struct _GdkQuartzDisplayManager
|
||||
{
|
||||
GdkDisplayManager parent;
|
||||
};
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkQuartzDisplayManager, gdk_quartz_display_manager, GDK_TYPE_DISPLAY_MANAGER)
|
||||
|
||||
static void
|
||||
gdk_quartz_display_manager_init (GdkQuartzDisplayManager *manager)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_display_manager_finalize (GObject *object)
|
||||
{
|
||||
g_error ("A GdkQuartzDisplayManager object was finalized. This should not happen");
|
||||
G_OBJECT_CLASS (gdk_quartz_display_manager_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_display_manager_class_init (GdkQuartzDisplayManagerClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GdkDisplayManagerClass *manager_class = GDK_DISPLAY_MANAGER_CLASS (class);
|
||||
|
||||
object_class->finalize = gdk_quartz_display_manager_finalize;
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
/* gdkdnd-quartz.c
|
||||
*
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gdkdnd.h"
|
||||
#include "gdkquartzdnd.h"
|
||||
#include "gdkprivate-quartz.h"
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkQuartzDragContext, gdk_quartz_drag_context, GDK_TYPE_DRAG_CONTEXT)
|
||||
|
||||
|
||||
GdkDragContext *_gdk_quartz_drag_source_context = NULL;
|
||||
|
||||
GdkDragContext *
|
||||
gdk_quartz_drag_source_context_libgtk_only ()
|
||||
{
|
||||
return _gdk_quartz_drag_source_context;
|
||||
}
|
||||
|
||||
GdkDragContext *
|
||||
_gdk_quartz_surface_drag_begin (GdkSurface *window,
|
||||
GdkDevice *device,
|
||||
GList *targets,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
g_assert (_gdk_quartz_drag_source_context == NULL);
|
||||
|
||||
/* Create fake context */
|
||||
_gdk_quartz_drag_source_context = g_object_new (GDK_TYPE_QUARTZ_DRAG_CONTEXT,
|
||||
"device", device,
|
||||
NULL);
|
||||
|
||||
_gdk_quartz_drag_source_context->source_surface = window;
|
||||
g_object_ref (window);
|
||||
|
||||
_gdk_quartz_drag_source_context->targets = targets;
|
||||
|
||||
return _gdk_quartz_drag_source_context;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_drag_context_drag_drop (GdkDragContext *context,
|
||||
guint32 time)
|
||||
{
|
||||
/* FIXME: Implement */
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_drag_context_drag_abort (GdkDragContext *context,
|
||||
guint32 time)
|
||||
{
|
||||
/* FIXME: Implement */
|
||||
}
|
||||
|
||||
id
|
||||
gdk_quartz_drag_context_get_dragging_info_libgtk_only (GdkDragContext *context)
|
||||
{
|
||||
return GDK_QUARTZ_DRAG_CONTEXT (context)->dragging_info;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_drag_context_init (GdkQuartzDragContext *context)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_drag_context_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (gdk_quartz_drag_context_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_drag_context_class_init (GdkQuartzDragContextClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDragContextClass *context_class = GDK_DRAG_CONTEXT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_quartz_drag_context_finalize;
|
||||
|
||||
context_class->drag_abort = gdk_quartz_drag_context_drag_abort;
|
||||
context_class->drag_drop = gdk_quartz_drag_context_drag_drop;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,39 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* gdkglcontext-quartz.c: Quartz specific OpenGL wrappers
|
||||
*
|
||||
* Copyright © 2014 Emmanuele Bassi
|
||||
* Copyright © 2014 Alexander Larsson
|
||||
* Copyright © 2014 Brion Vibber
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkglcontext-quartz.h"
|
||||
|
||||
#include "gdkintl.h"
|
||||
|
||||
GdkGLContext *
|
||||
gdk_quartz_surface_create_gl_context (GdkSurface *window,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error)
|
||||
{
|
||||
/* FIXME: implement */
|
||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Not implemented on OS X"));
|
||||
return NULL;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* gdkglcontext-quartz.h: Private Quartz specific OpenGL wrappers
|
||||
*
|
||||
* Copyright © 2014 Emmanuele Bassi
|
||||
* Copyright © 2014 Red Hat, Int
|
||||
* Copyright © 2014 Brion Vibber
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_GL_CONTEXT__
|
||||
#define __GDK_QUARTZ_GL_CONTEXT__
|
||||
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GdkGLContext * gdk_quartz_surface_create_gl_context (GdkSurface *window,
|
||||
gboolean attach,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_GL_CONTEXT__ */
|
@ -1,47 +0,0 @@
|
||||
/* gdkglobals-quartz.c
|
||||
*
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gdktypes.h"
|
||||
#include "gdkquartz.h"
|
||||
#include "gdkscreen-quartz.h"
|
||||
|
||||
GdkDisplay *_gdk_display = NULL;
|
||||
GdkQuartzScreen *_gdk_screen = NULL;
|
||||
GdkSurface *_gdk_root = NULL;
|
||||
GdkDeviceManager *_gdk_device_manager = NULL;
|
||||
|
||||
GdkOSXVersion
|
||||
gdk_quartz_osx_version (void)
|
||||
{
|
||||
static gint32 minor = GDK_OSX_UNSUPPORTED;
|
||||
|
||||
if (minor == GDK_OSX_UNSUPPORTED)
|
||||
{
|
||||
OSErr err = Gestalt (gestaltSystemVersionMinor, (SInt32*)&minor);
|
||||
|
||||
g_return_val_if_fail (err == noErr, GDK_OSX_UNSUPPORTED);
|
||||
}
|
||||
|
||||
if (minor < GDK_OSX_MIN)
|
||||
return GDK_OSX_UNSUPPORTED;
|
||||
else if (minor > GDK_OSX_CURRENT)
|
||||
return GDK_OSX_NEW;
|
||||
else
|
||||
return minor;
|
||||
}
|
@ -1,850 +0,0 @@
|
||||
/* gdkkeys-quartz.c
|
||||
*
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/* Some parts of this code come from quartzKeyboard.c,
|
||||
* from the Apple X11 Server.
|
||||
*
|
||||
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
|
||||
* HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above
|
||||
* copyright holders shall not be used in advertising or otherwise to
|
||||
* promote the sale, use or other dealings in this Software without
|
||||
* prior written authorization.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <AppKit/NSEvent.h>
|
||||
#include "gdk.h"
|
||||
#include "gdkquartzkeys.h"
|
||||
#include "gdkkeysprivate.h"
|
||||
#include "gdkkeysyms.h"
|
||||
|
||||
#define NUM_KEYCODES 128
|
||||
#define KEYVALS_PER_KEYCODE 4
|
||||
|
||||
static GdkKeymap *default_keymap = NULL;
|
||||
|
||||
struct _GdkQuartzKeymap
|
||||
{
|
||||
GdkKeymap keymap;
|
||||
};
|
||||
|
||||
struct _GdkQuartzKeymapClass
|
||||
{
|
||||
GdkKeymapClass keymap_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkQuartzKeymap, gdk_quartz_keymap, GDK_TYPE_KEYMAP)
|
||||
|
||||
GdkKeymap *
|
||||
_gdk_quartz_display_get_keymap (GdkDisplay *display)
|
||||
{
|
||||
if (default_keymap == NULL)
|
||||
default_keymap = g_object_new (gdk_quartz_keymap_get_type (), NULL);
|
||||
|
||||
return default_keymap;
|
||||
}
|
||||
|
||||
/* This is a table of all keyvals. Each keycode gets KEYVALS_PER_KEYCODE entries.
|
||||
* TThere is 1 keyval per modifier (Nothing, Shift, Alt, Shift+Alt);
|
||||
*/
|
||||
static guint *keyval_array = NULL;
|
||||
|
||||
static inline UniChar
|
||||
macroman2ucs (unsigned char c)
|
||||
{
|
||||
/* Precalculated table mapping MacRoman-128 to Unicode. Generated
|
||||
by creating single element CFStringRefs then extracting the
|
||||
first character. */
|
||||
|
||||
static const unsigned short table[128] = {
|
||||
0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1,
|
||||
0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8,
|
||||
0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3,
|
||||
0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc,
|
||||
0x2020, 0xb0, 0xa2, 0xa3, 0xa7, 0x2022, 0xb6, 0xdf,
|
||||
0xae, 0xa9, 0x2122, 0xb4, 0xa8, 0x2260, 0xc6, 0xd8,
|
||||
0x221e, 0xb1, 0x2264, 0x2265, 0xa5, 0xb5, 0x2202, 0x2211,
|
||||
0x220f, 0x3c0, 0x222b, 0xaa, 0xba, 0x3a9, 0xe6, 0xf8,
|
||||
0xbf, 0xa1, 0xac, 0x221a, 0x192, 0x2248, 0x2206, 0xab,
|
||||
0xbb, 0x2026, 0xa0, 0xc0, 0xc3, 0xd5, 0x152, 0x153,
|
||||
0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0xf7, 0x25ca,
|
||||
0xff, 0x178, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02,
|
||||
0x2021, 0xb7, 0x201a, 0x201e, 0x2030, 0xc2, 0xca, 0xc1,
|
||||
0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4,
|
||||
0xf8ff, 0xd2, 0xda, 0xdb, 0xd9, 0x131, 0x2c6, 0x2dc,
|
||||
0xaf, 0x2d8, 0x2d9, 0x2da, 0xb8, 0x2dd, 0x2db, 0x2c7
|
||||
};
|
||||
|
||||
if (c < 128)
|
||||
return c;
|
||||
else
|
||||
return table[c - 128];
|
||||
}
|
||||
|
||||
const static struct {
|
||||
guint keycode;
|
||||
guint keyval;
|
||||
unsigned int modmask; /* So we can tell when a mod key is pressed/released */
|
||||
} modifier_keys[] = {
|
||||
{ 54, GDK_KEY_Meta_R, NSCommandKeyMask },
|
||||
{ 55, GDK_KEY_Meta_L, NSCommandKeyMask },
|
||||
{ 56, GDK_KEY_Shift_L, NSShiftKeyMask },
|
||||
{ 57, GDK_KEY_Caps_Lock, NSAlphaShiftKeyMask },
|
||||
{ 58, GDK_KEY_Alt_L, NSAlternateKeyMask },
|
||||
{ 59, GDK_KEY_Control_L, NSControlKeyMask },
|
||||
{ 60, GDK_KEY_Shift_R, NSShiftKeyMask },
|
||||
{ 61, GDK_KEY_Alt_R, NSAlternateKeyMask },
|
||||
{ 62, GDK_KEY_Control_R, NSControlKeyMask }
|
||||
};
|
||||
|
||||
const static struct {
|
||||
guint keycode;
|
||||
guint keyval;
|
||||
} function_keys[] = {
|
||||
{ 122, GDK_KEY_F1 },
|
||||
{ 120, GDK_KEY_F2 },
|
||||
{ 99, GDK_KEY_F3 },
|
||||
{ 118, GDK_KEY_F4 },
|
||||
{ 96, GDK_KEY_F5 },
|
||||
{ 97, GDK_KEY_F6 },
|
||||
{ 98, GDK_KEY_F7 },
|
||||
{ 100, GDK_KEY_F8 },
|
||||
{ 101, GDK_KEY_F9 },
|
||||
{ 109, GDK_KEY_F10 },
|
||||
{ 103, GDK_KEY_F11 },
|
||||
{ 111, GDK_KEY_F12 },
|
||||
{ 105, GDK_KEY_F13 },
|
||||
{ 107, GDK_KEY_F14 },
|
||||
{ 113, GDK_KEY_F15 },
|
||||
{ 106, GDK_KEY_F16 }
|
||||
};
|
||||
|
||||
const static struct {
|
||||
guint keycode;
|
||||
guint normal_keyval, keypad_keyval;
|
||||
} known_numeric_keys[] = {
|
||||
{ 65, GDK_KEY_period, GDK_KEY_KP_Decimal },
|
||||
{ 67, GDK_KEY_asterisk, GDK_KEY_KP_Multiply },
|
||||
{ 69, GDK_KEY_plus, GDK_KEY_KP_Add },
|
||||
{ 75, GDK_KEY_slash, GDK_KEY_KP_Divide },
|
||||
{ 76, GDK_KEY_Return, GDK_KEY_KP_Enter },
|
||||
{ 78, GDK_KEY_minus, GDK_KEY_KP_Subtract },
|
||||
{ 81, GDK_KEY_equal, GDK_KEY_KP_Equal },
|
||||
{ 82, GDK_KEY_0, GDK_KEY_KP_0 },
|
||||
{ 83, GDK_KEY_1, GDK_KEY_KP_1 },
|
||||
{ 84, GDK_KEY_2, GDK_KEY_KP_2 },
|
||||
{ 85, GDK_KEY_3, GDK_KEY_KP_3 },
|
||||
{ 86, GDK_KEY_4, GDK_KEY_KP_4 },
|
||||
{ 87, GDK_KEY_5, GDK_KEY_KP_5 },
|
||||
{ 88, GDK_KEY_6, GDK_KEY_KP_6 },
|
||||
{ 89, GDK_KEY_7, GDK_KEY_KP_7 },
|
||||
{ 91, GDK_KEY_8, GDK_KEY_KP_8 },
|
||||
{ 92, GDK_KEY_9, GDK_KEY_KP_9 }
|
||||
};
|
||||
|
||||
/* These values aren't covered by gdk_unicode_to_keyval */
|
||||
const static struct {
|
||||
gunichar ucs_value;
|
||||
guint keyval;
|
||||
} special_ucs_table [] = {
|
||||
{ 0x0001, GDK_KEY_Home },
|
||||
{ 0x0003, GDK_KEY_Return },
|
||||
{ 0x0004, GDK_KEY_End },
|
||||
{ 0x0008, GDK_KEY_BackSpace },
|
||||
{ 0x0009, GDK_KEY_Tab },
|
||||
{ 0x000b, GDK_KEY_Page_Up },
|
||||
{ 0x000c, GDK_KEY_Page_Down },
|
||||
{ 0x000d, GDK_KEY_Return },
|
||||
{ 0x001b, GDK_KEY_Escape },
|
||||
{ 0x001c, GDK_KEY_Left },
|
||||
{ 0x001d, GDK_KEY_Right },
|
||||
{ 0x001e, GDK_KEY_Up },
|
||||
{ 0x001f, GDK_KEY_Down },
|
||||
{ 0x007f, GDK_KEY_Delete },
|
||||
{ 0xf027, GDK_KEY_dead_acute },
|
||||
{ 0xf060, GDK_KEY_dead_grave },
|
||||
{ 0xf300, GDK_KEY_dead_grave },
|
||||
{ 0xf0b4, GDK_KEY_dead_acute },
|
||||
{ 0xf301, GDK_KEY_dead_acute },
|
||||
{ 0xf385, GDK_KEY_dead_acute },
|
||||
{ 0xf05e, GDK_KEY_dead_circumflex },
|
||||
{ 0xf2c6, GDK_KEY_dead_circumflex },
|
||||
{ 0xf302, GDK_KEY_dead_circumflex },
|
||||
{ 0xf07e, GDK_KEY_dead_tilde },
|
||||
{ 0xf2dc, GDK_KEY_dead_tilde },
|
||||
{ 0xf303, GDK_KEY_dead_tilde },
|
||||
{ 0xf342, GDK_KEY_dead_perispomeni },
|
||||
{ 0xf0af, GDK_KEY_dead_macron },
|
||||
{ 0xf304, GDK_KEY_dead_macron },
|
||||
{ 0xf2d8, GDK_KEY_dead_breve },
|
||||
{ 0xf306, GDK_KEY_dead_breve },
|
||||
{ 0xf2d9, GDK_KEY_dead_abovedot },
|
||||
{ 0xf307, GDK_KEY_dead_abovedot },
|
||||
{ 0xf0a8, GDK_KEY_dead_diaeresis },
|
||||
{ 0xf308, GDK_KEY_dead_diaeresis },
|
||||
{ 0xf2da, GDK_KEY_dead_abovering },
|
||||
{ 0xf30A, GDK_KEY_dead_abovering },
|
||||
{ 0xf022, GDK_KEY_dead_doubleacute },
|
||||
{ 0xf2dd, GDK_KEY_dead_doubleacute },
|
||||
{ 0xf30B, GDK_KEY_dead_doubleacute },
|
||||
{ 0xf2c7, GDK_KEY_dead_caron },
|
||||
{ 0xf30C, GDK_KEY_dead_caron },
|
||||
{ 0xf0be, GDK_KEY_dead_cedilla },
|
||||
{ 0xf327, GDK_KEY_dead_cedilla },
|
||||
{ 0xf2db, GDK_KEY_dead_ogonek },
|
||||
{ 0xf328, GDK_KEY_dead_ogonek },
|
||||
{ 0xfe5d, GDK_KEY_dead_iota },
|
||||
{ 0xf323, GDK_KEY_dead_belowdot },
|
||||
{ 0xf309, GDK_KEY_dead_hook },
|
||||
{ 0xf31B, GDK_KEY_dead_horn },
|
||||
{ 0xf02d, GDK_KEY_dead_stroke },
|
||||
{ 0xf335, GDK_KEY_dead_stroke },
|
||||
{ 0xf336, GDK_KEY_dead_stroke },
|
||||
{ 0xf313, GDK_KEY_dead_abovecomma },
|
||||
/* { 0xf313, GDK_KEY_dead_psili }, */
|
||||
{ 0xf314, GDK_KEY_dead_abovereversedcomma },
|
||||
/* { 0xf314, GDK_KEY_dead_dasia }, */
|
||||
{ 0xf30F, GDK_KEY_dead_doublegrave },
|
||||
{ 0xf325, GDK_KEY_dead_belowring },
|
||||
{ 0xf2cd, GDK_KEY_dead_belowmacron },
|
||||
{ 0xf331, GDK_KEY_dead_belowmacron },
|
||||
{ 0xf32D, GDK_KEY_dead_belowcircumflex },
|
||||
{ 0xf330, GDK_KEY_dead_belowtilde },
|
||||
{ 0xf32E, GDK_KEY_dead_belowbreve },
|
||||
{ 0xf324, GDK_KEY_dead_belowdiaeresis },
|
||||
{ 0xf311, GDK_KEY_dead_invertedbreve },
|
||||
{ 0xf02c, GDK_KEY_dead_belowcomma },
|
||||
{ 0xf326, GDK_KEY_dead_belowcomma }
|
||||
};
|
||||
|
||||
static void
|
||||
update_keymap (void)
|
||||
{
|
||||
const void *chr_data = NULL;
|
||||
guint *p;
|
||||
int i;
|
||||
|
||||
/* Note: we could check only if building against the 10.5 SDK instead, but
|
||||
* that would make non-xml layouts not work in 32-bit which would be a quite
|
||||
* bad regression. This way, old unsupported layouts will just not work in
|
||||
* 64-bit.
|
||||
*/
|
||||
#ifdef __LP64__
|
||||
TISInputSourceRef new_layout = TISCopyCurrentKeyboardLayoutInputSource ();
|
||||
CFDataRef layout_data_ref;
|
||||
|
||||
#else
|
||||
KeyboardLayoutRef new_layout;
|
||||
KeyboardLayoutKind layout_kind;
|
||||
|
||||
KLGetCurrentKeyboardLayout (&new_layout);
|
||||
#endif
|
||||
|
||||
g_free (keyval_array);
|
||||
keyval_array = g_new0 (guint, NUM_KEYCODES * KEYVALS_PER_KEYCODE);
|
||||
|
||||
#ifdef __LP64__
|
||||
layout_data_ref = (CFDataRef) TISGetInputSourceProperty
|
||||
(new_layout, kTISPropertyUnicodeKeyLayoutData);
|
||||
|
||||
if (layout_data_ref)
|
||||
chr_data = CFDataGetBytePtr (layout_data_ref);
|
||||
|
||||
if (chr_data == NULL)
|
||||
{
|
||||
g_error ("cannot get keyboard layout data");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
|
||||
/* Get the layout kind */
|
||||
KLGetKeyboardLayoutProperty (new_layout, kKLKind, (const void **)&layout_kind);
|
||||
|
||||
/* 8-bit-only keyabord layout */
|
||||
if (layout_kind == kKLKCHRKind)
|
||||
{
|
||||
/* Get chr data */
|
||||
KLGetKeyboardLayoutProperty (new_layout, kKLKCHRData, (const void **)&chr_data);
|
||||
|
||||
for (i = 0; i < NUM_KEYCODES; i++)
|
||||
{
|
||||
int j;
|
||||
UInt32 modifiers[] = {0, shiftKey, optionKey, shiftKey | optionKey};
|
||||
|
||||
p = keyval_array + i * KEYVALS_PER_KEYCODE;
|
||||
|
||||
for (j = 0; j < KEYVALS_PER_KEYCODE; j++)
|
||||
{
|
||||
UInt32 c, state = 0;
|
||||
UInt16 key_code;
|
||||
UniChar uc;
|
||||
|
||||
key_code = modifiers[j] | i;
|
||||
c = KeyTranslate (chr_data, key_code, &state);
|
||||
|
||||
if (state != 0)
|
||||
{
|
||||
UInt32 state2 = 0;
|
||||
c = KeyTranslate (chr_data, key_code | 128, &state2);
|
||||
}
|
||||
|
||||
if (c != 0 && c != 0x10)
|
||||
{
|
||||
int k;
|
||||
gboolean found = FALSE;
|
||||
|
||||
/* FIXME: some keyboard layouts (e.g. Russian) use a
|
||||
* different 8-bit character set. We should check
|
||||
* for this. Not a serious problem, because most
|
||||
* (all?) of these layouts also have a uchr version.
|
||||
*/
|
||||
uc = macroman2ucs (c);
|
||||
|
||||
for (k = 0; k < G_N_ELEMENTS (special_ucs_table); k++)
|
||||
{
|
||||
if (special_ucs_table[k].ucs_value == uc)
|
||||
{
|
||||
p[j] = special_ucs_table[k].keyval;
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Special-case shift-tab since GTK+ expects
|
||||
* GDK_KEY_ISO_Left_Tab for that.
|
||||
*/
|
||||
if (found && p[j] == GDK_KEY_Tab && modifiers[j] == shiftKey)
|
||||
p[j] = GDK_KEY_ISO_Left_Tab;
|
||||
|
||||
if (!found)
|
||||
p[j] = gdk_unicode_to_keyval (uc);
|
||||
}
|
||||
}
|
||||
|
||||
if (p[3] == p[2])
|
||||
p[3] = 0;
|
||||
if (p[2] == p[1])
|
||||
p[2] = 0;
|
||||
if (p[1] == p[0])
|
||||
p[1] = 0;
|
||||
if (p[0] == p[2] &&
|
||||
p[1] == p[3])
|
||||
p[2] = p[3] = 0;
|
||||
}
|
||||
}
|
||||
/* unicode keyboard layout */
|
||||
else if (layout_kind == kKLKCHRuchrKind || layout_kind == kKLuchrKind)
|
||||
{
|
||||
/* Get chr data */
|
||||
KLGetKeyboardLayoutProperty (new_layout, kKLuchrData, (const void **)&chr_data);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < NUM_KEYCODES; i++)
|
||||
{
|
||||
int j;
|
||||
UInt32 modifiers[] = {0, shiftKey, optionKey, shiftKey | optionKey};
|
||||
UniChar chars[4];
|
||||
UniCharCount nChars;
|
||||
|
||||
p = keyval_array + i * KEYVALS_PER_KEYCODE;
|
||||
|
||||
for (j = 0; j < KEYVALS_PER_KEYCODE; j++)
|
||||
{
|
||||
UInt32 state = 0;
|
||||
OSStatus err;
|
||||
UInt16 key_code;
|
||||
UniChar uc;
|
||||
|
||||
key_code = modifiers[j] | i;
|
||||
err = UCKeyTranslate (chr_data, i, kUCKeyActionDisplay,
|
||||
(modifiers[j] >> 8) & 0xFF,
|
||||
LMGetKbdType(),
|
||||
0,
|
||||
&state, 4, &nChars, chars);
|
||||
|
||||
/* FIXME: Theoretically, we can get multiple UTF-16
|
||||
* values; we should convert them to proper unicode and
|
||||
* figure out whether there are really keyboard layouts
|
||||
* that give us more than one character for one
|
||||
* keypress.
|
||||
*/
|
||||
if (err == noErr && nChars == 1)
|
||||
{
|
||||
int k;
|
||||
gboolean found = FALSE;
|
||||
|
||||
/* A few <Shift><Option>keys return two characters,
|
||||
* the first of which is U+00a0, which isn't
|
||||
* interesting; so we return the second. More
|
||||
* sophisticated handling is the job of a
|
||||
* GtkIMContext.
|
||||
*
|
||||
* If state isn't zero, it means that it's a dead
|
||||
* key of some sort. Some of those are enumerated in
|
||||
* the special_ucs_table with the high nibble set to
|
||||
* f to push it into the private use range. Here we
|
||||
* do the same.
|
||||
*/
|
||||
if (state != 0)
|
||||
chars[nChars - 1] |= 0xf000;
|
||||
uc = chars[nChars - 1];
|
||||
|
||||
for (k = 0; k < G_N_ELEMENTS (special_ucs_table); k++)
|
||||
{
|
||||
if (special_ucs_table[k].ucs_value == uc)
|
||||
{
|
||||
p[j] = special_ucs_table[k].keyval;
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Special-case shift-tab since GTK+ expects
|
||||
* GDK_KEY_ISO_Left_Tab for that.
|
||||
*/
|
||||
if (found && p[j] == GDK_KEY_Tab && modifiers[j] == shiftKey)
|
||||
p[j] = GDK_KEY_ISO_Left_Tab;
|
||||
|
||||
if (!found)
|
||||
p[j] = gdk_unicode_to_keyval (uc);
|
||||
}
|
||||
}
|
||||
|
||||
if (p[3] == p[2])
|
||||
p[3] = 0;
|
||||
if (p[2] == p[1])
|
||||
p[2] = 0;
|
||||
if (p[1] == p[0])
|
||||
p[1] = 0;
|
||||
if (p[0] == p[2] &&
|
||||
p[1] == p[3])
|
||||
p[2] = p[3] = 0;
|
||||
}
|
||||
#ifndef __LP64__
|
||||
}
|
||||
else
|
||||
{
|
||||
g_error ("unknown type of keyboard layout (neither KCHR nor uchr)"
|
||||
" - not supported right now");
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (modifier_keys); i++)
|
||||
{
|
||||
p = keyval_array + modifier_keys[i].keycode * KEYVALS_PER_KEYCODE;
|
||||
|
||||
if (p[0] == 0 && p[1] == 0 &&
|
||||
p[2] == 0 && p[3] == 0)
|
||||
p[0] = modifier_keys[i].keyval;
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (function_keys); i++)
|
||||
{
|
||||
p = keyval_array + function_keys[i].keycode * KEYVALS_PER_KEYCODE;
|
||||
|
||||
p[0] = function_keys[i].keyval;
|
||||
p[1] = p[2] = p[3] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (known_numeric_keys); i++)
|
||||
{
|
||||
p = keyval_array + known_numeric_keys[i].keycode * KEYVALS_PER_KEYCODE;
|
||||
|
||||
if (p[0] == known_numeric_keys[i].normal_keyval)
|
||||
p[0] = known_numeric_keys[i].keypad_keyval;
|
||||
}
|
||||
|
||||
if (default_keymap != NULL)
|
||||
g_signal_emit_by_name (default_keymap, "keys-changed");
|
||||
}
|
||||
|
||||
static PangoDirection
|
||||
gdk_quartz_keymap_get_direction (GdkKeymap *keymap)
|
||||
{
|
||||
return PANGO_DIRECTION_NEUTRAL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_keymap_have_bidi_layouts (GdkKeymap *keymap)
|
||||
{
|
||||
/* FIXME: Can we implement this? */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_keymap_get_caps_lock_state (GdkKeymap *keymap)
|
||||
{
|
||||
/* FIXME: Implement this. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_keymap_get_num_lock_state (GdkKeymap *keymap)
|
||||
{
|
||||
/* FIXME: Implement this. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_keymap_get_scroll_lock_state (GdkKeymap *keymap)
|
||||
{
|
||||
/* FIXME: Implement this. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_keymap_get_entries_for_keyval (GdkKeymap *keymap,
|
||||
guint keyval,
|
||||
GdkKeymapKey **keys,
|
||||
gint *n_keys)
|
||||
{
|
||||
GArray *keys_array;
|
||||
int i;
|
||||
|
||||
*n_keys = 0;
|
||||
keys_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
|
||||
|
||||
for (i = 0; i < NUM_KEYCODES * KEYVALS_PER_KEYCODE; i++)
|
||||
{
|
||||
GdkKeymapKey key;
|
||||
|
||||
if (keyval_array[i] != keyval)
|
||||
continue;
|
||||
|
||||
(*n_keys)++;
|
||||
|
||||
key.keycode = i / KEYVALS_PER_KEYCODE;
|
||||
key.group = (i % KEYVALS_PER_KEYCODE) >= 2;
|
||||
key.level = i % 2;
|
||||
|
||||
g_array_append_val (keys_array, key);
|
||||
}
|
||||
|
||||
*keys = (GdkKeymapKey *)g_array_free (keys_array, FALSE);
|
||||
|
||||
return *n_keys > 0;;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_keymap_get_entries_for_keycode (GdkKeymap *keymap,
|
||||
guint hardware_keycode,
|
||||
GdkKeymapKey **keys,
|
||||
guint **keyvals,
|
||||
gint *n_entries)
|
||||
{
|
||||
GArray *keys_array, *keyvals_array;
|
||||
int i;
|
||||
guint *p;
|
||||
|
||||
*n_entries = 0;
|
||||
|
||||
if (hardware_keycode > NUM_KEYCODES)
|
||||
return FALSE;
|
||||
|
||||
if (keys)
|
||||
keys_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
|
||||
else
|
||||
keys_array = NULL;
|
||||
|
||||
if (keyvals)
|
||||
keyvals_array = g_array_new (FALSE, FALSE, sizeof (guint));
|
||||
else
|
||||
keyvals_array = NULL;
|
||||
|
||||
p = keyval_array + hardware_keycode * KEYVALS_PER_KEYCODE;
|
||||
|
||||
for (i = 0; i < KEYVALS_PER_KEYCODE; i++)
|
||||
{
|
||||
if (!p[i])
|
||||
continue;
|
||||
|
||||
(*n_entries)++;
|
||||
|
||||
if (keyvals_array)
|
||||
g_array_append_val (keyvals_array, p[i]);
|
||||
|
||||
if (keys_array)
|
||||
{
|
||||
GdkKeymapKey key;
|
||||
|
||||
key.keycode = hardware_keycode;
|
||||
key.group = i >= 2;
|
||||
key.level = i % 2;
|
||||
|
||||
g_array_append_val (keys_array, key);
|
||||
}
|
||||
}
|
||||
|
||||
if (keys)
|
||||
*keys = (GdkKeymapKey *)g_array_free (keys_array, FALSE);
|
||||
|
||||
if (keyvals)
|
||||
*keyvals = (guint *)g_array_free (keyvals_array, FALSE);
|
||||
|
||||
return *n_entries > 0;
|
||||
}
|
||||
|
||||
#define GET_KEYVAL(keycode, group, level) (keyval_array[(keycode * KEYVALS_PER_KEYCODE + group * 2 + level)])
|
||||
|
||||
static guint
|
||||
gdk_quartz_keymap_lookup_key (GdkKeymap *keymap,
|
||||
const GdkKeymapKey *key)
|
||||
{
|
||||
return GET_KEYVAL (key->keycode, key->group, key->level);
|
||||
}
|
||||
|
||||
static guint
|
||||
translate_keysym (guint hardware_keycode,
|
||||
gint group,
|
||||
GdkModifierType state,
|
||||
gint *effective_group,
|
||||
gint *effective_level)
|
||||
{
|
||||
gint level;
|
||||
guint tmp_keyval;
|
||||
|
||||
level = (state & GDK_SHIFT_MASK) ? 1 : 0;
|
||||
|
||||
if (!(GET_KEYVAL (hardware_keycode, group, 0) || GET_KEYVAL (hardware_keycode, group, 1)) &&
|
||||
(GET_KEYVAL (hardware_keycode, 0, 0) || GET_KEYVAL (hardware_keycode, 0, 1)))
|
||||
group = 0;
|
||||
|
||||
if (!GET_KEYVAL (hardware_keycode, group, level) &&
|
||||
GET_KEYVAL (hardware_keycode, group, 0))
|
||||
level = 0;
|
||||
|
||||
tmp_keyval = GET_KEYVAL (hardware_keycode, group, level);
|
||||
|
||||
if (state & GDK_LOCK_MASK)
|
||||
{
|
||||
guint upper = gdk_keyval_to_upper (tmp_keyval);
|
||||
if (upper != tmp_keyval)
|
||||
tmp_keyval = upper;
|
||||
}
|
||||
|
||||
if (effective_group)
|
||||
*effective_group = group;
|
||||
if (effective_level)
|
||||
*effective_level = level;
|
||||
|
||||
return tmp_keyval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_keymap_translate_keyboard_state (GdkKeymap *keymap,
|
||||
guint hardware_keycode,
|
||||
GdkModifierType state,
|
||||
gint group,
|
||||
guint *keyval,
|
||||
gint *effective_group,
|
||||
gint *level,
|
||||
GdkModifierType *consumed_modifiers)
|
||||
{
|
||||
guint tmp_keyval;
|
||||
GdkModifierType bit;
|
||||
|
||||
if (keyval)
|
||||
*keyval = 0;
|
||||
if (effective_group)
|
||||
*effective_group = 0;
|
||||
if (level)
|
||||
*level = 0;
|
||||
if (consumed_modifiers)
|
||||
*consumed_modifiers = 0;
|
||||
|
||||
if (hardware_keycode < 0 || hardware_keycode >= NUM_KEYCODES)
|
||||
return FALSE;
|
||||
|
||||
tmp_keyval = translate_keysym (hardware_keycode, group, state, level, effective_group);
|
||||
|
||||
/* Check if modifiers modify the keyval */
|
||||
if (consumed_modifiers)
|
||||
{
|
||||
guint tmp_modifiers = (state & GDK_MODIFIER_MASK);
|
||||
|
||||
for (bit = 1; bit <= tmp_modifiers; bit <<= 1)
|
||||
{
|
||||
if ((bit & tmp_modifiers) &&
|
||||
translate_keysym (hardware_keycode, group, state & ~bit,
|
||||
NULL, NULL) == tmp_keyval)
|
||||
tmp_modifiers &= ~bit;
|
||||
}
|
||||
|
||||
*consumed_modifiers = tmp_modifiers;
|
||||
}
|
||||
|
||||
if (keyval)
|
||||
*keyval = tmp_keyval;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_keymap_add_virtual_modifiers (GdkKeymap *keymap,
|
||||
GdkModifierType *state)
|
||||
{
|
||||
if (*state & GDK_MOD2_MASK)
|
||||
*state |= GDK_META_MASK;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_quartz_keymap_map_virtual_modifiers (GdkKeymap *keymap,
|
||||
GdkModifierType *state)
|
||||
{
|
||||
if (*state & GDK_META_MASK)
|
||||
*state |= GDK_MOD2_MASK;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* What sort of key event is this? Returns one of
|
||||
* GDK_KEY_PRESS, GDK_KEY_RELEASE, GDK_NOTHING (should be ignored)
|
||||
*/
|
||||
GdkEventType
|
||||
_gdk_quartz_keys_event_type (NSEvent *event)
|
||||
{
|
||||
unsigned short keycode;
|
||||
unsigned int flags;
|
||||
int i;
|
||||
|
||||
switch ([event type])
|
||||
{
|
||||
case NSKeyDown:
|
||||
return GDK_KEY_PRESS;
|
||||
case NSKeyUp:
|
||||
return GDK_KEY_RELEASE;
|
||||
case NSFlagsChanged:
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
/* For flags-changed events, we have to find the special key that caused the
|
||||
* event, and see if it's in the modifier mask. */
|
||||
keycode = [event keyCode];
|
||||
flags = [event modifierFlags];
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (modifier_keys); i++)
|
||||
{
|
||||
if (modifier_keys[i].keycode == keycode)
|
||||
{
|
||||
if (flags & modifier_keys[i].modmask)
|
||||
return GDK_KEY_PRESS;
|
||||
else
|
||||
return GDK_KEY_RELEASE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Some keypresses (eg: Expose' activations) seem to trigger flags-changed
|
||||
* events for no good reason. Ignore them! */
|
||||
return GDK_NOTHING;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_quartz_keys_is_modifier (guint keycode)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (modifier_keys); i++)
|
||||
{
|
||||
if (modifier_keys[i].modmask == 0)
|
||||
break;
|
||||
|
||||
if (modifier_keys[i].keycode == keycode)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
input_sources_changed_notification (CFNotificationCenterRef center,
|
||||
void *observer,
|
||||
CFStringRef name,
|
||||
const void *object,
|
||||
CFDictionaryRef userInfo)
|
||||
{
|
||||
update_keymap ();
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_keymap_init (GdkQuartzKeymap *keymap)
|
||||
{
|
||||
update_keymap ();
|
||||
CFNotificationCenterAddObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
keymap,
|
||||
input_sources_changed_notification,
|
||||
CFSTR ("AppleSelectedInputSourcesChangedNotification"),
|
||||
NULL,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_keymap_finalize (GObject *object)
|
||||
{
|
||||
CFNotificationCenterRemoveObserver (CFNotificationCenterGetDistributedCenter (),
|
||||
object,
|
||||
CFSTR ("AppleSelectedInputSourcesChangedNotification"),
|
||||
NULL);
|
||||
|
||||
G_OBJECT_CLASS (gdk_quartz_keymap_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_keymap_class_init (GdkQuartzKeymapClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkKeymapClass *keymap_class = GDK_KEYMAP_CLASS (klass);
|
||||
|
||||
object_class->finalize = gdk_quartz_keymap_finalize;
|
||||
|
||||
keymap_class->get_direction = gdk_quartz_keymap_get_direction;
|
||||
keymap_class->have_bidi_layouts = gdk_quartz_keymap_have_bidi_layouts;
|
||||
keymap_class->get_caps_lock_state = gdk_quartz_keymap_get_caps_lock_state;
|
||||
keymap_class->get_num_lock_state = gdk_quartz_keymap_get_num_lock_state;
|
||||
keymap_class->get_scroll_lock_state = gdk_quartz_keymap_get_scroll_lock_state;
|
||||
keymap_class->get_entries_for_keyval = gdk_quartz_keymap_get_entries_for_keyval;
|
||||
keymap_class->get_entries_for_keycode = gdk_quartz_keymap_get_entries_for_keycode;
|
||||
keymap_class->lookup_key = gdk_quartz_keymap_lookup_key;
|
||||
keymap_class->translate_keyboard_state = gdk_quartz_keymap_translate_keyboard_state;
|
||||
keymap_class->add_virtual_modifiers = gdk_quartz_keymap_add_virtual_modifiers;
|
||||
keymap_class->map_virtual_modifiers = gdk_quartz_keymap_map_virtual_modifiers;
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2017 Tom Schoonjans
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gdkmonitor-quartz.h"
|
||||
#include "gdkscreen-quartz.h"
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkQuartzMonitor, gdk_quartz_monitor, GDK_TYPE_MONITOR)
|
||||
|
||||
static void
|
||||
gdk_quartz_monitor_get_workarea (GdkMonitor *monitor,
|
||||
GdkRectangle *dest)
|
||||
{
|
||||
GdkQuartzScreen *quartz_screen = GDK_QUARTZ_SCREEN(_gdk_screen);
|
||||
GdkQuartzMonitor *quartz_monitor = GDK_QUARTZ_MONITOR(monitor);
|
||||
|
||||
GDK_QUARTZ_ALLOC_POOL;
|
||||
|
||||
NSArray *array = [NSScreen screens];
|
||||
if (quartz_monitor->monitor_num < [array count])
|
||||
{
|
||||
NSScreen *screen = [array objectAtIndex:quartz_monitor->monitor_num];
|
||||
NSRect rect = [screen visibleFrame];
|
||||
|
||||
dest->x = rect.origin.x - quartz_screen->min_x;
|
||||
dest->y = quartz_screen->height - (rect.origin.y + rect.size.height) + quartz_screen->min_y;
|
||||
dest->width = rect.size.width;
|
||||
dest->height = rect.size.height;
|
||||
}
|
||||
else
|
||||
*dest = monitor->geometry;
|
||||
|
||||
GDK_QUARTZ_RELEASE_POOL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_monitor_init (GdkQuartzMonitor *monitor)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_monitor_class_init (GdkQuartzMonitorClass *class)
|
||||
{
|
||||
GDK_MONITOR_CLASS (class)->get_workarea = gdk_quartz_monitor_get_workarea;
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2017 Tom Schoonjans
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_MONITOR_PRIVATE_H__
|
||||
#define __GDK_QUARTZ_MONITOR_PRIVATE_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gdkmonitorprivate.h"
|
||||
|
||||
#include "gdkquartzmonitor.h"
|
||||
#include "gdkprivate-quartz.h"
|
||||
|
||||
struct _GdkQuartzMonitor
|
||||
{
|
||||
GdkMonitor parent;
|
||||
|
||||
gint monitor_num;
|
||||
};
|
||||
|
||||
struct _GdkQuartzMonitorClass {
|
||||
GdkMonitorClass parent_class;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,149 +0,0 @@
|
||||
/* gdksurface-quartz.c
|
||||
*
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_PRIVATE_QUARTZ_H__
|
||||
#define __GDK_PRIVATE_QUARTZ_H__
|
||||
|
||||
#define GDK_QUARTZ_ALLOC_POOL NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]
|
||||
#define GDK_QUARTZ_RELEASE_POOL [pool release]
|
||||
|
||||
#include <gdk/quartz/gdkquartz.h>
|
||||
#include <gdk/quartz/gdkdevicemanager-core-quartz.h>
|
||||
#include <gdk/quartz/gdkdnd-quartz.h>
|
||||
#include <gdk/quartz/gdkscreen-quartz.h>
|
||||
#include <gdk/quartz/gdksurface-quartz.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkinternals.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
extern GdkDisplay *_gdk_display;
|
||||
extern GdkQuartzScreen *_gdk_screen;
|
||||
extern GdkSurface *_gdk_root;
|
||||
extern GdkDeviceManager *_gdk_device_manager;
|
||||
|
||||
extern GdkDragContext *_gdk_quartz_drag_source_context;
|
||||
|
||||
#define GDK_SURFACE_IS_QUARTZ(win) (GDK_IS_SURFACE_IMPL_QUARTZ (((GdkSurface *)win)->impl))
|
||||
|
||||
/* Initialization */
|
||||
void _gdk_quartz_surface_init_windowing (GdkDisplay *display);
|
||||
void _gdk_quartz_events_init (void);
|
||||
void _gdk_quartz_event_loop_init (void);
|
||||
|
||||
/* Cursor */
|
||||
NSCursor *_gdk_quartz_cursor_get_ns_cursor (GdkCursor *cursor);
|
||||
|
||||
/* Events */
|
||||
typedef enum {
|
||||
GDK_QUARTZ_EVENT_SUBTYPE_EVENTLOOP
|
||||
} GdkQuartzEventSubType;
|
||||
|
||||
void _gdk_quartz_events_update_focus_window (GdkSurface *new_window,
|
||||
gboolean got_focus);
|
||||
void _gdk_quartz_events_send_map_event (GdkSurface *window);
|
||||
|
||||
GdkModifierType _gdk_quartz_events_get_current_keyboard_modifiers (void);
|
||||
GdkModifierType _gdk_quartz_events_get_current_mouse_modifiers (void);
|
||||
|
||||
void _gdk_quartz_events_break_all_grabs (guint32 time);
|
||||
|
||||
/* Event loop */
|
||||
gboolean _gdk_quartz_event_loop_check_pending (void);
|
||||
NSEvent * _gdk_quartz_event_loop_get_pending (void);
|
||||
void _gdk_quartz_event_loop_release_event (NSEvent *event);
|
||||
|
||||
/* Keys */
|
||||
GdkEventType _gdk_quartz_keys_event_type (NSEvent *event);
|
||||
gboolean _gdk_quartz_keys_is_modifier (guint keycode);
|
||||
void _gdk_quartz_synthesize_null_key_event (GdkSurface *window);
|
||||
|
||||
/* Drag and Drop */
|
||||
GdkDragContext * _gdk_quartz_surface_drag_begin (GdkSurface *window,
|
||||
GdkDevice *device,
|
||||
GList *targets,
|
||||
gint x_root,
|
||||
gint y_root);
|
||||
|
||||
/* Display */
|
||||
|
||||
GdkDisplay * _gdk_quartz_display_open (const gchar *name);
|
||||
|
||||
|
||||
/* Screen */
|
||||
GdkQuartzScreen *_gdk_quartz_screen_new (void);
|
||||
void _gdk_quartz_screen_update_window_sizes (GdkQuartzScreen *screen);
|
||||
|
||||
/* Screen methods - events */
|
||||
gboolean _gdk_quartz_get_setting (const gchar *name,
|
||||
GValue *value);
|
||||
|
||||
|
||||
/* Window */
|
||||
gboolean _gdk_quartz_surface_is_ancestor (GdkSurface *ancestor,
|
||||
GdkSurface *window);
|
||||
void _gdk_quartz_surface_gdk_xy_to_xy (gint gdk_x,
|
||||
gint gdk_y,
|
||||
gint *ns_x,
|
||||
gint *ns_y);
|
||||
void _gdk_quartz_surface_xy_to_gdk_xy (gint ns_x,
|
||||
gint ns_y,
|
||||
gint *gdk_x,
|
||||
gint *gdk_y);
|
||||
void _gdk_quartz_surface_nspoint_to_gdk_xy (NSPoint point,
|
||||
gint *x,
|
||||
gint *y);
|
||||
GdkSurface *_gdk_quartz_surface_find_child (GdkSurface *window,
|
||||
gint x,
|
||||
gint y,
|
||||
gboolean get_toplevel);
|
||||
void _gdk_quartz_surface_attach_to_parent (GdkSurface *window);
|
||||
void _gdk_quartz_surface_detach_from_parent (GdkSurface *window);
|
||||
void _gdk_quartz_surface_did_become_main (GdkSurface *window);
|
||||
void _gdk_quartz_surface_did_resign_main (GdkSurface *window);
|
||||
void _gdk_quartz_surface_debug_highlight (GdkSurface *window,
|
||||
gint number);
|
||||
|
||||
void _gdk_quartz_surface_update_position (GdkSurface *window);
|
||||
void _gdk_quartz_surface_update_fullscreen_state (GdkSurface *window);
|
||||
|
||||
/* Window methods - property */
|
||||
gboolean _gdk_quartz_surface_get_property (GdkSurface *window,
|
||||
GdkAtom property,
|
||||
GdkAtom type,
|
||||
gulong offset,
|
||||
gulong length,
|
||||
gint pdelete,
|
||||
GdkAtom *actual_property_type,
|
||||
gint *actual_format_type,
|
||||
gint *actual_length,
|
||||
guchar **data);
|
||||
void _gdk_quartz_surface_change_property (GdkSurface *window,
|
||||
GdkAtom property,
|
||||
GdkAtom type,
|
||||
gint format,
|
||||
GdkPropMode mode,
|
||||
const guchar *data,
|
||||
gint nelements);
|
||||
void _gdk_quartz_surface_delete_property (GdkSurface *window,
|
||||
GdkAtom property);
|
||||
|
||||
|
||||
#endif /* __GDK_PRIVATE_QUARTZ_H__ */
|
@ -1,89 +0,0 @@
|
||||
|
||||
/* gdkquartz.h
|
||||
*
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_H__
|
||||
#define __GDK_QUARTZ_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* NSInteger only exists in Leopard and newer. This check has to be
|
||||
* done after inclusion of the system headers. If NSInteger has not
|
||||
* been defined, we know for sure that we are on 32-bit.
|
||||
*/
|
||||
#ifndef NSINTEGER_DEFINED
|
||||
typedef int NSInteger;
|
||||
typedef unsigned int NSUInteger;
|
||||
#endif
|
||||
|
||||
#ifndef CGFLOAT_DEFINED
|
||||
typedef float CGFloat;
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_OSX_UNSUPPORTED = 0,
|
||||
GDK_OSX_MIN = 4,
|
||||
GDK_OSX_TIGER = 4,
|
||||
GDK_OSX_LEOPARD = 5,
|
||||
GDK_OSX_SNOW_LEOPARD = 6,
|
||||
GDK_OSX_LION = 7,
|
||||
GDK_OSX_MOUNTAIN_LION = 8,
|
||||
GDK_OSX_MAVERICKS = 9,
|
||||
GDK_OSX_YOSEMITE = 10,
|
||||
GDK_OSX_EL_CAPITAN = 11,
|
||||
GDK_OSX_SIERRA = 12,
|
||||
GDK_OSX_HIGH_SIERRA = 13,
|
||||
GDK_OSX_MOJAVE = 14,
|
||||
GDK_OSX_CURRENT = 14,
|
||||
GDK_OSX_NEW = 99
|
||||
} GdkOSXVersion;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkOSXVersion gdk_quartz_osx_version (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkAtom gdk_quartz_pasteboard_type_to_atom_libgtk_only (NSString *type);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSString *gdk_quartz_target_to_pasteboard_type_libgtk_only (const gchar *target);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSString *gdk_quartz_atom_to_pasteboard_type_libgtk_only (GdkAtom atom);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#define __GDKQUARTZ_H_INSIDE__
|
||||
|
||||
#include <gdk/quartz/gdkquartzcursor.h>
|
||||
#include <gdk/quartz/gdkquartzdevice-core.h>
|
||||
#include <gdk/quartz/gdkquartzdevicemanager-core.h>
|
||||
#include <gdk/quartz/gdkquartzdisplay.h>
|
||||
#include <gdk/quartz/gdkquartzdisplaymanager.h>
|
||||
#include <gdk/quartz/gdkquartzdnd.h>
|
||||
#include <gdk/quartz/gdkquartzkeys.h>
|
||||
#include <gdk/quartz/gdkquartzmonitor.h>
|
||||
#include <gdk/quartz/gdkquartzscreen.h>
|
||||
#include <gdk/quartz/gdkquartzutils.h>
|
||||
#include <gdk/quartz/gdkquartzsurface.h>
|
||||
|
||||
#undef __GDKQUARTZ_H_INSIDE__
|
||||
|
||||
#endif /* __GDK_QUARTZ_H__ */
|
@ -1,50 +0,0 @@
|
||||
/* gdkquartzcursor.h
|
||||
*
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
* Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_CURSOR_H__
|
||||
#define __GDK_QUARTZ_CURSOR_H__
|
||||
|
||||
#if !defined(__GDKQUARTZ_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/quartz/gdkquartz.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_QUARTZ_CURSOR (gdk_quartz_cursor_get_type ())
|
||||
#define GDK_QUARTZ_CURSOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_QUARTZ_CURSOR, GdkQuartzCursor))
|
||||
#define GDK_QUARTZ_CURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_QUARTZ_CURSOR, GdkQuartzCursorClass))
|
||||
#define GDK_IS_QUARTZ_CURSOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_QUARTZ_CURSOR))
|
||||
#define GDK_IS_QUARTZ_CURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_QUARTZ_CURSOR))
|
||||
#define GDK_QUARTZ_CURSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_QUARTZ_CURSOR, GdkQuartzCursorClass))
|
||||
|
||||
#ifdef GTK_COMPILATION
|
||||
typedef struct _GdkQuartzCursor GdkQuartzCursor;
|
||||
#else
|
||||
typedef GdkCursor GdkQuartzCursor;
|
||||
#endif
|
||||
typedef struct _GdkQuartzCursorClass GdkQuartzCursorClass;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_quartz_cursor_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_CURSOR_H__ */
|
@ -1,44 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_DEVICE_CORE_H__
|
||||
#define __GDK_QUARTZ_DEVICE_CORE_H__
|
||||
|
||||
#if !defined(__GDKQUARTZ_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/quartz/gdkquartz.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_QUARTZ_DEVICE_CORE (gdk_quartz_device_core_get_type ())
|
||||
#define GDK_QUARTZ_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_QUARTZ_DEVICE_CORE, GdkQuartzDeviceCore))
|
||||
#define GDK_QUARTZ_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_QUARTZ_DEVICE_CORE, GdkQuartzDeviceCoreClass))
|
||||
#define GDK_IS_QUARTZ_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_QUARTZ_DEVICE_CORE))
|
||||
#define GDK_IS_QUARTZ_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_QUARTZ_DEVICE_CORE))
|
||||
#define GDK_QUARTZ_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_QUARTZ_DEVICE_CORE, GdkQuartzDeviceCoreClass))
|
||||
|
||||
typedef struct _GdkQuartzDeviceCore GdkQuartzDeviceCore;
|
||||
typedef struct _GdkQuartzDeviceCoreClass GdkQuartzDeviceCoreClass;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_quartz_device_core_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_DEVICE_CORE_H__ */
|
@ -1,46 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_DEVICE_MANAGER_CORE_H__
|
||||
#define __GDK_QUARTZ_DEVICE_MANAGER_CORE_H__
|
||||
|
||||
#if !defined(__GDKQUARTZ_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/quartz/gdkquartz.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_QUARTZ_DEVICE_MANAGER_CORE (gdk_quartz_device_manager_core_get_type ())
|
||||
#define GDK_QUARTZ_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_QUARTZ_DEVICE_MANAGER_CORE, GdkQuartzDeviceManagerCore))
|
||||
#define GDK_QUARTZ_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_QUARTZ_DEVICE_MANAGER_CORE, GdkQuartzDeviceManagerCoreClass))
|
||||
#define GDK_IS_QUARTZ_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_QUARTZ_DEVICE_MANAGER_CORE))
|
||||
#define GDK_IS_QUARTZ_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_QUARTZ_DEVICE_MANAGER_CORE))
|
||||
#define GDK_QUARTZ_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_QUARTZ_DEVICE_MANAGER_CORE, GdkQuartzDeviceManagerCoreClass))
|
||||
|
||||
typedef struct _GdkQuartzDeviceManagerCore GdkQuartzDeviceManagerCore;
|
||||
typedef struct _GdkQuartzDeviceManagerCoreClass GdkQuartzDeviceManagerCoreClass;
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_quartz_device_manager_core_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_DEVICE_MANAGER_CORE_H__ */
|
@ -1,51 +0,0 @@
|
||||
/* gdkquartzdisplay.h
|
||||
*
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
* Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_DISPLAY_H__
|
||||
#define __GDK_QUARTZ_DISPLAY_H__
|
||||
|
||||
#if !defined(__GDKQUARTZ_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/quartz/gdkquartz.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_QUARTZ_DISPLAY (gdk_quartz_display_get_type ())
|
||||
#define GDK_QUARTZ_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_QUARTZ_DISPLAY, GdkQuartzDisplay))
|
||||
#define GDK_QUARTZ_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_QUARTZ_DISPLAY, GdkQuartzDisplayClass))
|
||||
#define GDK_IS_QUARTZ_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_QUARTZ_DISPLAY))
|
||||
#define GDK_IS_QUARTZ_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_QUARTZ_DISPLAY))
|
||||
#define GDK_QUARTZ_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_QUARTZ_DISPLAY, GdkQuartzDisplayClass))
|
||||
|
||||
#ifdef GTK_COMPILATION
|
||||
typedef struct _GdkQuartzDisplay GdkQuartzDisplay;
|
||||
#else
|
||||
typedef GdkDisplay GdkQuartzDisplay;
|
||||
#endif
|
||||
typedef struct _GdkQuartzDisplayClass GdkQuartzDisplayClass;
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_quartz_display_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_DISPLAY_H__ */
|
@ -1,47 +0,0 @@
|
||||
/* gdkquartzdisplaymanager.h
|
||||
*
|
||||
* Copyright (C) 2005-2007 Imendio AB
|
||||
* Copyright 2010 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_DISPLAY_MANAGER_H__
|
||||
#define __GDK_QUARTZ_DISPLAY_MANAGER_H__
|
||||
|
||||
#if !defined(__GDKQUARTZ_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/quartz/gdkquartz.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_QUARTZ_DISPLAY_MANAGER (gdk_quartz_display_manager_get_type ())
|
||||
#define GDK_QUARTZ_DISPLAY_MANAGER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_QUARTZ_DISPLAY_MANAGER, GdkQuartzDisplayManager))
|
||||
|
||||
#ifdef GTK_COMPILATION
|
||||
typedef struct _GdkQuartzDisplayManager GdkQuartzDisplayManager;
|
||||
#else
|
||||
typedef GdkDisplayManager _GdkQuartzDisplayManager;
|
||||
#endif
|
||||
typedef struct _GdkDisplayManagerClass GdkQuartzDisplayManagerClass;
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_quartz_display_manager_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_DISPLAY_MANAGER_H__ */
|
@ -1,56 +0,0 @@
|
||||
/* gdkquartzdnd.h
|
||||
*
|
||||
* Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_DND_H__
|
||||
#define __GDK_QUARTZ_DND_H__
|
||||
|
||||
#if !defined(__GDKQUARTZ_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/quartz/gdkquartz.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_QUARTZ_DRAG_CONTEXT (gdk_quartz_drag_context_get_type ())
|
||||
#define GDK_QUARTZ_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_QUARTZ_DRAG_CONTEXT, GdkQuartzDragContext))
|
||||
#define GDK_QUARTZ_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_QUARTZ_DRAG_CONTEXT, GdkQuartzDragContextClass))
|
||||
#define GDK_IS_QUARTZ_DRAG_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_QUARTZ_DRAG_CONTEXT))
|
||||
#define GDK_IS_QUARTZ_DRAG_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_QUARTZ_DRAG_CONTEXT))
|
||||
#define GDK_QUARTZ_DRAG_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_QUARTZ_DRAG_CONTEXT, GdkQuartzDragContextClass))
|
||||
|
||||
#ifdef GTK_COMPILATION
|
||||
typedef struct _GdkQuartzDragContext GdkQuartzDragContext;
|
||||
#else
|
||||
typedef GdkDragContext GdkQuartzDragContext;
|
||||
#endif
|
||||
typedef struct _GdkQuartzDragContextClass GdkQuartzDragContextClass;
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_quartz_drag_context_get_type (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
id gdk_quartz_drag_context_get_dragging_info_libgtk_only (GdkDragContext *context);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDragContext *gdk_quartz_drag_source_context_libgtk_only (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_DRAG_CONTEXT_H__ */
|
@ -1,50 +0,0 @@
|
||||
/* gdkquartzkeyd.h
|
||||
*
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
* Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_KEYS_H__
|
||||
#define __GDK_QUARTZ_KEYS_H__
|
||||
|
||||
#if !defined (__GDKQUARTZ_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/quartz/gdkquartz.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_QUARTZ_KEYMAP (gdk_quartz_keymap_get_type ())
|
||||
#define GDK_QUARTZ_KEYMAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_QUARTZ_KEYMAP, GdkQuartzKeymap))
|
||||
#define GDK_QUARTZ_KEYMAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_QUARTZ_KEYMAP, GdkQuartzKeymapClass))
|
||||
#define GDK_IS_QUARTZ_KEYMAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_QUARTZ_KEYMAP))
|
||||
#define GDK_IS_QUARTZ_KEYMAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_QUARTZ_KEYMAP))
|
||||
#define GDK_QUARTZ_KEYMAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_QUARTZ_KEYMAP, GdkQuartzKeymapClass))
|
||||
|
||||
#ifdef GTK_COMPILATION
|
||||
typedef struct _GdkQuartzKeymap GdkQuartzKeymap;
|
||||
#else
|
||||
typedef GdkKeymap GdkQuartzKeymap;
|
||||
#endif
|
||||
typedef struct _GdkQuartzKeymapClass GdkQuartzKeymapClass;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_quartz_keymap_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_KEYS_H__ */
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* gdkquartzmonitor.h
|
||||
*
|
||||
* Copyright 2017 Tom Schoonjans
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_MONITOR_H__
|
||||
#define __GDK_QUARTZ_MONITOR_H__
|
||||
|
||||
#if !defined (__GDKQUARTZ_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/quartz/gdkquartz.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdkmonitor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_QUARTZ_MONITOR (gdk_quartz_monitor_get_type ())
|
||||
#define GDK_QUARTZ_MONITOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_QUARTZ_MONITOR, GdkQuartzMonitor))
|
||||
#define GDK_IS_QUARTZ_MONITOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_QUARTZ_MONITOR))
|
||||
|
||||
typedef struct _GdkQuartzMonitor GdkQuartzMonitor;
|
||||
typedef struct _GdkQuartzMonitorClass GdkQuartzMonitorClass;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_quartz_monitor_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_MONITOR_H__ */
|
||||
|
@ -1,46 +0,0 @@
|
||||
/* gdkquartzscreen.h
|
||||
*
|
||||
* Copyright (C) 2009, 2010 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_SCREEN_H__
|
||||
#define __GDK_QUARTZ_SCREEN_H__
|
||||
|
||||
#if !defined(__GDKQUARTZ_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/quartz/gdkquartz.h> can be included directly."
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#define GDK_TYPE_QUARTZ_SCREEN (gdk_quartz_screen_get_type ())
|
||||
#define GDK_QUARTZ_SCREEN(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_QUARTZ_SCREEN, GdkQuartzScreen))
|
||||
#define GDK_QUARTZ_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_QUARTZ_SCREEN, GdkQuartzScreenClass))
|
||||
#define GDK_IS_QUARTZ_SCREEN(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_QUARTZ_SCREEN))
|
||||
#define GDK_IS_QUARTZ_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_QUARTZ_SCREEN))
|
||||
#define GDK_QUARTZ_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_QUARTZ_SCREEN, GdkQuartzScreenClass))
|
||||
|
||||
typedef struct _GdkQuartzScreen GdkQuartzScreen;
|
||||
typedef struct _GdkQuartzScreenClass GdkQuartzScreenClass;
|
||||
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_quartz_screen_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _GDK_QUARTZ_SCREEN_H_ */
|
@ -1,55 +0,0 @@
|
||||
/* gdkquartzsurface.h
|
||||
*
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
* Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_SURFACE_H__
|
||||
#define __GDK_QUARTZ_SURFACE_H__
|
||||
|
||||
#if !defined (__GDKQUARTZ_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/quartz/gdkquartz.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_QUARTZ_SURFACE (gdk_quartz_surface_get_type ())
|
||||
#define GDK_QUARTZ_SURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_QUARTZ_SURFACE, GdkQuartzSurface))
|
||||
#define GDK_QUARTZ_SURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_QUARTZ_SURFACE, GdkQuartzSurfaceClass))
|
||||
#define GDK_IS_QUARTZ_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_QUARTZ_SURFACE))
|
||||
#define GDK_IS_QUARTZ_SURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_QUARTZ_SURFACE))
|
||||
#define GDK_QUARTZ_SURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_QUARTZ_SURFACE, GdkQuartzSurfaceClass))
|
||||
|
||||
#ifdef GTK_COMPILATION
|
||||
typedef struct _GdkQuartzSurface GdkQuartzSurface;
|
||||
#else
|
||||
typedef GdkSurface GdkQuartzSurface;
|
||||
#endif
|
||||
typedef struct _GdkQuartzSurfaceClass GdkQuartzSurfaceClass;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_quartz_surface_get_type (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSWindow *gdk_quartz_surface_get_nswindow (GdkSurface *window);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSView *gdk_quartz_surface_get_nsview (GdkSurface *window);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_SURFACE_H__ */
|
@ -1,40 +0,0 @@
|
||||
/* gdkquartzutils.h
|
||||
*
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
* Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_QUARTZ_UTILS_H__
|
||||
#define __GDK_QUARTZ_UTILS_H__
|
||||
|
||||
#if !defined (__GDKQUARTZ_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/quartz/gdkquartz.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSImage *gdk_quartz_pixbuf_to_ns_image_libgtk_only (GdkPixbuf *pixbuf);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
NSEvent *gdk_quartz_event_get_nsevent (GdkEvent *event);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gunichar gdk_quartz_get_key_equivalent (guint key);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_QUARTZ_UTILS_H__ */
|
@ -1,288 +0,0 @@
|
||||
/* gdkscreen-quartz.c
|
||||
*
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
* Copyright (C) 2009,2010 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include "gdkprivate-quartz.h"
|
||||
#include "gdkdisplay-quartz.h"
|
||||
#include "gdkmonitor-quartz.h"
|
||||
|
||||
|
||||
/* A couple of notes about this file are in order. In GDK, a
|
||||
* GdkScreen can contain multiple monitors. A GdkScreen has an
|
||||
* associated root window, in which the monitors are placed. The
|
||||
* root window "spans" all monitors. The origin is at the top-left
|
||||
* corner of the root window.
|
||||
*
|
||||
* Cocoa works differently. The system has a "screen" (NSScreen) for
|
||||
* each monitor that is connected (note the conflicting definitions
|
||||
* of screen). The screen containing the menu bar is screen 0 and the
|
||||
* bottom-left corner of this screen is the origin of the "monitor
|
||||
* coordinate space". All other screens are positioned according to this
|
||||
* origin. If the menu bar is on a secondary screen (for example on
|
||||
* a monitor hooked up to a laptop), then this screen is screen 0 and
|
||||
* other monitors will be positioned according to the "secondary screen".
|
||||
* The main screen is the monitor that shows the window that is currently
|
||||
* active (has focus), the position of the menu bar does not have influence
|
||||
* on this!
|
||||
*
|
||||
* Upon start up and changes in the layout of screens, we calculate the
|
||||
* size of the GdkScreen root window that is needed to be able to place
|
||||
* all monitors in the root window. Once that size is known, we iterate
|
||||
* over the monitors and translate their Cocoa position to a position
|
||||
* in the root window of the GdkScreen. This happens below in the
|
||||
* function gdk_quartz_screen_calculate_layout().
|
||||
*
|
||||
* A Cocoa coordinate is always relative to the origin of the monitor
|
||||
* coordinate space. Such coordinates are mapped to their respective
|
||||
* position in the GdkScreen root window (_gdk_quartz_surface_xy_to_gdk_xy)
|
||||
* and vice versa (_gdk_quartz_surface_gdk_xy_to_xy). Both functions can
|
||||
* be found in gdksurface-quartz.c. Note that Cocoa coordinates can have
|
||||
* negative values (in case a monitor is located left or below of screen 0),
|
||||
* but GDK coordinates can *not*!
|
||||
*/
|
||||
|
||||
static void gdk_quartz_screen_dispose (GObject *object);
|
||||
static void gdk_quartz_screen_finalize (GObject *object);
|
||||
static void gdk_quartz_screen_calculate_layout (GdkQuartzScreen *screen);
|
||||
|
||||
static void display_reconfiguration_callback (CGDirectDisplayID display,
|
||||
CGDisplayChangeSummaryFlags flags,
|
||||
void *userInfo);
|
||||
|
||||
static gint get_mm_from_pixels (NSScreen *screen, int pixels);
|
||||
|
||||
G_DEFINE_TYPE (GdkQuartzScreen, gdk_quartz_screen, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
gdk_quartz_screen_init (GdkQuartzScreen *screen)
|
||||
{
|
||||
NSDictionary *dd = [[[NSScreen screens] objectAtIndex:0] deviceDescription];
|
||||
NSSize size = [[dd valueForKey:NSDeviceResolution] sizeValue];
|
||||
|
||||
gdk_quartz_screen_calculate_layout (screen);
|
||||
|
||||
CGDisplayRegisterReconfigurationCallback (display_reconfiguration_callback, screen);
|
||||
|
||||
quartz_screen->emit_monitors_changed = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_screen_dispose (GObject *object)
|
||||
{
|
||||
GdkQuartzScreen *screen = GDK_QUARTZ_SCREEN (object);
|
||||
|
||||
if (screen->screen_changed_id)
|
||||
{
|
||||
g_source_remove (screen->screen_changed_id);
|
||||
screen->screen_changed_id = 0;
|
||||
}
|
||||
|
||||
CGDisplayRemoveReconfigurationCallback (display_reconfiguration_callback, screen);
|
||||
|
||||
G_OBJECT_CLASS (gdk_quartz_screen_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_screen_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (gdk_quartz_screen_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/* Protocol to build cleanly for OSX < 10.7 */
|
||||
@protocol ScaleFactor
|
||||
- (CGFloat) backingScaleFactor;
|
||||
@end
|
||||
|
||||
static void
|
||||
gdk_quartz_screen_calculate_layout (GdkQuartzScreen *screen)
|
||||
{
|
||||
NSArray *array;
|
||||
int i;
|
||||
int max_x, max_y;
|
||||
GdkDisplay *display = screen->display;
|
||||
GdkQuartzDisplay *display_quartz = GDK_QUARTZ_DISPLAY (display);
|
||||
|
||||
g_ptr_array_free (display_quartz->monitors, TRUE);
|
||||
display_quartz->monitors = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
GDK_QUARTZ_ALLOC_POOL;
|
||||
|
||||
array = [NSScreen screens];
|
||||
|
||||
screen->width = 0;
|
||||
screen->height = 0;
|
||||
screen->min_x = 0;
|
||||
screen->min_y = 0;
|
||||
max_x = max_y = 0;
|
||||
|
||||
/* We determine the minimum and maximum x and y coordinates
|
||||
* covered by the monitors. From this we can deduce the width
|
||||
* and height of the root screen.
|
||||
*/
|
||||
for (i = 0; i < [array count]; i++)
|
||||
{
|
||||
GdkQuartzMonitor *monitor = g_object_new (GDK_TYPE_QUARTZ_MONITOR,
|
||||
"display", display,
|
||||
NULL);
|
||||
g_ptr_array_add (display_quartz->monitors, monitor);
|
||||
monitor->monitor_num = i;
|
||||
|
||||
NSRect rect = [[array objectAtIndex:i] frame];
|
||||
|
||||
screen->min_x = MIN (screen->min_x, rect.origin.x);
|
||||
max_x = MAX (max_x, rect.origin.x + rect.size.width);
|
||||
|
||||
screen->min_y = MIN (screen->min_y, rect.origin.y);
|
||||
max_y = MAX (max_y, rect.origin.y + rect.size.height);
|
||||
}
|
||||
|
||||
screen->width = max_x - screen->min_x;
|
||||
screen->height = max_y - screen->min_y;
|
||||
|
||||
for (i = 0; i < [array count] ; i++)
|
||||
{
|
||||
NSScreen *nsscreen;
|
||||
NSRect rect;
|
||||
GdkMonitor *monitor;
|
||||
|
||||
monitor = GDK_MONITOR(display_quartz->monitors->pdata[i]);
|
||||
nsscreen = [array objectAtIndex:i];
|
||||
rect = [nsscreen frame];
|
||||
|
||||
monitor->geometry.x = rect.origin.x - screen->min_x;
|
||||
monitor->geometry.y
|
||||
= screen->height - (rect.origin.y + rect.size.height) + screen->min_y;
|
||||
monitor->geometry.width = rect.size.width;
|
||||
monitor->geometry.height = rect.size.height;
|
||||
if (gdk_quartz_osx_version() >= GDK_OSX_LION)
|
||||
monitor->scale_factor = [(id <ScaleFactor>) nsscreen backingScaleFactor];
|
||||
else
|
||||
monitor->scale_factor = 1;
|
||||
monitor->width_mm = get_mm_from_pixels(nsscreen, monitor->geometry.width);
|
||||
monitor->height_mm = get_mm_from_pixels(nsscreen, monitor->geometry.height);
|
||||
monitor->refresh_rate = 0; // unknown
|
||||
monitor->manufacturer = NULL; // unknown
|
||||
monitor->model = NULL; // unknown
|
||||
monitor->subpixel_layout = GDK_SUBPIXEL_LAYOUT_UNKNOWN; // unknown
|
||||
}
|
||||
|
||||
GDK_QUARTZ_RELEASE_POOL;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_quartz_screen_update_window_sizes (GdkQuartzScreen *screen)
|
||||
{
|
||||
GList *windows, *list;
|
||||
|
||||
/* The size of the root window is so that it can contain all
|
||||
* monitors attached to this machine. The monitors are laid out
|
||||
* within this root window. We calculate the size of the root window
|
||||
* and the positions of the different monitors in gdkscreen-quartz.c.
|
||||
*
|
||||
* This data is updated when the monitor configuration is changed.
|
||||
*/
|
||||
|
||||
_gdk_root->x = 0;
|
||||
_gdk_root->y = 0;
|
||||
_gdk_root->abs_x = 0;
|
||||
_gdk_root->abs_y = 0;
|
||||
|
||||
windows = get_toplevels ();
|
||||
for (list = windows; list; list = list->next)
|
||||
_gdk_quartz_surface_update_position (list->data);
|
||||
}
|
||||
|
||||
static void
|
||||
process_display_reconfiguration (GdkQuartzScreen *screen)
|
||||
{
|
||||
gdk_quartz_screen_calculate_layout (screen);
|
||||
|
||||
_gdk_quartz_screen_update_window_sizes (GDK_SCREEN (screen));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
screen_changed_idle (gpointer data)
|
||||
{
|
||||
GdkQuartzScreen *screen = data;
|
||||
|
||||
process_display_reconfiguration (data);
|
||||
|
||||
screen->screen_changed_id = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
display_reconfiguration_callback (CGDirectDisplayID display,
|
||||
CGDisplayChangeSummaryFlags flags,
|
||||
void *userInfo)
|
||||
{
|
||||
GdkQuartzScreen *screen = userInfo;
|
||||
|
||||
if (flags & kCGDisplayBeginConfigurationFlag)
|
||||
{
|
||||
/* Ignore the begin configuration signal. */
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We save information about the changes, so we can emit
|
||||
* ::monitors-changed when appropriate. This signal must be
|
||||
* emitted when the number, size of position of one of the
|
||||
* monitors changes.
|
||||
*/
|
||||
if (flags & kCGDisplayMovedFlag
|
||||
|| flags & kCGDisplayAddFlag
|
||||
|| flags & kCGDisplayRemoveFlag
|
||||
|| flags & kCGDisplayEnabledFlag
|
||||
|| flags & kCGDisplayDisabledFlag)
|
||||
screen->emit_monitors_changed = TRUE;
|
||||
|
||||
/* At this point Cocoa does not know about the new screen data
|
||||
* yet, so we delay our refresh into an idle handler.
|
||||
*/
|
||||
if (!screen->screen_changed_id)
|
||||
{
|
||||
screen->screen_changed_id = g_idle_add (screen_changed_idle, screen);
|
||||
g_source_set_name_by_id (screen->screen_changed_id, "[gtk] screen_changed_idle");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
get_mm_from_pixels (NSScreen *screen, int pixels)
|
||||
{
|
||||
const float mm_per_inch = 25.4;
|
||||
NSDictionary *dd = [[[NSScreen screens] objectAtIndex:0] deviceDescription];
|
||||
NSSize size = [[dd valueForKey:NSDeviceResolution] sizeValue];
|
||||
float dpi = size.width;
|
||||
return (pixels / dpi) * mm_per_inch;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_quartz_screen_class_init (GdkQuartzScreenClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gdk_quartz_screen_dispose;
|
||||
object_class->finalize = gdk_quartz_screen_finalize;
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/* gdkselection-quartz.c
|
||||
*
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
* Copyright (C) 1998-2002 Tor Lillqvist
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkquartz.h"
|
||||
|
||||
GdkAtom
|
||||
gdk_quartz_pasteboard_type_to_atom_libgtk_only (NSString *type)
|
||||
{
|
||||
if ([type isEqualToString:NSStringPboardType])
|
||||
return g_intern_static_string ("UTF8_STRING");
|
||||
else if ([type isEqualToString:NSTIFFPboardType])
|
||||
return g_intern_static_string ("image/tiff");
|
||||
else if ([type isEqualToString:NSColorPboardType])
|
||||
return g_intern_static_string ("application/x-color");
|
||||
else if ([type isEqualToString:NSURLPboardType])
|
||||
return g_intern_static_string ("text/uri-list");
|
||||
else
|
||||
return g_intern_string ([type UTF8String]);
|
||||
}
|
||||
|
||||
NSString *
|
||||
gdk_quartz_target_to_pasteboard_type_libgtk_only (const char *target)
|
||||
{
|
||||
if (strcmp (target, "UTF8_STRING") == 0)
|
||||
return NSStringPboardType;
|
||||
else if (strcmp (target, "image/tiff") == 0)
|
||||
return NSTIFFPboardType;
|
||||
else if (strcmp (target, "application/x-color") == 0)
|
||||
return NSColorPboardType;
|
||||
else if (strcmp (target, "text/uri-list") == 0)
|
||||
return NSURLPboardType;
|
||||
else
|
||||
return [NSString stringWithUTF8String:target];
|
||||
}
|
||||
|
||||
NSString *
|
||||
gdk_quartz_atom_to_pasteboard_type_libgtk_only (GdkAtom atom)
|
||||
{
|
||||
const char *target = (const char *)atom;
|
||||
NSString *ret = gdk_quartz_target_to_pasteboard_type_libgtk_only (target);
|
||||
|
||||
return ret;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,115 +0,0 @@
|
||||
/* gdkdrawable-quartz.h
|
||||
*
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_SURFACE_QUARTZ_H__
|
||||
#define __GDK_SURFACE_QUARTZ_H__
|
||||
|
||||
#import <gdk/quartz/GdkQuartzView.h>
|
||||
#import <gdk/quartz/GdkQuartzNSWindow.h>
|
||||
#include "gdk/gdksurfaceimpl.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Window implementation for Quartz
|
||||
*/
|
||||
|
||||
typedef struct _GdkSurfaceImplQuartz GdkSurfaceImplQuartz;
|
||||
typedef struct _GdkSurfaceImplQuartzClass GdkSurfaceImplQuartzClass;
|
||||
|
||||
#define GDK_TYPE_SURFACE_IMPL_QUARTZ (_gdk_surface_impl_quartz_get_type ())
|
||||
#define GDK_SURFACE_IMPL_QUARTZ(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_SURFACE_IMPL_QUARTZ, GdkSurfaceImplQuartz))
|
||||
#define GDK_SURFACE_IMPL_QUARTZ_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SURFACE_IMPL_QUARTZ, GdkSurfaceImplQuartzClass))
|
||||
#define GDK_IS_SURFACE_IMPL_QUARTZ(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_SURFACE_IMPL_QUARTZ))
|
||||
#define GDK_IS_SURFACE_IMPL_QUARTZ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_SURFACE_IMPL_QUARTZ))
|
||||
#define GDK_SURFACE_IMPL_QUARTZ_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SURFACE_IMPL_QUARTZ, GdkSurfaceImplQuartzClass))
|
||||
|
||||
struct _GdkSurfaceImplQuartz
|
||||
{
|
||||
GdkSurfaceImpl parent_instance;
|
||||
|
||||
GdkSurface *wrapper;
|
||||
|
||||
NSWindow *toplevel;
|
||||
NSTrackingRectTag tracking_rect;
|
||||
GdkQuartzView *view;
|
||||
|
||||
GdkSurfaceTypeHint type_hint;
|
||||
|
||||
gint in_paint_rect_count;
|
||||
|
||||
GdkSurface *transient_for;
|
||||
|
||||
/* Sorted by z-order */
|
||||
GList *sorted_children;
|
||||
|
||||
cairo_region_t *needs_display_region;
|
||||
|
||||
cairo_surface_t *cairo_surface;
|
||||
|
||||
gint shadow_top;
|
||||
|
||||
gint shadow_max;
|
||||
};
|
||||
|
||||
struct _GdkSurfaceImplQuartzClass
|
||||
{
|
||||
GdkSurfaceImplClass parent_class;
|
||||
|
||||
CGContextRef (* get_context) (GdkSurfaceImplQuartz *window,
|
||||
gboolean antialias);
|
||||
void (* release_context) (GdkSurfaceImplQuartz *window,
|
||||
CGContextRef cg_context);
|
||||
};
|
||||
|
||||
GType _gdk_surface_impl_quartz_get_type (void);
|
||||
|
||||
CGContextRef gdk_quartz_surface_get_context (GdkSurfaceImplQuartz *window,
|
||||
gboolean antialias);
|
||||
void gdk_quartz_surface_release_context (GdkSurfaceImplQuartz *window,
|
||||
CGContextRef context);
|
||||
|
||||
/* Root window implementation for Quartz
|
||||
*/
|
||||
|
||||
typedef struct _GdkRootWindowImplQuartz GdkRootWindowImplQuartz;
|
||||
typedef struct _GdkRootWindowImplQuartzClass GdkRootWindowImplQuartzClass;
|
||||
|
||||
#define GDK_TYPE_ROOT_SURFACE_IMPL_QUARTZ (_gdk_root_surface_impl_quartz_get_type ())
|
||||
#define GDK_ROOT_SURFACE_IMPL_QUARTZ(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_ROOT_SURFACE_IMPL_QUARTZ, GdkRootWindowImplQuartz))
|
||||
#define GDK_ROOT_SURFACE_IMPL_QUARTZ_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_ROOT_SURFACE_IMPL_QUARTZ, GdkRootWindowImplQuartzClass))
|
||||
#define GDK_IS_ROOT_SURFACE_IMPL_QUARTZ(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_ROOT_SURFACE_IMPL_QUARTZ))
|
||||
#define GDK_IS_ROOT_SURFACE_IMPL_QUARTZ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_ROOT_SURFACE_IMPL_QUARTZ))
|
||||
#define GDK_ROOT_SURFACE_IMPL_QUARTZ_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_ROOT_SURFACE_IMPL_QUARTZ, GdkRootWindowImplQuartzClass))
|
||||
|
||||
struct _GdkRootWindowImplQuartz
|
||||
{
|
||||
GdkSurfaceImplQuartz parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkRootWindowImplQuartzClass
|
||||
{
|
||||
GdkSurfaceImplQuartzClass parent_class;
|
||||
};
|
||||
|
||||
GType _gdk_root_surface_impl_quartz_get_type (void);
|
||||
|
||||
GList *get_toplevels (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_SURFACE_QUARTZ_H__ */
|
@ -1,244 +0,0 @@
|
||||
/* gdkutils-quartz.c
|
||||
*
|
||||
* Copyright (C) 2005 Imendio AB
|
||||
* Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include <gdkquartzutils.h>
|
||||
#include "gdkprivate-quartz.h"
|
||||
|
||||
NSImage *
|
||||
gdk_quartz_pixbuf_to_ns_image_libgtk_only (GdkPixbuf *pixbuf)
|
||||
{
|
||||
NSBitmapImageRep *bitmap_rep;
|
||||
NSImage *image;
|
||||
gboolean has_alpha;
|
||||
|
||||
has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
|
||||
|
||||
/* Create a bitmap image rep */
|
||||
bitmap_rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
||||
pixelsWide:gdk_pixbuf_get_width (pixbuf)
|
||||
pixelsHigh:gdk_pixbuf_get_height (pixbuf)
|
||||
bitsPerSample:8 samplesPerPixel:has_alpha ? 4 : 3
|
||||
hasAlpha:has_alpha isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
|
||||
bytesPerRow:0 bitsPerPixel:0];
|
||||
|
||||
{
|
||||
/* Add pixel data to bitmap rep */
|
||||
guchar *src, *dst;
|
||||
int src_stride, dst_stride;
|
||||
int x, y;
|
||||
|
||||
src_stride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
dst_stride = [bitmap_rep bytesPerRow];
|
||||
|
||||
for (y = 0; y < gdk_pixbuf_get_height (pixbuf); y++)
|
||||
{
|
||||
src = gdk_pixbuf_get_pixels (pixbuf) + y * src_stride;
|
||||
dst = [bitmap_rep bitmapData] + y * dst_stride;
|
||||
|
||||
for (x = 0; x < gdk_pixbuf_get_width (pixbuf); x++)
|
||||
{
|
||||
if (has_alpha)
|
||||
{
|
||||
guchar red, green, blue, alpha;
|
||||
|
||||
red = *src++;
|
||||
green = *src++;
|
||||
blue = *src++;
|
||||
alpha = *src++;
|
||||
|
||||
*dst++ = (red * alpha) / 255;
|
||||
*dst++ = (green * alpha) / 255;
|
||||
*dst++ = (blue * alpha) / 255;
|
||||
*dst++ = alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image = [[NSImage alloc] init];
|
||||
[image addRepresentation:bitmap_rep];
|
||||
[bitmap_rep release];
|
||||
[image autorelease];
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
NSEvent *
|
||||
gdk_quartz_event_get_nsevent (GdkEvent *event)
|
||||
{
|
||||
/* FIXME: If the event here is unallocated, we crash. */
|
||||
return ((GdkEventPrivate *) event)->windowing_data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Code for key code conversion
|
||||
*
|
||||
* Copyright (C) 2009 Paul Davis
|
||||
*/
|
||||
gunichar
|
||||
gdk_quartz_get_key_equivalent (guint key)
|
||||
{
|
||||
if (key >= GDK_KEY_A && key <= GDK_KEY_Z)
|
||||
return key + (GDK_KEY_a - GDK_KEY_A);
|
||||
|
||||
if (key >= GDK_KEY_space && key <= GDK_KEY_asciitilde)
|
||||
return key;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case GDK_KEY_BackSpace:
|
||||
return NSBackspaceCharacter;
|
||||
case GDK_KEY_Delete:
|
||||
return NSDeleteFunctionKey;
|
||||
case GDK_KEY_Pause:
|
||||
return NSPauseFunctionKey;
|
||||
case GDK_KEY_Scroll_Lock:
|
||||
return NSScrollLockFunctionKey;
|
||||
case GDK_KEY_Sys_Req:
|
||||
return NSSysReqFunctionKey;
|
||||
case GDK_KEY_Home:
|
||||
return NSHomeFunctionKey;
|
||||
case GDK_KEY_Left:
|
||||
case GDK_KEY_leftarrow:
|
||||
return NSLeftArrowFunctionKey;
|
||||
case GDK_KEY_Up:
|
||||
case GDK_KEY_uparrow:
|
||||
return NSUpArrowFunctionKey;
|
||||
case GDK_KEY_Right:
|
||||
case GDK_KEY_rightarrow:
|
||||
return NSRightArrowFunctionKey;
|
||||
case GDK_KEY_Down:
|
||||
case GDK_KEY_downarrow:
|
||||
return NSDownArrowFunctionKey;
|
||||
case GDK_KEY_Page_Up:
|
||||
return NSPageUpFunctionKey;
|
||||
case GDK_KEY_Page_Down:
|
||||
return NSPageDownFunctionKey;
|
||||
case GDK_KEY_End:
|
||||
return NSEndFunctionKey;
|
||||
case GDK_KEY_Begin:
|
||||
return NSBeginFunctionKey;
|
||||
case GDK_KEY_Select:
|
||||
return NSSelectFunctionKey;
|
||||
case GDK_KEY_Print:
|
||||
return NSPrintFunctionKey;
|
||||
case GDK_KEY_Execute:
|
||||
return NSExecuteFunctionKey;
|
||||
case GDK_KEY_Insert:
|
||||
return NSInsertFunctionKey;
|
||||
case GDK_KEY_Undo:
|
||||
return NSUndoFunctionKey;
|
||||
case GDK_KEY_Redo:
|
||||
return NSRedoFunctionKey;
|
||||
case GDK_KEY_Menu:
|
||||
return NSMenuFunctionKey;
|
||||
case GDK_KEY_Find:
|
||||
return NSFindFunctionKey;
|
||||
case GDK_KEY_Help:
|
||||
return NSHelpFunctionKey;
|
||||
case GDK_KEY_Break:
|
||||
return NSBreakFunctionKey;
|
||||
case GDK_KEY_Mode_switch:
|
||||
return NSModeSwitchFunctionKey;
|
||||
case GDK_KEY_F1:
|
||||
return NSF1FunctionKey;
|
||||
case GDK_KEY_F2:
|
||||
return NSF2FunctionKey;
|
||||
case GDK_KEY_F3:
|
||||
return NSF3FunctionKey;
|
||||
case GDK_KEY_F4:
|
||||
return NSF4FunctionKey;
|
||||
case GDK_KEY_F5:
|
||||
return NSF5FunctionKey;
|
||||
case GDK_KEY_F6:
|
||||
return NSF6FunctionKey;
|
||||
case GDK_KEY_F7:
|
||||
return NSF7FunctionKey;
|
||||
case GDK_KEY_F8:
|
||||
return NSF8FunctionKey;
|
||||
case GDK_KEY_F9:
|
||||
return NSF9FunctionKey;
|
||||
case GDK_KEY_F10:
|
||||
return NSF10FunctionKey;
|
||||
case GDK_KEY_F11:
|
||||
return NSF11FunctionKey;
|
||||
case GDK_KEY_F12:
|
||||
return NSF12FunctionKey;
|
||||
case GDK_KEY_F13:
|
||||
return NSF13FunctionKey;
|
||||
case GDK_KEY_F14:
|
||||
return NSF14FunctionKey;
|
||||
case GDK_KEY_F15:
|
||||
return NSF15FunctionKey;
|
||||
case GDK_KEY_F16:
|
||||
return NSF16FunctionKey;
|
||||
case GDK_KEY_F17:
|
||||
return NSF17FunctionKey;
|
||||
case GDK_KEY_F18:
|
||||
return NSF18FunctionKey;
|
||||
case GDK_KEY_F19:
|
||||
return NSF19FunctionKey;
|
||||
case GDK_KEY_F20:
|
||||
return NSF20FunctionKey;
|
||||
case GDK_KEY_F21:
|
||||
return NSF21FunctionKey;
|
||||
case GDK_KEY_F22:
|
||||
return NSF22FunctionKey;
|
||||
case GDK_KEY_F23:
|
||||
return NSF23FunctionKey;
|
||||
case GDK_KEY_F24:
|
||||
return NSF24FunctionKey;
|
||||
case GDK_KEY_F25:
|
||||
return NSF25FunctionKey;
|
||||
case GDK_KEY_F26:
|
||||
return NSF26FunctionKey;
|
||||
case GDK_KEY_F27:
|
||||
return NSF27FunctionKey;
|
||||
case GDK_KEY_F28:
|
||||
return NSF28FunctionKey;
|
||||
case GDK_KEY_F29:
|
||||
return NSF29FunctionKey;
|
||||
case GDK_KEY_F30:
|
||||
return NSF30FunctionKey;
|
||||
case GDK_KEY_F31:
|
||||
return NSF31FunctionKey;
|
||||
case GDK_KEY_F32:
|
||||
return NSF32FunctionKey;
|
||||
case GDK_KEY_F33:
|
||||
return NSF33FunctionKey;
|
||||
case GDK_KEY_F34:
|
||||
return NSF34FunctionKey;
|
||||
case GDK_KEY_F35:
|
||||
return NSF35FunctionKey;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return '\0';
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
# FIXME: do we need to do an add_language() for objective-c here?
|
||||
gdk_quartz_sources = files([
|
||||
'GdkQuartzView.c',
|
||||
'GdkQuartzNSWindow.c',
|
||||
'gdkcairocontext-quartz.c',
|
||||
'gdkcursor-quartz.c',
|
||||
'gdkdevice-core-quartz.c',
|
||||
'gdkdevicemanager-core-quartz.c',
|
||||
'gdkdisplay-quartz.c',
|
||||
'gdkdisplaymanager-quartz.c',
|
||||
'gdkdnd-quartz.c',
|
||||
'gdkevents-quartz.c',
|
||||
'gdkeventloop-quartz.c',
|
||||
'gdkglcontext-quartz.c',
|
||||
'gdkglobals-quartz.c',
|
||||
'gdkkeys-quartz.c',
|
||||
'gdkscreen-quartz.c',
|
||||
'gdkselection-quartz.c',
|
||||
'gdkutils-quartz.c',
|
||||
'gdksurface-quartz.c',
|
||||
])
|
||||
|
||||
gdk_quartz_public_headers = files([
|
||||
'gdkquartzcursor.h',
|
||||
'gdkquartzdevice-core.h',
|
||||
'gdkquartzdevicemanager-core.h',
|
||||
'gdkquartzdisplay.h',
|
||||
'gdkquartzdisplaymanager.h',
|
||||
'gdkquartzdnd.h',
|
||||
'gdkquartzkeys.h',
|
||||
'gdkquartzscreen.h',
|
||||
'gdkquartzutils.h',
|
||||
'gdkquartzsurface.h',
|
||||
])
|
||||
|
||||
install_headers(gdk_quartz_public_headers, 'gdkquartz.h', subdir: 'gtk-4.0/gdk/quartz/')
|
||||
|
||||
gdk_quartz_deps = [ # FIXME
|
||||
]
|
||||
|
||||
libgdk_quartz = static_library('gdk-quartz',
|
||||
gdk_quartz_sources, gdkconfig, gdkenum_h,
|
||||
include_directories: [confinc, gdkinc],
|
||||
c_args: ['-DGTK_COMPILATION', '-DG_LOG_DOMAIN="Gdk"', '-xobjective-c'],
|
||||
dependencies: [gdk_deps, gdk_quartz_deps])
|
@ -1,156 +0,0 @@
|
||||
static const struct { gint width, height; gint hotx, hoty; const guchar *bits; } xcursors[] = {
|
||||
{ 14, 14, 6, 6, (guchar *) "\x07\xb8\x0f\x3c\x1f\x3e\x3e\x1f\xfc\x0f\xf8\x07\xf0\x03\xf0\x03\xf8\x07\xfc\x0f\x3e\x1f\x1f\x3e\x0f\x3c\x07\x38" },
|
||||
{ 16, 16, 7, 7, (guchar *) "\x0f\xf0\x1f\xf8\x3f\xfc\x7f\xfe\xfe\x7f\xfc\x3f\xf8\x1f\xf0\x0f\xf0\x0f\xf8\x1f\xfc\x3f\xfe\x7f\x7f\xfe\x3f\xfc\x1f\xf8\x0f\xf0" },
|
||||
{ 14, 14, 13, 0, (guchar *) "\x00\xb0\x00\x3c\x00\x1f\xc0\x1f\xf0\x0f\xfc\x0f\xc0\x07\xe0\x07\x70\x03\x38\x03\x1c\x01\x0e\x01\x07\x00\x02\x00" },
|
||||
{ 16, 16, 14, 1, (guchar *) "\x00\xe0\x00\xf8\x00\xfe\x80\x7f\xe0\x7f\xf8\x3f\xfc\x3f\xfc\x1f\xe0\x1f\xf0\x0f\xf8\x0f\x7c\x07\x3e\x07\x1f\x02\x0e\x00\x04\x00" },
|
||||
{ 8, 10, 3, 9, (guchar *) "\xff\x00\xff\x18\x18\x18\x18\x5a\x3c\x18" },
|
||||
{ 10, 12, 4, 10, (guchar *) "\xff\x23\xff\x03\xff\x03\xff\x03\xff\x03\x78\x00\x78\x00\xfe\x01\xfe\x01\xfe\x01\xfc\x00\x78\x00" },
|
||||
{ 8, 10, 3, 9, (guchar *) "\x18\x3c\x5a\x18\x18\x18\x18\xff\x00\xff" },
|
||||
{ 10, 12, 4, 10, (guchar *) "\x30\x20\x78\x00\xfe\x01\xfe\x01\xfe\x01\x78\x00\x78\x00\xff\x03\xff\x03\xff\x03\xff\x03\xff\x03" },
|
||||
{ 16, 8, 14, 3, (guchar *) "\x80\x00\xe0\x03\x11\x06\xff\xff\x00\x18\x00\x04\x00\x02\xff\x03" },
|
||||
{ 16, 9, 14, 4, (guchar *) "\xe0\x00\xf0\x03\xf9\x07\xff\xff\xff\xff\xff\xff\xff\x1f\xff\x07\xff\x03" },
|
||||
{ 13, 14, 6, 6, (guchar *) "\x47\x9c\x44\x04\x44\x04\x44\x04\xff\x1f\x45\x14\x45\x14\x45\x14\x45\x14\xff\x1f\x44\x04\x44\x04\x44\x04\x47\x1c" },
|
||||
{ 15, 16, 7, 7, (guchar *) "\xdf\x7d\xdf\x7d\xdf\x7d\xdc\x1d\xff\x7f\xff\x7f\xff\x7f\xdf\x7d\xdf\x7d\xff\x7f\xff\x7f\xff\x7f\xdc\x1d\xdf\x7d\xdf\x7d\xdf\x7d" },
|
||||
{ 14, 14, 0, 13, (guchar *) "\x03\x80\x03\x00\x23\x08\x23\x04\x23\x02\x23\x01\xa3\x00\x63\x00\xe3\x0f\x03\x00\x03\x00\x03\x00\xff\x3f\xff\x3f" },
|
||||
{ 16, 16, 1, 14, (guchar *) "\x0f\x00\x0f\x00\xef\x30\xef\x38\xef\x1c\xef\x0e\xef\x07\xef\x03\xef\x3f\xef\x3f\xef\x3f\x0f\x00\xff\xff\xff\xff\xff\xff\xff\xff" },
|
||||
{ 14, 14, 13, 13, (guchar *) "\x00\xb0\x00\x30\x04\x31\x08\x31\x10\x31\x20\x31\x40\x31\x80\x31\xfc\x31\x00\x30\x00\x30\x00\x30\xff\x3f\xff\x3f" },
|
||||
{ 16, 16, 14, 14, (guchar *) "\x00\xf0\x00\xf0\x0c\xf7\x1c\xf7\x38\xf7\x70\xf7\xe0\xf7\xc0\xf7\xfc\xf7\xfc\xf7\xfc\xf7\x00\xf0\xff\xff\xff\xff\xff\xff\xff\xff" },
|
||||
{ 13, 14, 6, 13, (guchar *) "\x40\x80\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x44\x04\x48\x02\x50\x01\xe0\x00\x40\x00\x00\x00\xff\x1f\xff\x1f" },
|
||||
{ 15, 16, 7, 14, (guchar *) "\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xcc\x19\xdc\x1d\xf8\x0f\xf0\x07\xe0\x03\xc0\x01\xff\x7f\xff\x7f\xff\x7f\xff\x7f" },
|
||||
{ 14, 10, 7, 9, (guchar *) "\xc0\x80\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xff\x3f\xff\x3f" },
|
||||
{ 16, 12, 8, 10, (guchar *) "\xc0\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x03\xff\xff\xff\xff\xff\xff\xff\xff" },
|
||||
{ 15, 16, 8, 8, (guchar *) "\xff\xff\x01\x00\xfd\x7f\x05\x40\xf5\x5f\x15\x50\xd5\x57\x55\x54\x55\x55\xd5\x55\x15\x54\xf5\x57\x05\x50\xfd\x5f\x01\x40\xff\x7f" },
|
||||
{ 16, 16, 8, 8, (guchar *) "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" },
|
||||
{ 10, 14, 4, 0, (guchar *) "\x30\x90\x30\x00\x78\x00\x78\x00\xfc\x00\xfc\x00\xfe\x01\xfe\x01\x33\x03\x31\x02\x30\x00\x30\x00\x30\x00\x30\x00" },
|
||||
{ 12, 16, 5, 1, (guchar *) "\xf0\x20\xf0\x00\xf8\x01\xf8\x01\xfc\x03\xfc\x03\xfe\x07\xfe\x07\xff\x0f\xff\x0f\xff\x0f\xf7\x0e\xf0\x00\xf0\x00\xf0\x00\xf0\x00" },
|
||||
{ 14, 14, 7, 7, (guchar *) "\xe0\x81\xf8\x07\xfc\x0f\x1e\x1e\x0e\x1c\x07\x38\x07\x38\x07\x38\x07\x38\x0e\x1c\x1e\x1e\xfc\x0f\xf8\x07\xe0\x01" },
|
||||
{ 16, 16, 8, 8, (guchar *) "\xe0\x07\xf8\x1f\xfc\x3f\xfe\x7f\xfe\x7f\x3f\xfc\x1f\xf8\x1f\xf8\x1f\xf8\x1f\xf8\x3f\xfc\xfe\x7f\xfe\x7f\xfc\x3f\xf8\x1f\xe0\x07" },
|
||||
{ 14, 16, 6, 3, (guchar *) "\xfc\x8f\xe6\x19\x13\x33\xc9\x24\x79\x24\x11\x22\xe3\x31\xfe\x1f\xca\x14\xca\x14\xca\x14\xea\x15\xcb\x34\x0f\x3c\xff\x3f\xff\x3f" },
|
||||
{ 15, 16, 6, 3, (guchar *) "\xfe\x1f\xf7\x39\xdb\x77\xed\x6d\xfd\x6f\xf9\x66\xf3\x73\xff\x3f\xeb\x35\xeb\x35\xeb\x35\xfb\x37\xeb\x75\xcf\x7c\xff\x7f\xff\x7f" },
|
||||
{ 15, 16, 7, 9, (guchar *) "\xf8\x8f\x04\x10\x06\x60\x0a\x58\xf2\x47\x03\x40\x03\x40\x02\x40\x02\x40\x9a\x58\x56\x55\xd7\x55\x5b\x59\x02\x40\x02\x40\xfc\x3f" },
|
||||
{ 16, 16, 7, 9, (guchar *) "\xf8\x0f\xfc\x1f\xfe\xff\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xfc\x3f" },
|
||||
{ 16, 15, 7, 7, (guchar *) "\x40\x01\x40\x01\x40\x01\x40\x01\x40\x01\x40\x01\x7f\xff\x00\x00\x7f\xff\x40\x01\x40\x01\x40\x01\x40\x01\x40\x01\x40\x01" },
|
||||
{ 16, 16, 7, 7, (guchar *) "\xe0\x03\xe0\x03\xe0\x03\xe0\x03\xe0\x03\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\x03\xe0\x03\xe0\x03\xe0\x03\xe0\x03\xe0\x03" },
|
||||
{ 16, 15, 7, 7, (guchar *) "\x42\x21\x45\x51\x4a\x29\x54\x15\x68\x0b\x50\x05\xbf\xfe\x40\x01\xbf\xfe\x50\x05\x68\x0b\x54\x15\x4a\x29\x45\x51\x42\x21" },
|
||||
{ 16, 15, 7, 7, (guchar *) "\x66\x33\x6d\xdb\x7b\x6f\x76\x37\x6c\x1b\x5f\xfd\x3f\xfe\x80\x00\x3f\xfe\x5f\xfd\x6c\x1b\x76\x37\x7b\x6f\x6d\xdb\x66\x33" },
|
||||
{ 16, 15, 7, 7, (guchar *) "\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x7f\xff\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00" },
|
||||
{ 16, 16, 7, 7, (guchar *) "\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xff\xff\xff\xff\xff\xff\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01" },
|
||||
{ 15, 15, 7, 7, (guchar *) "\x40\x81\x60\x03\x50\x05\x48\x09\x44\x11\x42\x21\x7f\x7f\x00\x00\x7f\x7f\x42\x21\x44\x11\x48\x09\x50\x05\x60\x03\x40\x01" },
|
||||
{ 16, 16, 7, 7, (guchar *) "\xe0\x03\xf0\x07\xf8\x0f\xdc\x1d\xce\x39\xc7\x71\xff\xff\x7f\xff\xff\xff\xc7\x71\xce\x39\xdc\x1d\xf8\x0f\xf0\x07\xe0\x03\xc0\x01" },
|
||||
{ 10, 10, 5, 5, (guchar *) "\x78\x90\xfe\x01\xfe\x01\xff\x03\xff\x03\xff\x03\xff\x03\xfe\x01\xfe\x01\x78\x00" },
|
||||
{ 12, 12, 6, 6, (guchar *) "\xf8\x21\xfe\x07\xfe\x07\xff\x0f\xff\x0f\xff\x0f\xff\x0f\xff\x0f\xff\x0f\xfe\x07\xfe\x07\xf8\x01" },
|
||||
{ 12, 12, 6, 5, (guchar *) "\xff\x9f\x01\x08\x01\x08\x01\x08\x01\x08\x61\x08\x61\x08\x01\x08\x01\x08\x01\x08\x01\x08\xff\x0f" },
|
||||
{ 14, 14, 7, 6, (guchar *) "\xff\x3f\xff\x3f\xff\x3f\x07\x38\x07\x38\xe7\x39\xe7\x39\xe7\x39\xe7\x39\x07\x38\x07\x38\xff\x3f\xff\x3f\xff\x3f" },
|
||||
{ 10, 14, 5, 7, (guchar *) "\x30\x90\x78\x00\xfc\x00\xb6\x01\x33\x03\x30\x00\x30\x00\x30\x00\x30\x00\x33\x03\xb6\x01\xfc\x00\x78\x00\x30\x00" },
|
||||
{ 12, 16, 6, 8, (guchar *) "\xf0\x20\xf8\x01\xfc\x03\xfe\x07\xff\x0f\xff\x0f\xff\x0f\xf0\x00\xf0\x00\xff\x0f\xff\x0f\xff\x0f\xfe\x07\xfc\x03\xf8\x01\xf0\x00" },
|
||||
{ 15, 15, 14, 0, (guchar *) "\x00\xc0\x00\x30\x00\x3c\x00\x1f\xc0\x1f\xf0\x0f\xfc\x0f\x80\x07\x40\x07\x20\x03\x10\x03\x08\x01\x04\x01\x02\x00\x01\x00" },
|
||||
{ 15, 16, 14, 0, (guchar *) "\x00\x60\x00\x78\x00\x7e\x80\x3f\xe0\x1f\xf8\x1f\xfe\x0f\xfe\x0f\xe0\x07\xf0\x07\xb8\x03\x9c\x03\x8e\x01\x87\x01\x03\x00\x01\x00" },
|
||||
{ 15, 15, 14, 0, (guchar *) "\x00\x40\x00\x30\x00\x3c\x00\x1f\xc0\x1f\x00\x0e\x00\x0d\x80\x04\x40\x04\x20\x00\x10\x00\x08\x00\x04\x00\x02\x00\x01\x00" },
|
||||
{ 15, 15, 14, 0, (guchar *) "\x00\x60\x00\x78\x00\x3e\x80\x3f\xe0\x1f\xe0\x1f\x80\x0f\xc0\x0f\xe0\x06\x70\x02\x38\x00\x1c\x00\x0e\x00\x07\x00\x03\x00" },
|
||||
{ 12, 12, 6, 5, (guchar *) "\xff\x1f\x91\x08\x99\x09\x0d\x0b\x07\x0e\x61\x08\x61\x08\x07\x0e\x0d\x0b\x99\x09\x91\x08\xff\x0f" },
|
||||
{ 14, 14, 7, 6, (guchar *) "\xff\x3f\xff\x3f\xf3\x33\xfb\x37\x3f\x3f\xdf\x3e\xef\x3d\xef\x3d\xdf\x3e\x3f\x3f\xfb\x37\xf3\x33\xff\x3f\xff\x3f" },
|
||||
{ 14, 14, 6, 6, (guchar *) "\xf1\x03\xfb\x07\x1f\x0c\x09\x08\x19\x00\x3f\x00\x00\x00\x00\x00\x00\x3f\x00\x26\x04\x24\x0c\x3e\xf8\x37\xf0\x23" },
|
||||
{ 16, 16, 7, 7, (guchar *) "\xe3\x07\xf7\x0f\xff\x1f\xff\x3f\x3f\x38\xff\x30\xff\x00\xff\x00\x00\xff\x00\xff\x0c\xfe\x1c\xfc\xfc\xff\xf8\xff\xf0\xef\xe0\xc7" },
|
||||
{ 14, 14, 7, 7, (guchar *) "\xc0\x00\xe0\x01\xf0\x03\xc0\x00\xc4\x08\xc6\x18\xff\x3f\xff\x3f\xc6\x18\xc4\x08\xc0\x00\xf0\x03\xe0\x01\xc0\x00" },
|
||||
{ 16, 16, 8, 8, (guchar *) "\xc0\x03\xc0\x07\xe0\x07\xf0\x0f\xe8\x17\xdc\x3b\xff\xff\xff\xff\xff\xff\xff\xff\xdc\x3b\xe8\x17\xf0\x0f\xe0\x07\xc0\x03\xc0\x03" },
|
||||
{ 16, 15, 14, 2, (guchar *) "\x00\x1e\x00\x0e\x01\xcc\xf9\x0d\xff\x0f\x7f\x0c\x3f\x0c\x06\x1c\x00\x0f\xf8\x07\x10\x00\x10\x00\x10\x00\x10\x00\x78\x00" },
|
||||
{ 16, 16, 14, 3, (guchar *) "\x00\x3f\x00\x3f\x03\xff\xff\xff\xff\xff\xff\x3f\xff\x3f\xff\x3f\xff\x3f\xff\x3f\xfe\x1f\xf8\x0f\x38\x00\x38\x00\xfc\x00\xfc\x00" },
|
||||
{ 16, 16, 2, 0, (guchar *) "\xfc\x00\x08\x01\x13\x02\x57\x05\x13\x04\xd3\x05\x1f\x3c\x1c\xfc\x10\xe4\x10\xe4\x90\xf4\x90\xe4\x90\x04\x88\x08\x84\x10\x7c\x1f" },
|
||||
{ 16, 16, 2, 0, (guchar *) "\xfc\x00\xfb\x01\xf7\x03\xff\x07\xf7\x07\xf7\x3f\xff\x7f\xff\xff\xfc\xf7\xf0\xf7\xf0\xff\xf0\xf7\xf0\xe7\xf8\x0f\xfc\x1f\x7c\x1f" },
|
||||
{ 13, 16, 12, 0, (guchar *) "\x00\x18\x00\x1e\x80\x07\xc0\x03\xe0\x01\xf0\x03\xf8\x07\xfa\x03\xff\x07\xfd\x07\xf0\x03\xf0\x01\x29\x00\x23\x00\x16\x00\x0c\x00" },
|
||||
{ 13, 16, 12, 0, (guchar *) "\x00\xdc\x00\x1f\xc0\x0f\xe0\x07\xf0\x03\xf8\x07\xfe\x0f\xff\x0f\xff\x0f\xff\x0f\xff\x07\xff\x03\xff\x01\x7f\x00\x3f\x00\x1e\x00" },
|
||||
{ 15, 14, 0, 0, (guchar *) "\xfe\x01\x01\x02\x7e\x04\x08\x08\x70\x08\x08\x08\x70\x14\x08\x22\x30\x41\xc0\x20\x40\x12\x80\x08\x00\x05\x00\x02" },
|
||||
{ 16, 16, 0, 1, (guchar *) "\xfe\x01\xff\x03\xff\x07\xff\x0f\xfe\x1f\xf8\x1f\xfc\x1f\xf8\x3f\xfc\x7f\xf8\xff\xf0\x7f\xe0\x3f\xc0\x1f\x80\x0f\x00\x07\x00\x02" },
|
||||
{ 15, 14, 6, 8, (guchar *) "\x7c\x1f\xc6\x31\x83\x60\x01\x40\x01\x40\x01\x40\x01\x40\x03\x60\x06\x30\x0c\x18\x18\x0c\x30\x06\x60\x03\xc0\x01" },
|
||||
{ 15, 14, 6, 8, (guchar *) "\x7c\x9f\xfe\x3f\xc7\x71\x83\x60\x03\x60\x03\x60\x43\x61\x87\x70\x0e\x38\x1c\x1c\x38\x0e\xf0\x07\xe0\x03\xc0\x01" },
|
||||
{ 16, 16, 8, 8, (guchar *) "\xff\xff\xab\xaa\x55\xd5\xab\xaa\x05\xd0\x0b\xa0\x05\xd0\x0b\xa0\x05\xd0\x0b\xa0\x05\xd0\x0b\xa0\x55\xd5\xab\xaa\x55\xd5\xff\xff" },
|
||||
{ 16, 16, 8, 8, (guchar *) "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" },
|
||||
{ 14, 14, 7, 6, (guchar *) "\xfe\x1f\xfc\x0f\xf9\x27\xf3\x33\xe7\x39\xcf\x3c\xff\x3f\xff\x3f\xcf\x3c\xe7\x39\xf3\x33\xf9\x27\xfc\x0f\xfe\x1f" },
|
||||
{ 16, 16, 8, 7, (guchar *) "\xfc\x3f\xfe\x7f\xfe\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x7f\xfe\x7f\xfc\x3f" },
|
||||
{ 8, 14, 0, 0, (guchar *) "\x01\x03\x07\x0f\x1f\x3f\x7f\xff\x1f\x1b\x31\x30\x60\x60" },
|
||||
{ 10, 16, 1, 1, (guchar *) "\x03\xc0\x07\x00\x0f\x00\x1f\x00\x3f\x00\x7f\x00\xff\x00\xff\x01\xff\x03\xff\x03\x7f\x00\xf7\x00\xf3\x00\xe0\x01\xe0\x01\xc0\x00" },
|
||||
{ 14, 13, 0, 6, (guchar *) "\x03\x00\x03\x00\x83\x00\x43\x00\x23\x00\x13\x00\xfb\x3f\x13\x00\x23\x00\x43\x00\x83\x00\x03\x00\x03\x00" },
|
||||
{ 16, 15, 1, 7, (guchar *) "\x0f\x00\x0f\x00\x0f\x03\x8f\x03\xcf\x01\xef\x00\xff\xff\xff\xff\xff\xff\xef\x00\xcf\x01\x8f\x03\x0f\x03\x0f\x00\x0f\x00" },
|
||||
{ 10, 14, 0, 7, (guchar *) "\x03\x10\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\xff\x03\xff\x03\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00" },
|
||||
{ 12, 16, 1, 8, (guchar *) "\x0f\xc0\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\xff\x0f\xff\x0f\xff\x0f\xff\x0f\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00" },
|
||||
{ 16, 16, 8, 8, (guchar *) "\x01\xc0\xfe\xbf\xfe\xbf\x22\xa2\xa2\xaa\xa2\xaa\xa2\xaa\xa2\xaa\x22\xa2\xfe\xbf\xfe\xbf\xfe\xbf\xfe\xbf\xfe\xbf\xfe\xbf\x01\xc0" },
|
||||
{ 15, 16, 8, 8, (guchar *) "\xfe\xbf\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xfe\x3f" },
|
||||
{ 10, 10, 0, 9, (guchar *) "\x03\x10\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\xff\x03\xff\x03" },
|
||||
{ 12, 12, 1, 10, (guchar *) "\x0f\xc0\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\xff\x0f\xff\x0f\xff\x0f\xff\x0f" },
|
||||
{ 10, 10, 9, 9, (guchar *) "\x00\x13\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\xff\x03\xff\x03" },
|
||||
{ 12, 12, 10, 10, (guchar *) "\x00\xcf\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\xff\x0f\xff\x0f\xff\x0f\xff\x0f" },
|
||||
{ 16, 16, 14, 5, (guchar *) "\xc0\x01\x78\x0f\x40\x01\x81\x00\xc2\xe1\x24\xd2\xb8\x0e\xa0\x02\x20\x02\x40\x01\x20\x02\x90\x04\x48\x09\x28\x0a\x1e\x3c\x1f\xfc" },
|
||||
{ 16, 16, 14, 5, (guchar *) "\xf8\x07\xfc\x0f\xfc\x1f\xc3\x41\xe7\xe3\xfe\xff\xfc\xdf\xf8\x0f\xe0\x07\xe0\x03\xf0\x07\xf8\x0f\xfc\x1f\x7e\x3f\x3f\xfe\x3f\xfe" },
|
||||
{ 16, 16, 8, 8, (guchar *) "\x01\xc0\xfe\xbf\xfe\xbf\x22\xa2\x2a\xaa\x2a\xaa\x2a\xaa\x2a\xaa\x22\xa2\xfe\xbf\xfe\xbf\xfe\xbf\xfe\xbf\xfe\xbf\xfe\xbf\x01\xc0" },
|
||||
{ 15, 16, 8, 8, (guchar *) "\xfe\xbf\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xfe\x3f" },
|
||||
{ 15, 14, 4, 1, (guchar *) "\xe0\x00\x30\x00\x60\x00\xc0\x00\xfe\x1f\x01\x20\xcd\x6c\xcd\x6c\xcd\x6c\x01\x60\x01\x60\x06\x38\x18\x06\xe0\x01" },
|
||||
{ 16, 16, 4, 1, (guchar *) "\xf0\x01\x78\x00\xf0\x00\xe0\x00\xfe\x1f\xff\x3f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfc\xef\xf8\x07\xf0\x03\xe0\x01" },
|
||||
{ 11, 16, 10, 15, (guchar *) "\x0e\x10\x11\x00\x31\x00\x52\x00\x5e\x00\x84\x00\x88\x00\x08\x01\x10\x01\x30\x02\x20\x02\x40\x04\x80\x07\x00\x07\x00\x06\x00\x04" },
|
||||
{ 13, 16, 11, 15, (guchar *) "\x3f\xc0\x7f\x00\xff\x00\xfe\x00\xfc\x01\xfc\x01\xf8\x03\xf0\x03\xf0\x07\xe0\x07\xe0\x0f\xc0\x1f\x80\x1f\x00\x1f\x00\x1e\x00\x1c" },
|
||||
{ 15, 16, 7, 12, (guchar *) "\xe0\x01\xf0\x03\xf8\x07\xcc\x0c\xcc\x0c\xf8\x07\xf0\x03\xe0\x01\xe1\x21\xe1\x61\xc2\x10\x1c\x0e\xe0\x01\xf8\x47\x0f\x7c\x01\x20" },
|
||||
{ 16, 16, 7, 12, (guchar *) "\xf0\x03\xf8\x07\xfc\x0f\xfe\x1f\xfe\x1f\xfc\x0f\xf8\x07\xf1\x83\xf1\xe3\xf3\xf3\xef\x39\x1e\x1e\xe0\x01\xfe\xc7\xff\xff\x0f\x7c" },
|
||||
{ 10, 10, 4, 5, (guchar *) "\x30\x10\x30\x00\x30\x00\x30\x00\xff\x03\xff\x03\x30\x00\x30\x00\x30\x00\x30\x00" },
|
||||
{ 12, 12, 5, 6, (guchar *) "\xf0\xc0\xf0\x00\xf0\x00\xf0\x00\xff\x0f\xff\x0f\xff\x0f\xff\x0f\xf0\x00\xf0\x00\xf0\x00\xf0\x00" },
|
||||
{ 9, 15, 4, 7, (guchar *) "\x7c\x10\xfe\x00\xc7\x01\x83\x01\x87\x01\xc6\x01\xe0\x00\x78\x00\x38\x00\x28\x00\x28\x00\xee\x00\x6c\x00\x38\x00\x10\x00" },
|
||||
{ 11, 16, 5, 8, (guchar *) "\xf8\xc0\xfc\x01\xfe\x03\xff\x07\x8f\x07\x9f\x07\xde\x07\xfc\x03\xf8\x01\xf8\x00\xf8\x00\xfc\x01\xfe\x03\xfc\x01\xf8\x00\x70\x00" },
|
||||
{ 8, 14, 7, 0, (guchar *) "\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff\xf8\xd8\x8c\x0c\x06\x06" },
|
||||
{ 10, 16, 8, 1, (guchar *) "\x00\xc3\x80\x03\xc0\x03\xe0\x03\xf0\x03\xf8\x03\xfc\x03\xfe\x03\xff\x03\xff\x03\xf8\x03\xbc\x03\x3c\x03\x1e\x00\x1e\x00\x0c\x00" },
|
||||
{ 14, 13, 13, 6, (guchar *) "\x00\x30\x00\x30\x40\x30\x80\x30\x00\x31\x00\x32\xff\x37\x00\x32\x00\x31\x80\x30\x40\x30\x00\x30\x00\x30" },
|
||||
{ 16, 15, 14, 7, (guchar *) "\x00\xf0\x00\xf0\xc0\xf0\xc0\xf1\x80\xf3\x00\xf7\xff\xff\xff\xff\xff\xff\x00\xf7\x80\xf3\xc0\xf1\xc0\xf0\x00\xf0\x00\xf0" },
|
||||
{ 10, 14, 9, 7, (guchar *) "\x00\x13\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\xff\x03\xff\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03" },
|
||||
{ 12, 16, 10, 8, (guchar *) "\x00\xcf\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\xff\x0f\xff\x0f\xff\x0f\xff\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f" },
|
||||
{ 16, 16, 8, 8, (guchar *) "\x01\xc0\xfe\xbf\xfe\xbf\x22\xa2\xaa\xa2\xaa\xa2\xaa\xa2\xaa\xa2\x22\xa2\xfe\xbf\xfe\xbf\xfe\xbf\xfe\xbf\xfe\xbf\xfe\xbf\x01\xc0" },
|
||||
{ 15, 16, 8, 8, (guchar *) "\xfe\xbf\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xfe\x3f" },
|
||||
{ 14, 14, 6, 6, (guchar *) "\xff\x3f\x01\x22\x01\x22\x01\x22\xff\x23\x11\x22\x11\x22\x11\x22\x11\x22\xf1\x3f\x11\x20\x11\x20\x11\x20\xff\x3f" },
|
||||
{ 16, 16, 7, 7, (guchar *) "\xff\xff\xff\xff\xff\xff\x07\xee\xff\xef\xff\xef\xff\xef\x77\xee\x77\xee\xf7\xff\xf7\xff\xf7\xff\x77\xe0\xff\xff\xff\xff\xff\xff" },
|
||||
{ 12, 13, 6, -1, (guchar *) "\x80\x10\x80\x00\xa0\x01\xa0\x01\xb0\x01\xb0\x03\xb8\x03\xb8\x03\xbc\x07\xbc\x07\xbe\x07\xbe\x0f\x1f\x07" },
|
||||
{ 16, 16, 8, 0, (guchar *) "\x00\x03\x00\x07\x80\x07\xc0\x0f\xc0\x0f\xe0\x0f\xe0\x1f\xf0\x1f\xf0\x1f\xf8\x3f\xf8\x3f\xfc\x3f\xfc\xff\xfe\xff\xff\x1f\xfe\x07" },
|
||||
{ 7, 15, 3, 15, (guchar *) "\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x7f\x3e\x1c\x08" },
|
||||
{ 9, 16, 4, 15, (guchar *) "\x7c\xc0\x7c\x00\x7c\x00\x7c\x00\x7c\x00\x7c\x00\x7c\x00\x7c\x00\x7c\x00\x7c\x00\xff\x01\xff\x01\xfe\x00\x7c\x00\x38\x00\x10\x00" },
|
||||
{ 15, 7, 7, 3, (guchar *) "\x08\x08\x0c\x18\xfe\x3f\x0f\x78\xfe\x3f\x0c\x18\x08\x08" },
|
||||
{ 15, 9, 7, 4, (guchar *) "\x18\x8c\x1c\x1c\xfe\x3f\xff\x7f\xff\x7f\xff\x7f\xfe\x3f\x1c\x1c\x18\x0c" },
|
||||
{ 15, 7, -1, 3, (guchar *) "\x08\x00\x0c\x00\xfe\x7f\x0f\x00\xfe\x7f\x0c\x00\x08\x00" },
|
||||
{ 16, 9, 0, 4, (guchar *) "\x30\x00\x38\x00\xfc\xff\xfe\xff\xff\xff\xfe\xff\xfc\xff\x38\x00\x30\x00" },
|
||||
{ 15, 7, 15, 3, (guchar *) "\x00\x08\x00\x18\xff\x3f\x00\x78\xff\x3f\x00\x18\x00\x08" },
|
||||
{ 16, 9, 15, 4, (guchar *) "\x00\x0c\x00\x1c\xff\x3f\xff\x7f\xff\xff\xff\x7f\xff\x3f\x00\x1c\x00\x0c" },
|
||||
{ 7, 15, 3, -1, (guchar *) "\x08\x9c\x3e\x7f\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14\x14" },
|
||||
{ 9, 16, 4, 0, (guchar *) "\x10\xc0\x38\x00\x7c\x00\xfe\x00\xff\x01\xff\x01\x7c\x00\x7c\x00\x7c\x00\x7c\x00\x7c\x00\x7c\x00\x7c\x00\x7c\x00\x7c\x00\x7c\x00" },
|
||||
{ 7, 15, 3, 7, (guchar *) "\x08\x9c\x3e\x7f\x14\x14\x14\x14\x14\x14\x14\x7f\x3e\x1c\x08" },
|
||||
{ 9, 15, 4, 7, (guchar *) "\x38\xc0\x7c\x00\xfe\x00\xff\x01\xff\x01\x7c\x00\x7c\x00\x7c\x00\x7c\x00\x7c\x00\xff\x01\xff\x01\xfe\x00\x7c\x00\x38\x00" },
|
||||
{ 15, 16, 10, 0, (guchar *) "\x00\x84\x00\x0e\x00\x1f\x80\x7b\xa0\x7b\x90\x7b\x88\x7b\x88\x7b\x88\x7b\x88\x7b\x8c\x7b\x8e\x7b\xbf\x7b\x18\x11\x00\x1e\x00\x0c" },
|
||||
{ 16, 16, 11, 0, (guchar *) "\x00\x1c\x00\x3e\x00\x7f\x00\xff\x60\xff\x70\xff\x78\xff\x78\xff\x78\xff\x78\xff\x7c\xff\x7e\xff\x7f\xff\x7e\x7f\x30\x7e\x00\x3c" },
|
||||
{ 14, 14, 7, 7, (guchar *) "\xff\xc0\x01\x00\x01\x00\x01\x00\xf1\x03\x11\x02\x11\x22\x11\x22\x10\x22\xf0\x23\x00\x24\x00\x28\x00\x30\xc0\x3f" },
|
||||
{ 16, 16, 8, 8, (guchar *) "\xff\x03\xff\x03\xff\x03\x07\x00\xf7\x0f\xf7\x0f\xf7\xef\x77\xee\x77\xee\xf7\xef\xf0\xef\xf0\xff\x00\xf8\xc0\xff\xc0\xff\xc0\xff" },
|
||||
{ 16, 16, 6, 7, (guchar *) "\x04\x08\x08\x04\x08\x04\x10\x02\x10\x02\xe1\xe1\xe6\x19\xf8\x07\xf8\x07\xe6\x19\xe1\xe1\x10\x02\x10\x02\x08\x04\x08\x04\x04\x08" },
|
||||
{ 16, 16, 6, 7, (guchar *) "\x06\x18\x0c\x0c\x08\x04\x18\x06\xf1\x83\xf3\xf3\xf6\x3b\xfc\x0f\xfc\x07\xf6\x1f\xf3\xf3\xf1\x83\x18\x02\x18\x06\x0c\x0c\x06\x18" },
|
||||
{ 11, 16, 9, 2, (guchar *) "\x00\xe6\x80\x00\x2c\x06\x9e\x00\x16\x06\x3f\x00\x21\x00\x27\x00\x25\x00\x27\x00\x25\x00\x27\x00\x27\x00\x21\x00\x21\x00\x3f\x00" },
|
||||
{ 12, 16, 10, 2, (guchar *) "\x00\x4c\x18\x0d\x7c\x0d\x7c\x0d\x7e\x0d\xff\x00\xff\x00\xff\x00\xff\x00\xff\x00\xff\x00\xff\x00\xff\x00\xff\x00\xff\x00\xff\x00" },
|
||||
{ 15, 16, 7, 7, (guchar *) "\x80\x80\x40\x01\x40\x01\x40\x01\x20\x02\x20\x02\x20\x02\x9c\x1c\x03\x60\x1c\x1c\x90\x04\x48\x09\x24\x12\x14\x14\x0c\x18\x04\x10" },
|
||||
{ 16, 16, 7, 7, (guchar *) "\x80\x00\xc0\x01\xc0\x01\x60\x03\x60\x03\x30\x06\x38\x1e\x9f\x7c\x03\xe0\x1f\x7c\x9c\x1c\xcc\x19\x66\x33\x36\x36\x1e\x3c\x0e\x38" },
|
||||
{ 15, 13, 7, 6, (guchar *) "\xc0\x81\xf0\x07\x38\x0e\x0c\x18\x06\x30\x83\x60\x43\x61\x83\x60\x06\x30\x0c\x18\x38\x0e\xf0\x07\xc0\x01" },
|
||||
{ 16, 14, 7, 7, (guchar *) "\xe0\x03\xf0\x07\xf8\x0f\x3c\x1e\x0e\x38\x87\x70\xc3\xe1\x63\xe3\xc3\xe1\x87\x70\x0e\x38\x3c\x1e\xf8\x0f\xe0\x03" },
|
||||
{ 13, 13, 6, 6, (guchar *) "\x40\xe0\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\xff\x1f\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00" },
|
||||
{ 15, 15, 7, 7, (guchar *) "\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xff\x7f\xff\x7f\xff\x7f\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01" },
|
||||
{ 14, 14, 0, 0, (guchar *) "\x03\xc0\x0f\x00\x3e\x00\xfe\x00\xfc\x03\xfc\x0f\xf8\x00\xf8\x00\x30\x01\x30\x02\x20\x04\x20\x08\x00\x10\x00\x20" },
|
||||
{ 16, 16, 1, 1, (guchar *) "\x07\x00\x1f\x00\x7f\x00\xfe\x01\xfe\x07\xfc\x3f\xfc\x3f\xf8\x3f\xf8\x03\xf0\x07\xf0\x0e\xe0\x1c\xe0\x38\xe0\x70\x00\xe0\x00\xc0" },
|
||||
{ 14, 14, 0, 0, (guchar *) "\xff\xff\xff\x3f\x03\x00\x03\x00\x03\x00\xe3\x0f\x63\x00\xa3\x00\x23\x01\x23\x02\x23\x04\x23\x08\x03\x00\x03\x00" },
|
||||
{ 16, 16, 1, 1, (guchar *) "\xff\xff\xff\xff\xff\xff\xff\xff\x0f\x00\xef\x3f\xef\x3f\xef\x3f\xef\x03\xef\x07\xef\x0e\xef\x1c\xef\x38\xef\x30\x0f\x00\x0f\x00" },
|
||||
{ 14, 14, 13, 0, (guchar *) "\xff\xff\xff\x3f\x00\x30\x00\x30\x00\x30\xfc\x31\x80\x31\x40\x31\x20\x31\x10\x31\x08\x31\x04\x31\x00\x30\x00\x30" },
|
||||
{ 16, 16, 14, 1, (guchar *) "\xff\xff\xff\xff\xff\xff\xff\xff\x00\xf0\xfc\xf7\xfc\xf7\xfc\xf7\xc0\xf7\xe0\xf7\x70\xf7\x38\xf7\x1c\xf7\x0c\xf7\x00\xf0\x00\xf0" },
|
||||
{ 13, 14, 6, 0, (guchar *) "\xff\xff\xff\x1f\x00\x00\x40\x00\xe0\x00\x50\x01\x48\x02\x44\x04\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00" },
|
||||
{ 15, 16, 7, 1, (guchar *) "\xff\x7f\xff\x7f\xff\x7f\xff\x7f\xc0\x01\xe0\x03\xf0\x07\xf8\x0f\xdc\x1d\xcc\x19\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x01" },
|
||||
{ 14, 10, 7, 0, (guchar *) "\xff\xff\xff\x3f\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00\xc0\x00" },
|
||||
{ 16, 12, 8, 1, (guchar *) "\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x03\xc0\x03" },
|
||||
{ 7, 16, 3, 0, (guchar *) "\x88\x80\x1c\x3e\x7f\x77\x7f\x3e\x1c\x08\x5d\x6b\x49\x41\x41\x41" },
|
||||
{ 9, 16, 4, 0, (guchar *) "\x38\x40\x38\x00\x7c\x00\xfe\x00\xff\x01\xff\x01\xff\x01\xfe\x00\x7c\x00\xba\x00\xff\x01\xff\x01\xff\x01\xd7\x01\xd7\x01\xc7\x01" },
|
||||
{ 10, 10, 0, 0, (guchar *) "\xff\xe3\xff\x03\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00" },
|
||||
{ 12, 12, 1, 1, (guchar *) "\xff\x4f\xff\x0f\xff\x0f\xff\x0f\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00" },
|
||||
{ 14, 14, 7, 2, (guchar *) "\x88\xc4\x20\x0a\xc9\x32\xf2\x09\x4c\x06\x43\x18\x40\x00\x40\x00\x40\x00\x40\x00\x40\x00\x40\x01\x40\x01\x80\x00" },
|
||||
{ 16, 16, 8, 2, (guchar *) "\xe8\x76\xfb\xdf\xfd\x3f\xfe\xff\xff\x3f\xff\xff\xcf\x79\xc0\x01\xc0\x01\xc0\x01\xc0\x01\xc0\x07\xc0\x07\xc0\x07\xc0\x07\x80\x03" },
|
||||
{ 10, 10, 9, 0, (guchar *) "\xff\xe3\xff\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03" },
|
||||
{ 12, 12, 10, 1, (guchar *) "\xff\x4f\xff\x0f\xff\x0f\xff\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f" },
|
||||
{ 16, 16, 15, 9, (guchar *) "\xf8\x07\xf8\x07\xf8\x07\xfc\x0f\x86\x18\x83\x30\x81\xe0\xc1\xe1\xc1\xe1\x21\xe0\x13\x30\x06\x18\xfc\x0f\xf8\x07\xf8\x07\xf8\x07" },
|
||||
{ 16, 16, 15, 9, (guchar *) "\xfc\x0f\xfc\x0f\xfc\x0f\xfe\x1f\xff\x3f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3f\xfe\x1f\xfc\x0f\xfc\x0f\xfc\x0f" },
|
||||
{ 7, 14, 3, 7, (guchar *) "\xf7\x9c\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x1c\x77" },
|
||||
{ 9, 16, 4, 8, (guchar *) "\xef\x41\xff\x01\xff\x01\x7c\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x38\x00\x7c\x00\xff\x01\xff\x01\xef\x01" },
|
||||
};
|
@ -60,6 +60,9 @@
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
#include "vulkan/gskvulkanrenderer.h"
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_MACOS
|
||||
#include <gdk/macos/gdkmacos.h>
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -555,6 +558,10 @@ get_renderer_for_backend (GdkSurface *surface)
|
||||
if (GDK_IS_BROADWAY_SURFACE (surface))
|
||||
return GSK_TYPE_BROADWAY_RENDERER;
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_MACOS
|
||||
if (GDK_IS_MACOS_SURFACE (surface))
|
||||
return GSK_TYPE_GL_RENDERER;
|
||||
#endif
|
||||
|
||||
return G_TYPE_INVALID;
|
||||
}
|
||||
|
@ -1053,6 +1053,12 @@ if cc.has_header('langinfo.h')
|
||||
endforeach
|
||||
endif
|
||||
|
||||
# Maintain compatibility with autotools
|
||||
gtk_ldflags = []
|
||||
if os_darwin
|
||||
gtk_ldflags += [ '-compatibility_version 1', '-current_version 1.0', ]
|
||||
endif
|
||||
|
||||
# Library
|
||||
libgtk = library('gtk-4',
|
||||
soversion: gtk_soversion,
|
||||
@ -1062,7 +1068,7 @@ libgtk = library('gtk-4',
|
||||
include_directories: [confinc, gdkinc, gskinc, gtkinc],
|
||||
dependencies: gtk_deps + [libgtk_css_dep, libgdk_dep, libgsk_dep],
|
||||
link_with: [libgtk_css, libgdk, libgsk, ],
|
||||
link_args: common_ldflags,
|
||||
link_args: common_ldflags + gtk_ldflags,
|
||||
install: true)
|
||||
|
||||
gtk_dep_sources = [gtkversion, gtktypebuiltins_h]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user