Sunday, May 28, 2017

C Program for getting the position of mouse pointer

Graphics in C – Getting Position of Moving Mouse


In C computer language you can get the position of mouse pointer on the screen. There are plenty of services available under interrupt 33h. In the previous post, we have seen mouse pointer moving within a boundary. Now, we’ll see the mouse pointer along with its screen coordinates. Please type the program given below in your editor.

#include<graphics.h>
#include<dos.h>

union REGS in, out;
int mousestart();
void showpointer();
void boundpointer(int x1, int y1, int x2, int y2);
void mouseposition(int *x, int *y);

void main()
{
      int gd = DETECT, gm, maxx, maxy, x, y;
      char str[20];
      initgraph(&gd, &gm, "c:\\tc\\bgi");
      maxx = getmaxx();
      maxy = getmaxy();
      if(mousestart()==0)
      {
            closegraph();
            restorecrtmode();
            printf("\nMouse driver not loaded");
            exit(1);
      }
      while(!kbhit())
      {
            cleardevice();
            rectangle(0, 20, maxx, maxy-20);
            boundpointer(1, 21, maxx-1, maxy-21);
            showpointer();
            mouseposition(&x, &y);
            sprintf(str, "(%d, %d)", x, y);
            outtextxy(x, y, str);
            delay(10);
      }
      closegraph();
      restorecrtmode();
}

int mousestart()
{
      in.x.ax = 0;
      int86(0x33, &in, &out);
      return(out.x.ax);
}

void showpointer()
{
      in.x.ax = 1;
      int86(0x33, &in, &out);
}

void boundpointer(int x1, int y1, int x2, int y2)
{
      in.x.ax = 7;
      in.x.cx = x1;
      in.x.dx = x2;
      int86(0x33, &in, &out);

      in.x.ax = 8;
      in.x.cx = y1;
      in.x.dx = y2;
      int86(0x33, &in, &out);
}

void mouseposition(int *x, int *y)
{
      in.x.ax = 3;
      int86(0x33, &in, &out);
      *x = out.x.cx;
      *y = out.x.dx;
}

Compile and execute this program. In the output, you’ll see that as you move the mouse pointer, the screen coordinates of mouse pointer show up along with the mouse pointer.

In this program, I have declared two variables ‘in’ and ‘out’ of type union REGS. What is union REGS, I have already discussed this in my previous post. To recall the topic, please see here.

Then, I have declared four functions.

int mousestart();
void showpointer();
void boundpointer(int x1, int y1, int x2, int y2);
void mouseposition(int *x, int *y);

In the function main(), I have got maximum screen coordinates by these statements given below-

maxx = getmaxx();
maxy = getmaxy();

Then, I checked whether mouse driver is loaded or not.

if(mousestart()==0)
  {
    closegraph();
    restorecrtmode();
    printf("\nMouse driver not loaded");
    exit(1);
  }

The definition of function mousestart() is given after the function main().  For the explanation of this function, please refer my previous post here.

Now, I have taken a ‘while’ loop, which executes repeatedly until a key is pressed. In this loop, a rectangle has been drawn to define the boundaries of mouse pointer. Then, a function boundpointer() is called, which is defined after the function main(). Function boundpointer() restricts the movement of mouse pointer within the rectangular boundaries.

rectangle(0, 20, maxx, maxy-20);
boundpointer(1, 21, maxx-1, maxy-21);

For the explanation of function boundpointer(), please refer my previous post here.

Now, function showpointer() has been called to show the mouse pointer on the screen. Definition of this function is given after the function main(). For the explanation of this function, please refer my previous post here.

To get the position of mouse pointer on the screen, I have called the function mouseposition().

mouseposition(&x, &y);

In this function, I have passed the addresses of variables ‘x’ and ‘y’. This is so, because, in the definition of this function, the parameters are the pointer variables. This is the way of a function to return more than one value to the calling function. Now, see the function definition given below-

void mouseposition(int *x, int *y)
{
  in.x.ax = 3;
  int86(0x33, &in, &out);
  *x = out.x.cx;
  *y = out.x.dx;
}

To understand this function, please recall the service 3 available under interrupt 33h, which is given below-

