mac: took a detour and got it working in 10.4, before accidentally fixing the remaining memory leak I think

This commit is contained in:
IoIxD 2026-03-08 18:04:37 -07:00
commit 3b78872ce8
2 changed files with 871 additions and 834 deletions

View file

@ -21,10 +21,11 @@
#import <CoreGraphics/CoreGraphics.h>
#endif
@interface MilskoCocoaWindowDelegate<NSWindowDelegate> : NSObject {
// Note: implements NSWindowDelegate
@interface MilskoCocoaWindowDelegate : NSObject {
NSWindow* w;
}
- (instancetype)initWithWin:(NSWindow *)win;
- (MilskoCocoaWindowDelegate*)initWithWin:(NSWindow*)win;
@end
@interface MilskoFakePointer : NSView {
@ -79,7 +80,7 @@
MilskoCocoaView* view;
MwLL parent;
MilskoFakePointer* handle;
NSUInteger strHash;
unsigned int strHash;
NSEvent* lastEvent;
}

View file

@ -1,18 +1,18 @@
#include "Mw/BaseTypes.h"
#include "Mw/LowLevel.h"
#include <Mw/Milsko.h>
#include <stdlib.h>
#ifdef __clang__
#pragma clang push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
static CGRect rectFlip(CGRect originFrame) {
NSScreen *zeroScreen = NSScreen.screens[0];
double screenHeight = zeroScreen.frame.size.height;
static NSRect rectFlip(NSRect originFrame) {
NSScreen* zeroScreen = [[NSScreen screens] objectAtIndex:0];
double screenHeight = [zeroScreen frame].size.height;
double originY = originFrame.origin.y;
double frameHeight = originFrame.size.height;
double destinationY = screenHeight - (originY + frameHeight);
CGRect destinationFrame = originFrame;
NSRect destinationFrame = originFrame;
destinationFrame.origin.y = destinationY;
if(destinationFrame.origin.x < 0)
destinationFrame.origin.x = 0;
@ -25,7 +25,7 @@ static CGRect rectFlip(CGRect originFrame) {
return destinationFrame;
}
static CGPoint pointFlip(CGPoint point) {
static NSPoint pointFlip(NSPoint point) {
return rectFlip(NSMakeRect(point.x, point.y, 0, 0)).origin;
}
@ -85,10 +85,10 @@ static CGPoint pointFlip(CGPoint point) {
[c retain];
if(x == MwDEFAULT) {
x = ([NSScreen mainScreen].frame.size.width / 2.) - (width / 2.);
x = ([[NSScreen mainScreen] frame].size.width / 2.) - (width / 2.);
}
if(y == MwDEFAULT) {
y = ([NSScreen mainScreen].frame.size.height / 2.) - (height / 2.);
y = ([[NSScreen mainScreen] frame].size.height / 2.) - (height / 2.);
}
c->application = [NSApplication sharedApplication];
c->rect = rectFlip(NSMakeRect(x, y, width, height));
@ -104,11 +104,11 @@ static CGPoint pointFlip(CGPoint point) {
double offset = 0;
NSWindow* parentWindow = parent->cocoa.real->window;
offset =
[parentWindow frameRectForContentRect:parentWindow.frame].size.height -
[parentWindow contentRectForFrameRect:parentWindow.frame].size.height;
[parentWindow frameRectForContentRect:[parentWindow frame]].size.height -
[parentWindow contentRectForFrameRect:[parentWindow frame]].size.height;
c->rect.origin.x += parentWindow.frame.origin.x;
c->rect.origin.y -= parentWindow.frame.origin.y - offset;
c->rect.origin.x += [parentWindow frame].origin.x;
c->rect.origin.y -= [parentWindow frame].origin.y - offset;
c->rect.origin.y -= offset;
c->window = [[NSWindow alloc] initWithContentRect:c->rect
@ -116,8 +116,8 @@ static CGPoint pointFlip(CGPoint point) {
backing:NSBackingStoreBuffered
defer:NO];
}
c->window.delegate = (id<NSWindowDelegate>)[[MilskoCocoaWindowDelegate alloc]
initWithWin:c->window];
[c->window setDelegate:[[MilskoCocoaWindowDelegate alloc]
initWithWin:c->window]];
[c->window makeKeyAndOrderFront:c->application];
[c->window retain];
@ -127,13 +127,14 @@ static CGPoint pointFlip(CGPoint point) {
[p->window addChildWindow:c->window ordered:NSWindowAbove];
[c->window setHasShadow:MwFALSE];
} else {
[c->application setActivationPolicy:NSApplicationActivationPolicyRegular];
[c->application activateIgnoringOtherApps:true];
[c->window makeFirstResponder:c->view];
}
c->view = [[MilskoCocoaView alloc] initWithFrame:c->rect];
[c->view retain];
c->handle = [[MilskoFakePointer alloc] initWithFrame:NSMakeRect(0, 0, 1, 1)];
[c->handle retain];
[c->handle setPointer:r];
[c->view addSubview:c->handle];
@ -154,7 +155,7 @@ static CGPoint pointFlip(CGPoint point) {
if(ctx) {
int i;
NSBezierPath* path = [NSBezierPath bezierPath];
NSColor *nscolor = [NSColor colorWithRed:color->common.red / 255.
NSColor* nscolor = [NSColor colorWithCalibratedRed:color->common.red / 255.
green:color->common.green / 255.
blue:color->common.blue / 255.
alpha:1.0];
@ -185,6 +186,8 @@ static CGPoint pointFlip(CGPoint point) {
[pool release];
};
- (void)lineWithPoints:(MwPoint*)points color:(MwLLColor)color {
(void)points;
(void)color;
};
- (void)getX:(int*)x Y:(int*)y W:(unsigned int*)w H:(unsigned int*)h {
NSRect frame = rectFlip([self->window frame]);
@ -208,18 +211,16 @@ static CGPoint pointFlip(CGPoint point) {
double offset = 0;
NSWindow* parentWindow = parent->cocoa.real->window;
offset =
[parentWindow frameRectForContentRect:parentWindow.frame].size.height -
[parentWindow contentRectForFrameRect:parentWindow.frame].size.height;
[parentWindow frameRectForContentRect:[parentWindow frame]].size.height -
[parentWindow contentRectForFrameRect:[parentWindow frame]].size.height;
if (x < parentWindow.frame.origin.x) {
frame.origin.x += parentWindow.frame.origin.x;
if(x < [parentWindow frame].origin.x) {
frame.origin.x += [parentWindow frame].origin.x;
}
if (y < parentWindow.frame.origin.y) {
frame.origin.y -= parentWindow.frame.origin.y - offset;
frame.origin.y -= [parentWindow frame].origin.y - offset;
frame.origin.y -= offset;
}
}
[self->view setFrameSize:frame.size];
[self->window setFrame:frame display:YES animate:false];
@ -253,14 +254,19 @@ static CGPoint pointFlip(CGPoint point) {
};
- (void)getNextEvent {
NSEvent *ev;
while ((ev = [self->window nextEventMatchingMask:NSAnyEventMask
while(true) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSEvent* ev = [self->window nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantPast]
inMode:NSDefaultRunLoopMode
dequeue:YES])) {
dequeue:YES];
if(!ev) {
[pool release];
break;
}
[self eventProcess:ev];
[ev release];
[pool release];
}
[self sendClipboardEvent];
@ -269,7 +275,6 @@ static CGPoint pointFlip(CGPoint point) {
- (void)eventProcess:(NSEvent*)ev {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* win = [ev window];
NSWindow *parentWindow = [self parentWindow];
MwLL h;
MwBool doSendEvent = MwTRUE;
@ -278,48 +283,48 @@ static CGPoint pointFlip(CGPoint point) {
return;
}
if ([win contentView].subviews.count == 0) {
if([[[win contentView] subviews] count] == 0) {
printf("no subviews on %p\n", win);
[pool release];
return;
} else {
h = [((MilskoFakePointer *)[win contentView].subviews[0]) pointer];
h = [((MilskoFakePointer*)[[[win contentView] subviews] objectAtIndex:0]) pointer];
}
switch (ev.type) {
case NSEventTypeLeftMouseDown:
case NSEventTypeRightMouseDown:
case NSEventTypeOtherMouseDown:
case NSEventTypeLeftMouseUp:
case NSEventTypeRightMouseUp:
case NSEventTypeOtherMouseUp: {
switch([ev type]) {
case NSLeftMouseDown:
case NSRightMouseDown:
case NSOtherMouseDown:
case NSLeftMouseUp:
case NSRightMouseUp:
case NSOtherMouseUp: {
[self handleMouseEvent:ev ll:h];
}
case NSEventTypeLeftMouseDragged:
case NSEventTypeRightMouseDragged:
case NSEventTypeOtherMouseDragged:
case NSEventTypeMouseMoved: {
case NSLeftMouseDragged:
case NSRightMouseDragged:
case NSOtherMouseDragged:
case NSMouseMoved: {
MwPoint pos;
pos.x = [ev locationInWindow].x;
pos.y = [win contentRectForFrameRect:win.frame].size.height -
pos.y = [win contentRectForFrameRect:[win frame]].size.height -
[ev locationInWindow].y;
MwLLDispatch(h, move, &pos);
break;
}
case NSEventTypeMouseEntered:
case NSMouseEntered:
MwLLDispatch(h, focus_in, NULL);
break;
case NSEventTypeMouseExited:
case NSMouseExited:
MwLLDispatch(h, focus_out, NULL);
break;
case NSEventTypeKeyDown:
case NSEventTypeKeyUp: {
case NSKeyDown:
case NSKeyUp: {
[self handleKeyEvent:ev];
doSendEvent = MwFALSE;
}
case NSEventTypeCursorUpdate:
case NSCursorUpdate:
break;
case NSEventTypeScrollWheel:
case NSScrollWheel:
break;
default:
break;
@ -332,23 +337,23 @@ static CGPoint pointFlip(CGPoint point) {
}
- (void)handleMouseEvent:(NSEvent*)ev ll:(MwLL)ll {
MwLLMouse mouse = {};
MwLLMouse mouse;
MwBool isDown = MwTRUE;
CGPoint mousePoint = pointFlip([ev locationInWindow]);
switch (ev.type) {
case NSEventTypeLeftMouseUp:
NSPoint mousePoint = pointFlip([ev locationInWindow]);
switch([ev type]) {
case NSLeftMouseUp:
isDown = MwFALSE;
case NSEventTypeLeftMouseDown:
case NSLeftMouseDown:
mouse.button = MwLLMouseLeft;
break;
case NSEventTypeRightMouseUp:
case NSRightMouseUp:
isDown = MwFALSE;
case NSEventTypeRightMouseDown:
case NSRightMouseDown:
mouse.button = MwLLMouseRight;
break;
case NSEventTypeOtherMouseUp:
case NSOtherMouseUp:
isDown = MwFALSE;
case NSEventTypeOtherMouseDown:
case NSOtherMouseDown:
mouse.button = MwLLMouseMiddle;
break;
default:
@ -366,7 +371,7 @@ static CGPoint pointFlip(CGPoint point) {
- (void)handleKeyEvent:(NSEvent*)ev {
int ch;
MwLL this = self->handle.pointer;
MwLL this = [self->handle pointer];
enum {
kVK_ANSI_A = 0x00,
kVK_ANSI_S = 0x01,
@ -431,7 +436,7 @@ static CGPoint pointFlip(CGPoint point) {
case x: \
ch = y; \
break;
switch (ev.keyCode) {
switch([ev keyCode]) {
KEY_CASE(kVK_ANSI_A, 'a')
KEY_CASE(kVK_ANSI_B, 'b')
KEY_CASE(kVK_ANSI_C, 'c')
@ -491,11 +496,11 @@ static CGPoint pointFlip(CGPoint point) {
KEY_CASE(kVK_RightArrow, MwLLKeyRight)
KEY_CASE(kVK_UpArrow, MwLLKeyUp)
}
switch (ev.type) {
case NSEventTypeKeyDown:
switch([ev type]) {
case NSKeyDown:
MwLLDispatch(this, key, &ch);
break;
case NSEventTypeKeyUp:
case NSKeyUp:
MwLLDispatch(this, key_released, &ch);
break;
default:
@ -504,7 +509,7 @@ static CGPoint pointFlip(CGPoint point) {
}
- (void)sendClipboardEvent {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
/*NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
NSArray* items = @[
@"public.utf8-plain-text",
@ -533,7 +538,7 @@ static CGPoint pointFlip(CGPoint point) {
}
}
[pool release];
[pool release];*/
}
- (void)setTitle:(const char*)title {
@ -554,9 +559,7 @@ static CGPoint pointFlip(CGPoint point) {
_rect->height)
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1.0
respectFlipped:NO
hints:nil];
fraction:1.0];
[NSGraphicsContext restoreGraphicsState];
@ -565,26 +568,36 @@ static CGPoint pointFlip(CGPoint point) {
[pool release];
};
- (void)setIcon:(MwLLPixmap)pixmap {
(void)pixmap;
};
- (void)forceRender {
_forceRender = MwTRUE;
};
- (void)setCursor:(MwCursor*)image mask:(MwCursor*)mask {
(void)image;
(void)mask;
};
- (void)detachWithPoint:(MwPoint*)point {
(void)point;
};
- (void)show:(int)show {
(void)show;
};
- (void)makePopupWithParent:(MwLL)parent {
- (void)makePopupWithParent:(MwLL)_parent {
(void)_parent;
};
- (void)setSizeHintsWithMinX:(int)minx
MinY:(int)miny
MaxX:(int)maxx
MaxY:(int)maxy {
(void)minx;
(void)miny;
(void)maxx;
(void)maxy;
};
- (void)makeBorderless:(int)toggle {
MwU32 mask = [self->window styleMask];
if (mask & NSBorderlessWindowMask) {
if(toggle) {
mask ^= NSBorderlessWindowMask;
mask |= NSTitledWindowMask;
} else {
@ -600,15 +613,18 @@ static CGPoint pointFlip(CGPoint point) {
[self->window makeMainWindow];
};
- (void)grabPointer:(int)toggle {
(void)toggle;
/* MacOS didn't have a "pointer grab" function
* until 10.13.2 so I need to do this manually */
};
- (void)setClipboard:(const char*)text {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
[pasteboard declareTypes:@[ NSPasteboardTypeString ] owner:nil];
[pasteboard setString:@(text) forType:NSPasteboardTypeString];
[pool release];
(void)text;
// TODO: find out how to do this while supporting 10.4
// NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
// NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
// [pasteboard declareTypes:[NSArray arrayWithObjects:NSPasteboardTypeString] owner:nil];
// [pasteboard setString:[NSString stringWithUTF8String:text] forType:NSPasteboardTypeString];
// [pool release];
};
- (void)getClipboard {
};
@ -639,8 +655,8 @@ static CGPoint pointFlip(CGPoint point) {
- (NSWindow*)parentWindow {
NSWindow* topmostWindow = self->window;
while (topmostWindow.parentWindow)
topmostWindow = topmostWindow.parentWindow;
while([topmostWindow parentWindow])
topmostWindow = [topmostWindow parentWindow];
return topmostWindow;
}
@ -679,10 +695,12 @@ static CGPoint pointFlip(CGPoint point) {
bytesPerRow:width * 4
bitsPerPixel:32];
assert(self->rep);
[self->rep retain];
self->context =
[NSGraphicsContext graphicsContextWithBitmapImageRep:self->rep];
assert(self->context);
[self->context retain];
}
return self;
@ -698,7 +716,7 @@ static CGPoint pointFlip(CGPoint point) {
- (void)drawRect:(NSRect)dirtyRect {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSSize sz = self->rep.size;
NSSize sz = [self->rep size];
[super drawRect:dirtyRect];
if(!self->rep) {
[pool release];
@ -726,6 +744,7 @@ static CGPoint pointFlip(CGPoint point) {
}
- (void)displayRect:(NSRect)rect {
(void)rect;
};
@end
@ -734,28 +753,30 @@ static CGPoint pointFlip(CGPoint point) {
- (NSSize)windowWillResize:(NSWindow*)win toSize:(NSSize)frameSize;
{
if (win.contentView.subviews.count >= 1) {
MilskoFakePointer *ptr = win.contentView.subviews[0];
if([[[win contentView] subviews] count] >= 1) {
MilskoFakePointer* ptr = [[[win contentView] subviews] objectAtIndex:0];
MwLL h = [ptr pointer];
MwLLDispatch(h, resize, NULL);
// MwLLDispatch(h, resize, NULL);
MwLLDispatch(h, draw, NULL);
}
return frameSize;
}
- (void)windowDidResize:(NSNotification*)notification {
(void)notification;
}
// This will close/terminate the application when the main window is closed.
- (void)windowWillClose:(NSNotification*)notification {
(void)notification;
// MilskoCocoa *window = notification.object;
// MwLL handle = [window getHandle].pointer;
// MwLLDispatch(handle, close, NULL);
[NSApp terminate:nil];
}
- (instancetype)initWithWin:(NSWindow *)win {
- (MilskoCocoaWindowDelegate*)initWithWin:(NSWindow*)win {
self->w = win;
return self;
}
@ -764,7 +785,7 @@ static CGPoint pointFlip(CGPoint point) {
@implementation MilskoFakePointer
- (void)setPointer:(void*)pointer {
self.frame = *(NSRect *)&pointer;
[self setFrame:*(NSRect*)&pointer];
self->ptr = pointer;
};
- (void*)pointer {
@ -773,6 +794,7 @@ static CGPoint pointFlip(CGPoint point) {
- (void)drawRect:(NSRect)dirtyRect {
/* explicitly do nothing */
(void)dirtyRect;
}
- (void)destroy {
@ -811,9 +833,13 @@ static void MwLLDestroyImpl(MwLL handle) {
free(handle);
}
static void MwLLBeginDrawImpl(MwLL handle) { (void)handle; }
static void MwLLBeginDrawImpl(MwLL handle) {
(void)handle;
}
static void MwLLEndDrawImpl(MwLL handle) { (void)handle; }
static void MwLLEndDrawImpl(MwLL handle) {
(void)handle;
}
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count,
MwLLColor color) {
@ -856,7 +882,9 @@ static void MwLLSetWHImpl(MwLL handle, int w, int height) {
[h setW:w H:height];
}
static void MwLLFreeColorImpl(MwLLColor color) { free(color); }
static void MwLLFreeColorImpl(MwLLColor color) {
free(color);
}
static int MwLLPendingImpl(MwLL handle) {
MilskoCocoa* h = handle->cocoa.real;
@ -970,7 +998,9 @@ static void MwLLSetClipboardImpl(MwLL handle, const char *text) {
[h setClipboard:text];
}
static void MwLLGetClipboardImpl(MwLL handle) { (void)handle; }
static void MwLLGetClipboardImpl(MwLL handle) {
(void)handle;
}
static void MwLLMakeToolWindowImpl(MwLL handle) {
@ -988,11 +1018,17 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect *rect) {
[h getScreenSize:rect];
}
static void MwLLBeginStateChangeImpl(MwLL handle) { MwLLShow(handle, 0); }
static void MwLLBeginStateChangeImpl(MwLL handle) {
MwLLShow(handle, 0);
}
static void MwLLEndStateChangeImpl(MwLL handle) { MwLLShow(handle, 1); }
static void MwLLEndStateChangeImpl(MwLL handle) {
MwLLShow(handle, 1);
}
static int MwLLCocoaCallInitImpl(void) { return 0; }
static int MwLLCocoaCallInitImpl(void) {
return 0;
}
#include "call.c"
CALL(Cocoa);