diff options
author | Leo Ufimtsev | 2018-01-18 01:45:53 +0000 |
---|---|---|
committer | Alexander Kurtakov | 2018-01-18 10:00:34 +0000 |
commit | 5282e51a49c640f347e112faa9b2305ff5ed4111 (patch) | |
tree | 94269df599f1c3a7989ed232128095ecf2684fa9 | |
parent | 0f594b4f96e383e0f8802a000fe4bfabfead093e (diff) | |
download | rt.equinox.framework-5282e51a49c640f347e112faa9b2305ff5ed4111.tar.gz rt.equinox.framework-5282e51a49c640f347e112faa9b2305ff5ed4111.tar.xz rt.equinox.framework-5282e51a49c640f347e112faa9b2305ff5ed4111.zip |
Bug 528414 (swtWaylandLauncher) Part 2: Replace x11 with gdbus
eclipseGtk.c overhaul replacing x11 machinery with gio's gdbus for
wayland support.
Results:
- Launcher works on wayland
- All x11 is gone (at least for gtk3).
- Files no longer separated via colons.
- Verified on Wayland (and x11).
- Also added a makefile to accelerate future development efforts and
make it
more obvious on how to test launcher.
Technical notes:
- Old machinery used to set windowProperty via x11 atoms,
files were separated via colons ':'. This had issues with local urls'.
- New machinery checks if there is a session on:
org.eclipse.swt
and if so, it passes files via a gdbus array with each file
being a separate item. (I.e, colons not used anymore).
- The mutex/launcher window stuff was all related to x11. gdbus
doesn't use that anymore, locks are internall to gtk/glib.
- A few additional minor fixes/patches (code style etc...).
Test Strategy:
- Below were done on both Wayland and X11:
- Fedora 27, Gtk3.22. (Probably works on gtk2, but not tested).
1) Open eclipse with file(s) :
./eclipse /tmp/myfile1 [OK]
./eclipse /tmp/myfile1 /tmp/myfile2 [OK]
2) Open multiple eclipses at the same time: [OK]
./eclipse /tmp/myfile1 /tmp/myfile2 & ./eclipse /tmp/myfile3
/tmp/myfile3
3) Open eclipse. Once opened, run launcher again to pass files. [OK]
./eclipse
...
./eclipse /tmp/myfile
4) Open eclipse with launcher flag:
./eclipse --launcher.openFile /tmp/myfile1
Bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=528414
Change-Id: I73ab1e8b603deee803693f022f0c4c90ea3c43c9
Signed-off-by: Leo Ufimtsev <lufimtse@redhat.com>
8 files changed, 245 insertions, 205 deletions
diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipse.c b/features/org.eclipse.equinox.executable.feature/library/eclipse.c index 4ff218722..9ab57f740 100644 --- a/features/org.eclipse.equinox.executable.feature/library/eclipse.c +++ b/features/org.eclipse.equinox.executable.feature/library/eclipse.c @@ -1103,6 +1103,12 @@ static void getVMCommand( int launchMode, int argc, _TCHAR* argv[], _TCHAR **vmA /* If the user specified "-vmargs", add them instead of the default VM args. */ vmArg = (userVMarg != NULL) ? userVMarg : getArgVM( (launchMode == LAUNCH_JNI) ? jniLib : javaVM ); +#ifdef LINUX + // Append flags needed for SWT to understand it's started from launcher to provide things like dbus support. + vmArg = concatArgs(vmArg, gtkPlatformJavaSystemProperties); +#endif + + adjustVMArgs(javaVM, jniLib, &vmArg); /* Calculate the number of VM arguments. */ diff --git a/features/org.eclipse.equinox.executable.feature/library/eclipseOS.h b/features/org.eclipse.equinox.executable.feature/library/eclipseOS.h index 0b2b6a782..14035c30a 100644 --- a/features/org.eclipse.equinox.executable.feature/library/eclipseOS.h +++ b/features/org.eclipse.equinox.executable.feature/library/eclipseOS.h @@ -38,6 +38,10 @@ extern _TCHAR** initialArgv; /* argv originally used to start launcher */ extern _TCHAR* eeLibPath; /* library path specified in a .ee file */ extern int secondThread; /* whether or not to start the vm on a second thread */ +#ifdef LINUX +extern char* gtkPlatformJavaSystemProperties []; +#endif + /* OS Specific Functions */ /** Display a Message diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/README.md b/features/org.eclipse.equinox.executable.feature/library/gtk/README.md new file mode 100644 index 000000000..5f9906e35 --- /dev/null +++ b/features/org.eclipse.equinox.executable.feature/library/gtk/README.md @@ -0,0 +1,20 @@ + + +# Building + +To build: + + ./bulid.sh + +This will read the relevant make files. + +To clean: + + ./build.sh clean + +# Developer notes: + +To inject into a test eclipse instance for testing: + + cp eclipse (eclipseDir)/eclipse + cp eclipse_16xx.so (eclipseDir)/plugins/org.eclipse.equinox.launcher.<ws>.<os>.<arch>*/ diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.c b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.c index 65f1b0c8a..e26e48a4d 100644 --- a/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.c +++ b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -23,9 +23,7 @@ #include <sys/wait.h> #include <sys/ioctl.h> #include <dlfcn.h> -#ifdef SOLARIS -#include <sys/filio.h> -#endif + #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -34,10 +32,6 @@ #include <semaphore.h> #include <fcntl.h> -#ifdef HPUX -#define SEM_FAILED (void *)-1 -#endif - /* Global Variables */ char* defaultVM = "java"; char* vmLibrary = "libjvm.so"; @@ -46,188 +40,186 @@ char* shippedVMDir = "jre/bin/"; /* Define the special arguments for the various Java VMs. */ static char* argVM_JAVA[] = { NULL }; +/* + * Define arguments that are required/used by platform (e.g SWT) to function properly on gtk. (via Java's System.getProperty(..)). + * These should not affect JVM itself (e.g flags shouldn't set things like memory usage of the JVM). + * + * Note, these may re-occur in *.product (i.e eclipse.ini) such that "java -jar launcher" would work (e.g a child eclipse). + * See bug 528414. + * + * For swt.dbus.init, see bottom of method (SWT/Gtk) Display.java:createDisplay(). + */ +char* gtkPlatformJavaSystemProperties [] = { "-Dswt.dbus.init", NULL}; + /* Define local variables . */ -static long splashHandle = 0; +static GtkWidget* splashHandle = 0; static GtkWidget* shellHandle = 0; -static sem_t* mutex; -static Atom appWindowAtom, launcherWindowAtom; static _TCHAR** openFilePath = NULL; /* the files we want to open */ static int openFileTimeout = 60; /* number of seconds to wait before timeout */ -static int windowPropertySet = 0; /* set to 1 on success */ - -static struct sigaction quitAction; -static struct sigaction intAction; - -/* Local functions */ -static void catch_signal(int sig) { - //catch signals, free the lock, reinstall the original - //signal handlers and reraise the signal. - sem_post(mutex); - sem_close(mutex); - sigaction(SIGINT, &intAction, NULL); - sigaction(SIGQUIT, &intAction, NULL); - raise(sig); -} +static int filesPassedToSWT = 0; /* set to 1 on success */ +static const int FILEOPEN_RETRY_TIMEOUT_MS = 1000; + +/** GDBus related */ +static const gchar GDBUS_SERVICE[] = "org.eclipse.swt"; +static const gchar GDBUS_OBJECT[] = "/org/eclipse/swt"; +static const gchar GDBUS_INTERFACE[] = "org.eclipse.swt"; +GDBusProxy *gdbus_proxy = NULL; + +gboolean gdbus_initProxy (); +gboolean gdbus_testConnection(); +gboolean gdbus_FileOpen_TimerProc(gpointer data); +gboolean gdbus_call_FileOpen (); + +/* + * Deals with opening files passed to eclipse. e.g: ./eclipse /myfile + * + * return 1 = Files passed to eclipse. Don't spawn another instance. + * 0 = Launch a new eclipse instance, will try to pass files to eclipse once instance is launched. + */ +gboolean reuseWorkbench(_TCHAR** filePath, int timeout) { + openFileTimeout = timeout; + openFilePath = filePath; -typedef int (*LockFunc)(); -int executeWithLock(char *name, LockFunc func) { - int result = -1; - int lock = -1; - struct sigaction action; + if (initWindowSystem(&initialArgc, initialArgv, 1) != 0) + return -1; - mutex = sem_open(name, O_CREAT | O_EXCL, S_IRWXU | S_IRWXG | S_IRWXO, 1); - if (mutex == SEM_FAILED) { - //create failed. Probably lock is already created so try opening the existing lock. - mutex = sem_open(name, 0); - } - if (mutex == SEM_FAILED) - return -1; //this is an error. - - // install signal handler to free the lock if something bad happens. - // sem_t is not freed automatically when a process ends. - action.sa_handler = catch_signal; - sigaction(SIGINT, &action, &intAction); - sigaction(SIGQUIT, &action, &quitAction); - - while ((lock = sem_trywait(mutex)) != 0) { - if (errno == EAGAIN) { - //couldn't acquire lock, sleep a bit and try again - sleep(1); - if (--openFileTimeout > 0) - continue; - } - break; + if (!gdbus_initProxy()) { + _ftprintf(stderr, "Launcher Error. Could not init gdbus proxy. Bug? Launching eclipse without opening files passed in.\n"); + return 0; } - if (lock == 0) - result = func(); - - sem_post(mutex); - sem_close(mutex); - - //reinstall the original signal handlers - sigaction(SIGINT, &intAction, NULL); - sigaction(SIGQUIT, &quitAction, NULL); - return result; + // If eclipse already open, just pass files. + if (gdbus_testConnection()) { + return gdbus_call_FileOpen(); + } else { + // Otherwise add a timer that will keep trying to pass files to eclipse for a few minutes until it succeeds or times out. + // Note, the while loop in launchJavaVM() ensures the launcher doesn't quit before the timer expired. + gtk.g_timeout_add(FILEOPEN_RETRY_TIMEOUT_MS, gdbus_FileOpen_TimerProc, 0); + return 0; + } } -/* Create a "SWT_Window_" + APP_NAME string with optional suffix. - * Caller should free the memory when finished */ -static char * createSWTWindowString(char * suffix, int semaphore) { -#ifdef SOLARIS - /* solaris requires semaphore names to start with '/' */ - char * prefix = semaphore != 0 ? _T_ECLIPSE("/SWT_Window_") : _T_ECLIPSE("SWT_Window_"); -#else - char * prefix = _T_ECLIPSE("SWT_Window_"); -#endif - - char * result = malloc((_tcslen(prefix) + _tcslen(getOfficialName()) + (suffix != NULL ? _tcslen(suffix) : 0) + 1) * sizeof(char)); - if (suffix != NULL) - _stprintf(result, _T_ECLIPSE("%s%s%s"), prefix, getOfficialName(), suffix); - else - _stprintf(result, _T_ECLIPSE("%s%s"), prefix, getOfficialName()); - return result; +/** + * Initializes variables/structures for dbus connectivity to org.eclipse.swt. + * Can be called multiple times, only first time initializes, other times just return early (1). + * + * DO NOT USE TO TEST CONNECTION. Use dbus_testConnection() instead. + * + * return: 0 (false) bug, something that shouldn't fail failed. This can happen if dynamic function calls failed or gdbus is not available etc.. + * 1 (true) proxy configured. + */ +gboolean gdbus_initProxy () { + if (gdbus_proxy != NULL) + return 1; // already initialized. + + // Function 'g_type_init()' is not needed anymore as of glib 2.36 as gtype system is initialized earlier. It is marked as deprecated. + // It is here because at the time of writing, eclipse supports glib 2.28. + // It is dynamic to prevent compile warning. But should be removed once min glib eclipse version >= 2.36 + gtk.g_type_init(); + + GError *error = NULL; // Some functions return errors through params + gdbus_proxy = gtk.g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL, GDBUS_SERVICE, GDBUS_OBJECT, GDBUS_INTERFACE, NULL, &error); + if ((gdbus_proxy == NULL) || (error != NULL)) { + fprintf(stderr, "Launcher error: GDBus proxy init failed to connect %s:%s on %s.\n", GDBUS_SERVICE, GDBUS_OBJECT, GDBUS_INTERFACE); + if (error != NULL) { + _ftprintf(stderr, "Launcher error: GDBus gdbus_proxy init failed for reason: %s\n", error->message); + gtk.g_error_free (error); + } + return 0; + } else { + return 1; + } } -static int setAppWindowPropertyFn() { - Window appWindow; - Atom propAtom; - _TCHAR *propVal; - - //Look for the SWT window. If it's there, set a property on it. - appWindow = gtk.XGetSelectionOwner(gtk_GDK_DISPLAY, appWindowAtom); - if (appWindow) { - propAtom = gtk.XInternAtom(gtk_GDK_DISPLAY, "org.eclipse.swt.filePath.message", FALSE); - //append a colon delimiter in case more than one file gets appended to the app windows property. - propVal = concatPaths(openFilePath, _T_ECLIPSE(':')); - gtk.XChangeProperty(gtk_GDK_DISPLAY, appWindow, propAtom, propAtom, 8, PropModeAppend, (unsigned char *)propVal, _tcslen(propVal)); - free(propVal); - windowPropertySet = 1; +/* + * Test if we can reach org.eclipse.swt dbus session. + * + * return 0 (false) No connection. + * 1 (true) org.eclipse.swt listens to calls. + */ +gboolean gdbus_testConnection() { + if (!gdbus_initProxy()) + return 0; + GError *error = NULL; // Some functions return errors through params + GVariant *result; // The value result from a call + result = gtk.g_dbus_proxy_call_sync(gdbus_proxy, "org.freedesktop.DBus.Peer.Ping", 0, G_DBUS_CALL_FLAGS_NONE, /* Proxy default timeout */ -1, NULL, &error); + if (error != NULL) { + gtk.g_error_free(error); + return 0; + } + if (result != NULL) { + gtk.g_variant_unref (result); return 1; } + _ftprintf(stderr, "ERROR: testConnection failed due to unknown reason. Bug in eclipseGtk.c? Potential cause could be dynamic function not initialized properly\n"); return 0; } -/* set the Application window property by executing _setWindowPropertyFn within a semaphore */ -int setAppWindowProperty() { - int result; - char * mutexName = createSWTWindowString(NULL, 1); - result = executeWithLock(mutexName, setAppWindowPropertyFn); - gtk.XSync(gtk_GDK_DISPLAY, False); - free(mutexName); - return result; -} - -/* timer callback function to call setAppWindowProperty */ -static gboolean setAppWindowTimerProc(gpointer data) { - //try to set the app window property. If unsuccessful return true to reschedule the timer. +/* + * Timer callback function. + * + * Try to pass files to eclipse. If eclipse not up yet, try again later. + * + * Timer ends when it returns false. (Files passed to eclipse or timeout). + */ +gboolean gdbus_FileOpen_TimerProc(gpointer data) { + if (openFileTimeout == 0) + return 0; // stop timer. openFileTimeout--; - return !setAppWindowProperty() && openFileTimeout > 0; -} - -int createLauncherWindow() { - Window window, launcherWindow; - //check if a launcher window exists. If none exists, we know we are the first and we should be launching the app. - window = gtk.XGetSelectionOwner(gtk_GDK_DISPLAY, launcherWindowAtom); - if (window == 0) { - //create a launcher window that other processes can find. - launcherWindow = gtk.XCreateWindow(gtk_GDK_DISPLAY, gtk.XRootWindow(gtk_GDK_DISPLAY, gtk.XDefaultScreen(gtk_GDK_DISPLAY)), -10, -10, 1, - 1, 0, 0, InputOnly, CopyFromParent, (unsigned long) 0, (XSetWindowAttributes *) NULL); - //for some reason Set and Get are both necessary. Set alone does nothing. - gtk.XSetSelectionOwner(gtk_GDK_DISPLAY, launcherWindowAtom, launcherWindow, CurrentTime); - gtk.XGetSelectionOwner(gtk_GDK_DISPLAY, launcherWindowAtom); - //add a timeout to set the property on the apps window once the app is launched. - gtk.g_timeout_add(1000, setAppWindowTimerProc, 0); - return 0; + if (gdbus_testConnection()) { + gdbus_call_FileOpen(); + filesPassedToSWT = 1; + return 0; // stop timer. } - return 1; + return 1; // run timer again. } -int reuseWorkbench(_TCHAR** filePath, int timeout) { - char *appName, *launcherName; - int result = 0; +/* + * Call fileOpen method in SWT. Note, in SWT, see GDBus.java. fileOpen GDBusMethod is defined in Display.java. + * This call can be called multiple times if Eclipse hasn't launched yet. + * + * Return: FALSE (0) Call did not work. Probably eclipse not fired up yet. (try again later) + * TRUE (1) GDBus call completed successfully. + */ +gboolean gdbus_call_FileOpen () { + if (!gdbus_initProxy()) + return 0; - if (initWindowSystem(&initialArgc, initialArgv, 1) != 0) - return -1; + // Construct GDBus arguments based on files passed into launcher. + GVariantBuilder *builder; + GVariant *paramaters; + builder = gtk.g_variant_builder_new ((const GVariantType *) "as"); // as = G_VARIANT_TYPE_STRING_ARRAY - openFileTimeout = timeout; - openFilePath = filePath; - - //App name is defined in SWT as well. Values must be consistent. - appName = createSWTWindowString(NULL, 0); - appWindowAtom = gtk.XInternAtom(gtk_GDK_DISPLAY, appName, FALSE); - free(appName); + int i = -1; + while (openFilePath[++i] != NULL) { + gtk.g_variant_builder_add (builder, (const gchar *) (const GVariantType *) "s", (const gchar *) openFilePath[i]); // s = G_VARIANT_TYPE_STRING + } - //check if app is already running. Just set property if it is. - if (setAppWindowProperty() > 0) - return 1; + paramaters = gtk.g_variant_new ("(as)", builder); + gtk.g_variant_builder_unref (builder); - /* app is not running, create a launcher window to act as a mutex so we don't need to keep the semaphore locked */ - launcherName = createSWTWindowString(_T_ECLIPSE("_Launcher"), 1); - launcherWindowAtom = gtk.XInternAtom(gtk_GDK_DISPLAY, launcherName, FALSE); - result = executeWithLock(launcherName, createLauncherWindow); - free(launcherName); - - if (result == 1) { - //The app is already being launched in another process. Set the property on that app window and exit - while (openFileTimeout > 0) { - if (setAppWindowProperty() > 0) - return 1; //success - else { - openFileTimeout--; - sleep(1); - } + // Send a message + GError *error = NULL; + GVariant *result; + result = gtk.g_dbus_proxy_call_sync(gdbus_proxy, "FileOpen", paramaters, G_DBUS_CALL_FLAGS_NONE, /* Proxy default timeout */ -1, NULL, &error); + if (error != NULL) { + gtk.g_error_free (error); + return 0; // did not work. Eclipse probably not up yet. Try again later. + } else { + if (result != NULL) { + // Because this not straight forward, below is an example of how to retrieve string return value if needed in the future. + // Note, arguments are packaged into a tuple because we deal with gdbus in dynamic way. + // gchar *str; + // g_variant_get(result, "(&s)", &str); + gtk.g_variant_unref(result); } - //timed out trying to set the app property - result = 0; + return 1; // worked. } - return result; } /* Get current scaling-factor */ -float scaleFactor () -{ +float scaleFactor () { float scaleFactor = 1; GdkScreen * screen; double resolution; @@ -238,9 +230,9 @@ float scaleFactor () scaleFactor = (float)(resolution / 96); return scaleFactor; } + /* Create and Display the Splash Window */ -int showSplash( const char* featureImage ) -{ +int showSplash( const char* featureImage ) { GtkWidget *image; GdkPixbuf *pixbuf, *scaledPixbuf; int width, height; @@ -284,7 +276,7 @@ int showSplash( const char* featureImage ) gtk.gtk_window_set_position((GtkWindow*)(shellHandle), GTK_WIN_POS_CENTER); gtk.gtk_window_resize((GtkWindow*)(shellHandle), gtk.gdk_pixbuf_get_width(scaledPixbuf), gtk.gdk_pixbuf_get_height(scaledPixbuf)); gtk.gtk_widget_show_all((GtkWidget*)(shellHandle)); - splashHandle = (long)shellHandle; + splashHandle = shellHandle; dispatchMessages(); return 0; } @@ -295,7 +287,7 @@ void dispatchMessages() { } jlong getSplashHandle() { - return splashHandle; + return (jlong) splashHandle; } void takeDownSplash() { @@ -308,8 +300,7 @@ void takeDownSplash() { } /* Get the window system specific VM arguments */ -char** getArgVM( char* vm ) -{ +char** getArgVM( char* vm ) { char** result; /* if (isJ9VM( vm )) @@ -320,8 +311,7 @@ char** getArgVM( char* vm ) return result; } -JavaResults* launchJavaVM( char* args[] ) -{ +JavaResults* launchJavaVM( char* args[] ) { JavaResults* jvmResults = NULL; pid_t jvmProcess, finishedProcess = 0; int exitCode; @@ -352,7 +342,9 @@ JavaResults* launchJavaVM( char* args[] ) sleepTime.tv_sec = 0; sleepTime.tv_nsec = 5e+8; // 500 milliseconds - while(openFileTimeout > 0 && !windowPropertySet && (finishedProcess = waitpid(jvmProcess, &exitCode, WNOHANG)) == 0) { + // Ensure we don't quit the launcher until gdbus_FileOpen_TimerProc() finished or timed out. + // If making any changes to this loop, ensure "./eclipse /myFile" still works. + while(openFileTimeout > 0 && !filesPassedToSWT && (finishedProcess = waitpid(jvmProcess, &exitCode, WNOHANG)) == 0) { dispatchMessages(); nanosleep(&sleepTime, NULL); } @@ -363,6 +355,5 @@ JavaResults* launchJavaVM( char* args[] ) /* TODO, this should really be a runResult if we could distinguish the launch problem above */ jvmResults->launchResult = WEXITSTATUS(exitCode); } - return jvmResults; } diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.h b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.h index 9d76885ea..6619515c3 100644 --- a/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.h +++ b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtk.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2016 IBM Corporation and others. + * Copyright (c) 2007, 2018 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -15,7 +15,7 @@ #include <gdk-pixbuf/gdk-pixbuf.h> #include <gdk/gdkx.h> -struct GTK_PTRS { +struct GTK_PTRS { short not_initialized; void (*gtk_container_add) (GtkContainer*, GtkWidget*); gint (*gtk_dialog_run) (GtkDialog *); @@ -37,13 +37,19 @@ struct GTK_PTRS { void (*g_object_unref) (gpointer); guint (*g_timeout_add) (guint, GSourceFunc, gpointer); void (*g_error_free) (GError *); - + void (*g_type_init) (); + GDBusProxy* (*g_dbus_proxy_new_for_bus_sync) (GBusType, GDBusProxyFlags, GDBusInterfaceInfo *, const gchar *,const gchar *, const gchar *, GCancellable *, GError **); + GVariant * (*g_dbus_proxy_call_sync) (GDBusProxy *, const gchar *, GVariant *, GDBusCallFlags, gint, GCancellable *, GError **); + GVariantBuilder * (*g_variant_builder_new) (const GVariantType *); + void (*g_variant_builder_add) (GVariantBuilder *, const gchar *, const gchar *); + GVariant * (*g_variant_new) (const gchar *, GVariantBuilder *); + void (*g_variant_builder_unref) (GVariantBuilder *); + void (*g_variant_unref) (GVariant *); #ifdef SOLARIS GString* (*g_string_insert_c) (GString *, gssize, gchar); #endif GdkDisplay* (*gdk_display_get_default) (); - Display* (*gdk_x11_display_get_xdisplay) (GdkDisplay*); GdkPixbuf* (*gdk_pixbuf_new_from_file) (const char*, GError **); GdkPixbuf* (*gdk_pixbuf_scale_simple) (const GdkPixbuf*, int, int, GdkInterpType); int (*gdk_pixbuf_get_width) (const GdkPixbuf*); @@ -51,17 +57,8 @@ struct GTK_PTRS { GdkScreen * (*gdk_screen_get_default) (); double (*gdk_screen_get_resolution) (GdkScreen *); - Window (*XGetSelectionOwner) (Display*, Atom); - void (*XSetSelectionOwner) (Display*, Atom, Window, Time); - void (*XChangeProperty) (Display*, Window, Atom, Atom, int, int, unsigned char *, int); - Window (*XCreateWindow) (Display*, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*); - void (*XSync) (Display*, Bool); - int (*XDefaultScreen) (Display*); - Window (*XRootWindow) (Display*, int); - Atom (*XInternAtom) (Display*, _Xconst char*, Bool ); }; -#define gtk_GDK_DISPLAY gtk.gdk_x11_display_get_xdisplay(gtk.gdk_display_get_default()) extern struct GTK_PTRS gtk; #define FN_TABLE_ENTRY(fn, required) { (void**)& gtk.fn, #fn, required } diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtkInit.c b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtkInit.c index ccfea8b54..25bcf14f4 100644 --- a/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtkInit.c +++ b/features/org.eclipse.equinox.executable.feature/library/gtk/eclipseGtkInit.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2016 IBM Corporation and others. + * Copyright (c) 2007, 2018 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -49,11 +49,25 @@ static FN_TABLE gtkFunctions[] = { /* functions from libgdk-x11-2.0 or libgdk-3.so.0*/ static FN_TABLE gdkFunctions[] = { FN_TABLE_ENTRY(gdk_display_get_default, 1), - FN_TABLE_ENTRY(gdk_x11_display_get_xdisplay, 1), FN_TABLE_ENTRY(gdk_screen_get_default, 1), FN_TABLE_ENTRY(gdk_screen_get_resolution, 1), { NULL, NULL } }; +/* functions from libgio-2.0.so.0*/ +static FN_TABLE gioFunctions[] = { + FN_TABLE_ENTRY(g_dbus_proxy_new_for_bus_sync, 1), + FN_TABLE_ENTRY(g_dbus_proxy_call_sync, 1), + { NULL, NULL } +}; +/* functions from libglib-2.0.so.0*/ +static FN_TABLE glibFunctions[] = { + FN_TABLE_ENTRY(g_variant_builder_new, 1), + FN_TABLE_ENTRY(g_variant_builder_add, 1), + FN_TABLE_ENTRY(g_variant_new, 1), + FN_TABLE_ENTRY(g_variant_builder_unref, 1), + FN_TABLE_ENTRY(g_variant_unref, 1), + { NULL, NULL } +}; /* functions from libgdk_pixbuf-2.0 */ static FN_TABLE pixFunctions[] = { FN_TABLE_ENTRY(gdk_pixbuf_new_from_file, 1), @@ -69,25 +83,13 @@ static FN_TABLE gobjFunctions[] = { FN_TABLE_ENTRY(g_object_unref, 1), FN_TABLE_ENTRY(g_timeout_add, 1), FN_TABLE_ENTRY(g_error_free, 1), + FN_TABLE_ENTRY(g_type_init, 1), #ifdef SOLARIS FN_TABLE_ENTRY(g_string_insert_c, 1), #endif { NULL, NULL } }; -/* functions from libX11 */ -static FN_TABLE x11Functions[] = { - FN_TABLE_ENTRY(XGetSelectionOwner, 1), - FN_TABLE_ENTRY(XSetSelectionOwner, 1), - FN_TABLE_ENTRY(XCreateWindow, 1), - FN_TABLE_ENTRY(XChangeProperty, 1), - FN_TABLE_ENTRY(XSync, 1), - FN_TABLE_ENTRY(XRootWindow, 1), - FN_TABLE_ENTRY(XDefaultScreen, 1), - FN_TABLE_ENTRY(XInternAtom, 1), - { NULL, NULL } -}; - static int loadGtkSymbols( void * library, FN_TABLE * table) { int i = 0; void * fn; @@ -122,7 +124,7 @@ int loadGtk() { /* Disable GTK scaling*/ setenv("GDK_SCALE", "1", 1); - void *gdkLib = NULL, *gtkLib = NULL, *objLib = NULL, *pixLib = NULL, *x11Lib = NULL; + void *gioLib = NULL, *glibLib = NULL, *gdkLib = NULL, *gtkLib = NULL, *objLib = NULL, *pixLib = NULL; char *gtk3 = getenv("SWT_GTK3"); if (gtk3 == NULL || strcmp(gtk3,"1") == 0) { @@ -167,15 +169,17 @@ int loadGtk() { objLib = dlopen(GOBJ_LIB, DLFLAGS); pixLib = dlopen(PIXBUF_LIB, DLFLAGS); - x11Lib = dlopen(X11_LIB, DLFLAGS); + gioLib = dlopen(GIO_LIB, DLFLAGS); + glibLib= dlopen(GLIB_LIB, DLFLAGS); memset(>k, 0, sizeof(struct GTK_PTRS)); if ( gtkLib == NULL || loadGtkSymbols(gtkLib, gtkFunctions) != 0) return -1; if ( gdkLib == NULL || loadGtkSymbols(gdkLib, gdkFunctions) != 0) return -1; + if ( gioLib == NULL || loadGtkSymbols(gdkLib, gioFunctions) != 0) return -1; + if ( glibLib == NULL || loadGtkSymbols(gdkLib, glibFunctions) != 0) return -1; if ( pixLib == NULL || loadGtkSymbols(pixLib, pixFunctions) != 0) return -1; if ( objLib == NULL || loadGtkSymbols(objLib, gobjFunctions) != 0) return -1; - if ( x11Lib == NULL || loadGtkSymbols(x11Lib, x11Functions) != 0) return -1; /* Initialize GTK. */ if (gtk.gtk_init_with_args) { @@ -205,16 +209,18 @@ int loadGtk() { objLib = dlopen(GOBJ_LIB, DLFLAGS); pixLib = dlopen(PIXBUF_LIB, DLFLAGS); - x11Lib = dlopen(X11_LIB, DLFLAGS); + gioLib = dlopen(GIO_LIB, DLFLAGS); + glibLib= dlopen(GLIB_LIB, DLFLAGS); /* initialize ptr struct to 0's */ memset(>k, 0, sizeof(struct GTK_PTRS)); if ( gtkLib == NULL || loadGtkSymbols(gtkLib, gtkFunctions) != 0) return -1; if ( gdkLib == NULL || loadGtkSymbols(gdkLib, gdkFunctions) != 0) return -1; + if ( gioLib == NULL || loadGtkSymbols(gdkLib, gioFunctions) != 0) return -1; + if ( glibLib == NULL || loadGtkSymbols(gdkLib, glibFunctions) != 0) return -1; if ( pixLib == NULL || loadGtkSymbols(pixLib, pixFunctions) != 0) return -1; if ( objLib == NULL || loadGtkSymbols(objLib, gobjFunctions) != 0) return -1; - if ( x11Lib == NULL || loadGtkSymbols(x11Lib, x11Functions) != 0) return -1; return 0; } diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/make_linux.mak b/features/org.eclipse.equinox.executable.feature/library/gtk/make_linux.mak index a1f0dc14a..1167a6329 100644 --- a/features/org.eclipse.equinox.executable.feature/library/gtk/make_linux.mak +++ b/features/org.eclipse.equinox.executable.feature/library/gtk/make_linux.mak @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2000, 2010 IBM Corporation and others. +# Copyright (c) 2000, 2018 IBM Corporation and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at @@ -41,12 +41,13 @@ DLL_OBJS = eclipse.o eclipseGtk.o eclipseUtil.o eclipseJNI.o eclipseShm.o eclips EXEC = $(PROGRAM_OUTPUT) DLL = $(PROGRAM_LIBRARY) -#LIBS = `pkg-config --libs-only-L gtk+-2.0` -lgtk-x11-2.0 -lgdk_pixbuf-2.0 -lgobject-2.0 -lgdk-x11-2.0 -lpthread -ldl -lX11 +#LIBS = `pkg-config --libs-only-L gtk+-2.0` -lgtk-x11-2.0 -lgdk_pixbuf-2.0 -lgobject-2.0 -lgdk-x11-2.0 -lpthread -ldl LIBS = -lpthread -ldl GTK_LIBS = \ -DGTK_LIB="\"libgtk-x11-2.0.so.0\"" -DGDK_LIB="\"libgdk-x11-2.0.so.0\"" \ -DGTK3_LIB="\"libgtk-3.so.0\"" -DGDK3_LIB="\"libgdk-3.so.0\"" \ - -DPIXBUF_LIB="\"libgdk_pixbuf-2.0.so.0\"" -DGOBJ_LIB="\"libgobject-2.0.so.0\"" -DX11_LIB="\"libX11.so.6\"" + -DPIXBUF_LIB="\"libgdk_pixbuf-2.0.so.0\"" -DGOBJ_LIB="\"libgobject-2.0.so.0\"" \ + -DGIO_LIB="\"libgio-2.0.so.0\"" -DGLIB_LIB="\"libglib-2.0.so.0\"" LFLAGS = ${M_ARCH} -shared -fpic -Wl,--export-dynamic CFLAGS = ${M_CFLAGS} ${M_ARCH} -g -s -Wall\ -fpic \ diff --git a/features/org.eclipse.equinox.executable.feature/library/gtk/makefile b/features/org.eclipse.equinox.executable.feature/library/gtk/makefile new file mode 100644 index 000000000..9cd1a6b8b --- /dev/null +++ b/features/org.eclipse.equinox.executable.feature/library/gtk/makefile @@ -0,0 +1,15 @@ +all: + ./build.sh + +clean: + ./build.sh clean + +# For devs: +# Convienience target to move the launcher and the relevant *.so into your development eclipse folder for testing/verification. +# Typically, you can download the latest integration build from here: http://download.eclipse.org/eclipse/downloads/, and use it as your dev eclipse. +devinstall: + # You should define "DEV_ECLIPSE" to be the directory of your testing eclipse, containing the 'eclipse' executable. + # I.e the output of 'pwd' (Note: without trailing forward slash). + # export DEV_ECLIPSE="/home/YOUR_USER/Downloads/eclipse-SDK-I20180115-2000-linux-gtk-x86_64/eclipse" + cp eclipse ${DEV_ECLIPSE}/ + cp eclipse_*.so ${DEV_ECLIPSE}/plugins/org.eclipse.equinox.launcher.gtk.linux.x86_*/ |