rework transportque for shuttle speed codes, add rusage, cleanup
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / shuttle.C
index 4c440dbc0709f6e1a71451314e8dbef56869a07f..65e2f7f2e3f0aac5a90df10a777c8ca5670ab1b0 100644 (file)
@@ -6,6 +6,7 @@
 #include "cstrdup.h"
 #include "file.h"
 #include "guicast.h"
+#include "keys.h"
 #include "linklist.h"
 #include "loadfile.h"
 #include "mainmenu.h"
@@ -41,6 +42,7 @@ static Time milliTimeClock()
 }
 
 KeySymMapping KeySymMapping::key_sym_mapping[] = {
+// button keycodes
        { "XK_Button_1", XK_Button_1 },
        { "XK_Button_2", XK_Button_2 },
        { "XK_Button_3", XK_Button_3 },
@@ -52,6 +54,22 @@ KeySymMapping KeySymMapping::key_sym_mapping[] = {
 
 KeySym KeySymMapping::to_keysym(const char *str)
 {
+       if( !strncmp("FWD_",str, 4) ) {
+               float speed = atof(str+4) / SHUTTLE_MAX_SPEED;
+               if( speed > SHUTTLE_MAX_SPEED ) return 0;
+               int key_code = (SKEY_MAX+SKEY_MIN)/2. +
+                       (SKEY_MAX-SKEY_MIN)/2. * speed;
+               if( key_code > SKEY_MAX ) key_code = SKEY_MAX;
+               return key_code;
+       }
+       if( !strncmp("REV_",str, 4) ) {
+               float speed = atof(str+4) / SHUTTLE_MAX_SPEED;
+               if( speed > SHUTTLE_MAX_SPEED ) return 0;
+               int key_code = (SKEY_MAX+SKEY_MIN)/2. -
+                       (SKEY_MAX-SKEY_MIN)/2. * speed;
+               if( key_code < SKEY_MIN ) key_code = SKEY_MIN;
+               return key_code;
+       }
        for( KeySymMapping *ksp = &key_sym_mapping[0]; ksp->str; ++ksp )
                if( !strcmp(str, ksp->str) ) return ksp->sym;
        return 0;
@@ -61,6 +79,19 @@ const char *KeySymMapping::to_string(KeySym ks)
 {
        for( KeySymMapping *ksp = &key_sym_mapping[0]; ksp->sym; ++ksp )
                if( ksp->sym == ks ) return ksp->str;
+       if( ks >= SKEY_MIN && ks <= SKEY_MAX ) {
+               double speed = SHUTTLE_MAX_SPEED *
+                       (ks-(SKEY_MAX+SKEY_MIN)/2.) / ((SKEY_MAX-SKEY_MIN)/2.);
+               static char text[BCSTRLEN];
+               sprintf(text, "%s_%0.3f", speed>=0 ? "FWD" : "REV", fabs(speed));
+               char *bp = strchr(text,'.');
+               if( bp ) {
+                       char *cp = bp+strlen(bp);
+                       while( --cp>bp && *cp=='0' ) *cp=0;
+                       if( cp == bp ) *cp = 0;
+               }
+               return text;
+       }
        return 0;
 }
 
@@ -400,6 +431,7 @@ int Shuttle::send_button(unsigned int button, int press)
        memset(b, 0, sizeof(*b));
        b->type = press ? ButtonPress : ButtonRelease;
        b->time = milliTimeClock();
+       b->send_event = 1;
        b->display = wdw->top_level->display;
        b->root = wdw->top_level->rootwin;
        b->window = win;
@@ -413,15 +445,21 @@ int Shuttle::send_button(unsigned int button, int press)
        wdw->top_level->put_event((XEvent *) b);
        return 0;
 }
-int Shuttle::send_key(KeySym keysym, int press)
+int Shuttle::send_keycode(unsigned int keycode, int press, int send)
 {
-       KeyCode keycode = XKeysymToKeycode(wdw->top_level->display, keysym);
-       if( debug )
-               printf("key: %04x %d\n", (unsigned)keycode, press);
+       if( debug ) {
+               const char *cp = !send ? 0 :
+                       KeySymMapping::to_string(keycode);
+               if( cp )
+                       printf("key: %s %d\n", cp, press);
+               else
+                       printf("key: %04x %d\n", keycode, press);
+       }
        XKeyEvent *k = new XKeyEvent();
        memset(k, 0, sizeof(*k));
        k->type = press ? KeyPress : KeyRelease;
        k->time = milliTimeClock();
+       k->send_event = send;
        k->display = wdw->top_level->display;
        k->root = wdw->top_level->rootwin;
        k->window = win;
@@ -440,7 +478,9 @@ int Shuttle::send_keysym(KeySym keysym, int press)
 {
        return keysym >= XK_Button_1 && keysym <= XK_Scroll_Down ?
                send_button((unsigned int)keysym - XK_Button_0, press) :
-               send_key(keysym, press ? True : False);
+               send_keycode((unsigned int)keysym, press, 1);
+//     unsigned int keycode = XKeysymToKeycode(wdw->top_level->display, keysym);
+//     return send_keycode(keycode, press, 0);
 }
 
 
@@ -481,7 +521,7 @@ void Shuttle::key(unsigned short code, unsigned int value)
 }
 
 
-void Shuttle:: shuttle(int value)
+void Shuttle::shuttle(int value)
 {
        if( value < S_7 || value > S7 ) {
                fprintf(stderr, "shuttle(%d) out of range\n", value);
@@ -556,6 +596,7 @@ const char *Shuttle::probe()
        static const char *shuttle_devs[] = {
                "/dev/input/by-id/usb-Contour_Design_ShuttleXpress-event-if00",
                "/dev/input/by-id/usb-Contour_Design_ShuttlePRO_v2-event-if00",
+               "/dev/input/by-id/usb-Contour_Design_ShuttlePro-event-if00",
        };
        int ret = sizeof(shuttle_devs) / sizeof(shuttle_devs[0]);
        while( --ret >= 0 && stat(shuttle_devs[ret] , &st) );
@@ -579,6 +620,14 @@ void Shuttle::stop()
        }
 }
 
+BC_WindowBase *Shuttle::owns(BC_WindowBase *wdw, Window win)
+{
+       if( wdw->win == win ) return wdw;
+       if( (wdw=wdw->top_level)->win == win ) return wdw;
+       for( int i=wdw->popups.size(); --i>=0; )
+               if( wdw->popups[i]->win == win ) return wdw;
+       return 0;
+}
 
 int Shuttle::get_focused_window_translation()
 {
@@ -586,7 +635,7 @@ int Shuttle::get_focused_window_translation()
        Display *dpy = gui->display;
        Window focus = 0;
        int ret = 0, revert = 0;
-       char win_title[BCTEXTLEN];
+       char win_title[BCTEXTLEN];  win_title[0] = 0;
        gui->lock_window("Shuttle::get_focused_window_translation");
        XGetInputFocus(dpy, &focus, &revert);
        if( last_focused != focus ) {
@@ -620,13 +669,17 @@ int Shuttle::get_focused_window_translation()
        this->msk = 0;
        BC_WindowBase *wdw = 0;
        int cin = -1;
-       if( (wdw=mwindow->gui) && wdw->win == focus )
+       if( (wdw=owns(mwindow->gui, focus)) != 0 )
                cin = FOCUS_MWINDOW;
-       else if( (wdw=mwindow->awindow->gui) && wdw->win == focus )
+       else if( (wdw=owns(mwindow->awindow->gui, focus)) != 0 )
                cin = FOCUS_AWINDOW;
-       else if( (wdw=mwindow->cwindow->gui) && wdw->win == focus )
+       else if( (wdw=owns(mwindow->cwindow->gui, focus)) != 0 ) {
+               if( mwindow->cwindow->gui->canvas->get_fullscreen() )
+                       wdw = mwindow->cwindow->gui->canvas->get_canvas();
                cin = FOCUS_CWINDOW;
-       else if( (wdw=mwindow->gui->mainmenu->load_file->thread->window) &&
+       }
+       else if( mwindow->gui->mainmenu->load_file->thread->running() &&
+                (wdw=mwindow->gui->mainmenu->load_file->thread->window) != 0 &&
                 wdw->win == focus )
                cin = FOCUS_LOAD;
        else {
@@ -634,7 +687,9 @@ int Shuttle::get_focused_window_translation()
                while( --i >= 0 ) {
                        VWindow *vwdw =  mwindow->vwindows[i];
                        if( !vwdw->is_running() ) continue;
-                       if( (wdw=vwdw->gui) && wdw->win == focus ) {
+                       if( (wdw=owns(vwdw->gui, focus)) != 0 ) {
+                               if( vwdw->gui->canvas->get_fullscreen() )
+                                       wdw = vwdw->gui->canvas->get_canvas();
                                cin = FOCUS_VIEWER;  break;
                        }
                }
@@ -644,7 +699,7 @@ int Shuttle::get_focused_window_translation()
        int root_x = 0, root_y = 0, win_x = 0, win_y = 0, x = 0, y = 0;
        unsigned int mask = 0, width = 0, height = 0, border_width = 0, depth = 0;
        wdw->lock_window("Shuttle::get_focused_window_translation 1");
-       if( XQueryPointer(wdw->display, focus, &root, &child,
+       if( XQueryPointer(wdw->top_level->display, focus, &root, &child,
                        &root_x, &root_y, &win_x, &win_y, &mask) ) {
                if( !child ) {
                        if( wdw->active_menubar )
@@ -653,9 +708,11 @@ int Shuttle::get_focused_window_translation()
                                child = wdw->active_popup_menu->win;
                        else if( wdw->active_subwindow )
                                child = wdw->active_subwindow->win;
+                       else
+                               child = wdw->win;
                }
-               if( child )
-                       XGetGeometry(wdw->display, child, &root, &x, &y,
+               else
+                       XGetGeometry(wdw->top_level->display, child, &root, &x, &y,
                                &width, &height, &border_width, &depth);
        }
        wdw->unlock_window();