X-Git-Url: http://gitweb.hugovil.com/?a=blobdiff_plain;f=src%2Fxevents.c;h=3eec774570675026a5d355d43ccf126b8119b541;hb=5c8ffb2c9ab05420c17242149942af2a9a61fa21;hp=c9b66f6a624e5173b0443159ba26ff24faf0fc89;hpb=eaca75aa6c133cc6ff3d707f7ae8dbfbe51a6d2a;p=dockapps%2Fwmnotify.git diff --git a/src/xevents.c b/src/xevents.c index c9b66f6..3eec774 100644 --- a/src/xevents.c +++ b/src/xevents.c @@ -1,6 +1,23 @@ -/* xevents.c -- handling X events, and detecting single-click and double-click - * mouse events. */ - +/* + * xevents.c -- handling X events, and detecting single-click and double-click + * mouse events. + * + * Copyright (C) 2009 Hugo Villeneuve + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ #if HAVE_CONFIG_H # include "config.h" @@ -22,106 +39,123 @@ #include "xevents.h" +/* Maximum time between mouse double-clicks, in milliseconds */ +#define DOUBLE_CLICK_MAX_INTERVAL_MS 250 + + /* Function pointers to handle single and double mouse click events. */ -static void (*SingleClickCallback)( void ) = NULL; +static void (*SingleClickCallback) (void); -static void (*DoubleClickCallback)( void ) = NULL; +static void (*DoubleClickCallback) (void); -void -AudibleBeep( void ) +void AudibleBeep(void) { - /* The specified volume is relative to the base volume for the keyboard. - To change the base volume of the keyboard, use XChangeKeyboardControl(). */ - (void) XBell( dockapp.display, 100 ); /* Volume = 100% */ + /* + * The specified volume is relative to the base volume for the keyboard. + * To change the base volume of the keyboard, use + * XChangeKeyboardControl(). + */ + (void) XBell(dockapp.display, 100); /* Volume = 100% */ } /* This function must be called at the beginning of your program to initialize the function pointers to handle single and double click mouse events. */ void -ProcessXlibEventsInit( void (*single_click_callback)( void ), - void (*double_click_callback)( void ) ) +ProcessXlibEventsInit(void (*single_click_callback) (void), + void (*double_click_callback) (void)) { - int status; - - /* This must be called before any other XLib functions. */ - status = XInitThreads(); - if( status == 0 ) { - fprintf( stderr, "%s: XInitThreads() initialization failed\n", PACKAGE ); - ErrorLocation( __FILE__, __LINE__ ); - exit( EXIT_FAILURE ); - } - - SingleClickCallback = single_click_callback; - DoubleClickCallback = double_click_callback; + int status; + + /* This must be called before any other XLib functions. */ + status = XInitThreads(); + if (status == 0) { + fprintf(stderr, + "%s: XInitThreads() initialization failed\n", + PACKAGE); + ErrorLocation(__FILE__, __LINE__); + exit(EXIT_FAILURE); + } + + SingleClickCallback = single_click_callback; + DoubleClickCallback = double_click_callback; } +static void detect_double_click(bool *double_click) +{ + /* + * We act only when the button is + * released. + */ + if (*double_click) { + /* Double-click */ + if (DoubleClickCallback != NULL) + (*DoubleClickCallback)(); + + *double_click = false; + } else { + (void) usleep( + DOUBLE_CLICK_MAX_INTERVAL_MS + * 1000); + *double_click = true; + } +} /* Processing of X events */ -void -ProcessXlibEvents( void ) +void ProcessXlibEvents(void) { - bool quit = FALSE; - bool button1_pressed = FALSE; - bool check_for_double_click = FALSE; - XEvent Event; - - while( quit == FALSE ) { - if( ( check_for_double_click != FALSE ) && - ( XPending( dockapp.display ) == 0 ) ) { - /* If no other button 1 events are received after the delay, then it is a - single-click mouse event. */ - if( SingleClickCallback != NULL ) { - (*SingleClickCallback)(); - } - - check_for_double_click = FALSE; - } - /* XNextEvent is a blocking call: it will return only when an event is - ready to be processed, thus freeing the CPU for other tasks when no - events are available. */ - (void) XNextEvent( dockapp.display, &Event ); - switch( Event.type ) { - case Expose: - /* Window was uncovered... */ - RedrawWindow(); - break; - case DestroyNotify: - /* Window was killed... */ - /* Is this necessary ? */ - (void) XCloseDisplay( dockapp.display ); - quit = TRUE; - break; - case ClientMessage: - /* Doesn't seem to work... */ - printf( "Client message received...\n" ); - break; - case ButtonPress: - if( Event.xbutton.button == Button1 ) { - /* Mouse LEFT button pressed. */ - button1_pressed = TRUE; - } - break; - case ButtonRelease: - if( Event.xbutton.button == Button1 ) { - /* Mouse LEFT button released. */ - if( button1_pressed != FALSE ) { - /* We act only when the button is released */ - if( check_for_double_click != FALSE ) { - /* Double-click */ - if( DoubleClickCallback != NULL ) { - (*DoubleClickCallback)(); - } - check_for_double_click = FALSE; - } - else { - (void) usleep( DOUBLE_CLICK_MAX_INTERVAL_MS * 1000 ); - check_for_double_click = TRUE; - } - } - } - break; - } - } /* end while */ + bool quit = false; + bool button1_pressed = false; + bool double_click = false; + XEvent Event; + + while (quit == false) { + if ((double_click) && + (XPending(dockapp.display) == 0)) { + /* + * If no other button 1 events are received after the + * delay, then it is a single-click mouse event. + */ + if (SingleClickCallback != NULL) + (*SingleClickCallback)(); + + double_click = false; + } + /* + * XNextEvent is a blocking call: it will return only when an + * event is ready to be processed, thus freeing the CPU for + * other tasks when no events are available. + */ + (void) XNextEvent(dockapp.display, &Event); + switch (Event.type) { + case Expose: + /* Window was uncovered... */ + RedrawWindow(); + break; + case DestroyNotify: + /* Window was killed... */ + /* Is this necessary ? */ + (void) XCloseDisplay(dockapp.display); + quit = true; + break; + case ClientMessage: + /* Doesn't seem to work... */ + printf("Client message received...\n"); + break; + case ButtonPress: + if (Event.xbutton.button == Button1) { + /* Mouse LEFT button pressed. */ + button1_pressed = true; + } + break; + case ButtonRelease: + if (Event.xbutton.button == Button1) { + /* Mouse LEFT button released. */ + if (button1_pressed) + detect_double_click(&double_click); + } + break; + } + } /* end while */ }