Checked in terminatorX pre-3.65 - finally ;) - Alex
[terminatorX.git] / src / tX_mouse.cc
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999, 2000  Alexander K├Ânig
4  
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9  
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14  
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  
19     File: tX_mouse.cc
20  
21     Description: This implements the mouse AND keyboard Input handling in
22                  Grab-Mode.
23 */    
24
25
26 #include "tX_mouse.h"
27 #include "tX_mastergui.h"
28 #include "tX_global.h"
29 #include "tX_engine.h"
30 #include "tX_vtt.h"
31
32 #define TX_MOUSE_SPEED_NORMAL 0.05
33 #define TX_MOUSE_SPEED_WARP 250000
34
35 tx_mouse :: tx_mouse()
36 {
37         mask=PointerMotionMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask;
38         xmot=(XMotionEvent *) &xev;
39         xkey=(XKeyEvent *) &xev;
40         xbut=(XButtonEvent *) &xev;
41         
42 #ifdef USE_DGA2
43         xdgamot=(XDGAMotionEvent *) &xev;
44         xdgakey=(XDGAKeyEvent *) &xev;
45         xdgabut=(XDGAButtonEvent *) &xev;
46 #endif  
47         
48         grabbed=0;
49         warp=TX_MOUSE_SPEED_NORMAL;
50 }
51
52 int tx_mouse :: grab()
53 {       
54 #ifdef USE_DGA2
55         XDGAMode *mode;
56 #endif  
57         int i, num=0;
58         
59
60         if (grabbed) return(0);
61
62         dpy=XOpenDisplay(NULL); // FIXME: use correct display
63         if (!dpy)
64         {
65                 fputs("GrabMode Error: couldn't connect to XDisplay.", stderr);
66                 return(ENG_ERR_XOPEN);
67         }
68
69
70 #ifdef USE_DGA2
71         mode=XDGAQueryModes(dpy,DefaultScreen(dpy), &num);
72         
73         printf("Found %i DGA2-Modes:\n", num);
74         
75         for(i=0; i<num; i++)
76         {
77                 printf("%2i: %s\n", i, mode[i].name);
78         }
79         XFree(mode);
80 #endif  
81
82         if (globals.xinput_enable)
83         {
84                 if (set_xinput())
85                 {
86                         XCloseDisplay(dpy);
87                         fputs("GrabMode Error: failed to setup XInput.", stderr);
88                         return(ENG_ERR_XINPUT);
89                 }
90         }
91                                 
92         XSelectInput(dpy, xwindow, mask);       
93
94         XSetInputFocus(dpy, xwindow, None, CurrentTime);
95
96         if (GrabSuccess != XGrabPointer(dpy, xwindow, False, ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync,GrabModeAsync,None,None,CurrentTime))
97         {
98                 reset_xinput();
99                 XCloseDisplay(dpy);
100                 fputs("GrabMode Error: XGrabPointer failed.", stderr);
101                 return(ENG_ERR_GRABMOUSE);
102         }       
103         
104         if (GrabSuccess != XGrabKeyboard(dpy, xwindow, False, GrabModeAsync,GrabModeAsync,CurrentTime))
105         {
106                 XUngrabPointer (dpy, CurrentTime);
107                 reset_xinput();         
108                 XCloseDisplay(dpy);
109                 fputs("GrabMode Error: XGrabKeyboard failed.", stderr);
110                 return(ENG_ERR_GRABKEY);
111         }
112         
113
114 #ifdef USE_DGA2
115         if (!XDGASetMode(dpy, DefaultScreen(dpy), 1))
116 #else   
117         if (!XF86DGADirectVideo(dpy,DefaultScreen(dpy),XF86DGADirectMouse))
118 #endif
119         {
120                 XUngrabKeyboard(dpy, CurrentTime);                              
121                 XUngrabPointer (dpy, CurrentTime);
122                 reset_xinput();         
123                 XCloseDisplay(dpy);
124                 fputs("GrabMode Error: Failed to enable XF86DGA.", stderr);             
125                 return(ENG_ERR_DGA);
126         }
127
128 #ifdef USE_DGA2
129         XDGASelectInput(dpy, DefaultScreen(dpy), mask);
130 #endif  
131
132         XAutoRepeatOff(dpy);    
133         otime=CurrentTime;
134         
135         grabbed=1;
136         vtt_class::focus_no(0);
137         warp=TX_MOUSE_SPEED_NORMAL;
138         
139         return(0);
140 }
141
142 void tx_mouse :: ungrab()
143 {
144         if (!grabbed) return;
145         
146 #ifdef USE_DGA2 
147         XDGASetMode(dpy, DefaultScreen(dpy), 0);
148 #else
149         XF86DGADirectVideo(dpy,DefaultScreen(dpy),0);
150 #endif  
151
152         XUngrabKeyboard(dpy, CurrentTime);              
153         XUngrabPointer (dpy, CurrentTime);
154         XAutoRepeatOn(dpy);
155
156         reset_xinput(); 
157         
158         XCloseDisplay(dpy);
159
160         vtt_class::unfocus();
161
162         grabbed=0;
163 }
164
165
166
167 int tx_mouse :: set_xinput()
168 {
169         XDeviceInfo *devlist;                   
170         int listmax, i;
171         int match=-1;
172         
173         if (globals.xinput_enable)
174         {       
175                 devlist=XListInputDevices(dpy, &listmax);
176         
177                 for (i=0; i<listmax; i++)
178                 {
179                         if(!strcmp(globals.xinput_device,devlist[i].name))
180                         {
181                                 match=i;
182                         }
183                 
184                         if(devlist[i].use == IsXPointer)
185                         {
186                                 OrgXPointer=devlist[i].id;
187                         }
188                 }
189                 
190                 if (match>=0)
191                 {
192                         input_device=NULL;
193                         input_device=XOpenDevice(dpy,devlist[match].id);
194 /*                      if (XChangePointerDevice(dpy,input_device, 0, 1)!=Success)
195                         {
196                                 match=-1;
197                         }*/
198                         XCloseDevice(dpy, input_device);
199                 }
200                 
201                 XFreeDeviceList(devlist);               
202         
203                 if (match>=0) return(0); 
204                 else return(1);
205         }
206         
207         return(0);
208 }
209
210 #define vtt vtt_class::focused_vtt
211
212 int tx_mouse :: check_event()
213 {
214         if (XCheckWindowEvent(dpy, xwindow, mask, &xev))
215         {
216 #ifdef USE_DGA2
217                 puts("Got an event");
218 #endif          
219                 if (vtt)
220                 switch(xev.type)
221                 {
222                         case MotionNotify:
223                                 vtt->xy_input(((f_prec) xmot->x_root)*warp,((f_prec) xmot->y_root)*warp);
224                                 break;
225                         
226                         case ButtonPress:
227                                 switch(xbut->button)
228                                 {
229                                         case 1: if (vtt->is_playing)
230                                                         vtt->set_scratch(1); 
231                                                 else
232                                                         vtt->sp_trigger.receive_input_value(1);
233                                                 break;
234                                         case 2: vtt->sp_mute.receive_input_value(1); break;
235                                         case 3: vtt_class::focus_next(); break;
236                                 }
237                                 break;
238                         
239                         case ButtonRelease:
240                                 switch (xbut->button)
241                                 {       
242                                         case 1: vtt->set_scratch(0); break;
243                                         case 2: vtt->sp_mute.receive_input_value(0); break;
244                                 }
245                                 break;
246                         case KeyPress:
247 #ifdef USE_DGA2
248                                 puts("Yeah its a key");
249                                 XDGAKeyEventToXKeyEvent(xdgakey, (XKeyEvent *) &xev_copy);
250                                 memcpy(&xev, &xev_copy, sizeof(XEvent));
251 #endif                  
252                         {
253                                 key=XKeycodeToKeysym(dpy, xkey->keycode, 0);
254                                 
255                                 switch(key)
256                                 {
257                                         case XK_space: vtt->set_scratch(1); break;
258                                         case XK_Escape: return(1);
259                                         
260                                         case XK_Return: vtt->sp_trigger.receive_input_value(1); break;
261                                         case XK_BackSpace : vtt->sp_trigger.receive_input_value(0); break;
262                                         
263                                         case XK_Tab: vtt_class::focus_next(); break;
264                                         
265                                         case XK_s: vtt->sp_sync_client.receive_input_value(!vtt->is_sync_client); break;
266                                         
267                                         case XK_m:
268                                         case XK_Control_L:
269                                         case XK_Control_R:                                              
270                                         vtt->sp_mute.receive_input_value(1);
271                                         break;
272                                                 
273                                         case XK_Alt_L:
274                                         case XK_Alt_R:
275                                         vtt->sp_mute.receive_input_value(0);
276                                         break;
277                                         
278                                         case XK_w:
279                                         vtt->sp_mute.receive_input_value(1);
280                                         case XK_f: 
281                                         warp=((float) vtt->samples_in_buffer)/TX_MOUSE_SPEED_WARP;      
282                                         vtt->set_scratch(1);
283                                         break;
284                                                 
285                                         case XK_F1: vtt_class::focus_no(0); break;
286                                         case XK_F2: vtt_class::focus_no(1); break;
287                                         case XK_F3: vtt_class::focus_no(2); break;
288                                         case XK_F4: vtt_class::focus_no(3); break;
289                                         case XK_F5: vtt_class::focus_no(4); break;
290                                         case XK_F6: vtt_class::focus_no(5); break;
291                                         case XK_F7: vtt_class::focus_no(6); break;
292                                         case XK_F8: vtt_class::focus_no(7); break;
293                                         case XK_F9: vtt_class::focus_no(8); break;
294                                         case XK_F10: vtt_class::focus_no(9); break;
295                                         case XK_F11: vtt_class::focus_no(10); break;
296                                         case XK_F12: vtt_class::focus_no(11); break;
297                                 }
298                         } break;
299                         
300                         case KeyRelease:
301                         {
302                                 key=XKeycodeToKeysym (dpy, xkey->keycode, 0);
303                                 
304                                 switch(key)
305                                 {
306                                         case XK_space: vtt->set_scratch(0); break;
307                                         
308                                         case XK_m:
309                                         case XK_Control_L:
310                                         case XK_Control_R:                                              
311                                         vtt->sp_mute.receive_input_value(0);
312                                         break;
313                                                 
314                                         case XK_Alt_L:
315                                         case XK_Alt_R:
316                                         vtt->sp_mute.receive_input_value(1);
317                                         break;
318                                         
319                                         case XK_w:
320                                         vtt->sp_mute.receive_input_value(0);
321                                         case XK_f: warp=TX_MOUSE_SPEED_NORMAL;
322                                         vtt->set_scratch(0);
323                                         break;                                  
324                                 }
325                         }
326                 }
327                 else {  puts("no vtt"); return(1); }
328         }
329         return(0);
330 }
331
332 void tx_mouse :: reset_xinput()
333 {
334         /*      if (globals.xinput_enable)
335         {
336                 input_device=XOpenDevice(dpy, OrgXPointer);
337                 XChangePointerDevice(dpy, input_device, 0, 1);
338                 XCloseDevice(dpy,input_device); 
339         }*/
340 }