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