Control-Shift-Maus

Das Desktop bietet bisher die Möglichkeit, mehrere Dateien oder Icons zu selektieren. dabei muss man bei gedrückter Shift-Taste die Dateien mit dem Mauszeiger anklicken. Ab TOS 1.4 kann man Dateien auch verschieben, das heißt, die Quelldatei wird kopiert und anschliessend gelöscht. Sollen Dateien verschoben werden, muss die Control-Taste gedrückt sein. Wollte man bisher mehrere Dateien verschieben, musste man die Control- und Shift-Taste drücken und die Dateien mit dem Mauszeiger selektieren. Das Programm Control-Shift-Maus ( CS-Maus) ermöglicht jetzt mit Hilfe der rechten Maustaste ein Verschieben oder Kopieren von einzelnen oder mehreren Dateien ohne zusätzliches Drücken der Shift-oder Control-Taste.

Sollen mit CS-Maus mehrere Dateien ausgewählt werden, muß man anstelle der Shift-Taste die rechte Maustaste drücken. Beim Verschieben von Dateien wird auch die Control-Taste durch die rechte Maustaste ersetzt. Das Selektieren der Datei geschieht wie bisher mit einem Klick der linken Maustaste. Will man mit CS-Maus mehrere Dateien verschieben, drückt man einfach die rechte Maustaste wählt die Dateien aus und verschiebt sie bei gedrückter rechter Maustaste in das Zielverzeichnis. Das Selektieren oder Verschieben mehrerer Dateien ist wie bisher mit der Shift-oder Control-Taste möglich. Auch das Kopieren von einem nicht aktiven Fenster in das aktive bei gedrückter rechter Maustaste ist wie bisher möglich.

CS-Maus kann man aus dem Auto-Ordner starten oder direkt vom Desktop. Will man CS-Maus ausschalten, muß das Programm ein zweites Mal gestartet werden. Es wird dann die Meldung ‘CS-Maus AUS’ ausgegeben. Das Einschalten geschieht durch ein erneutes Starten des Programms. CS-Maus ist nur im Desktop aktiv; sobald ein Programm gestartet wird, schaltet es sich selber aus.

Installation

Nun zur Beschreibung des Listings. Das Programm springt zuerst zur Installierungsroutine (INSTALL). Dort werden eine neue Mausroutine installiert und die Adressen von kbshift und run geholt. Die Routine Kbdvbase (XBIOS 34) liefert einen Zeiger auf die KBDVECS-Struktur. In dieser Struktur ist der Mausvektor (.mousevec) enthalten. Das Betriebssystem springt bei jeder Mausbewegung durch diesen Vektor. Da CS-Maus die neue Mausroutine mit dem XBRA-Protokoll anmeldet, kann es auch feststellen, ob CS-Maus schon installiert ist. Eine Verfolgung der Kette ist nur dann möglich, wenn sich jede neue Mausroutine an das XBRA-Protokoll hält. War CS-Maus schon installiert, wird das Programm ein- oder ausgeschaltet. Dazu wird das Flag MAUS-OFF invertiert. Dieses befindet sich 13 Bytes hinter der schon installierten Mausroutine. War die Installation erfolgreich, werden die neue Mausroutine (NEW_MOUSE) und die VBL-Routine (NEU_VBL) resident im Speicher gehalten.

Neue Mausroutine

Wird CS-Maus zum ersten Mal installiert, muß zwischen einem Start aus dem Auto-Ordner und einem vom Desktop unterschieden werden. Deshalb wird versucht, eine Applikation anzumelden (APPL_INIT AES 10). Wird CS-Maus aus dem Auto-Ordner gestartet, ist die ap_version gleich Null, da das AES noch nicht initialisiert ist. Bei einem Start vom Desktop wird der alte Mausvektor in OLD -VEC gespeichert und die Adresse der neuen Mausroutine in die KBDVECS-Struktur eingetragen. Da der Mausvektor erst nach dem Starten aller Programme aus dem Auto-Ordner belegt wird, muß man bei einem Start von CS-Maus aus dem Auto-Ordner anders Vorgehen. Dabei wird eine VBL-Routine {NEU_VBL) installiert. Diese wartet jetzt solange, bis der Mausvektor überschrieben wird. Ist dies der Fall, wird wie beim Starten vom Desktop der alte Mausvektor in OLD_VEC gespeichert und die Adresse der neuen Mausroutine in die KB-DVECS-Struktur eingetragen. Danach wird die VBL-Routine gelöscht.

