source: trunk/platform/ixus60_sd600/kbd.c @ 711

Revision 711, 7.8 KB checked in by msl, 2 years ago (diff)

Neuer Tastatur-Befehl

  • Betrifft alle

+ neuer Befehl zur Tastatursteuerung: "shoot_full_only", nutzbar mit click, press und release
+ Mit diesem Befehl sind deutlich verbesserte Intervallaufnahmen mit kurzen Zeitabstaenden moeglich.
+ siehe http://chdk.setepontos.com/index.php?topic=1444.msg70223#msg70223
+ Danke fudgey

  • Betrifft A1100

+ Fehlerhafte Palettenangabe in rev705 in platform_camera.h korrigiert.

  • Veralteten Ordner "script" aus Repository entfernt.
  • Property svn:eol-style set to native
Line 
1#include "lolevel.h"
2#include "platform.h"
3#include "core.h"
4#include "keyboard.h"
5#include "stdlib.h"
6
7#define KEY_MASK 0x17FF
8
9#define NEW_SS (0x2000)
10#define SD_READONLY_FLAG (0x20000)
11
12typedef struct {
13    long hackkey;
14    long canonkey;
15} KeyMap;
16
17long kbd_new_state[3];
18long kbd_prev_state[3];
19long kbd_mod_state = KEY_MASK;
20long debug_kbd_state_diff;
21
22static KeyMap keymap[];
23static long last_kbd_key = 0;
24static int usb_power=0;
25static int remote_key=0;
26static int remote_count=0;
27
28#ifndef MALLOCD_STACK
29static char kbd_stack[NEW_SS];
30#endif
31
32long __attribute__((naked)) wrap_kbd_p1_f() ;
33
34static void __attribute__((noinline)) hook_kbd_task_proceed()
35{
36    while (physw_run){
37        _SleepTask(5);
38
39        if (wrap_kbd_p1_f() == 1) // Readout key state via camera function
40        {
41            _kbd_p2_f();
42        }
43
44    }
45}
46
47void __attribute__((naked,noinline)) mykbd_task()
48{
49    /* WARNING
50     * Stack pointer manipulation performed here!
51     * This means (but not limited to):
52     *  function arguments destroyed;
53     *  function CAN NOT return properly;
54     *  MUST NOT call or use stack variables before stack
55     *  is setup properly;
56     *
57     */
58
59    register int i;
60    register long *newstack;
61
62#ifndef MALLOCD_STACK
63    newstack = (void*)kbd_stack;
64#else
65    newstack = malloc(NEW_SS);
66#endif
67
68    for (i=0;i<NEW_SS/4;i++)
69        newstack[i]=0xdededede;
70
71    asm volatile (
72        "MOV    SP, %0"
73        :: "r"(((char*)newstack)+NEW_SS)
74        : "memory"
75    );
76
77    hook_kbd_task_proceed();
78
79    /* function can be modified to restore SP here...
80     */
81
82    _ExitTask();
83}
84
85
86long __attribute__((naked,noinline)) wrap_kbd_p1_f()
87{
88
89    asm volatile(
90                "STMFD   SP!, {R4-R7,LR}\n"
91                "SUB     SP, SP, #0xC\n"
92                "BL      _kbd_read_keys\n"
93                "BL      hook_kbd_handle_keys\n"
94                "B       _kbd_p1_f_cont\n"        // Continue original function execution
95    );
96    return 0; // shut up the compiler
97}
98
99#if CAM_FEATURE_FEATHER
100//extern int touch_keys_angle;
101#endif
102
103#define IN(base, value) ((value < base + 20) && (value > base - 20))
104
105/**
106 * Handles and forwards key settings to key processing routines
107 */
108void hook_kbd_handle_keys()
109{
110    kbd_prev_state[0] = kbd_new_state[0];
111    kbd_prev_state[1] = kbd_new_state[1];
112    kbd_prev_state[2] = kbd_new_state[2];
113
114    kbd_new_state[0] = physw_status[0];
115    kbd_new_state[1] = physw_status[1];
116    kbd_new_state[2] = physw_status[2];
117
118    static int taskFeatherID = 0;
119
120    if (taskFeatherID == 0) {
121        taskFeatherID = taskNameToId("tFeather");
122        printf("taskFeatherID:%x\n", taskFeatherID);
123    }
124
125
126
127/*
128    int key_emu = 0;
129    int canonkey = 0;
130    int i;
131
132    if (IN(250, touch_keys_angle)) {
133        key_emu = KEY_RIGHT;
134    }
135    if (IN(450, touch_keys_angle)) {
136        key_emu = KEY_DOWN;
137    }
138    if (IN(675, touch_keys_angle)) {
139        key_emu = KEY_LEFT;
140    }
141    if (IN(870, touch_keys_angle)) {
142        key_emu = KEY_UP;
143    }
144   
145    if (key_emu != 0) {
146        for (i=0; keymap[i].hackkey; i++){
147            if (keymap[i].hackkey == key_emu) {
148                canonkey = keymap[i].canonkey;
149                break;;
150            }
151        }
152    }
153
154    if (canonkey != 0) {
155        kbd_new_state[2] = kbd_new_state[2] & ~canonkey;
156    }
157*/
158   
159    if (kbd_process() == 0){
160        // leave it ...
161#if CAM_FEATURE_FEATHER
162        taskResume(taskFeatherID);
163#endif
164    } else {
165        // Drop platform keys to none, and simulate ordered key presses
166        physw_status[2] = (physw_status[2] & (~KEY_MASK)) | (kbd_mod_state & KEY_MASK);
167#if CAM_FEATURE_FEATHER
168        taskSuspend(taskFeatherID);
169
170        // We still need this sema when simulating key presses
171        if (kbd_mod_state != KEY_MASK) {
172            taskResume(taskFeatherID);
173        }
174
175#endif
176    }
177
178    // Drop SD readonly status
179    physw_status[2] = physw_status[2] & ~SD_READONLY_FLAG;
180
181}
182
183/****************/
184
185
186void kbd_key_press(long key)
187{
188    int i;
189    for (i=0;keymap[i].hackkey;i++){
190        if (keymap[i].hackkey == key){
191            kbd_mod_state &= ~keymap[i].canonkey;
192            return;
193        }
194    }
195}
196
197void kbd_key_release(long key)
198{
199    int i;
200    for (i=0;keymap[i].hackkey;i++){
201        if (keymap[i].hackkey == key){
202            kbd_mod_state |= keymap[i].canonkey;
203            return;
204        }
205    }
206}
207
208void kbd_key_release_all()
209{
210    kbd_mod_state |= KEY_MASK;
211}
212
213long kbd_is_key_pressed(long key)
214{
215    int i;
216    for (i=0;keymap[i].hackkey;i++){
217        if (keymap[i].hackkey == key){
218            return ((kbd_new_state[2] & keymap[i].canonkey) == 0) ? 1:0;
219        }
220    }
221    return 0;
222}
223
224long kbd_is_key_clicked(long key)
225{
226    int i;
227   
228    for (i=0;keymap[i].hackkey;i++){
229        if (keymap[i].hackkey == key){
230            return ((kbd_prev_state[2] & keymap[i].canonkey) != 0) &&
231                    ((kbd_new_state[2] & keymap[i].canonkey) == 0);
232        }
233    }
234    return 0;
235}
236
237long kbd_get_pressed_key()
238{
239    int i;
240    for (i=0;keymap[i].hackkey;i++){
241        if ((kbd_new_state[2] & keymap[i].canonkey) == 0){
242            return keymap[i].hackkey;
243        }
244    }
245    return 0;
246}
247
248long kbd_get_clicked_key()
249{
250    int i;
251    for (i=0;keymap[i].hackkey;i++){
252        if (((kbd_prev_state[2] & keymap[i].canonkey) != 0) &&
253            ((kbd_new_state[2] & keymap[i].canonkey) == 0)){
254            return keymap[i].hackkey;
255        }
256    }
257    return 0;
258}
259
260void kbd_reset_autoclicked_key() {
261    last_kbd_key = 0;
262}
263
264long kbd_get_autoclicked_key() {
265    static long last_kbd_time = 0, press_count = 0;
266    register long key, t;
267
268    key=kbd_get_clicked_key();
269    if (key) {
270        last_kbd_key = key;
271        press_count = 0;
272        last_kbd_time = get_tick_count();
273        return key;
274    } else {
275        if (last_kbd_key && kbd_is_key_pressed(last_kbd_key)) {
276            t = get_tick_count();
277            if (t-last_kbd_time > ( press_count ? KBD_REPEAT_DELAY : KBD_INITIAL_DELAY) ) {
278                ++press_count;
279                last_kbd_time = t;
280                return last_kbd_key;
281            } else {
282                return 0;
283            }
284        } else {
285            last_kbd_key = 0;
286            return 0;
287        }
288    }
289}
290
291long kbd_use_zoom_as_mf() {
292    static long v;
293    static long zoom_key_pressed = 0;
294
295    if (kbd_is_key_pressed(KEY_ZOOM_IN) && (mode_get()&MODE_MASK) == MODE_REC) {
296        get_property_case(12, &v, 4);
297        if (v) {
298            kbd_key_release_all();
299            kbd_key_press(KEY_RIGHT);
300            zoom_key_pressed = KEY_ZOOM_IN;
301            return 1;
302        }
303    } else {
304        if (zoom_key_pressed==KEY_ZOOM_IN) {
305            kbd_key_release(KEY_RIGHT);
306            zoom_key_pressed = 0;
307            return 1;
308        }
309    }
310    if (kbd_is_key_pressed(KEY_ZOOM_OUT) && (mode_get()&MODE_MASK) == MODE_REC) {
311        get_property_case(12, &v, 4);
312        if (v) {
313            kbd_key_release_all();
314            kbd_key_press(KEY_LEFT);
315            zoom_key_pressed = KEY_ZOOM_OUT;
316            return 1;
317        }
318    } else {
319        if (zoom_key_pressed==KEY_ZOOM_OUT) {
320            kbd_key_release(KEY_LEFT);
321            zoom_key_pressed = 0;
322            return 1;
323        }
324    }
325    return 0;
326}
327
328int get_usb_power(int edge)
329{
330        int x;
331
332        if (edge) return remote_key;
333        x = usb_power;
334        usb_power = 0;
335        return x;
336}
337
338static KeyMap keymap[] = {
339    /* tiny bug: key order matters. see kbd_get_pressed_key()
340     * for example
341     */
342        { KEY_UP        , 0x00000001 },
343        { KEY_DOWN      , 0x00000002 },
344        { KEY_LEFT      , 0x00000008 },
345        { KEY_RIGHT     , 0x00000004 },
346        { KEY_SET       , 0x00000100 },
347        { KEY_SHOOT_FULL, 0x00000030 }, // note 3 here!
348        { KEY_SHOOT_FULL_ONLY, 0x00000020 },
349        { KEY_SHOOT_HALF, 0x00000010 },
350        { KEY_ZOOM_IN   , 0x00000040 },
351        { KEY_ZOOM_OUT  , 0x00000080 },
352        { KEY_MENU      , 0x00000200 },
353        { KEY_DISPLAY   , 0x00000400 },
354        { KEY_PRINT     , 0x00001000 },
355//      { KEY_ERASE     , 0x00000800 },
356        { KEY_DUMMY     , 0x00001000 },
357        { 0, 0 }
358};
Note: See TracBrowser for help on using the repository browser.