Wednesday 2 October 2013

Mouse Programming in C Language

In GUI's like Windows, mouse is very important for user interaction. As everyone knows, It is a simple input device which allows you to point and execute interface in a random and faster manner than the keyboard which provides sequential interface. In this post, i explain interrupts for mouse programming and a few concepts regarding mouse programming.
Initializing Mouse in our Program
Before starting mouse programming, the very first thing you must know, how to tell a mouse to do anything. In actual we does not communicate with mouse directly, but through the driver(device driver) provide. Now the question arises is, how to communicate with driver? The answer is, interrupts are used to get access to a driver. Each device has a unique port which is a hexadecimal value and value is designed to be machine independent enhancing portability of program. Mouse has port attached to it 0X33 (Keyboard has 0X60). C language provides int86() function to execute a software interrupt, which is defined in "dos.h" header file.

int86(int int_no, UNION REGS *input_reg, UNION REGS *output_reg);

This function takes 3 arguments as shown.
  • Interrupt number.
  • UNION REGS type input_reg variable for inputting into CPU registers.
  • UNION REGS type output_reg variable for outputting from the CPU registers.
First argument, i have already explained above i.e. Interrupt number. Second and third arguments are nothing but UNION REGS type of variable, which are used to  pass information to and from int86() function. Before executing the interrupt, int86() function copies register values from input_reg argument to CPU registers, and after execution of the interrupt, int86() function copies the current CPU register value to the output_reg variable. Thats why we have used UNION REGS variable.
union REGS
{
struct WORDREGS x;
struct BYTEREGS h;
};

These two structures contain some 1-byte long and 2-byte long variables which indirectly represent CPU's registers. Now we need to perform various tasks related to mouse programming as, displaying mouse pointer on the screen, working with mouse clicks and much more. To perform these tasks, we have to execute mouse interrupt every time for every single operation with its own input. We can access various mouse functions using different values of AX input Register and passing those values to mouse port using a interrupt.

The Functions are listed below - Here AX, BX, CX and DX are members of Union REGS and more or less integers.

Input Function Performed Returns
AX=0Get Mouse StatusOutput AX Value = FFFFh if mouse support is available.
Output AX Value = 0 if mouse support is not available.
AX=1Show Mouse Pointer on screen.-
AX=2Hide Mouse pointer from screen.-
AX=3Get cursor position(coordinates).CX=X cordinate position.
DX=Y coordinate position.
AX=7, CX=MaxX1, DX=MaxX2Set Horizontal limit of the cursor.-
AX=8, CX=MaxX1, DX=MaxX2Set Vertical limit of the cursor.-

Playing with mouse on the screen

Here is the program to find whether mouse driver is loaded or not:

#include <dos.h>
union REGS in, out;
void detectmouse()
{
   in.x.ax = 0;                                     //set ax=0 to get mouse status.(shown in above table)
   int86 (0X33,&in,&out);                   //interrupt executes.
   if (out.x.ax == 0)                            //CPU register's value after interrupt execution.
   printf ("Mouse Fail To Initialize");
   else
   printf ("Mouse Succesfully Initialize");
}
void main ()
{
  clrscr();
  detectmouse ();
  getch ();
}
In the above program, we have used a user defined function, named detectmouse(). Which detects the mouse in our system.If mouse driver is not loaded, it returns 0 in ax register. All return values are accessed using 'out', that's why we have out.x.ax==0 in if statement.

Program to show the mouse pointer on the scren:

#include <dos.h>
void main()
{
      union REGS in,out;
      clrscr();
      in.x.ax=0;
      int86(0x33,&in,&out);
      if(out.x.ax==0)
      {
        printf("No Mouse Available.....");
        exit();
      }
      in.x.ax=1;                                //set ax=1 to display mouse pointer on screen.
      int86(0x33,&in,&out);                //again execute interrupt with new value of ax.
}

First we have checked for mouse status by setting ax=1. After completing this interrupt, we again set ax=1 to show mouse pointer. Then we have to again call int86() function with new input value. So to perform different tasks(hide pointer, restrict etc.) we have to call int86() function every time with new value of ax register.

Program to show mouse coordinates on the screen:

#include <dos.h>
void main()
{
      union REGS in,out;
      clrscr();
      in.x.ax=0;
      int86(0x33,&in,&out);
      if(out.x.ax==0)
      {
         printf("No Mouse Available...");
         exit();
      }
      in.x.ax=1;
      int86(0x33,&in,&out);                        //execute interrupt to show mouse pointer.
      gotoxy(25,23);                                    //goto any random position on screen.
      printf("Press any key to exit...");
      while(!kbhit())                                         //while you dont press any key this will not stop.
      {
         in.x.ax=3;                                         //set ax=3 to get the cursor position on screen.
         int86(0x33,&in,&out);
         gotoxy(2,2);                                                 //goto random position to print coordinates.
         printf("(x,y)=(%d,%d)",out.x.cx,out.x.dx);            //print the coordinates.
      }
      in.x.ax=2;                                                                  //set ax=2 to hide the pointer.
      int86(0x33,&in,&out);
}

In the above program we have a while loop.This loop continues until a key is hit.In loop,we used sub-function 3 and invoked mouse interrupt. Sub-function 3 returns X->co-ordinate in cx register and Y->co-ordinate in dx register.printf statements prints x and y co-ordinates as long as the loop continues.Maximum screen resolution for mouse in text mode is 640x200 and in graphics mode is 640x480.

Mouse programming can be done in text mode and graphics mode as well. Here we have focused in text mode. For graphics mode, you have to change your console into graphics mode using initgraph() function defined in "graphics.h", rest all will be same. More tasks can be performed in mouse programming like making pencil(like mspaint) on the screen, drawing lines, free hand drawing and much more.

No comments:

Post a Comment