Aufbau eines Mauspaketes

  1. Byte Header von $F8 bis $FB *
  2. Byte Mausbewegung in x-Richtung
  3. Byte Mausbewegung in y-Richtung

_run und kbshift

Die Zeiger j-un und kbshift sind in der SYSHDR-Struktur abgelegt. Das ist aber erst ab TOS 1.2 der Fall. Bei älteren TOS-Versionen liegen jun bei $602C und kbshift bei $E1B. Den Zeiger auf die SYSHDR-Struktur erhält man durch die Systemvariable _sysbase ($4-f2). _run enthält die Adresse des Zeigers der aktuellen Basepage. Die Länge des Programmcodes ist mit einem Offset von $C in der Basepage abgelegt. Ist die Länge des Programmcodes gleich Null, ist das aktuelle Programm das Desktop. _run wird dazu benutzt, CS-Maus auszuschalten, wenn ein Programm gestartet wird. Der Zeiger kbshift zeigt auf ein Byte, in dem der Tastaturstatus abgelegt ist. Dabei entspricht Bit 0 der rechten Shift-Taste und Bit 2 der Control-Taste. Man kann den Tastaturstatus auslesen oder setzen.

Mauspakete

Der Tastaturprozessor schickt bei jeder Mausbewegung Pakete zur Mausroutine. Diese Mauspakete bestehen aus drei Bytes, deren Adresse ist im Register A0 enthalten. Das erste Byte enthält den Header. In diesem Byte ist der Status der Mausknöpfe abgelegt. Dabei entspricht B it 0 der rechten und Bit 1 der linken Maustaste. Ist eine Taste gedrückt, ist das entsprechende Bit gesetzt. Der Wert des Headers liegt bei Mausbewegungen von $F8 bis $FB. Die relative Mausbewegung in x-Richtung enthält das zweite Byte. Die Mausbewegung in y-Richtung ist im dritten Byte enthalten. Die neue Mausroutine, die nach der erfolgreichen Installation jetzt jedes Mauspaket zuerst erhält, benötigt nur das erste Byte.

Shift und Control

Die neue Mausroutine testet zuerst, ob ein Mauspaket angekommen ist; danach, ob CS-Maus ein- oder ausgeschaltet ist. Wenn der Programmcode gleich Null ist (Desktop aktiv), wird der Maus-Header auf einen rechten Mausdruck getestet. Ist dies der Fall, wird der Zeiger auf den Tastaturstatus geholt. Nun setzt man Bit 0 (Shift) und Bit 2 (Control). Die beiden Bits werden gelöscht, sobald eine Mausbewegung erfolgt, bei der nicht die rechte Maustaste gedrückt ist. Auch wenn das aktuelle Programm nicht mehr das Desktop ist, werden die Bits gelöscht.

Literatur:

[1] Atari ST Profibuch, Sybex

[2] ST Computer 6/90, Seite 83, Springmaus

**Bit-Belegung des Tastaturstatus’**

Bit 0: Shift-Taste rechts *
Bit 1: Shift-Taste links Bit 2: Control-Taste *
Bit 3: Alternate-Taste
Bit 4: Caps Lock gesetzt
Bit 5: Maustaste rechts (Clr Home)
Bit 6: Maustaste links (Insert)
Bit 7: reserviert

