no longer need ffmpeg patch0 which was for Termux
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / shuttle.h
1 // Copyright 2013 Eric Messick (FixedImagePhoto.com/Contact)
2 // reworked 2019 for cinelerra-gg by William Morrow
3
4 #ifndef __SHUTTLE_H__
5 #define __SHUTTLE_H__
6 #ifdef HAVE_SHUTTLE
7
8 #include "arraylist.h"
9 #include "bcwindowbase.inc"
10 #include "linklist.h"
11 #include "shuttle.inc"
12 #include "thread.h"
13
14 #include <linux/input.h>
15 #include <sys/types.h>
16
17 #ifdef HAVE_SHUTTLE_USB
18 #include <libusb-1.0/libusb.h>
19 #endif
20
21 // Copyright 2013 Eric Messick (FixedImagePhoto.com/Contact)
22 // reworked 2019 for cinelerra-gg by William Morrow (aka goodguy)
23
24 // delay in ms before processing each XTest event
25 // CurrentTime means no delay
26 #define DELAY CurrentTime
27
28 #define SHUTTLE_INTERFACE 0
29
30 // protocol for events from the shuttlepro HUD device
31 //
32 // ev.type values:
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
37
38 // ev.code when ev.type == KEY
39 #define EVENT_CODE_KEY1 256
40 // KEY2 257, etc...
41
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, };
44 enum { JL=0,JR };
45
46 // ev.value when ev.type == KEY
47 // 1 -> PRESS; 0 -> RELEASE
48
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
53
54 // ev.value when ev.code == JOG
55 // 8 bit value changing by one for each jog step
56
57 // ev.value when ev.code == SHUTTLE
58 // -7 .. 7 encoding shuttle position
59
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
67
68 #define PRESS 1
69 #define RELEASE 2
70 #define PRESS_RELEASE 3
71 #define HOLD 4
72
73 #define NUM_KEYS 15
74 #define NUM_SHUTTLES 15
75 #define NUM_JOGS 2
76
77 #define KJS_KEY_DOWN 1
78 #define KJS_KEY_UP 2
79 #define KJS_SHUTTLE 3
80 #define KJS_JOG 4
81
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
88 #define FOCUS_LOAD    5
89
90 class SKeySym {
91 public:
92         union {
93                 struct { uint32_t key, msk; };
94                 uint64_t v;
95         };
96         SKeySym() { v = 0; }
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; }
101 };
102
103 class KeySymMapping {
104 public:
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[];
109
110         const char *str;
111         SKeySym sym;
112 };
113
114 class Stroke : public ListItem<Stroke>
115 {
116 public:
117         SKeySym keysym;
118         int press; // 1:press, 0:release
119 };
120
121 class Strokes : public List<Stroke>
122 {
123 public:
124         Strokes() {}
125         ~Strokes() {}
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;
130         }
131 };
132
133 class Modifiers : public ArrayList<Stroke>
134 {
135         Translation *trans;
136 public:
137         Modifiers(Translation *trans) { this->trans = trans; }
138         ~Modifiers() {}
139
140         void mark_as_down(SKeySym sym, int hold);
141         void mark_as_up(SKeySym sym);
142         void release(int allkeys);
143         void re_press();
144 };
145
146 class TransName
147 {
148 public:
149         int cin;
150         const char *name;
151
152         TransName(int cin, const char *nm, const char *re);
153         ~TransName();
154 };
155
156 class TransNames : public ArrayList<TransName *>
157 {
158 public:
159         TransNames() {}
160         ~TransNames() { remove_all_objects(); }
161 };
162
163 class Translation : public ListItem<Translation>
164 {
165 public:
166         Translation(Shuttle *shuttle);
167         Translation(Shuttle *shuttle, const char *name);
168         ~Translation();
169         void init(int def);
170         void clear();
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);
179         void finish_line();
180         void print_line(const char *key);
181
182         Shuttle *shuttle;
183         TransNames names;
184         const char *name;
185         int is_default, is_key;
186         int first_release_stroke;
187         Strokes *pressed, *released;
188         Strokes *pressed_strokes, *released_strokes;
189         SKeySym keysym_down;
190
191         Strokes key_down[NUM_KEYS];
192         Strokes key_up[NUM_KEYS];
193         Strokes shuttles[NUM_SHUTTLES];
194         Strokes jog[NUM_JOGS];
195         Modifiers modifiers;
196 };
197
198 class Translations : public List<Translation>
199 {
200 public:
201         Translations() {}
202         ~Translations() {}
203         void clear() { while( last ) delete last; }
204 };
205
206 class Shuttle : public Thread
207 {
208         int fd;
209         unsigned short jogvalue, shuttlevalue;
210         int dev_index;
211 #ifdef HAVE_SHUTTLE_USB
212         struct libusb_device_handle *devsh;
213         void usb_probe(int idx);
214         void usb_done();
215         unsigned last_jog, last_shuttle, last_btns;
216         int claimed;
217 #endif
218
219         Translation *default_translation;
220         Translations translations;
221 public:
222         Shuttle(MWindow *mwindow);
223         ~Shuttle();
224
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);
233         void start(int idx);
234         void stop();
235         void handle_event();
236         int load_translation();
237         int get_focused_window_translation();
238         static int probe();
239         void run();
240         int read_config_file();
241         static BC_WindowBase *owns(BC_WindowBase *wdw, Window win);
242
243         int done;
244         int failed;
245         int first_time;
246         int debug;
247         int usb_direct;
248
249         MWindow *mwindow;
250         Translation *tr, *last_translation;
251         BC_WindowBase *wdw;
252         Window win;
253         unsigned msk;
254         int rx, ry, wx, wy;
255         Window last_focused;
256
257         const char *config_path;
258         time_t config_mtime;
259         input_event ev;
260 };
261
262 #endif
263 #endif