From 4319ea25b5b27bdbad0c8b85059c2106f691f735 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Sun, 8 Mar 2026 16:05:57 -0700 Subject: [PATCH] mac: fix a bunch of memory leaks --- include/Mw/LowLevel/Cocoa.h | 3 + src/backend/cocoa.m | 727 +++++++++++------------------------- 2 files changed, 220 insertions(+), 510 deletions(-) diff --git a/include/Mw/LowLevel/Cocoa.h b/include/Mw/LowLevel/Cocoa.h index 58401b2..0ebe775 100644 --- a/include/Mw/LowLevel/Cocoa.h +++ b/include/Mw/LowLevel/Cocoa.h @@ -40,6 +40,7 @@ MwBool valid; int width; int height; + unsigned char *buf; NSImage *image; NSBitmapImageRep *rep; } @@ -97,6 +98,8 @@ - (void)setW:(int)w H:(int)h; - (int)pending; - (void)eventProcess:(NSEvent *)ev; +- (void)handleKeyEvent:(NSEvent *)ev; +- (void)handleMouseEvent:(NSEvent *)ev ll:(MwLL)ll; - (void)getNextEvent; - (void)setTitle:(const char *)title; - (void)drawPixmap:(MwLLPixmap)pixmap rect:(MwRect *)rect; diff --git a/src/backend/cocoa.m b/src/backend/cocoa.m index 0f21dd3..c3cfc3f 100644 --- a/src/backend/cocoa.m +++ b/src/backend/cocoa.m @@ -1,6 +1,7 @@ #include "Mw/BaseTypes.h" #include "Mw/LowLevel.h" #include +#include #pragma clang push #pragma clang diagnostic ignored "-Wdeprecated-declarations" @@ -36,14 +37,11 @@ static CGPoint pointFlip(CGPoint point) { p->width = width; p->height = height; p->image = NULL; - return p; -} -- (void)updateWithData:(unsigned char *)_data { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [self destroy]; - self->rep = - [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&_data + p->buf = malloc(width * height * 4); + + p->rep = + [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&p->buf pixelsWide:(int)width pixelsHigh:(int)height bitsPerSample:8 @@ -53,18 +51,22 @@ static CGPoint pointFlip(CGPoint point) { colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:(int)width * 4 bitsPerPixel:32]; - assert(self->rep); - [self->rep retain]; - self->image = [[NSImage alloc] initWithSize:NSMakeSize(width, height)]; - assert(self->image); - [self->image addRepresentation:self->rep]; - [self->image retain]; - [pool release]; + assert(p->rep); + + p->image = [[NSImage alloc] initWithSize:NSMakeSize(width, height)]; + assert(p->image); + [p->image addRepresentation:p->rep]; + + return p; +} +- (void)updateWithData:(unsigned char *)_data { + memcpy(self->buf, _data, width * height * 4); } - (void)destroy { - if (self->image != NULL) { - [self->image release]; - } + free(self->buf); + [self->image removeRepresentation:self->rep]; + [self->image dealloc]; + [self->rep dealloc]; } - (NSImage *)image { return self->image; @@ -175,6 +177,7 @@ static CGPoint pointFlip(CGPoint point) { [path closePath]; [path fill]; + [nscolor release]; [NSGraphicsContext restoreGraphicsState]; @@ -186,6 +189,7 @@ static CGPoint pointFlip(CGPoint point) { }; - (void)getX:(int *)x Y:(int *)y W:(unsigned int *)w H:(unsigned int *)h { NSRect frame = rectFlip([self->window frame]); + frame = rectFlip(frame); *x = frame.origin.x; *y = frame.origin.y; @@ -232,8 +236,11 @@ static CGPoint pointFlip(CGPoint point) { [self->window setFrame:frame display:YES animate:false]; }; - (int)pending { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + MwBool isPending = MwFALSE; if (_forceRender) { _forceRender = MwFALSE; + [pool release]; return 1; } self->lastEvent = [self->window nextEventMatchingMask:NSAnyEventMask @@ -241,11 +248,12 @@ static CGPoint pointFlip(CGPoint point) { inMode:NSDefaultRunLoopMode dequeue:YES]; - return self->lastEvent != NULL; + isPending = self->lastEvent != NULL; + [pool release]; + return isPending; }; - (void)getNextEvent { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSEvent *ev; while ((ev = [self->window nextEventMatchingMask:NSAnyEventMask @@ -253,10 +261,10 @@ static CGPoint pointFlip(CGPoint point) { inMode:NSDefaultRunLoopMode dequeue:YES])) { [self eventProcess:ev]; + [ev release]; } [self sendClipboardEvent]; - [pool release]; }; - (void)eventProcess:(NSEvent *)ev { @@ -265,7 +273,6 @@ static CGPoint pointFlip(CGPoint point) { NSWindow *parentWindow = [self parentWindow]; MwLL h; MwBool doSendEvent = MwTRUE; - MwLL this = self->handle.pointer; if (!win) { [pool release]; @@ -287,37 +294,7 @@ static CGPoint pointFlip(CGPoint point) { case NSEventTypeLeftMouseUp: case NSEventTypeRightMouseUp: case NSEventTypeOtherMouseUp: { - MwLLMouse mouse = {}; - MwBool isDown = MwTRUE; - CGPoint mousePoint = pointFlip([ev locationInWindow]); - switch (ev.type) { - case NSEventTypeLeftMouseUp: - isDown = MwFALSE; - case NSEventTypeLeftMouseDown: - mouse.button = MwLLMouseLeft; - break; - case NSEventTypeRightMouseUp: - isDown = MwFALSE; - case NSEventTypeRightMouseDown: - mouse.button = MwLLMouseRight; - break; - case NSEventTypeOtherMouseUp: - isDown = MwFALSE; - case NSEventTypeOtherMouseDown: - mouse.button = MwLLMouseMiddle; - break; - default: - break; - } - mouse.point.x = mousePoint.x; - mouse.point.y = mousePoint.y; - - if (isDown) { - MwLLDispatch(h, down, &mouse); - } else { - MwLLDispatch(h, up, &mouse); - } - break; + [self handleMouseEvent:ev ll:h]; } case NSEventTypeLeftMouseDragged: case NSEventTypeRightMouseDragged: @@ -338,464 +315,8 @@ static CGPoint pointFlip(CGPoint point) { break; case NSEventTypeKeyDown: case NSEventTypeKeyUp: { - int ch; - enum { - kVK_ANSI_A = 0x00, - kVK_ANSI_S = 0x01, - kVK_ANSI_D = 0x02, - kVK_ANSI_F = 0x03, - kVK_ANSI_H = 0x04, - kVK_ANSI_G = 0x05, - kVK_ANSI_Z = 0x06, - kVK_ANSI_X = 0x07, - kVK_ANSI_C = 0x08, - kVK_ANSI_V = 0x09, - kVK_ANSI_B = 0x0B, - kVK_ANSI_Q = 0x0C, - kVK_ANSI_W = 0x0D, - kVK_ANSI_E = 0x0E, - kVK_ANSI_R = 0x0F, - kVK_ANSI_Y = 0x10, - kVK_ANSI_T = 0x11, - kVK_ANSI_1 = 0x12, - kVK_ANSI_2 = 0x13, - kVK_ANSI_3 = 0x14, - kVK_ANSI_4 = 0x15, - kVK_ANSI_6 = 0x16, - kVK_ANSI_5 = 0x17, - kVK_ANSI_Equal = 0x18, - kVK_ANSI_9 = 0x19, - kVK_ANSI_7 = 0x1A, - kVK_ANSI_Minus = 0x1B, - kVK_ANSI_8 = 0x1C, - kVK_ANSI_0 = 0x1D, - kVK_ANSI_RightBracket = 0x1E, - kVK_ANSI_O = 0x1F, - kVK_ANSI_U = 0x20, - kVK_ANSI_LeftBracket = 0x21, - kVK_ANSI_I = 0x22, - kVK_ANSI_P = 0x23, - kVK_ANSI_L = 0x25, - kVK_ANSI_J = 0x26, - kVK_ANSI_Quote = 0x27, - kVK_ANSI_K = 0x28, - kVK_ANSI_Semicolon = 0x29, - kVK_ANSI_Backslash = 0x2A, - kVK_ANSI_Comma = 0x2B, - kVK_ANSI_Slash = 0x2C, - kVK_ANSI_N = 0x2D, - kVK_ANSI_M = 0x2E, - kVK_ANSI_Period = 0x2F, - kVK_ANSI_Grave = 0x32, - kVK_ANSI_KeypadDecimal = 0x41, - kVK_ANSI_KeypadMultiply = 0x43, - kVK_ANSI_KeypadPlus = 0x45, - kVK_ANSI_KeypadClear = 0x47, - kVK_ANSI_KeypadDivide = 0x4B, - kVK_ANSI_KeypadEnter = 0x4C, - kVK_ANSI_KeypadMinus = 0x4E, - kVK_ANSI_KeypadEquals = 0x51, - kVK_ANSI_Keypad0 = 0x52, - kVK_ANSI_Keypad1 = 0x53, - kVK_ANSI_Keypad2 = 0x54, - kVK_ANSI_Keypad3 = 0x55, - kVK_ANSI_Keypad4 = 0x56, - kVK_ANSI_Keypad5 = 0x57, - kVK_ANSI_Keypad6 = 0x58, - kVK_ANSI_Keypad7 = 0x59, - kVK_ANSI_Keypad8 = 0x5B, - kVK_ANSI_Keypad9 = 0x5C, - kVK_Return = 0x24, - kVK_Tab = 0x30, - kVK_Space = 0x31, - kVK_Delete = 0x33, - kVK_Escape = 0x35, - kVK_Command = 0x37, - kVK_Shift = 0x38, - kVK_CapsLock = 0x39, - kVK_Option = 0x3A, - kVK_Control = 0x3B, - kVK_RightCommand = 0x36, - kVK_RightShift = 0x3C, - kVK_RightOption = 0x3D, - kVK_RightControl = 0x3E, - kVK_Function = 0x3F, - kVK_F17 = 0x40, - kVK_VolumeUp = 0x48, - kVK_VolumeDown = 0x49, - kVK_Mute = 0x4A, - kVK_F18 = 0x4F, - kVK_F19 = 0x50, - kVK_F20 = 0x5A, - kVK_F5 = 0x60, - kVK_F6 = 0x61, - kVK_F7 = 0x62, - kVK_F3 = 0x63, - kVK_F8 = 0x64, - kVK_F9 = 0x65, - kVK_F11 = 0x67, - kVK_F13 = 0x69, - kVK_F16 = 0x6A, - kVK_F14 = 0x6B, - kVK_F10 = 0x6D, - kVK_F12 = 0x6F, - kVK_F15 = 0x71, - kVK_Help = 0x72, - kVK_Home = 0x73, - kVK_PageUp = 0x74, - kVK_ForwardDelete = 0x75, - kVK_F4 = 0x76, - kVK_End = 0x77, - kVK_F2 = 0x78, - kVK_PageDown = 0x79, - kVK_F1 = 0x7A, - kVK_LeftArrow = 0x7B, - kVK_RightArrow = 0x7C, - kVK_DownArrow = 0x7D, - kVK_UpArrow = 0x7E - }; - // [view.nextResponder - // interpretKeyEvents:[NSArray arrayWithObject:lastEvent]]; - switch (ev.keyCode) { - case kVK_ANSI_A: - ch = 'a'; - break; - case kVK_ANSI_B: - ch = 'b'; - break; - case kVK_ANSI_C: - ch = 'c'; - break; - case kVK_ANSI_D: - ch = 'd'; - break; - case kVK_ANSI_E: - ch = 'e'; - break; - case kVK_ANSI_F: - ch = 'f'; - break; - case kVK_ANSI_G: - ch = 'g'; - break; - case kVK_ANSI_H: - ch = 'h'; - break; - case kVK_ANSI_I: - ch = 'i'; - break; - case kVK_ANSI_J: - ch = 'j'; - break; - case kVK_ANSI_K: - ch = 'k'; - break; - case kVK_ANSI_L: - ch = 'l'; - break; - case kVK_ANSI_M: - ch = 'm'; - break; - case kVK_ANSI_N: - ch = 'n'; - break; - case kVK_ANSI_O: - ch = 'o'; - break; - case kVK_ANSI_P: - ch = 'p'; - break; - case kVK_ANSI_Q: - ch = 'q'; - break; - case kVK_ANSI_R: - ch = 'r'; - break; - case kVK_ANSI_S: - ch = 's'; - break; - case kVK_ANSI_T: - ch = 't'; - break; - case kVK_ANSI_U: - ch = 'u'; - break; - case kVK_ANSI_V: - ch = 'v'; - break; - case kVK_ANSI_W: - ch = 'w'; - break; - case kVK_ANSI_X: - ch = 'x'; - break; - case kVK_ANSI_Y: - ch = 'y'; - break; - case kVK_ANSI_Z: - ch = 'z'; - break; - case kVK_ANSI_0: - ch = '0'; - break; - case kVK_ANSI_1: - ch = '1'; - break; - case kVK_ANSI_2: - ch = '2'; - break; - case kVK_ANSI_3: - ch = '3'; - break; - case kVK_ANSI_4: - ch = '4'; - break; - case kVK_ANSI_5: - ch = '5'; - break; - case kVK_ANSI_6: - ch = '6'; - break; - case kVK_ANSI_7: - ch = '7'; - break; - case kVK_ANSI_8: - ch = '8'; - break; - case kVK_ANSI_9: - ch = '9'; - break; - - // case kVK_ANSI_Keypad0: - // ch = MwLLKey; - // break; - // case kVK_ANSI_Keypad1: - // ch = keypad1; - // break; - // case kVK_ANSI_Keypad2: - // ch = keypad2; - // break; - // case kVK_ANSI_Keypad3: - // ch = keypad3; - // break; - // case kVK_ANSI_Keypad4: - // ch = keypad4; - // break; - // case kVK_ANSI_Keypad5: - // ch = keypad5; - // break; - // case kVK_ANSI_Keypad6: - // ch = keypad6; - // break; - // case kVK_ANSI_Keypad7: - // ch = keypad7; - // break; - // case kVK_ANSI_Keypad8: - // ch = keypad8; - // break; - // case kVK_ANSI_Keypad9: - // ch = keypad9; - // break; - // case kVK_ANSI_KeypadClear: - // ch = keypadClear; - // break; - // case kVK_ANSI_KeypadDivide: - // ch = keypadDivide; - // break; - // case kVK_ANSI_KeypadEnter: - // ch = keypadEnter; - // break; - // case kVK_ANSI_KeypadEquals: - // ch = keypadEquals; - // break; - // case kVK_ANSI_KeypadMinus: - // ch = keypadMinus; - // break; - // case kVK_ANSI_KeypadPlus: - // ch = keypadPlus; - // break; - // case kVK_PageDown: - // ch = MwLLKey; - // break; - // case kVK_PageUp: - // ch = pageUp; - // break; - // case kVK_End: - // ch = end; - // break; - // case kVK_Home: - // ch = home; - // break; - - // case kVK_F1: - // ch = f1; - // break; - // case kVK_F2: - // ch = f2; - // break; - // case kVK_F3: - // ch = f3; - // break; - // case kVK_F4: - // ch = f4; - // break; - // case kVK_F5: - // ch = f5; - // break; - // case kVK_F6: - // ch = f6; - // break; - // case kVK_F7: - // ch = f7; - // break; - // case kVK_F8: - // ch = f8; - // break; - // case kVK_F9: - // ch = f9; - // break; - // case kVK_F10: - // ch = f10; - // break; - // case kVK_F11: - // ch = f11; - // break; - // case kVK_F12: - // ch = f12; - // break; - // case kVK_F13: - // ch = f13; - // break; - // case kVK_F14: - // ch = f14; - // break; - // case kVK_F15: - // ch = f15; - // break; - // case kVK_F16: - // ch = f16; - // break; - // case kVK_F17: - // ch = f17; - // break; - // case kVK_F18: - // ch = f18; - // break; - // case kVK_F19: - // ch = f19; - // break; - // case kVK_F20: - // ch = f20; - // break; - // case kVK_ANSI_KeypadDecimal: - // ch = decimal; - // break; - - case kVK_ANSI_Quote: - ch = '\"'; - break; - case kVK_ANSI_Grave: - ch = '`'; - break; - case kVK_ANSI_Backslash: - ch = '/'; - break; - case kVK_ANSI_Comma: - ch = ','; - break; - // case kVK_Delete: - // ch = delete; - // break; - // case kVK_ANSI_Equal: - // ch = equals; - // break; - case kVK_Escape: - ch = MwLLKeyEscape; - break; - // case kVK_ANSI_LeftBracket: - // ch = leftBracket; - // break; - // case kVK_ANSI_Minus: - // ch = minus; - // break; - // case kVK_ANSI_KeypadMultiply: - // ch = multiply; - // break; - // case kVK_ANSI_Period: - // ch = period; - // break; - case kVK_Return: - ch = MwLLKeyEnter; - break; - // case kVK_ANSI_RightBracket: - // ch = rightBracket; - // break; - case kVK_ANSI_Semicolon: - ch = ';'; - break; - case kVK_ANSI_Slash: - ch = '\\'; - break; - case kVK_Space: - ch = ' '; - break; - // case kVK_Tab: - // ch = tab; - // break; - - // case kVK_Command: - // ch = MwLLKey; - // break; - // case kVK_RightCommand: - // ch = rightCommand; - // break; - case kVK_Control: - ch = MwLLKeyControl; - break; - case kVK_RightControl: - ch = MwLLKeyControl; - break; - // case kVK_Function: - // ch = function; - // break; - // case kVK_Option: - // ch = option; - // break; - // case kVK_RightOption: - // ch = rightOption; - // break; - case kVK_Shift: - ch = MwLLKeyLeftShift; - break; - case kVK_RightShift: - ch = MwLLKeyRightShift; - break; - - case kVK_DownArrow: - ch = MwLLKeyDown; - break; - case kVK_LeftArrow: - ch = MwLLKeyLeft; - break; - case kVK_RightArrow: - ch = MwLLKeyRight; - break; - case kVK_UpArrow: - ch = MwLLKeyUp; - break; - } - switch (ev.type) { - case NSEventTypeKeyDown: - MwLLDispatch(this, key, &ch); - break; - case NSEventTypeKeyUp: - MwLLDispatch(this, key_released, &ch); - break; - default: - break; - } + [self handleKeyEvent:ev]; doSendEvent = MwFALSE; - break; } case NSEventTypeCursorUpdate: break; @@ -811,6 +332,178 @@ static CGPoint pointFlip(CGPoint point) { [pool release]; } +- (void)handleMouseEvent:(NSEvent *)ev ll:(MwLL)ll { + MwLLMouse mouse = {}; + MwBool isDown = MwTRUE; + CGPoint mousePoint = pointFlip([ev locationInWindow]); + switch (ev.type) { + case NSEventTypeLeftMouseUp: + isDown = MwFALSE; + case NSEventTypeLeftMouseDown: + mouse.button = MwLLMouseLeft; + break; + case NSEventTypeRightMouseUp: + isDown = MwFALSE; + case NSEventTypeRightMouseDown: + mouse.button = MwLLMouseRight; + break; + case NSEventTypeOtherMouseUp: + isDown = MwFALSE; + case NSEventTypeOtherMouseDown: + mouse.button = MwLLMouseMiddle; + break; + default: + break; + } + mouse.point.x = mousePoint.x; + mouse.point.y = mousePoint.y; + + if (isDown) { + MwLLDispatch(ll, down, &mouse); + } else { + MwLLDispatch(ll, up, &mouse); + } +} + +- (void)handleKeyEvent:(NSEvent *)ev { + int ch; + MwLL this = self->handle.pointer; + enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_Return = 0x24, + kVK_Space = 0x31, + kVK_Escape = 0x35, + kVK_Shift = 0x38, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightControl = 0x3E, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E + }; +#define KEY_CASE(x, y) \ + case x: \ + ch = y; \ + break; + switch (ev.keyCode) { + KEY_CASE(kVK_ANSI_A, 'a') + KEY_CASE(kVK_ANSI_B, 'b') + KEY_CASE(kVK_ANSI_C, 'c') + KEY_CASE(kVK_ANSI_D, 'd') + KEY_CASE(kVK_ANSI_E, 'e') + KEY_CASE(kVK_ANSI_F, 'f') + KEY_CASE(kVK_ANSI_G, 'g') + KEY_CASE(kVK_ANSI_H, 'h') + KEY_CASE(kVK_ANSI_I, 'i') + KEY_CASE(kVK_ANSI_J, 'j') + KEY_CASE(kVK_ANSI_K, 'k') + KEY_CASE(kVK_ANSI_L, 'l') + KEY_CASE(kVK_ANSI_M, 'm') + KEY_CASE(kVK_ANSI_N, 'n') + KEY_CASE(kVK_ANSI_O, 'o') + KEY_CASE(kVK_ANSI_P, 'p') + KEY_CASE(kVK_ANSI_Q, 'q') + KEY_CASE(kVK_ANSI_R, 'r') + KEY_CASE(kVK_ANSI_S, 's') + KEY_CASE(kVK_ANSI_T, 't') + KEY_CASE(kVK_ANSI_U, 'u') + KEY_CASE(kVK_ANSI_V, 'v') + KEY_CASE(kVK_ANSI_W, 'w') + KEY_CASE(kVK_ANSI_X, 'x') + KEY_CASE(kVK_ANSI_Y, 'y') + KEY_CASE(kVK_ANSI_Z, 'z') + KEY_CASE(kVK_ANSI_0, '0') + KEY_CASE(kVK_ANSI_1, '1') + KEY_CASE(kVK_ANSI_2, '2') + KEY_CASE(kVK_ANSI_3, '3') + KEY_CASE(kVK_ANSI_4, '4') + KEY_CASE(kVK_ANSI_5, '5') + KEY_CASE(kVK_ANSI_6, '6') + KEY_CASE(kVK_ANSI_7, '7') + KEY_CASE(kVK_ANSI_8, '8') + KEY_CASE(kVK_ANSI_9, '9') + KEY_CASE(kVK_ANSI_Quote, '\"') + KEY_CASE(kVK_ANSI_Grave, '`') + KEY_CASE(kVK_ANSI_Backslash, '/') + KEY_CASE(kVK_ANSI_Comma, ',') + KEY_CASE(kVK_ANSI_Equal, '=') + KEY_CASE(kVK_Escape, MwLLKeyEscape) + KEY_CASE(kVK_ANSI_LeftBracket, '[') + KEY_CASE(kVK_ANSI_Minus, '-') + KEY_CASE(kVK_ANSI_Period, '.') + KEY_CASE(kVK_Return, MwLLKeyEnter) + KEY_CASE(kVK_ANSI_RightBracket, ']') + KEY_CASE(kVK_ANSI_Semicolon, ';') + KEY_CASE(kVK_ANSI_Slash, '\\') + KEY_CASE(kVK_Space, ' ') + KEY_CASE(kVK_Control, MwLLKeyControl) + KEY_CASE(kVK_RightControl, MwLLKeyControl) + KEY_CASE(kVK_Shift, MwLLKeyLeftShift) + KEY_CASE(kVK_RightShift, MwLLKeyRightShift) + KEY_CASE(kVK_DownArrow, MwLLKeyDown) + KEY_CASE(kVK_LeftArrow, MwLLKeyLeft) + KEY_CASE(kVK_RightArrow, MwLLKeyRight) + KEY_CASE(kVK_UpArrow, MwLLKeyUp) + } + switch (ev.type) { + case NSEventTypeKeyDown: + MwLLDispatch(this, key, &ch); + break; + case NSEventTypeKeyUp: + MwLLDispatch(this, key_released, &ch); + break; + default: + break; + } +} + - (void)sendClipboardEvent { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; @@ -935,7 +628,14 @@ static CGPoint pointFlip(CGPoint point) { _rect->height = [screen frame].size.height; }; - (void)destroy { + if (self->lastEvent) { + [self->lastEvent release]; + [self->lastEvent dealloc]; + } + [self->handle release]; + [self->handle dealloc]; [self->window release]; + [self->window dealloc]; } - (NSWindow *)parentWindow { @@ -1014,11 +714,16 @@ static CGPoint pointFlip(CGPoint point) { - (void)destroy { CGColorSpaceRelease(self->space); + [self->rep release]; + [self->context release]; } - (void)setFrameSize:(NSSize)newSize { [super setFrameSize:newSize]; [self->rep setSize:newSize]; + + self->width = newSize.width; + self->height = newSize.height; } - (void)displayRect:(NSRect)rect { @@ -1034,7 +739,7 @@ static CGPoint pointFlip(CGPoint point) { MilskoFakePointer *ptr = win.contentView.subviews[0]; MwLL h = [ptr pointer]; - // MwLLDispatch(h, resize, NULL); + MwLLDispatch(h, resize, NULL); MwLLDispatch(h, draw, NULL); } return frameSize; @@ -1188,6 +893,7 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char *data, r->cocoa.real = [MilskoCocoaPixmap newWithWidth:width height:height]; MwLLPixmapUpdate(r); + free(r->common.raw); return r; } @@ -1199,6 +905,7 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap pixmap) { static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { MilskoCocoaPixmap *p = pixmap->cocoa.real; [p destroy]; + [p dealloc]; free(pixmap); }