Listing 1 (mouse.c)

/*
     NAME = MOUSE.C
     This program demonstrates the fundamentals of using a mouse to
     select options in a menu-driven application. Uses two "dummy"
     functions: genledg() and payroll().
     Note:  Function chkdrv() taken from page 7-16 of "Microsoft
           Mouse Programmer's Reference Guide"
*/

#include <stdio.h>
#include <dos.h>               /* required for BIOS calls, etc.         */
#include <string.h>
#include <signal.h>            /* disable & enable control break        */

#define RED_BACK 74            /* display using a red background        */

extern void pascal far mouse(int*, int*, int*, int*);    /*declare mouse*/

void txtcursor(char cur), cls(), outstr(), genledg(), payroll(), heading();
void chkdrv();                 /* checks for existence of mouse driver  */

int i, handler();              /* handler() part of control-break       */
int m1, m2, m3, m4;            /* mouse parameters                      */
struct menu                    /* structure for our sample menu         */
{

       char text[20];                  /* text of options              */
       int x;                          /* horiz. screen coordinate     */
       int y;                          /* vert. screen coordinate      */
       int mh,mh2,mv;                  /* mouse horiz/vert. coordinates*/
}options[3];                            /* 3 options in our sample prog.*/

main()
{

       int choice, loop;

             /* disable Control-Break interrupt      */

       if(signal(SIGINT,handler) == (int(*) ())-1)
       {
             cls();
             printf("Fatal error - could not disable Control-Break\n");
             abort();
       }

             /* check for mouse hardware & driver    */
       m1=O;
       mouse(&m1,&m2,&m3,&m4);          /* check hardware here */
       if(m1 != -1)
       {

             cls();
             printf("Fatal error - no mouse found..\n");
             abort();
       }
       chkdrv();                        /* check for mouse driver       */

       /*     "Populate" our structure with data              */

       strcpy(options[0].text, "General Ledger" );
             options[0].x = 6;
             options[0].y = 30;
             options[0].mh = 240;      /* mh & mh2 define the horiz.   */
             options[0].mh2= 344;      /* limits of option's "hot spot"*/
             options[0].mv = 48;       /* define vertical limit here   */

       strcpy(options[1].text, "Payroll" );
             options[1].x = 8;
             options[1].y = 30;
             options[1].mh = 240;
             options[1].mh2 = 288;
             options[1].mv = 64;

       strcpy(options[2].text,"Exit");
             options[2].x = 10;
             options[2].y = 30;
             options[2].mh = 240;
             options[2].mh2= 264;
             options[2].mv = 80;

       heading();                       /* display menu, etc.   */
       m1=m2=m3=m4=i=0;                 /* initialize variables */
       mouse(&m1,&m2,&m3,&m4);          /* init mouse           */
       txtcursor(0);                    /* turn off text cursor */
       m1=1;                            /* show cursor          */
       mouse(&m1,&m2,&m3,&m4);

       /*      now set up infinite loop which processes the
              user's requests                                  */
       loop=1;
       while(loop)
       {

              m1=3;                    /* read mouse cursor position   */
              m2=m3=m4=0;
              mouse(&m1,&m2,&m3,&m4);

              for(i=0; i < 3; ++i)     /* is cursor in 1 of 3 options? */
              {
                 if((m3 >=options[i].mh && m3 <= options[i].mh2) &&
                    (m4 == options[i].mv))
                 {
                      outstr(options[i].x,options[i].y, options[i].text,RED_BACK);
                      break;
                 }
                 else
                      outstr(options[i].x,options[i].y, options[i].text,10);
              }
              m1=6;                  /* read left button       */
              m2=m3=m4=0;
              mouse(&m1,&m2,&m3,&m4);
              if(m2)                 /* user pressed left button        */
              {
                      choice= -1;  /* reset from last choice made    */
                      for(i=0; i < 3; i++)
                      {
                             if((m3 >= options[i].mh && m3 <= options[i].mh2)
                               && (m4 == options[i].mv))
                                    choice = i;
                      }
                      switch(choice)
                      {
                             case 0:        /* selected GEN. LEDGER */
                                   genledg();
                                   break;
                             case 1:        /* selected PAYROLL     */
                                   payroll();
                                   break;
                             case 2:        /* selected EXIT        */
                                   loop=0; /* ends infinite loop   */
                                   break;
                             default:       /* meaningless "click"  */
                                   break;
              }
              m1=m2=m3=m4=i=0;
              mouse(&m1,&m2,&n3,&m4);                  /* init mouse   */
              m1=1;                                    /* show cursor  */
              mouse (&m1,&m2,&m3,&m4);
              }
       }
              /* perform housekeeping chores before exiting   */
       
       m1=2;                          /* hide mouse cursor     */
       mouse(&m1,&m2,&m3,&m4);
       txtcursor(1);                  /* restore text cursor   */
       cls();                         /* clear screen          */
       signal(SIGINT, SIG_IGN);       /* enable control-break  */
       exit(0);                       /* return to DOS         */
}                        /* END MAIN PROGRAM    */

