1 // Copyright 2013 Eric Messick (FixedImagePhoto.com/Contact)
2 // reworked 2019 for cinelerra-gg by William Morrow
9 #include "bcwindowbase.inc"
11 #include "shuttle.inc"
14 #include <linux/input.h>
15 #include <sys/types.h>
17 #ifdef HAVE_SHUTTLE_USB
18 #include <libusb-1.0/libusb.h>
21 // Copyright 2013 Eric Messick (FixedImagePhoto.com/Contact)
22 // reworked 2019 for cinelerra-gg by William Morrow (aka goodguy)
24 // delay in ms before processing each XTest event
25 // CurrentTime means no delay
26 #define DELAY CurrentTime
28 #define SHUTTLE_INTERFACE 0
30 // protocol for events from the shuttlepro HUD device
33 #define EVENT_TYPE_DONE 0
34 #define EVENT_TYPE_KEY 1
35 #define EVENT_TYPE_JOGSHUTTLE 2
36 #define EVENT_TYPE_ACTIVE_KEY 4
38 // ev.code when ev.type == KEY
39 #define EVENT_CODE_KEY1 256
42 enum { K1=0,K2,K3,K4,K5,K6,K7,K8,K9,K10,K11,K12,K13,K14,K15, };
43 enum { S_7=-7,S_6,S_5,S_4,S_3,S_2,S_1,S0,S1,S2,S3,S4,S5,S6,S7, };
46 // ev.value when ev.type == KEY
47 // 1 -> PRESS; 0 -> RELEASE
49 // ev.code when ev.type == JOGSHUTTLE
50 #define EVENT_CODE_JOG 7
51 #define EVENT_CODE_SHUTTLE 8
52 #define EVENT_CODE_HI_JOG 11
54 // ev.value when ev.code == JOG
55 // 8 bit value changing by one for each jog step
57 // ev.value when ev.code == SHUTTLE
58 // -7 .. 7 encoding shuttle position
60 // we define these as extra KeySyms to represent mouse events
61 #define XK_Button_0 0x2000000 // just an offset, not a real button
62 #define XK_Button_1 0x2000001
63 #define XK_Button_2 0x2000002
64 #define XK_Button_3 0x2000003
65 #define XK_Scroll_Up 0x2000004
66 #define XK_Scroll_Down 0x2000005
70 #define PRESS_RELEASE 3
74 #define NUM_SHUTTLES 15
77 #define KJS_KEY_DOWN 1
82 // cinelerra window input targets
83 #define FOCUS_DEFAULT 0
84 #define FOCUS_MWINDOW 1
85 #define FOCUS_AWINDOW 2
86 #define FOCUS_CWINDOW 3
87 #define FOCUS_VIEWER 4
93 struct { uint32_t key, msk; };
97 SKeySym(int k) { key = k; msk = 0; }
98 SKeySym(unsigned k, unsigned m) { key = k; msk = m; }
99 bool operator ==(SKeySym &ks) { return ks.v == v; }
100 operator int() { return key; }
103 class KeySymMapping {
105 static int get_mask(const char *&str);
106 static SKeySym to_keysym(const char *str);
107 static const char *to_string(SKeySym ks);
108 static KeySymMapping key_sym_mapping[];
114 class Stroke : public ListItem<Stroke>
118 int press; // 1:press, 0:release
121 class Strokes : public List<Stroke>
126 void clear() { while( last ) delete last; }
127 void add_stroke(SKeySym keysym, int press=1) {
128 Stroke *s = append();
129 s->keysym = keysym; s->press = press;
133 class Modifiers : public ArrayList<Stroke>
137 Modifiers(Translation *trans) { this->trans = trans; }
140 void mark_as_down(SKeySym sym, int hold);
141 void mark_as_up(SKeySym sym);
142 void release(int allkeys);
152 TransName(int cin, const char *nm, const char *re);
156 class TransNames : public ArrayList<TransName *>
160 ~TransNames() { remove_all_objects(); }
163 class Translation : public ListItem<Translation>
166 Translation(Shuttle *shuttle);
167 Translation(Shuttle *shuttle, const char *name);
171 void append_stroke(SKeySym sym, int press);
172 void add_release(int all_keys);
173 void add_keystroke(const char *keySymName, int press_release);
174 void add_keysym(SKeySym sym, int press_release);
175 void add_string(char *&str);
176 int start_line(const char *key);
177 void print_strokes(const char *name, const char *up_dn, Strokes *strokes);
178 void print_stroke(Stroke *s);
180 void print_line(const char *key);
185 int is_default, is_key;
186 int first_release_stroke;
187 Strokes *pressed, *released;
188 Strokes *pressed_strokes, *released_strokes;
191 Strokes key_down[NUM_KEYS];
192 Strokes key_up[NUM_KEYS];
193 Strokes shuttles[NUM_SHUTTLES];
194 Strokes jog[NUM_JOGS];
198 class Translations : public List<Translation>
203 void clear() { while( last ) delete last; }
206 class Shuttle : public Thread
209 unsigned short jogvalue, shuttlevalue;
211 #ifdef HAVE_SHUTTLE_USB
212 struct libusb_device_handle *devsh;
213 void usb_probe(int idx);
215 unsigned last_jog, last_shuttle, last_btns;
219 Translation *default_translation;
220 Translations translations;
222 Shuttle(MWindow *mwindow);
225 int send_button(unsigned int button, int press);
226 int send_keycode(unsigned key, unsigned msk, int press, int send);
227 int send_keysym(SKeySym keysym, int press);
228 void send_stroke_sequence(int kjs, int index);
229 void key(unsigned short code, unsigned int value);
230 void shuttle(int value);
231 void jog(unsigned int value);
232 void jogshuttle(unsigned short code, unsigned int value);
236 int load_translation();
237 int get_focused_window_translation();
240 int read_config_file();
241 static BC_WindowBase *owns(BC_WindowBase *wdw, Window win);
250 Translation *tr, *last_translation;
257 const char *config_path;