Interrupt : 33h
Service : 3
Gets mouse position and button status
Call with AX = 3
Returns BX = Mouse button status (1=Corresponding button  pressed)
Bit 0 à left button is down
Bit 1 à right button is down
Bit 2 à center button is down (if present)
Bits 3-15 à cleared to 0
CX = x coordinate
DX = y coordinate

Therefore, you can see, I have given the value ‘3’ to ‘ax’ variable, called the function int86(), and passed the addresses of variables ‘in’ and ‘out’ in this function. This function returns some values in ‘out’ variable. We know that after executing the service ‘3’ through function int86(), variable ‘cx’ has the value of mouse’s x-coordinate, and variable ‘dx’ will get the value of mouse’s y-coordinate on the screen. These values are assigned to pointer variables ‘x’ and ‘y’. Here, I assume you understand the basics of pointers. To understand this function better, please refer my two recent posts.

After getting mouse pointer’s position on screen, we have formatted these values to a string ‘str’ using function sprintf(). Next, this string is being displayed continuously on this mouse position using function outtextxy() as you move mouse pointer. Function delay() has been used to give a smooth display.

mouseposition(&x, &y);
sprintf(str, "(%d, %d)", x, y);
outtextxy(x, y, str);
delay(10);

Now, the explanation of this simple program is complete. For explanation of the rest of the functions and terms, please refer my previous posts. You can click on labels given in the right side-bar for the explanation of any function.

OUTPUT:












                                                                                                       

Sunday, May 21, 2017

C Program to restrict mouse pointer in a window

Graphics in C – Restrict Mouse Pointer in a Window


In the previous post I have explained the features which are essential to know for mouse programming using C computer language. Now, here is a simple program, by which you will understand these concepts better. Please type this program in your editor. 

#include<graphics.h>
#include<dos.h>

union REGS in, out;
int mousestart();
void showpointer();
void boundpointer(int x1, int y1, int x2, int y2);

void main()
{
      int gd = DETECT, gm, maxx, maxy, x, y;
      initgraph(&gd, &gm, "c:\\tc\\bgi");
      maxx = getmaxx();
      maxy = getmaxy();
      rectangle(0, 20, maxx, maxy-20);
      setviewport(1, 21, maxx-1, maxy-21, 1);
      if(mousestart() == 0)
      {
            closegraph();
            restorecrtmode();
            printf("\nMouse driver not loaded");
            exit(1);
      }
      boundpointer(1, 21, maxx-1, maxy-21);
      showpointer();
      getch();
      closegraph();
      restorecrtmode();
}

int mousestart()
{
      in.x.ax = 0;
      int86(0x33, &in, &out);
      return(out.x.ax);
}

void showpointer()
{
      in.x.ax = 1;
      int86(0x33, &in, &out);
}

void boundpointer(int x1, int y1, int x2, int y2)
{
      in.x.ax = 7;
      in.x.cx = x1;
      in.x.dx = x2;
      int86(0x33, &in, &out);

      in.x.ax = 8;
      in.x.cx = y1;
      in.x.dx = y2;
      int86(0x33, &in, &out);
}

Compile and execute this program. Output will be a rectangle or window, in which mouse pointer shows up. Move the mouse pointer. You will see that mouse pointer moves within this rectangular boundary or box and does not cross the boundaries.

In this program, I have declared three functions. The task of first function is to check whether mouse driver is loaded or not. Second function does the task of showing mouse pointer in a user-defined window. Third function restricts the movement of mouse pointer in this window. These functions are defined after the function main().

int mousestart();
void showpointer();
void boundpointer(int x1, int y1, int x2, int y2);

In the start, I have declared two variables ‘in’ and ‘out’ of type union REGS. I have told you about union REGS in my previous post. Here is a quick revision.

struct BYTEREGS {
      unsigned char al, ah, bl, bh;
      unsigned char cl, ch, dl, dh;
};

struct WORDREGS {
      unsigned int ax, bx, cx, dx;
      unsigned int si, di, cflag, flags;
};

union REGS {
        struct WORDREGS x;
        struct BYTEREGS h;
};

Thus, union REGS is a user-defined data type, which contains two struct WORDREGS and BYTEREGS variables ‘x’ and ‘h’. What is the use of these union variables, you will see later. These structures and union are defined in dos.h file.

