diff -r b5a20c01d46f -r fa3c8eb0bc1d WinWorkstation.st --- a/WinWorkstation.st Wed Dec 14 23:35:42 2016 +0000 +++ b/WinWorkstation.st Thu Dec 15 20:11:12 2016 +0000 @@ -6674,9 +6674,22 @@ displayName "return the display-connections display name. - For Windows, a dummy name is returned" - - ^ 'local' + For Windows, a name of window station is returned" + | err | + +%{ + if (__isExternalAddress(__INST(displayId))) { + HANDLE station = (HANDLE)__externalAddressVal(__INST(displayId)); + char stationName[256]; + DWORD stationNameLen = 0; + + stationName[255] = '\0'; + if ( GetUserObjectInformation ( station, UOI_NAME, stationName, 255, &stationNameLen)) { + RETURN( __MKSTRING(stationName)); + } + } +%}. + self primitiveFailed: err ! focusFollowsMouse:aBoolean @@ -15314,16 +15327,68 @@ %} ! -primInitializeFor:aDisplayName - "initialize the receiver for a connection to a display; - the argument, aDisplayName may be nil (for the default display) - or the name of the display server as hostname:number - (not yet under WIN32)" - -%{ /* NOCONTEXT */ - - RETURN ( __MKSMALLINT(1) ); -%}. +primInitializeFor:stationNameOrNil + "Initialize the receiver for a connection to given window station. + It the argument `stationNameOrNil` is nil, then it connects + to process default window station. + + Return an external address for window station handle or nil if + requested window station is not an interactive one (i.e, one + cannot initialize Win32Workstation on non-interactive window + station). + + See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687096(v=vs.85).aspx + " + + | errcode | + +%{ + HWINSTA station; + if (stationNameOrNil == nil) { + station = GetProcessWindowStation(); + if (station == NULL) { + errcode = __MKINT( GetLastError() ); + goto err; + } + /* + * Check we're connected to "WinSta0" station, only this + * one is interactive one. + */ + char stationName[8]; + int stationNameLen; + if ( GetUserObjectInformation ( station, UOI_NAME, stationName, 9, &stationNameLen) ) { + if (strncmp(stationName, "WinSta0", 8) == 0) { + RETURN ( __MKEXTERNALADDRESS ( station ) ); + } + } + RETURN ( nil ); + + } else if (__isStringLike( stationNameOrNil)) { + if (strncmp(__stringVal(stationNameOrNil), "WinSta0", 8) == 0) { + /* + * We're explicitly asked to connect to "WinSta0" station. + * This could be hand for example when Smalltalk is running as + * a service on non-interactive session and want to open + * a window to inform user. Maybe, maybe not. Anyway, do our best + * here. + */ + station = OpenWindowStation("WinSta0", TRUE, NULL); + if (station == NULL) { + errcode = __MKINT( GetLastError() ); + goto err; + } + if ( ! SetProcessWindowStation(station) ) { + errcode = __MKINT( GetLastError() ); + goto err; + } + RETURN ( __MKEXTERNALADDRESS ( station ) ); + } + RETURN ( nil ); + } + err:; +%}. + self primitiveFailed: errcode + ! reinitialize