achowe@tiger.waterloo.edu (anthony howe) (10/18/89)
About 2 years ago this question came up on the net. I still have a hard copy of the post which I used to develop the following tit-bit on detecting the right mouse button. Anyways it boiled down to this... "Install your own button handler in assembler. The button value comes in d0, save it out to a nice place, then change it to a left click no matter what, and install the routine using vex_butv()." - Kenneth Soohoo Long exmaple to follow...... -------->8------- EXAMPLE ------------>8-------------- ;*** ;*** Button Handler ;*** ; ; Trap the mouse button state because the current handler kills or ignores ; the right mouse button. Once the state is stored chain to the old handler. .bss .globl _OldButHandler .comm _OldButHandler, 4 .globl _ButState .comm _ButState, 2 .text .globl _NewButHandler _NewButHandler: tst.w d0 beq.s newbut1 move.w d0, _ButState move.w #1, d0 newbut1: move.l _OldButHandler, -(sp) rts ;*** end of Button Handler ------------->8--------- C portion ------------>8---------- /* This example code is ripped straight out of a game I'm writing. There is more here than necessary. But for the curious here is a good portion of setting up a GEM application. The routines to look at in connection with button events are: init() - right at the end, fini() - near the top, and ChkButton() - first line. In ChkButton() I could have tested ButState directly but then I would have had to change M.bstate everywhere. Some code has been ripped out that is relative only to the game itself (not GEM or buttons). Also all the global variables have been left out too. I denote globals variables and routines with a capital letter at the start of a name and on and clear sub words -- eg ChkButton is global while process is local. Dummy is global while foobar is not, MenuObj is global while snert_var is not. The great book on GEM programming is << Programmer's Guide to GEM >> by Phillp Balma and William Fitler from Sybex (ISBN 0-89588-297-3). They howver do not cover the right mouse button problem. NOTE: This is an example only. This code will not work without further additions and routines. */ int init() { if( Getrez() != 1 ){ form_alert( 1, "[1][ We need MEDIUM resolution.][ Sorry ]" ); return( 5 ); }/* if */ if( appl_init() == -1 ){ return( 5 ); }/* if */ ColorGet( OldColor ); ColorSet( NewColor ); /* Prepare to load .RSC file. */ wind_update( BEG_UPDATE ); graf_mouse( HOURGLASS, NULL ); if( !rsrc_load( "example.rsc" ) ){ graf_mouse( ARROW, NULL ); form_alert( 1, "[1][Could not find| EXAMPLE.RSC][ abort ]" ); return( 4 ); }/* if */ /* Get local pointers to the principal trees */ rsrc_gaddr( R_TREE, MAIN, &MenuObj ); /* Get VDI handle and system font sizes. */ VdiHandle = graf_handle( &SysCharW, &SysCharH, &SysBoxW, &SysBoxH ); /* Open the screen as virtual workstation */ VworkOpen( &VdiHandle ); if( VdiHandle == 0 ){ return( 3 ); }/* if */ /* Find size of desktop. This is the max for any window. */ wind_get( DESK, WF_WORKXYWH, &DeskX, &DeskY, &DeskW, &DeskH ); /* Create window #1 */ GameW = wind_create( INFO, DeskX, DeskY, DeskW, DeskH ); if( GameW < 0 ){ form_alert( 1, "[1][No Windows available.][ abort ]" ); return( 1 ); }/* if */ /* Display menu-bar. */ menu_bar( MenuObj, TRUE ); /* Init info line */ strcpy( Info, Ready ); wind_set( GameW, WF_INFO, Info, 0, 0 ); /* Open window #1 to fill desk window and get it's current size. */ graf_growbox( DeskW/2, DeskH/2, 21, 21, DeskX, DeskY, DeskW, DeskH ); wind_open( GameW, DeskX, DeskY, DeskW, DeskH ); wind_get( GameW, WF_WORKXYWH, &GameArea.g_x, &GameArea.g_y, &GameArea.g_w, &GameArea.g_h ); graf_mouse( ARROW, NULL ); wind_update( END_UPDATE ); GameInit(); /* Change mouse button handler so we can get right mouse button. */ vex_butv( VdiHandle, NewButHandler, &OldButHandler ); return( 0 ); }/* init */ void fini( code ) int code; { int x, y, w, h; switch( code ){ case 0: /* normal exit */ /* Close window #1 on the display. */ wind_get( GameW, WF_CURRXYWH, &x, &y, &w, &h ); wind_close( GameW ); graf_shrinkbox( DeskW/2, DeskH/2, 21, 21, x, y, w, h ); /* Free memory used by window #1 & RSC. */ wind_delete( GameW ); menu_bar( MenuObj, FALSE ); vex_butv( VdiHandle, OldButHandler, &Dummy ); case 1: /* no windows free */ VworkClose( VdiHandle ); case 2: /* could not allocate buffers */ case 3: /* error on device */ rsrc_free(); case 4: /* could not load RCS file */ wind_update( END_UPDATE ); ColorSet( OldColor ); appl_exit(); case 5: /* wrong resolution or error on appl_init() */ }/* switch */ }/* fini */ int ChkMenu( title, item ) int title; int item; { switch( title ){ case MDESK: if( item == ABOUT ){ DoAbout(); }/* if */ break; case MFILE: switch( item ){ case PLAY: break; case QUIT: return( TRUE ); }/* switch */ break; case MINFO: if( item == STATUS ){ DoStatus(); }/* if */ break; }/* switch */ menu_tnormal( MenuObj, title, TRUE ); return( FALSE ); }/* ChkMenu */ int ChkMsg() { switch( Msg[0] ){ case MN_SELECTED: return( ChkMenu( Msg[3], Msg[4] ) ); case WM_REDRAW: DoRedraw( Msg[3], (GRECT*) &Msg[4] ); break; case WM_TOPPED: wind_set( Msg[3], WF_TOP, 0, 0, 0, 0 ); break; }/* switch */ return( FALSE ); }/* ChkMsg */ void ChkButton() { M.bstate = ButState; if( M.bstate & 1 ){ strcpy( Info, "left button" ); } else if( M.bstate & 2 ){ strcpy( Info, "right button" ); }/* if */ wind_set( GameW, WF_INFO, Info, 0, 0 ); }/* ChkButton */ void process() { for( ;; ){ Event = evnt_multi( MU_BUTTON | MU_MESAG | MU_M1, 1, 0x3, 1, M.flag, FieldArea.g_x, FieldArea.g_y, FieldArea.g_w, FieldArea.g_h, 0, 0, 0, 0, 0, Msg, 0, 0, &M.x, &M.y, &M.bstate, &Dummy, &Dummy, &M.bclicks ); wind_update( BEG_UPDATE ); if( (Event & MU_MESAG) && ChkMsg() ){ break; }/* if */ if( Event & MU_BUTTON ){ ChkButton(); }/* if */ if( Event & MU_M1 ){ M.flag = !M.flag; }/* if */ wind_update( END_UPDATE ); }/* for */ }/* process */ int main() { int rc; srand( SEED ); rc = init(); if( !rc ) process(); fini( rc ); return( rc ); }/* main */ achowe@tiger.waterloo.edu | "Life is not fair. Anyone who tells _ -|-|_ _ | you different is trying to sell you (_\ |\| | | | (_) |\| \/ | something." - The Princess Bride ___/ | disclaimer...
covertr@force.UUCP (Richard E. Covert) (10/19/89)
In article <17337@watdragon.waterloo.edu>, achowe@tiger.waterloo.edu (anthony howe) writes: > About 2 years ago this question came up on the net. I still have a hard copy > of the post which I used to develop the following tit-bit on detecting the > right mouse button. Anyways it boiled down to this... > > "Install your own button handler in assembler. The button value comes in > d0, save it out to a nice place, then change it to a left click no matter > what, and install the routine using vex_butv()." - Kenneth Soohoo > > Long exmaple to follow...... > > achowe@tiger.waterloo.edu | "Life is not fair. Anyone who tells > _ -|-|_ _ | you different is trying to sell you > (_\ |\| | | | (_) |\| \/ | something." - The Princess Bride > ___/ | disclaimer... Thanks to Anthony Howe for his fine example of right button processing. I wish that more examples of tricky ST programming would be posted on this newsgroup. In particular, I would like to hear from other people who have tried the 'vdit' program posted awhile ago. 'vdit' was an example in loading GDOS fonts, but it didn't appear to work. I would like to write a small utility to print out a sample of each GDOS font in your collection. So, I need to be able to load and unload GDOS fonts (both screen and printer) and then dump a sample to the printer. Any ideas out there?? Richard ( The Whiner (tm) ) Covert