Add test for #3356.
[ardour.git] / gtk2_ardour / utils.cc
index b8d75694146831e51061b08d8f6617b18324536e..ac43d06e5984d66c5f41679db528b1e251aa2ce5 100644 (file)
@@ -47,6 +47,7 @@
 #include "i18n.h"
 #include "rgb_macros.h"
 #include "canvas_impl.h"
+#include "gui_thread.h"
 
 using namespace std;
 using namespace Gtk;
@@ -503,12 +504,6 @@ set_color (Gdk::Color& c, int rgb)
        c.set_rgb((rgb >> 16)*256, ((rgb & 0xff00) >> 8)*256, (rgb & 0xff)*256);
 }
 
-#ifdef GTKOSX
-extern "C" {
-       gboolean gdk_quartz_possibly_forward (GdkEvent*);
-}
-#endif
-
 bool
 relay_key_press (GdkEventKey* ev, Gtk::Window* win)
 {
@@ -519,6 +514,79 @@ relay_key_press (GdkEventKey* ev, Gtk::Window* win)
        }
 }
 
+bool
+forward_key_press (GdkEventKey* ev)
+{
+        return PublicEditor::instance().on_key_press_event(ev);
+}
+
+#ifdef GTKOSX
+static guint
+osx_keyval_without_alt (guint accent_keyval)
+{
+       switch (accent_keyval) {
+       case GDK_oe:
+               return GDK_q;
+       case GDK_registered:
+               return GDK_r;
+       case GDK_dagger:
+               return GDK_t;
+       case GDK_yen:
+               return GDK_y;
+       case GDK_diaeresis:
+               return GDK_u;
+       case GDK_oslash:
+               return GDK_o;
+       case GDK_Greek_pi:
+               return GDK_p;
+       case GDK_leftdoublequotemark:
+               return GDK_bracketleft;
+       case GDK_leftsinglequotemark:
+               return GDK_bracketright;
+       case GDK_guillemotleft:
+               return GDK_backslash;
+       case GDK_aring:
+               return GDK_a;
+       case GDK_ssharp:
+               return GDK_s;
+       case GDK_partialderivative:
+               return GDK_d;
+       case GDK_function:
+               return GDK_f;
+       case GDK_copyright:
+               return GDK_g;
+       case GDK_abovedot:
+               return GDK_h;
+       case GDK_notsign:
+               return GDK_l;
+       case GDK_ellipsis:
+               return GDK_semicolon;
+       case GDK_ae:
+               return GDK_apostrophe;
+       case GDK_Greek_OMEGA:
+               return GDK_z;
+       case GDK_ccedilla:
+               return GDK_c;
+       case GDK_radical:
+               return GDK_v;
+       case GDK_integral:
+               return GDK_b;
+       case GDK_mu:
+               return GDK_m;
+       case GDK_lessthanequal:
+               return GDK_comma;
+       case GDK_greaterthanequal:
+               return GDK_period;
+       case GDK_division:
+               return GDK_slash;
+       default:
+               break;
+       }
+
+       return GDK_VoidSymbol;
+}
+#endif
+
 bool
 key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
 {
@@ -588,6 +656,24 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
           all "normal text" accelerators.
        */
 
+#ifdef GTKOSX
+       if (!special_handling_of_unmodified_accelerators) {
+               if (ev->state & GDK_MOD1_MASK) {
+                       /* we're not in a text entry or "magic focus" widget so we don't want OS X "special-character" 
+                          text-style handling of alt-<key>. change the keyval back to what it would be without
+                          the alt key. this way, we see <alt>-v rather than <alt>-radical and so on.
+                       */
+                       guint keyval_without_alt = osx_keyval_without_alt (ev->keyval);
+
+                       if (keyval_without_alt != GDK_VoidSymbol) {
+#ifdef DEBUG_ACCELERATOR_HANDLING
+                               cerr << "Remapped " << gdk_keyval_name (ev->keyval) << " to " << gdk_keyval_name (keyval_without_alt) << endl;
+
+#endif                         ev->keyval = keyval_without_alt;
+                       }
+               }
+       }
+#endif
 
        if (!special_handling_of_unmodified_accelerators) {
 
@@ -598,21 +684,10 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
 
                uint32_t fakekey = ev->keyval;
 
-               if (possibly_translate_keyval_to_make_legal_accelerator (fakekey)) {
+               if (Gtkmm2ext::possibly_translate_keyval_to_make_legal_accelerator (fakekey)) {
                        if (allow_activating && gtk_accel_groups_activate(G_OBJECT(win), fakekey, GdkModifierType(ev->state))) {
                                return true;
                        }
-
-#ifdef GTKOSX
-                       if (allow_activating) {
-                               int oldval = ev->keyval;
-                               ev->keyval = fakekey;
-                               if (gdk_quartz_possibly_forward ((GdkEvent*) ev)) {
-                                       return true;
-                               }
-                               ev->keyval = oldval;
-                       }
-#endif
                }
        }
 
@@ -631,11 +706,6 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
 #endif
 
                if (allow_activating) {
-#ifdef GTKOSX
-                       if (gdk_quartz_possibly_forward ((GdkEvent*) ev)) {
-                               return true;
-                       }
-#endif
                        if (gtk_window_activate_key (win, ev)) {
                                return true;
                        }
@@ -664,12 +734,6 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
 #endif
 
                if (allow_activating) {
-
-#ifdef GTKOSX
-                       if (gdk_quartz_possibly_forward ((GdkEvent*) ev)) {
-                               return true;
-                       }
-#endif
                        return gtk_window_activate_key (win, ev);
                }
 
@@ -852,88 +916,6 @@ reset_dpi ()
        DPIReset();//Emit Signal
 }
 
-bool
-possibly_translate_keyval_to_make_legal_accelerator (uint32_t& keyval)
-{
-       int fakekey = GDK_VoidSymbol;
-
-       switch (keyval) {
-       case GDK_Tab:
-       case GDK_ISO_Left_Tab:
-               fakekey = GDK_nabla;
-               break;
-
-       case GDK_Up:
-               fakekey = GDK_uparrow;
-               break;
-
-       case GDK_Down:
-               fakekey = GDK_downarrow;
-               break;
-
-       case GDK_Right:
-               fakekey = GDK_rightarrow;
-               break;
-
-       case GDK_Left:
-               fakekey = GDK_leftarrow;
-               break;
-
-       case GDK_Return:
-               fakekey = GDK_3270_Enter;
-               break;
-
-       case GDK_KP_Enter:
-               fakekey = GDK_F35;
-               break;
-
-       default:
-               break;
-       }
-
-       if (fakekey != GDK_VoidSymbol) {
-               keyval = fakekey;
-               return true;
-       }
-
-       return false;
-}
-
-uint32_t
-possibly_translate_legal_accelerator_to_real_key (uint32_t keyval)
-{
-       switch (keyval) {
-       case GDK_nabla:
-               return GDK_Tab;
-               break;
-
-       case GDK_uparrow:
-               return GDK_Up;
-               break;
-
-       case GDK_downarrow:
-               return GDK_Down;
-               break;
-
-       case GDK_rightarrow:
-               return GDK_Right;
-               break;
-
-       case GDK_leftarrow:
-               return GDK_Left;
-               break;
-
-       case GDK_3270_Enter:
-               return GDK_Return;
-
-       case GDK_F35:
-               return GDK_KP_Enter;
-               break;
-       }
-
-       return keyval;
-}
-
 
 
 inline guint8
@@ -1034,3 +1016,41 @@ escape_underscores (string const & s)
 
        return o;
 }
+
+static void
+adjustment_to_controllable (Gtk::Adjustment* adj, boost::weak_ptr<Controllable> wcont)
+{
+        boost::shared_ptr<Controllable> cont = wcont.lock();
+
+        if (cont) {
+                double val = adj->get_value();
+                if (val != cont->get_value()) {
+                        cont->set_value (val);
+                }
+        }
+}
+
+static void
+controllable_to_adjustment (Gtk::Adjustment* adj, boost::weak_ptr<Controllable> wcont)
+{
+        boost::shared_ptr<Controllable> cont = wcont.lock();
+
+        if (cont) {
+                float val = cont->get_value();
+                
+                if (val != adj->get_value()) {
+                        adj->set_value (val);
+                }
+        }
+}
+
+void
+control_link (ScopedConnectionList& scl, boost::shared_ptr<Controllable> c, Gtk::Adjustment& a)
+{
+        boost::weak_ptr<Controllable> wc (c);
+
+        a.signal_value_changed().connect (sigc::bind (sigc::ptr_fun (adjustment_to_controllable), &a, wc));
+        c->Changed.connect (scl, MISSING_INVALIDATOR, boost::bind (controllable_to_adjustment, &a, wc),
+                            gui_context());
+}
+