SynchronousWindowSensor.st
author Stefan Vogel <sv@exept.de>
Sat, 20 Mar 2004 16:43:19 +0100
changeset 4120 bd779aa2b314
parent 3888 1e06f949dc58
child 4212 b04d89b5695a
permissions -rw-r--r--
Use Timestamp/#asTimestamp instead of AbsoluteTime/#asAbsoluteTime

"
 COPYRIGHT (c) 1995 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

"{ Package: 'stx:libview' }"

WindowSensor subclass:#SynchronousWindowSensor
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'Interface-Support'
!

!SynchronousWindowSensor class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1995 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

documentation
"
    These sensors are not used with regular views.

    In contrast to a regular windowSensor, instances of SynchronousWindowSensor
    do NOT put events into a queue and do NOT wakeup any windowGroup process.
    Instead, the underlying view is notified synchronously (via a message send)
    immediately about the event.

    SynchronousWindowSensor are used for only one single situation: 
        when a super-modal debugger is open
    (i.e. one that is debugging the scheduler or event-dispatcher).

    This debugger's windowGroup is augmented with a synchronous Sensor, in order
    to prevent the event handling code from suspending any process 
    (you cannot suspend the scheduler; you should not suspend the event dispatcher).

    This is pretty tricky and magic - and you dont have to understand this.
    (consider this system internal code)

    [author:]
        Claus Gittinger
"
! !

!SynchronousWindowSensor methodsFor:'dummy event flushing'!

compressKeyPressEventsWithKey:aKey
    ^ 0
!

flushEventsFor:aViewOrNil inQueue:anEventQueue where:aCondition
    ^ nil
! !

!SynchronousWindowSensor methodsFor:'event processing'!

addDamage:aRectangle view:aView wakeup:doWakeup
    "forward as an expose for some view"

    aView
        dispatchEvent:#exposeX:y:width:height:
        arguments:(Array with:aRectangle left 
                         with:aRectangle top 
                         with:aRectangle width
                         with:aRectangle height)
!

buttonMotion:buttonAndModifierState x:x y:y view:aView
    "forward a button-motion for some view"

    |buttonState ev|

    "/ in the following, we are only interested in the buttons (i.e. mask out the modifiers)
    buttonState := buttonAndModifierState bitAnd:(aView device anyButtonStateMask).

    ev := WindowEvent buttonMotion:buttonState x:x y:y view:aView.
    self sendEvent:ev to:aView.
!

buttonMultiPress:button x:x y:y view:aView
    "forward a button-multi-press event for some view"

    |ev|

    ev := WindowEvent buttonMultiPress:button x:x y:y view:aView.
    self sendEvent:ev to:aView.

    "Created: / 24.11.1995 / 19:14:14 / cg"
    "Modified: / 20.5.1998 / 22:56:07 / cg"
!

buttonPress:button x:x y:y view:aView
    "forward a button-press event for some view"

    |ev|

    ev := WindowEvent buttonPress:button x:x y:y view:aView.
    self sendEvent:ev to:aView.
!

buttonRelease:button x:x y:y view:aView
    "forward a button-release event for some view"

    |ev|

    ev := WindowEvent buttonRelease:button x:x y:y view:aView.
    self sendEvent:ev to:aView.
!

configureX:x y:y width:w height:h view:aView
    "forward a configure for some view"

    |ev|

    ev := WindowEvent configureX:x y:y width:w height:h view:aView.
    aView dispatchEvent:ev
!

exposeX:x y:y width:w height:h view:aView
    "forward an expose for some view"

    ignoreExposeEvents ~~ true ifTrue:[
        aView
            dispatchEvent:#exposeX:y:width:height:
            arguments:(Array with:x with:y with:w with:h)
    ]
!

graphicsExposeX:x y:y width:w height:h final:final view:aView
    "forward a graphic expose for some view"

    "/ this is a possible response to a scroll operation
    "/ (if an expose is pending)

    final ifTrue:[
        (catchExpose includes:aView) ifTrue:[
            gotExpose add:aView.
        ]
    ].

    aView
        dispatchEvent:#graphicsExposeX:y:width:height:final:
        arguments:(Array with:x with:y with:w with:h with:final)

    "Created: / 24.11.1995 / 19:16:38 / cg"
    "Modified: / 20.5.1998 / 22:57:32 / cg"
!

keyPress:untranslatedKey x:x y:y view:aView
    "forward a key-press event for some view"

    |xlatedKey ev|

    self key:untranslatedKey state:true. 

    xlatedKey := aView graphicsDevice translateKey:untranslatedKey forView:aView.
    xlatedKey notNil ifTrue:[
        ev := WindowEvent 
                keyPress:xlatedKey
                rawKey:untranslatedKey
                hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
                button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown
                x:x y:y view:aView.

        self sendEvent:ev to:aView.
    ]

    "Created: / 24.11.1995 / 19:17:23 / cg"
    "Modified: / 20.5.1998 / 22:57:52 / cg"
!

