-/* 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 <hugo@hugovil.com>
+ *
+ * This file is released under the GPLv2
+ */
#if HAVE_CONFIG_H
# include "config.h"
/* 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 */
}