/* TECO for DOS Copyright (C) 1986-1991 Matt Fichtenbaum */ /* Based on Ultrix TECO (C) 1986-1990 GenRad Inc., Concord, MA 01742 */ /* These programs may be copied if this copyright notice is included and */ /* only on a "not for sale or profit" basis */ /* te_mouse.c: mouse-driver interface routines */ /* 02/05/91 21.15 */ /* mod for horizontal split screen 08/28/91 20.21 */ /* mouse driver */ /* implements nFM command, as follows */ /* n,1FM: set mouse mode: 0: off, >0: on, bit 0: displayed, */ /* bit 1: mouse active during command execution */ /* 2FM: character position of mouse */ /* 3FM: buffer in which mouse is */ /* 4FM: absolute screen y coordinate */ /* 5FM: absolute screen x coordinate */ /* Q`X: left mouse button macro */ /* Q'Y: right mouse buttom macro */ /* all but 1FM are read-only */ #include #include "te_defs.h" #define Mousepointer_and mousepointer[0] #define Mousepointer_xor mousepointer[1] long fm_vals[5] = { 0, 0, 0, 0, 0 }; /* mouse control parameters */ unsigned char mousepointer[2] = { 0x0, 0xc0 }; extern unsigned char mousepointer[]; void do_mouse(void); long setup_mouse(long); void clear_mouse(void); void set_mouse_range(void); void display_mouse(unsigned short mouse_disp_func); static unsigned short install_mouse_ptr(unsigned short pointer_on); long xy_to_dot(long x, long y, long *p); void _far _loadds mouse_handler(); void do_mouse() { if (!(ez_val & EZ_MOUSE)) ERROR(E_IFC); /* bit must be set in EZ */ if (!esp->flag1 || esp->val1 < 1 || esp->val1 > 5 || (esp->flag2 && esp->val1 > 1)) ERROR(E_IMO); /* invalid mouse function */ if (esp->flag2) /* enable/disable/hide mouse */ { esp->val1 = setup_mouse(esp->val2); /* call routine to do work */ if (!esp->val1 && !colonflag) ERROR(E_NOM); /* error if no mouse support */ esp->flag2 = 0; /* consume write argument */ esp->flag1 = colonflag; /* return value only if asked */ colonflag = 0; } else esp->val1 = fm_vals[esp->val1 - 1]; /* return value - esp->flag1 is already set */ esp->op = OP_START; } long setup_mouse(long func) { union REGS r; struct SREGS s; long retval = -1L; void (_far _loadds *handler_p)() = mouse_handler; if (fm_ctrl < 0) return(0L); /* no mouse support available */ if ((func & MOUSE_IS_ENABLED) && !(fm_ctrl & MOUSE_IS_ENABLED)) /* turn mouse on, was off */ { if (reset_mouse() == 0) { fm_ctrl = -1; /* mark no support available */ retval = 0; /* return failure */ } set_mouse_range(); /* set maximum x, y */ r.x.ax = 0x0c; /* install our event handler */ r.x.cx = 0x1f; /* motion or either button pressed */ r.x.dx = FP_OFF(handler_p); s.es = FP_SEG(handler_p); int86x(0x33, &r, &r, &s); r.x.ax = 0x04; /* set present position */ r.x.cx = fm_x; r.x.dx = fm_y; int86(0x33, &r, &r); display_mouse((func & MOUSE_IS_INVISIBLE) ? MOUSE_HIDE : MOUSE_SHOW); } else if (!(func & MOUSE_IS_ENABLED) && (fm_ctrl & MOUSE_IS_ENABLED)) /* turn mouse off, was on */ { (void) reset_mouse; display_mouse(MOUSE_HIDE); /* remove from display */ func = 0; /* clear all of fm_ctrl */ } else if (func < 0) ERROR(E_IMO); /* can't write it negative */ fm_ctrl = func; /* save last op */ display_mouse( ((func & 3) == 1) ? MOUSE_SHOW : MOUSE_HIDE); /* show if on and visible; hide otherwise */ return(retval); } /* routine to reset mouse driver (inactivate our event routine) */ /* returns mouse status code */ short reset_mouse() { union REGS r; r.x.ax = 0; /* reset mouse */ int86(0x33, &r, &r); return(r.x.ax); } /* routine to set range of mouse position */ void set_mouse_range() { union REGS r; r.x.ax = 0x07; /* set minimum, maximum x */ r.x.cx = 0; r.x.dx = (term_cols - 1) << 3; int86(0x33, &r, &r); r.x.ax = 0x08; /* set minimum, maximum y */ r.x.cx = 0; r.x.dx = (term_rows - WN_scroll - 1) << 3; int86(0x33, &r, &r); } /* routine to clear mouse (called when EZ mouse bit set to 0) */ void clear_mouse(void) { if (fm_ctrl > 0) { display_mouse(MOUSE_HIDE); reset_mouse(); fm_ctrl = 0; } } /* routine to control display of mouse pointer */ /* call with argument: */ /* MOUSE_HIDE: disable display, MOUSE_SHOW: enable display, */ /* MOUSE_RDCMD: begin command read-in (show mouse), */ /* MOUSE_NORDCMD: end command read-in (hide mouse unless MOUSE_WHILE_EXEC set */ static unsigned short mouse_disp_sw = 0; /* bit 0: off/on, bit 1: suspend/resume */ void display_mouse(unsigned short mouse_disp_func) { unsigned short temp_sw = mouse_disp_sw; switch (mouse_disp_func) { case MOUSE_HIDE: temp_sw &= ~1; break; /* off */ case MOUSE_SHOW: temp_sw |= ((fm_ctrl & MOUSE_WHILE_EXEC) ? 3 : 1); break; /* on */ case MOUSE_RDCMD: temp_sw |= 2; break; /* resume */ case MOUSE_NORDCMD: if (!(fm_ctrl & MOUSE_WHILE_EXEC)) temp_sw &= ~2; break; /* suspend */ case MOUSE_SUSPEND: temp_sw |= 4; break; /* suspend for screen update */ case MOUSE_RESUME: temp_sw &= ~4; break; } if (temp_sw == 3 && mouse_disp_sw != 3) install_mouse_ptr(1); /* new */ else if (temp_sw != 3 && mouse_disp_sw == 3) install_mouse_ptr(0); /* remove */ mouse_disp_sw = temp_sw; } /* routine to install or remove mouse pointer */ /* always remove, then install if arg nonzero */ /* returns previous state of pointer */ static unsigned char saved_attributes = 0; static unsigned char _far *saved_loc = 0; static unsigned short saved_state = 0; static unsigned short install_mouse_ptr(unsigned short pointer_on) { unsigned short temp_state = saved_state; /* return previous state */ #pragma check_pointer(off) saved_state = pointer_on; /* save new pointer state */ if (saved_loc != 0) /* remove existing pointer */ { *saved_loc = saved_attributes; saved_loc = 0; } if (pointer_on) { saved_loc = ((unsigned char _far *) video_buffer) + 1 + 2 * (term_cols * fm_y + fm_x); saved_attributes = *saved_loc; *saved_loc = (saved_attributes & Mousepointer_and) ^ Mousepointer_xor; } return(temp_state); #pragma check_pointer () } /* mouse event processor */ /* this routine is called by the keyboard processing routine when a mouse event occurs */ /* it returns the mouse char if a button pressed, else 0 */ #define MOUSE_KEYL 1 #define MOUSE_KEYR 2 #define MOUSE_KEYM 4 static unsigned short last_mouse_event = 0; static unsigned short last_fm_x, last_fm_y; unsigned short do_mouse_event() { unsigned short return_val = 0; union REGS r; r.x.ax = 0x03; /* what happened? */ int86(0x33, &r, &r); fm_y = r.x.dx >> 3; /* update coordinates */ fm_x = r.x.cx >> 3; if (mouse_disp_sw == 3 && (fm_x != last_fm_x || fm_y != last_fm_y)) install_mouse_ptr(1); /* if motion & display, update pointer */ last_fm_x = fm_x; last_fm_y = fm_y; if (r.x.bx & (MOUSE_KEYL | MOUSE_KEYR) & ~last_mouse_event) /* if mouse button pushed */ { if ((fm_dot = xy_to_dot(fm_x, fm_y, &fm_buff)) != -2) /* get a pointer from screen position */ { if (r.x.bx & MOUSE_KEYL & ~last_mouse_event) return_val = KEY_MOUSEL; else if (r.x.bx & MOUSE_KEYR & ~last_mouse_event) return_val = KEY_MOUSER; } } last_mouse_event = r.x.bx; /* save this event */ return(return_val); } /* mouse event handler */ /* called by mouse driver when button pushed or mouse moves */ unsigned short mouse_event_flag = 0; #pragma check_stack(off) void _far _loadds mouse_handler() { if (mouse_disp_sw == 3) mouse_event_flag = 1; } #pragma check_stack()