2 * xevents.c -- handling X events, and detecting single-click and double-click
5 * Copyright (C) 2009 Hugo Villeneuve <hugo@hugovil.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
34 #include <sys/types.h>
42 /* Maximum time between mouse double-clicks, in milliseconds */
43 #define DOUBLE_CLICK_MAX_INTERVAL_MS 250
46 /* Function pointers to handle single and double mouse click events. */
47 static void (*SingleClickCallback
)( void ) = NULL
;
49 static void (*DoubleClickCallback
)( void ) = NULL
;
55 /* The specified volume is relative to the base volume for the keyboard.
56 To change the base volume of the keyboard, use XChangeKeyboardControl(). */
57 (void) XBell( dockapp
.display
, 100 ); /* Volume = 100% */
61 /* This function must be called at the beginning of your program to initialize
62 the function pointers to handle single and double click mouse events. */
64 ProcessXlibEventsInit( void (*single_click_callback
)( void ),
65 void (*double_click_callback
)( void ) )
69 /* This must be called before any other XLib functions. */
70 status
= XInitThreads();
72 fprintf( stderr
, "%s: XInitThreads() initialization failed\n", PACKAGE
);
73 ErrorLocation( __FILE__
, __LINE__
);
77 SingleClickCallback
= single_click_callback
;
78 DoubleClickCallback
= double_click_callback
;
82 /* Processing of X events */
84 ProcessXlibEvents( void )
87 bool button1_pressed
= false;
88 bool check_for_double_click
= false;
91 while( quit
== false ) {
92 if( ( check_for_double_click
!= false ) &&
93 ( XPending( dockapp
.display
) == 0 ) ) {
94 /* If no other button 1 events are received after the delay, then it is a
95 single-click mouse event. */
96 if( SingleClickCallback
!= NULL
) {
97 (*SingleClickCallback
)();
100 check_for_double_click
= false;
102 /* XNextEvent is a blocking call: it will return only when an event is
103 ready to be processed, thus freeing the CPU for other tasks when no
104 events are available. */
105 (void) XNextEvent( dockapp
.display
, &Event
);
106 switch( Event
.type
) {
108 /* Window was uncovered... */
112 /* Window was killed... */
113 /* Is this necessary ? */
114 (void) XCloseDisplay( dockapp
.display
);
118 /* Doesn't seem to work... */
119 printf( "Client message received...\n" );
122 if( Event
.xbutton
.button
== Button1
) {
123 /* Mouse LEFT button pressed. */
124 button1_pressed
= true;
128 if( Event
.xbutton
.button
== Button1
) {
129 /* Mouse LEFT button released. */
130 if( button1_pressed
!= false ) {
131 /* We act only when the button is released */
132 if( check_for_double_click
!= false ) {
134 if( DoubleClickCallback
!= NULL
) {
135 (*DoubleClickCallback
)();
137 check_for_double_click
= false;
140 (void) usleep( DOUBLE_CLICK_MAX_INTERVAL_MS
* 1000 );
141 check_for_double_click
= true;