www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/03/13/11:39:12

From: "A.Appleyard" <A DOT APPLEYARD AT fs2 DOT mt DOT umist DOT ac DOT uk>
To: DJGPP AT SUN DOT SOE DOT CLARKSON DOT EDU
Date: Mon, 13 Mar 1995 13:18:05 GMT
Subject: How I handle the mouse in Gnu C

(P.S. Please does anyone out there know the email address of am email group re
FLYING (aeroplanes and helicopters) (real, not toy))?
..................................................................
People have asked about Gnu C mouse handling.
With Leo Zaretski's help I got a Gnu C program to handle the mouse thus:-
/*-----*/
#include <dos.h>
class Mouse;
/*-----*/
class mousestate {public: int x,y,xe,ye; char visible,mc,bd;
    inline mousestate(){}; void operator=(Mouse&);};
/*-----*/
class Mouse {public: int x,y,xe,ye,ldx,ldy,mdx,mdy,rdx,rdy;
char nbuttons,buttons,visible,handlerInstalled,mc,bd;
void show(); void hide(); void read();
void move(int Y,int X);
inline Mouse(){};
void setup();
void operator=(mousestate&);
void settrap(uns int,void (*func)(Regs *));
void range(int ye,int xe);
~Mouse();};
/*-----*/
Mouse Jerry; int oldmx,oldmy; enum{LB=1,MB=4,RB=2}; Regs R;
/*-----*//* Put a char into DOS's input buffer. Returns 0 if fail */
int inject(int C){R.x.ax=0x500;
R.x.cx=C<0?((-C)&0xff)<<8:((C&0xff)<<8)+(C&0xff); Int(0x16);return !(R.x.ax&1);}
/*-----*/
void Mouse::show(){R.x.ax=1; Int(0x33); visible=1;};
void Mouse::hide(){R.x.ax=2; Int(0x33); visible=0;};
void Mouse::read(){R.x.ax=3; Int(0x33); x=R.x.cx>>3; y=R.x.dx>>3;};
void Mouse::move(int Y,int X){
    R.x.ax=4; R.x.cx=X*8+4; R.x.dx=Y*8+4; Int(0x33); read();};
void Mouse::range(int YE,int XE){
    R.x.ax=7; R.x.cx=0; R.x.dx=XE*8-1; Int(0x33); xe=XE;
    R.x.ax=8; R.x.cx=0; R.x.dx=YE*8-1; Int(0x33); ye=YE;}
Mouse::~Mouse(){hide(); settrap(0,(void (*)(Regs *))(0));};
void Mouse::operator=(mousestate&m){move(m.x,m.y);
  if(m.visible) show(); else hide(); mc=m.mc; bd=m.bd; range(m.ye,m.xe);}
/*-----*/
void mousestate::operator=(Mouse&m){
x=m.x; y=m.y; visible=m.visible; mc=m.mc; bd=m.bd; xe=m.xe; ye=m.ye;};
/*-----*/
/* Simulate a software interrupt from protected mode. Like int86() but calls
   DPMI services and so doesn't need DOS extender, only a DPMI server. */
int int86dpmi(int intno) {REGS r,s; Regs S; S=R;
S.x.ss=S.x.sp=0;        /* DPMI server is to provide stack for interrupt call */
S.x.flags=0;                         /* he likeliest forgot to zero the flags */
/* I replaced the call of _go32_dpmi_simulate_int() by a copy of its body here*/
r.h.bl=intno; r.h.bh=0; r.x.cx=0; r.x.di=(int)&S;
if(intno==0x21 && S.x.ax==0x4b00) {                   /* call a child process */
      r.x.ax=0xff0a; int86(0x21,&r,&s);}
else {r.x.ax=0x0300; int86(0x31,&r,&s);}
R=S; return R.d.eax;}
/*-----*/
Regs cb_regs; static _go32_dpmi_seginfo cb_info; /* for callback */
/*-----*/
void Mouse::settrap(uns int mask,void (*func)(Regs *)) {REGS r;
/* This is tricky in protected-mode. We must allocate a real-mode wrapper
   function which will be called by the mouse driver, and which in turn will
   switch to protected-mode and call our protected-mode handler function. */
if(!Jerry.nbuttons) return;
if(!func) {Jerry.handlerInstalled=0; /* remove handler */
    _go32_dpmi_free_real_mode_callback(&cb_info); R.x.dx=R.x.es=0;}
else { /* Allocate real-mode call-back. Find real-mode address of handler */
    cb_info.pm_offset=(uns long)func; Jerry.handlerInstalled=1;
    if(_go32_dpmi_allocate_real_mode_callback_retf(&cb_info,&cb_regs)) return;
    R.x.dx=cb_info.rm_offset; R.x.es=cb_info.rm_segment;}
R.x.ax=12; R.x.cx=mask; int86dpmi(0x33);}
/*-----*/
void event(Regs*R){char events;
events=R->x.ax; Jerry.buttons=R->x.bx&7; Jerry.x=R->x.cx/8; Jerry.y=R->x.dx/8;
if(events&1&Jerry.mc) inject(-mousemove); /* mouse moved */
#define J Jerry /* buttons pressed */
if(events&0x02) {if(J.bd) inject(-lbuttond); J.ldx=J.x; J.ldy=J.y;}
if(events&0x20) {if(J.bd) inject(-mbuttond); J.mdx=J.x; J.mdy=J.y;}
if(events&0x08) {if(J.bd) inject(-rbuttond); J.rdx=J.x; J.rdy=J.y;}
if(events&0x04) inject(-lbutton); /* buttons released */
if(events&0x40) inject(-mbutton);
if(events&0x10) inject(-rbutton);}
#undef J
/*-----*/
void Mouse::setup() {_go32_dpmi_seginfo info;
/* Check if a mouse is installed. If it is, then somebody
   (the mouse driver) should have grabbed the 33h interrupt vector. */
buttons=nbuttons=handlerInstalled=visible=0;
/* if(_go32_dpmi_get_real_mode_interrupt_vector(0x33,&info)) return;
if(!info.rm_segment) if(!info.rm_offset) return; /* exit if no mouse driver */
R.x.ax=0; Int(0x33); /* Initialise mouse driver */
if(!(R.x.ax&0xffff)) return; /* no mouse found */
nbuttons=R.x.bx&0xff; move(0,0); mc=bd=0; hide(); range(gp_Cols,gp_Rows);}
/*-----*/
main(){............
Jerry.setup(); Jerry.settrap(0x7f,&event);

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019