Offset | Bezeichnung | Beschreibung ------ | ----------- | ------------ 0 | midivec | Midi-Eingabe 4 | vkbderr | Tastaturfehler 8 | vmiderr | Midi-Fehler 12 | statvec | Status von IKBD lesen 16 | mousevec | Mausabfrage * 20 | clockvec | Uhrzeitabfrage 24 | joyvec | Joystick-Abfrage 28 | midisys | Midi-Systemvektor 32 | ikbdsys | | KBD-Systemvektor
**Belegung der KBDVECS-Struktur**
Offset Bezeichnung Beschreibung
0 os_entry Einsprungadresse
2 os_version TOS-Version *
4 os_start Startadresse des OS-Codes
8 os_base Anfangsadresse des Betriebssystems
12 os_membot Beginn des freien RAM
16 os_shell Default Shell
20 os_magic Zeiger auf GEM-Magic-Variable
24 os_gendat Erstellungsdatum BCD-Format
28 os_palmode PAL oder NTSC
30 os_gendatg Erstellungsdatum GEMDOS-Format

Folgende Variablen erst ab TOS 1.2

     
32 *_root Zeiger auf ‘mifl'-Liste
36 kbshift Zeiger auf Bit-Belegung des Tastaturstatus *
40 **_run Zeiger auf aktuelle Basepage *

Belegung der SYSHDR-Struktur

*-------------------------*
*  Control-Shift-Maus     *
*  by Ralf Stachs         *
* ------------------------*
* (c) 1991 MAXON Computer *
* ------------------------*

;TRAPS
GEMDOS  equ 1 
BIOS    equ 13
XBIOS   equ 14

******************************************* 
;Programmteil der resident im Speicher 
;gehalten wird v. RESI_ANFANG bis RESI_ENDE 
******************************************* 
    TEXT 
RESI_ANFANG:
        bra INSTALL
            ;zur Installationroutine springen

;Flags 
******
    ;FIRST       ->Rechte Maustaste zum ersten mal gedruckt 
    ;           0->Rechte Maustaste noch nicht gedrückt 
    ;           1->Rechte Maustaste war schon gedrückt 
    ;MAUS_OFF    ->schaltet CS_Maus an oder aus
    ;               $00 CS_Maus an
    ;               $FF CS_MAUS aus

FIRST:      dc.b 0
MAOS_OFF:   dc.b 0

        dc.b "XBRA”     ;XBRA Protokoll
        dc.b "RS11"     ;eigene Kennung
0LD_VEC:    dc.l 0      ;alter Mausvektor

;neue Mausroutine
*****************
NEW_MOUSE:
    movem.l d0/a0-a2,-(sp) ;Register retten

;Maus Header?
    move.b (a0),d0      ;Header Kopf in d0

    cmp.b   #$f8,d0     ;kleiner $f8 
    blt     ENDE        ;ja

    cmp.b   #$fb,d0     ;größer $fb 
    bgt     ENDE        ;ja

;Maus ausgeschaltet TOS?
    move.l  A_MOUSE_FLAG,a1 ;Flag für Maus aus (MOUSE_FLAG)

    tst.b   (a1)        ;Maus ausgeschaltet 
    bne     ENDE        ;ja

;CS_Maus ausgeschaltet7
    tst.b   MAUS_OFF    ;CS_MAUS ausgeschaltet 
    bne     ENDE        ;ja

;aktuelles PRG Desktop?
    move.l  A_RUN,a1    ;a1=Adresse auf Zeiger der aktuellen Basepage 
    move.l  (a1),a2     ;a2=Zeiger auf Basepage 
    tst.l   $C(a2)      ;Länge des Programmcode = 0 
    bne     SP_11       ;nein, nicht Desktop

;Rechte Maustaste gedrückt
    btst.b  #0,(a0)     ;rechte Maustaste gedrückt 
    beq     SP_11       ;nein, Flags und Tasten löschen 
                        ;wenn FIRST noch gesetzt

;Rechte Maustaste zum ersten mal gedrückt 
    tst.b   FIRST       ;zum ersten mal
    bne     ENDE        ;nein

