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