diff --git a/Jenkinsfile b/Jenkinsfile index 8c1d0050..3bdf08ea 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -7,11 +7,7 @@ pipeline { when { branch "master" } - agent { - label "built-in" - } steps { - sh("rm -rf include/Mw/LowLevel/Wayland") sh("doxygen") sh("rm -rf /var/www/milsko-doxygen") sh("mv doxygen/html /var/www/milsko-doxygen") diff --git a/configure b/configure index 5d981086..0371bcd0 100755 --- a/configure +++ b/configure @@ -38,6 +38,7 @@ require("./pl/utils.pl"); param_set("classic-theme", 0); param_set("stb-image", 1); +param_set("stb-truetype", 0); param_set("xrender", 1); param_set("opengl", 0); param_set("vulkan", 0); @@ -49,9 +50,6 @@ param_set("examples", 1); if($target ne "Darwin") { param_set("freetype2", 1); - param_set("stb-truetype", 0); -} else { - param_set("stb-truetype", 1); } my %features = ( @@ -66,7 +64,6 @@ my %features = ( "shared" => "build shared library", "static" => "build static library", "wayland" => "enable wayland backend", - "gnustep" => "use gnustep", ); my @features_keys = ( "1classic-theme", "1stb-image", @@ -74,16 +71,9 @@ my @features_keys = ( "1opengl", "2xrender", "1vulkan", "2vulkan-string-helper", "1shared", "1static", - "1wayland", "1gnustep", + "1wayland", ); -if($target eq "Linux") { - param_set("x11", 1); - if(!param_get("tiny")){ - param_set("wayland", 1); - } -} - foreach my $l (@ARGV) { if ($l =~ /^--with-([^=]+)=(.+)$/) { param_set($1, $2); @@ -146,6 +136,13 @@ foreach my $l (@ARGV) { } } +if($target eq "Linux") { + param_set("x11", 1); + if(!param_get("tiny")){ + param_set("wayland", 1); + } +} + if (-f "./pl/ostype/${target}.pl") { require("./pl/ostype/${target}.pl"); } diff --git a/examples/gldemos/CMakeLists.txt b/examples/gldemos/CMakeLists.txt index 122f62c5..9afda19f 100644 --- a/examples/gldemos/CMakeLists.txt +++ b/examples/gldemos/CMakeLists.txt @@ -15,7 +15,7 @@ foreach(PATH IN LISTS EXAMPLES_GL_SOURCES) ${TARGET} PRIVATE Mw - OpenGL::GL OpenGL::GLU + OpenGL::GL ) if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") target_link_libraries( diff --git a/examples/vkdemos/CMakeLists.txt b/examples/vkdemos/CMakeLists.txt index a315bf91..354bf363 100644 --- a/examples/vkdemos/CMakeLists.txt +++ b/examples/vkdemos/CMakeLists.txt @@ -3,16 +3,10 @@ file( EXAMPLES_VULKAN_SOURCES *.c ) -find_package(Vulkan) foreach(PATH IN LISTS EXAMPLES_VULKAN_SOURCES) get_filename_component(TARGET ${PATH} NAME_WE) add_executable(${TARGET} WIN32 MACOSX_BUNDLE ${PATH}) - target_include_directories( - ${TARGET} - PRIVATE - ${Vulkan_INCLUDE_DIR} - ) target_link_libraries( ${TARGET} PRIVATE diff --git a/include/Mw/Draw.h b/include/Mw/Draw.h index 9208d725..c6c36127 100644 --- a/include/Mw/Draw.h +++ b/include/Mw/Draw.h @@ -53,7 +53,7 @@ MWDECL void MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color); * @param rect Rectangle area * @param color Color */ -MWDECL void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color); +MWDECL void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color, int rounded); /*! * @brief Draws a frame @@ -63,7 +63,7 @@ MWDECL void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color); * @param invert Invert the 3D border color or not * @warning `rect` gets changed to the area of rectangle inside */ -MWDECL void MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert); +MWDECL void MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int rounded); /*! * @brief Does the DrawFrame/DrawRect combo used for drawing widget. @@ -96,7 +96,7 @@ MWDECL void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int i * @param rounded Rounded or not * @warning `rect` gets changed to the area of rectangle inside */ -MWDECL void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same); +MWDECL void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same, int rounded); /*! * @brief Creates a pixmap from image diff --git a/include/Mw/LowLevel/Cocoa.h b/include/Mw/LowLevel/Cocoa.h index 2a8c7ec7..da104f01 100644 --- a/include/Mw/LowLevel/Cocoa.h +++ b/include/Mw/LowLevel/Cocoa.h @@ -15,6 +15,12 @@ #import #import +#ifdef __APPLE__ +#import +#else +#import +#endif + @interface MilskoCocoaApplication : NSApplication { MwBool doPending; } @@ -34,9 +40,9 @@ // Note: implements NSWindowDelegate @interface MilskoCocoaWindowDelegate : NSObject { - NSWindow* w; + MilskoCocoaWindow* w; } -- (MilskoCocoaWindowDelegate*)initWithWin:(NSWindow*)win; +- (MilskoCocoaWindowDelegate*)initWithWin:(MilskoCocoaWindow*)win; @end /* @@ -61,7 +67,6 @@ @end @interface MilskoCocoaPixmap : NSObject { - @public MwBool valid; int width; int height; @@ -81,17 +86,18 @@ @end @interface MilskoCocoaView : NSView { - @public - unsigned char* buf; - NSBitmapImageRep* rep; - NSGraphicsContext* context; - MwBool valid; - NSRect givenRect; - float x; - float y; - float width; - float height; - MwBool _child; + NSBitmapImageRep* rep; + NSGraphicsContext* context; + MwBool valid; + CGColorSpaceRef space; + CGDataProviderRef provider; + NSRect givenRect; + float x; + float y; + float width; + float height; + MwBool _child; + IBOutlet NSViewController* viewController; } - (void)initRepAndContextWithWidth:(float)w Height:(float)h; @@ -99,18 +105,14 @@ - (void)destroy; - (NSBitmapImageRep*)getRep; - (void)setChild; -@end -@interface MilskoCocoaSubView : MilskoCocoaView { -} @end @interface MilskoCocoa : NSObject { - @public MilskoCocoaApplication* application; MwBool _forceRender; MwBool _eventsPending; - NSWindow* window; + MilskoCocoaWindow* window; NSRect rect; MilskoCocoaView* view; MwLL parent; @@ -124,21 +126,55 @@ MwBool pointerLocked; MwBool mouseMoved; - - MwBool rejectFirstTest; } + ++ (MilskoCocoa*)newWithParent:(MwLL)parent + x:(int)x + y:(int)y + width:(int)width + height:(int)height + handle:(MwLL)handle; +- (void)polygonWithPoints:(MwPoint*)points + points_count:(int)points_count + color:(MwLLColor)color; +- (void)lineWithPoints:(MwPoint*)points color:(MwLLColor)color; +- (void)getX:(int*)x Y:(int*)y W:(unsigned int*)w H:(unsigned int*)h; +- (void)setX:(int)x Y:(int)y; +- (void)setW:(int)w H:(int)h; +- (int)pending; +- (void)getNextEvent; +- (void)setTitle:(const char*)title; +- (void)drawPixmap:(MwLLPixmap)pixmap rect:(MwRect*)rect; +- (void)setIcon:(MwLLPixmap)pixmap; +- (void)forceRender; +- (void)setCursor:(MwCursor*)image mask:(MwCursor*)mask; +- (void)detachWithPoint:(MwPoint*)point; +- (void)show:(int)show; +- (void)makePopupWithParent:(MwLL)parent; +- (void)setSizeHintsWithMinX:(int)minx + MinY:(int)miny + MaxX:(int)maxx + MaxY:(int)maxy; +- (void)makeBorderless:(int)toggle; +- (void)focus; +- (void)grabPointer:(int)toggle; +- (void)setClipboard:(const char*)text; +- (void)makeToolWindow; +- (void)getCursorCoord:(MwPoint*)point; +- (void)getScreenSize:(MwRect*)rect; - (void)destroy; - (void)sendClipboardEvent; - (MwLL)getParent; - (NSView*)getView; -- (NSWindow*)getWindow; +- (MilskoCocoaWindow*)getWindow; - (void)nudge; - (void)pushCursor; - (void)popCursor; - (MilskoFakePointer*)getHandle; ++ (void)eventCanceller:(MilskoCocoa*)this; @end #define OBJC(x) x diff --git a/include/Mw/MachDep.h b/include/Mw/MachDep.h index 50898f67..61a6f909 100644 --- a/include/Mw/MachDep.h +++ b/include/Mw/MachDep.h @@ -57,26 +57,17 @@ #define M_PI 3.14159265 #endif -/* Windows */ #if defined(_MILSKO) && defined(_WIN32) #define MWDECL extern __declspec(dllexport) #elif defined(_WIN32) #define MWDECL extern __declspec(dllimport) -/* GCC/Clang */ -/* First check if we have __has_attribute and can check for the existence of visibility */ #elif defined(__has_attribute) #if __has_attribute(visibility) #define MWDECL extern __attribute__((visibility("default"))) #else #define MWDECL extern #endif -/* It might be that we're on an old version of GCC (like the one Apple ships with older versions of Mac OS). - * If we're on gcc 3 or above, assume it's there - */ -#elif __GNUC__ >= 3 -#define MWDECL extern __attribute__((visibility("default"))) #else -/* all else fails */ #define MWDECL extern #endif diff --git a/milsko.xml b/milsko.xml index 18caed3c..51c065a8 100644 --- a/milsko.xml +++ b/milsko.xml @@ -40,7 +40,21 @@ - - - - + + + + @@ -66,39 +80,38 @@ - - + + - - - + + + - + - + - - - + + - - - - + + + + - + diff --git a/pl/rules.pl b/pl/rules.pl index 0f4870e3..46d9da92 100644 --- a/pl/rules.pl +++ b/pl/rules.pl @@ -55,17 +55,10 @@ if (grep(/^wayland$/, @backends)) { $gl_libs = "-lGL -lGLU"; } -if (grep(/^cocoa$/, @backends) || param_get("gnustep")) { +if (grep(/^cocoa$/, @backends)) { add_cflags("-DUSE_COCOA"); new_object("src/backend/cocoa.m"); - if(param_get("gnustep")){ - add_incdir("-I".`gnustep-config --variable=GNUSTEP_SYSTEM_HEADERS`); - add_libdir("-L".`gnustep-config --variable=GNUSTEP_SYSTEM_LIBRARIES`); - add_cflags("-fobjc-runtime=gnustep-2.0 -fblocks"); - add_ldflags("-lobjc -lgnustep-base -lm -lgnustep-gui"); - } - if (param_get("opengl")) { new_object("src/widget/opengl_cocoa.m"); } diff --git a/src/backend/cocoa.m b/src/backend/cocoa.m index c336f7fb..04ce17ed 100644 --- a/src/backend/cocoa.m +++ b/src/backend/cocoa.m @@ -64,6 +64,554 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { } }; +@implementation MilskoCocoaPixmap + ++ (MilskoCocoaPixmap*)newWithWidth:(int)width height:(int)height { + MilskoCocoaPixmap* p = [MilskoCocoaPixmap alloc]; + + p->width = width; + p->height = height; + p->image = NULL; + + p->buf = malloc(width * height * 4); + + p->rep = + [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&p->buf + pixelsWide:(int)width + pixelsHigh:(int)height + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:(int)width * 4 + bitsPerPixel:32]; + 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); + if(self->rep) { + [self->image removeRepresentation:self->rep]; + [self->rep release]; + } + self->rep = + [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&self->buf + pixelsWide:(int)width + pixelsHigh:(int)height + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:(int)width * 4 + bitsPerPixel:32]; + [self->image addRepresentation:self->rep]; +} +- (void)destroy { + free(self->buf); + [self->image removeRepresentation:self->rep]; + [self->image dealloc]; + [self->rep dealloc]; + self->image = NULL; + self->rep = NULL; +} +- (NSImage*)image { + return self->image; +} +@end + +@implementation MilskoCocoa + ++ (MilskoCocoa*)newWithParent:(MwLL)parent + x:(int)x + y:(int)y + width:(int)width + height:(int)height + handle:(MwLL)r { + MilskoCocoa* c = [MilskoCocoa alloc]; + [c retain]; + + /* + * MacOS doesn't really have a "default" window position, you're actually + * meant to center the window yourself, so if the user passes MwDEFAULT + * respond appropriately. Also for child windows just have it be 0. + */ + if(x == MwDEFAULT) { + x = r ? ([[NSScreen mainScreen] frame].size.width / 2.) - (width / 2.) : 0; + } + if(y == MwDEFAULT) { + y = r ? ([[NSScreen mainScreen] frame].size.height / 2.) - (height / 2.) + : 0; + } + c->application = [MilskoCocoaApplication sharedApplication]; + c->rect = NSMakeRect(x, y, width, height); + + if(parent == NULL) { + c->window = [[MilskoCocoaWindow alloc] + initWithContentRect:rectFlip(c->rect) + styleMask:(NSTitledWindowMask | + NSTexturedBackgroundWindowMask | + NSClosableWindowMask | NSMiniaturizableWindowMask | + NSResizableWindowMask) + backing:NSBackingStoreBuffered + defer:NO]; + [c->window + setDelegate:[[MilskoCocoaWindowDelegate alloc] initWithWin:c->window]]; + [c->window retain]; + + [c->window makeKeyAndOrderFront:c->application]; + [c->window makeFirstResponder:c->view]; + + c->view = [[MilskoCocoaView alloc] initWithFrame:c->rect]; + [c->view retain]; + [c->window setContentView:c->view]; + + if([c->application respondsToSelector:@selector(setActivationPolicy:)]) { + [c->application + setActivationPolicy:0 /* NSApplicationActivationPolicyRegular */]; + } + [c->application activateIgnoringOtherApps:MwTRUE]; + [c->application setDelegate:[[MilskoCocoaApplicationDelegate alloc] + initWithAppl:c->application]]; + [c->application retain]; + + [c->view addTrackingRect:c->rect owner:c->view userData:NULL assumeInside:MwFALSE]; + } else { + MilskoCocoa* p = parent->cocoa.real; + + c->window = p->window; + + NSRect rect = localRectFlip(c->rect, p->view); + c->view = [[MilskoCocoaView alloc] initWithFrame:rect]; + [c->view setBounds:c->rect]; + + [c->view retain]; + [c->view setNeedsDisplay:TRUE]; + [c->view setChild]; + + [c->view addTrackingRect:c->rect owner:c->view userData:NULL assumeInside:MwFALSE]; + + [p->view addSubview:c->view]; + [p->window setContentView:p->view]; + } + [c->window setAcceptsMouseMovedEvents:MwTRUE]; + + c->handle = [[MilskoFakePointer alloc] initWithFrame:NSMakeRect(0, 0, 1, 1)]; + [c->handle retain]; + [c->handle setPointer:r]; + [c->view addSubview:c->handle]; + + c->modalSession = [c->application beginModalSessionForWindow:c->window]; + c->parent = parent; + + c->_forceRender = MwTRUE; + c->strHash = 0; + + c->cursorPixmap = NULL; + + [c->application finishLaunching]; + + c->pointerLocked = MwFALSE; + + return c; +} + +- (void)polygonWithPoints:(MwPoint*)points + points_count:(int)points_count + color:(MwLLColor)color { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSGraphicsContext* ctx = [self->view context]; + if(ctx) { + int i; + NSBezierPath* path = [NSBezierPath bezierPath]; + /* whatever rect we use for coordinate flipping */ + NSRect _rect = parent ? [self->view bounds] : [self->window frame]; + + NSColor* nscolor = + [NSColor colorWithCalibratedRed:color->common.red / 255. + green:color->common.green / 255. + blue:color->common.blue / 255. + alpha:1.0]; + + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:ctx]; + + [nscolor setFill]; + for(i = 0; i < points_count; i++) { + NSPoint p = localPointFlip(NSMakePoint(points[i].x, points[i].y), self->view); + if(i == 0) { + [path moveToPoint:p]; + } else { + [path lineToPoint:p]; + } + } + + [path closePath]; + [path fill]; + + [NSGraphicsContext restoreGraphicsState]; + + [self->view setNeedsDisplay:YES]; + } + [pool release]; +}; +- (void)lineWithPoints:(MwPoint*)points color:(MwLLColor)color { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSGraphicsContext* ctx = [self->view context]; + if(ctx) { + int i; + NSBezierPath* path = [NSBezierPath bezierPath]; + /* whatever rect we use for coordinate flipping */ + NSRect _rect = parent ? [self->view bounds] : [self->window frame]; + + NSColor* nscolor = + [NSColor colorWithCalibratedRed:color->common.red / 255. + green:color->common.green / 255. + blue:color->common.blue / 255. + alpha:1.0]; + + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:ctx]; + + [nscolor setFill]; + for(i = 0; i < 2; i++) { + NSPoint p = localPointFlip(NSMakePoint(points[i].x, points[i].y), self->view); + if(i == 0) { + [path moveToPoint:p]; + } else { + [path lineToPoint:p]; + } + } + + [path closePath]; + [path stroke]; + + [NSGraphicsContext restoreGraphicsState]; + + [self->view setNeedsDisplay:YES]; + } + [pool release]; +}; +- (void)getX:(int*)x Y:(int*)y W:(unsigned int*)w H:(unsigned int*)h { + NSRect frame; + if(parent) { + frame = [self->view frame]; + } else { + frame = [self->window frame]; + } + frame = rectFlip(frame); + + *x = frame.origin.x; + *y = frame.origin.y; + + *w = frame.size.width; + *h = frame.size.height; +}; +- (void)setX:(int)x Y:(int)y { + NSRect frame; + if(parent) { + frame = [self->view frame]; + } else { + frame = [self->window frame]; + } + + frame.origin.x = x; + frame.origin.y = y; + + if(!parent) { + frame = rectFlip(frame); + [self->window setFrame:frame display:TRUE animate:TRUE]; + } else { + frame = localRectFlip(frame, parent->cocoa.real->view); + [self->view setBounds:frame]; + } + self->_eventsPending = MwTRUE; +}; +- (void)setW:(int)w H:(int)h { + NSRect frame = [self->window frame]; + frame.size.width = w; + frame.size.height = h; + + self->rect = frame; + + [self->view setFrameSize:frame.size]; + if(self->parent) { + [self->view setFrame:frame]; + } else { + [self->window setFrame:frame display:YES animate:false]; + } + self->_eventsPending = MwTRUE; +}; +- (int)pending { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + MwBool isPending = [self->application pending]; + [NSApp runModalSession:self->modalSession]; + [pool release]; + return _forceRender || _eventsPending || isPending; +}; + +- (void)getNextEvent { + MwLL h = [self->handle pointer]; + if(_forceRender) { + MwLLDispatch(h, draw, NULL); + [self->view setNeedsDisplay:true]; + _forceRender = MwFALSE; + } + if(_eventsPending) { + MwLLDispatch(h, draw, NULL); + [self->view setNeedsDisplay:true]; + _eventsPending = MwFALSE; + } + [self sendClipboardEvent]; + + if(self->pointerLocked && [self->window isMainWindow] && self->lastEvent) { + struct CGPoint pos; + pos.x = [window frame].origin.x + [window frame].size.width / 2; + pos.y = [window frame].origin.y + [window frame].size.height / 2; + + CGWarpMouseCursorPosition(pos); + } + + [self->application updateWindows]; +}; + +- (void)sendClipboardEvent { + /*NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; + NSArray* items = @[ + @"public.utf8-plain-text", + @"public.utf16-external-plain-text", + @"com.apple.traditional-mac-plain-text", + ]; + MwLL this = self->handle.pointer; + + if([pasteboard canReadItemWithDataConformingToTypes:items]) { + char* data = NULL; + size_t size = 0; + for(NSPasteboardItem* item in [pasteboard pasteboardItems]) { + for(NSString* it in items) { + NSString* itemData = [item + stringForType:(NSString*)it]; if(itemData != NULL) { if(strHash != 0 && + strHash != [itemData hash]) { char* text = malloc([itemData length]); + strncpy(text, [itemData UTF8String], + [itemData length]); MwLLDispatch(this, clipboard, text); printf("%s -> %p\n", + text, this); free(text); + } + strHash = [itemData hash]; + } + } + } + } + + [pool release];*/ +} + +- (void)setTitle:(const char*)title { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [self->window + setTitleWithRepresentedFilename:[NSString stringWithUTF8String:title]]; + [pool release]; +}; +- (void)drawPixmap:(MwLLPixmap)pixmap rect:(MwRect*)_rect { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + MilskoCocoaPixmap* p = pixmap->cocoa.real; + NSGraphicsContext* ctx = [self->view context]; + if(ctx) { + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:ctx]; + + [[p image] + drawInRect:localRectFlip(NSMakeRect(_rect->x, _rect->y, _rect->width, _rect->height), self->view) + fromRect:NSZeroRect + operation:NSCompositeSourceOver + fraction:1.0]; + + [NSGraphicsContext restoreGraphicsState]; + + [self->view setNeedsDisplay:YES]; + } + [pool release]; +}; +- (void)setIcon:(MwLLPixmap)pixmap { + [self->application setApplicationIconImage:[pixmap->cocoa.real image]]; +}; +- (void)forceRender { + self->_forceRender = MwTRUE; + // NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + // NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined + // location:NSMakePoint(0, 0) + // modifierFlags:0 + // timestamp:0 + // windowNumber:0 + // context:nil + // subtype:0 + // data1:0 + // data2:0]; + // [NSApp postEvent:event atStart:YES]; + // [pool release]; +}; +- (void)setCursor:(MwCursor*)image mask:(MwCursor*)mask { + int y, x, ys, xs; + unsigned char* di = malloc(image->width * image->height * 4); + memset(di, 0, image->width * image->height * 4); + + if(self->cursorPixmap) { + [self->cursorPixmap destroy]; + } + self->cursorPixmap = + [MilskoCocoaPixmap newWithWidth:image->width + height:image->height]; + + xs = -mask->x + image->x; + ys = MwCursorDataHeight + mask->y; + ys = MwCursorDataHeight + image->y - ys; + + for(y = 0; y < mask->height; y++) { + unsigned int d = mask->data[y]; + for(x = mask->width - 1; x >= 0; x--) { + int px = 0; + int idx = ((y * mask->width) + x) * 4; + + if(d & 1) { + di[idx + 3] = 255; + }; + d = d >> 1; + } + } + for(y = 0; y < image->height; y++) { + unsigned int d = image->data[y]; + for(x = image->width - 1; x >= 0; x--) { + int px = 0; + int idx = ((y * image->width) + x) * 4; + + if(d & 1) { + px = 255; + }; + + di[idx] = px; + di[idx + 1] = px; + di[idx + 2] = px; + d = d >> 1; + } + } + + [self->cursorPixmap updateWithData:di]; + + self->cursor = [[NSCursor alloc] + initWithImage:[self->cursorPixmap image] + hotSpot:NSMakePoint(image->x, image->y + image->height)]; + [self->cursor retain]; + + [self->cursor pop]; + [self->cursor push]; + + free(di); +}; +- (void)detachWithPoint:(MwPoint*)point { + [self->window setParentWindow:NULL]; +}; +- (void)show:(int)show { + (void)show; +}; +- (void)makePopupWithParent:(MwLL)_parent { + (void)_parent; +}; +- (void)setSizeHintsWithMinX:(int)minx + MinY:(int)miny + MaxX:(int)maxx + MaxY:(int)maxy { + [self->window setMinSize:NSMakeSize(minx, miny)]; + [self->window setMaxSize:NSMakeSize(maxx, maxy)]; +}; +- (void)makeBorderless:(int)toggle { + MwU32 mask = [self->window styleMask]; + if(toggle) { + mask ^= NSBorderlessWindowMask; + mask |= NSTitledWindowMask; + } else { + mask |= NSBorderlessWindowMask; + mask ^= NSTitledWindowMask; + } + [self->window initWithContentRect:self->rect + styleMask:mask + backing:NSBackingStoreBuffered + defer:NO]; +}; +- (void)focus { + [self->window makeMainWindow]; +}; +- (void)grabPointer:(int)toggle { + self->pointerLocked = toggle; +}; +- (void)setClipboard:(const char*)text { + (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)makeToolWindow { + /* If my understand of what a "tool window" usually is is correct then I + * highly doubt the Mac OS has this and if they did they probably outright + * removed it along time ago is this kind of conflicts with modern UX. So + * we'll just make it borderless idgaf */ + [self makeBorderless:MwTRUE]; +}; +- (void)getCursorCoord:(MwPoint*)point { + NSPoint p = [NSEvent mouseLocation]; + point->x = p.x; + point->y = p.y; +}; +- (void)getScreenSize:(MwRect*)_rect { + NSScreen* screen = [self->window screen]; + _rect->x = [screen frame].origin.x; + _rect->y = [screen frame].origin.y; + _rect->width = [screen frame].size.width; + _rect->height = [screen frame].size.height; +}; +- (void)destroy { + [self->handle release]; + [self->handle dealloc]; + [self->window release]; + [self->window dealloc]; +} + +- (MwLL)getParent { + return self->parent; +} + +- (NSView*)getView { + return view; +} +- (NSWindow*)getWindow { + return window; +} + +- (void)nudge { + self->_eventsPending = MwTRUE; +} + +- (void)pushCursor { + [self->cursor push]; +} +- (void)popCursor { + [self->cursor pop]; +} + +- (MilskoFakePointer*)getHandle { + return handle; +} + +@end + @implementation MilskoCocoaApplication - (void)sendEvent:(NSEvent*)event { self->doPending = MwTRUE; @@ -80,12 +628,13 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { @implementation MilskoCocoaView - (id)initWithFrame:(NSRect)frame { - givenRect = frame; - x = frame.origin.x; - y = frame.origin.y; - width = frame.size.width; - height = frame.size.height; - self = [super initWithFrame:frame]; + givenRect = frame; + x = frame.origin.x; + y = frame.origin.y; + width = frame.size.width; + height = frame.size.height; + self = [super initWithFrame:frame]; + self->space = CGColorSpaceCreateDeviceRGB(); if(width == 0 || height == 0) { self->rep = NULL; @@ -112,10 +661,12 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { } - (void)drawRect:(NSRect)dirtyRect { - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSArray* subviews = [self subviews]; - int i; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSSize sz = [self->rep size]; + MwLL ll = [((MilskoFakePointer*)[[[[self window] contentView] subviews] + objectAtIndex:0]) pointer]; + [super drawRect:dirtyRect]; if(!self->rep) { if(dirtyRect.size.width && dirtyRect.size.height) { [self initRepAndContextWithWidth:dirtyRect.size.width @@ -128,23 +679,23 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { } } - [self->rep drawInRect:NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y, [self->rep pixelsWide], [self->rep pixelsHigh])]; + // MwLLDispatch(ll, draw, NULL); - for(i = 0; i < [subviews count]; i++) { - MilskoCocoaView* subview = [subviews objectAtIndex:i]; - NSRect bounds = [subview bounds]; + [self->rep drawInRect:dirtyRect]; + + for(NSView* subview in [self subviews]) { + NSRect bounds = [subview bounds]; [subview drawRect:bounds]; } + + [self->rep bitmapData]; + [pool release]; } - (void)initRepAndContextWithWidth:(float)w Height:(float)h { - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - self->buf = malloc(w * h * 4); - memset(self->buf, 255, w * h * 4); - self->rep = - [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&self->buf + [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:w pixelsHigh:h bitsPerSample:8 @@ -157,17 +708,14 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { assert(self->rep); [self->rep retain]; - [self->rep setOpaque:MwFALSE]; - [self->rep setAlpha:MwTRUE]; - self->context = [NSGraphicsContext graphicsContextWithBitmapImageRep:self->rep]; assert(self->context); [self->context retain]; - [pool release]; } - (void)destroy { + CGColorSpaceRelease(self->space); [self->rep release]; [self->context release]; } @@ -197,7 +745,6 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { - (void)handleKeyEvent:(NSEvent*)ev ll:(MwLL)ll down:(MwBool)isDown { int ch; - /* todo: consolidate these values into the below switch case. */ enum { kVK_ANSI_A = 0x00, kVK_ANSI_S = 0x01, @@ -421,10 +968,21 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { @end @implementation MilskoCocoaApplicationDelegate -- (MilskoCocoaApplicationDelegate*)initWithAppl:(MilskoCocoaApplication*)_appl { +- (MilskoCocoaApplicationDelegate*)initWithAppl:(NSApplication*)_appl { self->appl = _appl; return self; } +- (void)applicationDidBecomeActive:(NSNotification*)notification { + [self->appl activateIgnoringOtherApps:true]; + // printf("test\n"); +} +- (void)applicationWillFinishLaunching:(NSNotification*)notification { + // printf("test\n"); + // [self->appl activateIgnoringOtherApps:MwTRUE]; +} +- (void)applicationDidFinishLaunching:(NSNotification*)notification { + // [self->appl activateIgnoringOtherApps:MwTRUE]; +} @end @implementation MilskoCocoaWindowDelegate @@ -436,6 +994,7 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { if([ptr isKindOfClass:[MilskoFakePointer class]]) { MwLL h = [(MilskoFakePointer*)ptr pointer]; MwLLDispatch(h, resize, NULL); + // MwLLDispatch(h, draw, NULL); } } return frameSize; @@ -450,19 +1009,24 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { [self->w makeKeyAndOrderFront:nil]; } +- (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]; +} + - (MilskoCocoaWindowDelegate*)initWithWin:(NSWindow*)win { self->w = win; return self; } -- (void)windowWillClose:(NSNotification*)notification { - if([[[w contentView] subviews] count] != 0) { - MwLL h = [((MilskoFakePointer*)[[[w contentView] subviews] - objectAtIndex:0]) pointer]; - MwLLDispatch(h, close, NULL); - } -} - @end @implementation MilskoFakePointer @@ -493,234 +1057,19 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { @end -@implementation MilskoCocoaPixmap -+ (MilskoCocoaPixmap*)newWithWidth:(int)width height:(int)height { - MilskoCocoaPixmap* p = [MilskoCocoaPixmap alloc]; - - p->width = width; - p->height = height; - p->image = NULL; - - p->buf = malloc(width * height * 4); - - p->rep = - [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&p->buf - pixelsWide:(int)width - pixelsHigh:(int)height - bitsPerSample:8 - samplesPerPixel:4 - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSDeviceRGBColorSpace - bytesPerRow:(int)width * 4 - bitsPerPixel:32]; - 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); - if(self->rep) { - [self->image removeRepresentation:self->rep]; - [self->rep release]; - } - self->rep = - [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&self->buf - pixelsWide:(int)width - pixelsHigh:(int)height - bitsPerSample:8 - samplesPerPixel:4 - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSDeviceRGBColorSpace - bytesPerRow:(int)width * 4 - bitsPerPixel:32]; - assert(self->rep); - [self->image addRepresentation:self->rep]; -} -- (void)destroy { - free(self->buf); - [self->image removeRepresentation:self->rep]; - [self->image release]; - [self->rep release]; - self->image = NULL; - self->rep = NULL; -} -- (NSImage*)image { - return self->image; -} -@end - -@implementation MilskoCocoa -- (void)sendClipboardEvent { - /*NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; - NSArray* items = @[ - @"public.utf8-plain-text", - @"public.utf16-external-plain-text", - @"com.apple.traditional-mac-plain-text", - ]; - MwLL this = self->handle.pointer; - - if([pasteboard canReadItemWithDataConformingToTypes:items]) { - char* data = NULL; - size_t size = 0; - for(NSPasteboardItem* item in [pasteboard pasteboardItems]) { - for(NSString* it in items) { - NSString* itemData = [item - stringForType:(NSString*)it]; if(itemData != NULL) { if(strHash != 0 && - strHash != [itemData hash]) { char* text = malloc([itemData length]); - strncpy(text, [itemData UTF8String], - [itemData length]); MwLLDispatch(this, clipboard, text); printf("%s -> %p\n", - text, this); free(text); - } - strHash = [itemData hash]; - } - } - } - } - - [pool release];*/ -} - -- (void)destroy { - [self->handle release]; - [self->window release]; -} - -- (MwLL)getParent { - return self->parent; -} - -- (NSView*)getView { - return view; -} -- (NSWindow*)getWindow { - return window; -} - -- (void)nudge { - MwLL p = self->parent; - self->_eventsPending = MwTRUE; - - if(p) { - [p->cocoa.real->view setNeedsDisplay:true]; - p = p->cocoa.real->parent; - } -} - -- (void)pushCursor { - [self->cursor push]; -} -- (void)popCursor { - [self->cursor pop]; -} - -- (MilskoFakePointer*)getHandle { - return handle; -} - -@end - static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { - MwLL r; - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - MilskoCocoa* c = [MilskoCocoa alloc]; - r = malloc(sizeof(*r)); + MwLL r; + r = malloc(sizeof(*r)); MwLLCreateCommon(r); - [c retain]; - c->application = (MilskoCocoaApplication*)[MilskoCocoaApplication sharedApplication]; - [c->application retain]; - - /* - * MacOS doesn't really have a "default" window position, you're actually - * meant to center the window yourself, so if the user passes MwDEFAULT - * respond appropriately. Also for child windows just have it be 0. - */ - if(x == MwDEFAULT) { - x = r ? ([[NSScreen mainScreen] frame].size.width / 2.) - (width / 2.) : 0; - } - if(y == MwDEFAULT) { - y = r ? ([[NSScreen mainScreen] frame].size.height / 2.) - (height / 2.) - : 0; - } - c->rect = NSMakeRect(x, y, width, height); - - if(parent == NULL) { - c->window = [[NSWindow alloc] - initWithContentRect:rectFlip(c->rect) - styleMask:(NSTitledWindowMask | - NSClosableWindowMask | NSMiniaturizableWindowMask | - NSResizableWindowMask) - backing:NSBackingStoreBuffered - defer:NO]; - [c->window - setDelegate:[[MilskoCocoaWindowDelegate alloc] initWithWin:c->window]]; - [c->window retain]; - - [c->window makeKeyAndOrderFront:c->application]; - [c->window makeFirstResponder:c->view]; - - c->view = [[MilskoCocoaView alloc] initWithFrame:c->rect]; - [c->view retain]; - [c->window setContentView:c->view]; - - /* In order for our application to be front and center when launched, we need to use this function introduced in 10.5. There's no function that works on 10.4 or below as far as I know because what you're actually supposed to do is use a feature of XCode project files to modify the settings of the compiled app to set the activation policy. */ - if([c->application respondsToSelector:@selector(setActivationPolicy:)]) { - [c->application - setActivationPolicy:0 /* NSApplicationActivationPolicyRegular */]; - } - - [c->application activateIgnoringOtherApps:MwTRUE]; - [c->application setDelegate:[[MilskoCocoaApplicationDelegate alloc] - initWithAppl:c->application]]; - [c->application retain]; - - [c->view addTrackingRect:c->rect owner:c->view userData:NULL assumeInside:MwFALSE]; - c->modalSession = [c->application beginModalSessionForWindow:c->window]; - } else { - MilskoCocoa* p = parent->cocoa.real; - NSRect rect = localRectFlip(c->rect, p->view); - - c->window = p->window; - c->view = [[MilskoCocoaView alloc] initWithFrame:rect]; - [c->view setBounds:c->rect]; - [c->view retain]; - [c->view setChild]; - - [c->view addTrackingRect:c->rect owner:c->view userData:NULL assumeInside:MwFALSE]; - - [p->view addSubview:c->view]; - - c->modalSession = p->modalSession; - } - [c->window setAcceptsMouseMovedEvents:MwTRUE]; - - c->handle = [[MilskoFakePointer alloc] initWithFrame:NSMakeRect(0, 0, 1, 1)]; - [c->handle retain]; - [c->handle setPointer:r]; - [c->view addSubview:c->handle]; - - c->parent = parent; - - c->_forceRender = MwTRUE; - c->strHash = 0; - - c->cursorPixmap = NULL; - - [c->application finishLaunching]; - - c->pointerLocked = MwFALSE; - - [pool release]; - - r->cocoa.real = c; + MilskoCocoa* o = [MilskoCocoa newWithParent:parent + x:x + y:y + width:width + height:height + handle:r]; + r->cocoa.real = o; return r; } @@ -745,81 +1094,13 @@ static void MwLLEndDrawImpl(MwLL handle) { static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { - MilskoCocoa* self = handle->cocoa.real; - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSGraphicsContext* ctx = [self->view context]; - if(ctx) { - int i; - NSBezierPath* path = [NSBezierPath bezierPath]; - /* whatever rect we use for coordinate flipping */ - NSRect _rect = self->parent ? [self->view bounds] : [self->window frame]; - - NSColor* nscolor = - [NSColor colorWithCalibratedRed:color->common.red / 255. - green:color->common.green / 255. - blue:color->common.blue / 255. - alpha:1.0]; - - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:ctx]; - - [nscolor setFill]; - for(i = 0; i < points_count; i++) { - NSPoint p = localPointFlip(NSMakePoint(points[i].x, points[i].y), self->view); - if(i == 0) { - [path moveToPoint:p]; - } else { - [path lineToPoint:p]; - } - } - - [path closePath]; - [path fill]; - - [NSGraphicsContext restoreGraphicsState]; - - [self->view setNeedsDisplay:YES]; - } - [pool release]; + MilskoCocoa* h = handle->cocoa.real; + [h polygonWithPoints:points points_count:points_count color:color]; } static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { - MilskoCocoa* self = handle->cocoa.real; - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - NSGraphicsContext* ctx = [self->view context]; - if(ctx) { - int i; - NSBezierPath* path = [NSBezierPath bezierPath]; - /* whatever rect we use for coordinate flipping */ - NSRect _rect = self->parent ? [self->view bounds] : [self->window frame]; - - NSColor* nscolor = - [NSColor colorWithCalibratedRed:color->common.red / 255. - green:color->common.green / 255. - blue:color->common.blue / 255. - alpha:1.0]; - - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:ctx]; - - [nscolor setFill]; - for(i = 0; i < 2; i++) { - NSPoint p = localPointFlip(NSMakePoint(points[i].x, points[i].y), self->view); - if(i == 0) { - [path moveToPoint:p]; - } else { - [path lineToPoint:p]; - } - } - - [path closePath]; - [path stroke]; - - [NSGraphicsContext restoreGraphicsState]; - - [self->view setNeedsDisplay:YES]; - } - [pool release]; + MilskoCocoa* h = handle->cocoa.real; + [h lineWithPoints:points color:color]; } static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { @@ -837,60 +1118,19 @@ static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { } static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, - unsigned int* h) { - MilskoCocoa* self = handle->cocoa.real; - NSRect frame; - if(self->parent) { - frame = [self->view frame]; - } else { - frame = [self->window frame]; - } - frame = rectFlip(frame); - - *x = frame.origin.x; - *y = frame.origin.y; - - *w = frame.size.width; - *h = frame.size.height; + unsigned int* height) { + MilskoCocoa* h = handle->cocoa.real; + [h getX:x Y:y W:w H:height]; } static void MwLLSetXYImpl(MwLL handle, int x, int y) { - MilskoCocoa* self = handle->cocoa.real; - NSRect frame; - if(self->parent) { - frame = [self->view frame]; - } else { - frame = [self->window frame]; - } - - frame.origin.x = x; - frame.origin.y = y; - - if(!self->parent) { - frame = rectFlip(frame); - [self->window setFrame:frame display:MwTRUE animate:MwTRUE]; - } else { - frame = localRectFlip(frame, self->parent->cocoa.real->view); - [self->view setBounds:frame]; - } - [self nudge]; + MilskoCocoa* h = handle->cocoa.real; + [h setX:x Y:y]; } -static void MwLLSetWHImpl(MwLL handle, int w, int h) { - MilskoCocoa* self = handle->cocoa.real; - NSRect frame = [self->window frame]; - frame.size.width = w; - frame.size.height = h; - - self->rect = frame; - - [self->view setFrameSize:frame.size]; - if(self->parent) { - [self->view setFrame:frame]; - } else { - [self->window setFrame:frame display:YES animate:false]; - } - [self nudge]; +static void MwLLSetWHImpl(MwLL handle, int w, int height) { + MilskoCocoa* h = handle->cocoa.real; + [h setW:w H:height]; } static void MwLLFreeColorImpl(MwLLColor color) { @@ -898,52 +1138,28 @@ static void MwLLFreeColorImpl(MwLLColor color) { } static int MwLLPendingImpl(MwLL handle) { - MilskoCocoa* self = handle->cocoa.real; - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - MwBool isPending = [self->application pending]; - [self->application runModalSession:self->modalSession]; - [pool release]; - return self->_forceRender || self->_eventsPending || isPending; + int p = [handle->cocoa.real pending]; + if(p) { + MwLLDispatch(handle, draw, NULL); + } + return p; } static void MwLLNextEventImpl(MwLL handle) { - MilskoCocoa* self = handle->cocoa.real; - MwLL h = [self->handle pointer]; - if(self->_forceRender) { - MwLLDispatch(h, draw, NULL); - self->_forceRender = MwFALSE; - } - if(self->_eventsPending) { - MwLLDispatch(h, draw, NULL); - self->_eventsPending = MwFALSE; - } - [self sendClipboardEvent]; - -#ifdef __APPLE__ - if(self->pointerLocked && [self->window isMainWindow] && self->lastEvent) { - struct CGPoint pos; - pos.x = [self->window frame].origin.x + [self->window frame].size.width / 2; - pos.y = [self->window frame].origin.y + [self->window frame].size.height / 2; - - CGWarpMouseCursorPosition(pos); - } -#endif - - [self->application updateWindows]; + MilskoCocoa* h = handle->cocoa.real; + [h getNextEvent]; } static void MwLLSetTitleImpl(MwLL handle, const char* title) { - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - [handle->cocoa.real->window - setTitleWithRepresentedFilename:[NSString stringWithUTF8String:title]]; - [pool release]; + MilskoCocoa* h = handle->cocoa.real; + [h setTitle:title]; } static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) { - MwLLPixmap r = malloc(sizeof(*r)); - (void)handle; + + MwLLPixmap r = malloc(sizeof(*r)); memset(r, 0, sizeof(*r)); r->common.raw = malloc(4 * width * height); @@ -959,153 +1175,77 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, } static void MwLLPixmapUpdateImpl(MwLLPixmap pixmap) { - MilskoCocoaPixmap* self = pixmap->cocoa.real; - memcpy(self->buf, pixmap->common.raw, pixmap->common.width * pixmap->common.height * 4); - [pixmap->cocoa.real updateWithData:pixmap->common.raw]; + MilskoCocoaPixmap* p = pixmap->cocoa.real; + [p updateWithData:pixmap->common.raw]; } static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { - [pixmap->cocoa.real destroy]; - [pixmap->cocoa.real release]; + MilskoCocoaPixmap* p = pixmap->cocoa.real; + [p destroy]; + [p dealloc]; free(pixmap); } static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { - MilskoCocoa* self = handle->cocoa.real; - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - MilskoCocoaPixmap* p = pixmap->cocoa.real; - NSGraphicsContext* ctx = [self->view context]; - if(ctx) { - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:ctx]; - - [p->image - drawInRect:localRectFlip(NSMakeRect(rect->x, rect->y, rect->width, rect->height), self->view) - fromRect:NSZeroRect - operation:NSCompositeSourceOver - fraction:1.0]; - - [NSGraphicsContext restoreGraphicsState]; - - [self->view setNeedsDisplay:YES]; - } - [pool release]; + MilskoCocoa* h = handle->cocoa.real; + [h drawPixmap:pixmap rect:rect]; MwLLForceRender(handle); } static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { - [handle->cocoa.real->application setApplicationIconImage:[pixmap->cocoa.real image]]; + MilskoCocoa* h = handle->cocoa.real; + [h setIcon:pixmap]; } static void MwLLForceRenderImpl(MwLL handle) { - handle->cocoa.real->_forceRender = MwTRUE; + MilskoCocoa* h = handle->cocoa.real; + [h forceRender]; } static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) { - MilskoCocoa* self = handle->cocoa.real; - int y, x, ys, xs; - unsigned char* di = malloc(image->width * image->height * 4); - memset(di, 0, image->width * image->height * 4); - - if(self->cursorPixmap) { - [self->cursorPixmap destroy]; - } - self->cursorPixmap = - [MilskoCocoaPixmap newWithWidth:image->width - height:image->height]; - - xs = -mask->x + image->x; - ys = MwCursorDataHeight + mask->y; - ys = MwCursorDataHeight + image->y - ys; - - for(y = 0; y < mask->height; y++) { - unsigned int d = mask->data[y]; - for(x = mask->width - 1; x >= 0; x--) { - int px = 0; - int idx = ((y * mask->width) + x) * 4; - - if(d & 1) { - di[idx + 3] = 255; - }; - d = d >> 1; - } - } - for(y = 0; y < image->height; y++) { - unsigned int d = image->data[y]; - for(x = image->width - 1; x >= 0; x--) { - int px = 0; - int idx = ((y * image->width) + x) * 4; - - if(d & 1) { - px = 255; - }; - - di[idx] = px; - di[idx + 1] = px; - di[idx + 2] = px; - d = d >> 1; - } - } - - [self->cursorPixmap updateWithData:di]; - - self->cursor = [[NSCursor alloc] - initWithImage:[self->cursorPixmap image] - hotSpot:NSMakePoint(image->x, image->y + image->height)]; - [self->cursor retain]; - - [self->cursor pop]; - [self->cursor push]; - - free(di); + MilskoCocoa* h = handle->cocoa.real; + [h setCursor:image mask:mask]; } static void MwLLDetachImpl(MwLL handle, MwPoint* point) { - [handle->cocoa.real->window setParentWindow:NULL]; + MilskoCocoa* h = handle->cocoa.real; + [h detachWithPoint:point]; } static void MwLLShowImpl(MwLL handle, int show) { - (void)show; + MilskoCocoa* h = handle->cocoa.real; + [h show:show]; } static void MwLLMakePopupImpl(MwLL handle, MwLL parent) { - (void)parent; + MilskoCocoa* h = handle->cocoa.real; + [h makePopupWithParent:parent]; } static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) { - MilskoCocoa* self = handle->cocoa.real; - [self->window setMinSize:NSMakeSize(minx, miny)]; - [self->window setMaxSize:NSMakeSize(maxx, maxy)]; + MilskoCocoa* h = handle->cocoa.real; + [h setSizeHintsWithMinX:minx MinY:miny MaxX:maxx MaxY:maxy]; } static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) { - MilskoCocoa* self = handle->cocoa.real; - MwU32 mask = [self->window styleMask]; - if(toggle) { - mask ^= NSBorderlessWindowMask; - mask |= NSTitledWindowMask; - } else { - mask |= NSBorderlessWindowMask; - mask ^= NSTitledWindowMask; - } - [self->window initWithContentRect:self->rect - styleMask:mask - backing:NSBackingStoreBuffered - defer:NO]; + MilskoCocoa* h = handle->cocoa.real; + [h makeBorderless:toggle]; } static void MwLLFocusImpl(MwLL handle) { - [handle->cocoa.real->application activateIgnoringOtherApps:MwTRUE]; + MilskoCocoa* h = handle->cocoa.real; + [h focus]; } static void MwLLGrabPointerImpl(MwLL handle, int toggle) { - handle->cocoa.real->pointerLocked = toggle; + MilskoCocoa* h = handle->cocoa.real; + [h grabPointer:toggle]; } static void MwLLSetClipboardImpl(MwLL handle, const char* text) { - (void)handle; - (void)text; + MilskoCocoa* h = handle->cocoa.real; + [h setClipboard:text]; } static void MwLLGetClipboardImpl(MwLL handle) { @@ -1113,26 +1253,19 @@ static void MwLLGetClipboardImpl(MwLL handle) { } static void MwLLMakeToolWindowImpl(MwLL handle) { - /* If my understand of what a "tool window" usually is is correct then I - * highly doubt the Mac OS has this and if they did they probably outright - * removed it along time ago is this kind of conflicts with modern UX. So - * we'll just make it borderless idgaf */ - MwLLMakeBorderlessImpl(handle, 1); + + MilskoCocoa* h = handle->cocoa.real; + [h makeToolWindow]; } static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) { - NSPoint p = [NSEvent mouseLocation]; - point->x = p.x; - point->y = p.y; + MilskoCocoa* h = handle->cocoa.real; + [h getCursorCoord:point]; } static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { - MilskoCocoa* self = handle->cocoa.real; - NSScreen* screen = [self->window screen]; - rect->x = [screen frame].origin.x; - rect->y = [screen frame].origin.y; - rect->width = [screen frame].size.width; - rect->height = [screen frame].size.height; + MilskoCocoa* h = handle->cocoa.real; + [h getScreenSize:rect]; } static void MwLLBeginStateChangeImpl(MwLL handle) { @@ -1144,12 +1277,6 @@ static void MwLLEndStateChangeImpl(MwLL handle) { } static int MwLLCocoaCallInitImpl(void) { -#ifndef __APPLE__ - printf("Using GNUStep Backend\n"); -#endif - - [MilskoCocoaApplication sharedApplication]; - return 0; } diff --git a/src/backend/wayland.c b/src/backend/wayland.c index a1e6a620..df05dce8 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -2646,6 +2646,7 @@ static int MwLLWaylandCallInitImpl(void) { /* * Order of precedence: * - MILSKO_BACKEND + * - XDG_SESSION_TYPE * - manually checking environment variables */ #ifdef __linux__ diff --git a/src/backend/x11.c b/src/backend/x11.c index 42216079..253012da 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -1288,11 +1288,7 @@ static int MwLLX11CallInitImpl(void) { return 1; } -#ifdef __APPLE__ - xsymtbl.lib_xlib = MwDynamicOpen("libX11.dylib"); -#else xsymtbl.lib_xlib = MwDynamicOpen("libX11.so"); -#endif if(!xsymtbl.lib_xlib) { return 1; } diff --git a/src/core.c b/src/core.c index 2b98ec5f..c8a5c12d 100644 --- a/src/core.c +++ b/src/core.c @@ -606,6 +606,7 @@ int MwGetInteger(MwWidget handle, const char* key) { #else if(strcmp(key, MwNmodernLook) == 0) return inherit_integer(handle, key, 1); #endif + if(strcmp(key, MwNisRounded) == 0) return inherit_integer(handle, key, 1); if(strcmp(key, MwNdarkTheme) == 0) return inherit_integer(handle, key, 0); if(strcmp(key, MwNuseMonospace) == 0) return inherit_integer(handle, key, 0); } @@ -855,16 +856,15 @@ MwWidget MwGetParent(MwWidget handle) { typedef int (*call_t)(void); int MwLibraryInit(void) { call_t calls[] = { +#ifdef USE_COCOA + MwLLCocoaCallInit, +#endif #ifdef USE_WAYLAND MwLLWaylandCallInit, #endif -/* x11 has higher priority then cocoa until it works */ #ifdef USE_X11 MwLLX11CallInit, #endif -#ifdef USE_COCOA - MwLLCocoaCallInit, -#endif #ifdef USE_GDI MwLLGDICallInit, #endif diff --git a/src/draw.c b/src/draw.c index f5e1368d..12ccb512 100644 --- a/src/draw.c +++ b/src/draw.c @@ -11,6 +11,10 @@ #include "../external/stb_ds.h" +#define DEFAULT_ROUNDNESS 5 +#define MAX_ROUNDNESS 30 +#define BORDER_SMOOTHNESS 50 + static int get_color_diff(MwWidget handle) { if(MwGetInteger(handle, MwNmodernLook)) { return 40; @@ -102,7 +106,7 @@ void MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color) { MwLLPolygon(handle->lowlevel, p, 4, color); } -void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { +void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color, int rounded) { MwLLPixmap pixmap; int y, i; double darken = 0.; @@ -111,18 +115,17 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { unsigned long sz = 1 * rect->height * 4; unsigned char* data = malloc(sz); MwRect r = *rect; + int roundness = MwGetInteger(handle, MwNroundness); double div; if(rect->width <= 0 || rect->height <= 0) { free(data); return; } + if(roundness == MwDEFAULT) roundness = DEFAULT_ROUNDNESS; + if(roundness >= MAX_ROUNDNESS) roundness = MAX_ROUNDNESS; + div = (roundness <= 10) ? 7. : 10.; memset(data, 0, sz); - r.x += 1; - r.y += 1; - r.width -= 2; - r.height -= 2; - for(y = 0; y < rect->height; y++) { MwLLColor col = MwLightenColor(handle, color, -darken, -darken, -darken); int idx = y * 4; @@ -135,18 +138,42 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { } pixmap = MwLLCreatePixmap(handle->lowlevel, data, 1, rect->height); - MwLLDrawPixmap(handle->lowlevel, &r, pixmap); + if(rounded && rect->height >= (roundness * 2) && rect->width >= (roundness * 2) && roundness > 0) { + for(i = 0; i < roundness; i++) { + int x = (roundness + 2); + int y = rect->y + (roundness + 2); + double point = ((i + (M_PI * 4)) / div); + r.x = (roundness + 4) - (sin(point) * roundness); + r.y = y + (cos(point) * roundness) + 1; + r.width = roundness; + r.height = (rect->height - ((r.y - rect->y) * 2) - 1); + MwLLDrawPixmap(handle->lowlevel, &r, pixmap); + r.width = x + (sin(point + 1) * roundness); + r.x = ((rect->width - (roundness + 1)) + (sin(point) * roundness)) - r.width; + MwLLDrawPixmap(handle->lowlevel, &r, pixmap); + } + + r = *rect; + r.x += roundness; + r.y += 3; + r.width -= (roundness * 2) + 1; + r.height -= 6; + MwLLDrawPixmap(handle->lowlevel, &r, pixmap); + + } else { + MwLLDrawPixmap(handle->lowlevel, &r, pixmap); + } MwLLDestroyPixmap(pixmap); free(data); } -void MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { +void MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int rounded) { int inv; if((inv = MwGetInteger(handle, MwNforceInverted)) != MwDEFAULT && inv) invert = 1; if(MwGetInteger(handle, MwNmodernLook)) { - MwDrawFrameEx(handle, rect, color, invert, MwDefaultBorderWidth(handle), 0, 0); + MwDrawFrameEx(handle, rect, color, invert, MwDefaultBorderWidth(handle), 0, 0, rounded); } else { int diff = get_color_diff(handle) / 3 * 2; @@ -154,17 +181,18 @@ void MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { int i; int st = invert ? 1 : 0; for(i = st; i < st + 2; i++) { - if((i % 2) == 0) MwDrawFrameEx(handle, rect, color, invert, MwDefaultBorderWidth(handle) - 1, -diff, (handle->parent == NULL || handle->parent->lowlevel == NULL) ? 1 : 0); - if((i % 2) == 1) MwDrawFrameEx(handle, rect, color, invert, 1, diff, 0); + if((i % 2) == 0) MwDrawFrameEx(handle, rect, color, invert, MwDefaultBorderWidth(handle) - 1, -diff, (handle->parent == NULL || handle->parent->lowlevel == NULL) ? 1 : 0, 0); + if((i % 2) == 1) MwDrawFrameEx(handle, rect, color, invert, 1, diff, 0, 0); } } else { - MwDrawFrameEx(handle, rect, color, invert, 1, 0, 0); + MwDrawFrameEx(handle, rect, color, invert, 1, 0, 0, 0); } } } void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border) { MwLLColor col; + MwBool rounded = MwGetInteger(handle, MwNroundness) != MwDEFAULT && MwGetInteger(handle, MwNisRounded) != 0; if(rect->width <= 0 || rect->height <= 0) return; @@ -178,11 +206,11 @@ void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert } } - MwDrawFrame(handle, rect, color, invert); + MwDrawFrame(handle, rect, color, invert, rounded); } col = invert ? MwLightenColor(handle, color, -8, -8, -8) : color; if(MwGetInteger(handle, MwNmodernLook)) { - MwDrawRectFading(handle, rect, col); + MwDrawRectFading(handle, rect, col, rounded); } else { MwDrawRect(handle, rect, col); } @@ -256,47 +284,55 @@ void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { MwLLFreeColor(darker); } -static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) { +static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same, int rounded) { MwPoint p[7]; int ColorDiff = get_color_diff(handle); MwLLColor darker = MwLightenColor(handle, color, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff); MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, ColorDiff - diff, ColorDiff - diff, ColorDiff - diff); - p[0].x = rect->x; - p[0].y = rect->y; + int roundness = MwGetInteger(handle, MwNroundness); - p[1].x = rect->x + rect->width; - p[1].y = rect->y; + if(roundness == MwDEFAULT) roundness = DEFAULT_ROUNDNESS; + if(roundness >= MAX_ROUNDNESS) roundness = MAX_ROUNDNESS; + if(!(rounded && rect->height >= (roundness * 2) && rect->width >= (roundness * 2) && roundness > 0)) { + p[0].x = rect->x; + p[0].y = rect->y; - p[2].x = rect->x + rect->width - border; - p[2].y = rect->y + border; - p[3].x = rect->x + border; - p[3].y = rect->y + border; + p[1].x = rect->x + rect->width; + p[1].y = rect->y; - p[4].x = rect->x + border; - p[4].y = rect->y + rect->height - border; + p[2].x = rect->x + rect->width - border; + p[2].y = rect->y + border; + p[3].x = rect->x + border; + p[3].y = rect->y + border; - p[5].x = rect->x; - p[5].y = rect->y + rect->height; + p[4].x = rect->x + border; + p[4].y = rect->y + rect->height - border; + + p[5].x = rect->x; + p[5].y = rect->y + rect->height; + } MwLLPolygon(handle->lowlevel, p, 6, invert ? darker : lighter); - p[0].x = rect->x + rect->width; - p[0].y = rect->y; + if(!(rounded && rect->height >= (roundness * 2) && rect->width >= (roundness * 2) && roundness > 0)) { + p[0].x = rect->x + rect->width; + p[0].y = rect->y; - p[1].x = rect->x + rect->width - border; - p[1].y = rect->y + border; + p[1].x = rect->x + rect->width - border; + p[1].y = rect->y + border; - p[2].x = rect->x + rect->width - border; - p[2].y = rect->y + rect->height - border; + p[2].x = rect->x + rect->width - border; + p[2].y = rect->y + rect->height - border; - p[3].x = rect->x + border; - p[3].y = rect->y + rect->height - border; + p[3].x = rect->x + border; + p[3].y = rect->y + rect->height - border; - p[4].x = rect->x; - p[4].y = rect->y + rect->height; + p[4].x = rect->x; + p[4].y = rect->y + rect->height; - p[5].x = rect->x + rect->width; - p[5].y = rect->y + rect->height; - MwLLPolygon(handle->lowlevel, p, 6, invert ? lighter : darker); + p[5].x = rect->x + rect->width; + p[5].y = rect->y + rect->height; + MwLLPolygon(handle->lowlevel, p, 6, invert ? lighter : darker); + } MwLLFreeColor(lighter); MwLLFreeColor(darker); @@ -307,64 +343,168 @@ static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color, rect->height -= border * 2; } -static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighter, MwLLColor darker, int invert, int border, int diff, int same) { +static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighter, MwLLColor darker, int invert, int border, int diff, int same, int rounded) { MwPoint p[7]; + int roundness = MwGetInteger(handle, MwNroundness); int i; (void)diff; (void)same; - p[0].x = rect->x; - p[0].y = rect->y; + if(roundness == MwDEFAULT) roundness = DEFAULT_ROUNDNESS; + if(roundness >= MAX_ROUNDNESS) roundness = MAX_ROUNDNESS; + if(rounded && rect->height >= (roundness * 4) && rect->width >= (roundness * 4) && roundness > 0) { + /* top left edge */ + for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { + MwPoint line[2]; + double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + int x = rect->x + (roundness + 2); + int y = rect->y + (roundness + 2); - p[1].x = rect->x + rect->width; - p[1].y = rect->y; + line[0].x = x - (sin(point) * roundness); + line[0].y = y + (cos(point) * roundness); + line[1].x = x - (sin(point + 1) * roundness); + line[1].y = y + (cos(point + 1) * roundness); + MwLLLine(handle->lowlevel, line, invert ? lighter : darker); + } - p[2].x = rect->x + rect->width - border; - p[2].y = rect->y + border; - p[3].x = rect->x + border; - p[3].y = rect->y + border; + p[0].x = rect->x + roundness; + p[0].y = rect->y + border; - p[4].x = rect->x + border; - p[4].y = rect->y + rect->height - border; + p[1].x = rect->x + rect->width - border - roundness; + p[1].y = rect->y + border; - p[5].x = rect->x; - p[5].y = rect->y + rect->height; + p[2].x = rect->x + rect->width - border - roundness; + p[2].y = rect->y + border + roundness; + + p[3].x = rect->x + border; + p[3].y = rect->y + border + roundness; + + p[4].x = rect->x + border; + p[4].y = (rect->y + border) + rect->height - roundness; + + p[5].x = rect->x + roundness; + p[5].y = (rect->y + border) + rect->height - roundness; + MwLLPolygon(handle->lowlevel, p, 6, invert ? lighter : darker); + + /* top right edge */ + for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { + MwPoint line[2]; + double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + int x = (rect->x + rect->width) - (roundness + 2); + int y = rect->y + (roundness + 2); + double placeholder = (sin(point) * roundness); + line[0].x = x + placeholder; + line[0].y = y + (cos(point) * roundness); + line[1].x = x + (sin(point + 1) * roundness); + line[1].y = y + (cos(point + 1) * roundness); + MwLLLine(handle->lowlevel, line, invert ? lighter : darker); + } + } else { + p[0].x = rect->x; + p[0].y = rect->y; + + p[1].x = rect->x + rect->width; + p[1].y = rect->y; + + p[2].x = rect->x + rect->width - border; + p[2].y = rect->y + border; + p[3].x = rect->x + border; + p[3].y = rect->y + border; + + p[4].x = rect->x + border; + p[4].y = rect->y + rect->height - border; + + p[5].x = rect->x; + p[5].y = rect->y + rect->height; + } MwLLPolygon(handle->lowlevel, p, 6, invert ? lighter : darker); - p[0].x = rect->x + rect->width; - p[0].y = rect->y; + if(rounded && rect->height >= (roundness * 4) && rect->width >= (roundness * 4) && roundness > 0) { + /* bottom left edge */ + for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { + MwPoint line[2]; + double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + int x = rect->x + (roundness + 2); + int y = (rect->y + rect->height) - (roundness + 2); - p[1].x = rect->x + rect->width - border; - p[1].y = rect->y + border; + line[0].x = x - (sin(point) * roundness); + line[0].y = y - (cos(point) * roundness); + line[1].x = x - (sin(point + 1) * roundness); + line[1].y = y - (cos(point + 1) * roundness); + MwLLLine(handle->lowlevel, line, invert ? lighter : darker); + } + p[0].x = rect->x + roundness; + p[0].y = rect->y + border + roundness; - p[2].x = rect->x + rect->width - border; - p[2].y = rect->y + rect->height - border; + p[1].x = rect->x + rect->width - border; + p[1].y = rect->y + border + roundness; - p[3].x = rect->x + border; - p[3].y = rect->y + rect->height - border; + p[2].x = rect->x + rect->width - border; + p[2].y = rect->y + rect->height - border - roundness; - p[4].x = rect->x; - p[4].y = rect->y + rect->height; + p[3].x = rect->x + rect->width - border - roundness; + p[3].y = rect->y + rect->height - border; - p[5].x = rect->x + rect->width; - p[5].y = rect->y + rect->height; - MwLLPolygon(handle->lowlevel, p, 6, invert ? lighter : darker); + p[4].x = rect->x + border + roundness; + p[4].y = rect->y + rect->height - border; + + p[5].x = rect->x + roundness; + p[5].y = rect->y + rect->height - roundness; + + p[6].x = rect->x + rect->width - border - roundness; + p[6].y = rect->y + rect->height - roundness; + + MwLLPolygon(handle->lowlevel, p, 7, invert ? lighter : darker); + + /* bottom right edge */ + for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { + MwPoint line[2]; + double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + int x = (rect->x + rect->width) - (roundness + 2); + int y = (rect->y + rect->height) - (roundness + 2); + + line[0].x = x + (sin(point) * roundness); + line[0].y = y - (cos(point) * roundness); + line[1].x = x + (sin(point + 1) * roundness); + line[1].y = y - (cos(point + 1) * roundness); + MwLLLine(handle->lowlevel, line, invert ? lighter : darker); + } + } else { + p[0].x = rect->x + rect->width; + p[0].y = rect->y; + + p[1].x = rect->x + rect->width - border; + p[1].y = rect->y + border; + + p[2].x = rect->x + rect->width - border; + p[2].y = rect->y + rect->height - border; + + p[3].x = rect->x + border; + p[3].y = rect->y + rect->height - border; + + p[4].x = rect->x; + p[4].y = rect->y + rect->height; + + p[5].x = rect->x + rect->width; + p[5].y = rect->y + rect->height; + MwLLPolygon(handle->lowlevel, p, 6, invert ? lighter : darker); + } } -static void MwDrawFrameEx_complex(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) { +static void MwDrawFrameEx_complex(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same, int rounded) { int ColorDiff = get_color_diff(handle); MwLLColor darker = MwLightenColor(handle, color, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff); MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff); MwRect r = *rect; - frame_border_complex(handle, rect, lighter, darker, invert, border, diff, same); + frame_border_complex(handle, rect, lighter, darker, invert, border, diff, same, rounded); r.x += 1; r.y += 1; r.width -= 2; r.height -= 2; - frame_border_complex(handle, &r, lighter, darker, !invert, border, diff, same); + frame_border_complex(handle, &r, lighter, darker, !invert, border, diff, same, rounded); MwLLFreeColor(lighter); MwLLFreeColor(darker); @@ -375,11 +515,11 @@ static void MwDrawFrameEx_complex(MwWidget handle, MwRect* rect, MwLLColor color rect->height -= border * 2; } -void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) { +void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same, int rounded) { if(MwGetInteger(handle, MwNmodernLook)) { - MwDrawFrameEx_complex(handle, rect, color, invert, border, diff, same); + MwDrawFrameEx_complex(handle, rect, color, invert, border, diff, same, rounded); } else { - MwDrawFrameEx_simple(handle, rect, color, invert, border, diff, same); + MwDrawFrameEx_simple(handle, rect, color, invert, border, diff, same, rounded); } } diff --git a/src/text/text.c b/src/text/text.c index fec0bb44..f550195c 100644 --- a/src/text/text.c +++ b/src/text/text.c @@ -26,7 +26,6 @@ static int is_bold(MwWidget handle, MwFLFont ttf) { return s; } -#ifdef TTF static int is_monospace(MwWidget handle, MwFLFont ttf) { size_t u = (size_t)ttf; int s; @@ -37,7 +36,6 @@ static int is_monospace(MwWidget handle, MwFLFont ttf) { if(s == MwDEFAULT) return 0; return s; } -#endif #ifdef TTF diff --git a/src/widget/box.c b/src/widget/box.c index a87000f0..0cc8df1f 100644 --- a/src/widget/box.c +++ b/src/widget/box.c @@ -86,7 +86,7 @@ static void draw(MwWidget handle) { r.height = MwGetInteger(handle, MwNheight); if(MwGetInteger(handle, MwNhasBorder)) { - MwDrawFrame(handle, &r, base, MwGetInteger(handle, MwNinverted)); + MwDrawFrame(handle, &r, base, MwGetInteger(handle, MwNinverted), 0); } MwDrawRect(handle, &r, base); diff --git a/src/widget/combobox.c b/src/widget/combobox.c index 22a90060..d52cc250 100644 --- a/src/widget/combobox.c +++ b/src/widget/combobox.c @@ -72,7 +72,7 @@ static void draw(MwWidget handle) { r.y += r.height; r.height = MwDefaultBorderWidth(handle) * 2; - MwDrawFrame(handle, &r, base, 0); + MwDrawFrame(handle, &r, base, 0, 0); MwLLFreeColor(text); MwLLFreeColor(base); diff --git a/src/widget/entry.c b/src/widget/entry.c index bd7dbe1b..3a7aa764 100644 --- a/src/widget/entry.c +++ b/src/widget/entry.c @@ -49,7 +49,7 @@ static void draw(MwWidget handle) { int attr; MwRect currc; - p.x = (r.width - (r.width / w * w)) / 2; + p.x = (r.width - (r.width / w * w)) / 2 + (MwGetInteger(handle, MwNisRounded) ? MwGetInteger(handle, MwNroundness) : 0); p.y = r.height / 2; len = (r.width - p.x * 2) / w; diff --git a/src/widget/frame.c b/src/widget/frame.c index 117b0f8b..3c2ffe99 100644 --- a/src/widget/frame.c +++ b/src/widget/frame.c @@ -22,7 +22,7 @@ static void draw(MwWidget handle) { fr.y = 0; fr.width = MwGetInteger(handle, MwNwidth); fr.height = MwGetInteger(handle, MwNheight); - MwDrawFrame(handle, &fr, base, inverted); + MwDrawFrame(handle, &fr, base, inverted, 0); rr.x = MwDefaultBorderWidth(handle); rr.y = MwDefaultBorderWidth(handle); diff --git a/src/widget/image.c b/src/widget/image.c index 74ee0bfd..cadddb32 100644 --- a/src/widget/image.c +++ b/src/widget/image.c @@ -20,7 +20,7 @@ static void draw(MwWidget handle) { r.width = MwGetInteger(handle, MwNwidth); r.height = MwGetInteger(handle, MwNheight); - if(MwGetInteger(handle, MwNhasBorder)) MwDrawFrame(handle, &r, base, MwGetInteger(handle, MwNinverted)); + if(MwGetInteger(handle, MwNhasBorder)) MwDrawFrame(handle, &r, base, MwGetInteger(handle, MwNinverted), 0); MwDrawRect(handle, &r, base); if(px != NULL) { diff --git a/src/widget/listbox.c b/src/widget/listbox.c index 9960e1d6..b25528fb 100644 --- a/src/widget/listbox.c +++ b/src/widget/listbox.c @@ -210,7 +210,7 @@ static void frame_draw(MwWidget handle) { p.x = MwDefaultBorderWidth(handle); p.y = MwDefaultBorderWidth(handle); - MwDrawFrame(handle, &r, base, 1); + MwDrawFrame(handle, &r, base, 1, 0); MwDrawRect(handle, &r, base2); r = r2; @@ -284,7 +284,7 @@ static void frame_draw(MwWidget handle) { handle->bgcolor = NULL; } - MwDrawFrame(handle, &r, base, 1); + MwDrawFrame(handle, &r, base, 1, 0); MwLLFreeColor(text2); MwLLFreeColor(text); @@ -403,7 +403,7 @@ static void draw(MwWidget handle) { r.y = 0; r.width = get_col_width(lb, i); r.height = MwDefaultBorderWidth(handle) * 2 + MwTextHeight(handle, NULL, "M"); - MwDrawFrame(handle, &r, base, 0); + MwDrawFrame(handle, &r, base, 0, 0); x += MwDefaultBorderWidth(handle); diff --git a/src/widget/menu.c b/src/widget/menu.c index 0808f691..85753f9b 100644 --- a/src/widget/menu.c +++ b/src/widget/menu.c @@ -100,7 +100,7 @@ static void draw(MwWidget handle) { BEGIN_MENU_LOOP; if(m->sub[i]->wsub != NULL || (in_area && handle->pressed)) { - MwDrawFrame(handle, &r, base, MwFALSE); + MwDrawFrame(handle, &r, base, MwFALSE, 0); MwDrawWidgetBack(handle, &r, base, 0, MwFALSE); } diff --git a/src/widget/progressbar.c b/src/widget/progressbar.c index d85a8dda..7be7bffd 100644 --- a/src/widget/progressbar.c +++ b/src/widget/progressbar.c @@ -23,7 +23,7 @@ static void draw(MwWidget handle) { r.width = MwGetInteger(handle, MwNwidth); r.height = MwGetInteger(handle, MwNheight); - MwDrawFrame(handle, &r, base, 1); + MwDrawFrame(handle, &r, base, 1, 0); MwDrawRect(handle, &r, base); w = MwGetInteger(handle, MwNvalue) - MwGetInteger(handle, MwNminValue); w = w / (MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue)); diff --git a/src/widget/separator.c b/src/widget/separator.c index 8fcfc5b7..571c5dfa 100644 --- a/src/widget/separator.c +++ b/src/widget/separator.c @@ -25,7 +25,7 @@ static void draw(MwWidget handle) { r.y = (r.height - 2) / 2; r.height = 2; } - MwDrawFrameEx(handle, &r, base, 1, 1, 0, 0); + MwDrawFrameEx(handle, &r, base, 1, 1, 0, 0, MwGetInteger(handle, MwNmodernLook)); MwLLFreeColor(base); } diff --git a/src/widget/submenu.c b/src/widget/submenu.c index 4990fd21..3b646055 100644 --- a/src/widget/submenu.c +++ b/src/widget/submenu.c @@ -59,7 +59,7 @@ static void draw(MwWidget handle) { rc.x += MwGetInteger(handle, MwNleftPadding); - MwDrawFrameEx(handle, &rc, base, 1, 1, 0, 0); + MwDrawFrameEx(handle, &rc, base, 1, 1, 0, 0, 0); p.y += 2 + 1; } else { diff --git a/src/widget/treeview.c b/src/widget/treeview.c index acc35bf6..16898ef9 100644 --- a/src/widget/treeview.c +++ b/src/widget/treeview.c @@ -64,7 +64,7 @@ static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwTreeViewEntry** const int len = 4; MwDrawRect(handle, &r, col); - MwDrawFrame(handle, &r, base, tree->opened); + MwDrawFrame(handle, &r, base, tree->opened, 0); if(tree->opened) { l[0].x = r.x + (r.width - len) / 2; l[0].y = r.y + r.height / 2; @@ -91,7 +91,7 @@ static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwTreeViewEntry** MwLLLine(handle->lowlevel, &l[0], text); } r = r2; - MwDrawFrame(handle, &r, base, tree->opened); + MwDrawFrame(handle, &r, base, tree->opened, 0); if(col != base) MwLLFreeColor(col); } else { @@ -183,7 +183,7 @@ static void frame_draw(MwWidget handle) { p.x = MwDefaultBorderWidth(handle); p.y = MwDefaultBorderWidth(handle); - MwDrawFrame(handle, &r, base, 1); + MwDrawFrame(handle, &r, base, 1, 0); MwDrawRect(handle, &r, base2); r = r2; @@ -193,7 +193,7 @@ static void frame_draw(MwWidget handle) { recursion(handle, tv->tree[i], tv->tree, base, text, base2, text2, &p, 0, LineSpace, &skip, &shared, 1, NULL); } - MwDrawFrame(handle, &r, base, 1); + MwDrawFrame(handle, &r, base, 1, 0); MwLLFreeColor(text2); MwLLFreeColor(text); diff --git a/src/widget/window.c b/src/widget/window.c index 979e073c..74a96e61 100644 --- a/src/widget/window.c +++ b/src/widget/window.c @@ -18,7 +18,7 @@ static void draw(MwWidget handle) { r.width = MwGetInteger(handle, MwNwidth); r.height = MwGetInteger(handle, MwNheight); - if(MwGetInteger(handle, MwNhasBorder)) MwDrawFrame(handle, &r, c, MwGetInteger(handle, MwNinverted)); + if(MwGetInteger(handle, MwNhasBorder)) MwDrawFrame(handle, &r, c, MwGetInteger(handle, MwNinverted), 0); MwDrawRect(handle, &r, c);