In the function main(), I have obtained maximum screen coordinates and stored these in  variables ‘maxx’ and ‘maxy’.

maxx = getmaxx();
maxy = getmaxy();

I have drawn a rectangle, in which mouse pointer will move.

rectangle(0, 20, maxx, maxy-20);

Then, I have defined the user-defined view-port.

setviewport(1, 21, maxx-1, maxy-21, 1);

Function setviewport() establishes a new view-port for graphics output.

Declaration:

void far setviewport(int left, int top, int right, int bottom, int clip);

Where (left, top) is the upper-left corner, and (right, bottom) is the bottom-right corner of the view-port. The ‘clip’ argument determines whether drawings are clipped or truncated at the current view-port boundaries. If ‘clip’ is non-zero, all drawings will be truncated to the current view-port. The current position (C.P.) moves to (0, 0) in the new window.

Syntax for calling this function is given below-

setviewport(left, top, right, bottom, clip);

Therefore, whatever you draw beyond these boundaries, will not be drawn on the screen, because value of ‘clip’ has been given 1.

Now, an ‘if’ construct checks whether mouse driver has been installed or not. If installed, take further actions, otherwise exit. To check the availability of mouse driver, a function mousestart() has been called.

int mousestart()
{
      in.x.ax = 0;
      int86(0x33, &in, &out);
      return(out.x.ax);
}

To understand this function, please recall from the previous post.

Interrupt : 33h
Service : 0
Call with AX = 0
Returns
AX = 0000 (if mouse driver is not installed)
AX = FFFFh (if mouse driver is installed)

Thus, in the function mousestart(), I have given the value 0 (service number = 0) to the element  ‘ax’ of structure WORDREGS, now ‘x’ is the element of type struct WORDREGS in the union REGS, and ‘in’ is the variable of type union REGS. To refer ‘ax’, I have given the full notation like this- in.x.ax.

in.x.ax = 0;

Then, I have called the function int86() and passed the interrupt number 33h, and addresses of variables ‘in’ & ‘out’. After execution, this function returns the value of register ‘ax’ in the variable ‘out’. If it is 0, it means driver not loaded. If value of out.x.ax is FFFFh, it means driver is loaded.

return (out.x.ax);

Now, control returns to function main().  I assume that mouse driver is loaded. In the function main(), function boundpointer() is called. 

void boundpointer(int x1, int y1, int x2, int y2)
{
      in.x.ax = 7;
      in.x.cx = x1;
      in.x.dx = x2;
      int86(0x33, &in, &out);

      in.x.ax = 8;
      in.x.cx = y1;
      in.x.dx = y2;
      int86(0x33, &in, &out);
}

To understand this function, please recall the services from the previous post. These are given below-

Service : 7
Sets horizontal limits for pointer
Call with AX = 7
CX = minimum x coordinate
DX = maximum x coordinate
Returns nothing
à Restricts mouse horizontal movement to window
à If min value is greater than max value they are swapped

Service : 8
Sets vertical limit for pointer
Call with AX = 8
CX = minimum y coordinate
DX = maximum y coordinate
Returns nothing
à Restricts mouse vertical movement to window
à If min value is greater than max value they are swapped

Therefore, to restrict the horizontal movement, we call service 7 under interrupt 33h.

in.x.ax = 7;

To give the horizontal bounds, we have given the values to ‘cx’ and ‘dx’ variables as given below-

in.x.cx = x1; // minimum horizontal bound
in.x.dx = x2; // maximum horizontal bound

Then, we have called the function int86(). This function takes the action.

int86(0x33, &in, &out);

The same way, to give the vertical bounds, we have given the instructions given below-

in.x.ax = 8; // for vertical bounds give service 8
in.x.cx = y1; //minimum vertical bound
in.x.dx = y2; // maximum vertical bound
int86(0x33, &in, &out); // execute the service

Now, for showing the pointer, function showpointer() has been called.

void showpointer()
{
      in.x.ax = 1;
      int86(0x33, &in, &out);
}

This time, service 1 is executed available under interrupt 33h. Please recall from previous post.

Service : 1
Shows mouse pointer
Call with AX = 1
Returns nothing

Therefore, this way mouse pointer is displayed and restricted in the given boundaries. To understand this program better, please refer my previous post.

OUTPUT: