Mäuse und Knöpfe - oder die vergessene Taste

Nur die wenigsten Programme auf dem ATARI ST erinnern sich daran, dass die Maus nicht nur eine, sondern zwei Tasten hat. Da die Abfrage der rechten Maustaste vom GEM nur unvollkommen unterstützt wird, ist sie dementsprechend wenig zu Ehren gekommen.

Dabei ist es mit wenigen zusätzlichen Programmzeilen möglich, die rechte Maustaste genauso effizient in einem Programm abzufragen, wie die linke.

Sehen wir uns zunächst jedoch erst einmal die Möglichkeiten an, die das Betriebssystem von sich aus zur Abfrage der beiden Maustasten bietet. So versorgt uns das VDI mit der vq_mouse (SAMPLE MOUSE BUTTON STATE)-Routine. Das AES stellt uns graf_mkstate zur Verfügung. Will man eine der beiden angegebenen Funktionen zur Abfrage der Maustasten verwenden, erfordert dies eine Abfrage, die regelmäßig, z.B. in einer Programmschleife, erfolgen muß. Damit ein Mausklick möglichst bald erkannt wird, sollte diese Abfrage möglichst häufig erfolgen. Soll gar auf einen Doppelklick reagiert werden, wird das Ganze schon recht kompliziert.

Aber noch brauchen wir die Flinte nicht ins Korn zu werfen. Um die linke Maustaste mit möglichst wenig Aufwand abzufragen, gibt es ja noch den evnt_button- bzw. evnt_multi-Aufruf des AES. Dies stellt die sinnvollste Möglichkeit zur Abfrage der Maustaste dar, da hier erst dann wieder in das aufrufende Programm zurückgekehrt wird, wenn sich eine Aktion ereignet hat, die mit dem linken Maus-Button in Verbindung steht. Und somit sind wir auch schon beim größten Pferdefuß angelangt. Das GEM auf dem ST erlaubt es nämlich nicht, über die genannten evnt-Routinen die rechte Maustaste abzufragen. Hier zeigt das Betriebssystem überhaupt keine Reaktion. Aus diesem Grund habe ich mir überlegt, wie man das GEM überlisten und die Abfrage der rechten Maustaste auch über die bereits vorhandenen evnt-Routinen realisieren kann.

Die Lösung für dieses Problem sehen Sie im Programm-Listing. Angelpunkt für die Routine ist das Ändern des BUTTON CHANGE-Vektors. Dieser Vektor wird jedesmal dann angesprungen, wenn sich etwas am Status der Maustasten geändert hat. Dies ist dann der Fall, wenn eine Maustaste gedrückt oder losgelassen wurde. Die Nummer der gedrückten Maustaste wird im Datenregister D0 an die BUTTON CHANGE-Routine übergeben. Zu diesem Zeitpunkt ist die Information, um welche Maustaste es sich handelt, noch nicht verlorengegangen. Mein Programm geht nun folgendermaßen vor: Wird eine Null als Nummer der betätigten Maustaste übergeben, wird sofort wieder in die alte Routine des GEM verzweigt, da in diesem Fall nur eine Maustaste losgelassen worden ist. Wird eine 1 als Wert übergeben, handelt es sich um die linke Maustaste, bei einer 2 wurde die rechte Taste gedrückt. Über ein Flag merkt sich das Programm nun, welche der beiden Maustasten betätigt wurde. Anschließend wird in jedem Fall eine 1 nach D0 geladen.

Hierdurch wird dem Betriebssystem simuliert, daß die linke Maustaste gedrückt worden ist. auch wenn es sich in Wirklichkeit um die rechte gehandelt hat. Ein Druck auf die linke Maustaste ist aber nun für das GEM Grund genug, die evnt-Routinen zu verlassen und die Programmkontrolle wieder an das aufrufende Programm zu übergeben. Sie als Programmierer wissen nun jedoch anhand des entsprechend gesetzten Flags, welche der beiden Maustasten wirklich gedrückt worden ist und können entsprechend reagieren.

Ein Nebeneffekt der angegebenen Routine ist übrigens, daß auch die Menüleiste und die Dialogboxen über die rechte Maustaste bedient werden können, da das GEM nicht weiter zwischen den beiden Tasten unterscheidet. Schließlich wissen ja nur wir anhand des von uns definierten Flags, daß es sich eventuell nicht um die linke, sondern die rechte Maustaste gehandelt hat.

Um die Mausroutinen korrekt verwenden zu können, müssen sie in das Hauptprogramm integriert werden. Die Initialisierung erfolgt über die Routine init. Vorher muß bereits das VDI initialisiert worden sein, und vdi_h muß das VDI-Handle enthalten. Die Dummy-Sprungadresse $ffff in Zeile 28 des Quelltextes wird nach der Initialisierung durch den alten Wert der Routine für die Maus-Buttons ersetzt. Dieser Wert wird schließlich noch benötigt.

Die Variable flag enthält nun stets die Angabe darüber, welche Maustaste betätigt wurde und sollte nach einem evnt-Aufruf geprüft werden. Ist ihr Inhalt -1, so handelte es sich um die rechte Maustaste, bei einem Inhalt von 0 war es die linke. Durch einen TST.B-Befehl kann sofort festgestellt werden, welche Maustaste den Abbruch einer evnt-Schleife veranlaßt hat.

Bitte denken Sie daran, vor dem Verlassen Ihres Programms die Routine exit aufzurufen, damit der alte Button-Vektor wieder eingetragen wird. Andernfalls würde sich das GEM nach dem Verlassen Ihres eigenen Programms verabschieden, weil der Mausvektor dann ins Leere zeigt.

*************************************************
* Routinen zur effektiven Abfrage der rechten   *
* Maustaste, 1989 by Uwe Seimet                 *
* (c) MAXON Computer GmbH 1989                  * 
************************************************* 
*Initialisierung der Mausroutine
init:
        moveq #125,d0               ; vex_butv
        move.l #butvec,contrl+14
        bsr.s vdi       ; neuer Vektor f.Mausbutton 
        move.l contrl+18,oldvec+2   ; alten Vektor merken
        rts

*rechte Maustaste abschalten 
exit:
        moveq #125,d0   ; vex_butv 
        move.l oldvec+2(pc),contrl+14 
        bra.s vdi       ; alten Button-Vektor zurückschreiben

*neue Routine zur Behandlung der Mausbuttons 
butvec:
        tst d0          ; Maustaste losgelassen?
        beq.s oldvec    ; ja-
        cmp #2,d0       ; rechte Maustaste?
        seq flag        ; Flag für rechte Taste
        bne.s oldvec    ; weiter, falls linke 
        moveq #1,d0
oldvec: jmp $ffff       ; zurück zur alten Mausroutine

*Allgemeiner VDI-Aufruf, Funktionsnummer in D0
vdi:
        move vdi_h, contrl+12
        move d0,contrl
        move.l #vdipb,d1
        moveq #$73,d0   ; Code für VDI
        trap #2
        rts


        data

vdipb:  dc.l contrl,intin,ptsin,intout,ptsout ; VDI-Arrays


        bss

contrl: ds.w 11 

intin:  ds.w 64

ptsin:  ds.w 64

intout: ds.w 64

ptsout: ds.w 64

vdi_h:  ds.w 1      ; muß VDI-Handle enthalten!

flag:   ds.b 1      ; Flag für rechte Maustaste


Uwe Seimet
Links

Copyright-Bestimmungen: siehe Über diese Seite