# HG changeset patch # User Jan Vrany # Date 1494066393 -3600 # Node ID fd95fdcb8533d6cc2220294058134ff82d75cdad # Parent 653376a94c8f90590160b75eeb2a0943f3d46ed0 Issue #134: Added generic implementation of `#sendKeyOrButtonEvent:..` to `DeviceWorkstation` ...as a fallback. This implementation works purely on a Smalltalk level by directly injecting (St/X) events in (St/X) window group's event queue, completely bypassing windowing system. The implementation is icomplete and is designed and tested only with UI testing framework (stx:goodies/sunit/ext/ui) to allow UI testing on systems with no specific implementation of `#sendKeyOrButtonEvent...` - e.g. Windows at the time. https://swing.fit.cvut.cz/projects/stx-jv/ticket/134 diff -r 653376a94c8f -r fd95fdcb8533 DeviceWorkstation.st --- a/DeviceWorkstation.st Tue Apr 25 11:20:05 2017 +0200 +++ b/DeviceWorkstation.st Sat May 06 11:26:33 2017 +0100 @@ -5168,7 +5168,49 @@ The non-nil case is the lowlevel entry, where state must include any shift/ctrl information (not very user friendly)" - self subclassResponsibility + "/ WARNING: this is a generic implementation that completely bypasses underlaying + "/ system event queue. It may not be complete - it has been written as a quick hack + "/ to make UI testing framework kind-of working on systems where there's no proper + "/ implementation of this method (e.g., Windows at the time) + + | view shiftWasDown ctrlWasDown altWasDown metaWasDown | + + view := self viewFromId: targetId. + + [ + shiftWasDown := shiftDown. + altWasDown := altDown. + metaWasDown := metaDown. + ctrlWasDown := ctrlDown. + stateMask notNil ifTrue:[ + shiftDown := (stateMask bitAnd: self shiftModifierMask) ~~ 0. + altDown := (stateMask bitAnd: self altModifierMask) ~~ 0. + metaDown := (stateMask bitAnd: self metaModifierMask) ~~ 0. + ctrlDown := (stateMask bitAnd: self ctrlModifierMask) ~~ 0. + ]. + (typeSymbol == #keyPress or:[ typeSymbol == #keyRelease ]) ifTrue:[ + | key | + + key := keySymCodeOrButtonNr. + (#(Left Right Up Down) includes: key) ifTrue:[ + key := (#Cursor , key) asSymbol. + ]. + typeSymbol == #keyPress ifTrue:[ + self keyPress:key x:1 y:1 view:view. + ] ifFalse:[ + self keyRelease:key x:1 y:1 view:view. + ] + ] ifFalse:[ + self notYetImplemented. + ]. + ] ensure:[ + shiftDown := shiftWasDown. + altDown := altWasDown. + metaDown := metaWasDown. + ctrlDown := ctrlWasDown. + ]. + + "Modified (comment): / 06-05-2017 / 11:15:25 / jv" ! simulateKeyboardInput:aCharacterOrString inViewId:viewId diff -r 653376a94c8f -r fd95fdcb8533 WinWorkstation.st --- a/WinWorkstation.st Tue Apr 25 11:20:05 2017 +0200 +++ b/WinWorkstation.st Sat May 06 11:26:33 2017 +0100 @@ -19,7 +19,7 @@ classVariableNames:'BeepDuration NativeDialogs NativeFileDialogs NativeWidgets NativeWidgetClassTable StandardColorValues IgnoreSysColorChanges IgnoreFontChanges SystemColorValues CanEndSession - VerboseNativeDialogs ' + VerboseNativeDialogs' poolDictionaries:'' category:'Interface-Graphics' ! @@ -6495,7 +6495,7 @@ ' Peak User Objects = ' errorPrint. counts second errorPrintCR. ' # GDI Objects = ' errorPrint. counts third errorPrintCR. ' Peak GDI Objects = ' errorPrint. counts fourth errorPrintCR. -! +! printHandleCounts "show prim values" @@ -8090,55 +8090,6 @@ "Modified: / 28-01-2012 / 10:20:30 / cg" ! -destroyGC:aGCId -%{ - if (__isExternalAddress(aGCId)) { - struct gcData *gcData = _GCDATA(aGCId); - - if (gcData == NULL) { - console_fprintf(stderr, "WinWorkstation [warning]: trying to destroy GC twice\n"); - RETURN(self); - } - -#ifdef COUNT_RESOURCES - __cnt_gcData--; - RESPRINTF(("DestroyGcData %d\n",__cnt_gcData)); -#endif - -#ifdef CACHE_LAST_DC - if (lastGcData == gcData) { - _releaseDC(gcData); - } -#endif - __ExternalAddressInstPtr(aGCId)->e_address = NULL; - - freeGcData(gcData); - } -%} -! - -destroyPixmap:aDrawableId - -%{ /* NOCONTEXT */ - if (__isExternalAddress(aDrawableId) && ISCONNECTED) { - HANDLE bitmapHandle = _HANDLEVal(aDrawableId); - - if (bitmapHandle) { -#ifdef COUNT_BMP_RESOURCES - __cnt_bitmap--; - RES_BMP_PRINTF(("DestroyPixmap %x %d\n", bitmapHandle, __cnt_bitmap)); -#endif - _DeleteObject(bitmapHandle, __LINE__); - } - } -%} -! - -destroyView:aView withId:aWindowId - self primDestroyView:aView withId:aWindowId. - self removeKnownView:aView withId:aWindowId -! - dcGetClipBoxForGC: gcId "Return clipping box for given device context (as #(left top right bottom) ). " @@ -8201,7 +8152,7 @@ err:; %}. ^ self primitiveFailed: error -! +! dcUnlockForGC:gcId "Unlocks and __destroy__ a device context for given GC previously @@ -8224,7 +8175,56 @@ err:; %}. ^ self primitiveFailed: error -! +! + +destroyGC:aGCId +%{ + if (__isExternalAddress(aGCId)) { + struct gcData *gcData = _GCDATA(aGCId); + + if (gcData == NULL) { + console_fprintf(stderr, "WinWorkstation [warning]: trying to destroy GC twice\n"); + RETURN(self); + } + +#ifdef COUNT_RESOURCES + __cnt_gcData--; + RESPRINTF(("DestroyGcData %d\n",__cnt_gcData)); +#endif + +#ifdef CACHE_LAST_DC + if (lastGcData == gcData) { + _releaseDC(gcData); + } +#endif + __ExternalAddressInstPtr(aGCId)->e_address = NULL; + + freeGcData(gcData); + } +%} +! + +destroyPixmap:aDrawableId + +%{ /* NOCONTEXT */ + if (__isExternalAddress(aDrawableId) && ISCONNECTED) { + HANDLE bitmapHandle = _HANDLEVal(aDrawableId); + + if (bitmapHandle) { +#ifdef COUNT_BMP_RESOURCES + __cnt_bitmap--; + RES_BMP_PRINTF(("DestroyPixmap %x %d\n", bitmapHandle, __cnt_bitmap)); +#endif + _DeleteObject(bitmapHandle, __LINE__); + } + } +%} +! + +destroyView:aView withId:aWindowId + self primDestroyView:aView withId:aWindowId. + self removeKnownView:aView withId:aWindowId +! gcFor:aDrawableId @@ -13171,8 +13171,9 @@ The non-nil case is the lowlevel entry, where state must include any shift/ctrl information (not very user friendly)" - 'WinWorkstation [warning]: sendKeyOrButtonEvent unimplemented' infoPrintCR. - ^ false + super sendKeyOrButtonEvent:typeSymbol x:xPos y:yPos keyOrButton:keySymCodeOrButtonNr state:stateMask toViewId:targetId + + "Modified: / 06-05-2017 / 11:19:03 / jv" ! ! !WinWorkstation methodsFor:'font stuff'! @@ -19612,6 +19613,11 @@ version_CVS ^ '$Header$' +! + +version_HG + + ^ '$Changeset: $' ! !