;Control und Shift Taste setzen
    move.l  A_KBSHIFT,a1    ;Adresse von Kbshift in a1 
    or.b    #%00000101,(a1) ;Control Taste (Bit 2) setzen 
                            ;und Shift Taste (Bit 0) setzen 
    move.b  #1,FIRST        ;Flag setzen
    bra     ENDE

;Control und Shift Taste löschen
SP_11:      tst.b FIRST     ;First Flag noch gesetzt 
    beq     ENDE            ;Nein, dann Ende

    move.l  A_KBSHIFT,a1    ;Adresse von Kbshift in a1 
    and.b   #%11111010,(a1) ;Control-Taste (Bit 2) löschen 
                            ;und Shift Taste (Bit 0) löschen 
    move.b  #0,FIRST        ;Flag löschen

;alte Mausroutine anspringen 
ENDE:   movem.l (sp)+,d0/a0-a2 ;Register zurückschreiben 
    move.l  OLD_VEC,-(sp)   ;alte Mausroutine 
    rts                     ;anspringen

;VBL-Routine bei Start aus AUTO-Ordner 
**************************************

    dc.b "XBRA"             ;XBRA Protokoll
    dc.b "RS12"             ;eigene Kennung
    dc.l 0                  ;alter Vektor nicht benutzt


NEU_VBL:
    move.l  A_KBDV,a0       ;kdbv Adresse nach a0
    lea     16(a0),a1       ;Adresse Mausvektor a1 
    lea     OLD_VEC,a0      ;alter Mausvektor vom Betriebssystem 
    cmp.l   (a0)+,(a1)+     ;alter Mausvektor noch da 
    beq     SP_3            ;ja

    move.l  -(a1),OLD_VEC   ;alten Mausvektor sichern 
    move.l  #NEW_MOUSE,(a1) ;neue Mausroutine initialisieren

    move.l  A_VBL_SLOT,a0   ;vbl-Slot löschen
    move.l  #0,(a0)

SP_3: rts

;Adressen
*********
    ;A_KBDV       -> Adresse der kbdv Tabelle
    ;A_VBL_SLOT   -> Adresse des VBL-Slot
    ;A_MOUSE_FLAG -> Adresse von MOUSE_FLAG 
    ;   MOUSE_FLAG = 0 ->Maus-Interuptbehandlung ein 
    ;   MOUSE_FLAG <>0 ->Maus-Interuptbehandlung aus 
    ;A_KBSHIFT    -> Adresse von Kbshift
    ;A_RUN        -> Adresse von Zeiger auf aktueller Basepage

A_KBDV:         dc.l 0
A_VBL_SLOT:     dc.l 0
A_MOUSE_FLAG:   dc.l 0
A_KBSHIFT:      dc.l 0
A_RUN :         dc.l 0

RESI_ENDE:


*************************
;Instalierung von CS_Maus 
*************************
;gesammten Programmspeicher belegen 
    EVEN 
INSTALL:
    move.l  sp,a6       ;Adresse BASEPAGE
    lea     USTACK,sp   ;neuer Stack

    move.l  4(a6),a6    ;Speicher belegen
    move.l  $c(a6),a4
    adda.l  $14(a6),a4
    adda.l  $1c(a6),a4

    pea     256(a4)
    pea     (a6)
    clr.w   -(sp)
    move.w  #74,-(sp)   ;Mshrink aufrufen

    trap    #GEMD0S 
    lea     12(sp),sp

;Adresse KBDVECS holen
    move    #34,-(a7)   ;Kbdvbase aufrufen
    trap    #XBIOS 
    addq.l  #2,a7
    move.l  d0,A_KBDV   ;Adresse der Vektortabelle sichern

;CS_Maus schon installiert?
    move.l  A_KBDV,a1   ;Adresse der Vektortabelle nach a1
    move.l  16(a1),a2   ;Adresse von Mausroutine in a2 
    move.l  a2,a0       ;a0 zum suchen

