*/
+#include <pango/pangoft2.h> // for fontmap resolution control for GnomeCanvas
+#include <pango/pangocairo.h> // for fontmap resolution control for GnomeCanvas
+
#include <cstdlib>
#include <cctype>
#include <fstream>
#include <sys/stat.h>
#include <libart_lgpl/art_misc.h>
+#include <gtkmm/rc.h>
#include <gtkmm/window.h>
#include <gtkmm/combo.h>
#include <gtkmm/label.h>
#include <gtkmm2ext/utils.h>
#include <ardour/ardour.h>
+#include <ardour/configuration.h>
#include "ardour_ui.h"
#include "keyboard.h"
using namespace Glib;
using namespace PBD;
+sigc::signal<void> DPIReset;
+
int
pixel_width (const ustring& str, Pango::FontDescription& font)
{
gint
just_hide_it (GdkEventAny *ev, Gtk::Window *win)
{
- win->hide_all ();
+ win->hide ();
return TRUE;
}
return new ArdourCanvas::Points (npoints);
}
-Pango::FontDescription
+Pango::FontDescription*
get_font_for_style (string widgetname)
{
Gtk::Window window (WINDOW_TOPLEVEL);
PangoContext* ctxt = (PangoContext*) pango_layout_get_context ((PangoLayout*) layout->gobj());
pfd = pango_context_get_font_description (ctxt);
- return Pango::FontDescription (pfd, true); /* make a copy */
+ return new Pango::FontDescription (pfd, true); /* make a copy */
}
- return Pango::FontDescription (pfd, true); /* make a copy */
+ return new Pango::FontDescription (pfd, true); /* make a copy */
}
uint32_t
}
}
+
+Gdk::Color
+color_from_style (string widget_style_name, int state, string attr)
+{
+ GtkStyle* style;
+
+ style = gtk_rc_get_style_by_paths (gtk_settings_get_default(),
+ widget_style_name.c_str(),
+ 0, G_TYPE_NONE);
+
+ if (!style) {
+ error << string_compose (_("no style found for %1, using red"), style) << endmsg;
+ return Gdk::Color ("red");
+ }
+
+ cerr << "got style for " << widget_style_name << endl;
+
+ if (attr == "fg") {
+ return Gdk::Color (&style->fg[state]);
+ }
+
+ if (attr == "bg") {
+ cerr << "returning color from bg\n";
+ return Gdk::Color (&style->bg[state]);
+ }
+
+ if (attr == "light") {
+ return Gdk::Color (&style->light[state]);
+ }
+
+ if (attr == "dark") {
+ return Gdk::Color (&style->dark[state]);
+ }
+
+ if (attr == "mid") {
+ return Gdk::Color (&style->mid[state]);
+ }
+
+ if (attr == "text") {
+ return Gdk::Color (&style->text[state]);
+ }
+
+ if (attr == "base") {
+ return Gdk::Color (&style->base[state]);
+ }
+
+ if (attr == "text_aa") {
+ return Gdk::Color (&style->text_aa[state]);
+ }
+
+ error << string_compose (_("unknown style attribute %1 requested for color; using \"red\""), attr) << endmsg;
+ return Gdk::Color ("red");
+}
+
+
bool
canvas_item_visible (ArdourCanvas::Item* item)
{
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
key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
{
GtkWindow* win = window.gobj();
GtkWidget* focus = gtk_window_get_focus (win);
bool special_handling_of_unmodified_accelerators = false;
+ bool allow_activating = true;
-#undef DEBUG_ACCELERATOR_HANDLING
+#undef DEBUG_ACCELERATOR_HANDLING
#ifdef DEBUG_ACCELERATOR_HANDLING
- bool debug = (getenv ("ARDOUR_DEBUG_ACCELERATOR_HANDLING") != 0);
+ //bool debug = (getenv ("ARDOUR_DEBUG_ACCELERATOR_HANDLING") != 0);
+ bool debug=true;
#endif
-
if (focus) {
if (GTK_IS_ENTRY(focus) || Keyboard::some_magic_widget_has_focus()) {
special_handling_of_unmodified_accelerators = true;
}
}
+#ifdef GTKOSX
+ /* should this be universally true? */
+ if (Keyboard::some_magic_widget_has_focus ()) {
+ allow_activating = false;
+ }
+#endif
+
#ifdef DEBUG_ACCELERATOR_HANDLING
if (debug) {
cerr << "Win = " << win << " Key event: code = " << ev->keyval << " state = " << hex << ev->state << dec << " special handling ? "
<< special_handling_of_unmodified_accelerators
+ << " magic widget focus ? "
+ << Keyboard::some_magic_widget_has_focus()
+ << " allow_activation ? "
+ << allow_activating
<< endl;
}
#endif
it does allow.
*/
- int ret = false;
+ uint32_t fakekey = ev->keyval;
- switch (ev->keyval) {
- case GDK_Up:
- ret = gtk_accel_groups_activate(G_OBJECT(win), GDK_uparrow, GdkModifierType(ev->state));
- break;
+ if (possibly_translate_keyval_to_make_legal_accelerator (fakekey)) {
+ if (allow_activating && gtk_accel_groups_activate(G_OBJECT(win), fakekey, GdkModifierType(ev->state))) {
+ return true;
+ }
- case GDK_Down:
- ret = gtk_accel_groups_activate(G_OBJECT(win), GDK_downarrow, GdkModifierType(ev->state));
- break;
+#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
+ }
+ }
- case GDK_Right:
- ret = gtk_accel_groups_activate(G_OBJECT(win), GDK_rightarrow, GdkModifierType(ev->state));
- break;
+ /* consider all relevant modifiers but not LOCK or SHIFT */
- case GDK_Left:
- ret = gtk_accel_groups_activate(G_OBJECT(win), GDK_leftarrow, GdkModifierType(ev->state));
- break;
+ guint mask = (Keyboard::RelevantModifierKeyMask & ~(Gdk::SHIFT_MASK|Gdk::LOCK_MASK));
- default:
- break;
- }
+ if (!special_handling_of_unmodified_accelerators || (ev->state & mask)) {
- if (ret) {
- return true;
- }
- }
-
- if (!special_handling_of_unmodified_accelerators ||
- ev->state & (Gdk::MOD1_MASK|
- Gdk::MOD3_MASK|
- Gdk::MOD4_MASK|
- Gdk::MOD5_MASK|
- Gdk::CONTROL_MASK)) {
-
- /* no special handling or modifiers in effect: accelerate first */
+ /* no special handling or there are modifiers in effect: accelerate first */
#ifdef DEBUG_ACCELERATOR_HANDLING
if (debug) {
cerr << "\tactivate, then propagate\n";
}
#endif
- if (!gtk_window_activate_key (win, ev)) {
- return gtk_window_propagate_key_event (win, ev);
- } else {
+
+ if (allow_activating) {
+#ifdef GTKOSX
+ if (gdk_quartz_possibly_forward ((GdkEvent*) ev)) {
+ return true;
+ }
+#endif
+ if (gtk_window_activate_key (win, ev)) {
+ return true;
+ }
+ }
+
#ifdef DEBUG_ACCELERATOR_HANDLING
if (debug) {
- cerr << "\tnot handled\n";
+ cerr << "\tnot accelerated, now propagate\n";
}
#endif
- return true;
- }
+ return gtk_window_propagate_key_event (win, ev);
}
/* no modifiers, propagate first */
cerr << "\tpropagation didn't handle, so activate\n";
}
#endif
- return gtk_window_activate_key (win, ev);
+
+ if (allow_activating) {
+
+#ifdef GTKOSX
+ if (gdk_quartz_possibly_forward ((GdkEvent*) ev)) {
+ return true;
+ }
+#endif
+ return gtk_window_activate_key (win, ev);
+ }
+
} else {
#ifdef DEBUG_ACCELERATOR_HANDLING
if (debug) {
Glib::RefPtr<Gdk::Pixbuf>
get_xpm (std::string name)
{
+ //cerr << "xpm path = " << ARDOUR::find_data_file(name, "pixmaps") << endl;//DEBUG
if (!xpm_map[name]) {
- xpm_map[name] = Gdk::Pixbuf::create_from_file (ARDOUR::find_data_file(name, "pixmaps"));
+ try {
+ xpm_map[name] = Gdk::Pixbuf::create_from_file (ARDOUR::find_data_file(name, "pixmaps"));
+ }
+ catch(const Glib::Error& e) {
+ warning << "Caught Glib::Error: " << e.what() << endmsg;
+ }
}
return (xpm_map[name]);
/*NOTREACHED*/
}
- return Gdk::Pixbuf::create_from_file (path);
+ Glib::RefPtr<Gdk::Pixbuf> img;
+ try {
+ img = Gdk::Pixbuf::create_from_file (path);
+ }
+ catch (const Gdk::PixbufError &e)
+ {
+ cerr << "Caught PixbufError: " << e.what() << endl;
+ }
+ catch (...)
+ {
+ g_message("Caught ... ");
+ }
+
+ return img;
}
string
return false;
}
+void
+set_pango_fontsize ()
+{
+ long val = ARDOUR::Config->get_font_scale();
+ /* FT2 rendering - used by GnomeCanvas, sigh */
+ pango_ft2_font_map_set_resolution ((PangoFT2FontMap*) pango_ft2_font_map_for_display(), val/1024, val/1024);
+ /* Cairo rendering, in case there is any */
+
+ // pango_cairo_font_map_set_resolution ((PangoCairoFontMap*) pango_cairo_font_map_get_default(), val/1024);
+}
+
+void
+reset_dpi ()
+{
+ long val = ARDOUR::Config->get_font_scale();
+ set_pango_fontsize ();
+ /* Xft rendering */
+
+ gtk_settings_set_long_property (gtk_settings_get_default(),
+ "gtk-xft-dpi", val, "ardour");
+ 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;
+
+ default:
+ break;
+ }
+
+ if (fakekey != GDK_VoidSymbol) {
+ keyval = fakekey;
+ return true;
+ }
+
+ return false;
+}
+
+inline guint8
+convert_color_channel (guint8 src,
+ guint8 alpha)
+{
+ return alpha ? ((guint (src) << 8) - src) / alpha : 0;
+}
+
+void
+convert_bgra_to_rgba (guint8 const* src,
+ guint8* dst,
+ int width,
+ int height)
+{
+ guint8 const* src_pixel = src;
+ guint8* dst_pixel = dst;
+
+ for (int y = 0; y < height; y++)
+ for (int x = 0; x < width; x++)
+ {
+ dst_pixel[0] = convert_color_channel (src_pixel[2],
+ src_pixel[3]);
+ dst_pixel[1] = convert_color_channel (src_pixel[1],
+ src_pixel[3]);
+ dst_pixel[2] = convert_color_channel (src_pixel[0],
+ src_pixel[3]);
+ dst_pixel[3] = src_pixel[3];
+
+ dst_pixel += 4;
+ src_pixel += 4;
+ }
+}
+
+Glib::RefPtr<Gdk::Pixbuf>
+pixbuf_from_ustring(const ustring& name, Pango::FontDescription* font, int clip_width, int clip_height)
+{
+ Glib::RefPtr<Gdk::Pixbuf> buf = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, clip_width, clip_height);
+ cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, clip_width, clip_height);
+ cairo_t* cr = cairo_create (surface);
+ cairo_text_extents_t te;
+
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
+ cairo_select_font_face (cr, font->get_family().c_str(),
+ CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+ cairo_set_font_size (cr, font->get_size() / Pango::SCALE);
+ cairo_text_extents (cr, name.c_str(), &te);
+
+ cairo_move_to (cr, 0.5, 0.5 - te.height / 2 - te.y_bearing + clip_height / 2);
+ cairo_show_text (cr, name.c_str());
+
+ convert_bgra_to_rgba(cairo_image_surface_get_data (surface), buf->get_pixels(), clip_width, clip_height);
+
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+
+ return buf;
+}