WindowGroup.st
author claus
Sun, 19 Dec 1993 01:46:41 +0100
changeset 19 74683e998f36
parent 17 be9898c59977
child 23 4a7e02de7b72
permissions -rw-r--r--
*** empty log message ***

'From Smalltalk/X, Version:2.8.2 on 29-nov-1993 at 15:22:58'!

Object subclass:#WindowGroup
         instanceVariableNames:'views topViews myProcess mySensor'
         classVariableNames:'ActiveGroup'
         poolDictionaries:''
         category:'Interface-Support'
!

!WindowGroup class methodsFor:'instance creation'!

new
    ^ self basicNew initialize
! !

!WindowGroup methodsFor:'accessing'!

addView:aView
    views isNil ifTrue:[
        views := OrderedCollection new.
    ].
    views add:aView
!

sensor
    ^ mySensor
!

removeView:aView
    views notNil ifTrue:[
        views remove:aView ifAbsent:[].
        views isEmpty ifTrue:[
            views := nil
        ]
    ].
    topViews notNil ifTrue:[
        topViews remove:aView ifAbsent:[].
        topViews isEmpty ifTrue:[
            topViews := nil
        ]
    ].

    (views isNil and:[topViews isNil]) ifTrue:[
        views := nil.
        topViews := nil.
        myProcess notNil ifTrue:[
            myProcess terminate
        ]
    ].
!

views
    ^ views
!

process 
    ^ myProcess
!

sensor:aSensor
    mySensor := aSensor
!

addTopView:aView
    topViews isNil ifTrue:[
        topViews := OrderedCollection new.
    ].
    topViews add:aView
! !

!WindowGroup methodsFor:'event handling'!

processEvent
    "process a single event from either the damage- or
     user input queues"

    |damage event view rect|

    ActiveGroup := self.
    [mySensor hasDamage] whileTrue:[
        damage := mySensor nextDamage.
        view := damage at:1.
        rect := damage at:2.
        view exposeX:rect left y:rect top width:rect width height:rect height
    ].
    [mySensor hasEvents] whileTrue:[
        event := mySensor nextEvent.
        event sendEvent
    ]
!

eventLoop
    "loop executed by windowGroup process;
     wait-for and process events forever"

   [true] whileTrue:[
        mySensor eventSemaphore wait.
        self processEvent
   ]
! !

!WindowGroup methodsFor:'activation / deactivation'!

startup
    "startup the window-group;
     this creates a new window group process, which
     does the event processing."

    myProcess isNil ifTrue:[
        myProcess := [
            self eventLoop
        ] forkAt:Processor userSchedulingPriority.

        (topViews notNil and:[topViews isEmpty not]) ifTrue:[
            "give the handler process a user friendly name"
            myProcess name:(topViews first name)
        ] ifFalse:[
            myProcess name:'window handler'.
        ].

        "when the process dies, we have to close-down
         the views as well"
        myProcess exitAction:[self closeDownViews]
    ]
!

closeDownViews
    "destroy all views associated to this window group"

    topViews notNil ifTrue:[
        topViews do:[:aTopView | aTopView destroy]
    ].
    views := nil.
    topViews := nil.
!

shutdown
    "shutdow the window group; close all views and
     terminate process"

    self closeDownViews.
    myProcess notNil ifTrue:[
        myProcess terminate.
        myProcess := nil
    ]
! !

!WindowGroup methodsFor:'initialization'!

reinitialize
    "throw away old (zombie) process"
    myProcess := nil.

    "throw away old events"
    self initialize
!

initialize
    "setup the windowgroup, by creating a new sensor
     and an event semaphore"

    mySensor := WindowSensor new.
    mySensor eventSemaphore:Semaphore new
! !

!WindowGroup methodsFor:'printing'!

printString
    "return a printed representation;
     just for more user friendlyness, add name of process."

    myProcess isNil ifTrue:[^ super displayString].
    ^ 'WindowGroup(' , myProcess nameOrId , ')'
! !