1 /*---------------------------------------------------------------------------*
2 Project: Revolution Low-Level Sync USB keyboard demo
3 File: kbdLowLevelSync.c
4
5 Copyright 2007 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: kbdLowLevelSync.c,v $
14 Revision 1.8 2007/07/13 23:37:18 carlmu
15 Changed from TrySetLeds to KBDSetLedsRetry.
16
17 Revision 1.7 2007/06/21 22:46:50 carlmu
18 Updated for KBD 1.4 API (changed LED handling).
19
20 Revision 1.6 2007/05/05 01:56:57 carlmu
21 Changes for 0.8 API
22
23 Revision 1.5 2007/04/17 23:55:57 carlmu
24 Updated for 0.5 API.
25
26 Revision 1.4 2007/04/10 18:34:05 carlmu
27 Changed for compatibility with 0.4 API.
28
29 Revision 1.3 2007/04/02 19:12:17 carlmu
30 Set callback functions modified for new return value.
31
32 Revision 1.2 2007/03/29 22:38:01 carlmu
33 Added multiple channel support.
34
35 Revision 1.1 2007/03/28 00:18:25 carlmu
36 Initial version.
37
38
39 $NoKeywords: $
40 *---------------------------------------------------------------------------*/
41
42 /*
43 Example simple keyboard application to output the low-level API HID code
44 to the console. Uses the synchronous keyboard API.
45 */
46
47 #include <demo.h>
48 #include <revolution/kbd.h>
49
50 //-----------------------------------------------------------------------------
51
52 #define KBD_CALL(_fn_call) \
53 if ((_fn_call) != KBD_SUCCESS) { \
54 OSReport ("KBD error: calling %s @ %s:%i\n", \
55 #_fn_call, __FILE__, __LINE__); \
56 }
57
58 //-----------------------------------------------------------------------------
59
60 static void
kbdAppAttach(KBDDevEvent * kde)61 kbdAppAttach (KBDDevEvent *kde) {
62 OSReport ("kbd app: keyboard added on channel %d\n", kde->channel);
63 // for demo purposes, enable NumLock on newly attached keyboard
64 KBDSetModState(kde->channel, KBD_MS_NUM_LOCK);
65 KBDSetLedsRetry(kde->channel, KBD_LED_NUM_LOCK);
66 }
67
68
69 static void
kbdAppDetach(KBDDevEvent * kde)70 kbdAppDetach (KBDDevEvent *kde) {
71 OSReport ("kbd app: keyboard removed on channel %d\n", kde->channel);
72 }
73
74
75 static void
kbdAppKeyEvent(KBDKeyEvent * kke)76 kbdAppKeyEvent (KBDKeyEvent *kke) {
77 if (KBD_KEY_MODE_REPEAT(kke->mode)) {
78 return;
79 }
80
81 if (KBD_KEY_MODE_UP(kke->mode))
82 OSReport ("\t\t\thid code: 0x%02x ^ up (chan %d)\n", kke->hid, kke->channel);
83 else
84 OSReport ("hid code: 0x%02x v down (chan %d)\n", kke->hid, kke->channel);
85
86 // check for CapsLock, NumLock, or ScrollLock (handle LEDs)
87 if (kke->hid == KBD_HID_Caps_Lock ||
88 kke->hid == KBD_HID_Keypad_Num_Lock ||
89 kke->unicode == KBK_Scroll_Lock) {
90
91 KBDModState ms;
92 KBDLedState leds;
93
94 // First compute the new LED state
95 KBDGetModState(kke->channel, &ms);
96
97 leds = (KBDLedState)
98 (((ms & KBD_MS_NUM_LOCK) == KBD_MS_NUM_LOCK) * KBD_LED_NUM_LOCK |
99 ((ms & KBD_MS_CAPS_LOCK) == KBD_MS_CAPS_LOCK) * KBD_LED_CAPS_LOCK |
100 ((ms & KBD_MS_SCROLL_LOCK) == KBD_MS_SCROLL_LOCK) * KBD_LED_SCROLL_LOCK);
101
102 KBDSetLedsRetry(kke->channel, leds);
103 }
104 }
105
main(void)106 int main(void) {
107 KBDKeyEvent kevent;
108 KBDChannel ch;
109 KBDEc rc;
110
111 DEMOInit (NULL);
112
113 OSReport ("\n\n");
114 OSReport ("************************************************\n");
115 OSReport ("kbdLowLevelSync Low-level Sync keyboard demo\n");
116 OSReport ("************************************************\n");
117 OSReport ("Attach a USB keyboard and press some keys.\n");
118 OSReport ("Use a GameCube controller plugged into port 1.\n");
119 OSReport ("Right Trigger: sleeps for 5 seconds (to test overflow)\n");
120 OSReport ("\n");
121
122 // One of these MUST be called before calling KBDInit.
123 // It's okay to call more than one.
124 KBDInitRegionUS();
125 KBDInitRegionJP();
126 KBDInitRegionEU();
127
128 // It's important to set the callbacks before calling KBDInit.
129 KBDSetAttachCallback(kbdAppAttach);
130 KBDSetDetachCallback(kbdAppDetach);
131
132 KBD_CALL (KBDInit());
133
134 while (1) {
135
136 DEMOPadRead();
137
138 if ( DEMOPadGetButtonDown(0) & PAD_TRIGGER_R ) {
139 OSSleepSeconds(5);
140 }
141
142 // poll all keyboard channels
143 for(ch=0; ch<KBD_MAX_CHANNELS; ch++) {
144 KBDChanStatus cstat;
145
146 // see if keyboard is connected
147 KBD_CALL(KBDGetChannelStatus (ch, &cstat));
148 if (cstat == KBD_CS_OK) {
149
150 // call KBDGetKey until queue is empty or error
151 do {
152 rc=KBDGetKey(ch, &kevent);
153 if (rc != KBD_SUCCESS) break;
154
155 if (kevent.hid == KBD_HID_OVERFLOW) {
156 OSReport("KBD queue overflowed!\n");
157 continue;
158 }
159 if (kevent.hid == KBD_HID_NONE) {
160 break;
161 }
162 // process event
163 kbdAppKeyEvent(&kevent);
164 } while (1);
165 }
166 }
167
168 OSYieldThread();
169
170 }
171
172 OSShutdownSystem(); // Never reached!
173
174 return 0;
175 }
176
177
178