Merge pull request #79 from ianrrees/20160123-3dconnexion-mac-bundle
Fixes issue with Mac bundles and 3Dconnexion drivers
This commit is contained in:
commit
4c3782ff96
|
@ -73,18 +73,14 @@ Gui::GUIApplicationNativeEventAware::~GUIApplicationNativeEventAware()
|
|||
#endif
|
||||
//mac
|
||||
#ifdef Q_WS_MACX
|
||||
/* make sure the framework is installed */
|
||||
if (InstallConnexionHandlers == NULL)
|
||||
{
|
||||
Base::Console().Log("3Dconnexion framework not found!\n");
|
||||
return;
|
||||
}
|
||||
/* close the connection with the 3dx driver */
|
||||
//std::cerr << "tdxClientID: " << tdxClientID << std::endl;
|
||||
if (tdxClientID)
|
||||
UnregisterConnexionClient(tdxClientID);
|
||||
CleanupConnexionHandlers();
|
||||
Base::Console().Log("Disconnected from 3DConnexion driver\n");
|
||||
// if 3Dconnexion library was loaded at runtime
|
||||
if (InstallConnexionHandlers) {
|
||||
// Close our connection with the 3dx driver
|
||||
if (tdxClientID)
|
||||
UnregisterConnexionClient(tdxClientID);
|
||||
CleanupConnexionHandlers();
|
||||
Base::Console().Log("Disconnected from 3Dconnexion driver\n");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
@ -123,33 +119,33 @@ void Gui::GUIApplicationNativeEventAware::initSpaceball(QMainWindow *window)
|
|||
OSStatus err;
|
||||
/* make sure the framework is installed */
|
||||
if (InstallConnexionHandlers == NULL)
|
||||
{
|
||||
{
|
||||
Base::Console().Log("3Dconnexion framework not found!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* install 3dx message handler in order to receive driver events */
|
||||
err = InstallConnexionHandlers(tdx_drv_handler, 0L, 0L);
|
||||
assert(err == 0);
|
||||
if (err)
|
||||
{
|
||||
{
|
||||
Base::Console().Log("Error installing 3Dconnexion handler\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* register our app with the driver */
|
||||
//Pascal string Application name required to register driver for application
|
||||
// Pascal string Application name required to register driver for application
|
||||
UInt8 tdxAppName[] = {7,'F','r','e','e','C','A','D'};
|
||||
//32bit appID to register driver for application
|
||||
// 32bit appID to register driver for application
|
||||
UInt32 tdxAppID = 'FCAd';
|
||||
//std::cerr << "tdxClientID: " << tdxClientID << std::endl;
|
||||
tdxClientID = RegisterConnexionClient(tdxAppID, tdxAppName, kConnexionClientModeTakeOver, kConnexionMaskAll);
|
||||
//std::cerr << "tdxClientID: " << tdxClientID << std::endl;
|
||||
tdxClientID = RegisterConnexionClient( tdxAppID, tdxAppName,
|
||||
kConnexionClientModeTakeOver,
|
||||
kConnexionMaskAll );
|
||||
if (tdxClientID == 0)
|
||||
{
|
||||
{
|
||||
Base::Console().Log("Couldn't connect to 3Dconnexion driver\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Base::Console().Log("3Dconnexion device initialized. Client ID: %d\n", tdxClientID);
|
||||
Base::Console().Log("3Dconnexion driver initialized. Client ID: %d\n", tdxClientID);
|
||||
spaceballPresent = true;
|
||||
#endif
|
||||
#endif // _USE_3DCONNEXION_SDK
|
||||
|
|
|
@ -46,9 +46,14 @@ class QMainWindow;
|
|||
#ifdef Q_WS_MACX
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <ConnexionClientAPI.h>
|
||||
extern OSErr InstallConnexionHandlers(ConnexionMessageHandlerProc messageHandler, ConnexionAddedHandlerProc addedHandler, ConnexionRemovedHandlerProc removedHandler)
|
||||
__attribute__((weak_import));
|
||||
extern UInt16 RegisterConnexionClient(UInt32 signature, UInt8 *name, UInt16 mode, UInt32 mask) __attribute__((weak_import));
|
||||
// Note that InstallConnexionHandlers will be replaced with
|
||||
// SetConnexionHandlers "in the future".
|
||||
extern OSErr InstallConnexionHandlers(ConnexionMessageHandlerProc messageHandler,
|
||||
ConnexionAddedHandlerProc addedHandler,
|
||||
ConnexionRemovedHandlerProc removedHandler)
|
||||
__attribute__((weak_import));
|
||||
extern UInt16 RegisterConnexionClient(UInt32 signature, UInt8 *name, UInt16 mode,
|
||||
UInt32 mask) __attribute__((weak_import));
|
||||
extern void UnregisterConnexionClient(UInt16 clientID) __attribute__((weak_import));
|
||||
extern void CleanupConnexionHandlers(void) __attribute__((weak_import));
|
||||
#endif // Q_WS_MACX
|
||||
|
@ -129,12 +134,14 @@ namespace Gui
|
|||
#endif // Q_WS_WIN
|
||||
#ifdef Q_WS_MACX
|
||||
private:
|
||||
static UInt16 tdxClientID; /* ID assigned by the driver */
|
||||
static uint32_t lastButtons;
|
||||
static UInt16 tdxClientID; /* ID assigned by the driver */
|
||||
static uint32_t lastButtons;
|
||||
public:
|
||||
static void tdx_drv_handler(io_connect_t connection, natural_t messageType, void *messageArgument);
|
||||
void Move3d();
|
||||
void Button3d(bool buttonDown, int buttonNumber);
|
||||
static void tdx_drv_handler( io_connect_t connection,
|
||||
natural_t messageType,
|
||||
void *messageArgument );
|
||||
void Move3d();
|
||||
void Button3d(bool buttonDown, int buttonNumber);
|
||||
|
||||
#endif// Q_WS_MACX
|
||||
#endif // _USE_3DCONNEXION_SDK
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
from subprocess import Popen, PIPE, check_call, check_output
|
||||
import pprint
|
||||
import re
|
||||
|
||||
SYS_PATHS = ["/System/", "/usr/lib/"]
|
||||
SYS_PATHS = ["/System/", "/usr/lib/", "/Library/Frameworks/"]
|
||||
|
||||
class LibraryNotFound(Exception):
|
||||
pass
|
||||
|
@ -63,8 +64,9 @@ class DepsGraph:
|
|||
stack.append(ck)
|
||||
operation(self, self.graph[node_key], *op_args)
|
||||
|
||||
|
||||
def is_macho(path):
|
||||
output = subprocess.check_output(["file", path])
|
||||
output = check_output(["file", path])
|
||||
if output.count("Mach-O") != 0:
|
||||
return True
|
||||
|
||||
|
@ -83,7 +85,7 @@ def get_path(name, search_paths):
|
|||
return None
|
||||
|
||||
def list_install_names(path_macho):
|
||||
output = subprocess.check_output(["otool", "-L", path_macho])
|
||||
output = check_output(["otool", "-L", path_macho])
|
||||
lines = output.split("\t")
|
||||
libs = []
|
||||
|
||||
|
@ -129,7 +131,7 @@ def create_dep_nodes(install_names, search_paths):
|
|||
path = get_path(lib_name, search_paths)
|
||||
|
||||
if install_path != "" and lib[0] != "@":
|
||||
#we have an absolte path install name
|
||||
#we have an absolute path install name
|
||||
if not path:
|
||||
path = install_path
|
||||
|
||||
|
@ -148,7 +150,6 @@ def paths_at_depth(prefix, paths, depth):
|
|||
filtered.append(p)
|
||||
return filtered
|
||||
|
||||
|
||||
def should_visit(prefix, path_filters, path):
|
||||
s_path = path.strip('/').split('/')
|
||||
filters = []
|
||||
|
@ -227,14 +228,44 @@ def in_bundle(lib, bundle_path):
|
|||
|
||||
def copy_into_bundle(graph, node, bundle_path):
|
||||
if not in_bundle(node.path, bundle_path):
|
||||
subprocess.check_call(["cp", "-L", os.path.join(node.path, node.name),
|
||||
os.path.join(bundle_path, "lib", node.name)])
|
||||
check_call([ "cp", "-L", os.path.join(node.path, node.name),
|
||||
os.path.join(bundle_path, "lib", node.name) ])
|
||||
|
||||
node.path = os.path.join(bundle_path, "lib")
|
||||
|
||||
#fix permissions
|
||||
subprocess.check_call(["chmod", "a+w", os.path.join(bundle_path,
|
||||
"lib", node.name)])
|
||||
|
||||
check_call([ "chmod", "a+w",
|
||||
os.path.join(bundle_path, "lib", node.name) ])
|
||||
|
||||
def get_rpaths(library):
|
||||
"Returns a list of rpaths specified within library"
|
||||
|
||||
out = check_output(["otool", "-l", library])
|
||||
|
||||
pathRegex = r"^path (.*) \(offset \d+\)$"
|
||||
expectingRpath = False
|
||||
rpaths = []
|
||||
for line in out.split('\n'):
|
||||
line = line.strip()
|
||||
|
||||
if "cmd LC_RPATH" in line:
|
||||
expectingRpath = True
|
||||
continue
|
||||
|
||||
if "Load command" in line:
|
||||
expectingRpath = False
|
||||
continue
|
||||
|
||||
if not expectingRpath:
|
||||
continue
|
||||
|
||||
m = re.match(pathRegex, line)
|
||||
if m:
|
||||
rpaths.append(m.group(1))
|
||||
expectingRpath = False
|
||||
|
||||
return rpaths
|
||||
|
||||
def add_rpaths(graph, node, bundle_path):
|
||||
if node.children:
|
||||
lib = os.path.join(node.path, node.name)
|
||||
|
@ -245,8 +276,8 @@ def add_rpaths(graph, node, bundle_path):
|
|||
for install_name in install_names:
|
||||
name = os.path.basename(install_name)
|
||||
#change install names to use rpaths
|
||||
subprocess.check_call(["install_name_tool", "-change",
|
||||
install_name, "@rpath/" + name, lib])
|
||||
check_call([ "install_name_tool", "-change",
|
||||
install_name, "@rpath/" + name, lib ])
|
||||
|
||||
dep_node = node.children[node.children.index(name)]
|
||||
rel_path = os.path.relpath(graph.get_node(dep_node).path,
|
||||
|
@ -258,8 +289,12 @@ def add_rpaths(graph, node, bundle_path):
|
|||
rpath = "@loader_path/" + rel_path + "/"
|
||||
if rpath not in rpaths:
|
||||
rpaths.append(rpath)
|
||||
for path in rpaths:
|
||||
subprocess.call(["install_name_tool", "-add_rpath", path, lib])
|
||||
|
||||
for rpath in rpaths:
|
||||
# Ensure that lib has rpath set
|
||||
if not rpath in get_rpaths(lib):
|
||||
check_output([ "install_name_tool",
|
||||
"-add_rpath", rpath, lib ])
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
|
|
Loading…
Reference in New Issue
Block a user