/***************************************************************************** * Change Log * Date | Change *-----------+----------------------------------------------------------------- * 24-Jan-86 | [1.312] Created * 24-Jan-86 | [1.314] Check_left_mouse_button => check_mouse_halt * 24-Jan-86 | [1.322] Properly simulate hide/show cursor with depth count * 25-Jan-86 | [1.332] Added 'tracking' feature * 27-Jan-86 | [1.350] check_for_mouse_up now aborts on mouse_halt code and * | also if activation (lastkey) was keypad * 23-Feb-86 | [1.369] Added mhidden, print out as part of tracking * 25-Feb-86 | [1.379] include <> => include "" * 30-Jul-86 | [1.401] wait_for_mouse_up polls keyboard * 31-Jul-86 | [1.405] Made chars unsigned * 10-Nov-91 | [1.428] converted to Microsoft C 6.0 * 7-Dec-91 | [1.475] use new keybindings structure * 21-Dec-91 | [1.499] added CTRL-LEFT, CTRL-RIGHT dispatches * 23-Dec-91 | [1.521] added pragmas for check_stack * 15-Mar-92 Made changes to make screen stuff independent of MS C *****************************************************************************/ #include "stdio.h" #include "boolean.h" /* #include "graph.h" */ #include "btypes.h" #include "scdspmsg.h" #include "mouse.h" #include "keys.h" #include "kb.h" #include "kbd.h" #include "scan.h" #include "kbd.h" extern boolean mousing; extern short lastkey; extern boolean tracking; short mhidden = -1; extern struct videoconfig video; keybindings * current_kb = NULL; /**************************************************************************** * del_key * Result: void * * Effect: * Handles DEL key ****************************************************************************/ void del_key() { lastkey = KEYACTIVATE2; } /**************************************************************************** * ins_key * Result: void * * Effect: * Handles INS key ****************************************************************************/ void ins_key() { lastkey = KEYACTIVATE; } /**************************************************************************** * move_y_down * Result: void * * Effect: * Moves y down ****************************************************************************/ void move_y_down() { short M1; short M2; short M3; short M4; M1 = mouse_get_cursor; vmouse(&M1,&M2,&M3,&M4); M4 += MOUSE_Y; if(M4 > video.numypixels) M4 = video.numypixels; M1 = mouse_set_cursor; vmouse(&M1,&M2,&M3,&M4); } /**************************************************************************** * move_y_up * Result: void * * Effect: * Moves cursor up ****************************************************************************/ void move_y_up() { short M1; short M2; short M3; short M4; M1 = mouse_get_cursor; vmouse(&M1,&M2,&M3,&M4); M4 -= MOUSE_Y; if(M4 < 0) M4 = 0; M1 = mouse_set_cursor; vmouse(&M1,&M2,&M3,&M4); } /**************************************************************************** * move_x_left * Result: void * * Effect: * Moves cursor left ****************************************************************************/ void move_x_left() { short M1; short M2; short M3; short M4; M1 = mouse_get_cursor; vmouse(&M1,&M2,&M3,&M4); M3 -= MOUSE_X; if(M3 < 0) M3 = 0; M1 = mouse_set_cursor; vmouse(&M1,&M2,&M3,&M4); } /**************************************************************************** * move_x_right * Result: void * * Effect: * Moves cursor right ****************************************************************************/ void move_x_right() { short M1; short M2; short M3; short M4; M1 = mouse_get_cursor; vmouse(&M1,&M2,&M3,&M4); M3 += MOUSE_X; if(M3 > video.numxpixels) M3 = video.numxpixels; M1 = mouse_set_cursor; vmouse(&M1,&M2,&M3,&M4); } /**************************************************************************** * trackit * Inputs: * char * msg: Identifying position * short M2: M2 value * short M3: * short M4; * Effect: * Tracks the value ****************************************************************************/ void trackit(char * msg, short M2, short M3, short M4) { coord x; coord y; short mode; short columns; short page = 0; if(!tracking) return; #if 0 scmode(&mode,&columns,&page); #endif sccurpos(&y, &x); sc_settextposition(24,0); printf("%.3s: M3 = %3d, M4 = %3d, M2 = %d, hid = %3d, key = \\%03o, pg = %2d", msg,M3,M4,M2,mhidden,lastkey,page); sccurset(y, x); } /**************************************************************************** * hide_mouse_cursor * Effect: * Hides the mouse cursor ****************************************************************************/ void hide_mouse_cursor() { short M1, M2, M3, M4; mhidden--; M1 = mouse_hide_cursor; vmouse(&M1,&M2,&M3,&M4); } /**************************************************************************** * show_mouse_cursor * Effect: * Shows the mouse cursor ****************************************************************************/ void show_mouse_cursor() { short M1, M2, M3, M4; mhidden++; if(mhidden > 0) mhidden = 0; M1 = mouse_show_cursor; vmouse(&M1,&M2,&M3,&M4); } /**************************************************************************** * wait_for_mouse_up * Effect: * Waits until all mouse buttons have been released ****************************************************************************/ void wait_for_mouse_up() { short M1, M2, M3, M4; if(!mousing) return; if(lastkey == KEYACTIVATE || lastkey == KEYACTIVATE2 || lastkey == KEYHALT) return; while(true) { M1 = mouse_get_cursor; vmouse(&M1,&M2,&M3,&M4); if((M2 & 7) == 0) return; read_keyboard_char(current_kb); } } /**************************************************************************** * vmouse * Inputs: * short * M1: * short * M2: * short * M3: * short * M4: * Effect: * Simulates mouse if not mousing. Virtual mouse if is mousing ****************************************************************************/ #pragma check_stack(off) static hidden = 0; void vmouse(short * M1,short * M2,short * M3,short *M4) { coord tx; coord ty; #if debug_x coord rX; coord rY; coord x; coord y; #endif if(mousing) { /* real */ real_mouse(M1,M2,M3,M4); if(lastkey == KEYACTIVATE) *M2 |= MOUSEACTIVATE; else if(lastkey == KEYHALT) *M2 |= MOUSEHALT; else if(lastkey == KEYACTIVATE2) *M2 |= MOUSEACTIVATE2; if(tracking && *M1 == mouse_get_cursor) { /* track it */ trackit("vmr",*M2,*M3,*M4); } /* track it */ return; } /* real */ switch(*M1) { /* simulate */ case mouse_hide_cursor: hidden--; sc_settextcursor(SC_CURSOR_NONE); break; case mouse_show_cursor: hidden++; if(hidden < 0) break; if(hidden > 0) hidden = 0; sc_settextcursor(SC_CURSOR_BLOCK); break; case mouse_set_sensitivity: break; case mouse_set_text_cursor: break; case mouse_get_cursor: *M2 = 0; sccurpos(&ty,&tx); *M4 = ty; *M3 = tx; #if debug_x rX = *M3; rY = *M4; sccurset(0,0); printf("get: *M4 = %2d, *M3 = %2d",*M4,*M3); #endif *M4 = screen_to_mouse_y(*M4); *M3 = screen_to_mouse_x(*M3); #if debug_x printf("; s_t_m(*M4) = %2d, s_t_m(*M3) = %2d",*M4, *M3); sccurset(rY,rX); #endif if(lastkey == KEYACTIVATE) *M2 |= MOUSEACTIVATE; else if(lastkey == KEYHALT) *M2 |= MOUSEHALT; else if(lastkey == KEYACTIVATE2) *M2 |= MOUSEACTIVATE2; break; case mouse_set_cursor: #if debug_x sccurset(1,0); printf("set: *M4 = %2d, *M3 = %2d",*M4,*M3); printf("; m_t_s(*M4) = %2d, m_t_s(*M3) = %2d", mouse_to_screen_y(*M4), mouse_to_screen_x(*M3)); #endif sccurset(mouse_to_screen_y(*M4), mouse_to_screen_x(*M3)); #if debug_x sccurpos(&y, &x); rX = x; rY = y; if(*M4/8 != rY || *M3/8 != rX) printf("\7\7"); #endif break; } /* simulate */ if(tracking && (*M1 == mouse_get_cursor || *M1 == mouse_set_cursor)) { /* track it */ trackit("vms",*M2,*M3,*M4); } /* track it */ } #pragma check_stack(on) /**************************************************************************** * check_mouse_halt * Result: boolean * true if mouse button "halt" is pushed. Does not return until * button is released. ****************************************************************************/ #pragma check_stack(off) boolean check_mouse_halt() { short M1, M2, M3, M4; M1 = mouse_get_cursor; vmouse(&M1,&M2,&M3,&M4); if((M2 & 7) == MOUSEHALT) { /* wait for release */ printf("\7"); /* tell user we saw it */ wait_for_mouse_up(); return true; } /* wait for release */ return false; } #pragma check_stack(on) /**************************************************************************** * dokey * Inputs: * unsigned char key: Function key scan code * Effect: * Does the operation required by the key ****************************************************************************/ #define UP 72 #define DOWN 80 #define LEFT 75 #define RIGHT 77 #define HOME 71 #define PGUP 73 #define PGDN 81 #define INS 82 #define DEL 83 #define HOME 71 #define END 79 #define CTRL_LEFT 115 #define CTRL_RIGHT 116 void dokey(unsigned char key,keybindings * kb) { hide_mouse_cursor(); if(kb != NULL) { /* decode kb */ switch(key) { /* operations */ case UP: if(kb->uparrow) (*kb->uparrow)(); break; case DOWN: if(kb->downarrow) (*kb->downarrow)(); break; case LEFT: if(kb->leftarrow) (*kb->leftarrow)(); break; case RIGHT: if(kb->rightarrow) (*kb->rightarrow)(); break; case INS: if(kb->ins) (*kb->ins)(); break; case DEL: if(kb->del) (*kb->del)(); break; case PGUP: if(kb->pgup) (*kb->pgup)(); break; case PGDN: if(kb->pgdown) (*kb->pgdown)(); break; case HOME: if(kb->home) (*kb->home)(); case END: if(kb->end) (*kb->end)(); case CTRL_LEFT: if(kb->ctrl_leftarrow) (*kb->ctrl_leftarrow)(); break; case CTRL_RIGHT: if(kb->ctrl_rightarrow) (*kb->ctrl_rightarrow)(); break; } /* operations */ } /* decode kb */ show_mouse_cursor(); } /**************************************************************************** * scan * Inputs: * boolean * done: Boolean to tell if done * keybindings * kb: Key bindings * boolean forcehalt: Forces halt after single scan if true * Effect: * Scans input. Handles keyboard or mouse interface. Calls procedures * for mouse button hits * Sets current_kb to input parameter so that subcomponents will use * the current keybinding ****************************************************************************/ void scan(boolean * done, keybindings * kb, boolean forcehalt) { short M1, M2, M3, M4; boolean activate_down; boolean activate2_down; boolean extra_down; boolean restore; short rX; short rY; keybindings * old_kb = current_kb; activate_down = false; activate2_down = false; extra_down = false; restore = false; current_kb = kb; while(!*done) { /* scan it */ *done = forcehalt; lastkey = 0; get_keyboard_char(kb); if(!mousing && lastkey == 0) continue; M1 = mouse_get_cursor; vmouse(&M1,&M2,&M3,&M4); rX = M3; rY = M4; if(check_mouse_halt()) { /* halt */ *done = true; continue; } /* halt */ if(M2 & MOUSEEXTRA) { /* extra button */ if(!extra_down) { /* extra button */ if(kb->mouse_middle) (*kb->mouse_middle)(M3,M4); if(!mousing) extra_down = true; restore = true; } /* extra button */ } /* extra button */ if(M2 & MOUSEACTIVATE2) { /* activate2 button */ if(!activate2_down) { /* 2 down */ if(kb->mouse_right) (*kb->mouse_right)(M3,M4); if(mousing) activate2_down = true; restore = true; } /* 2 down */ } /* activate2 button */ if(M2 & MOUSEACTIVATE) { /* activate button */ if(!activate_down) { if(kb->mouse_left) (*kb->mouse_left)(M3,M4); if(mousing) activate_down = true; restore = true; } } /* activate button */ /* --- WATCH FOR BUTTON RELEASE --- */ if(!(M2 & MOUSEACTIVATE)) { /* activate button release */ activate_down = false; } /* activate button release */ if(!(M2 & MOUSEACTIVATE2)) { /* activate2 button release */ activate2_down = false; } /* activate2 button release */ if(!(M2 & MOUSEEXTRA)) { /* extra button release */ extra_down = false; } /* extra button release */ #if 0 if(restore) { /* restore cursor */ /* The following odd sequence is required because if the mouse hardware cursor is used various screen updates will mess its position up; we get the mouse's image of where the cursor is and the set it back, thus forcing the cursor into correspondence with where it is thought to be */ hide_mouse_cursor(); M1 = mouse_set_cursor; vmouse(&M1,&M2,&rX,&rY); /* return cursor to original pos */ show_mouse_cursor(); restore = false; } /* restore cursor */ #endif } /* scan it */ current_kb = old_kb; } /**************************************************************************** * liven_mouse * Effect: * Attempts to reactivate mouse in a new color display page ****************************************************************************/ void liven_mouse() { short M1,M2,M3,M4; M1 = mouse_get_cursor; vmouse(&M1,&M2,&M3,&M4); M1 = mouse_set_cursor; vmouse(&M1,&M2,&M3,&M4); M1 = mouse_set_text_cursor; M2 = mouse_software_cursor; M3 = 0x0000; M4 = 0x0FB0; vmouse(&M1,&M2,&M3,&M4); }