SP_1: cmp.l #"RS11",-8(a0) ;CS_Maus schon vorhanden
    beq     SP_2        ;ja, CS_MAUS init.

    cmp.l   #"XBRA",-12(a0) ;XBRA Kennung 
    bne     SP_4        ;CS_Maus installieren  
                        ;Original Mausvektor oder kein XBRA Protokoll

    move.l  -4(a0),a1   ;Adresse der nächsten Mausroutine 
    move.l  a1,a0       ;von a1 nach a0
    bra     SP_1        ;weiter

;CS_Maus war schon installiert 
*****************************
SP_2: not.b -13(a0)     ;MAUS_OFF invertieren
    bne     SP_7

;Meldung CS_Maus einschalten 
    pea     STRING_3 
    move.w  #9,-(sp) 
    trap    #GEMDOS 
    addq.l  #6,sp 
    bra     SP_8        ;ende

;Meldung CS_Maus auschalten 
SP_7: pea   STRING_4
    move.w  #9,-(sp) 
    trap    #GEMDOS 
    addq.l  #6,sp

;PRG beenden 
SP_8: clr.w -(sp) trap #GEMDOS

;CS_MAUS instalieren 
******************** 
;alten Vektor sichern 
SP_4: lea OLD_VEC,a0 
    move.l  a2,(a0)

;AES-anmelden
    move.w  #10,d0      ;Applikation anmelden
    bsr     AES_INIT    ;AES aufrufen
    tst.w   AES_GLOBAL  ;starten aus AUTO-Ordner 
    beq     SP_6        ;ja, keine ap_version

;Vom Desktop starten 
********************
;maus installieren
    lea     DESKTOP,a0  ;Adresse von Desktop nach a0
    pea     (a0)
    move.w  #38,-(sp)   ;Supexec aufrufen
    trap    #XBIOS 
    addq.l  #6,sp 
    bra     SP_5

;Aus AUTO-Ordner starten 
************************
;Unterprogramm im Supervisor-Modus ausführen
SP_6: lea   AUTO,a0     ;Adresse von auto nach a0
    pea     (a0)
    move.w  #$26,-(sp) ;Supexec aufrufen
    trap    #XBIOS 
    addq.l  #6,sp

;Adresse von MOUSE_FLAG holen 
SP_5: dc.w  $a000       ;Adresse negative Line-A Variabelen
    sub.l   #$153,a0    ;Adresse MOUSE-FLAG berechnen 
    move.l  a0,A_MOUSE_FLAG ;MOUSE FLAG merken

;installierung i.o. 
    pea     STRING_1 
    move.w  #9,-(sp) 
    trap    #GEMDOS 
    addq.l  #6,sp

;Speicherplatz für Mausroutine 
;resident im Speicher halten 
    clr.w   -(sp)
    pea     RESI_ENDE-RESI_ANFANG+256 
    move.w  #49,-(a7)   ;Ptermres aufrufen
    trap    #GEMDOS

***************************
;Unterprogramme von CS_MAUS 
***************************

;PRG im Supervisor-Modus Mausroutine installieren 
*******************************************
;starten aus AUTO Ordner 
;VBL installieren
AUTO: move.w $454,d0    ;Anzahl der VBL-Routinen (nvbls) 
    lsl     #2,d0       ;Anzahl*4
    move.l  $456,a0     ;Zeiger auf VBL (_vblqueue) 
    clr     d1          ;Zähler

WEITER: tst.l 4(a0,d1)  ;VBL Slot frei
    beq     FREI        ;ja
    add     #4,d1       ;nächster Slotpointer 
    cmp.w   d0,d1       ;alle slots abgefragt
    bne     WEITER

;CS_Maus nicht initialisieren
    pea     STRING_2    ;Alle Slots besetzt
    move.w  #9,-(sp) 
    trap    #GEMDOS 
    addq.l  #6,sp

    clr.w   -(sp)       ;PRG beenden
    trap    #GEMDOS

FREI: lea   4(a0,d1),a2 ;Adresse Slot in a2 
    lea     NEU_VBL,a1  ;Adresse neue Routine
    move.l  a1,(a2)     ;neue Routine einhängen 
    lea     A_VBL_SLOT,a1 ;Slot Adresse
    move.l  a2,(a1)     ;sichern

