|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- /*
- * Carla Bridge Toolkit, Gtk version
- * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com>
- *
- * 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 the Free Software Foundation; either version 2 of
- * the License, or any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * For a full copy of the GNU General Public License see the doc/GPL.txt file.
- */
-
- #include "CarlaBridgeUI.hpp"
-
- #include <gtk/gtk.h>
-
- #if defined(CARLA_OS_LINUX) && defined(HAVE_X11)
- # define USE_CUSTOM_X11_METHODS
- # include <gdk/gdkx.h>
- #endif
-
- CARLA_BRIDGE_START_NAMESPACE
-
- // -------------------------------------------------------------------------
-
- static int gargc = 0;
- static char** gargv = nullptr;
-
- static const bool gHideShowTesting = std::getenv("CARLA_UI_TESTING") != nullptr;
-
- // -------------------------------------------------------------------------
-
- class CarlaBridgeToolkitGtk : public CarlaBridgeToolkit
- {
- public:
- CarlaBridgeToolkitGtk(CarlaBridgeUI* const u)
- : CarlaBridgeToolkit(u),
- fNeedsShow(false),
- fWindow(nullptr),
- fLastX(0),
- fLastY(0),
- fLastWidth(0),
- fLastHeight(0)
- {
- carla_debug("CarlaBridgeToolkitGtk::CarlaBridgeToolkitGtk(%p)", u);
- }
-
- ~CarlaBridgeToolkitGtk() override
- {
- CARLA_SAFE_ASSERT(fWindow == nullptr);
- carla_debug("CarlaBridgeToolkitGtk::~CarlaBridgeToolkitGtk()");
- }
-
- bool init(const int /*argc*/, const char** /*argv[]*/) override
- {
- CARLA_SAFE_ASSERT_RETURN(fWindow == nullptr, false);
- carla_debug("CarlaBridgeToolkitGtk::init()");
-
- gtk_init(&gargc, &gargv);
-
- fWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr, false);
-
- gtk_window_resize(GTK_WINDOW(fWindow), 30, 30);
- gtk_widget_hide(fWindow);
-
- return true;
- }
-
- void exec(const bool showUI) override
- {
- CARLA_SAFE_ASSERT_RETURN(ui != nullptr,);
- CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
- carla_debug("CarlaBridgeToolkitGtk::exec(%s)", bool2str(showUI));
-
- const CarlaBridgeUI::Options& options(ui->getOptions());
-
- GtkWindow* const gtkWindow(GTK_WINDOW(fWindow));
- CARLA_SAFE_ASSERT_RETURN(gtkWindow != nullptr,);
-
- GtkWidget* const widget((GtkWidget*)ui->getWidget());
- gtk_container_add(GTK_CONTAINER(fWindow), widget);
-
- gtk_window_set_resizable(gtkWindow, options.isResizable);
- gtk_window_set_title(gtkWindow, options.windowTitle.buffer());
-
- if (showUI || fNeedsShow)
- {
- show();
- fNeedsShow = false;
- }
-
- g_timeout_add(30, gtk_ui_timeout, this);
- g_signal_connect(fWindow, "destroy", G_CALLBACK(gtk_ui_destroy), this);
- g_signal_connect(fWindow, "realize", G_CALLBACK(gtk_ui_realize), this);
-
- // First idle
- handleTimeout();
-
- // Main loop
- gtk_main();
- }
-
- void quit() override
- {
- carla_debug("CarlaBridgeToolkitGtk::quit()");
-
- if (fWindow != nullptr)
- {
- gtk_widget_destroy(fWindow);
- fWindow = nullptr;
-
- gtk_main_quit_if_needed();
- }
- }
-
- void show() override
- {
- carla_debug("CarlaBridgeToolkitGtk::show()");
-
- fNeedsShow = true;
-
- if (fWindow != nullptr)
- gtk_widget_show_all(fWindow);
- }
-
- void focus() override
- {
- carla_debug("CarlaBridgeToolkitGtk::focus()");
- }
-
- void hide() override
- {
- carla_debug("CarlaBridgeToolkitGtk::hide()");
-
- fNeedsShow = false;
-
- if (fWindow != nullptr)
- gtk_widget_hide(fWindow);
- }
-
- void setSize(const uint width, const uint height) override
- {
- CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
- carla_debug("CarlaBridgeToolkitGtk::resize(%i, %i)", width, height);
-
- gtk_window_resize(GTK_WINDOW(fWindow), static_cast<gint>(width), static_cast<gint>(height));
- }
-
- void setTitle(const char* const title) override
- {
- CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
- carla_debug("CarlaBridgeToolkitGtk::setTitle(\"%s\")", title);
-
- gtk_window_set_title(GTK_WINDOW(fWindow), title);
- }
-
- // ---------------------------------------------------------------------
-
- protected:
- bool fNeedsShow;
- GtkWidget* fWindow;
-
- gint fLastX;
- gint fLastY;
- gint fLastWidth;
- gint fLastHeight;
-
- void handleDestroy()
- {
- carla_debug("CarlaBridgeToolkitGtk::handleDestroy()");
-
- fWindow = nullptr;
- }
-
- void handleRealize()
- {
- carla_debug("CarlaBridgeToolkitGtk::handleRealize()");
-
- const CarlaBridgeUI::Options& options(ui->getOptions());
-
- if (options.transientWindowId != 0)
- setTransient(options.transientWindowId);
- }
-
- gboolean handleTimeout()
- {
- if (fWindow != nullptr)
- {
- gtk_window_get_position(GTK_WINDOW(fWindow), &fLastX, &fLastY);
- gtk_window_get_size(GTK_WINDOW(fWindow), &fLastWidth, &fLastHeight);
- }
-
- if (ui->isPipeRunning())
- ui->idlePipe();
-
- ui->idleUI();
-
- if (gHideShowTesting)
- {
- static int counter = 0;
- ++counter;
-
- if (counter == 100)
- {
- hide();
- }
- else if (counter == 200)
- {
- show();
- counter = 0;
- }
- }
-
- return true;
- }
-
- void setTransient(const uintptr_t winId)
- {
- CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
- carla_debug("CarlaBridgeToolkitGtk::setTransient(0x" P_UINTPTR ")", winId);
-
- #ifdef USE_CUSTOM_X11_METHODS
- GdkWindow* const gdkWindow(gtk_widget_get_window(fWindow));
- CARLA_SAFE_ASSERT_RETURN(gdkWindow != nullptr,);
-
- # ifdef BRIDGE_GTK3
- GdkDisplay* const gdkDisplay(gdk_window_get_display(gdkWindow));
- CARLA_SAFE_ASSERT_RETURN(gdkDisplay != nullptr,);
-
- ::Display* const display(gdk_x11_display_get_xdisplay(gdkDisplay));
- CARLA_SAFE_ASSERT_RETURN(display != nullptr,);
-
- const ::XID xid(gdk_x11_window_get_xid(gdkWindow));
- CARLA_SAFE_ASSERT_RETURN(xid != 0,);
- # else
- ::Display* const display(gdk_x11_drawable_get_xdisplay(gdkWindow));
- CARLA_SAFE_ASSERT_RETURN(display != nullptr,);
-
- const ::XID xid(gdk_x11_drawable_get_xid(gdkWindow));
- CARLA_SAFE_ASSERT_RETURN(xid != 0,);
- # endif
-
- XSetTransientForHint(display, xid, static_cast< ::Window>(winId));
- #endif
- }
-
- // ---------------------------------------------------------------------
-
- private:
- static void gtk_main_quit_if_needed()
- {
- if (gtk_main_level() != 0)
- gtk_main_quit();
- }
-
- static void gtk_ui_destroy(GtkWidget*, gpointer data)
- {
- CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
-
- ((CarlaBridgeToolkitGtk*)data)->handleDestroy();
- gtk_main_quit_if_needed();
- }
-
- static void gtk_ui_realize(GtkWidget*, gpointer data)
- {
- CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
-
- ((CarlaBridgeToolkitGtk*)data)->handleRealize();
- }
-
- static gboolean gtk_ui_timeout(gpointer data)
- {
- CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);
-
- return ((CarlaBridgeToolkitGtk*)data)->handleTimeout();
- }
-
- CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaBridgeToolkitGtk)
- };
-
- // -------------------------------------------------------------------------
-
- CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeUI* const ui)
- {
- return new CarlaBridgeToolkitGtk(ui);
- }
-
- // -------------------------------------------------------------------------
-
- CARLA_BRIDGE_END_NAMESPACE
|