diff --git a/ChangeLog b/ChangeLog index d505ebc..f17a4a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2012-10-14 Fred Kiefer + + * Source/win32/w32_create.m (-decodeWM_CREATEParams:::): Call + windowbacking:: instead of handling backingstore here. + Merge some changes from testplant branch + * Source/win32/WIN32Server.m : Fix for fatal exceptions when a nil + mouse event tried to post + Patch by Jonathan Gillaspie + * Source/gsc/GSGState.m (-description), + * Source/cairo/CairoGState.m (-description): Add this method. + * Headers/win32/WIN32Server.h - Added a mutable array for storing + multiple screen information from GDI screen lookup + * Source/win32/WIN32Server.m - Added startup sequence to invoke + GDI functions to look up multiple screen/monitor information + * Source/gsc/GSGState.m: Fix compiler warnings + Patch by Marcian Lytwyn + 2012-09-28 Fred Kiefer * Source/gsc/GSStreamContext.m (-GSShowGlyphsWithAdvances:): Add diff --git a/Headers/win32/WIN32Server.h b/Headers/win32/WIN32Server.h index 6b6fa14..a530e85 100644 --- a/Headers/win32/WIN32Server.h +++ b/Headers/win32/WIN32Server.h @@ -93,6 +93,7 @@ typedef struct w32serverFlags { HWND desiredFocus; HWND currentActive; HICON currentAppIcon; + NSMutableArray *monitorInfo; } - (BOOL) handlesWindowDecorations; diff --git a/Source/cairo/CairoGState.m b/Source/cairo/CairoGState.m index 6232860..425fcbf 100644 --- a/Source/cairo/CairoGState.m +++ b/Source/cairo/CairoGState.m @@ -122,6 +122,12 @@ static inline float floatToUserSpace(NSAffineTransform *ctm, double d) [super dealloc]; } +- (NSString*) description +{ + return [NSString stringWithFormat: @"%@ surface: %@ context: %p", + [super description], _surface, _ct]; +} + - (id) copyWithZone: (NSZone *)zone { CairoGState *copy = (CairoGState *)[super copyWithZone: zone]; @@ -491,6 +497,7 @@ static inline float floatToUserSpace(NSAffineTransform *ctm, double d) if (_ct) { cairo_destroy(_ct); + _ct = NULL; } if (!_surface) { diff --git a/Source/gsc/GSGState.m b/Source/gsc/GSGState.m index a2be4b9..fbc5db5 100644 --- a/Source/gsc/GSGState.m +++ b/Source/gsc/GSGState.m @@ -101,6 +101,12 @@ return self; } +- (NSString*) description +{ + return [NSString stringWithFormat: @"%@ drawcontext: %@ ctm: %@", + [super description], drawcontext, ctm]; +} + - copyWithZone: (NSZone *)zone { GSGState *new = (GSGState *)NSCopyObject(self, 0, zone); @@ -299,7 +305,7 @@ { device_color_t col; - ASSIGN(fillColorS, spaceref); + ASSIGN(fillColorS, (NSColorSpace*)spaceref); gsMakeColor(&col, rgb_colorspace, 0, 0, 0, 0); // Keep the old alpha value col.field[AINDEX] = fillColor.field[AINDEX]; @@ -310,7 +316,7 @@ { device_color_t col; - ASSIGN(strokeColorS, spaceref); + ASSIGN(strokeColorS, (NSColorSpace*)spaceref); gsMakeColor(&col, rgb_colorspace, 0, 0, 0, 0); // Keep the old alpha value col.field[AINDEX] = fillColor.field[AINDEX]; diff --git a/Source/win32/WIN32Server.m b/Source/win32/WIN32Server.m index 2bf64ac..0544738 100644 --- a/Source/win32/WIN32Server.m +++ b/Source/win32/WIN32Server.m @@ -75,6 +75,81 @@ static NSEvent *process_mouse_event(WIN32Server *svr, LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +@interface W32DisplayMonitorInfo : NSObject +{ + HMONITOR _hMonitor; + RECT _rect; + NSRect _frame; +} + +- (id)initWithHMonitor:(HMONITOR)hMonitor rect:(LPRECT)lprcMonitor; +- (HMONITOR)hMonitor; +- (RECT)rect; +- (NSRect)frame; +- (void)setFrame:(NSRect)frame; + +@end + +@implementation W32DisplayMonitorInfo + +- (id) initWithHMonitor: (HMONITOR)hMonitor rect: (LPRECT)lprcMonitor +{ + self = [self init]; + if (self) + { + CGFloat w = lprcMonitor->right - lprcMonitor->left; + CGFloat h = lprcMonitor->bottom - lprcMonitor->top; + CGFloat x = lprcMonitor->left; + CGFloat y = h - lprcMonitor->bottom; + _frame = NSMakeRect(x, y, w, h); + memcpy(&_rect, lprcMonitor, sizeof(RECT)); + } + return self; +} + +- (HMONITOR) hMonitor +{ + return _hMonitor; +} + +- (RECT) rect +{ + return _rect; +} + +- (NSRect) frame +{ + return _frame; +} + +- (void) setFrame: (NSRect)frame +{ + _frame = frame; +} + +@end + +BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, + HDC hdcMonitor, + LPRECT lprcMonitor, + LPARAM dwData) +{ + NSMutableArray *monitors = (NSMutableArray*)dwData; + W32DisplayMonitorInfo *info = [[W32DisplayMonitorInfo alloc] + initWithHMonitor: hMonitor + rect: lprcMonitor]; + + NSDebugLog(@"screen %ld:hdc: %ld frame:top:%ld left:%ld right:%ld bottom:%ld frame:x:%f y:%f w:%f h:%f\n", + [monitors count], (long)hMonitor, + lprcMonitor->top, lprcMonitor->left, + lprcMonitor->right, lprcMonitor->bottom, + [info frame].origin.x, [info frame].origin.y, + [info frame].size.width, [info frame].size.height); + [monitors addObject:info]; + + return TRUE; +} + @implementation WIN32Server - (BOOL) handlesWindowDecorations @@ -258,6 +333,9 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, [self _initWin32Context]; [super initWithAttributes: info]; + monitorInfo = [NSMutableArray array]; + EnumDisplayMonitors(NULL, NULL, (MONITORENUMPROC)LoadDisplayMonitorInfo, (LPARAM)monitorInfo); + [self setupRunLoopInputSourcesForMode: NSDefaultRunLoopMode]; [self setupRunLoopInputSourcesForMode: NSConnectionReplyMode]; [self setupRunLoopInputSourcesForMode: NSModalPanelRunLoopMode]; @@ -294,7 +372,7 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, if ([defs objectForKey: @"GSBackUsesNativeTaskbar"]) { [self setUsesNativeTaskbar: - [defs boolForKey: @"GSUseNativeTaskbar"]]; + [defs boolForKey: @"GSBackUsesNativeTaskbar"]]; } } } @@ -375,20 +453,35 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, - (NSRect) boundsForScreen: (int)screen { - return NSMakeRect(0, 0, GetSystemMetrics(SM_CXSCREEN), - GetSystemMetrics(SM_CYSCREEN)); + if (screen < [monitorInfo count]) + { + return [[monitorInfo objectAtIndex:screen] frame]; + } + return NSZeroRect; } - (NSWindowDepth) windowDepthForScreen: (int)screen { - HDC hdc; - int bits; + HDC hdc = 0; + int bits = 0; //int planes; - hdc = GetDC(NULL); - bits = GetDeviceCaps(hdc, BITSPIXEL) / 3; - //planes = GetDeviceCaps(hdc, PLANES); - //NSLog(@"bits %d planes %d", bits, planes); + if (screen < [monitorInfo count]) + { + MONITORINFOEX mix = { 0 }; + mix.cbSize = sizeof(MONITORINFOEX); + HMONITOR hMonitor = [[monitorInfo objectAtIndex: screen] hMonitor]; + + if (GetMonitorInfo(hMonitor, (LPMONITORINFO)&mix)) + { + hdc = CreateDC("DISPLAY", mix.szDevice, NULL, NULL); + bits = GetDeviceCaps(hdc, BITSPIXEL) / 3; + //planes = GetDeviceCaps(hdc, PLANES); + //NSLog(@"bits %d planes %d", bits, planes); + ReleaseDC(NULL, hdc); + } + } + ReleaseDC(NULL, hdc); return (_GSRGBBitValue | bits); @@ -410,7 +503,15 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, - (NSArray *) screenList { - return [NSArray arrayWithObject: [NSNumber numberWithInt: 0]]; + NSInteger index; + NSInteger nMonitors = [monitorInfo count]; + NSMutableArray *screenList = [NSMutableArray arrayWithCapacity: nMonitors]; + + for (index = 0; index < nMonitors; ++index) + { + [screenList addObject: [NSNumber numberWithInt: index]]; + } + return [[screenList copy] autorelease]; } /** @@ -2014,7 +2115,8 @@ process_mouse_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, { e = process_mouse_event(svr, hwnd, wParam, lParam, NSLeftMouseDown, uMsg); - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } eventType = NSLeftMouseDragged; } @@ -2024,13 +2126,15 @@ process_mouse_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, { e = process_mouse_event(svr, hwnd, wParam, lParam, NSLeftMouseUp, uMsg); - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } if (rDown == NO) { e = process_mouse_event(svr, hwnd, wParam, lParam, NSRightMouseDown, uMsg); - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } eventType = NSRightMouseDragged; } @@ -2040,19 +2144,22 @@ process_mouse_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, { e = process_mouse_event(svr, hwnd, wParam, lParam, NSLeftMouseUp, uMsg); - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } if (rDown == YES) { e = process_mouse_event(svr, hwnd, wParam, lParam, NSRightMouseUp, uMsg); - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } if (oDown == NO) { e = process_mouse_event(svr, hwnd, wParam, lParam, NSOtherMouseDown, uMsg); - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } eventType = NSOtherMouseDragged; } @@ -2062,19 +2169,22 @@ process_mouse_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, { e = process_mouse_event(svr, hwnd, wParam, lParam, NSLeftMouseUp, uMsg); - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } if (rDown == YES) { e = process_mouse_event(svr, hwnd, wParam, lParam, NSRightMouseUp, uMsg); - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } if (oDown == YES) { e = process_mouse_event(svr, hwnd, wParam, lParam, NSOtherMouseUp, uMsg); - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } } } diff --git a/Source/win32/w32_create.m b/Source/win32/w32_create.m index 5b461f3..0329e4c 100644 --- a/Source/win32/w32_create.m +++ b/Source/win32/w32_create.m @@ -56,42 +56,23 @@ is stored in the extra fields for this window. Drawing operations work on this buffer. */ win = malloc(sizeof(WIN_INTERN)); + memset(win, 0, sizeof(WIN_INTERN)); + win->useHDC = NO; SetWindowLong(hwnd, GWL_USERDATA, (int)win); - - if (type != NSBackingStoreNonretained) - { - HDC hdc, hdc2; - HBITMAP hbitmap; - RECT r; - GetClientRect((HWND)hwnd, &r); - hdc = GetDC(hwnd); - hdc2 = CreateCompatibleDC(hdc); - hbitmap = CreateCompatibleBitmap(hdc, r.right - r.left, - r.bottom - r.top); - win->old = SelectObject(hdc2, hbitmap); - - win->hdc = hdc2; - win->useHDC = YES; - - ReleaseDC(hwnd, hdc); - } - else - { - win->useHDC = NO; - } + [self windowbacking: type : (int)hwnd]; // Find the icon file, assume it has the same name as the "icon" which // was specified in the bundle's dictionary... iconName = [[bundle infoDictionary] objectForKey: @"NSIcon"]; - if(iconName == nil) + if (iconName == nil) { iconName = [[bundle infoDictionary] objectForKey: @"CFBundleIconFile"]; } // If the icon name is set, get the path... - if(iconName != nil) + if (iconName != nil) { iconName = [iconName stringByDeletingPathExtension]; iconPath = [[NSBundle mainBundle] pathForResource: iconName @@ -101,7 +82,7 @@ // If the path is set, load the icon file and set it as the // icon on the window. - if(iconPath != nil) + if (iconPath != nil) { HICON icon = NULL; const char *cpath = [iconPath cString]; @@ -110,7 +91,7 @@ cpath, IMAGE_ICON,0,0, LR_DEFAULTSIZE|LR_LOADFROMFILE); - SetClassLongPtr(hwnd,GCLP_HICON,(LONG_PTR)icon); + SetClassLongPtr(hwnd,GCLP_HICON, (LONG_PTR)icon); } return 0;