;Adresse von Kbshift ermitteln und 
;Adresse von Zeiger auf aktueller Basepage 
SP_10: move.l #$e1b,A_KBSHIFT ;Vorgabe für TOS 1.0 (Kbshift) 
    move.l  #$602c,A_RUN ;Vorgabe für TOS 1.0 (Basepage)

    move.l  $4f2,a0     ;(a0) _sysbase

    cmp.w   #$0100,2(a0) ;TOS 1 0
    beq     SP_9        ;ja

    move.l  36(a0),a1   ;(a1) Adresse von Kbshift 
    move.l  a1,A_KBSHIFT ;Adresse merken

    move.l  40(a0),a1   ;(a1) Adresse auf Zeiger der aktuellen Basepage 
    move.l  a1,A_RUN    ;Adresse merken

SP_9: rts

;PRG im Supervisor-Modus Mausroutine instal1ieren 
*******************************************
;Starten vom Desktop 
DESKTOP:
    move.l  A_KBDV,a0   ;Keyboardadresse nach a0
    lea     NEW_MOUSE,a1 ;Adresse neue Mausroutine 
    move.l  a1,16(a0)   ;neuen Vektor setzen
                        ;Kbshift und Zeiger auf 
    bra     SP_10       ;aktueller Basepage ermitteln

;AES aufrufen 
*************
AES_INIT:
    lea     CONTRL,a0   ;Adresse CONTRL nach a0
    move.w  d0,(a0)+    ;Opcode
    clr.w   (a0)+       ;einträge INIT_IN
    move.w  #1,(a0)     ;einträge INIT_OUT
    clr.w   (a0)+       ;einträge ADDR_IN
    clr.w   (a0)        ;einträge ADDR_OUT

    move.l  #AES_DATA,d1 ;Adresse AES-Array
    move.w  #$c8,d0     ;AES-Aufruf
    trap    #2
    rts


    DATA 
    EVEN 
STRING_1:
    dc.b 27,"E",27,"p"
    dc.b 13,10,"+***************************+" 
    dc.b 13,10,"+                           +"
    dc.b 13,10,"+  Control-Shift-Maus  1.0  +"
    dc.b 13,10,"+           CS_MAUS         +"
    dc.b 13,10,"+                           +"
    dc.b 13,10,"+    7/91  Ralf Stachs      +"
    dc.b 13,10,”+        ST Computer        +"
    dc.b 13,10,"+                           +"
    dc.b 13,10,"+***************************+" 
    dc.b 13,10 
    dc.b 27,"q",0

    EVEN 
STRING_2:
    dc.b 13,10,"Alle VBL-Slots besetzt",13, 10,0

    EVEN 
STRING_3:
    dc.b 27,"E"
    dc.b 13,10,"*****************" 
    dc.b 13,10,"*  CS_MAUS EIN  *" 
    dc.b 13,10,"*****************",0

    EVEN
STRING_4:
    dc.b 27,"E",27,"p" 
    dc.b 13,10,"*****************" 
    dc.b 13,10,"*  CS_MAUS AUS  *" 
    dc.b 13,10,"*****************" 
    dc.b 27,"q",0

    EVEN
AES_DATA:
        dc.l CONTRL 
        dc.l AES_GLOBAL 
        dc.l INIT_IN 
        dc.l INIT_OUT 
        dc.l ADDR_IN 
        dc.l ADDR_OUT

    BSS
AES_GLOBAL: ds.w 15 
CONTRL:     ds.w 10
INIT_IN:    ds.w 128
INIT_OUT:   ds.w 128
ADDR_IN:    ds.l 128
ADDR_OUT:   ds.l 128

            ds.b 100
USTACK:     ds.w 0

Ralf Stachs
Aus: ST-Computer 12 / 1991, Seite 93

Links

Copyright-Bestimmungen: siehe Über diese Seite