Issue #134: Added generic implementation of `#sendKeyOrButtonEvent:..` to `DeviceWorkstation` jv
authorJan Vrany <jan.vrany@fit.cvut.cz>
Sat, 06 May 2017 11:26:33 +0100
branchjv
changeset 8073 fd95fdcb8533
parent 8016 653376a94c8f
child 8077 08cff8ab7e0a
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
DeviceWorkstation.st
WinWorkstation.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
--- 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: <not expanded> $'
 ! !