add x10tv ati remote rework, android remote rework, wintv remote tweaks
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / shuttle.h
1 #ifndef __SHUTTLE_H__
2 #define __SHUTTLE_H__
3
4 #include "arraylist.h"
5 #include "bcwindowbase.inc"
6 #include "linklist.h"
7 #include "shuttle.inc"
8 #include "thread.h"
9
10 #include <linux/input.h>
11 #include <sys/types.h>
12
13 #ifdef HAVE_SHUTTLE_USB
14 #include <libusb-1.0/libusb.h>
15 #endif
16
17 // Copyright 2013 Eric Messick (FixedImagePhoto.com/Contact)
18 // reworked 2019 for cinelerra-gg by William Morrow (aka goodguy)
19
20 // delay in ms before processing each XTest event
21 // CurrentTime means no delay
22 #define DELAY CurrentTime
23 // playback max speed -64x .. 64x
24 #define SHUTTLE_MAX_SPEED 64.
25 #define SHUTTLE_INTERFACE 0
26
27 // protocol for events from the shuttlepro HUD device
28 //
29 // ev.type values:
30 #define EVENT_TYPE_DONE 0
31 #define EVENT_TYPE_KEY 1
32 #define EVENT_TYPE_JOGSHUTTLE 2
33 #define EVENT_TYPE_ACTIVE_KEY 4
34
35 // ev.code when ev.type == KEY
36 #define EVENT_CODE_KEY1 256
37 // KEY2 257, etc...
38
39 enum { K1=0,K2,K3,K4,K5,K6,K7,K8,K9,K10,K11,K12,K13,K14,K15, };
40 enum { S_7=-7,S_6,S_5,S_4,S_3,S_2,S_1,S0,S1,S2,S3,S4,S5,S6,S7, };
41 enum { JL=0,JR };
42
43 // ev.value when ev.type == KEY
44 // 1 -> PRESS; 0 -> RELEASE
45
46 // ev.code when ev.type == JOGSHUTTLE
47 #define EVENT_CODE_JOG 7
48 #define EVENT_CODE_SHUTTLE 8
49 #define EVENT_CODE_HI_JOG 11
50
51 // ev.value when ev.code == JOG
52 // 8 bit value changing by one for each jog step
53
54 // ev.value when ev.code == SHUTTLE
55 // -7 .. 7 encoding shuttle position
56
57 // we define these as extra KeySyms to represent mouse events
58 #define XK_Button_0 0x2000000 // just an offset, not a real button
59 #define XK_Button_1 0x2000001
60 #define XK_Button_2 0x2000002
61 #define XK_Button_3 0x2000003
62 #define XK_Scroll_Up 0x2000004
63 #define XK_Scroll_Down 0x2000005
64
65 #define PRESS 1
66 #define RELEASE 2
67 #define PRESS_RELEASE 3
68 #define HOLD 4
69
70 #define NUM_KEYS 15
71 #define NUM_SHUTTLES 15
72 #define NUM_JOGS 2
73
74 #define KJS_KEY_DOWN 1
75 #define KJS_KEY_UP 2
76 #define KJS_SHUTTLE 3
77 #define KJS_JOG 4
78
79 // cinelerra window input targets
80 #define FOCUS_DEFAULT 0
81 #define FOCUS_MWINDOW 1
82 #define FOCUS_AWINDOW 2
83 #define FOCUS_CWINDOW 3
84 #define FOCUS_VIEWER  4
85 #define FOCUS_LOAD    5
86
87 class SKeySym {
88 public:
89         union {
90                 struct { uint32_t key, msk; };
91                 uint64_t v;
92         };
93         SKeySym() { v = 0; }
94         SKeySym(int k) { key = k;  msk = 0; }
95         SKeySym(unsigned k, unsigned m) { key = k;  msk = m; }
96         bool operator ==(SKeySym &ks) { return ks.v == v; }
97         operator int() { return key; }
98 };
99
100 class KeySymMapping {
101 public:
102         static int get_mask(const char *&str);
103         static SKeySym to_keysym(const char *str);
104         static const char *to_string(SKeySym ks);
105         static KeySymMapping key_sym_mapping[];
106
107         const char *str;
108         SKeySym sym;
109 };
110
111 class Stroke : public ListItem<Stroke>
112 {
113 public:
114         SKeySym keysym;
115         int press; // 1:press, 0:release
116 };
117
118 class Strokes : public List<Stroke>
119 {
120 public:
121         Strokes() {}
122         ~Strokes() {}
123         void clear() { while( last ) delete last; }
124         void add_stroke(SKeySym keysym, int press=1) {
125                 Stroke *s = append();
126                 s->keysym = keysym; s->press = press;
127         }
128 };
129
130 class Modifiers : public ArrayList<Stroke>
131 {
132         Translation *trans;
133 public:
134         Modifiers(Translation *trans) { this->trans = trans; }
135         ~Modifiers() {}
136
137         void mark_as_down(SKeySym sym, int hold);
138         void mark_as_up(SKeySym sym);
139         void release(int allkeys);
140         void re_press();
141 };
142
143 class TransName
144 {
145 public:
146         int cin;
147         const char *name;
148
149         TransName(int cin, const char *nm, const char *re);
150         ~TransName();
151 };
152
153 class TransNames : public ArrayList<TransName *>
154 {
155 public:
156         TransNames() {}
157         ~TransNames() { remove_all_objects(); }
158 };
159
160 class Translation : public ListItem<Translation>
161 {
162 public:
163         Translation(Shuttle *shuttle);
164         Translation(Shuttle *shuttle, const char *name);
165         ~Translation();
166         void init(int def);
167         void clear();
168         void append_stroke(SKeySym sym, int press);
169         void add_release(int all_keys);
170         void add_keystroke(const char *keySymName, int press_release);
171         void add_keysym(SKeySym sym, int press_release);
172         void add_string(char *&str);
173         int start_line(const char *key);
174         void print_strokes(const char *name, const char *up_dn, Strokes *strokes);
175         void print_stroke(Stroke *s);
176         void finish_line();
177         void print_line(const char *key);
178
179         Shuttle *shuttle;
180         TransNames names;
181         const char *name;
182         int is_default, is_key;
183         int first_release_stroke;
184         Strokes *pressed, *released;
185         Strokes *pressed_strokes, *released_strokes;
186         SKeySym keysym_down;
187
188         Strokes key_down[NUM_KEYS];
189         Strokes key_up[NUM_KEYS];
190         Strokes shuttles[NUM_SHUTTLES];
191         Strokes jog[NUM_JOGS];
192         Modifiers modifiers;
193 };
194
195 class Translations : public List<Translation>
196 {
197 public:
198         Translations() {}
199         ~Translations() {}
200         void clear() { while( last ) delete last; }
201 };
202
203 class Shuttle : public Thread
204 {
205         int fd;
206         unsigned short jogvalue, shuttlevalue;
207         int dev_index;
208 #ifdef HAVE_SHUTTLE_USB
209         struct libusb_device_handle *devsh;
210         void usb_probe(int idx);
211         void usb_done();
212         unsigned last_jog, last_shuttle, last_btns;
213         int claimed;
214 #endif
215
216         Translation *default_translation;
217         Translations translations;
218 public:
219         Shuttle(MWindow *mwindow);
220         ~Shuttle();
221
222         int send_button(unsigned int button, int press);
223         int send_keycode(unsigned key, unsigned msk, int press, int send);
224         int send_keysym(SKeySym keysym, int press);
225         void send_stroke_sequence(int kjs, int index);
226         void key(unsigned short code, unsigned int value);
227         void shuttle(int value);
228         void jog(unsigned int value);
229         void jogshuttle(unsigned short code, unsigned int value);
230         void start(int idx);
231         void stop();
232         void handle_event();
233         int load_translation();
234         int get_focused_window_translation();
235         static int probe();
236         void run();
237         int read_config_file();
238         static BC_WindowBase *owns(BC_WindowBase *wdw, Window win);
239
240         int done;
241         int failed;
242         int first_time;
243         int debug;
244         int usb_direct;
245
246         MWindow *mwindow;
247         Translation *tr, *last_translation;
248         BC_WindowBase *wdw;
249         Window win;
250         unsigned msk;
251         int rx, ry, wx, wy;
252         Window last_focused;
253
254         const char *config_path;
255         time_t config_mtime;
256         input_event ev;
257 };
258
259 #endif