Mouse Programming in C
Mouse Programming in C
BACHELOR OF ENGINEERING
IN
COMPUTER SCIENCE & ENGINEERING
Submitted By:
Navpreet Singh
12BCS1176
Submitted to:
Er. Jasneet kaur
CONTENTS
BASIC TERMINOLOGY
Interrupt
Interrupt Service Routine
Device Driver
Int86 function in c
Union regs
Generic values for the mouse programming
Steps for implementation
MOUSE programs
Conclusion
BASIC TERMINOLOGY
INTERRUPT:Interrupt is a signal to the processor of computer informing some event needs a immediate
attention. An interrupt alerts the processor to a high-priority condition requiring the interruption
of the current code the processor is executing. The processor responds by suspending its current
activities, saving its state, and executing a function called an interrupt handler (or an interrupt
service routine, ISR) to deal with the event. This interruption is temporary, and, after the interrupt
handler finishes, the processor resumes normal activities. There are two types of interrupts:
hardware interrupts and software interrupts.
Hardware interrupts are used by devices to communicate that they require attention from the
operating system. Internally, hardware interrupts are implemented using electronic alerting signals
that are sent to the processor from an external device, which is either a part of the computer itself,
such as a disk controller, or an external peripheral. For example, pressing a key on the keyboard
or moving the mouse triggers hardware interrupts that cause the processor to read the keystroke or
mouse position. Unlike the software type (described below), hardware interrupts are asynchronous
and can occur in the middle of instruction execution, requiring additional care in programming.
The act of initiating a hardware interrupt is referred to as an interrupt request (IRQ).
INTERRUPT SERVICE ROUTINE:In computer systems programming, an interrupt handler, also known as an interrupt service routine
or ISR, is a callback function in microcontroller firmware, an operating system or a device driver,
whose execution is triggered by the reception of an interrupt. In general, interrupts and their
handlers are used to handle high-priority conditions that require the interruption of the current code
the processor is executing.
Interrupt handlers have a multitude of functions, which vary based on the reason the interrupt was
generated and the speed at which the interrupt handler completes its task. For example, pressing a
key on a computer keyboard, or moving the mouse, triggers interrupts that call interrupt handlers
which read the key, or the mouse's position, and copy the associated information into the
computer's memory.
An interrupt handler is a low-level counterpart of event handlers. These handlers are initiated by
either hardware interrupts or interrupt instructions in software, and are used for servicing hardware
devices and transitions between protected modes of operation such as system calls.
In several operating systemsLinux, Unix, Mac OS X, Microsoft Windows, z/OS, and some other
operating systems used in the pastinterrupt handlers are divided into two parts: the First-Level
Interrupt Handler (FLIH) and the Second-Level Interrupt Handlers (SLIH). FLIHs are also known
as hard interrupt handlers or fast interrupt handlers, and SLIHs are also known as slow/soft
interrupt handlers, Deferred Procedure Call.
A FLIH implements at minimum platform-specific interrupt handling similar to interrupt routines.
In response to an interrupt, there is a context switch, and the code for the interrupt is loaded and
executed. The job of a FLIH is to quickly service the interrupt, or to record platform-specific
critical information which is only available at the time of the interrupt, and schedule the execution
of a SLIH for further long-lived interrupt handling.
FLIHs cause jitter in process execution. FLIHs also mask interrupts. Reducing the jitter is most
important for real-time operating systems, since they must maintain a guarantee that execution of
specific code will complete within an agreed amount of time. To reduce jitter and to reduce the
potential for losing data from masked interrupts, programmers attempt to minimize the execution
time of a FLIH, moving as much as possible to the SLIH. With the speed of modern computers,
FLIHs may implement all device and platform-dependent handling, and use a SLIH for further
platform-independent long-lived handling.
FLIHs which service hardware typically mask their associated interrupt (or keep it masked as the
case may be) until they complete their execution. An (unusual) FLIH which unmasks its associated
interrupt before it completes is called a reentrant interrupt handler. Reentrant interrupt handlers
might cause a stack overflow from multiple preemptions by the same interrupt vector, and so they
are usually avoided. In a priority interrupt system, the FLIH also (briefly) masks other interrupts
of equal or lesser priority.
A SLIH completes long interrupt processing tasks similarly to a process. SLIHs either have a
dedicated kernel thread for each handler, or are executed by a pool of kernel worker threads. These
threads sit on a run queue in the operating system until processor time is available for them to
perform processing for the interrupt. SLIHs may have a long-lived execution time, and thus are
typically scheduled similarly to threads and processes.
In Linux, FLIHs are called upper half, and SLIHs are called lower half or bottom half. This is
different from naming used in other Unix-like systems, where both are a part of bottom half.
DEVICE DRIVER:In computing, a device driver (commonly referred to as a driver) is a computer program that
operates or controls a particular type of device that is attached to a computer. A driver provides a
software interface to hardware devices, enabling operating systems and other computer programs
to access hardware functions without needing to know precise details of the hardware being used.
A driver typically communicates with the device through the computer bus or communications
subsystem to which the hardware connects. When a calling program invokes a routine in the driver,
the driver issues commands to the device. Once the device sends data back to the driver, the driver
may invoke routines in the original calling program. Drivers are hardware-dependent and
operating-system-specific. They usually provide the interrupt handling required for any necessary
asynchronous time-dependent hardware interface.
Device drivers simplify programming by acting as translator between a hardware device and the
applications or operating systems that use it. Programmers can write the higher-level application
code independently of whatever specific hardware the end-user is using.
For example, a high-level application for interacting with a serial port may simply have two
functions for "send data" and "receive data". At a lower level, a device driver implementing these
functions would communicate to the particular serial port controller installed on a user's computer.
The commands needed to control a 16550 UART are much different from the commands needed
to control an FTDI serial port converter, but each hardware-specific device driver abstracts these
details into the same (or similar) software interface.
Device drivers, particularly on modern Microsoft Windows platforms, can run in kernel-mode
(Ring 0 on x86 CPUs) or in user-mode (Ring 3 on x86 CPUs). The primary benefit of running a
driver in user mode is improved stability, since a poorly written user mode device driver cannot
crash the system by overwriting kernel memory. On the other hand, user/kernel-mode transitions
usually impose a considerable performance overhead, thereby prohibiting user-mode drivers for
low latency and high throughput requirements.
Kernel space can be accessed by user module only through the use of system calls. End user
programs like the UNIX shell or other GUI-based applications are part of the user space. These
applications interact with hardware through kernel supported functions.
INT86() FUNCTION :INT 86 Int86() is a C function that allows to call interrupts in the program. prototype in dos.h
Usage is int86 (int intr num, union REGS *inregs, union REGS *outregs) In and out register must
be type of REGS. REGS is a built in UNION declaration in C. It is defined in the header file
<DOS.h>
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 are using 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 some 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.
The Functions are listed below - Here AX, BX, CX and DX are members of Union REGS and
more or less integers. We can access different mouse functions by placing the different values in
AX register.
Struct WORDREGS{
Unsigned int ax,bx,cx,dx,si,di,cflags,flags;
}
Struct ByteReg {
Unsigned char ah,al,bh,bl,ch,cl,dh,dl;
}
MOUSE PROGRAMS
1. C program to check the mouse availability
Source code:
#include <dos.h>
union REGS in, out;
void detect_mouse ()
{
in.x.ax = 0;
int86 (0X33,&in,&out);
//invoke interrupt
if (out.x.ax == 0)
printf ("\nMouse Failed To Initialize");
else
printf ("\nMouse was Succesfully Initialized");
}
int main ()
{
detect_mouse ();
getch ();
return 0;
}
Explaination : 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.
Source code:
#include <dos.h>
union REGS in, out;
void showmouse_text ()
{
in.x.ax = 1;
int86 (0X33,&in,&out);
}
int main ()
{
detect_mouse ();
showmouse_text ();
getch ();
return 0;
}
Explaination: 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 call again int86() function
with new input value. So to perform different tasks(hide pointer, restrict mouse etc.) we have to
call int86() function every time with new value of ax register.
case 4:
print(middle button pressed\n);
break;
case 3:
print(left and right button pressed\n);
break;
case 5:
print(left and middle button pressed\n);
break;
case 6:
print(right and middle button pressed\n);
break;
case 7:
print(all the three buttons pressed\n);
break;
default:
print(No button pressed\n);
}
delay (200); // Otherwise due to quick computer response 100s
of words will get print
}
}
int main ()
{
detect_mouse ();
showmouse_text ();
detect ();
hide_mouse ();
getch ();
return 0;
}
status = initmouse();
if ( status == 0 )
printf("Mouse support not available.\n");
else
{
showmouseptr();
getmousepos(&button,&x,&y);
tempx = x;
tempy = y;
while(!kbhit())
{
getmousepos(&button,&x,&y);
if( x == tempx && y == tempy )
{}
else
{
cleardevice();
sprintf(array,"X = %d, Y = %d",x,y);
outtext(array);
tempx = x;
tempy = y;
}
}
}
getch();
return 0;
}
int initmouse()
{
i.x.ax = 0;
int86(0X33,&i,&o);
return ( o.x.ax );
}
void showmouseptr()
{
i.x.ax = 1;
int86(0X33,&i,&o);
}
void getmousepos(int *button, int *x, int *y)
{
i.x.ax = 3;
int86(0X33,&i,&o);
*button = o.x.bx;
*x = o.x.cx;
*y = o.x.dx; }
int86(0X33,&i,&o);
return ( o.x.ax );
}
void showmouseptr()
{
i.x.ax = 1;
int86(0X33,&i,&o);
}
void hidemouseptr()
{
i.x.ax = 2;
// to hide mouse
int86(0X33,&i,&o);
}
6. c program to restrict mouse pointer
Source code:
#include<dos.h>
#include<graphics.h>
#include<conio.h>
int initmouse();
void showmouseptr();
void hidemouseptr();
void restrictmouseptr(int, int, int, int);
union REGS i, o;
main()
{
int status, gd = DETECT, gm;
initgraph(&gd,&gm,"C:\\TC\\BGI");
settextstyle(DEFAULT_FONT,0,2);
status = initmouse();
if ( status == 0 )
outtext("Mouse support not available.\n");
else
{
showmouseptr();
rectangle(120,70,520,410);
restrictmouseptr(120,70,520,410);
}
getch();
return 0;
}
int initmouse()
{
i.x.ax = 0;
int86(0X33,&i,&o);
return ( o.x.ax );
}
void showmouseptr()
{
i.x.ax = 1;
int86(0X33,&i,&o);
}
void restrictmouseptr(int x1, int y1, int x2, int y2)
{
i.x.ax = 7;
i.x.cx = x1;
i.x.dx = x2;
int86(0X33,&i,&o);
i.x.ax = 8;
i.x.cx = y1;
i.x.dx = y2;
int86(0X33,&i,&o);
}
7. c program to restrict mouse pointer in a circle
Source code:
#include<graphics.h>
#include<conio.h>
#include<dos.h>
#include<stdlib.h>
#include<math.h>
union REGS i, o;
int initmouse()
{
i.x.ax = 0;
int86(0X33, &i, &o);
return ( o.x.ax );
}
void showmouseptr()
{
i.x.ax = 1;
int86(0X33, &i, &o);
}
void hidemopuseptr()
{
i.x.ax = 2;
int86(0X33,&i,&o);
}
void getmousepos(int *x, int *y)
{
i.x.ax = 3;
int86(0X33, &i, &o);
*x = o.x.cx;
*y = o.x.dx;
}
void movemouseptr(int x, int y)
{
i.x.ax = 4;
i.x.cx = x;
i.x.dx = y;
int86(0X33, &i, &o);
}
main()
{
int gd = DETECT, gm, midx, midy, radius, x, y, tempx, tempy;
radius = 100;
initgraph(&gd, &gm, "C:\\TC\\BGI");
if(!initmouse())
{
closegraph();
exit(1);
}
midx = getmaxx()/2;
midy = getmaxy()/2;
showmouseptr();
movemouseptr(midx, midy);
circle(midx, midy, radius);
x = tempx = midx;
y = tempy = midy;
while(!kbhit())
{
getmousepos(&x, &y);
if((pow(x-midx,2)+pow(y-midy,2)-pow(radius,2))>0)
{
movemouseptr(tempx, tempy);
x = tempx;
y = tempy;
}
tempx = x;
tempy = y;
}
closegraph();
return 0;
}
8. c program to show mouse pointer on to the screen in text mode
Source code:
#include<dos.h>
#include<conio.h>
int initmouse();
void showmouseptr();
union REGS i, o;
main()
{
int status;
status = initmouse();
if ( status == 0 )
printf("Mouse support not available.\n");
else
showmouseptr();
getch();
return 0;
}
int initmouse()
{
i.x.ax = 0;
int86(0X33,&i,&o);
return ( o.x.ax );
}
void showmouseptr()
{
i.x.ax = 1;
int86(0X33,&i,&o);
}
CONCLUSION
Mouse programming has lots of applications like gaming, GUI , Graphics ,
animations etc.
Mouse programming is a topic which every C programmer from beginner to
professional needs to have in his tool box to have a cutting edge .