summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Spillaz <smspillaz@gmail.com>2008-04-26 21:26:42 +0800
committerSam Spillaz <smspillaz@gmail.com>2008-04-26 21:26:42 +0800
commite1737e4024c66e066531fd3552abaf5428c1c382 (patch)
tree9b8fca80b1e6e0db9c2ff4f81f7341d8aab1ad64
parentca73db7c91c0e28c3170f9946c168cf4576befa8 (diff)
downloadwiimote-e1737e4024c66e066531fd3552abaf5428c1c382.tar.gz
wiimote-e1737e4024c66e066531fd3552abaf5428c1c382.tar.bz2
* Added the new files that I split into (I think I went overboard. Meh)
-rw-r--r--.dotest/00010
-rw-r--r--.dotest/last0
-rw-r--r--CMakeLists.txt3
-rw-r--r--action.c198
-rw-r--r--communicate.c56
-rw-r--r--gesture.c156
-rw-r--r--option.c182
-rw-r--r--util.c142
8 files changed, 737 insertions, 0 deletions
diff --git a/.dotest/0001 b/.dotest/0001
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.dotest/0001
diff --git a/.dotest/last b/.dotest/last
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.dotest/last
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..87cce7b
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,3 @@
+include (CompizFusion)
+
+compiz_fusion_plugin (wiimote PLUGINDEPS prompt)
diff --git a/action.c b/action.c
new file mode 100644
index 0000000..6e83042
--- /dev/null
+++ b/action.c
@@ -0,0 +1,198 @@
+/**
+ *
+ * Compiz Nintendo(R) Wii(TM) Remote Interface Plugin
+ *
+ * Copyright : (C) 2008 by Sam Spilsbury
+ * E-mail : smspillaz@gmail.com
+ *
+ *
+ * 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.
+ *
+ */
+
+#include "compiz-wiimote.h"
+
+/* Callable Actions --------------------------------------------------- */
+
+Bool
+wiimoteToggle (CompDisplay *d,
+ CompAction *action,
+ CompActionState cstate,
+ CompOption *option,
+ int nOption)
+{
+ int rc;
+
+ WIIMOTE_DISPLAY (d);
+
+ /* Create second thread attributes */
+
+ pthread_attr_t secondThreadAttr;
+ pthread_attr_init(&secondThreadAttr);
+ pthread_attr_setdetachstate(&secondThreadAttr, PTHREAD_CREATE_JOINABLE);
+
+ CompWindow *w;
+ w = findWindowAtDisplay (d, getIntOptionNamed (option, nOption,
+ "window", 0));
+ if (!w)
+ return TRUE;
+
+ CompScreen *s;
+ s = findScreenAtDisplay (d, getIntOptionNamed (option, nOption,
+ "root", 0));
+ if (s)
+ {
+ ad->firstRoot = s->root;
+
+ /* Create Message */
+ CompOption arg[4];
+ int nArg = 0;
+
+ arg[nArg].name = "window";
+ arg[nArg].type = CompOptionTypeInt;
+ arg[nArg].value.i = d->activeWindow;
+ nArg++;
+
+ arg[nArg].name = "root";
+ arg[nArg].type = CompOptionTypeInt;
+ arg[nArg].value.i = s->root;
+ nArg++;
+
+ arg[nArg].name = "string";
+ arg[nArg].type = CompOptionTypeString;
+ arg[nArg].value.s = "Put your Wii Remote in a neutral position and \n"\
+ "hold down the 1 and 2 Buttons now";
+ nArg++;
+
+ arg[nArg].name = "timeout";
+ arg[nArg].type = CompOptionTypeInt;
+ arg[nArg].value.i = 2000;
+
+ sendInfoToPlugin (d, arg, nArg,
+ "prompt",
+ "display_text");
+ compLogMessage (d, "wiimote", CompLogLevelInfo,
+ "Hold down the 1 and 2 Buttons on your Nintendo Wii Remote now");
+ /* Create the second thread. */
+ rc = pthread_create(&ad->cWiimote[ad->nWiimote].connectWiimote, &secondThreadAttr, connectWiimote, (void *)d);
+
+ /* Clean up second thread's attribute. */
+ pthread_attr_destroy(&secondThreadAttr);
+ if (!rc)
+ {
+ /* So the thread succeeded!
+ * Start Checking! */
+ ad->checkingTimeoutHandle = compAddTimeout (10, checkConnected, d);
+ }
+ }
+ return TRUE;
+}
+
+Bool
+wiimoteDisable (CompDisplay *d,
+ CompAction *action,
+ CompActionState cstate,
+ CompOption *option,
+ int nOption)
+{
+
+ int rc;
+
+ WIIMOTE_DISPLAY (d);
+
+ /* nWiimote -1 because we increment nWiimote
+ * so we need to find the most recent (Which is -1)
+ */
+
+
+ if (ad->nWiimote < 1)
+ return FALSE;
+
+ ad->cWiimote[ad->nWiimote - 1].initiated = FALSE;
+ ad->cWiimote[ad->nWiimote - 1].connected = FALSE;
+
+ /* Wait for the second thread to return control to itself */
+
+ rc = pthread_join(ad->cWiimote[ad->nWiimote -1].connectWiimote, NULL);
+ if (rc)
+ compLogMessage (d, "wiimote", CompLogLevelError,
+ "Threading error occurred.\n");
+
+ /* Remove timeout handles */
+
+ if (ad->infoTimeoutHandle)
+ compRemoveTimeout (ad->infoTimeoutHandle);
+
+ if (ad->gestureTimeoutHandle)
+ compRemoveTimeout (ad->gestureTimeoutHandle);
+
+ /* Remove the lights timeout handle */
+
+ if (ad->cWiimote[ad->nWiimote - 1].lightsTimeoutHandle)
+ compRemoveTimeout (ad->cWiimote[ad->nWiimote - 1].lightsTimeoutHandle);
+
+ /* Tell the user that we are closing the connection */
+
+ compLogMessage (d, "wiimote", CompLogLevelInfo,
+ "Closing connection to most recently connected Wii Remote\n");
+ if (cwiid_close(ad->cWiimote[ad->nWiimote - 1].wiimote)) {
+ compLogMessage (d, "wiimote", CompLogLevelError,
+ "Error closing that connection\n");
+ return -1;
+ }
+
+ /* Decrement Wiimote Iter */
+
+ ad->nWiimote--;
+
+ return TRUE;
+}
+
+
+
+Bool
+wiimoteSendInfo (CompDisplay *d,
+ CompAction *action,
+ CompActionState cstate,
+ CompOption *option,
+ int nOption)
+{
+ WIIMOTE_DISPLAY (d);
+
+ Window root;
+ CompScreen *s;
+
+ ad->report = !ad->report;
+
+ if (!ad->report)
+ {
+ if (ad->infoTimeoutHandle)
+ compRemoveTimeout (ad->infoTimeoutHandle);
+ return FALSE;
+ }
+
+ root = getIntOptionNamed (option, nOption, "root", 0);
+ s = findScreenAtDisplay (d, root);
+
+ if (s)
+ {
+ /* Add a timeout to send info to another
+ * plugin. The preferable way would be for
+ * other plugins to get the values when they
+ * need them, but this is just a workaround
+ * for plugins that support the action system
+ */
+
+ ad->infoTimeoutHandle = compAddTimeout(wiimoteGetPollInterval (s->display) , sendReports, s);
+ ad->gestureTimeoutHandle = compAddTimeout(wiimoteGetGestureTimeout (s->display) , wiimoteCheckForGestures, s);
+ }
+ return TRUE;
+}
diff --git a/communicate.c b/communicate.c
new file mode 100644
index 0000000..0fa7cc0
--- /dev/null
+++ b/communicate.c
@@ -0,0 +1,56 @@
+#include "compiz-wiimote.h"
+
+/* Inter-Plugin Communication --------------------------------------------------- */
+
+Bool
+sendInfoToPlugin (CompDisplay *d, CompOption *argument, int nArgument, char *pluginName, char *actionName)
+{
+ Bool pluginExists = FALSE;
+ CompOption *options, *option;
+ CompPlugin *p;
+ CompObject *o;
+ int nOptions;
+ int i = wiimoteDisplayPrivateIndex;
+
+ free(&i);
+
+ p = findActivePlugin (pluginName);
+ o = compObjectFind (&core.base, COMP_OBJECT_TYPE_DISPLAY, NULL);
+
+ if (!o)
+ return FALSE;
+
+ if (!p || !p->vTable->getObjectOptions)
+ {
+ compLogMessage (d, "wiimote", CompLogLevelError,
+ "Reporting plugin '%s' does not exist!", pluginName);
+ return FALSE;
+ }
+
+ if (p && p->vTable->getObjectOptions)
+ {
+ options = (*p->vTable->getObjectOptions) (p, o, &nOptions);
+ option = compFindOption (options, nOptions, actionName, 0);
+ pluginExists = TRUE;
+ }
+
+ if (pluginExists)
+ {
+ if (option && option->value.action.initiate)
+ {
+ (*option->value.action.initiate) (d,
+ &option->value.action,
+ 0,
+ argument,
+ nArgument);
+ }
+ else
+ {
+ compLogMessage (d, "wiimote", CompLogLevelError,
+ "Plugin '%s' does exist, but no option named '%s' was found!", pluginName, actionName);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/gesture.c b/gesture.c
new file mode 100644
index 0000000..cb0abd4
--- /dev/null
+++ b/gesture.c
@@ -0,0 +1,156 @@
+/**
+ *
+ * Compiz Nintendo(R) Wii(TM) Remote Interface Plugin
+ *
+ * Copyright : (C) 2008 by Sam Spilsbury
+ * E-mail : smspillaz@gmail.com
+ *
+ *
+ * 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.
+ *
+ */
+
+#include "compiz-wiimote.h"
+
+/* Gesturing and gesture checking --------------------------------------------- */
+
+#define CHECK_BUTTON(a,b,c,e) \
+ if (mesg->buttons & a) \
+ { \
+ if (!b) \
+ sendGesture(d, wiimoteNumber, c); \
+ b = TRUE; \
+ } \
+ else \
+ { \
+ if (b) \
+ sendGesture(d, wiimoteNumber, e); \
+ b = FALSE; \
+ } \
+
+
+static Bool sendGesture(CompDisplay *d, int wiimoteNumber, int type)
+{
+ CompOption argument[2];
+ int nArgument = 0;
+ int i;
+
+ WIIMOTE_DISPLAY (d);
+
+ if (ad->cWiimote[wiimoteNumber].connected)
+ {
+ for (i = 0; i < ad->cWiimote[wiimoteNumber].nGesture; i++)
+ {
+ if (ad->cWiimote[wiimoteNumber].gesture[i].type == type)
+ {
+ argument[nArgument].name = "window";
+ argument[nArgument].type = CompOptionTypeInt;
+ argument[nArgument].value.i = d->activeWindow;
+ nArgument++;
+
+ argument[nArgument].name = "root";
+ argument[nArgument].type = CompOptionTypeInt;
+ argument[nArgument].value.i = ad->firstRoot;
+ nArgument++;
+
+ sendInfoToPlugin (d, argument, nArgument,
+ ad->cWiimote[wiimoteNumber].gesture[i].pluginName,
+ ad->cWiimote[wiimoteNumber].gesture[i].actionName);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+void
+wiimoteProcessButtons(CompDisplay *d, int wiimoteNumber, struct cwiid_btn_mesg *mesg)
+{
+ WIIMOTE_DISPLAY (d);
+
+ CHECK_BUTTON( CWIID_BTN_A, ad->cWiimote[wiimoteNumber].buttons.A, 1, 2);
+ CHECK_BUTTON( CWIID_BTN_B, ad->cWiimote[wiimoteNumber].buttons.B, 3, 4);
+ CHECK_BUTTON( CWIID_BTN_UP, ad->cWiimote[wiimoteNumber].buttons.Up, 5, 6);
+ CHECK_BUTTON( CWIID_BTN_DOWN, ad->cWiimote[wiimoteNumber].buttons.Down, 7, 8);
+ CHECK_BUTTON( CWIID_BTN_LEFT, ad->cWiimote[wiimoteNumber].buttons.Left, 9, 10);
+ CHECK_BUTTON( CWIID_BTN_RIGHT, ad->cWiimote[wiimoteNumber].buttons.Right, 11, 12);
+ CHECK_BUTTON( CWIID_BTN_PLUS, ad->cWiimote[wiimoteNumber].buttons.Plus, 13, 14);
+ CHECK_BUTTON( CWIID_BTN_MINUS, ad->cWiimote[wiimoteNumber].buttons.Minus, 15, 16);
+ CHECK_BUTTON( CWIID_BTN_HOME, ad->cWiimote[wiimoteNumber].buttons.Home, 17, 18);
+ CHECK_BUTTON( CWIID_BTN_1, ad->cWiimote[wiimoteNumber].buttons.One, 19, 20);
+ CHECK_BUTTON( CWIID_BTN_2, ad->cWiimote[wiimoteNumber].buttons.Two, 21, 22);
+
+}
+
+void
+wiimoteProcessNunchuckButtons (CompDisplay *d, int wiimoteNumber, struct cwiid_nunchuk_mesg *mesg)
+{
+ WIIMOTE_DISPLAY (d);
+
+ CHECK_BUTTON ( CWIID_NUNCHUK_BTN_C, ad->cWiimote[wiimoteNumber].nunchuck.buttons.C, 23, 24);
+ CHECK_BUTTON ( CWIID_NUNCHUK_BTN_Z, ad->cWiimote[wiimoteNumber].nunchuck.buttons.Z, 25, 26);
+}
+
+/* I would rather use #define, but it's bugged up, so I have to compromise */
+
+static void
+wiimoteCheckGesture (CompScreen *s, int wiimoteNumber, float diff, float init, float *old, float value, int posGest, int negGest)
+{
+
+ if (*old <= value - diff && value <= init)
+ sendGesture (s->display, wiimoteNumber, negGest);
+ if (*old >= value + diff && value >= init)
+ sendGesture (s->display, wiimoteNumber, posGest);
+
+ *old = value;
+}
+
+Bool wiimoteCheckForGestures (void *vs)
+{
+ CompScreen *s = (CompScreen *) vs;
+ int i;
+ float sens = wiimoteGetGestureSens (s->display);
+
+ WIIMOTE_DISPLAY (s->display);
+
+ for (i = 0; i < MAX_WIIMOTES; i++)
+ {
+ if (ad->cWiimote[i].connected)
+ {
+ /* Check Accellerometer */
+
+ wiimoteCheckGesture (s, i, sens, ad->cWiimote[i].acc.initAccY,
+ &ad->cWiimote[i].acc.oldAccY,
+ ad->cWiimote[i].acc.accY, 27, 28);
+ wiimoteCheckGesture (s, i, sens, ad->cWiimote[i].acc.initAccX,
+ &ad->cWiimote[i].acc.oldAccX,
+ ad->cWiimote[i].acc.accX, 29, 30);
+
+ /* Check Nunchuk */
+ if (ad->cWiimote[i].nunchuck.connected)
+ {
+ wiimoteCheckGesture ( s, i, sens, ad->cWiimote[i].nunchuck.initAccY,
+ &ad->cWiimote[i].nunchuck.oldAccY,
+ ad->cWiimote[i].nunchuck.accY, 31, 32 );
+ wiimoteCheckGesture ( s, i, sens, ad->cWiimote[i].nunchuck.initAccX,
+ &ad->cWiimote[i].nunchuck.oldAccX,
+ ad->cWiimote[i].nunchuck.accX, 33, 34 );
+ wiimoteCheckGesture ( s, i, sens, ad->cWiimote[i].nunchuck.initStickY,
+ &ad->cWiimote[i].nunchuck.oldStickY,
+ ad->cWiimote[i].nunchuck.stickY, 35, 36 );
+ wiimoteCheckGesture ( s, i, sens, ad->cWiimote[i].nunchuck.initStickX,
+ &ad->cWiimote[i].nunchuck.oldStickX,
+ ad->cWiimote[i].nunchuck.stickX, 37, 38 );
+ }
+ }
+ }
+ return TRUE;
+}
diff --git a/option.c b/option.c
new file mode 100644
index 0000000..ce0ed66
--- /dev/null
+++ b/option.c
@@ -0,0 +1,182 @@
+/**
+ *
+ * Compiz Nintendo(R) Wii(TM) Remote Interface Plugin
+ *
+ * Copyright : (C) 2008 by Sam Spilsbury
+ * E-mail : smspillaz@gmail.com
+ *
+ *
+ * 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.
+ *
+ */
+
+#include "compiz-wiimote.h"
+
+/* Option Initialisation --------------------------------------------------- */
+
+void
+reloadWiimoteGestures (CompDisplay *d)
+{
+ CompListValue *cWiimoteNumber = wiimoteGetGestureWiimoteNumber (d);
+ CompListValue *cGestureType = wiimoteGetGestureType (d);
+ CompListValue *cPluginName = wiimoteGetGesturePluginName (d);
+ CompListValue *cActionName = wiimoteGetGestureActionName (d);
+ CompListValue *cGestureSensitivity = wiimoteGetGestureSensitivity (d);
+
+ int nGesture;
+ int iGesture = 0;
+ int i = 0;
+
+ if ((cWiimoteNumber->nValue != cGestureType->nValue) ||
+ (cWiimoteNumber->nValue != cPluginName->nValue) ||
+ (cWiimoteNumber->nValue != cGestureSensitivity->nValue) ||
+ (cWiimoteNumber->nValue != cActionName->nValue))
+ {
+ /* Options have not been set correctly */
+ return;
+ }
+
+ WIIMOTE_DISPLAY (d);
+
+ for (i = 0; i < MAX_WIIMOTES; i++)
+ {
+ nGesture = cWiimoteNumber->nValue;
+ iGesture = 0;
+ int k = 0;
+ ad->cWiimote[i].nGesture = 0;
+
+ while (nGesture-- && iGesture < MAX_GESTURES)
+ {
+ if (cWiimoteNumber->value[iGesture].i == i)
+ {
+ ad->cWiimote[i].gesture[iGesture].set = TRUE;
+ ad->cWiimote[i].gesture[iGesture].pluginName = strdup(cPluginName->value[iGesture].s);
+ ad->cWiimote[i].gesture[iGesture].actionName = strdup(cActionName->value[iGesture].s);
+ ad->cWiimote[i].gesture[iGesture].sensitivity = cGestureSensitivity->value[iGesture].i;
+
+ ad->cWiimote[i].gesture[k].type = cGestureType->value[iGesture].i;
+ k++;
+ ad->cWiimote[i].nGesture++;
+
+ }
+ iGesture++;
+ }
+ }
+}
+
+void
+reloadWiimoteReporters(CompDisplay *d)
+{
+ CompListValue *cWiimoteNumber = wiimoteGetReportWiimoteNumber (d);
+ CompListValue *cReportType = wiimoteGetReportType (d);
+ CompListValue *cPluginName = wiimoteGetReportPluginName (d);
+ CompListValue *cActionName = wiimoteGetReportActionName (d);
+ CompListValue *cReportSensitivity = wiimoteGetReportSensitivity (d);
+
+ CompListValue *cXArgument = wiimoteGetReportXArgument (d);
+ CompListValue *cYArgument = wiimoteGetReportYArgument (d);
+ CompListValue *cZArgument = wiimoteGetReportZArgument (d);
+
+ CompListValue *cDataType = wiimoteGetReportDataType (d);
+
+ int nReport;
+ int iReport = 0;
+ int i = 0;
+
+ WIIMOTE_DISPLAY (d);
+
+ if ((cWiimoteNumber->nValue != cReportType->nValue) ||
+ (cWiimoteNumber->nValue != cPluginName->nValue) ||
+ (cWiimoteNumber->nValue != cActionName->nValue) ||
+ (cWiimoteNumber->nValue != cXArgument->nValue) ||
+ (cWiimoteNumber->nValue != cYArgument->nValue) ||
+ (cWiimoteNumber->nValue != cZArgument->nValue) ||
+ (cWiimoteNumber->nValue != cDataType->nValue) ||
+ (cWiimoteNumber->nValue != cReportSensitivity->nValue))
+ {
+ compLogMessage (d, "wiimote", CompLogLevelError,
+ "Options are not set correctly. Please revisit them and make sure each option in the list is set\n");
+ return;
+ }
+
+ for (i = 0; i < MAX_WIIMOTES; i++)
+ {
+ nReport = cWiimoteNumber->nValue;
+ iReport = 0;
+ ad->cWiimote[i].nReport = 0;
+ int k = 0;
+
+ while (nReport-- && iReport < MAX_REPORTS - 1)
+ {
+ if (cWiimoteNumber->value[iReport].i == i)
+ {
+ /* And set them */
+ ad->cWiimote[i].nReport++;
+ ad->cWiimote[i].report[k].set = TRUE;
+ ad->cWiimote[i].report[k].pluginName = strdup(cPluginName->value[iReport].s);
+ ad->cWiimote[i].report[k].actionName = strdup(cActionName->value[iReport].s);
+ ad->cWiimote[i].report[k].sensitivity = cReportSensitivity->value[iReport].i;
+
+ ad->cWiimote[i].report[k].xarg = strdup(cXArgument->value[iReport].s);
+ ad->cWiimote[i].report[k].yarg = strdup(cYArgument->value[iReport].s);
+ ad->cWiimote[i].report[k].zarg = strdup(cZArgument->value[iReport].s);
+
+ ad->cWiimote[i].report[k].type = cReportType->value[iReport].i;
+ ad->cWiimote[i].report[k].dataType = cDataType->value[iReport].i;
+
+ k++; /* Set next availiable option */
+ }
+
+ iReport++;
+ }
+ }
+}
+
+void
+reloadWiimoteOptions (CompDisplay *d)
+{
+ CompListValue *cXCal = wiimoteGetXCalibrationMul (d);
+ CompListValue *cYCal = wiimoteGetYCalibrationMul (d);
+ CompListValue *cXAdj = wiimoteGetXAdjust (d);
+ CompListValue *cYAdj = wiimoteGetYAdjust (d);
+
+ int nWiimote;
+ int iWiimote = 0;
+ int i = 0;
+
+ WIIMOTE_DISPLAY (d);
+
+ if ((cXCal->nValue != cYCal->nValue) ||
+ (cXCal->nValue != cXAdj->nValue) ||
+ (cXCal->nValue != cYAdj->nValue))
+ {
+ /* Options have not been set correctly */
+ return;
+ }
+
+ for (i = 0; i < MAX_WIIMOTES; i++)
+ {
+ nWiimote = cXCal->nValue;
+ iWiimote = 0;
+ while (nWiimote-- && iWiimote < MAX_REPORTS)
+ {
+ if (iWiimote == i)
+ {
+ ad->cWiimote[i].irMulX = cXCal->value[iWiimote].f;
+ ad->cWiimote[i].irMulY = cYCal->value[iWiimote].f;
+ ad->cWiimote[i].irSubX = cXAdj->value[iWiimote].f;
+ ad->cWiimote[i].irSubY = cYAdj->value[iWiimote].f;
+ }
+
+ iWiimote++;
+ }
+ }
+}
diff --git a/util.c b/util.c
new file mode 100644
index 0000000..adda275
--- /dev/null
+++ b/util.c
@@ -0,0 +1,142 @@
+/**
+ *
+ * Compiz Nintendo(R) Wii(TM) Remote Interface Plugin
+ *
+ * Copyright : (C) 2008 by Sam Spilsbury
+ * E-mail : smspillaz@gmail.com
+ *
+ *
+ * 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.
+ *
+ */
+
+#include "compiz-wiimote.h"
+
+/* Utility Functions --------------------------------------------------- */
+
+/* Error Handling */
+void err(cwiid_wiimote_t *wiimote, const char *s, va_list ap)
+{
+ if (wiimote) printf("%d:", cwiid_get_id(wiimote));
+ else printf("-1:");
+ vprintf(s, ap);
+ printf("\n");
+}
+
+/* Set LED Wrapper */
+void set_led_state(cwiid_wiimote_t *wiimote, unsigned char led_state)
+{
+ if (cwiid_set_led(wiimote, led_state)) {
+ fprintf(stderr, "Error setting LEDs \n");
+ }
+}
+
+/* Set Reporting Mode Wrapper*/
+void set_rpt_mode(cwiid_wiimote_t *wiimote, unsigned char rpt_mode)
+{
+ if (cwiid_set_rpt_mode(wiimote, rpt_mode)) {
+ fprintf(stderr, "Error setting report mode\n");
+ }
+}
+
+/* Wii Remote Light Show */
+
+Bool wiimoteChangeLights(void *Wiimote)
+{
+ cwiid_wiimote_t *wiimote = Wiimote;
+ WIIMOTE_DISPLAY (firstDisplay);
+ int led_state = 0;
+ ad->count++;
+ switch (ad->count)
+ {
+ case 1:
+ {
+ toggle_bit(led_state, CWIID_LED1_ON);
+ set_led_state(wiimote, led_state);
+ }
+ break;
+ case 2:
+ {
+ toggle_bit(led_state, CWIID_LED2_ON);
+ set_led_state(wiimote, led_state);
+ }
+ break;
+ case 3:
+ {
+ toggle_bit(led_state, CWIID_LED3_ON);
+ set_led_state(wiimote, led_state);
+ }
+ break;
+ case 4:
+ {
+ toggle_bit(led_state, CWIID_LED4_ON);
+ set_led_state(wiimote, led_state);
+ }
+ break;
+ case 5:
+ {
+ toggle_bit(led_state, CWIID_LED3_ON);
+ set_led_state(wiimote, led_state);
+ }
+ break;
+ case 6:
+ {
+ toggle_bit(led_state, CWIID_LED2_ON);
+ set_led_state(wiimote, led_state);
+ }
+ break;
+ case 7:
+ {
+ toggle_bit(led_state, CWIID_LED1_ON);
+ set_led_state(wiimote, led_state);
+ ad->count = 1;
+ }
+ break;
+ }
+
+
+ return TRUE;
+}
+
+/* Utility */
+int findMinIR (CompDisplay *d, int wiimoteNumber, int ir1, int ir2, int ir3, int ir4)
+{
+ WIIMOTE_DISPLAY (d);
+
+ int min = ir1;
+
+ if ((ir2 < min) && ad->cWiimote[wiimoteNumber].ir[1].valid)
+ min = ir2;
+ if ((ir3 < min) && ad->cWiimote[wiimoteNumber].ir[2].valid)
+ min = ir3;
+ if ((ir4 < min) && ad->cWiimote[wiimoteNumber].ir[3].valid)
+ min = ir4;
+
+ return min;
+}
+
+int findMaxIR (CompDisplay *d, int wiimoteNumber, int ir1, int ir2, int ir3, int ir4)
+{
+ WIIMOTE_DISPLAY (d);
+
+ int max = ir1;
+
+ if ((ir2 > max) && ad->cWiimote[wiimoteNumber].ir[1].valid)
+ max = ir2;
+ if ((ir3 > max) && ad->cWiimote[wiimoteNumber].ir[2].valid)
+ max = ir3;
+ if ((ir4 > max) && ad->cWiimote[wiimoteNumber].ir[3].valid)
+ max = ir4;
+
+ return max;
+}
+
+