keyRelease:untranslatedKey x:x y:y view:aView
    "forward a key-release event for some view"

    |xlatedKey ev|

    self key:untranslatedKey state:false. 

    xlatedKey := aView graphicsDevice translateKey:untranslatedKey forView:aView.
    xlatedKey notNil ifTrue:[
        ev := WindowEvent
                keyRelease:xlatedKey
                rawKey:untranslatedKey
                hasShift:shiftDown ctrl:ctrlDown alt:altDown meta:metaDown
                button1:leftButtonDown button2:middleButtonDown button3:rightButtonDown
                x:x y:y view:aView.

        self sendEvent:ev to:aView.
    ]

    "Created: / 24.11.1995 / 19:17:50 / cg"
    "Modified: / 20.5.1998 / 22:58:05 / cg"
!

mouseWheelMotion:buttonState x:x y:y amount:amount deltaTime:dTime view:aView
    "forward a wheel-motion for some view"

    |ev|

    ev := WindowEvent mouseWheelMotion:buttonState x:x y:y amount:amount deltaTime:dTime view:aView.
    self sendEvent:ev to:aView.

    "Created: / 21.5.1999 / 13:07:51 / cg"
!

noExposeView:aView
    "forward a noExpose event for some view"

    catchExpose isNil ifTrue:[
	'SWSensor [info]: noExpose but not catching' infoPrintCR.
    ].

    (catchExpose includes:aView) ifTrue:[
	gotExpose add:aView.
	catchExpose remove:aView.
    ].
    aView noExpose.

    "Created: 24.11.1995 / 19:18:10 / cg"
    "Modified: 29.1.1997 / 20:46:47 / cg"
!

pointerEnter:buttonState x:x y:y view:aView
    "forward a pointer enter for some view"

    |ev|

    ev := WindowEvent pointerEnter:buttonState x:x y:y view:aView.
    aView dispatchEvent:ev

    "Created: / 24.11.1995 / 19:18:20 / cg"
    "Modified: / 20.5.1998 / 22:58:20 / cg"
!

pointerLeave:buttonState view:aView
    "forward a pointer leave for some view"

    |ev|

    ev := WindowEvent pointerLeave:buttonState view:aView.
    aView dispatchEvent:ev

    "Created: / 24.11.1995 / 19:18:30 / cg"
    "Modified: / 20.5.1998 / 22:58:35 / cg"
!

saveAndTerminateView:aView
    "forward a saveAndTerminate event for some view"

    aView saveAndTerminate

    "Created: 24.11.1995 / 19:18:38 / cg"
!

terminateView:aView
    "forward a terminate event for some view"

    aView terminate

    "Created: 24.11.1995 / 19:18:48 / cg"
! !

!SynchronousWindowSensor methodsFor:'event processing-private'!

pushDamageEvent:ev
    self sendEvent:ev to:ev view
!

pushUserEvent:selector for:anyObject withArguments:argList
    ^ anyObject perform:selector withArguments:argList.
! !

!SynchronousWindowSensor methodsFor:'private'!

sendEvent:anEvent to:aView
    WindowGroup lastEventQuerySignal answer:anEvent do:[
        aView dispatchEvent:anEvent
    ].
! !

!SynchronousWindowSensor methodsFor:'specials'!

catchExposeFor:aView
    "start catching noExpose events (must be done BEFORE a bitblt)."

    catchExpose notEmpty ifTrue:[
	'SWSensor [warning]: already catching in catchExpose' errorPrintCR.
    ].

    gotOtherEvent remove:aView ifAbsent:nil.
    gotExpose remove:aView ifAbsent:nil.
    catchExpose add:aView.

    "Modified: 29.1.1997 / 20:43:44 / cg"
!

waitForExposeFor:aView
    "wait until a graphicsExpose or a noExpose arrives (after a bitblt)."

    |device windowId stopPoll endPollTime|

    device := aView graphicsDevice.

    "/ this is only needed for X ...
    device scrollsAsynchronous ifTrue:[
        windowId := aView id.

        "/
        "/ cannot suspend, I am a synchronous-modal sensor
        "/ must poll for the event
        "/
        endPollTime := Timestamp now addSeconds:10.
        stopPoll := false.

        [(gotExpose includes:aView) or:[stopPoll]] whileFalse:[
            (device exposeEventPendingFor:windowId withSync:true) ifTrue:[
                device dispatchExposeEventFor:windowId.
            ].
            stopPoll := Timestamp now > endPollTime.
            Processor yield.
        ].

        stopPoll ifTrue:[
            'SyncWindowSensor [warning]: lost expose event' errorPrintCR.
        ]
    ].

    catchExpose remove:aView ifAbsent:nil.
    gotExpose remove:aView ifAbsent:nil.

    "Modified: 19.8.1997 / 17:25:09 / cg"
! !

!SynchronousWindowSensor class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libview/SynchronousWindowSensor.st,v 1.26 2004-03-20 15:42:56 stefan Exp $'
! !