void txtcursor(char cur)               /* controls text cursor  */
{
       union REGS r;                  /* prepare registers,etc */
       r.h.ah = 1;
       if(cur)                        /* turn text cursor on   */

       {
             r.h.cl = 7;
             r.h.ch = 6;
       }
       else
       {
             r.h.ch = 113;           /* set bits 5,6          */
             r.h.cl = 0;             /* set lower bits        */
       }
       int86(0x10, &r, &r);           /* execute the interrupt */

}

void cls()                             /* clears the screen     */
{
       union REGS r;
       r.h.ah = 6;                    /* screen scroll code    */
       r.h.al = 0;                    /* clear screen code     */
       r.h.ch = 0;                    /* start row             */
       r.h.cl = 0;                    /* start column          */
       r.h.dh = 24;                   /* end row               */
       r.h.dl = 79;                   /* end column            */
       r.h.bh = 7;
       int86(0x10, &r, &r);           /* execute interrupt     */
}
void outstr(x,y,s, color)       /* writes a string to video RAM */
char *s;                               /* string to write       */
char color;                            /* color of string       */
int x,y;                               /* where to start writing*/
{
       char far *vid_mem;             /* video memory pointer  */
       vid_mem= (char far *) 0xB8000000;       /* start of video memory */
       vid_mem=vid_mem+((x * 160) + (y * 2));  /* where to start output */
       while(*s)                               /* loop thru string...   */
       {

             *vid_mem=*s++;         /* move string into video memory*/
             ++vid_mem;             /* incr. to next byte=attribute */
             *vid_mem=color;        /* and set the color there      */
             ++vid_mem;             /* incr. for next character in  */
       }                              /* the string "s" ....         */
}

void chkdrv()                  /* checks for presence of mouse driver  */
{
       union REGS inregs, outregs;
       struct SREGS segregs;
       long address;
       unsigned char first_byte;

       inregs.x.ax = 0x3533;
       intdosx(&inregs, &outregs, &segregs);

       address=(((long) segregs.es) << 16)+(long) outregs.x.bx;
       first_byte= * (long far *) address;

       if((address==0)  (first_byte==0xcf))
       {
             cls();
             printf("System has a mouse, but no mouse driver !\n");
             printf("Install file MOUSE.SYS and re-start this program.");
             exit(0);
       }
}
void genledg()                         /* "dummy" function     */
{
       m1=2;                                  /* hide cursor  */
       mouse(&m1,&m2,&m3,&m4);
       cls();
       printf("Perform Option 1, 'General Ledger'\nNow press 'ENTER'...");
       getchar();
       heading();
}

void payroll()                         /* "dummy" function     */

{
       m1=2;                                  /* hide cursor  */
       mouse(&m1,&m2,&m3,&m4);
       cls();
       printf("Perform Option 2, 'Payroll'\nNow press 'ENTER'...");
       getchar();
       heading();
}
void heading()                         /* menu heading         */
{
       cls();                         /* clear screen         */
       outstr(3,25,"Sample Mouse/Menu Program",14);
       for(i=0; i < 3; i++)
             outstr(options[i].x,options[i].y,options[i].text,10);
}

int handler()                   /* control-break function      */
{
       signal(SIGINT, SIG_IGN);
}