/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (c) 2014-2021 3Dconnexion. * * 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 3 of the License, or (at your * option) 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. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ /** * @file navlib_stub.c * @brief interface routines to the navlib library routines. */ /*----------------------------------------------------------------------------- * The module contains interface routines to the navlib library routines contained * in the associated Dynamic Link Library. The DLL is loaded explicitly when * NlLoadLibrary is invoked. When the DLL is loaded, the initialization routine * finds the addresses of the routines that it exposes and allows them to be used * in this code. */ #if _WIN32 /* windows */ #include #include #elif __APPLE__ #include #include #include #endif #ifndef EISCONN #define EISCONN 113 #define ENOBUFS 119 #define ENODATA 120 #define EOPNOTSUPP 130 #endif /* navlib */ #include /* library name */ #ifdef _WIN32 static const wchar_t* TheLibrary = L"TDxNavLib"; #elif __APPLE__ static const char* TheLibrary = "/Library/Frameworks/3DconnexionNavlib.framework/3DconnexionNavlib"; #endif /* Names of functions contained in the framework used to find their addresses at load time */ static const char* cNlCreate = "NlCreate"; static const char* cNlClose = "NlClose"; static const char* cNlReadValue = "NlReadValue"; static const char* cNlWriteValue = "NlWriteValue"; static const char* cNlGetType = "NlGetType"; typedef long( __cdecl* PFN_NLCREATE )( nlHandle_t* pnh, const char* appname, const accessor_t accessors[], size_t accessor_count, nlCreateOptions_t const* options ); typedef long( __cdecl* PFN_NLCLOSE )( nlHandle_t nh ); typedef long( __cdecl* PFN_NLREADVALUE )( nlHandle_t nh, property_t name, value_t* value ); typedef long( __cdecl* PFN_NLWRITEVALUE )( nlHandle_t nh, property_t name, const value_t* value ); typedef propertyType_t( __cdecl* PFN_NLGETTYPE )( property_t name ); /* Function pointers to functions in DLL */ static PFN_NLCREATE pfnNlCreate = NULL; static PFN_NLCLOSE pfnNlClose = NULL; static PFN_NLREADVALUE pfnNlReadValue = NULL; static PFN_NLWRITEVALUE pfnNlWriteValue = NULL; static PFN_NLGETTYPE pfnNlGetType = NULL; extern long NlErrorCode; #if _WIN32 long NlLoadLibrary() { long error = 0; HMODULE h = LoadLibrary( TheLibrary ); if( !h ) { error = HRESULT_FROM_WIN32( GetLastError() ); } else { /* load up the function pointer table */ if( ( ( pfnNlCreate = (PFN_NLCREATE) GetProcAddress( h, cNlCreate ) ) == NULL ) || ( ( pfnNlClose = (PFN_NLCLOSE) GetProcAddress( h, cNlClose ) ) == NULL ) || ( ( pfnNlReadValue = (PFN_NLREADVALUE) GetProcAddress( h, cNlReadValue ) ) == NULL ) || ( ( pfnNlWriteValue = (PFN_NLWRITEVALUE) GetProcAddress( h, cNlWriteValue ) ) == NULL ) || ( ( pfnNlGetType = (PFN_NLGETTYPE) GetProcAddress( h, cNlGetType ) ) == NULL ) ) { error = HRESULT_FROM_WIN32( GetLastError() ); FreeLibrary( h ); h = NULL; } } return error; } #elif __APPLE__ long NlLoadLibrary() { long error = 0; void* libHandle = dlopen( TheLibrary, RTLD_LAZY | RTLD_LOCAL ); if( NULL == libHandle ) { error = -1; // whatever error it's an error dlopen() does not set errno #if 0 fprintf( stderr, "Error: Failed to open library \"%s\"! Error: %s!\n", TheLibrary, dlerror() ); #endif } else { /* load up the function pointer table */ if( ( ( pfnNlCreate = (PFN_NLCREATE) dlsym( libHandle, cNlCreate ) ) == NULL ) || ( ( pfnNlClose = (PFN_NLCLOSE) dlsym( libHandle, cNlClose ) ) == NULL ) || ( ( pfnNlReadValue = (PFN_NLREADVALUE) dlsym( libHandle, cNlReadValue ) ) == NULL ) || ( ( pfnNlWriteValue = (PFN_NLWRITEVALUE) dlsym( libHandle, cNlWriteValue ) ) == NULL ) || ( ( pfnNlGetType = (PFN_NLGETTYPE) dlsym( libHandle, cNlGetType ) ) == NULL ) ) { error = -2; // whatever error it is - it's an error dlsym() does not set errno #if 0 fprintf( stderr, "Error: Failed to fetch symbols from \"%s\"! Error: %s!\n", TheLibrary, dlerror() ); #endif dlclose( libHandle ); libHandle = NULL; } } return error; } #else long NlLoadLibrary() { return EOPNOTSUPP; } #endif long __cdecl NlCreate( nlHandle_t* pnh, const char* appname, const accessor_t accessors[], size_t accessor_count, const nlCreateOptions_t* options ) { if( pfnNlCreate ) { return pfnNlCreate( pnh, appname, accessors, accessor_count, options ); } return NlErrorCode; } long __cdecl NlClose( nlHandle_t nh ) { if( pfnNlClose ) { return pfnNlClose( nh ); } return NlErrorCode; } long __cdecl NlReadValue( nlHandle_t nh, property_t name, value_t* value ) { if( pfnNlReadValue ) { return pfnNlReadValue( nh, name, value ); } return NlErrorCode; } long __cdecl NlWriteValue( nlHandle_t nh, property_t name, const value_t* value ) { if( pfnNlWriteValue ) { return pfnNlWriteValue( nh, name, value ); } return NlErrorCode; } propertyType_t __cdecl NlGetType( property_t name ) { if( pfnNlGetType ) { return pfnNlGetType( name ); } return unknown_type; }