180 likes | 233 Views
On using the mouse. A brief introduction to LIBGPM: the General Purpose Mouse programming interface. Diversity of hardware. As with SVGA devices, there are computer mice from a diversity of vendors – and no universal standard hardware design
E N D
On using the mouse A brief introduction to LIBGPM: the General Purpose Mouse programming interface
Diversity of hardware • As with SVGA devices, there are computer mice from a diversity of vendors – and no universal standard hardware design • The customary solution: a software layer is created which ‘hides’ hardware differences • For Linux platforms, the ‘libgpm’ package provides one such software-layer – though it was intended for text-based applications
Example: the PS/2 Mouse The Mouse Report Format (3 bytes) 7 6 5 4 3 2 1 0 Y-data over flow X-data over flow Y-data sign X-data sign 0 Middle Button down Right Button down Left Button down Byte 0 Byte 1 Byte 2 X-coordinate data (bits 7..0) Y-coordinate data (bits 7..0) Other types of computer mice use different report formats with possibly a different number of bytes (e.g., 4 or 5)
The Linux “gpm” package • It’s a mouse server for the Linux console • It “hides” details about mouse hardware • Intended for use with text-based programs • But we can use it with graphics programs • Requires that the gpm daemon is running • Type ‘info gpm’ to see official information • Also an online article by Pradeep Padala
Programming steps • Your client application must establish a connection with the gpm server-daemon • You need a header-file: #include <gpm.h> • You declare an important data-structure: Gpm_Connect conn; • You will need to initialize its four fields • Then you call Gpm_Open( &conn, 0 ); • Returns -1 if unsuccessful (otherwise 0)
Fields to be initialized conn.eventMask = ~0; // events of interest conn.defaultMask = 0; // to handle for you conn.minMod = 0; // lowest modifier conn.maxMod = ~0; // highest modifer
Responding to mouse activity • You create your own ‘handler’ function for those mouse events that you wish to act upon • Prototype of the handler-function is: int my_handler( Gpm_Event *evt, void *my_data ); • To install the handler, use this assignment: gpm_handler = my_handler; • Whenever the mouse is moved, or its buttons are pressed or released, your function executes
Useful fields in Gpm_Event Gpm_Event *evt; evt->type == 1: // indicates a mouse-move evt->x, evt->y: // current mouse ‘hot-spot’ evt->dx, evt->dy: // changes in position(+/-) NOTE: Remember that GPM was developed for text-based applications, so the hot-spot coordinates are character-cell locations (not graphics-pixel locations)
The GPM mouse-event mask #include <gpm.h> L E A V E E N T E R H A R D M O V C L K T R I P L E D O U B L E S I N G L E U P D O W N D R A G M O V E Your event-handler function will ‘test’ one or more of these flag-bits to determine what type of state-change the mouse has undergone, so that your application can respond to it in an appropriate manner
A typical program loop This loop allows normal keyboard input to continue being processed (e.g., echoed, buffered) while any mouse activities are processed by your handler (or else by a default handler supplied by the daemon) int c; while ( ( c = Gpm_Getc( stdin ) ) != EOF ); Gpm_Close();
A simple text-mode demo • Pradeep Padala has published a short C program that illustrates ‘barebones’ usage of the gpm package (from Linux Journal) • We have adapted his code for C++ • Our demo is called ‘trymouse.cpp’ • It’s compiled like this: $ g++ trymouse.cpp –lgpm –o trymouse
A simple graphics demo • We have created a minimal graphics demo • It shows how you could use the mouse to move a ‘slider’ object (e.g.,in Pong game) • It’s called ‘gpmslide.cpp’ • You compile it like this: $ g++ gpmslide.cpp –lgpm –o gpmslide
More elaborate graphics demo • We also created a more elaborate mouse-demo (called ‘seemouse.cpp’) • It defines its own custom mouse-cursor • It handles the four most common types of mouse events: • GPM_MOVE • GPM_DOWN • GPM_DRAG • GPM_UP
Our mouse cursor • We built a 2-color 16-by-16 pixel image We used an array of character-strings to define our image with only three character-values ‘0’ = transparent color ‘1’ = background color ‘2’ = foreground color
Our mouse cache • Each time we want to draw our cursor, we first copy the existing 16-by-16 pixel-grid that occupies the planned cursor-location • Then we can draw our cursor threre • When the mouse is moved, we need to ‘erase’ our cursor-image (by copying the saved background there), and then save-and-draw our cursor in the new location
In-class exercise #1 • Can you create a different cursor-image, based on your own design ideas? Will your design define a different ‘hot-spot’? Will you need to modify the boundaries to keep your cursor from going out-of-view?
Demo: ‘persists.cpp’ • We created a sound-playing program that plays a continuous tone – until a ‘signal’ is received (asynchronous notification) that the user has pressed the <ESCAPE> key • We used an ‘ioctl’ command to ‘RESET’ the playback device – to stop the tone’s sound almost immediately when our user presses the <ESCAPE> key
In-class exercise #2 • Try commenting out the final ‘ioctl’() call in our ‘persists.cpp’ demo, then recompile it and execute that demo again. Does the sound cease immediately? • Can you incorporate the sound-effect into our ‘seemouse.cpp’ demo, so that a user can start the tone by pressing the mouse-button, and stop the tone by releasing it?