Search

Google

Monday 12 November, 2007

mouse programming in c

Hello,
to all programmers out there,here is a cool stuff for you guys to check out. I assume you guys have fair knowledge in C language and everybody have tried turbo c.Well, it may sound ridiculous to use turbo c now a days for its boring interface and that crazy black screen and what I find very irritating is that it doesn't offer any direct support for mouse.But actually it does.No more prologue,let's jump to the topic.....
To add mouse support to your application you need to include the library file dos.h; i.e.
#include"dos.h"
This library file declares an useful union(i hope you know what is meant by 'union' in c,better to brush up old things) named REGS and it is declared as

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

where both the structures are defined in "dos.h" as

struct BYTEREGS{ unsigned char al, ah, bl, bh;
unsigned char cl, ch, dl, dh;};
and
struct WORDREGS{ unsigned int ax, bx, cx, dx;
unsigned int si, di, cflag , flags;};
Lots of strange things mixed up, isn't it. Well, I'll suggest you to have some knowledge of x86 processor architecture. For our topic we just need to know that the processor has got four sixteen bit general purpose registers called ax ,bx, cx, dx and they can also be used as bytes. The higher bytes are called ah, bh, ch, dh respectively and the lower bytes are termed as al ,bl, cl, dl; which means you may use either a sixteen bit register (say ax) or two eight bit registers(ah or al). It also has got other registers (si,di,flags etc ) but we don't need them now.You may think why am i meaninglessly wasting time on these hardware topics .OK,just scroll back and you gonna find that the structures actually depicts the registers.BYTEREGS is useful to access the eight bit registers as do WORDREGS for sixteen bit registers.
The next thing we are going to cover is interrupt.An interrupt means a certain signal that changes the sequential flow of programs as do the jump or brunch instructions and cpu saves the current register values in stack and performs certain routine (called ISR or interrupt service routine)other than that was being executed and then returns and continues with the old program.A hardwire interrupt is an electronic signal or pulse from other device. Here we are concerned with software interrupts.There are certain codes that can be embedded in the program to interrupt the cpu and cpu performs an intended action based on that code.The code is called an interrupt no.now the main part; dos.h has got two functions to generate software interrupts.they are:
int int86(int interrupt_no , union REGS * inregs ,union REGS *outregs);
and
int int86x(int interrupt_no,union REGS * inregs ,union REGS *outregs, struct SREGS *segregs);
For simplicity we shall confine our discussion to int86 only.
int86 has got three arguments.The first one is for interrupt no.For mouse related interrupts we use 0x33(hex) as interrupt no.There are many services an interrupt can perform, as for example we may want to display the mouse pointer or may want to know the mouse position.They are differentiated by sub functions and inreg contains this information. The result is stored in outregs.
Well from here on we can proceed to the world of mouse programming.To proceed further You need to have mouse driver installed in your computer and here we go.................
Program 1:Determining whether the mouse driver is loaded or not
Our first program determines whether the system has got the mouse driver installed.here goes the code
#include"dos.h"
int main(void)
{union REGS inreg,outreg;
inreg.x.ax=0;
int86(0x33,&inreg,&outreg);//initializes mouse driver
if(outreg.x.ax==0)
printf("not available");
else
printf("available");
return 0;
}
the ax register is given the value 0 which is the service number and interrupt is generated.if the output of ax of outreg is 0 no driver is loaded otherwise the driver is loaded.This also sets the mouse driver's internal mouse position to the center of the screen. The center of the screen, according to the mouse driver, is not (160,100), it is (320,100). This is because the mouse driver maps the x position of the mouse from 0 to 639 and the y position from 0 to 199, no matter what video mode is currently active. outreg.x.bx contains the no of mouse buttons the driver identifies.
Program 2:Displaying the mouse pointer and hiding it
sub functions 1 and 2 can be used respectively for this purpose.
#include"dos.h"
#include"graphics.h"
void main(){
union REGS inreg,outreg;
int GDriver=DETECT,GMode;
inreg.x.ax=1;
initgraph(&GDriver,&GMode,"");//initiates graphics mode
int86(0x33,&inreg,&outreg);//this shows the mouse pointer
getch();
inreg.x.ax=2;
int86(0x33,&inreg,&outreg);/this hides mouse pointer
getch();
restorecrtmode();
}
The code is pretty simple just call int86 with two different arguments.Now, there is an important point to note, in order to see the mouse pointer as an arrow we must be in the graphics mode initialized in the program by making a call to initgraph(). In text mode the mouse pointer appears as a blinking box.Try them out and follow the result.
Program 3:To know mouse status and mouse position
sub function 3 is used for this purpose and the code is:
#include"dos.h"
void main(){
union REGS inreg,outreg;
int button;
inreg.x.ax=0;
int86(0x33,&inreg,&outreg);//initializes mouse driver
inreg.x.ax=1;
int86(0x33,&inreg,&outreg);//shows mouse pointer
inreg.x.ax=3;
int86(0x33,&inreg,&outreg);//interrupt with sub function 3
printf("mouse position is ");
printf("x_coordinate=%d,y_coordinate=%d",outreg.x.cx,outreg.x.dx);//printing the position

button=outreg.x.bx & 7;//determine mouse status
if(button==1) printf("left button pressed");
else if(button==2)printf("right button pressed");
else if(button==4)printf("middle button pressed");
else if(button==3)printf("left and right buttons pressed");
else if(button==5)printf("left and middle buttons pressed");
else if(button==6)printf("middle and right buttons pressed");
else if(button==7)printf("all three buttons pressed");
else printf(" no button pressed");
inreg.x.ax=2;
int86(0x33,&inreg,&outreg);//hides mouse pointer
}

When we interrupt with sub function 3 the mouse position is stored at x.cx and x.dx(x position and y position respectively) of outreg.and x.bx shows the status of buttons.



the picture explains the status of bx and consequently the code.

At this point I think these examples and the text have throw some light on this interesting topic.Dozens of sub functions are there to implement different functionality to the code.A detailed listing of these sub functions can be found at http://www.delorie.com/djgpp/doc/rbinter/ix/33/00.html
Hope you find the topic interesting and enjoyed it.

No comments: