Colors customizable - 'w' + 'f' "fix" - Alex
[terminatorX.git] / src / tX_mouse.cc
index df03617fae3faf53f07e04c8e15c18c511b16074..196d48d190fd919e2cc523ebc09cb0c358799e1d 100644 (file)
@@ -1,6 +1,6 @@
 /*
     terminatorX - realtime audio scratching software
-    Copyright (C) 1999, 2000  Alexander König
+    Copyright (C) 1999-2003  Alexander König
  
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
  
     Description: This implements the mouse AND keyboard Input handling in
                 Grab-Mode.
-*/    
+*/
 
+#include <sys/wait.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/xf86dga.h>
 
 #include "tX_mouse.h"
 #include "tX_mastergui.h"
@@ -32,8 +35,7 @@
 #define TX_MOUSE_SPEED_NORMAL 0.05
 #define TX_MOUSE_SPEED_WARP 250000
 
-tx_mouse :: tx_mouse()
-{
+tx_mouse :: tx_mouse() {
        mask=PointerMotionMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask;
        xmot=(XMotionEvent *) &xev;
        xkey=(XKeyEvent *) &xev;
@@ -50,16 +52,16 @@ tx_mouse :: tx_mouse()
 }
 
 
-int tx_mouse :: grab()
-{      
+int tx_mouse :: grab() {       
 #ifdef USE_DGA2
        XDGAMode *mode;
 #endif 
-       int i, num=0;
 
        if (grabbed) return(0);
 
-       dpy=XOpenDisplay(NULL); // FIXME: use correct display
+       warp_override=false;
+       
+       dpy=XOpenDisplay(NULL);
        if (!dpy)
        {
                fputs("GrabMode Error: couldn't connect to XDisplay.", stderr);
@@ -133,15 +135,32 @@ int tx_mouse :: grab()
        otime=CurrentTime;
        
        grabbed=1;
-       vtt_class::focus_no(0);
+       
+       std::list<vtt_class *> :: iterator v;
+       int c=0;
+       
+       for (v=vtt_class::main_list.begin(); v!=vtt_class::main_list.end(); v++) {
+               if (!(*v)->audio_hidden) {
+                       vtt_class::focus_no(c);
+                       break;
+               }
+               c++;
+               //vtt_class::focus_no(0);
+       }
+       
+       
        warp=TX_MOUSE_SPEED_NORMAL;
        
+       tX_debug("tX_mouse::grab(): this: %08x, dpy: %08x", (int) this, (int) dpy);
+       
        return(0);
 }
 
 void tx_mouse :: ungrab()
 {
        if (!grabbed) return;
+
+       tX_debug("tX_mouse::ungrab(): this: %08x, dpy: %08x", (int) this, (int) dpy);
        
 #ifdef USE_DGA2        
        XDGASetMode(dpy, DefaultScreen(dpy), 0);
@@ -162,23 +181,81 @@ void tx_mouse :: ungrab()
 
        vtt_class::unfocus();
 
+       tX_debug("tX_mouse::ungrab(): done");
+       
        grabbed=0;
 }
 
+#ifdef USE_XSETPOINTER
+
+void tx_mouse :: set_x_pointer(char *devname)
+{
+       pid_t pid;
+       int status;
+               
+       pid = fork();
+       
+       if (pid==-1) 
+       { 
+               /* OOPS. fork failed */
+               perror("tX: Error: Couldn't fork process!");
+               return; 
+       }
+       
+       if (pid==0) 
+       {
+               /* The child execlps xsetpointer */
+               execlp("xsetpointer", "xsetpointer", devname, NULL);
+               perror("tX: Error: Failed to execute xpointer!");
+               exit(0);
+       }
+       
+       /* parent waits for xsetpointer to finish */
+       waitpid(pid,  &status, WUNTRACED);
+}
+
+#else
+
 void tx_mouse :: set_x_pointer(char *devname)
 {
-       char commandline[256];
+       XDeviceInfo *devlist;                   
+       XDevice *device;
+       int listmax, i;
+       
+       devlist=XListInputDevices(dpy, &listmax);
        
-       sprintf(commandline, "xsetpointer %s", devname);
-       system(commandline);
-       printf("ran: %s\n", commandline);
+       for (i=0; i<listmax; i++)
+       {
+               if(strcmp(devlist[i].name, devname)==0)
+               {
+                       device=XOpenDevice(dpy, devlist[i].id);
+                       if (device)
+                       {
+                               if (XChangePointerDevice(dpy, device, 0, 1))
+                               {
+                                       printf("tX: Error: failed to set pointer device.");                     
+                               }
+                               XCloseDevice(dpy, device);
+                       }
+                       else
+                       {
+                               printf("tX: Error: failed to open XInput device.");
+                       }               
+               }
+       }
+               
+       XFreeDeviceList(devlist);               
 }
 
+#endif
+
 int tx_mouse :: set_xinput()
 {
        XDeviceInfo *devlist;                   
        int listmax, i;
        
+       OrgXPointer=0;
+       
        if (globals.xinput_enable)
        {       
                devlist=XListInputDevices(dpy, &listmax);
@@ -196,6 +273,8 @@ int tx_mouse :: set_xinput()
                
                set_x_pointer(globals.xinput_device);
        }
+       
+       if (OrgXPointer==0) printf("tX: Error failed to detect core pointer.");
        return(0);
 }
 
@@ -204,7 +283,7 @@ void tx_mouse :: reset_xinput()
 {
        if (globals.xinput_enable)
        {
-               set_x_pointer(OrgXPointerName);
+               if (OrgXPointer) set_x_pointer(OrgXPointerName);
        }
 }
 
@@ -222,7 +301,12 @@ int tx_mouse :: check_event()
                switch(xev.type)
                {
                        case MotionNotify:
-                               vtt->xy_input(((f_prec) xmot->x_root)*warp,((f_prec) xmot->y_root)*warp);
+                               
+                               if (warp_override) {
+                                       vtt->sp_speed.handle_mouse_input(((f_prec) xmot->x_root)*globals.mouse_speed*warp);
+                               } else {
+                                       vtt->xy_input((f_prec) xmot->x_root, (f_prec) xmot->y_root);
+                               }
                                break;
                        
                        case ButtonPress:
@@ -280,6 +364,7 @@ int tx_mouse :: check_event()
                                        case XK_w:
                                        vtt->sp_mute.receive_input_value(1);
                                        case XK_f: 
+                                       warp_override=true;
                                        warp=((float) vtt->samples_in_buffer)/TX_MOUSE_SPEED_WARP;      
                                        vtt->set_scratch(1);
                                        break;
@@ -321,6 +406,7 @@ int tx_mouse :: check_event()
                                        case XK_w:
                                        vtt->sp_mute.receive_input_value(0);
                                        case XK_f: warp=TX_MOUSE_SPEED_NORMAL;
+                                       warp_override=false;
                                        vtt->set_scratch(0);
                                        break;                                  
                                }