root/wmgui/main.c @ 422e116295dcc983b62bf24728fcbae936c138cb

Revision 422e116295dcc983b62bf24728fcbae936c138cb, 39.7 KB (checked in by dsmith <dsmith@…>, 6 years ago)

Changed CWIID_BDADDR back to WIIMOTE_BDADDR

git-svn-id: http://abstrakraft.org/cwiid/svn/trunk@86 918edb2d-ff29-0410-9de2-eb38e7f22bc7

  • Property mode set to 100644
Line 
1/* Copyright (C) 2007 L. Donnie Smith <cwiid@abstrakraft.org>
2 *
3 *  This program is free software; you can redistribute it and/or modify
4 *  it under the terms of the GNU General Public License as published by
5 *  the Free Software Foundation; either version 2 of the License, or
6 *  (at your option) any later version.
7 *
8 *  This program is distributed in the hope that it will be useful,
9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *  GNU General Public License for more details.
12 *
13 *  You should have received a copy of the GNU General Public License
14 *  along with this program; if not, write to the Free Software
15 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16 *
17 *  ChangeLog:
18 *  2007-04-09 L. Donnie Smith <cwiid@abstrakraft.org>
19 *  * updated for libcwiid rename
20 *
21 *  2007-04-08 L. Donnie Smith <cwiid@anstrakraft.org>
22 *  * fixed signed/unsigned comparison warning in btnRead_clicked
23 *
24 *  2007-04-04 L. Donnie Smith <cwiid@abstrakraft.org>
25 *  * disconnect on cwiid_mesg_error
26 *
27 *  2007-04-03 L. Donnie Smith <cwiid@abstrakraft.org>
28 *  * commented custom cwiid_err (causing Xlib errors)
29 *
30 *  2007-03-01 L. Donnie Smith <cwiid@abstrakraft.org>
31 *  * Initial Changelog
32 *  * type audit (stdint, const, char booleans)
33 */
34
35#define APP_NAME                "CWiid wmgui"
36#define APP_COPYRIGHT   "Copyright (C) 2007 L. Donnie Smith " \
37                        "<cwiid@abstrakraft.org>"
38#define APP_COMMENTS    "Wiimote GUI"
39
40#include <ctype.h>
41#include <float.h>
42#include <math.h>
43#include <stdio.h>
44#include <stdint.h>
45#include <string.h>
46#include <stdlib.h>
47#include <unistd.h>
48
49#include <glib.h>
50#include <gtk/gtk.h>
51
52#include "interface.h"
53#include "support.h"
54
55#include <bluetooth/bluetooth.h>
56#include "cwiid.h"
57
58#define PI      3.14159265358979323
59
60struct acc {
61        uint8_t x;
62        uint8_t y;
63        uint8_t z;
64};
65
66struct stick {
67        char valid;
68        uint8_t x;
69        uint8_t y;
70        uint8_t max;
71};
72
73/* Globals */
74cwiid_wiimote_t *wiimote = NULL;
75bdaddr_t bdaddr;
76struct acc acc_zero, acc_one;
77struct cwiid_ir_mesg ir_data;
78struct acc nc_acc_zero, nc_acc_one;
79struct stick nc_stick;
80struct stick cc_l_stick, cc_r_stick;
81
82/* Widgets */
83GtkWidget *winMain;
84GtkWidget *winRW;
85GtkWidget *winDialog;
86GtkWidget *menuConnect, *menuDisconnect, *menuQuit, *menuRW, *menuAbout;
87GtkWidget *chkAcc, *chkIR, *chkExt;
88GtkWidget *chkLED1, *chkLED2, *chkLED3, *chkLED4;
89GtkWidget *chkRumble;
90GtkWidget *evUp, *evDown, *evLeft, *evRight, *evA, *evB,
91          *evMinus, *evPlus, *evHome, *ev1, *ev2;
92GtkWidget *lblUp, *lblDown, *lblLeft, *lblRight, *lblA, *lblB,
93          *lblMinus, *lblPlus, *lblHome, *lbl1, *lbl2;
94GtkWidget *lblAccX, *lblAccY, *lblAccZ;
95GtkWidget *lblAccXVal, *lblAccYVal, *lblAccZVal;
96GtkWidget *progAccX, *progAccY, *progAccZ;
97GtkWidget *lblAcc, *lblRoll, *lblPitch;
98GtkWidget *lblAccVal, *lblRollVal, *lblPitchVal;
99GtkWidget *lblIR;
100GtkWidget *drawIR;
101GtkWidget *lblNC;
102GtkWidget *drawNCStick;
103GtkWidget *evNCC, *evNCZ;
104GtkWidget *lblNCC, *lblNCZ;
105GtkWidget *lblNCAccX, *lblNCAccY, *lblNCAccZ;
106GtkWidget *lblNCAccXVal, *lblNCAccYVal, *lblNCAccZVal;
107GtkWidget *progNCAccX, *progNCAccY, *progNCAccZ;
108GtkWidget *lblNCAcc, *lblNCRoll, *lblNCPitch;
109GtkWidget *lblNCAccVal, *lblNCRollVal, *lblNCPitchVal;
110GtkWidget *evCCUp, *evCCDown, *evCCLeft, *evCCRight, *evCCMinus, *evCCPlus,
111          *evCCHome, *evCCA, *evCCB, *evCCX, *evCCY, *evCCZL, *evCCZR;
112GtkWidget *lblCCUp, *lblCCDown, *lblCCLeft, *lblCCRight, *lblCCMinus,
113          *lblCCPlus, *lblCCHome, *lblCCA, *lblCCB, *lblCCX, *lblCCY, *lblCCZL,
114          *lblCCZR;
115GtkWidget *drawCCLStick, *drawCCRStick;
116GtkWidget *evCCL, *evCCR;
117GtkWidget *lblCCL, *lblCCR;
118GtkWidget *lblCCLVal, *lblCCRVal;
119GtkWidget *progCCL, *progCCR;
120GtkWidget *statConnection, *statBattery, *statExtension;
121GtkWidget *txtReadOffset, *txtReadLen;
122GtkWidget *radReadEEPROM, *radReadReg;
123GtkWidget *btnRead;
124GtkWidget *txtWriteOffset, *txtWriteData;
125GtkWidget *radWriteEEPROM, *radWriteReg;
126GtkWidget *btnWrite;
127GtkWidget *tvRW;
128GtkWidget *btnRWClose;
129GtkWidget *btnBeep;
130
131GtkTextBuffer *tbRW;
132
133GdkColor btn_on, btn_off;
134
135/* Utility functions */
136void set_gui_state();
137void clear_widgets();
138void clear_acc_widgets();
139void clear_ir_data();
140void clear_nunchuk_widgets();
141void clear_classic_widgets();
142void message(GtkMessageType type, const gchar *message, GtkWindow *parent);
143void status(const gchar *status);
144
145/* GTK Callbacks */
146gboolean winMain_delete_event(void);
147gboolean winRW_delete_event(void);
148void menuConnect_activate(void);
149void menuDisconnect_activate(void);
150void menuQuit_activate(void);
151void menuRW_activate(void);
152void menuAbout_activate(void);
153void chkAcc_toggled(void);
154void chkIR_toggled(void);
155void chkExt_toggled(void);
156void chkLED_toggled(void);
157void chkRumble_toggled(void);
158void drawIR_expose_event(void);
159void drawStick_expose_event(GtkWidget *, GdkEventExpose *, struct stick *);
160void btnRead_clicked(void);
161void btnWrite_clicked(void);
162void btnRWClose_clicked(void);
163void btnBeep_clicked(void);
164
165void set_report_mode(void);
166
167/* Wiimote Callback */
168cwiid_mesg_callback_t cwiid_callback;
169
170/* Wiimote Handler Functions */
171void cwiid_btn(struct cwiid_btn_mesg *);
172void cwiid_acc(struct cwiid_acc_mesg *);
173void cwiid_ir(struct cwiid_ir_mesg *);
174void cwiid_nunchuk(struct cwiid_nunchuk_mesg *);
175void cwiid_classic(struct cwiid_classic_mesg *);
176
177/* GetOpt */
178#define OPTSTRING       "h"
179extern char *optarg;
180extern int optind, opterr, optopt;
181
182#define USAGE "usage:%s [-h] [BDADDR]\n"
183
184/*
185cwiid_err_t err;
186
187void err(int id, const char *s, ...)
188{
189        message(GTK_MESSAGE_ERROR, s, GTK_WINDOW(winMain));
190}
191*/
192
193int main (int argc, char *argv[])
194{
195        int c;
196        char *str_addr;
197
198        gtk_set_locale ();
199        gtk_init (&argc, &argv);
200
201        if (!g_thread_supported()) {
202                g_thread_init(NULL);
203        }
204        gdk_threads_init();
205        gdk_threads_enter();
206
207        /* cwiid_set_err(err); */
208
209        /* Parse Options */
210        while ((c = getopt(argc, argv, OPTSTRING)) != -1) {
211                switch (c) {
212                case 'h':
213                        printf(USAGE, argv[0]);
214                        return 0;
215                        break;
216                case '?':
217                        return -1;
218                        break;
219                default:
220                        printf("unknown command-line option: -%c\n", c);
221                        break;
222                }
223        }
224
225        /* BDADDR */
226        if (optind < argc) {
227                if (str2ba(argv[optind], &bdaddr)) {
228                        printf("invalid bdaddr\n");
229                        bdaddr = *BDADDR_ANY;
230                }
231                optind++;
232                if (optind < argc) {
233                        printf("invalid command-line\n");
234                        printf(USAGE, argv[0]);
235                        return -1;
236                }
237        }
238        else if ((str_addr = getenv(WIIMOTE_BDADDR)) != NULL) {
239                if (str2ba(str_addr, &bdaddr)) {
240                        printf("invalid address in %s\n", WIIMOTE_BDADDR);
241                        bdaddr = *BDADDR_ANY;
242                }
243        }
244        else {
245                bdaddr = *BDADDR_ANY;
246        }               
247
248        /* Create the window */
249        winMain = create_winMain();
250        winRW = create_winRW();
251
252        /* Lookup Widgets */
253        menuConnect = lookup_widget(winMain, "menuConnect");
254        menuDisconnect = lookup_widget(winMain, "menuDisconnect");
255        menuQuit = lookup_widget(winMain, "menuQuit");
256        menuRW = lookup_widget(winMain, "menuRW");
257        menuAbout = lookup_widget(winMain, "menuAbout");
258        chkAcc = lookup_widget(winMain, "chkAcc");
259        chkIR = lookup_widget(winMain, "chkIR");
260        chkExt = lookup_widget(winMain, "chkExt");
261        chkLED1 = lookup_widget(winMain, "chkLED1");
262        chkLED2 = lookup_widget(winMain, "chkLED2");
263        chkLED3 = lookup_widget(winMain, "chkLED3");
264        chkLED4 = lookup_widget(winMain, "chkLED4");
265        chkRumble = lookup_widget(winMain, "chkRumble");
266        evUp = lookup_widget(winMain, "evUp");
267        evDown = lookup_widget(winMain, "evDown");
268        evLeft = lookup_widget(winMain, "evLeft");
269        evRight = lookup_widget(winMain, "evRight");
270        evA = lookup_widget(winMain, "evA");
271        evB = lookup_widget(winMain, "evB");
272        evMinus = lookup_widget(winMain, "evMinus");
273        evPlus = lookup_widget(winMain, "evPlus");
274        evHome = lookup_widget(winMain, "evHome");
275        ev1 = lookup_widget(winMain, "ev1");
276        ev2 = lookup_widget(winMain, "ev2");
277        lblUp = lookup_widget(winMain, "lblUp");
278        lblDown = lookup_widget(winMain, "lblDown");
279        lblLeft = lookup_widget(winMain, "lblLeft");
280        lblRight = lookup_widget(winMain, "lblRight");
281        lblA = lookup_widget(winMain, "lblA");
282        lblB = lookup_widget(winMain, "lblB");
283        lblMinus = lookup_widget(winMain, "lblMinus");
284        lblPlus = lookup_widget(winMain, "lblPlus");
285        lblHome = lookup_widget(winMain, "lblHome");
286        lbl1 = lookup_widget(winMain, "lbl1");
287        lbl2 = lookup_widget(winMain, "lbl2");
288        lblAccX = lookup_widget(winMain, "lblAccX");
289        lblAccY = lookup_widget(winMain, "lblAccY");
290        lblAccZ = lookup_widget(winMain, "lblAccZ");
291        lblAccXVal = lookup_widget(winMain, "lblAccXVal");
292        lblAccYVal = lookup_widget(winMain, "lblAccYVal");
293        lblAccZVal = lookup_widget(winMain, "lblAccZVal");
294        progAccX = lookup_widget(winMain, "progAccX");
295        progAccY = lookup_widget(winMain, "progAccY");
296        progAccZ = lookup_widget(winMain, "progAccZ");
297        lblAcc = lookup_widget(winMain, "lblAcc");
298        lblRoll = lookup_widget(winMain, "lblRoll");
299        lblPitch = lookup_widget(winMain, "lblPitch");
300        lblAccVal = lookup_widget(winMain, "lblAccVal");
301        lblRollVal = lookup_widget(winMain, "lblRollVal");
302        lblPitchVal = lookup_widget(winMain, "lblPitchVal");
303        lblIR = lookup_widget(winMain, "lblIR");
304        drawIR = lookup_widget(winMain, "drawIR");
305        lblNC = lookup_widget(winMain, "lblNC");
306        drawNCStick = lookup_widget(winMain, "drawNCStick");
307        evNCC = lookup_widget(winMain, "evNCC");
308        evNCZ = lookup_widget(winMain, "evNCZ");
309        lblNCC = lookup_widget(winMain, "lblNCC");
310        lblNCZ = lookup_widget(winMain, "lblNCZ");
311        lblNCAccX = lookup_widget(winMain, "lblNCAccX");
312        lblNCAccY = lookup_widget(winMain, "lblNCAccY");
313        lblNCAccZ = lookup_widget(winMain, "lblNCAccZ");
314        lblNCAccXVal = lookup_widget(winMain, "lblNCAccXVal");
315        lblNCAccYVal = lookup_widget(winMain, "lblNCAccYVal");
316        lblNCAccZVal = lookup_widget(winMain, "lblNCAccZVal");
317        progNCAccX = lookup_widget(winMain, "progNCAccX");
318        progNCAccY = lookup_widget(winMain, "progNCAccY");
319        progNCAccZ = lookup_widget(winMain, "progNCAccZ");
320        lblNCAcc = lookup_widget(winMain, "lblNCAcc");
321        lblNCRoll = lookup_widget(winMain, "lblNCRoll");
322        lblNCPitch = lookup_widget(winMain, "lblNCPitch");
323        lblNCAccVal = lookup_widget(winMain, "lblNCAccVal");
324        lblNCRollVal = lookup_widget(winMain, "lblNCRollVal");
325        lblNCPitchVal = lookup_widget(winMain, "lblNCPitchVal");
326        evCCUp = lookup_widget(winMain, "evCCUp");
327        evCCDown = lookup_widget(winMain, "evCCDown");
328        evCCLeft = lookup_widget(winMain, "evCCLeft");
329        evCCRight = lookup_widget(winMain, "evCCRight");
330        evCCMinus = lookup_widget(winMain, "evCCMinus");
331        evCCPlus = lookup_widget(winMain, "evCCPlus");
332        evCCHome = lookup_widget(winMain, "evCCHome");
333        evCCA = lookup_widget(winMain, "evCCA");
334        evCCB = lookup_widget(winMain, "evCCB");
335        evCCX = lookup_widget(winMain, "evCCX");
336        evCCY = lookup_widget(winMain, "evCCY");
337        evCCZL = lookup_widget(winMain, "evCCZL");
338        evCCZR = lookup_widget(winMain, "evCCZR");
339        lblCCUp = lookup_widget(winMain, "lblCCUp");
340        lblCCDown = lookup_widget(winMain, "lblCCDown");
341        lblCCLeft = lookup_widget(winMain, "lblCCLeft");
342        lblCCRight = lookup_widget(winMain, "lblCCRight");
343        lblCCMinus = lookup_widget(winMain, "lblCCMinus");
344        lblCCPlus = lookup_widget(winMain, "lblCCPlus");
345        lblCCHome = lookup_widget(winMain, "lblCCHome");
346        lblCCA = lookup_widget(winMain, "lblCCA");
347        lblCCB = lookup_widget(winMain, "lblCCB");
348        lblCCX = lookup_widget(winMain, "lblCCX");
349        lblCCY = lookup_widget(winMain, "lblCCY");
350        lblCCZL = lookup_widget(winMain, "lblCCZL");
351        lblCCZR = lookup_widget(winMain, "lblCCZR");
352        drawCCLStick = lookup_widget(winMain, "drawCCLStick");
353        drawCCRStick = lookup_widget(winMain, "drawCCRStick");
354        evCCL = lookup_widget(winMain, "evCCL");
355        evCCR = lookup_widget(winMain, "evCCR");
356        lblCCL = lookup_widget(winMain, "lblCCL");
357        lblCCR = lookup_widget(winMain, "lblCCR");
358        lblCCLVal = lookup_widget(winMain, "lblCCLVal");
359        lblCCRVal = lookup_widget(winMain, "lblCCRVal");
360        progCCL = lookup_widget(winMain, "progCCL");
361        progCCR = lookup_widget(winMain, "progCCR");
362        statConnection = lookup_widget(winMain, "statConnection");
363        statBattery = lookup_widget(winMain, "statBattery");
364        statExtension = lookup_widget(winMain, "statExtension");
365        txtReadOffset = lookup_widget(winRW, "txtReadOffset");
366        txtReadLen = lookup_widget(winRW, "txtReadLen");
367        radReadEEPROM = lookup_widget(winRW, "radReadEEPROM");
368        radReadReg = lookup_widget(winRW, "radReadReg");
369        btnRead = lookup_widget(winRW, "btnRead");
370        txtWriteOffset = lookup_widget(winRW, "txtWriteOffset");
371        txtWriteData = lookup_widget(winRW, "txtWriteData");
372        radWriteEEPROM = lookup_widget(winRW, "radWriteEEPROM");
373        radWriteReg = lookup_widget(winRW, "radWriteReg");
374        btnWrite = lookup_widget(winRW, "btnWrite");
375        tvRW = lookup_widget(winRW, "tvRW");
376        btnRWClose = lookup_widget(winRW, "btnRWClose");
377        btnBeep = lookup_widget(winMain, "btnBeep");
378       
379        tbRW = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tvRW));
380
381        /* Connect Callbacks */
382        g_signal_connect(winMain, "delete_event", G_CALLBACK(winMain_delete_event),
383                         NULL);
384        g_signal_connect(winRW, "delete_event", G_CALLBACK(winRW_delete_event),
385                         NULL);
386        g_signal_connect(menuConnect, "activate", G_CALLBACK(menuConnect_activate),
387                         NULL);
388        g_signal_connect(menuDisconnect, "activate",
389                         G_CALLBACK(menuDisconnect_activate), NULL);
390        g_signal_connect(menuQuit, "activate", G_CALLBACK(menuQuit_activate),
391                         NULL);
392        g_signal_connect(menuRW, "activate", G_CALLBACK(menuRW_activate), NULL);
393        g_signal_connect(menuAbout, "activate", G_CALLBACK(menuAbout_activate),
394                         NULL);
395        g_signal_connect(chkAcc, "toggled", G_CALLBACK(chkAcc_toggled), NULL);
396        g_signal_connect(chkIR, "toggled", G_CALLBACK(chkIR_toggled), NULL);
397        g_signal_connect(chkExt, "toggled", G_CALLBACK(chkExt_toggled), NULL);
398        g_signal_connect(chkLED1, "toggled", G_CALLBACK(chkLED_toggled), NULL);
399        g_signal_connect(chkLED2, "toggled", G_CALLBACK(chkLED_toggled), NULL);
400        g_signal_connect(chkLED3, "toggled", G_CALLBACK(chkLED_toggled), NULL);
401        g_signal_connect(chkLED4, "toggled", G_CALLBACK(chkLED_toggled), NULL);
402        g_signal_connect(chkRumble, "toggled", G_CALLBACK(chkRumble_toggled),
403                         NULL);
404        g_signal_connect(drawIR, "expose_event",
405                         G_CALLBACK(drawIR_expose_event), NULL);
406        g_signal_connect(drawNCStick, "expose_event",
407                         G_CALLBACK(drawStick_expose_event), &nc_stick);
408        g_signal_connect(drawCCLStick, "expose_event",
409                         G_CALLBACK(drawStick_expose_event), &cc_l_stick);
410        g_signal_connect(drawCCRStick, "expose_event",
411                         G_CALLBACK(drawStick_expose_event), &cc_r_stick);
412        g_signal_connect(btnRead, "clicked", G_CALLBACK(btnRead_clicked), NULL);
413        g_signal_connect(btnWrite, "clicked", G_CALLBACK(btnWrite_clicked), NULL);
414        g_signal_connect(btnRWClose, "clicked", G_CALLBACK(btnRWClose_clicked),
415                         NULL);
416        g_signal_connect(btnBeep, "clicked", G_CALLBACK(btnBeep_clicked), NULL);
417
418        /* Initialize */
419        btn_on.red = 0; btn_on.blue = 0; btn_on.green = 0xFFFF;
420        btn_off = gtk_widget_get_style(evUp)->bg[GTK_STATE_NORMAL];
421
422        nc_stick.max = 0xFF;
423        cc_l_stick.max = CWIID_CLASSIC_L_STICK_MAX;
424        cc_r_stick.max = CWIID_CLASSIC_R_STICK_MAX;
425
426        set_gui_state();
427        clear_widgets();
428        status("No connection");
429
430        gtk_widget_show(winMain);
431
432        gtk_main();
433        gdk_threads_leave();
434        return 0;
435}
436
437void message(GtkMessageType type, const gchar *message, GtkWindow *parent)
438{
439        GtkWidget *dialog;
440
441        dialog = gtk_message_dialog_new(parent, 0, type, GTK_BUTTONS_OK, message);
442        gtk_dialog_run(GTK_DIALOG(dialog));
443        gtk_widget_destroy(dialog);
444}
445
446void status(const gchar *status)
447{
448        gtk_statusbar_push(GTK_STATUSBAR(statConnection), 0, status);
449}
450
451void set_gui_state()
452{
453        gboolean connected;
454        gboolean acc_active;
455        gboolean ext_active;
456
457        connected = wiimote ? TRUE : FALSE;
458        /* Set Input Widget Sensitivities */
459        gtk_widget_set_sensitive(menuConnect, !connected);
460        gtk_widget_set_sensitive(menuDisconnect, connected);
461        gtk_widget_set_sensitive(chkLED1, connected);
462        gtk_widget_set_sensitive(chkLED2, connected);
463        gtk_widget_set_sensitive(chkLED3, connected);
464        gtk_widget_set_sensitive(chkLED4, connected);
465        gtk_widget_set_sensitive(chkRumble, connected);
466        gtk_widget_set_sensitive(btnRead, connected);
467        gtk_widget_set_sensitive(btnWrite, connected);
468
469        /* Set Button Sensitivities */
470        gtk_widget_set_sensitive(lblUp, connected);
471        gtk_widget_set_sensitive(lblDown, connected);
472        gtk_widget_set_sensitive(lblLeft, connected);
473        gtk_widget_set_sensitive(lblRight, connected);
474        gtk_widget_set_sensitive(lblA, connected);
475        gtk_widget_set_sensitive(lblB, connected);
476        gtk_widget_set_sensitive(lblMinus, connected);
477        gtk_widget_set_sensitive(lblPlus, connected);
478        gtk_widget_set_sensitive(lblHome, connected);
479        gtk_widget_set_sensitive(lbl1, connected);
480        gtk_widget_set_sensitive(lbl2, connected);
481
482        acc_active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkAcc));
483        /* Set Acc Widget Sensitivities */
484        gtk_widget_set_sensitive(lblAccX, acc_active);
485        gtk_widget_set_sensitive(lblAccY, acc_active);
486        gtk_widget_set_sensitive(lblAccZ, acc_active);
487        gtk_widget_set_sensitive(lblAccXVal, acc_active);
488        gtk_widget_set_sensitive(lblAccYVal, acc_active);
489        gtk_widget_set_sensitive(lblAccZVal, acc_active);
490        gtk_widget_set_sensitive(progAccX, acc_active);
491        gtk_widget_set_sensitive(progAccY, acc_active);
492        gtk_widget_set_sensitive(progAccZ, acc_active);
493        gtk_widget_set_sensitive(lblAcc, acc_active);
494        gtk_widget_set_sensitive(lblRoll, acc_active);
495        gtk_widget_set_sensitive(lblPitch, acc_active);
496        gtk_widget_set_sensitive(lblAccVal, acc_active);
497        gtk_widget_set_sensitive(lblRollVal, acc_active);
498        gtk_widget_set_sensitive(lblPitchVal, acc_active);
499
500        /* Set IC Widget Sensitivities */
501        gtk_widget_set_sensitive(lblIR,
502      gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkIR)));
503
504        ext_active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkExt));
505        /* Set Extension Widget Sensitivities */
506        gtk_widget_set_sensitive(lblNCC, ext_active);
507        gtk_widget_set_sensitive(lblNCZ, ext_active);
508        gtk_widget_set_sensitive(lblNCAccX, ext_active);
509        gtk_widget_set_sensitive(lblNCAccY, ext_active);
510        gtk_widget_set_sensitive(lblNCAccZ, ext_active);
511        gtk_widget_set_sensitive(lblNCAccXVal, ext_active);
512        gtk_widget_set_sensitive(lblNCAccYVal, ext_active);
513        gtk_widget_set_sensitive(lblNCAccZVal, ext_active);
514        gtk_widget_set_sensitive(progNCAccX, ext_active);
515        gtk_widget_set_sensitive(progNCAccY, ext_active);
516        gtk_widget_set_sensitive(progNCAccZ, ext_active);
517        gtk_widget_set_sensitive(lblNCAcc, ext_active);
518        gtk_widget_set_sensitive(lblNCRoll, ext_active);
519        gtk_widget_set_sensitive(lblNCPitch, ext_active);
520        gtk_widget_set_sensitive(lblNCAccVal, ext_active);
521        gtk_widget_set_sensitive(lblNCRollVal, ext_active);
522        gtk_widget_set_sensitive(lblNCPitchVal, ext_active);
523        gtk_widget_set_sensitive(lblCCUp, ext_active);
524        gtk_widget_set_sensitive(lblCCDown, ext_active);
525        gtk_widget_set_sensitive(lblCCLeft, ext_active);
526        gtk_widget_set_sensitive(lblCCRight, ext_active);
527        gtk_widget_set_sensitive(lblCCMinus, ext_active);
528        gtk_widget_set_sensitive(lblCCPlus, ext_active);
529        gtk_widget_set_sensitive(lblCCHome, ext_active);
530        gtk_widget_set_sensitive(lblCCA, ext_active);
531        gtk_widget_set_sensitive(lblCCB, ext_active);
532        gtk_widget_set_sensitive(lblCCX, ext_active);
533        gtk_widget_set_sensitive(lblCCY, ext_active);
534        gtk_widget_set_sensitive(lblCCZL, ext_active);
535        gtk_widget_set_sensitive(lblCCZR, ext_active);
536        gtk_widget_set_sensitive(lblCCL, ext_active);
537        gtk_widget_set_sensitive(lblCCR, ext_active);
538        gtk_widget_set_sensitive(lblCCLVal, ext_active);
539        gtk_widget_set_sensitive(lblCCRVal, ext_active);
540        gtk_widget_set_sensitive(progCCL, ext_active);
541        gtk_widget_set_sensitive(progCCR, ext_active);
542}
543
544void clear_widgets()
545{
546        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(chkLED1), FALSE);
547        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(chkLED2), FALSE);
548        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(chkLED3), FALSE);
549        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(chkLED4), FALSE);
550        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(chkRumble), FALSE);
551
552        gtk_statusbar_push(GTK_STATUSBAR(statBattery), 0, "");
553        gtk_statusbar_push(GTK_STATUSBAR(statExtension), 0, "");
554
555        clear_acc_widgets();
556        clear_ir_data();
557        clear_nunchuk_widgets();
558        clear_classic_widgets();
559}
560
561void clear_acc_widgets()
562{
563        gtk_label_set_text(GTK_LABEL(lblAccXVal), "0");
564        gtk_label_set_text(GTK_LABEL(lblAccYVal), "0");
565        gtk_label_set_text(GTK_LABEL(lblAccZVal), "0");
566        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progAccX), 0.0);
567        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progAccY), 0.0);
568        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progAccZ), 0.0);
569        gtk_label_set_text(GTK_LABEL(lblAccVal), "0");
570        gtk_label_set_text(GTK_LABEL(lblRollVal), "0");
571        gtk_label_set_text(GTK_LABEL(lblPitchVal), "0");
572}
573
574void clear_ir_data()
575{
576        int i;
577
578        for (i=0; i < CWIID_IR_SRC_COUNT; i++) {
579                ir_data.src[i].x = -1;
580                ir_data.src[i].y = -1;
581                ir_data.src[i].size = -1;
582        }
583        gtk_widget_queue_draw(drawIR);
584}
585
586void clear_nunchuk_widgets()
587{
588        nc_stick.valid = 0;
589        gtk_widget_queue_draw(drawNCStick);
590
591        gtk_label_set_text(GTK_LABEL(lblNCAccXVal), "0");
592        gtk_label_set_text(GTK_LABEL(lblNCAccYVal), "0");
593        gtk_label_set_text(GTK_LABEL(lblNCAccZVal), "0");
594        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progNCAccX), 0.0);
595        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progNCAccY), 0.0);
596        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progNCAccZ), 0.0);
597        gtk_label_set_text(GTK_LABEL(lblNCAccVal), "0");
598        gtk_label_set_text(GTK_LABEL(lblNCRollVal), "0");
599        gtk_label_set_text(GTK_LABEL(lblNCPitchVal), "0");
600}
601
602void clear_classic_widgets()
603{
604        cc_l_stick.valid = 0;
605        gtk_widget_queue_draw(drawCCLStick);
606        cc_r_stick.valid = 0;
607        gtk_widget_queue_draw(drawCCRStick);
608
609        gtk_label_set_text(GTK_LABEL(lblCCLVal), "0");
610        gtk_label_set_text(GTK_LABEL(lblCCRVal), "0");
611        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progCCL), 0.0);
612        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progCCR), 0.0);
613}
614
615gboolean winMain_delete_event(void)
616{
617        menuQuit_activate();
618        return FALSE;
619}
620
621gboolean winRW_delete_event(void)
622{
623        btnRWClose_clicked();
624        return TRUE;
625}
626
627void menuConnect_activate(void)
628{
629        char reset_bdaddr = 0;
630        unsigned char buf[7];
631
632        if (bacmp(&bdaddr, BDADDR_ANY) == 0) {
633                reset_bdaddr = 1;
634        }
635        message(GTK_MESSAGE_INFO,
636                "Put Wiimote in discoverable mode (press 1+2) and press OK",
637                 GTK_WINDOW(winMain));
638        if ((wiimote = cwiid_connect(&bdaddr, &cwiid_callback, NULL)) == NULL) {
639                message(GTK_MESSAGE_ERROR, "Unable to connect", GTK_WINDOW(winMain));
640                status("No connection");
641        }
642        else {
643                status("Connected");
644                if (cwiid_read(wiimote, CWIID_RW_EEPROM, 0x16, 7, buf)) {
645                        message(GTK_MESSAGE_ERROR, "Unable to retrieve accelerometer "
646                                "calibration", GTK_WINDOW(winMain));
647                }
648                else {
649                        acc_zero.x = buf[0];
650                        acc_zero.y = buf[1];
651                        acc_zero.z = buf[2];
652                        acc_one.= buf[4];
653                        acc_one.= buf[5];
654                        acc_one.= buf[6];
655                }
656                set_gui_state();
657                set_report_mode();
658                cwiid_command(wiimote, CWIID_CMD_STATUS, 0);
659        }
660
661        if (reset_bdaddr) {
662                bdaddr = *BDADDR_ANY;
663        }
664}
665
666void menuDisconnect_activate(void)
667{
668        if (cwiid_disconnect(wiimote)) {
669                message(GTK_MESSAGE_ERROR, "Error on disconnect", GTK_WINDOW(winMain));
670        }
671        wiimote = NULL;
672        status("No connection");
673        clear_widgets();
674        set_gui_state();
675}
676
677void menuQuit_activate(void)
678{
679        if (wiimote) {
680                menuDisconnect_activate();
681        }
682        gtk_main_quit();
683}
684
685void menuRW_activate(void)
686{
687        gtk_widget_show(winRW);
688}
689
690void menuAbout_activate(void)
691{
692        gtk_show_about_dialog(GTK_WINDOW(winMain),
693                              "name", APP_NAME,
694                              "version", CWIID_VERSION,
695                              "copyright", APP_COPYRIGHT,
696                              "comments", APP_COMMENTS,
697                              NULL);
698}
699
700void chkAcc_toggled(void)
701{
702        if (wiimote) {
703                set_report_mode();
704        }
705        if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkAcc))) {
706                clear_acc_widgets();
707        }
708        set_gui_state();
709}
710
711void chkIR_toggled(void)
712{
713        if (wiimote) {
714                set_report_mode();
715        }
716        if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkIR))) {
717                clear_ir_data();
718        }
719        set_gui_state();
720}
721
722void chkExt_toggled(void)
723{
724        if (wiimote) {
725                set_report_mode();
726        }
727        if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkExt))) {
728                clear_nunchuk_widgets();
729                clear_classic_widgets();
730        }
731        set_gui_state();
732}
733
734void chkLED_toggled(void)
735{
736        uint8_t LED_state;
737
738        if (wiimote) {
739                LED_state =
740                  (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkLED1))
741                    ? CWIID_LED1_ON : 0) |
742                  (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkLED2))
743                    ? CWIID_LED2_ON : 0) |
744                  (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkLED3))
745                    ? CWIID_LED3_ON : 0) |
746                  (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkLED4))
747                    ? CWIID_LED4_ON : 0);
748                if (cwiid_command(wiimote, CWIID_CMD_LED, LED_state)) {
749                        message(GTK_MESSAGE_ERROR, "error setting LEDs",
750                                GTK_WINDOW(winMain));
751                }
752        }
753}
754
755void chkRumble_toggled(void)
756{
757        if (wiimote) {
758                if (cwiid_command(wiimote, CWIID_CMD_RUMBLE,
759                  gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkRumble)))) {
760                        message(GTK_MESSAGE_ERROR, "error setting rumble",
761                                GTK_WINDOW(winMain));
762                }
763        }
764}
765
766void drawIR_expose_event(void)
767{
768        int i;
769        int size;
770        gint width, height;
771
772        gdk_window_get_geometry(drawIR->window, NULL, NULL, &width, &height, NULL);
773
774        for (i=0; i < CWIID_IR_SRC_COUNT; i++) {
775                if (ir_data.src[i].valid) {
776                        if (ir_data.src[i].size == -1) {
777                                size = 3;
778                        }
779                        else {
780                                size = ir_data.src[i].size+1;
781                        }
782                        gdk_draw_arc(drawIR->window,
783                                     drawIR->style->fg_gc[GTK_WIDGET_STATE(drawIR)],
784                                     TRUE,
785                                                 ir_data.src[i].x*width/CWIID_IR_X_MAX,
786                                                 height - ir_data.src[i].y*height/CWIID_IR_Y_MAX,
787                                                 size, size,
788                                                 0, 64 * 360);
789                }
790        }
791}
792
793void drawStick_expose_event(GtkWidget *drawStick, GdkEventExpose *event,
794                            struct stick *stick)
795{
796        gint width, height;
797
798        gdk_window_get_geometry(drawStick->window, NULL, NULL, &width, &height,
799                                NULL);
800        gdk_draw_arc(drawStick->window,
801                     drawStick->style->fg_gc[GTK_WIDGET_STATE(drawStick)],
802                                 FALSE,
803                                 0, 0, width-1, height-1, 0, 64*360);
804        if (stick->valid) {
805                gdk_draw_arc(drawStick->window,
806                             drawStick->style->fg_gc[GTK_WIDGET_STATE(drawStick)],
807                             TRUE,
808                             (double)stick->x/stick->max*width - 2,
809                             (1 - (double)stick->y/stick->max)*height - 2,
810                             3, 3, 0, 64*360);
811        }
812}
813
814void btnRead_clicked(void)
815{
816        static unsigned char buf[CWIID_MAX_READ_LEN];
817        static char txt[CWIID_MAX_READ_LEN*4+50]; /* 3 chars per byte, with
818                                                     * plenty extra */
819        GtkTextIter text_iter;
820        GtkTextMark *p_text_mark;
821        char *cursor;
822        unsigned int offset, len;
823        int flags;
824        unsigned int i;
825
826        /* Decode arguments */
827        offset = strtol(gtk_entry_get_text(GTK_ENTRY(txtReadOffset)), &cursor, 16);
828        if (*cursor != '\0') {
829                message(GTK_MESSAGE_ERROR, "Invalid read offset", GTK_WINDOW(winRW));
830        }
831
832        len = strtol(gtk_entry_get_text(GTK_ENTRY(txtReadLen)), &cursor, 16);
833        if (*cursor != '\0') {
834                message(GTK_MESSAGE_ERROR, "Invalid read len", GTK_WINDOW(winRW));
835        }
836        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radReadReg))) {
837                flags = CWIID_RW_REG;
838        }
839        else {
840                flags = CWIID_RW_EEPROM;
841        }
842
843        /* Make the call */
844        if (cwiid_read(wiimote, flags, offset, len, buf)) {
845                message(GTK_MESSAGE_ERROR, "Wiimote read error", GTK_WINDOW(winRW));
846        }
847        else {
848                /* construct the hexedit-style string */
849                cursor=txt;
850                sprintf(cursor, "0x%08X:", offset & ~0xF);
851                cursor+=11;
852                for (i=0; i < (offset & 0xF); i++) {
853                        sprintf(cursor, "   ");
854                        cursor+=3;
855                }
856                for (i=0; i < len; i++) {
857                        if ((((i + offset) & 0xF) == 0) && (i!=0)) {
858                                sprintf(cursor, "\n0x%08X:", offset+i);
859                                cursor+=12;
860                        }
861                        if (((i +offset) & 0x7) == 0) {
862                                sprintf(cursor, " ");
863                                cursor++;
864                        }
865                        sprintf(cursor, "%02X ", buf[i]);
866                        cursor+=3;
867                }
868                sprintf(cursor, "\n\n");
869
870                gtk_text_buffer_get_end_iter(tbRW, &text_iter);
871                p_text_mark = gtk_text_buffer_create_mark(tbRW, NULL, &text_iter,
872                                                          TRUE);
873                gtk_text_buffer_insert(tbRW, &text_iter, txt, -1);
874                gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(tvRW), p_text_mark, 0.01,
875                                             TRUE, 0.0, 0.0);
876        }
877}
878
879char chartox(char c)
880{
881        char str[2];
882        char *endptr;
883        int val;
884
885        str[0] = c;
886        str[1] = '\0';
887        val = strtol(str, &endptr, 16);
888        if (*endptr != '\0') {
889                return -1;
890        }
891
892        return (char)val;
893}
894
895#define MAX_WRITE_LEN   0x20
896void btnWrite_clicked(void)
897{
898        static unsigned char buf[MAX_WRITE_LEN];
899        char *cursor, *data;
900        uint32_t offset;
901        uint16_t len;
902        uint8_t flags;
903
904        /* Decode arguments */
905        offset = strtol(gtk_entry_get_text(GTK_ENTRY(txtWriteOffset)), &cursor, 16);
906        if (*cursor != '\0') {
907                message(GTK_MESSAGE_ERROR, "Invalid read offset", GTK_WINDOW(winRW));
908        }
909
910        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radWriteReg))) {
911                flags = CWIID_RW_REG;
912        }
913        else {
914                flags = CWIID_RW_EEPROM;
915        }
916
917        data = (char *) gtk_entry_get_text(GTK_ENTRY(txtWriteData));
918        cursor = data;
919        len = 0;
920        while (*cursor != '\0') {
921                if (len > MAX_WRITE_LEN) {
922                        message(GTK_MESSAGE_ERROR, "Message too long", GTK_WINDOW(winRW));
923                        return;
924                }
925                /* Trim Leading spaces */
926                while (*cursor == ' ') {
927                        cursor++;
928                }
929                /* Test for end */
930                if (*cursor == '\0') {
931                        break;
932                }
933                /* Read first nibble */
934                if (!isxdigit((int)*cursor)) {
935                        message(GTK_MESSAGE_ERROR, "Invalid write data",
936                                GTK_WINDOW(winRW));
937                        return;
938                }
939                buf[len] = chartox(*cursor)<<4;
940
941                /* Read second nibble */
942                cursor++;
943                if (!isxdigit((int)*cursor)) {
944                        message(GTK_MESSAGE_ERROR,
945                                "Invalid write data (digits must come in pairs)",
946                                GTK_WINDOW(winRW));
947                        return;
948                }
949                buf[len] = buf[len] | chartox(*cursor);
950
951                cursor++;
952                len++;
953        }
954
955        if (len == 0) {
956                message(GTK_MESSAGE_ERROR, "No write data", GTK_WINDOW(winRW));
957                return;
958        }
959
960        /* Make the call */
961        if (cwiid_write(wiimote, flags, offset, len, buf)) {
962                message(GTK_MESSAGE_ERROR, "Wiimote write error", GTK_WINDOW(winRW));
963        }
964        else {
965                message(GTK_MESSAGE_INFO, "Wiimote write successful",
966                        GTK_WINDOW(winRW));
967        }
968}
969
970void btnRWClose_clicked(void)
971{
972        gtk_widget_hide(winRW);
973}
974
975void btnBeep_clicked(void)
976{
977        /*if (cwiid_beep(wiimote)) {
978                message(GTK_MESSAGE_ERROR, "Wiimote sound error", GTK_WINDOW(winMain));
979        }*/
980}
981
982void set_report_mode(void)
983{
984        uint8_t rpt_mode;
985       
986        rpt_mode = CWIID_RPT_STATUS | CWIID_RPT_BTN;
987
988        if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkIR))) {
989                rpt_mode |= CWIID_RPT_IR;
990        }
991        if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkAcc))) {
992                rpt_mode |= CWIID_RPT_ACC;
993        }
994        if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkExt))) {
995                rpt_mode |= CWIID_RPT_EXT;
996        }
997        if (cwiid_command(wiimote, CWIID_CMD_RPT_MODE, rpt_mode)) {
998                message(GTK_MESSAGE_ERROR, "error setting report mode",
999                        GTK_WINDOW(winMain));
1000        }
1001}
1002
1003#define BATTERY_STR_LEN 14      /* "Battery: 100%" + '\0' */
1004void cwiid_callback(int id, int mesg_count, union cwiid_mesg *mesg_array[])
1005{
1006        int i;
1007        char battery[BATTERY_STR_LEN];
1008        char *ext_str;
1009        unsigned char buf[7];
1010        static enum cwiid_ext_type ext_type = CWIID_EXT_NONE;
1011
1012        gdk_threads_enter();
1013        for (i=0; i < mesg_count; i++) {
1014                switch (mesg_array[i]->type) {
1015                case CWIID_MESG_STATUS:
1016                        snprintf(battery, BATTERY_STR_LEN,"Battery:%d%%",
1017                                 (int) (100.0 * mesg_array[i]->status_mesg.battery /
1018                                        CWIID_BATTERY_MAX));
1019                        gtk_statusbar_push(GTK_STATUSBAR(statBattery), 0, battery);
1020                        switch (mesg_array[i]->status_mesg.extension) {
1021                        case CWIID_EXT_NONE:
1022                                ext_str = "No extension";
1023                                break;
1024                        case CWIID_EXT_NUNCHUK:
1025                                ext_str = "Nunchuk";
1026                                if (ext_type != CWIID_EXT_NUNCHUK) {
1027                                        if (cwiid_read(wiimote,
1028                                                         CWIID_RW_REG | CWIID_RW_DECODE,
1029                                                     0xA40020, 7, buf)) {
1030                                                message(GTK_MESSAGE_ERROR, "Unable to retrieve "
1031                                                        "nunchuk calibration", GTK_WINDOW(winMain));
1032                                        }
1033                                        else {
1034                                                nc_acc_zero.x = buf[0];
1035                                                nc_acc_zero.y = buf[1];
1036                                                nc_acc_zero.z = buf[2];
1037                                                nc_acc_one.= buf[4];
1038                                                nc_acc_one.= buf[5];
1039                                                nc_acc_one.= buf[6];
1040                                        }
1041                                }
1042                                break;
1043                        case CWIID_EXT_CLASSIC:
1044                                ext_str = "Classic controller";
1045                                break;
1046                        case CWIID_EXT_UNKNOWN:
1047                                ext_str = "Unknown extension";
1048                                break;
1049                        }
1050                        gtk_statusbar_push(GTK_STATUSBAR(statExtension), 0, ext_str);
1051                        clear_nunchuk_widgets();
1052                        clear_classic_widgets();
1053                        ext_type = mesg_array[i]->status_mesg.extension;
1054                        break;
1055                case CWIID_MESG_BTN:
1056                        cwiid_btn(&mesg_array[i]->btn_mesg);
1057                        break;
1058                case CWIID_MESG_ACC:
1059                        cwiid_acc(&mesg_array[i]->acc_mesg);
1060                        break;
1061                case CWIID_MESG_IR:
1062                        cwiid_ir(&mesg_array[i]->ir_mesg);
1063                        break;
1064                case CWIID_MESG_NUNCHUK:
1065                        cwiid_nunchuk(&mesg_array[i]->nunchuk_mesg);
1066                        break;
1067                case CWIID_MESG_CLASSIC:
1068                        cwiid_classic(&mesg_array[i]->classic_mesg);
1069                        break;
1070                case CWIID_MESG_ERROR:
1071                        menuDisconnect_activate();
1072                        break;
1073                default:
1074                        break;
1075                }
1076        }
1077        gdk_flush();
1078        gdk_threads_leave();
1079}
1080
1081void cwiid_btn(struct cwiid_btn_mesg *mesg)
1082{
1083        gtk_widget_modify_bg(evUp, GTK_STATE_NORMAL,
1084            (mesg->buttons & CWIID_BTN_UP) ? &btn_on : &btn_off);
1085        gtk_widget_modify_bg(evDown, GTK_STATE_NORMAL,
1086            (mesg->buttons & CWIID_BTN_DOWN) ? &btn_on : &btn_off);
1087        gtk_widget_modify_bg(evLeft, GTK_STATE_NORMAL,
1088            (mesg->buttons & CWIID_BTN_LEFT) ? &btn_on : &btn_off);
1089        gtk_widget_modify_bg(evRight, GTK_STATE_NORMAL,
1090            (mesg->buttons & CWIID_BTN_RIGHT) ? &btn_on : &btn_off);
1091        gtk_widget_modify_bg(evA, GTK_STATE_NORMAL,
1092            (mesg->buttons & CWIID_BTN_A) ? &btn_on : &btn_off);
1093        gtk_widget_modify_bg(evB, GTK_STATE_NORMAL,
1094            (mesg->buttons & CWIID_BTN_B) ? &btn_on : &btn_off);
1095        gtk_widget_modify_bg(evMinus, GTK_STATE_NORMAL,
1096            (mesg->buttons & CWIID_BTN_MINUS) ? &btn_on : &btn_off);
1097        gtk_widget_modify_bg(evPlus, GTK_STATE_NORMAL,
1098            (mesg->buttons & CWIID_BTN_PLUS) ? &btn_on : &btn_off);
1099        gtk_widget_modify_bg(evHome, GTK_STATE_NORMAL,
1100            (mesg->buttons & CWIID_BTN_HOME) ? &btn_on : &btn_off);
1101        gtk_widget_modify_bg(ev1, GTK_STATE_NORMAL,
1102            (mesg->buttons & CWIID_BTN_1) ? &btn_on : &btn_off);
1103        gtk_widget_modify_bg(ev2, GTK_STATE_NORMAL,
1104            (mesg->buttons & CWIID_BTN_2) ? &btn_on : &btn_off);
1105}
1106
1107#define LBLVAL_LEN 6
1108void cwiid_acc(struct cwiid_acc_mesg *mesg)
1109{
1110        static gchar str[LBLVAL_LEN];
1111        double a_x, a_y, a_z, a;
1112        double roll, pitch;
1113       
1114        if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkAcc))) {
1115                g_snprintf(str, LBLVAL_LEN, "%X", mesg->x);
1116                gtk_label_set_text(GTK_LABEL(lblAccXVal), str);
1117                gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progAccX),
1118                                              (double)mesg->x/0xFF);
1119                g_snprintf(str, LBLVAL_LEN, "%X", mesg->y);
1120                gtk_label_set_text(GTK_LABEL(lblAccYVal), str);
1121                gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progAccY),
1122                                              (double)mesg->y/0xFF);
1123                g_snprintf(str, LBLVAL_LEN, "%X", mesg->z);
1124                gtk_label_set_text(GTK_LABEL(lblAccZVal), str);
1125                gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progAccZ),
1126                                              (double)mesg->z/0xFF);
1127
1128                a_x = ((double)mesg->x - acc_zero.x) /
1129                      (acc_one.x - acc_zero.x);
1130                a_y = ((double)mesg->y - acc_zero.y) /
1131                      (acc_one.y - acc_zero.y);
1132                a_z = ((double)mesg->z - acc_zero.z) /
1133                      (acc_one.z - acc_zero.z);
1134                a = sqrt(pow(a_x,2)+pow(a_y,2)+pow(a_z,2));
1135
1136                roll = atan(a_x/a_z);
1137                if (a_z <= 0.0) {
1138                        roll += PI * ((a_x > 0.0) ? 1 : -1);
1139                }
1140                roll *= -1;
1141
1142                pitch = atan(a_y/a_z*cos(roll));
1143
1144                g_snprintf(str, LBLVAL_LEN, "%.2f", a);
1145                gtk_label_set_text(GTK_LABEL(lblAccVal), str);
1146                g_snprintf(str, LBLVAL_LEN, "%.2f", roll);
1147                gtk_label_set_text(GTK_LABEL(lblRollVal), str);
1148                g_snprintf(str, LBLVAL_LEN, "%.2f", pitch);
1149                gtk_label_set_text(GTK_LABEL(lblPitchVal), str);
1150        }
1151}
1152
1153void cwiid_ir(struct cwiid_ir_mesg *mesg)
1154{
1155        if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkIR))) {
1156                /* memcpy(&ir_data, mesg, sizeof(struct cwiid_ir_mesg)); */
1157                ir_data = *mesg;
1158                gtk_widget_queue_draw(drawIR);
1159        }
1160}
1161
1162void cwiid_nunchuk(struct cwiid_nunchuk_mesg *mesg)
1163{
1164        static gchar str[LBLVAL_LEN];
1165        double a_x, a_y, a_z, a;
1166        double roll, pitch;
1167       
1168        if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkExt))) {
1169                gtk_widget_modify_bg(evNCC, GTK_STATE_NORMAL,
1170                    (mesg->buttons & CWIID_NUNCHUK_BTN_C) ? &btn_on : &btn_off);
1171                gtk_widget_modify_bg(evNCZ, GTK_STATE_NORMAL,
1172                    (mesg->buttons & CWIID_NUNCHUK_BTN_Z) ? &btn_on : &btn_off);
1173
1174                nc_stick.valid = 1;
1175                nc_stick.x = mesg->stick_x;
1176                nc_stick.y = mesg->stick_y;
1177                gtk_widget_queue_draw(drawNCStick);
1178
1179                g_snprintf(str, LBLVAL_LEN, "%X", mesg->acc_x);
1180                gtk_label_set_text(GTK_LABEL(lblNCAccXVal), str);
1181                gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progNCAccX),
1182                                              (double)mesg->acc_x/0xFF);
1183                g_snprintf(str, LBLVAL_LEN, "%X", mesg->acc_y);
1184                gtk_label_set_text(GTK_LABEL(lblNCAccYVal), str);
1185                gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progNCAccY),
1186                                              (double)mesg->acc_y/0xFF);
1187                g_snprintf(str, LBLVAL_LEN, "%X", mesg->acc_z);
1188                gtk_label_set_text(GTK_LABEL(lblNCAccZVal), str);
1189                gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progNCAccZ),
1190                                              (double)mesg->acc_z/0xFF);
1191
1192                /* TODO: get nunchuk calibration */
1193                a_x = ((double)mesg->acc_x - nc_acc_zero.x) /
1194                      (nc_acc_one.x - nc_acc_zero.x);
1195                a_y = ((double)mesg->acc_y - nc_acc_zero.y) /
1196                      (nc_acc_one.y - nc_acc_zero.y);
1197                a_z = ((double)mesg->acc_z - nc_acc_zero.z) /
1198                      (nc_acc_one.z - nc_acc_zero.z);
1199                a = sqrt(pow(a_x,2)+pow(a_y,2)+pow(a_z,2));
1200                roll = atan(a_x/a_z);
1201                if (a_z <= 0.0) {
1202                        roll += PI * ((a_x > 0.0) ? 1 : -1);
1203                }
1204                roll *= -1;
1205
1206                pitch = atan(a_y/a_z*cos(roll));
1207
1208                g_snprintf(str, LBLVAL_LEN, "%.2f", a);
1209                gtk_label_set_text(GTK_LABEL(lblNCAccVal), str);
1210                g_snprintf(str, LBLVAL_LEN, "%.2f", roll);
1211                gtk_label_set_text(GTK_LABEL(lblNCRollVal), str);
1212                g_snprintf(str, LBLVAL_LEN, "%.2f", pitch);
1213                gtk_label_set_text(GTK_LABEL(lblNCPitchVal), str);
1214        }
1215}
1216
1217void cwiid_classic(struct cwiid_classic_mesg *mesg)
1218{
1219        static gchar str[LBLVAL_LEN];
1220
1221        if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(chkExt))) {
1222                gtk_widget_modify_bg(evCCUp, GTK_STATE_NORMAL,
1223                    (mesg->buttons & CWIID_CLASSIC_BTN_UP) ? &btn_on : &btn_off);
1224                gtk_widget_modify_bg(evCCDown, GTK_STATE_NORMAL,
1225                    (mesg->buttons & CWIID_CLASSIC_BTN_DOWN) ? &btn_on : &btn_off);
1226                gtk_widget_modify_bg(evCCLeft, GTK_STATE_NORMAL,
1227                    (mesg->buttons & CWIID_CLASSIC_BTN_LEFT) ? &btn_on : &btn_off);
1228                gtk_widget_modify_bg(evCCRight, GTK_STATE_NORMAL,
1229                    (mesg->buttons & CWIID_CLASSIC_BTN_RIGHT) ? &btn_on : &btn_off);
1230                gtk_widget_modify_bg(evCCMinus, GTK_STATE_NORMAL,
1231                    (mesg->buttons & CWIID_CLASSIC_BTN_MINUS) ? &btn_on : &btn_off);
1232                gtk_widget_modify_bg(evCCPlus, GTK_STATE_NORMAL,
1233                    (mesg->buttons & CWIID_CLASSIC_BTN_PLUS) ? &btn_on : &btn_off);
1234                gtk_widget_modify_bg(evCCHome, GTK_STATE_NORMAL,
1235                    (mesg->buttons & CWIID_CLASSIC_BTN_HOME) ? &btn_on : &btn_off);
1236                gtk_widget_modify_bg(evCCA, GTK_STATE_NORMAL,
1237                    (mesg->buttons & CWIID_CLASSIC_BTN_A) ? &btn_on : &btn_off);
1238                gtk_widget_modify_bg(evCCB, GTK_STATE_NORMAL,
1239                    (mesg->buttons & CWIID_CLASSIC_BTN_B) ? &btn_on : &btn_off);
1240                gtk_widget_modify_bg(evCCX, GTK_STATE_NORMAL,
1241                    (mesg->buttons & CWIID_CLASSIC_BTN_X) ? &btn_on : &btn_off);
1242                gtk_widget_modify_bg(evCCY, GTK_STATE_NORMAL,
1243                    (mesg->buttons & CWIID_CLASSIC_BTN_Y) ? &btn_on : &btn_off);
1244                gtk_widget_modify_bg(evCCZL, GTK_STATE_NORMAL,
1245                    (mesg->buttons & CWIID_CLASSIC_BTN_ZL) ? &btn_on : &btn_off);
1246                gtk_widget_modify_bg(evCCZR, GTK_STATE_NORMAL,
1247                    (mesg->buttons & CWIID_CLASSIC_BTN_ZR) ? &btn_on : &btn_off);
1248
1249                cc_l_stick.valid = 1;
1250                cc_l_stick.x = mesg->l_stick_x;
1251                cc_l_stick.y = mesg->l_stick_y;
1252                gtk_widget_queue_draw(drawCCLStick);
1253
1254                cc_r_stick.valid = 1;
1255                cc_r_stick.x = mesg->r_stick_x;
1256                cc_r_stick.y = mesg->r_stick_y;
1257                gtk_widget_queue_draw(drawCCRStick);
1258               
1259                g_snprintf(str, LBLVAL_LEN, "%X", mesg->l);
1260                gtk_label_set_text(GTK_LABEL(lblCCLVal), str);
1261                gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progCCL),
1262                                              (double)mesg->l/CWIID_CLASSIC_LR_MAX);
1263                gtk_widget_modify_bg(evCCL, GTK_STATE_NORMAL,
1264                    (mesg->buttons & CWIID_CLASSIC_BTN_L) ? &btn_on : &btn_off);
1265                g_snprintf(str, LBLVAL_LEN, "%X", mesg->r);
1266                gtk_label_set_text(GTK_LABEL(lblCCRVal), str);
1267                gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progCCR),
1268                                              (double)mesg->r/CWIID_CLASSIC_LR_MAX);
1269                gtk_widget_modify_bg(evCCR, GTK_STATE_NORMAL,
1270                    (mesg->buttons & CWIID_CLASSIC_BTN_R) ? &btn_on : &btn_off);
1271        }
1272}
1273
Note: See TracBrowser for help on using the browser.