diff --git a/ChangeLog b/ChangeLog index f17a4a0..fd9f6e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2012-11-26 00:37-EST Gregory John Casamento + + * ChangeLog + * config.h.in + * configure + * configure.ac + * Headers/win32/WIN32Server.h + * Source/cairo/CairoContext.m + * Source/cairo/CairoGState.m + * Source/cairo/CairoPDFSurface.m + * Source/cairo/GNUmakefile + * Source/cairo/Win32CairoSurface.m + * Source/GSBackend.m + * Source/gsc/GSGState.m + * Source/win32/w32_create.m + * Source/win32/w32_general.m + * Source/win32/w32_GLcontext.m + * Source/win32/w32_movesize.m + * Source/win32/w32_windowdisplay.m + * Source/win32/WIN32Server.m + * Source/winlib/GNUmakefile.preamble: Merge of all testplant + branch changes to trunk for Cairo changes. Did code cleanup to + make the code conform to coding standards. + +2012-10-24 Doug Simons + + * Source/win32/WIN32Server.m : Fix findWindowAt:windowRef:excluding: + to skip windows with the ignoresMouseEvents property set. + 2012-10-14 Fred Kiefer * Source/win32/w32_create.m (-decodeWM_CREATEParams:::): Call @@ -15,6 +44,11 @@ * Source/gsc/GSGState.m: Fix compiler warnings Patch by Marcian Lytwyn +2012-10-10 Jonathan Gillaspie + + * Source/win32/WIN32Server.m : Fix for fatal exceptions when a + nil mouse event tried to post + 2012-09-28 Fred Kiefer * Source/gsc/GSStreamContext.m (-GSShowGlyphsWithAdvances:): Add @@ -45,6 +79,30 @@ * Source/x11/XGGLContext.m: Implement 10.6 methods to get/set the CGLContextObj. +2012-08-08 Marcian Lytwyn + + *** Modifications/fixes for cairo support on win32 *** + * Headers/win32/Win32CairoGState.h - NEW + * Source/win32/Win32CairoGState.m - NEW + * Headers/win32/WIN32Server.h + * Source/gsc/GSGState.m: Fix compiler warnings + * Source/win32/WIN32Server.m + * Source/win32/w32_create.m + * Source/win32/Win32CairoSurface.m + * Source/cairo/GNUmakefile + * Source/cairo/CairoContext.m + * configure + * configure.ac + +2012-06-27 Marcian Lytwyn + + *** Modifications to Win32 server backend to support multiple + monitors. + * 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 + 2012-06-21 Eric Wasylishen * configure.ac: use AC_CHECK_LIB to check for cairo if pkg-config @@ -53,13 +111,13 @@ 2012-05-14 Quentin Mathe - * Source/gsc/GSContext.m (+initialize): Protected +initialize from being - called multiple times because of subclasses. As a result, this - eliminates a gtable memory leak (e.g. +initialize sent to both GSContext - and CairoContext at backend initialization time), and prevents the - gstate stack to be reset while still in use (e.g. the program enumerates - classes at runtime and sends messages to them... +initialize might be - sent to GSStreamContext in such a case). + * Source/gsc/GSContext.m (+initialize): Protected +initialize from being + called multiple times because of subclasses. As a result, this + eliminates a gtable memory leak (e.g. +initialize sent to both GSContext + and CairoContext at backend initialization time), and prevents the + gstate stack to be reset while still in use (e.g. the program enumerates + classes at runtime and sends messages to them... +initialize might be + sent to GSStreamContext in such a case). 2012-05-12 Eric Wasylishen diff --git a/Headers/win32/WIN32Server.h b/Headers/win32/WIN32Server.h index a530e85..a134e89 100644 --- a/Headers/win32/WIN32Server.h +++ b/Headers/win32/WIN32Server.h @@ -53,7 +53,7 @@ #include #include - +#include #include /* @@ -76,10 +76,11 @@ DWORD windowStyleForGSStyle(unsigned int style); -typedef struct w32serverFlags { - BOOL HOLD_MINI_FOR_SIZE; // override GS size event on miniturize - BOOL _eventHandled; // did we handle the event? - } serverFlags; +typedef struct w32serverFlags +{ + BOOL HOLD_MINI_FOR_SIZE; // override GS size event on miniturize + BOOL _eventHandled; // did we handle the event? +} serverFlags; @interface WIN32Server : GSDisplayServer { @@ -136,6 +137,7 @@ typedef struct w32serverFlags { - (void) decodeWM_WINDOWPOSCHANGINGParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd; - (void) decodeWM_WINDOWPOSCHANGEDParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd; - (LRESULT) decodeWM_GETMINMAXINFOParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd; +- (LRESULT) decodeWM_ENTERSIZEMOVEParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd; - (LRESULT) decodeWM_EXITSIZEMOVEParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd; - (LRESULT) decodeWM_MOVINGParams: (HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam; - (LRESULT) decodeWM_SIZINGParams: (HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam; @@ -187,9 +189,31 @@ typedef struct w32serverFlags { // Extra window data accessed via GetWindowLong -#define OFF_LEVEL 0 -#define OFF_ORDERED sizeof(DWORD) -#define WIN_EXTRABYTES (2*sizeof(DWORD)) +enum _WIN_EXTRA_BYTES +{ + OFF_LEVEL = 0, + OFF_ORDERED = OFF_LEVEL + sizeof(DWORD), + IME_INFO = OFF_ORDERED + sizeof(DWORD), + WIN_EXTRABYTES = IME_INFO + sizeof(DWORD) +}; + + +// Pointer to this struct set in IME_INFO extra bytes space for +// handling IME composition processing between various windows... +typedef struct IME_INFO_S +{ + DWORD isOpened; + BOOL isComposing; + + LPVOID readString; + DWORD readStringLength; + LPVOID compString; + DWORD compStringLength; + + DWORD compositionMode; + DWORD sentenceMode; +} IME_INFO_T; + // Extra window data allocated using objc_malloc in WM_CREATE and accessed via // the GWL_USERDATA pointer @@ -200,7 +224,10 @@ typedef struct _win_intern { HDC hdc; HGDIOBJ old; MINMAXINFO minmax; + NSBackingStoreType type; +#if (BUILD_GRAPHICS==GRAPHICS_cairo) + void *surface; +#endif } WIN_INTERN; - #endif /* _WIN32Server_h_INCLUDE */ diff --git a/Source/GSBackend.m b/Source/GSBackend.m index b417779..ffc16e8 100644 --- a/Source/GSBackend.m +++ b/Source/GSBackend.m @@ -55,7 +55,7 @@ + (void) initializeBackend { Class contextClass; - NSString *context; + NSString *context = nil; NSUserDefaults *defs = [NSUserDefaults standardUserDefaults]; /* Load in only one server */ @@ -70,23 +70,35 @@ /* The way the frontend is currently structured it's not possible to have more than one */ - context = [NSString stringWithCString: STRINGIFY(BUILD_GRAPHICS)]; /* What backend context? */ if ([defs stringForKey: @"GSContext"]) context = [defs stringForKey: @"GSContext"]; - - if ([context isEqual: @"xdps"]) - contextClass = NSClassFromString(@"NSDPSContext"); - else if ([context isEqual: @"art"]) - contextClass = NSClassFromString(@"ARTContext"); - else if ([context isEqual: @"winlib"]) - contextClass = NSClassFromString(@"WIN32Context"); - else if ([context isEqual: @"cairo"]) - contextClass = NSClassFromString(@"CairoContext"); - else - contextClass = NSClassFromString(@"XGContext"); - + + if ((context == nil) || ([context length] == 0)) + { +#if (BUILD_GRAPHICS==GRAPHICS_xdps) + context = @"NSDPSContext"; +#elif (BUILD_GRAPHICS==GRAPHICS_art) + context = @"ARTContext"; +#elif (BUILD_GRAPHICS==GRAPHICS_xlib) + context = @"XGContext"; +#elif (BUILD_GRAPHICS==GRAPHICS_winlib) + context = @"WIN32Context"; +#elif (BUILD_GRAPHICS==GRAPHICS_cairo) + context = @"CairoContext"; +#else +#error INVALID build graphics type +#endif + } + + // Reference the requested build time class... + contextClass = NSClassFromString(context); + if (contextClass == nil) + { + NSLog(@"%s:Backend context class missing for: %@\n", __PRETTY_FUNCTION__, context); + exit(1); + } [contextClass initializeBackend]; } diff --git a/Source/cairo/CairoContext.m b/Source/cairo/CairoContext.m index 30bea99..423c6b6 100644 --- a/Source/cairo/CairoContext.m +++ b/Source/cairo/CairoContext.m @@ -31,7 +31,6 @@ #include #include "cairo/CairoContext.h" -#include "cairo/CairoGState.h" #include "cairo/CairoSurface.h" #include "cairo/CairoPSSurface.h" #include "cairo/CairoPDFSurface.h" @@ -42,7 +41,9 @@ #define CGSTATE ((CairoGState *)gstate) #if BUILD_SERVER == SERVER_x11 +# include "cairo/CairoGState.h" # include "x11/XGServer.h" +# define _CAIRO_GSTATE_CLASSNAME CairoGState # ifdef USE_GLITZ # define _CAIRO_SURFACE_CLASSNAME XGCairoGlitzSurface # include "cairo/XGCairoGlitzSurface.h" @@ -57,7 +58,9 @@ # include "x11/XGServerWindow.h" # include "x11/XWindowBuffer.h" #elif BUILD_SERVER == SERVER_win32 +# include "cairo/Win32CairoGState.h" # include +# define _CAIRO_GSTATE_CLASSNAME Win32CairoGState # ifdef USE_GLITZ # define _CAIRO_SURFACE_CLASSNAME Win32CairoGlitzSurface # include "cairo/Win32CairoGlitzSurface.h" @@ -92,7 +95,7 @@ + (Class) GStateClass { - return [CairoGState class]; + return [_CAIRO_GSTATE_CLASSNAME class]; } + (BOOL) handlesPS @@ -120,23 +123,27 @@ #endif // BUILD_SERVER = SERVER_x11 } -#if BUILD_SERVER == SERVER_x11 /* Private backend methods */ + (void) handleExposeRect: (NSRect)rect forDriver: (void *)driver { +#if BUILD_SERVER == SERVER_x11 if ([(id)driver isKindOfClass: [XWindowBuffer class]]) { // For XGCairoXImageSurface [(XWindowBuffer *)driver _exposeRect: rect]; } - else if ([(id)driver isKindOfClass: [CairoSurface class]]) + else +#endif + if ([(id)driver isKindOfClass: [CairoSurface class]]) { // For XGCairoModernSurface [(CairoSurface *)driver handleExposeRect: rect]; } } +#if BUILD_SERVER == SERVER_x11 + #ifdef XSHM + (void) _gotShmCompletion: (Drawable)d @@ -292,3 +299,5 @@ @end #undef _CAIRO_SURFACE_CLASSNAME +#undef _CAIRO_GSTATE_CLASSNAME + diff --git a/Source/cairo/CairoGState.m b/Source/cairo/CairoGState.m index 425fcbf..297202e 100644 --- a/Source/cairo/CairoGState.m +++ b/Source/cairo/CairoGState.m @@ -1,3 +1,4 @@ + /* CairoGState.m @@ -124,8 +125,10 @@ static inline float floatToUserSpace(NSAffineTransform *ctm, double d) - (NSString*) description { - return [NSString stringWithFormat: @"%@ surface: %@ context: %p", - [super description], _surface, _ct]; + NSMutableString *description = [[[super description] mutableCopy] autorelease]; + [description appendFormat: @" surface: %@",_surface]; + [description appendFormat: @" context: %p",_ct]; + return [[description copy] autorelease]; } - (id) copyWithZone: (NSZone *)zone @@ -1257,6 +1260,8 @@ _set_op(cairo_t *ct, NSCompositingOperation op) cairo_pattern_t *cpattern; cairo_matrix_t source_matrix; + NSDebugMLLog(@"CairoGState", @"%self: %@\n", self); + if (!_ct || !source->_ct) { return; @@ -1379,6 +1384,11 @@ doesn't support to use the receiver cairo target as the source. */ cairo_matrix_t local_matrix; cairo_matrix_t source_matrix; + NSDebugMLLog(@"CairoGState", @"source: %@ fromRect: %@ toPoint: %@\n", + source, + NSStringFromRect(aRect), + NSStringFromPoint(aPoint)); + if (!_ct || !source->_ct) { NSLog(@"WARNING: -drawGState called with a NULL target context (%p) or source context (%p)", diff --git a/Source/cairo/CairoPDFSurface.m b/Source/cairo/CairoPDFSurface.m index a603489..6c543a1 100644 --- a/Source/cairo/CairoPDFSurface.m +++ b/Source/cairo/CairoPDFSurface.m @@ -58,13 +58,13 @@ cairo_pdf_surface_set_size(_surface, size.width, size.height); } -- (void) writeComment: (NSString *)comment -{ -} - - (BOOL) isDrawingToScreen { return NO; } +- (void) writeComment: (NSString *)comment +{ +} + @end diff --git a/Source/cairo/GNUmakefile b/Source/cairo/GNUmakefile index 1609c8f..c3538f2 100644 --- a/Source/cairo/GNUmakefile +++ b/Source/cairo/GNUmakefile @@ -49,7 +49,7 @@ else ifeq ($(WITH_GLITZ),yes) cairo_OBJC_FILES += Win32CairoGlitzSurface.m else - cairo_OBJC_FILES += Win32CairoSurface.m + cairo_OBJC_FILES += Win32CairoSurface.m Win32CairoGState.m # Win32CairoXImageSurface.m endif endif diff --git a/Source/cairo/Win32CairoSurface.m b/Source/cairo/Win32CairoSurface.m index cc9412f..beac9ed 100644 --- a/Source/cairo/Win32CairoSurface.m +++ b/Source/cairo/Win32CairoSurface.m @@ -27,47 +27,240 @@ */ #include "cairo/Win32CairoSurface.h" +#include "win32/WIN32Geometry.h" #include #define GSWINDEVICE ((HWND)gsDevice) @implementation Win32CairoSurface + - (id) initWithDevice: (void *)device { - HDC hDC; - WIN_INTERN *win; + // Save/set initial state... gsDevice = device; - - win = (WIN_INTERN *)GetWindowLong(GSWINDEVICE, GWL_USERDATA); - if (win && win->useHDC) - hDC = win->hdc; - else - hDC = GetDC(GSWINDEVICE); + _surface = NULL; - if (!hDC) - { - NSLog(@"Win32CairoSurface : %d : no device context",__LINE__); - exit(1); - } + WIN_INTERN *win = (WIN_INTERN *)GetWindowLong(GSWINDEVICE, GWL_USERDATA); + HDC hDC = GetDC(GSWINDEVICE); - _surface = cairo_win32_surface_create(hDC); - if (!(win && win->useHDC)) - ReleaseDC(GSWINDEVICE, hDC); - if (cairo_surface_status(_surface)) + if (hDC == NULL) { + NSWarnMLog(@"Win32CairoSurface line: %d : no device context", __LINE__); + + // And deallocate ourselves... DESTROY(self); } + else + { + // Create the cairo surfaces... + // NSBackingStoreRetained works like Buffered since 10.5 (See apple docs)... + // NOTE: According to Apple docs NSBackingStoreBuffered should be the only one + // ever used anymore....others are NOT recommended... + if (win && (win->type == NSBackingStoreNonretained)) + { + // This is the raw DC surface... + _surface = cairo_win32_surface_create(hDC); + // Check for error... + if (cairo_surface_status(_surface) != CAIRO_STATUS_SUCCESS) + { + // Output the surface create error... + cairo_status_t status = cairo_surface_status(_surface); + NSWarnMLog(@"surface create FAILED - status: %s\n", cairo_status_to_string(status)); + + // Destroy the initial surface created... + cairo_surface_destroy(_surface); + + // And deallocate ourselves... + DESTROY(self); + } + } + else + { + NSSize csize = [self size]; + + // This is the raw DC surface... + cairo_surface_t *window = cairo_win32_surface_create(hDC); + + // Check for error... + if (cairo_surface_status(window) != CAIRO_STATUS_SUCCESS) + { + // Output the surface create error... + cairo_status_t status = cairo_surface_status(window); + NSWarnMLog(@"surface create FAILED - status: %s\n", cairo_status_to_string(status)); + + // And deallocate ourselves... + DESTROY(self); + } + else + { + // and this is the in-memory DC surface...surface owns its DC... + // NOTE: For some reason we get an init sequence with zero width/height, + // which creates problems in the cairo layer. It tries to clear + // the 'similar' surface it's creating, and with a zero width/height + // it incorrectly thinks the clear failed...so we will init with + // a minimum size of 1 for width/height... + _surface = cairo_surface_create_similar(window, CAIRO_CONTENT_COLOR_ALPHA, + MAX(1, csize.width), + MAX(1, csize.height)); + + // Check for error... + if (cairo_surface_status(_surface) != CAIRO_STATUS_SUCCESS) + { + // Output the surface create error... + cairo_status_t status = cairo_surface_status(_surface); + NSWarnMLog(@"surface create FAILED - status: %s\n", cairo_status_to_string(status)); + + // Destroy the surface created... + cairo_surface_destroy(_surface); + + // And deallocate ourselves... + DESTROY(self); + } + } + + // Destroy the initial surface created... + cairo_surface_destroy(window); + + // Release the device context... + ReleaseDC(GSWINDEVICE, hDC); + } + + if (self) + { + // We need this for handleExposeEvent in WIN32Server... + win->surface = (void*)self; + } + } return self; } +- (void) dealloc +{ + if ((_surface == NULL) || (cairo_surface_status(_surface) != CAIRO_STATUS_SUCCESS)) + { + NSWarnMLog(@"null surface or bad status\n"); + } + else + { + if (cairo_win32_surface_get_dc(_surface) == NULL) + { + NSWarnMLog(@"HDC is NULL for surface: %@\n", self); + } + else + { + ReleaseDC(GSWINDEVICE, cairo_win32_surface_get_dc(_surface)); + } + } + [super dealloc]; +} + +- (NSString*) description +{ + HDC shdc = NULL; + if (_surface) + { + shdc = cairo_win32_surface_get_dc(_surface); + } + NSMutableString *description = AUTORELEASE([[super description] mutableCopy]); + [description appendFormat: @" size: %@",NSStringFromSize([self size])]; + [description appendFormat: @" _surface: %p",_surface]; + [description appendFormat: @" surfDC: %p",shdc]; + return AUTORELEASE([description copy]); +} + - (NSSize) size { - RECT sz; + RECT csize; - GetClientRect(GSWINDEVICE, &sz); - return NSMakeSize(sz.right - sz.left, sz.top - sz.bottom); + GetClientRect(GSWINDEVICE, &csize); + return NSMakeSize(csize.right - csize.left, csize.bottom - csize.top); +} + +- (void) setSize: (NSSize)newSize +{ + NSDebugMLLog(@"Win32CairoSurface", @"size: %@\n", NSStringFromSize(newSize)); +} + +- (void) handleExposeRect: (NSRect)rect +{ + // If the surface is buffered then we will have been invoked... + HDC hdc = GetDC(GSWINDEVICE); + + // Make sure we got a HDC... + if (hdc == NULL) + { + NSWarnMLog(@"ERROR: cannot get a HDC for surface: %@\n", self); + } + else + { + // Create a cairo surface for the hDC... + cairo_surface_t *window = cairo_win32_surface_create(hdc); + + // If the surface is buffered then... + if (window == NULL) + { + NSWarnMLog(@"ERROR: cannot create cairo surface for: %@\n", self); + } + else + { + // First check the current status of the foreground surface... + if (cairo_surface_status(window) != CAIRO_STATUS_SUCCESS) + { + NSWarnMLog(@"cairo initial window error status: %s\n", + cairo_status_to_string(cairo_surface_status(window))); + } + else + { + cairo_t *context = cairo_create(window); + + if (cairo_status(context) != CAIRO_STATUS_SUCCESS) + { + NSWarnMLog(@"cairo context create error - status: _surface: %s window: %s windowCtxt: %s (%d)", + cairo_status_to_string(cairo_surface_status(_surface)), + cairo_status_to_string(cairo_surface_status(window)), + cairo_status_to_string(cairo_status(context)), cairo_get_reference_count(context)); + } + else + { + double backupOffsetX = 0; + double backupOffsetY = 0; + RECT msRect = GSWindowRectToMS((WIN32Server*)GSCurrentServer(), GSWINDEVICE, rect); + + // Need to save the device offset context... + cairo_surface_get_device_offset(_surface, &backupOffsetX, &backupOffsetY); + cairo_surface_set_device_offset(_surface, 0, 0); + + cairo_rectangle(context, msRect.left, msRect.top, rect.size.width, rect.size.height); + cairo_clip(context); + cairo_set_source_surface(context, _surface, 0, 0); + cairo_set_operator(context, CAIRO_OPERATOR_SOURCE); + cairo_paint(context); + + if (cairo_status(context) != CAIRO_STATUS_SUCCESS) + { + NSWarnMLog(@"cairo expose error - status: _surface: %s window: %s windowCtxt: %s", + cairo_status_to_string(cairo_surface_status(_surface)), + cairo_status_to_string(cairo_surface_status(window)), + cairo_status_to_string(cairo_status(context))); + } + + // Cleanup... + cairo_destroy(context); + + // Restore device offset + cairo_surface_set_device_offset(_surface, backupOffsetX, backupOffsetY); + } + } + + // Destroy the surface... + cairo_surface_destroy(window); + } + + // Release the aquired HDC... + ReleaseDC(GSWINDEVICE, hdc); + } } @end diff --git a/Source/gsc/GSGState.m b/Source/gsc/GSGState.m index fbc5db5..9e53d39 100644 --- a/Source/gsc/GSGState.m +++ b/Source/gsc/GSGState.m @@ -51,7 +51,7 @@ /* Designated initializer. */ - initWithDrawContext: (GSContext *)drawContext -{ +{ self = [super init]; if (!self) return nil; @@ -103,8 +103,10 @@ - (NSString*) description { - return [NSString stringWithFormat: @"%@ drawcontext: %@ ctm: %@", - [super description], drawcontext, ctm]; + NSMutableString *description = [[super description] mutableCopy]; + [description appendFormat: @" drawcontext: %@",drawcontext]; + [description appendFormat: @" ctm: %@",ctm]; + return [description copy]; } - copyWithZone: (NSZone *)zone diff --git a/Source/win32/WIN32Server.m b/Source/win32/WIN32Server.m index 0544738..f9b48e5 100644 --- a/Source/win32/WIN32Server.m +++ b/Source/win32/WIN32Server.m @@ -62,18 +62,8 @@ #include -static BOOL _enableCallbacks = YES; - -static NSEvent *process_key_event(WIN32Server *svr, - HWND hwnd, WPARAM wParam, - LPARAM lParam, NSEventType eventType); -static NSEvent *process_mouse_event(WIN32Server *svr, - HWND hwnd, WPARAM wParam, - LPARAM lParam, NSEventType eventType, - UINT uMsg); - -LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, - WPARAM wParam, LPARAM lParam); +// Forward declarations... +static unsigned int mask_for_keystate(BYTE *keyState); @interface W32DisplayMonitorInfo : NSObject { @@ -92,54 +82,66 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, @implementation W32DisplayMonitorInfo -- (id) initWithHMonitor: (HMONITOR)hMonitor rect: (LPRECT)lprcMonitor +- (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)); - } + { + 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 +- (HMONITOR)hMonitor { return _hMonitor; } -- (RECT) rect +- (RECT)rect { return _rect; } -- (NSRect) frame +- (NSRect)frame { return _frame; } -- (void) setFrame: (NSRect)frame +- (void)setFrame:(NSRect)frame { _frame = frame; } @end + +static BOOL _enableCallbacks = YES; + +static NSEvent *process_key_event(WIN32Server *svr, + HWND hwnd, WPARAM wParam, + LPARAM lParam, NSEventType eventType); +static NSEvent *process_mouse_event(WIN32Server *svr, + HWND hwnd, WPARAM wParam, + LPARAM lParam, NSEventType eventType, + UINT uMsg); + +LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, + WPARAM wParam, LPARAM lParam); + BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, - HDC hdcMonitor, - LPRECT lprcMonitor, - LPARAM dwData) + HDC hdcMonitor, + LPRECT lprcMonitor, + LPARAM dwData) { - NSMutableArray *monitors = (NSMutableArray*)dwData; - W32DisplayMonitorInfo *info = [[W32DisplayMonitorInfo alloc] - initWithHMonitor: hMonitor - rect: lprcMonitor]; + 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", + NSLog(@"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, @@ -150,6 +152,7 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, return TRUE; } + @implementation WIN32Server - (BOOL) handlesWindowDecorations @@ -190,9 +193,11 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, } else { - // Don't translate messages, as this would give - // extra character messages. - DispatchMessage(&msg); + // Original author disregarded a translate message call here stating + // that it would give extra character messages - BUT THIS KILLS IME + // MESSAGE PROCESSING!!!!! + TranslateMessage(&msg); + DispatchMessage(&msg); } } } @@ -223,6 +228,7 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, } else { + TranslateMessage(m); DispatchMessage(m); } } @@ -263,14 +269,13 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, - (void) _initWin32Context { - WNDCLASSEX wc; + WNDCLASSEXW wc; hinstance = (HINSTANCE)GetModuleHandle(NULL); // Register the main window class. wc.cbSize = sizeof(wc); - //wc.style = CS_OWNDC; // | CS_HREDRAW | CS_VREDRAW; - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC) MainWndProc; + wc.style = 0; + wc.lpfnWndProc = (WNDPROC) MainWndProc; wc.cbClsExtra = 0; // Keep extra space for each window, for OFF_LEVEL and OFF_ORDERED wc.cbWndExtra = WIN_EXTRABYTES; @@ -279,11 +284,11 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; - wc.lpszClassName = "GNUstepWindowClass"; + wc.lpszClassName = L"GNUstepWindowClass"; wc.hIconSm = NULL;//currentAppIcon; - if (!RegisterClassEx(&wc)) - return; + if (!RegisterClassExW(&wc)) + return; // FIXME We should use GetSysColor to get standard colours from MS Window and // use them in NSColor @@ -332,7 +337,7 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, { [self _initWin32Context]; [super initWithAttributes: info]; - + monitorInfo = [NSMutableArray array]; EnumDisplayMonitors(NULL, NULL, (MONITORENUMPROC)LoadDisplayMonitorInfo, (LPARAM)monitorInfo); @@ -395,6 +400,26 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, //TODO [self subclassResponsibility: _cmd]; } +static HWND foundWindowHwnd = 0; +static POINT findWindowAtPoint; + +LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam) +{ + if (foundWindowHwnd == 0 && hwnd != (HWND)lParam) + { + RECT r; + GetWindowRect(hwnd, &r); + + if (PtInRect(&r,findWindowAtPoint) && IsWindowVisible(hwnd)) + { + NSWindow *window = GSWindowWithNumber((int)hwnd); + if (![window ignoresMouseEvents]) + foundWindowHwnd = hwnd; + } + } + return true; +} + - (int) findWindowAt: (NSPoint)screenLocation windowRef: (int*)windowRef excluding: (int)win @@ -403,26 +428,20 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, POINT p; p = GSScreenPointToMS(screenLocation); - hwnd = WindowFromPoint(p); - if ((int)hwnd == win) - { - /* - * If the window at the point we want is excluded, - * we must look through ALL windows at a lower level - * until we find one which contains the same point. - */ - while (hwnd != 0) - { - RECT r; - - hwnd = GetWindow(hwnd, GW_HWNDNEXT); - GetWindowRect(hwnd, &r); - if (PtInRect(&r, p) && IsWindowVisible(hwnd)) - { - break; - } - } - } + /* + * This is insufficient: hwnd = WindowFromPoint(p); + * + * We must look through all windows until we find one + * which contains the specified point, does not have + * the ignoresMouseEvents property set, and is not + * the excluded window. This is done through the + * EnumWindows function which makes a call back to us + * for each window. + */ + foundWindowHwnd = 0; + findWindowAtPoint = p; + EnumWindows((WNDENUMPROC)windowEnumCallback, win); + hwnd = foundWindowHwnd; *windowRef = (int)hwnd; // Any windows @@ -462,27 +481,25 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, - (NSWindowDepth) windowDepthForScreen: (int)screen { - HDC hdc = 0; + HDC hdc = 0; int bits = 0; //int planes; - + if (screen < [monitorInfo count]) { MONITORINFOEX mix = { 0 }; mix.cbSize = sizeof(MONITORINFOEX); - HMONITOR hMonitor = [[monitorInfo objectAtIndex: screen] hMonitor]; + 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); - } + { + 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); } @@ -505,12 +522,9 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, { NSInteger index; NSInteger nMonitors = [monitorInfo count]; - NSMutableArray *screenList = [NSMutableArray arrayWithCapacity: nMonitors]; - + NSMutableArray *screenList = [NSMutableArray arrayWithCapacity:nMonitors]; for (index = 0; index < nMonitors; ++index) - { - [screenList addObject: [NSNumber numberWithInt: index]]; - } + [screenList addObject:[NSNumber numberWithInt:index]]; return [[screenList copy] autorelease]; } @@ -554,28 +568,30 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, return WS_POPUP | WS_CLIPCHILDREN; if (style == 0) - wstyle = WS_POPUP; + { + wstyle = WS_POPUP; + } else { if ((style & NSTitledWindowMask) == NSTitledWindowMask) wstyle |= WS_CAPTION; if ((style & NSClosableWindowMask) == NSClosableWindowMask) - wstyle |= WS_CAPTION + WS_SYSMENU; + wstyle |= WS_CAPTION | WS_SYSMENU; if ((style & NSMiniaturizableWindowMask) == NSMiniaturizableWindowMask) - wstyle |= WS_MINIMIZEBOX + WS_SYSMENU; + wstyle |= WS_MINIMIZEBOX | WS_SYSMENU; if ((style & NSResizableWindowMask) == NSResizableWindowMask) - wstyle |= WS_SIZEBOX + WS_MAXIMIZEBOX; + wstyle |= WS_SIZEBOX | WS_MAXIMIZEBOX; if (((style & NSMiniWindowMask) == NSMiniWindowMask) || ((style & NSIconWindowMask) == NSIconWindowMask)) wstyle |= WS_ICONIC; if (wstyle == 0) - wstyle = WS_POPUP; //WS_CAPTION+WS_SYSMENU; - } + wstyle = WS_POPUP; + } //NSLog(@"Window wstyle %d for style %d", wstyle, style); return wstyle | WS_CLIPCHILDREN; @@ -625,7 +641,7 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, - (void) resizeBackingStoreFor: (HWND)hwnd { - RECT r; +#if (BUILD_GRAPHICS==GRAPHICS_winlib) WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)hwnd, GWL_USERDATA); // FIXME: We should check if the size really did change. @@ -634,6 +650,7 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, HDC hdc, hdc2; HBITMAP hbitmap; HGDIOBJ old; + RECT r; old = SelectObject(win->hdc, win->old); DeleteObject(old); @@ -649,10 +666,11 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, win->hdc = hdc2; ReleaseDC((HWND)hwnd, hdc); - + // After resizing the backing store, we need to redraw the window win->backingStoreEmpty = YES; } +#endif } - (BOOL) displayEvent: (unsigned int)uMsg; // diagnotic filter @@ -674,20 +692,406 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, // future house keeping can go here } -- (LRESULT) windowEventProc: (HWND)hwnd : (UINT)uMsg +- (void) freeCompositionStringForWindow: (HWND)hwnd +{ + IME_INFO_T *imeInfo = (IME_INFO_T*)GetWindowLongPtr(hwnd, IME_INFO); + + // Free any buffer(s)... + if (imeInfo->compString) + free(imeInfo->compString); + imeInfo->compString = NULL; + imeInfo->compStringLength = 0; +} + +- (void) freeReadStringForWindow: (HWND)hwnd +{ + IME_INFO_T *imeInfo = (IME_INFO_T*)GetWindowLongPtr(hwnd, IME_INFO); + + // Free any buffer(s)... + if (imeInfo->readString) + free(imeInfo->readString); + imeInfo->readString = NULL; + imeInfo->readStringLength = 0; +} + +- (void) freeCompositionInfoForWindow: (HWND)hwnd +{ + // Clear information... + [self freeCompositionStringForWindow: hwnd]; + [self freeReadStringForWindow: hwnd]; +} + +- (void) getCompositionStringForWindow: (HWND)hwnd +{ + IME_INFO_T *imeInfo = (IME_INFO_T*)GetWindowLongPtr(hwnd, IME_INFO); + HIMC immc = ImmGetContext(hwnd); + + // Current composition string... + imeInfo->compStringLength = ImmGetCompositionStringW(immc, GCS_COMPSTR, NULL, 0); + imeInfo->compString = malloc(imeInfo->compStringLength+sizeof(TCHAR)); + ImmGetCompositionStringW(immc, GCS_COMPSTR, imeInfo->compString, imeInfo->compStringLength); + + // Cleanup... + ImmReleaseContext(hwnd, immc); +} + +- (void) getReadStringForWindow: (HWND)hwnd +{ + IME_INFO_T *imeInfo = (IME_INFO_T*)GetWindowLongPtr(hwnd, IME_INFO); + HIMC immc = ImmGetContext(hwnd); + + // Current read string... + imeInfo->readStringLength = ImmGetCompositionStringW(immc, GCS_COMPREADSTR, NULL, 0); + imeInfo->readString = malloc(imeInfo->readStringLength+sizeof(TCHAR)); + ImmGetCompositionStringW(immc, GCS_COMPREADSTR, imeInfo->readString, imeInfo->readStringLength); + + // Cleanup... + ImmReleaseContext(hwnd, immc); +} + +- (void) saveCompositionInfoForWindow: (HWND)hwnd +{ + // First, ensure we've cleared out any saved information... + [self freeCompositionInfoForWindow: hwnd]; + + // Current composition string... + [self getCompositionStringForWindow: hwnd]; + + // Current read string... + [self getReadStringForWindow: hwnd]; +} + +- (void) setCompositionStringForWindow: (HWND)hwnd +{ + IME_INFO_T *imeInfo = (IME_INFO_T*)GetWindowLongPtr(hwnd, IME_INFO); + HIMC immc = ImmGetContext(hwnd); + + // Restore the state... + ImmSetCompositionStringW(immc, SCS_SETSTR, imeInfo->compString, imeInfo->compStringLength, NULL, 0); + + // Clear out any saved information... + [self freeCompositionInfoForWindow: hwnd]; + + // Cleanup... + ImmReleaseContext(hwnd, immc); +} + +- (void) setReadStringForWindow: (HWND)hwnd +{ + IME_INFO_T *imeInfo = (IME_INFO_T*)GetWindowLongPtr(hwnd, IME_INFO); + HIMC immc = ImmGetContext(hwnd); + + // Restore the state... + ImmSetCompositionStringW(immc, SCS_SETSTR, NULL, 0, imeInfo->readString, imeInfo->readStringLength); + + // Clear out any saved information... + [self freeReadStringForWindow: hwnd]; + + // Cleanup... + ImmReleaseContext(hwnd, immc); +} + +- (void) restoreCompositionInfoForWindow: (HWND)hwnd +{ + // Restore the state... + [self setCompositionStringForWindow: hwnd]; + + // Restore the read string... + [self setReadStringForWindow: hwnd]; +} + +- (LRESULT) imnMessage: (HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam +{ + HIMC immc = ImmGetContext(hwnd); + switch (wParam) + { + case IMN_CLOSESTATUSWINDOW: + { + NSDebugLog(@"IMN_CLOSESTATUSWINDOW: hwnd: %p wParam: %p lParam: %p immc: %p\n", + hwnd, wParam, lParam, immc); + if (immc) + { + ImmNotifyIME(immc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); + HideCaret(hwnd); + DestroyCaret(); + } + break; + } + + case IMN_SETOPENSTATUS: + { + NSDebugLog(@"IMN_SETOPENSTATUS: hwnd: %p wParam: %p lParam: %p immc: %p\n", + hwnd, wParam, lParam, immc); + if (immc) + { + NSDebugLog(@"IMN_SETOPENSTATUS: openstatus: %d\n", ImmGetOpenStatus(immc)); + + IME_INFO_T *imeInfo = (IME_INFO_T*)GetWindowLongPtr(hwnd, IME_INFO); + if (imeInfo == NULL) + { + NSDebugLog(@"IMN_SETOPENSTATUS: IME info pointer is NULL\n"); + } + else + { + if (ImmGetOpenStatus(immc)) + { + if (imeInfo->isOpened == NO) + { + // Restore previous information... +#if defined(IME_SAVERESTORE_COMPOSITIONINFO) + [self restoreCompositionInfoForWindow: hwnd]; +#else + ImmNotifyIME(immc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); +#endif + } + } + else if (imeInfo->isOpened == YES) + { + // Save current information... + [self saveCompositionInfoForWindow: hwnd]; + } + + // Save state... + imeInfo->isOpened = ImmGetOpenStatus(immc); + } + +#if defined(USE_SYSTEM_CARET) + if (ImmGetOpenStatus(immc)) + ShowCaret(hwnd); + else + HideCaret(hwnd); +#endif + +#if defined(IME_SETCOMPOSITIONFONT) + { + LOGFONT logFont; + ImmGetCompositionFont(immc, &logFont); + LOGFONT newFont = logFont; + newFont.lfCharSet = ((logFont.lfCharSet == DEFAULT_CHARSET) ? OEM_CHARSET : DEFAULT_CHARSET); + ImmSetCompositionFont(immc, &newFont); + NSDebugLog(@"IMN_SETOPENSTATUS: changing logfont from: %d to: %d\n", logFont.lfCharSet, newFont.lfCharSet); + } +#endif + } + break; + } + + case IMN_OPENSTATUSWINDOW: + { + NSDebugLog(@"IMN_OPENSTATUSWINDOW: hwnd: %p wParam: %p lParam: %p immc: %p\n", + hwnd, wParam, lParam, immc); + if (immc) + { + NSDebugLog(@"IMN_OPENSTATUSWINDOW: openstatus: %d\n", ImmGetOpenStatus(immc)); + LOGFONT logFont; + { + ImmGetCompositionFont(immc, &logFont); + NSDebugLog(@"IMN_OPENSTATUSWINDOW: logfont - width: %d height: %d\n", + logFont.lfWidth, logFont.lfHeight); + } +#if defined(USE_SYSTEM_CARET) + CreateCaret(hwnd, NULL, logFont.lfWidth, logFont.lfHeight); + if (ImmGetOpenStatus(immc)) + ShowCaret(hwnd); + else + HideCaret(hwnd); +#endif + } + break; + } + + case IMN_CHANGECANDIDATE: + NSDebugLog(@"IMN_CHANGECANDIDATE: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + + case IMN_CLOSECANDIDATE: + NSDebugLog(@"IMN_CLOSECANDIDATE: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + + case IMN_OPENCANDIDATE: + NSDebugLog(@"IMN_OPENCANDIDATE: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + + case IMN_SETCONVERSIONMODE: + { + NSDebugLog(@"IMN_SETCONVERSIONMODE: hwnd: %p wParam: %p lParam: %p immc: %p\n", + hwnd, wParam, lParam, immc); + if (immc) + { + DWORD conversion; + DWORD sentence; + if (ImmGetConversionStatus(immc, &conversion, &sentence) == 0) + NSDebugLog(@"IMN_SETCONVERSIONMODE: error getting conversion status: %d\n", GetLastError()); + else + NSDebugLog(@"IMN_SETCONVERSIONMODE: conversion: %p sentence: %p\n", conversion, sentence); + } + break; + } + + case IMN_SETSENTENCEMODE: + { + NSDebugLog(@"IMN_SETSENTENCEMODE: hwnd: %p wParam: %p lParam: %p immc: %p\n", + hwnd, wParam, lParam, immc); + if (immc) + { + DWORD conversion; + DWORD sentence; + if (ImmGetConversionStatus(immc, &conversion, &sentence) == 0) + NSDebugLog(@"IMN_SETSENTENCEMODE: error getting conversion status: %d\n", GetLastError()); + else + NSDebugLog(@"IMN_SETSENTENCEMODE: conversion: %p sentence: %p\n", conversion, sentence); + } + break; + } + + case IMN_SETCANDIDATEPOS: + NSDebugLog(@"IMN_SETCANDIDATEPOS: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + + case IMN_SETCOMPOSITIONFONT: + { + NSDebugLog(@"IMN_SETCOMPOSITIONFONT: hwnd: %p wParam: %p lParam: %p immc: %p\n", + hwnd, wParam, lParam, immc); + if (immc) + { +#if defined(IME_SETCOMPOSITIONFONT) + { + LOGFONT logFont; + ImmGetCompositionFont(immc, &logFont); + NSDebugLog(@"IMN_SETCOMPOSITIONFONT: new character set: %d\n", logFont.lfCharSet); + } +#endif + } + break; + } + + case IMN_SETCOMPOSITIONWINDOW: + NSDebugLog(@"IMN_SETCOMPOSITIONWINDOW: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + + case IMN_SETSTATUSWINDOWPOS: + NSDebugLog(@"IMN_SETSTATUSWINDOWPOS: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + + case IMN_GUIDELINE: + NSDebugLog(@"IMN_GUIDELINE: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + + case IMN_PRIVATE: + NSDebugLog(@"IMN_PRIVATE: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + + default: + NSDebugLog(@"Unknown IMN message: %p hwnd: %p\n", wParam, hwnd); + break; + } + + // Release the IME context... + ImmReleaseContext(hwnd, immc); + + return 0; +} + +- (NSEvent*)imeCompositionMessage: (HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam +{ + NSDebugLog(@"WM_IME_COMPOSITION: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + HIMC immc = ImmGetContext(hwnd); + if (immc == 0) + { + NSWarnMLog(@"IMMContext is NULL\n"); + } + else if (lParam & GCS_RESULTSTR) + { + // Update our composition string information... + LONG length = ImmGetCompositionStringW(immc, GCS_RESULTSTR, NULL, 0); + NSDebugLog(@"length: %d\n", length); + if (length) + { + TCHAR composition[length+sizeof(TCHAR)]; + length = ImmGetCompositionStringW(immc, GCS_RESULTSTR, &composition, length); + { + int index; + for (index = 0; index < length; ++index) + NSDebugLog(@"%2.2X ", composition[index]); + } + NSDebugLog(@"composition (uKeys): %@\n", + [NSString stringWithCharacters: (unichar*)composition length: length]); + } + ImmReleaseContext(hwnd, immc); + } + + return 0; +} + +- (LRESULT) imeCharacter: (HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam +{ + BYTE keyState[256]; + + // Get the current key states... + GetKeyboardState(keyState); + + // key events should go to the key window if we have one (Windows' focus window isn't always appropriate) + int windowNumber = [[NSApp keyWindow] windowNumber]; + if (windowNumber == 0) + windowNumber = (int)hwnd; + + /* FIXME: How do you guarentee a context is associated with an event? */ + NSGraphicsContext *gcontext = GSCurrentContext(); + LONG ltime = GetMessageTime(); + NSTimeInterval time = ltime / 1000.0f; + BOOL repeat = (lParam & 0xFFFF) != 0; + unsigned int eventFlags = mask_for_keystate(keyState); + DWORD pos = GetMessagePos(); + NSPoint eventLocation = MSWindowPointToGS(self, hwnd, GET_X_LPARAM(pos), GET_Y_LPARAM(pos)); + NSString *keys = [NSString stringWithCharacters: (unichar*)&wParam length: 1]; + NSString *ukeys = [NSString stringWithCharacters: (unichar*)&wParam length: 1]; + + // Create a NSKeyDown message... + NSEvent *ev = [NSEvent keyEventWithType: NSKeyDown + location: eventLocation + modifierFlags: eventFlags + timestamp: time + windowNumber: windowNumber + context: gcontext + characters: keys + charactersIgnoringModifiers: ukeys + isARepeat: repeat + keyCode: wParam]; + + // Post it... + [GSCurrentServer() postEvent: ev atStart: NO]; + + // then an associated NSKeyUp message... + ev = [NSEvent keyEventWithType: NSKeyUp + location: eventLocation + modifierFlags: eventFlags + timestamp: time + windowNumber: windowNumber + context: gcontext + characters: keys + charactersIgnoringModifiers: ukeys + isARepeat: repeat + keyCode: wParam]; + + // Post it... + [GSCurrentServer() postEvent: ev atStart: NO]; + + return 0; +} + +- (LRESULT) windowEventProc: (HWND)hwnd : (UINT)uMsg : (WPARAM)wParam : (LPARAM)lParam -{ +{ NSEvent *ev = nil; [self setFlagsforEventLoop: hwnd]; -//NSLog(@"event %u", uMsg); - switch (uMsg) - { - case WM_SIZING: + switch (uMsg) + { + case WM_SIZING: return [self decodeWM_SIZINGParams: hwnd : wParam : lParam]; - break; - case WM_NCCREATE: + break; + case WM_NCCREATE: return [self decodeWM_NCCREATEParams: wParam : lParam : hwnd]; break; case WM_NCCALCSIZE: @@ -735,10 +1139,10 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, return [self decodeWM_SIZEParams: hwnd : wParam : lParam]; break; case WM_ENTERSIZEMOVE: + return [self decodeWM_ENTERSIZEMOVEParams: wParam : lParam : hwnd]; break; case WM_EXITSIZEMOVE: - //return [self decodeWM_EXITSIZEMOVEParams: wParam : lParam : hwnd]; - return DefWindowProc(hwnd, uMsg, wParam, lParam); + return [self decodeWM_EXITSIZEMOVEParams: wParam : lParam : hwnd]; break; case WM_ACTIVATE: if ((int)lParam !=0) @@ -891,12 +1295,89 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, NSDebugLLog(@"NSEvent", @"Got Message %s for %d", "MOUSEWHEEL", hwnd); ev = process_mouse_event(self, hwnd, wParam, lParam, NSScrollWheel, uMsg); break; - + + // WINDOWS IME PROCESSING MESSAGES... + case WM_IME_NOTIFY: + [self imnMessage: hwnd : wParam : lParam]; + break; + case WM_IME_REQUEST: + NSDebugLog(@"WM_IME_REQUEST: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + case WM_IME_SELECT: + NSDebugLog(@"WM_IME_SELECT: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + case WM_IME_SETCONTEXT: + NSDebugLog(@"WM_IME_SETCONTEXT: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + case WM_IME_STARTCOMPOSITION: + { + NSDebugLog(@"WM_IME_STARTCOMPOSITION: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + IME_INFO_T *imeInfo = (IME_INFO_T*)GetWindowLongPtr(hwnd, IME_INFO); + if (imeInfo) + imeInfo->isComposing = YES; + break; + } + case WM_IME_ENDCOMPOSITION: + { + NSDebugLog(@"WM_IME_ENDCOMPOSITION: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + IME_INFO_T *imeInfo = (IME_INFO_T*)GetWindowLongPtr(hwnd, IME_INFO); + if (imeInfo) + imeInfo->isComposing = NO; + break; + } + case WM_IME_COMPOSITION: + { + IME_INFO_T *imeInfo = (IME_INFO_T*)GetWindowLongPtr(hwnd, IME_INFO); + if (imeInfo && imeInfo->isComposing) + ev = [self imeCompositionMessage: hwnd : wParam : lParam]; + break; + } + case WM_IME_COMPOSITIONFULL: + NSDebugLog(@"WM_IME_COMPOSITIONFULL: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + case WM_IME_KEYDOWN: + NSDebugLog(@"WM_IME_KEYDOWN: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + if (wParam == 0xd) // Carriage return... + { + HIMC immc = ImmGetContext(hwnd); + if (immc) + { + // If currently in a composition sequence in the IMM... + ImmNotifyIME(immc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); + + // Release the context... + ImmReleaseContext(hwnd, immc); + } + } + + // Don't pass this message on for processing... + flags._eventHandled = YES; + break; + case WM_IME_KEYUP: + NSDebugLog(@"WM_IME_KEYUP: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + case WM_IME_CHAR: + return [self imeCharacter: hwnd : wParam : lParam]; + break; + + case WM_CHAR: + NSDebugLog(@"WM_CHAR: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + + case WM_INPUTLANGCHANGEREQUEST: + NSDebugLog(@"WM_INPUTLANGCHANGEREQUEST: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + case WM_INPUTLANGCHANGE: + NSDebugLog(@"WM_INPUTLANGCHANGE: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); + break; + case WM_KEYDOWN: //KEYBOARD + NSDebugLog(@"WM_KEYDOWN: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); NSDebugLLog(@"NSEvent", @"Got Message %s for %d", "KEYDOWN", hwnd); ev = process_key_event(self, hwnd, wParam, lParam, NSKeyDown); break; case WM_KEYUP: //KEYBOARD + NSDebugLog(@"WM_KEYUP: hwnd: %p wParam: %p lParam: %p\n", hwnd, wParam, lParam); NSDebugLLog(@"NSEvent", @"Got Message %s for %d", "KEYUP", hwnd); ev = process_key_event(self, hwnd, wParam, lParam, NSKeyUp); break; @@ -935,7 +1416,7 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, * We did not care about the event, return it back to the windows * event handler */ - return DefWindowProc(hwnd, uMsg, wParam, lParam); + return DefWindowProcW(hwnd, uMsg, wParam, lParam); } - glContextClass @@ -1021,12 +1502,16 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, type, style, screen); NSDebugLLog(@"WTrace", @" device frame: %d, %d, %d, %d", r.left, r.top, r.right - r.left, r.bottom - r.top); - hwnd = CreateWindowEx(estyle | WS_EX_LAYERED, - "GNUstepWindowClass", - "GNUstepWindow", - wstyle, - r.left, - r.top, + hwnd = CreateWindowEx(estyle | WS_EX_LAYERED, + "GNUstepWindowClass", + "GNUstepWindow", +#if (BUILD_GRAPHICS==GRAPHICS_cairo) + ((wstyle & WS_POPUP) ? ((wstyle & ~WS_POPUP) | WS_OVERLAPPED) : wstyle), +#else + wstyle, +#endif + r.left, + r.top, r.right - r.left, r.bottom - r.top, (HWND)NULL, @@ -1034,13 +1519,39 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, hinstance, (void*)type); NSDebugLLog(@"WCTrace", @" num/handle: %d", hwnd); - if (!hwnd) { - NSLog(@"CreateWindowEx Failed %d", GetLastError()); - } - - SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA); + if (hwnd == NULL) + { + NSLog(@"CreateWindowEx Failed %d", GetLastError()); + } + else + { +#if (BUILD_GRAPHICS==GRAPHICS_cairo) + // Borderless window request... + if (wstyle & WS_POPUP) + { + LONG wstyleOld = GetWindowLong(hwnd, GWL_STYLE); + LONG estyleOld = GetWindowLong(hwnd, GWL_EXSTYLE); + LONG wstyleNew = (wstyleOld & ~WS_OVERLAPPEDWINDOW); + LONG estyleNew = estyleOld | WS_EX_TOOLWINDOW; + + NSDebugMLLog(@"WCTrace", @"wstyles - old: %8.8X new: %8.8X\n", + wstyleOld, wstyleNew); + NSDebugMLLog(@"WCTrace", @"estyles - old: %8.8X new: %8.8X\n", + estyleOld, estyleNew); + + // Modify window style parameters and update the window information... + SetWindowLong(hwnd, GWL_STYLE, wstyleNew); + SetWindowLong(hwnd, GWL_EXSTYLE, estyleNew); + SetWindowPos(hwnd, NULL, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOSENDCHANGING | SWP_NOREPOSITION | + SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); + } +#endif - [self _setWindowOwnedByServer: (int)hwnd]; + SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA); + + [self _setWindowOwnedByServer: (int)hwnd]; + } return (int)hwnd; } @@ -1075,6 +1586,7 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA); NSDebugLLog(@"WTrace", @"windowbacking: %d : %d", type, winNum); +#if (BUILD_GRAPHICS==GRAPHICS_winlib) if (win->useHDC) { HGDIOBJ old; @@ -1105,10 +1617,14 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, ReleaseDC((HWND)winNum, hdc); } else +#endif { win->useHDC = NO; win->hdc = NULL; } + + // Save updated window backing store type... + win->type = type; } - (void) titlewindow: (NSString*)window_title : (int) winNum @@ -1121,7 +1637,7 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, - (void) miniwindow: (int) winNum { NSDebugLLog(@"WTrace", @"miniwindow: %d", winNum); - ShowWindow((HWND)winNum, SW_MINIMIZE); + ShowWindow((HWND)winNum, SW_MINIMIZE); } /** Returns NO as we don't provide mini windows on MS Windows */ @@ -1148,12 +1664,12 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, - (void) orderwindow: (int) op : (int) otherWin : (int) winNum { - int flag; + int flag = 0; int foreground = 0; int otherLevel; int level; NSWindow *window = GSWindowWithNumber(winNum); - + NSDebugLLog(@"WTrace", @"orderwindow: %d : %d : %d", op, otherWin, winNum); if ([self usesNativeTaskbar]) @@ -1181,44 +1697,43 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, if (op == NSWindowOut) { SetWindowLong((HWND)winNum, OFF_ORDERED, 0); - SetWindowPos((HWND)winNum, NULL, 0, 0, 0, 0, - SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + ShowWindow((HWND)winNum, SW_HIDE); return; } - if (![window canBecomeMainWindow] && ![window canBecomeKeyWindow]) - { // Bring front, but do not activate, eg - tooltips - flag = SW_SHOWNA; - ShowWindow((HWND)winNum, flag); - } - else + if (![window canBecomeMainWindow] && ![window canBecomeKeyWindow]) { - flag = SW_SHOW; - - if (IsIconic((HWND)winNum)) - flag = SW_RESTORE; - - ShowWindow((HWND)winNum, flag); + // Bring front, but do not activate, eg - tooltips + flag = SW_SHOWNA; + } + else + { + flag = SW_SHOW; + if (IsIconic((HWND)winNum)) + flag = SW_RESTORE; } + ShowWindow((HWND)winNum, flag); SetWindowLong((HWND)winNum, OFF_ORDERED, 1); + + // Process window leveling... level = GetWindowLong((HWND)winNum, OFF_LEVEL); if (otherWin <= 0) { if (otherWin == 0 && op == NSWindowAbove) - { - /* This combination means we should move to the top of the current - * window level but stay below the key window, so if we have a key - * window (other than the current window), we store it's id for - * testing later. - */ - foreground = (int)GetForegroundWindow(); - if (foreground < 0 || foreground == winNum) - { - foreground = 0; - } - } + { + /* This combination means we should move to the top of the current + * window level but stay below the key window, so if we have a key + * window (other than the current window), we store it's id for + * testing later. + */ + foreground = (int)GetForegroundWindow(); + if (foreground < 0 || foreground == winNum) + { + foreground = 0; + } + } otherWin = 0; } @@ -1229,13 +1744,13 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, */ otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL); if (level != otherLevel) - { - NSDebugLLog(@"WTrace", - @"orderwindow: implicitly set level of %d (%d) to that of %d (%d)", - winNum, level, otherWin, otherLevel); - level = otherLevel; - SetWindowLong((HWND)winNum, OFF_LEVEL, level); - } + { + NSDebugLLog(@"WTrace", + @"orderwindow: implicitly set level of %d (%d) to that of %d (%d)", + winNum, level, otherWin, otherLevel); + level = otherLevel; + SetWindowLong((HWND)winNum, OFF_LEVEL, level); + } } if (level <= NSDesktopWindowLevel) @@ -1245,108 +1760,103 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, // For desktop level, put this at the bottom of the z-order SetParent((HWND)winNum, desktop); otherWin = (int)HWND_BOTTOM; - NSDebugLLog(@"WTrace", - @"orderwindow: set %i (%i) to bottom", winNum, level); + NSDebugLLog(@"WTrace", @"orderwindow: set %i (%i) to bottom", winNum, level); } else if (otherWin == 0 || op == NSWindowAbove) { if (otherWin == 0) - { - /* Start searching from bottom of window list... - * The last child of the desktop. - */ - otherWin = (int)GetDesktopWindow(); - otherWin = (int)GetWindow((HWND)otherWin, GW_CHILD); - if (otherWin > 0) - { - otherWin = (int)GetWindow((HWND)otherWin, GW_HWNDLAST); - } - } - NSDebugLLog(@"WTrace", - @"orderwindow: traverse for %d (%d) starting at %d", - winNum, level, otherWin); + { + /* Start searching from bottom of window list... + * The last child of the desktop. + */ + otherWin = (int)GetDesktopWindow(); + otherWin = (int)GetWindow((HWND)otherWin, GW_CHILD); + if (otherWin > 0) + { + otherWin = (int)GetWindow((HWND)otherWin, GW_HWNDLAST); + } + } + NSDebugLLog(@"WTrace", @"orderwindow: traverse for %d (%d) starting at %d", + winNum, level, otherWin); while (otherWin > 0) { - TCHAR buf[32]; + TCHAR buf[32]; - otherWin = (int)GetNextWindow((HWND)otherWin, GW_HWNDPREV); + otherWin = (int)GetNextWindow((HWND)otherWin, GW_HWNDPREV); - /* We only look at gnustep windows (other than the one being - * ordered) to decide where to place our window. - * The assumption is, that if we are ordering a window in, - * we want it to be above any non-gnustep window. - * FIXME ... perhaps we should move all non-gnustep windows - * to be lower than the lowest (excluding gnustep desktop - * level windows I suppose) gnustep window. - */ - if (otherWin > 0 && otherWin != winNum - && GetClassName((HWND)otherWin, buf, 32) == 18 - && strncmp(buf, "GNUstepWindowClass", 18) == 0) - { - if (GetWindowLong((HWND)otherWin, OFF_ORDERED) == 1) - { - otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL); - NSDebugLLog(@"WTrace", - @"orderwindow: found gnustep window %d (%d)", - otherWin, otherLevel); - if (otherLevel >= level) - { - if (otherLevel > level) - { - /* On windows, there is no notion of levels, so - * native apps will automatically move to the - * very top of the stack (above our alert panels etc) - * - * So to cope with this, when we move to the top - * of a level, we assume there may be native apps - * above us and we set otherWin=0 to move to the - * very top of the stack past them. - * - * We rely on the fact that we have code in the - * window positioning notification to rearrange - * (sort) all the windows into level order if - * moving this window to the top messes up the - * level ordering. - */ - otherWin = 0; - break; - } - if (op == NSWindowBelow || foreground == otherWin) - { - break; - } - } - } - } - } + /* We only look at gnustep windows (other than the one being + * ordered) to decide where to place our window. + * The assumption is, that if we are ordering a window in, + * we want it to be above any non-gnustep window. + * FIXME ... perhaps we should move all non-gnustep windows + * to be lower than the lowest (excluding gnustep desktop + * level windows I suppose) gnustep window. + */ + if (otherWin > 0 && otherWin != winNum + && GetClassName((HWND)otherWin, buf, 32) == 18 + && strncmp(buf, "GNUstepWindowClass", 18) == 0) + { + if (GetWindowLong((HWND)otherWin, OFF_ORDERED) == 1) + { + otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL); + NSDebugLLog(@"WTrace", @"orderwindow: found gnustep window %d (%d)", + otherWin, otherLevel); + if (otherLevel >= level) + { + if (otherLevel > level) + { + /* On windows, there is no notion of levels, so + * native apps will automatically move to the + * very top of the stack (above our alert panels etc) + * + * So to cope with this, when we move to the top + * of a level, we assume there may be native apps + * above us and we set otherWin=0 to move to the + * very top of the stack past them. + * + * We rely on the fact that we have code in the + * window positioning notification to rearrange + * (sort) all the windows into level order if + * moving this window to the top messes up the + * level ordering. + */ + otherWin = 0; + break; + } + if (op == NSWindowBelow || foreground == otherWin) + { + break; + } + } + } + } + } } if (otherWin == 0) { otherWin = (int)HWND_TOP; - NSDebugLLog(@"WTrace", - @"orderwindow: set %i (%i) to top", winNum, level); + NSDebugLLog(@"WTrace", @"orderwindow: set %i (%i) to top", winNum, level); } else if (otherWin == (int)HWND_BOTTOM) { - NSDebugLLog(@"WTrace", - @"orderwindow: set %i (%i) to bottom", winNum, level); + NSDebugLLog(@"WTrace", @"orderwindow: set %i (%i) to bottom", winNum, level); } else { - NSDebugLLog(@"WTrace", - @"orderwindow: set %i (%i) below %d", winNum, level, otherWin); + NSDebugLLog(@"WTrace", @"orderwindow: set %i (%i) below %d", winNum, level, otherWin); } SetWindowPos((HWND)winNum, (HWND)otherWin, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); if (otherWin == (int)HWND_TOP) { _enableCallbacks = NO; - SetForegroundWindow((HWND)winNum); + if (SetForegroundWindow((HWND)winNum) == 0) + NSDebugMLLog(@"WError", @"SetForegroundWindow error for HWND: %p\n", winNum); _enableCallbacks = YES; - } + } /* For debug log window stack. */ if (GSDebugSet(@"WTrace") == YES) @@ -1356,27 +1866,27 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, otherWin = (int)GetDesktopWindow(); otherWin = (int)GetWindow((HWND)otherWin, GW_CHILD); if (otherWin > 0) - { - otherWin = (int)GetWindow((HWND)otherWin, GW_HWNDLAST); - } + { + otherWin = (int)GetWindow((HWND)otherWin, GW_HWNDLAST); + } while (otherWin > 0) - { - TCHAR buf[32]; + { + TCHAR buf[32]; - otherWin = (int)GetNextWindow((HWND)otherWin, GW_HWNDPREV); + otherWin = (int)GetNextWindow((HWND)otherWin, GW_HWNDPREV); - if (otherWin > 0 - && GetClassName((HWND)otherWin, buf, 32) == 18 - && strncmp(buf, "GNUstepWindowClass", 18) == 0) - { - if (GetWindowLong((HWND)otherWin, OFF_ORDERED) == 1) - { - otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL); - s = [s stringByAppendingFormat: - @"%d (%d)\n", otherWin, otherLevel]; - } - } - } + if (otherWin > 0 + && GetClassName((HWND)otherWin, buf, 32) == 18 + && strncmp(buf, "GNUstepWindowClass", 18) == 0) + { + if (GetWindowLong((HWND)otherWin, OFF_ORDERED) == 1) + { + otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL); + s = [s stringByAppendingFormat: + @"%d (%d)\n", otherWin, otherLevel]; + } + } + } NSDebugLLog(@"WTrace", @"orderwindow: %@", s); } } @@ -1390,23 +1900,25 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, p = GSWindowOriginToMS((HWND)winNum, loc); SetWindowPos((HWND)winNum, NULL, p.x, p.y, 0, 0, - SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); + SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); } - (void) placewindow: (NSRect)frame : (int) winNum { RECT r; RECT r2; - WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA); NSDebugLLog(@"WTrace", @"placewindow: %@ : %d", NSStringFromRect(frame), winNum); r = GSScreenRectToMS(frame); GetWindowRect((HWND)winNum, &r2); - + SetWindowPos((HWND)winNum, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, - SWP_NOZORDER | SWP_NOACTIVATE); + SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING); + +#if (BUILD_GRAPHICS==GRAPHICS_winlib) + WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA); if ((win->useHDC) && (r.right - r.left != r2.right - r2.left) @@ -1431,6 +1943,7 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, ReleaseDC((HWND)winNum, hdc); } +#endif } - (BOOL) findwindow: (NSPoint)loc : (int) op : (int) otherWin @@ -1549,24 +2062,40 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, - (void) flushwindowrect: (NSRect)rect : (int)winNum { HWND hwnd = (HWND)winNum; - RECT r = GSWindowRectToMS(self, hwnd, rect); WIN_INTERN *win = (WIN_INTERN *)GetWindowLong(hwnd, GWL_USERDATA); - if (win->useHDC) + if (win) { - HDC hdc = GetDC(hwnd); - WINBOOL result; - - result = BitBlt(hdc, r.left, r.top, - (r.right - r.left), (r.bottom - r.top), - win->hdc, r.left, r.top, SRCCOPY); - if (!result) +#if (BUILD_GRAPHICS==GRAPHICS_winlib) + if (win->useHDC) { - NSLog(@"Flush window %d %@", hwnd, - NSStringFromRect(MSWindowRectToGS(self, hwnd, r))); - NSLog(@"Flush window failed with %d", GetLastError()); + HDC hdc = GetDC(hwnd); + RECT r = GSWindowRectToMS(self, hwnd, rect); + WINBOOL result; + + result = BitBlt(hdc, r.left, r.top, + (r.right - r.left), (r.bottom - r.top), + win->hdc, r.left, r.top, SRCCOPY); + if (!result) + { + NSLog(@"Flush window %d %@", hwnd, + NSStringFromRect(MSWindowRectToGS(self, hwnd, r))); + NSLog(@"Flush window failed with %d", GetLastError()); + } + ReleaseDC(hwnd, hdc); } - ReleaseDC(hwnd, hdc); +#elif (BUILD_GRAPHICS==GRAPHICS_cairo) + if (win->surface == NULL) + { + NSWarnMLog(@"NULL surface for window %p", hwnd); + } + else + { + [[GSCurrentContext() class] handleExposeRect: rect forDriver: (void*)win->surface]; + } +#else +#error INVALID build graphics type +#endif } } @@ -1585,7 +2114,7 @@ BOOL CALLBACK LoadDisplayMonitorInfo(HMONITOR hMonitor, *r = rect.right - 200; *t = 100 - rect.top; *b = rect.bottom - 200; - //NSLog(@"Style %d offset %f %f %f %f", wstyle, *l, *r, *t, *b); + //NSLog(@"Style 0x%X offset %f %f %f %f", wstyle, *l, *r, *t, *b); } else { @@ -1905,8 +2434,7 @@ mask_for_keystate(BYTE *keyState) } static NSEvent* -process_key_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, - NSEventType eventType) +process_key_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, NSEventType eventType) { NSEvent *event; BOOL repeat; @@ -1921,7 +2449,7 @@ process_key_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, BYTE keyState[256]; NSString *keys, *ukeys; NSGraphicsContext *gcontext; - unichar uChar; + unichar uChar = 0; /* FIXME: How do you guarentee a context is associated with an event? */ gcontext = GSCurrentContext(); @@ -1964,8 +2492,20 @@ process_key_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, break; } - - uChar = process_char(wParam, &eventFlags); + if (wParam == VK_PROCESSKEY) + { + // Ignore VK_PROCESSKEY for IME processing... + return 0; + } + else + { + // Ignore if currently in IME composition processing... + IME_INFO_T *imeInfo = (IME_INFO_T*)GetWindowLongPtr(hwnd, IME_INFO); + if (imeInfo && (imeInfo->isComposing)) + return 0; + uChar = process_char(wParam, &eventFlags); + } + if (uChar) { keys = [NSString stringWithCharacters: &uChar length: 1]; @@ -1978,31 +2518,30 @@ process_key_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, // initialize blank key state array.... for(i = 0; i < 256; i++) - blankKeyState[i] = 0; + blankKeyState[i] = 0; scan = ((lParam >> 16) & 0xFF); - //NSLog(@"Got key code %d %d", scan, wParam); - result = ToUnicode(wParam, scan, keyState, unicode, 5, 0); - //NSLog(@"To Unicode resulted in %d with %d", result, unicode[0]); + result = ToUnicodeEx(wParam, scan, keyState, unicode, 5, 0, GetKeyboardLayout(0)); if (result == -1) - { - // A non spacing accent key was found, we still try to use the result - result = 1; - } + { + // A non spacing accent key was found, we still try to use the result + result = 1; + } keys = [NSString stringWithCharacters: unicode length: result]; // Now get the characters with a blank keyboard state so that // no modifiers are applied. - result = ToUnicode(wParam, scan, blankKeyState, unicode, 5, 0); + result = ToUnicodeEx(wParam, scan, blankKeyState, unicode, 5, 0, GetKeyboardLayout(0)); //NSLog(@"To Unicode resulted in %d with %d", result, unicode[0]); if (result == -1) - { - // A non spacing accent key was found, we still try to use the result - result = 1; - } - + { + // A non spacing accent key was found, we still try to use the result + result = 1; + NSWarnMLog(@"To Unicode resulted in -1 with: 0x%4.4X\n", unicode[0]); + } ukeys = [NSString stringWithCharacters: unicode length: result]; } + if (eventFlags & NSShiftKeyMask) ukeys = [ukeys uppercaseString]; @@ -2115,8 +2654,8 @@ process_mouse_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, { e = process_mouse_event(svr, hwnd, wParam, lParam, NSLeftMouseDown, uMsg); - if (e != nil) - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } eventType = NSLeftMouseDragged; } @@ -2126,15 +2665,15 @@ process_mouse_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, { e = process_mouse_event(svr, hwnd, wParam, lParam, NSLeftMouseUp, uMsg); - if (e != nil) - [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); - if (e != nil) - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } eventType = NSRightMouseDragged; } @@ -2144,22 +2683,22 @@ process_mouse_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, { e = process_mouse_event(svr, hwnd, wParam, lParam, NSLeftMouseUp, uMsg); - if (e != nil) - [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); - if (e != nil) - [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); - if (e != nil) - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } eventType = NSOtherMouseDragged; } @@ -2169,22 +2708,22 @@ process_mouse_event(WIN32Server *svr, HWND hwnd, WPARAM wParam, LPARAM lParam, { e = process_mouse_event(svr, hwnd, wParam, lParam, NSLeftMouseUp, uMsg); - if (e != nil) - [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); - if (e != nil) - [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); - if (e != nil) - [GSCurrentServer() postEvent: e atStart: NO]; + if (e != nil) + [GSCurrentServer() postEvent: e atStart: NO]; } } } @@ -2268,3 +2807,4 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, return [ctxt windowEventProc: hwnd : uMsg : wParam : lParam]; } + diff --git a/Source/win32/w32_GLcontext.m b/Source/win32/w32_GLcontext.m index e7d7290..c9e6b46 100644 --- a/Source/win32/w32_GLcontext.m +++ b/Source/win32/w32_GLcontext.m @@ -337,18 +337,17 @@ static Win32GLContext *currentGLContext; - (id)initWithCGLContextObj: (void *)context { self = [super init]; - if (!self) { return nil; } - + // FIXME: Need to set the pixelFormat ivar wgl_context = context; return self; } -- (id)initWithFormat:(NSOpenGLPixelFormat *)aFormat +- (id)initWithFormat:(NSOpenGLPixelFormat *)aFormat shareContext:(NSOpenGLContext *)share { NSDebugMLLog(@"WGL", @"will init with format %@", aFormat); diff --git a/Source/win32/w32_create.m b/Source/win32/w32_create.m index 0329e4c..0ce2a81 100644 --- a/Source/win32/w32_create.m +++ b/Source/win32/w32_create.m @@ -26,6 +26,7 @@ Boston, MA 02110-1301, USA. */ +#include "config.h" #include #include #include @@ -35,6 +36,7 @@ @implementation WIN32Server (w32_create) + - (LRESULT) decodeWM_NCCREATEParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd { @@ -45,6 +47,7 @@ : (HWND)hwnd { WIN_INTERN *win; + IME_INFO_T *ime; NSBackingStoreType type = (NSBackingStoreType)((LPCREATESTRUCT)lParam)->lpCreateParams; NSBundle *bundle = [NSBundle mainBundle]; NSString *iconName = nil; @@ -56,9 +59,17 @@ is stored in the extra fields for this window. Drawing operations work on this buffer. */ win = malloc(sizeof(WIN_INTERN)); + ime = malloc(sizeof(IME_INFO_T)); + + // Initialize win internals structure... memset(win, 0, sizeof(WIN_INTERN)); + memset(ime, 0, sizeof(IME_INFO_T)); + win->type = type; win->useHDC = NO; + + // Save win internals structure pointer for window handle... SetWindowLong(hwnd, GWL_USERDATA, (int)win); + SetWindowLongPtr(hwnd, IME_INFO, (LONG)ime); [self windowbacking: type : (int)hwnd]; @@ -91,7 +102,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; diff --git a/Source/win32/w32_general.m b/Source/win32/w32_general.m index e847fdc..f21c1d2 100644 --- a/Source/win32/w32_general.m +++ b/Source/win32/w32_general.m @@ -75,6 +75,7 @@ DeleteDC(win->hdc); } free(win); + free((IME_INFO_T*)GetWindowLongPtr(hwnd, IME_INFO)); flags._eventHandled=YES; } diff --git a/Source/win32/w32_movesize.m b/Source/win32/w32_movesize.m index f9b3a04..652859b 100644 --- a/Source/win32/w32_movesize.m +++ b/Source/win32/w32_movesize.m @@ -33,34 +33,37 @@ - (LRESULT) decodeWM_MOVEParams:(HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam { - NSPoint eventLocation; - NSRect rect; - RECT r; - NSEvent *ev = nil; - - GetWindowRect(hwnd, &r); - rect = MSScreenRectToGS(r); - eventLocation = rect.origin; - - ev = [NSEvent otherEventWithType: NSAppKitDefined - location: eventLocation - modifierFlags: 0 - timestamp: 0 - windowNumber: (int)hwnd - context: GSCurrentContext() - subtype: GSAppKitWindowMoved - data1: rect.origin.x - data2: rect.origin.y]; - - - //need native code here? - [EVENT_WINDOW(hwnd) sendEvent: ev]; - + if (flags.HOLD_MINI_FOR_SIZE == FALSE) + { + NSPoint eventLocation; + NSRect rect; + RECT r; + NSEvent *ev = nil; + + GetWindowRect(hwnd, &r); + rect = MSScreenRectToGS(r); + eventLocation = rect.origin; + + ev = [NSEvent otherEventWithType: NSAppKitDefined + location: eventLocation + modifierFlags: 0 + timestamp: 0 + windowNumber: (int)hwnd + context: GSCurrentContext() + subtype: GSAppKitWindowMoved + data1: rect.origin.x + data2: rect.origin.y]; + + + //need native code here? + [EVENT_WINDOW(hwnd) sendEvent: ev]; + } + return 0; } - (LRESULT) decodeWM_SIZEParams:(HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam -{ +{ switch ((int)wParam) { case SIZE_MAXHIDE: @@ -92,22 +95,22 @@ NSRect rect; RECT r; NSEvent *ev =nil; - + GetWindowRect(hwnd, &r); rect = MSScreenRectToGS(r); eventLocation = rect.origin; - + // make event ev = [NSEvent otherEventWithType: NSAppKitDefined - location: eventLocation - modifierFlags: 0 - timestamp: 0 - windowNumber: (int)hwnd - context: GSCurrentContext() - subtype: GSAppKitWindowResized - data1: rect.size.width - data2: rect.size.height]; - + location: eventLocation + modifierFlags: 0 + timestamp: 0 + windowNumber: (int)hwnd + context: GSCurrentContext() + subtype: GSAppKitWindowResized + data1: rect.size.width + data2: rect.size.height]; + [EVENT_WINDOW(hwnd) sendEvent: ev]; [self resizeBackingStoreFor: hwnd]; // fixes part one of bug [5, 25] see notes @@ -125,61 +128,13 @@ return 0; } -- (void) decodeWM_NCCALCSIZEParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd +- (void) decodeWM_NCCALCSIZEParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd { - // stub for future dev - - /*NCCALCSIZE_PARAMS * newRects; - - NSPoint eventLocation; - NSRect rect; - RECT drect; - NSEvent *ev =nil; - - if (wParam == TRUE) - { - // get first rect from NCCALCSIZE_PARAMS Structure - newRects=(NCCALCSIZE_PARAMS *)lParam; - // get rect 1 from array - drect=newRects->rgrc[1]; - - //create a size event and send it to the window - rect = MSScreenRectToGS(drect); - eventLocation = rect.origin; - - // make event - ev = [NSEvent otherEventWithType: NSAppKitDefined - location: eventLocation - modifierFlags: 0 - timestamp: 0 - windowNumber: (int)hwnd - context: GSCurrentContext() - subtype: GSAppKitWindowResized - data1: rect.size.width - data2: rect.size.height]; - - [EVENT_WINDOW(hwnd) sendEvent:ev];*/ - //[[EVENT_WINDOW(hwnd) contentView] display]; - //[self resizeBackingStoreFor:hwnd]; - - - /* ev = [NSEvent otherEventWithType: NSAppKitDefined - location: eventLocation - modifierFlags: 0 - timestamp: 0 - windowNumber: (int)hwnd - context: GSCurrentContext() - subtype: GSAppKitWindowMoved - data1: rect.origin.x - data2: rect.origin.y]; - - [EVENT_WINDOW(hwnd) sendEvent:ev]; - - //printf(" Rect 1 =\n%s", [[self MSRectDetails:drect] cString]); - - } - - //printf("wParam is %s\n", wParam ? "TRUE" : "FALSE");*/ +#if 0 + DefWindowProc(hwnd, WM_NCCALCSIZE, wParam, lParam); + flags._eventHandled = YES; +#endif + return; } - (void) decodeWM_WINDOWPOSCHANGEDParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd @@ -196,34 +151,34 @@ /* For debugging, log current window stack. */ if (GSDebugSet(@"WTrace") == YES) - { - NSString *s = @"Window list:\n"; + { + NSString *s = @"Window list:\n"; - hi = GetDesktopWindow(); - hi = GetWindow(hi, GW_CHILD); - if (hi > 0) - { - hi = GetWindow(hi, GW_HWNDLAST); - } - while (hi > 0) - { - TCHAR buf[32]; + hi = GetDesktopWindow(); + hi = GetWindow(hi, GW_CHILD); + if (hi > 0) + { + hi = GetWindow(hi, GW_HWNDLAST); + } + while (hi > 0) + { + TCHAR buf[32]; - hi = GetNextWindow(hi, GW_HWNDPREV); + hi = GetNextWindow(hi, GW_HWNDPREV); - if (hi > 0 - && GetClassName(hi, buf, 32) == 18 - && strncmp(buf, "GNUstepWindowClass", 18) == 0) - { - if (GetWindowLong(hi, OFF_ORDERED) == 1) - { - hl = GetWindowLong(hi, OFF_LEVEL); - s = [s stringByAppendingFormat: @"%d (%d)\n", hi, hl]; - } - } - } - NSLog(@"window pos changed: %@", s); - } + if (hi > 0 + && GetClassName(hi, buf, 32) == 18 + && strncmp(buf, "GNUstepWindowClass", 18) == 0) + { + if (GetWindowLong(hi, OFF_ORDERED) == 1) + { + hl = GetWindowLong(hi, OFF_LEVEL); + s = [s stringByAppendingFormat: @"%d (%d)\n", hi, hl]; + } + } + } + NSLog(@"window pos changed: %@", s); + } /* This window has changed its z-order, so we take the opportunity * to check that all the GNUstep windows are in the correct order @@ -236,76 +191,76 @@ hi = GetDesktopWindow(); hi = GetWindow(hi, GW_CHILD); while (hi > 0) - { - TCHAR buf[32]; + { + TCHAR buf[32]; - /* Find a GNUstep window which is ordered in and above desktop - */ - while (hi > 0) - { - if (GetClassName(hi, buf, 32) == 18 - && strncmp(buf, "GNUstepWindowClass", 18) == 0 - && GetWindowLong(hi, OFF_ORDERED) == 1 - && (hl = GetWindowLong(hi, OFF_LEVEL)) - > NSDesktopWindowLevel) - { - break; - } - hi = GetNextWindow(hi, GW_HWNDNEXT); - } - - if (hi > 0) - { - NSDebugLLog(@"WTrace", @"sort hi %d (%d)", hi, hl); - /* Find the next (lower in z-order) GNUstep window which - * is ordered in and above desktop - */ - lo = GetNextWindow(hi, GW_HWNDNEXT); - while (lo > 0) - { - if (GetClassName(lo, buf, 32) == 18 - && strncmp(buf, "GNUstepWindowClass", 18) == 0 - && GetWindowLong(lo, OFF_ORDERED) == 1 - && (ll = GetWindowLong(lo, OFF_LEVEL)) - > NSDesktopWindowLevel) - { - break; - } - lo = GetNextWindow(lo, GW_HWNDNEXT); - } + /* Find a GNUstep window which is ordered in and above desktop + */ + while (hi > 0) + { + if (GetClassName(hi, buf, 32) == 18 + && strncmp(buf, "GNUstepWindowClass", 18) == 0 + && GetWindowLong(hi, OFF_ORDERED) == 1 + && (hl = GetWindowLong(hi, OFF_LEVEL)) + > NSDesktopWindowLevel) + { + break; + } + hi = GetNextWindow(hi, GW_HWNDNEXT); + } + + if (hi > 0) + { + NSDebugLLog(@"WTrace", @"sort hi %d (%d)", hi, hl); + /* Find the next (lower in z-order) GNUstep window which + * is ordered in and above desktop + */ + lo = GetNextWindow(hi, GW_HWNDNEXT); + while (lo > 0) + { + if (GetClassName(lo, buf, 32) == 18 + && strncmp(buf, "GNUstepWindowClass", 18) == 0 + && GetWindowLong(lo, OFF_ORDERED) == 1 + && (ll = GetWindowLong(lo, OFF_LEVEL)) + > NSDesktopWindowLevel) + { + break; + } + lo = GetNextWindow(lo, GW_HWNDNEXT); + } - if (lo > 0) - { - NSDebugLLog(@"WTrace", @"sort lo %d (%d)", lo, ll); - /* Check to see if the higher of the two windows should - * actually be lower. - */ - if (hl < ll) - { - HWND higher; + if (lo > 0) + { + NSDebugLLog(@"WTrace", @"sort lo %d (%d)", lo, ll); + /* Check to see if the higher of the two windows should + * actually be lower. + */ + if (hl < ll) + { + HWND higher; - /* Insert the low window before the high one. - * ie after the window preceding the high one. - */ - higher = GetNextWindow(hi, GW_HWNDPREV); - if (higher == 0) - { - higher = HWND_TOP; - } -NSDebugLLog(@"WTrace", @"swap %d (%d) with %d (%d)", hi, hl, lo, ll); - SetWindowPos(lo, higher, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); + /* Insert the low window before the high one. + * ie after the window preceding the high one. + */ + higher = GetNextWindow(hi, GW_HWNDPREV); + if (higher == 0) + { + higher = HWND_TOP; + } + NSDebugLLog(@"WTrace", @"swap %d (%d) with %d (%d)", hi, hl, lo, ll); + SetWindowPos(lo, higher, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); - /* Done this iteration of the sort ... the next - * iteration takes place when we get notified - * that the swap we have just donew is complete. - */ - break; - } - } - hi = lo; - } - } + /* Done this iteration of the sort ... the next + * iteration takes place when we get notified + * that the swap we have just donew is complete. + */ + break; + } + } + hi = lo; + } + } } } @@ -321,9 +276,9 @@ NSDebugLLog(@"WTrace", @"swap %d (%d) with %d (%d)", hi, hl, lo, ll); * desktop level window is inserted below them. */ if (GetWindowLong(hwnd, OFF_LEVEL) <= NSDesktopWindowLevel) - { - inf->hwndInsertAfter = HWND_BOTTOM; - } + { + inf->hwndInsertAfter = HWND_BOTTOM; + } } } @@ -344,6 +299,11 @@ NSDebugLLog(@"WTrace", @"swap %d (%d) with %d (%d)", hi, hl, lo, ll); return 0; } +- (LRESULT) decodeWM_ENTERSIZEMOVEParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd +{ + return DefWindowProc(hwnd, WM_ENTERSIZEMOVE, wParam, lParam); +} + - (LRESULT) decodeWM_EXITSIZEMOVEParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd { // may have a small bug here note it for follow up @@ -352,11 +312,11 @@ NSDebugLLog(@"WTrace", @"swap %d (%d) with %d (%d)", hi, hl, lo, ll); no posting is needed. */ [self resizeBackingStoreFor: hwnd]; - [self decodeWM_MOVEParams:hwnd :wParam :lParam]; - [self decodeWM_SIZEParams:hwnd :wParam :lParam]; - +// [self decodeWM_MOVEParams:hwnd :wParam :lParam]; +// [self decodeWM_SIZEParams:hwnd :wParam :lParam]; + //Make sure DefWindowProc gets called - return 0; + return DefWindowProc(hwnd, WM_EXITSIZEMOVE, wParam, lParam); } - (LRESULT) decodeWM_SIZINGParams:(HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam @@ -367,10 +327,10 @@ NSDebugLLog(@"WTrace", @"swap %d (%d) with %d (%d)", hi, hl, lo, ll); - (LRESULT) decodeWM_MOVINGParams:(HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam { - // stub for future dev - [self decodeWM_MOVEParams:(HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam]; +// [self decodeWM_MOVEParams:(HWND)hwnd : (WPARAM)wParam : (LPARAM)lParam]; + [EVENT_WINDOW(hwnd) display]; - return TRUE; + return TRUE; } @end diff --git a/Source/win32/w32_windowdisplay.m b/Source/win32/w32_windowdisplay.m index 13013a0..2d93a89 100644 --- a/Source/win32/w32_windowdisplay.m +++ b/Source/win32/w32_windowdisplay.m @@ -55,6 +55,7 @@ invalidateWindow(WIN32Server *svr, HWND hwnd, RECT rect) win->backingStoreEmpty = NO; } +#if (BUILD_GRAPHICS==GRAPHICS_winlib) if (win->useHDC) { HDC hdc = GetDC((HWND)hwnd); @@ -65,10 +66,11 @@ invalidateWindow(WIN32Server *svr, HWND hwnd, RECT rect) win->hdc, rect.left, rect.top, SRCCOPY); if (!result) { - NSLog(@"validateWindow failed %d", GetLastError()); + NSWarnMLog(@"validateWindow failed %d", GetLastError()); } ReleaseDC((HWND)hwnd, hdc); } +#endif } @implementation WIN32Server (w32_windowdisplay) diff --git a/Source/winlib/GNUmakefile.preamble b/Source/winlib/GNUmakefile.preamble index 13133f4..4ad6c10 100644 --- a/Source/winlib/GNUmakefile.preamble +++ b/Source/winlib/GNUmakefile.preamble @@ -47,7 +47,7 @@ ADDITIONAL_CFLAGS = -DWINVER=0x0500 # Additional include directories the compiler should search ADDITIONAL_INCLUDE_DIRS = -I../../Headers \ - -I$(GNUSTEP_TARGET_DIR) $(GRAPHIC_CFLAGS) + -I$(GNUSTEP_TARGET_DIR) -I.. $(GRAPHIC_CFLAGS) # Additional LDFLAGS to pass to the linker # ADDITIONAL_LDFLAGS = diff --git a/config.h.in b/config.h.in index 1b7cbab..b5d8907 100644 --- a/config.h.in +++ b/config.h.in @@ -1,8 +1,13 @@ /* config.h.in. Generated from configure.ac by autoheader. */ -#define SERVER_x11 1 -#define SERVER_win32 2 +#define SERVER_x11 1 +#define SERVER_win32 2 +#define GRAPHICS_xdps 0 +#define GRAPHICS_art 1 +#define GRAPHICS_xlib 2 +#define GRAPHICS_winlib 3 +#define GRAPHICS_cairo 4 /* Define to type of graphics context to build */ diff --git a/configure b/configure index b5ba127..228ae70 100755 --- a/configure +++ b/configure @@ -613,6 +613,8 @@ GLITZ_GLX_LIBS GLITZ_GLX_CFLAGS GLITZ_LIBS GLITZ_CFLAGS +FONTCONFIG_LIBS +FONTCONFIG_CFLAGS CAIRO_GLITZ_LIBS CAIRO_GLITZ_CFLAGS CAIRO_WIN32_LIBS @@ -5584,6 +5586,45 @@ fi if test "$have_msimg32" = yes; then WIN32_LIBS="${WIN32_LIBS} -lmsimg32" fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -limm32" >&5 +$as_echo_n "checking for main in -limm32... " >&6; } +if ${ac_cv_lib_imm32_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-limm32 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_imm32_main=yes +else + ac_cv_lib_imm32_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_imm32_main" >&5 +$as_echo "$ac_cv_lib_imm32_main" >&6; } +if test "x$ac_cv_lib_imm32_main" = xyes; then : + have_imm32=yes +else + have_imm32=no +fi + +if test "$have_imm32" = yes; then + WIN32_LIBS="${WIN32_LIBS} -limm32" +fi #-------------------------------------------------------------------- # WGL support @@ -6251,6 +6292,106 @@ $as_echo "$CAIRO_GLITZ_LIBS" >&6; } have_cairo_glitz=no fi +PKG_FONTCONFIG=no + + succeeded=no + + if test -z "$PKG_CONFIG"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "pkg-config script not be found" + ## We don't want the user to see this warning + ## echo "*** The pkg-config script could not be found. Make sure it is" + ## echo "*** in your path, or set the PKG_CONFIG environment variable" + ## echo "*** to the full path to pkg-config." + ## echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fontconfig" >&5 +$as_echo_n "checking for fontconfig... " >&6; } + + if $PKG_CONFIG --exists "fontconfig" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + succeeded=yes + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking FONTCONFIG_CFLAGS" >&5 +$as_echo_n "checking FONTCONFIG_CFLAGS... " >&6; } + FONTCONFIG_CFLAGS=`$PKG_CONFIG --cflags "fontconfig"` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FONTCONFIG_CFLAGS" >&5 +$as_echo "$FONTCONFIG_CFLAGS" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking FONTCONFIG_LIBS" >&5 +$as_echo_n "checking FONTCONFIG_LIBS... " >&6; } + FONTCONFIG_LIBS=`$PKG_CONFIG --libs "fontconfig"` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FONTCONFIG_LIBS" >&5 +$as_echo "$FONTCONFIG_LIBS" >&6; } + else + FONTCONFIG_CFLAGS="" + FONTCONFIG_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + FONTCONFIG_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "fontconfig"` + + fi + + + + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + have_fontconfig=yes + else + have_fontconfig=no + fi + if test "$have_cairo" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cairo_create in -lcairo" >&5 @@ -6915,12 +7056,22 @@ $as_echo "$as_me: WARNING: can't find cairo, required for graphics=cairo!" >&2;} BUILD_GRAPHICS=art fi { $as_echo "$as_me:${as_lineno-$LINENO}: Switching to $BUILD_GRAPHICS" >&5 +$as_echo "$as_me: Switching to $BUILD_GRAPHICS" >&6;} + elif test $BUILD_SERVER = win32 -a "$have_fontconfig" = no ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find fontconfig, required for graphics=cairo!" >&5 +$as_echo "$as_me: WARNING: can't find fontconfig, required for graphics=cairo!" >&2;} + BUILD_GRAPHICS=winlib + { $as_echo "$as_me:${as_lineno-$LINENO}: Switching to $BUILD_GRAPHICS" >&5 $as_echo "$as_me: Switching to $BUILD_GRAPHICS" >&6;} else { $as_echo "$as_me:${as_lineno-$LINENO}: checking Cairo backend" >&5 $as_echo_n "checking Cairo backend... " >&6; } CAIRO_LIBS="$CAIRO_FT_LIBS" CAIRO_CFLAGS="$CAIRO_FT_CFLAGS" + if test $BUILD_SERVER = win32; then + CAIRO_LIBS="$CAIRO_LIBS $FONTCONFIG_LIBS" + CAIRO_CFLAGS="$CAIRO_CFLAGS $FONTCONFIG_CFLAGS" + fi if test "$have_xrender" = yes; then if test $BUILD_SERVER = x11 -a "x$have_cairo_xlib" = "xyes"; then @@ -6957,10 +7108,8 @@ $as_echo "$as_me: WARNING: **** Are you a backend developer ?" >&2;} CAIRO_CFLAGS="$CAIRO_CFLAGS $CAIRO_WIN32_CFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: winlib" >&5 $as_echo "winlib" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: **** Cairo backend on win32 is experimental and is not supported." >&5 -$as_echo "$as_me: WARNING: **** Cairo backend on win32 is experimental and is not supported." >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: **** Are you a backend developer ?" >&5 -$as_echo "$as_me: WARNING: **** Are you a backend developer ?" >&2;} + #AC_MSG_WARN([**** Cairo backend on win32 is experimental and is not supported.]) + #AC_MSG_WARN([**** Are you a backend developer ?]) elif test $BUILD_SERVER = x11 -a "x$have_cairo_xlib" = "xyes"; then CAIRO_LIBS="$CAIRO_LIBS $CAIRO_XLIB_LIBS $XFT_LIBS" CAIRO_CFLAGS="$CAIRO_CFLAGS $CAIRO_XLIB_CFLAGS" @@ -7057,7 +7206,7 @@ _ACEOF cat >>confdefs.h <<_ACEOF -#define BUILD_GRAPHICS $BUILD_GRAPHICS +#define BUILD_GRAPHICS GRAPHICS_$BUILD_GRAPHICS _ACEOF diff --git a/configure.ac b/configure.ac index baba7f2..a953cfe 100644 --- a/configure.ac +++ b/configure.ac @@ -354,6 +354,10 @@ AC_CHECK_LIB(msimg32, main, have_msimg32=yes, have_msimg32=no) if test "$have_msimg32" = yes; then WIN32_LIBS="${WIN32_LIBS} -lmsimg32" fi +AC_CHECK_LIB(imm32, main, have_imm32=yes, have_imm32=no) +if test "$have_imm32" = yes; then + WIN32_LIBS="${WIN32_LIBS} -limm32" +fi #-------------------------------------------------------------------- # WGL support @@ -423,6 +427,8 @@ PKG_CAIRO_WIN32=no PKG_CHECK_MODULES(CAIRO_WIN32, cairo-win32, have_cairo_win32=yes, have_cairo_win32=no) PKG_CAIRO_GLITZ=no PKG_CHECK_MODULES(CAIRO_GLITZ, cairo-glitz, have_cairo_glitz=yes, have_cairo_glitz=no) +PKG_FONTCONFIG=no +PKG_CHECK_MODULES(FONTCONFIG, fontconfig, have_fontconfig=yes, have_fontconfig=no) if test "$have_cairo" = no; then AC_CHECK_LIB(cairo, cairo_create, have_cairo=yes) @@ -551,11 +557,19 @@ if test x"$BUILD_GRAPHICS" = "xcairo"; then BUILD_GRAPHICS=art fi AC_MSG_NOTICE([Switching to $BUILD_GRAPHICS]) + elif test $BUILD_SERVER = win32 -a "$have_fontconfig" = no ; then + AC_MSG_WARN([can't find fontconfig, required for graphics=cairo!]) + BUILD_GRAPHICS=winlib + AC_MSG_NOTICE([Switching to $BUILD_GRAPHICS]) else AC_MSG_CHECKING(Cairo backend) CAIRO_LIBS="$CAIRO_FT_LIBS" CAIRO_CFLAGS="$CAIRO_FT_CFLAGS" - + if test $BUILD_SERVER = win32; then + CAIRO_LIBS="$CAIRO_LIBS $FONTCONFIG_LIBS" + CAIRO_CFLAGS="$CAIRO_CFLAGS $FONTCONFIG_CFLAGS" + fi + if test "$have_xrender" = yes; then if test $BUILD_SERVER = x11 -a "x$have_cairo_xlib" = "xyes"; then AC_DEFINE(XRENDER,1,[Define if you have X11 XRender extension]) @@ -583,8 +597,8 @@ if test x"$BUILD_GRAPHICS" = "xcairo"; then CAIRO_LIBS="$CAIRO_LIBS $CAIRO_WIN32_LIBS $WIN32_LIBS" CAIRO_CFLAGS="$CAIRO_CFLAGS $CAIRO_WIN32_CFLAGS" AC_MSG_RESULT(winlib) - AC_MSG_WARN([**** Cairo backend on win32 is experimental and is not supported.]) - AC_MSG_WARN([**** Are you a backend developer ?]) + #AC_MSG_WARN([**** Cairo backend on win32 is experimental and is not supported.]) + #AC_MSG_WARN([**** Are you a backend developer ?]) elif test $BUILD_SERVER = x11 -a "x$have_cairo_xlib" = "xyes"; then CAIRO_LIBS="$CAIRO_LIBS $CAIRO_XLIB_LIBS $XFT_LIBS" CAIRO_CFLAGS="$CAIRO_CFLAGS $CAIRO_XLIB_CFLAGS" @@ -667,12 +681,17 @@ if test $BUILD_SERVER = win32; then fi AH_TOP([ -#define SERVER_x11 1 -#define SERVER_win32 2 +#define SERVER_x11 1 +#define SERVER_win32 2 +#define GRAPHICS_xdps 0 +#define GRAPHICS_art 1 +#define GRAPHICS_xlib 2 +#define GRAPHICS_winlib 3 +#define GRAPHICS_cairo 4 ]) AC_DEFINE_UNQUOTED(BUILD_SERVER,SERVER_$BUILD_SERVER, [Define to type of window server to build]) -AC_DEFINE_UNQUOTED(BUILD_GRAPHICS,$BUILD_GRAPHICS, +AC_DEFINE_UNQUOTED(BUILD_GRAPHICS,GRAPHICS_$BUILD_GRAPHICS, [Define to type of graphics context to build]) AC_SUBST(BUILD_GRAPHICS) AC_SUBST(BUILD_SERVER)