1/* @configure_input@ */ 2 3/*---------------------------------------------------------------------- 4 * (C) 1998-2009 3Dconnexion. All rights reserved. 5 * Permission to use, copy, modify, and distribute this software for all 6 * purposes and without fees is hereby grated provided that this copyright 7 * notice appears in all copies. Permission to modify this software is granted 8 * and 3Dconnexion will support such modifications only is said modifications are 9 * approved by 3Dconnexion. 10 * 11 */ 12/* 13 * The module contains interface routines to the Si library routines contained 14 * in the associated Dynamic Link Library. The DLL is loaded explicitly when 15 * Si is initialized. When the DLL is loaded, the initialization routine finds 16 * the addresses of the routines that it exposes to the world. Once this is 17 * done the library routines are used as if they were part of the original 18 * source code. 19 */ 20 21#ifdef HAVE_CONFIG_H 22#include <config.h> 23#endif /* HAVE_CONFIG_H */ 24 25#ifdef HAVE_WIN32_API /* Only compile this file when the Win32 API is available */ 26 27#define SPW_DEFINE_COPYRIGHT 28#define SPW_DEFINE_GLOBALS 29 30#include <windows.h> 31#include <Inventor/@Gui@/devices/spwinput_win32.h> 32 33 34/* DLL library name */ 35 36static LPCTSTR DllLibrary = "siappdll"; 37 38 39/* names of DLL variables used in DLL */ 40 41static LPCSTR strDLLRetVal = "SpwErrorVal"; 42 43/*typedef enum SpwRetVal SpwReturnValue;*/ 44/* Names of functions contained in DLL; used to find their addresses at load 45 time */ 46 47static LPCSTR fnSiBeep = "SiBeep"; 48static LPCSTR fnSiInitialize = "SiInitialize"; 49static LPCSTR fnSiTerminate = "SiTerminate"; 50static LPCSTR fnSiGetDeviceID = "SiGetDeviceID"; 51static LPCSTR fnSiGetNumDevices = "SiGetNumDevices"; 52static LPCSTR fnSiDeviceIndex = "SiDeviceIndex"; 53static LPCSTR fnSiDispatch = "SiDispatch"; 54static LPCSTR fnSiIsSpaceWareEvent = "SiIsSpaceWareEvent"; 55static LPCSTR fnSiOpenWinInit = "SiOpenWinInit"; 56static LPCSTR fnSiOpen = "SiOpen"; 57static LPCSTR fnSiClose = "SiClose"; 58static LPCSTR fnSiGetEventWinInit = "SiGetEventWinInit"; 59static LPCSTR fnSiGetEvent = "SiGetEvent"; 60static LPCSTR fnSiRezero = "SiRezero"; 61static LPCSTR fnSiGrabDevice = "SiGrabDevice"; 62static LPCSTR fnSiReleaseDevice = "SiReleaseDevice"; 63static LPCSTR fnSiButtonPressed = "SiButtonPressed"; 64static LPCSTR fnSiButtonReleased = "SiButtonReleased"; 65static LPCSTR fnSiSetUIMode = "SiSetUiMode"; 66static LPCSTR fnSiGetDevicePort = "SiGetDevicePort"; 67static LPCSTR fnSiGetDriverInfo = "SiGetDriverInfo"; 68static LPCSTR fnSiGetLibraryInfo = "SiGetLibraryInfo"; 69static LPCSTR fnSiGetDeviceInfo = "SiGetDeviceInfo"; 70static LPCSTR fnSpwErrorString = "SpwErrorString"; 71 72/* DLL initialization status */ 73static enum InitResult gInitStatus = NOT_LOADED; 74 75/* DLL handle */ 76HINSTANCE ghDll; 77enum SpwRetVal SpwErrorVal; 78 79/* Device handle */ 80SiHdl Spw_DeviceHandle = SI_NO_HANDLE; 81 82/* Check to see if we can open a device handle to the spaceball */ 83int SPW_SpaceBallExistsWin32(void) 84{ 85 SiOpenData oData; 86 SiOpenWinInit(&oData,NULL); 87 return (SiOpen("", SI_ANY_DEVICE, SI_NO_MASK, SI_EVENT, &oData) != SI_NO_HANDLE) ? TRUE : FALSE; 88} 89 90/* check if can open a handle to the spaceball, load the driver functions 91 and start receiving input from the spaceball */ 92int SPW_CheckForSpaceballWin32(void * win) 93{ 94 char classname[25]; 95 SiOpenData oData; 96 97 if (Spw_DeviceHandle == SI_NO_HANDLE) { 98 if (SiInitialize() != SPW_DLL_LOAD_ERROR) { 99 GetClassName((HWND)win, classname, sizeof(classname)); 100 SiOpenWinInit(&oData, (HWND)win); 101 102 Spw_DeviceHandle = SiOpen(classname, SI_ANY_DEVICE, SI_NO_MASK, SI_EVENT, &oData); 103 104 if (Spw_DeviceHandle != SI_NO_HANDLE) { 105 SiSetUiMode(Spw_DeviceHandle, SI_UI_ALL_CONTROLS); 106 return TRUE; 107 } 108 else { 109 SiTerminate(); 110 return FALSE; 111 } 112 } 113 else return FALSE; 114 } 115 else return TRUE; 116} 117 118/* translates a Win32 event to a SPW_InputEvent. */ 119int SPW_TranslateEventWin32(MSG * msg, SPW_InputEvent * sbEvent) 120{ 121 SiSpwEvent spwEvent; 122 SiGetEventData eventdata; 123 124 if (Spw_DeviceHandle != SI_NO_HANDLE) { 125 126 SiGetEventWinInit (&eventdata, msg->message, msg->wParam, msg->lParam); 127 if (SiGetEvent (Spw_DeviceHandle, 0, &eventdata, &spwEvent) == SI_IS_EVENT) { 128 129 int i; 130 switch(spwEvent.type) { 131 case SI_MOTION_EVENT: 132 sbEvent->type = SPW_InputMotionEvent; 133 for(i=0; i<6; i++) { 134 sbEvent->sData[i] = (short)spwEvent.u.spwData.mData[i]; 135 } 136 break; 137 case SI_BUTTON_EVENT: 138 sbEvent->type = SPW_InputButtonPressEvent; 139 sbEvent->buttonState.pressed = (SiButtonPressed(&spwEvent) != SI_NO_BUTTON); 140 sbEvent->buttonState.released = (SiButtonReleased(&spwEvent) != SI_NO_BUTTON); 141 break; 142 } 143 return TRUE; 144 } 145 } 146 return FALSE; 147} 148 149/* Stop receiving input from the spaceball */ 150void SPW_disableSpaceBallWin32(void) 151{ 152 SiClose(Spw_DeviceHandle); 153 SiTerminate(); 154 Spw_DeviceHandle = SI_NO_HANDLE; 155} 156 157 158/*----------------------------------------------------------------------------- 159 * 160 * void __SiAppInitialize(void) 161 * 162 * Args: 163 * None 164 * 165 * Return Value: 166 * None 167 * 168 * Description: 169 * This function opens up the DLL library and, if successful, loads a 170 * function pointer table with exported UAPI functions contained in the DLL. 171 * 172 *---------------------------------------------------------------------------*/ 173int __SiAppInitialize(void) 174{ 175 enum InitResult nResult; /* intialization result code */ 176 enum ErrorCode nErrorCode; /* function return code */ 177 178 /* attempt to load the DLL */ 179 if ((ghDll = LoadLibrary (DllLibrary)) != NULL) 180 { 181 /* preset variables and hope for success */ 182 nResult = LOADED; 183 nErrorCode = NO_DLL_ERROR; 184 185 /* load up the global variable used by the DLL to return error info */ 186 187 if ((pDllSpwRetVal = (enum SpwRetVal *) 188 GetProcAddress(ghDll, strDLLRetVal)) == NULL) 189 { 190 nResult = FAILED; 191 nErrorCode = DLL_VAR_LOAD_FAILURE; 192 } 193 194 /* load up function pointer table */ 195 if ((pfnSiBeep = (PFNSI_BEEP) 196 GetProcAddress(ghDll, fnSiBeep)) == NULL) 197 { 198 nResult = FAILED; 199 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 200 } 201 202 if ((pfnSiInit = (PFNSI_INIT) 203 GetProcAddress(ghDll, fnSiInitialize)) == NULL) 204 { 205 nResult = FAILED; 206 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 207 } 208 209 if ((pfnSiTerminate = (PFNSI_TERMINATE) 210 GetProcAddress(ghDll, fnSiTerminate)) == NULL) 211 { 212 nResult = FAILED; 213 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 214 } 215 216 if ((pfnSiGetNumDevices = (PFNSI_GETNUMDEVICES) 217 GetProcAddress(ghDll, fnSiGetNumDevices)) == NULL) 218 { 219 nResult = FAILED; 220 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 221 } 222 223 if ((pfnSiGetDeviceID = (PFNSI_GETDEVICEID) 224 GetProcAddress(ghDll, fnSiGetDeviceID)) == NULL) 225 { 226 nResult = FAILED; 227 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 228 } 229 230 if ((pfnSiDeviceIndex = (PFNSI_DEVICEINDEX) 231 GetProcAddress(ghDll, fnSiDeviceIndex)) == NULL) 232 { 233 nResult = FAILED; 234 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 235 } 236 237 if ((pfnSiDispatch = (PFNSI_DISPATCH) 238 GetProcAddress(ghDll, fnSiDispatch)) == NULL) 239 { 240 nResult = FAILED; 241 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 242 } 243 244 if ((pfnSiOpenWinInit = (PFNSI_OPENWININIT) 245 GetProcAddress(ghDll, fnSiOpenWinInit)) == NULL) 246 { 247 nResult = FAILED; 248 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 249 } 250 251 if ((pfnSiOpen = (PFNSI_OPEN) 252 GetProcAddress(ghDll, fnSiOpen)) == NULL) 253 { 254 nResult = FAILED; 255 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 256 } 257 258 if ((pfnSiClose = (PFNSI_CLOSE) 259 GetProcAddress(ghDll, fnSiClose)) == NULL) 260 { 261 nResult = FAILED; 262 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 263 } 264 265 if ((pfnSiGetEventWinInit = (PFNSI_GETEVENTWININIT) 266 GetProcAddress(ghDll, fnSiGetEventWinInit)) == NULL) 267 { 268 nResult = FAILED; 269 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 270 } 271 272 if ((pfnSiIsSpaceWareEvent = (PFNSI_ISSPACEWAREEVENT) 273 GetProcAddress(ghDll, fnSiIsSpaceWareEvent)) == NULL) 274 { 275 nResult = FAILED; 276 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 277 } 278 279 if ((pfnSiGetEvent = (PFNSI_GETEVENT) 280 GetProcAddress(ghDll, fnSiGetEvent)) == NULL) 281 { 282 nResult = FAILED; 283 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 284 } 285 286 if ((pfnSiRezero = (PFNSI_REZERO) 287 GetProcAddress(ghDll, fnSiRezero)) == NULL) 288 { 289 nResult = FAILED; 290 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 291 } 292 293 if ((pfnSiGrabDevice = (PFNSI_GRABDEVICE) 294 GetProcAddress(ghDll, fnSiGrabDevice)) == NULL) 295 { 296 nResult = FAILED; 297 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 298 } 299 300 if ((pfnSiReleaseDevice = (PFNSI_RELEASEDEVICE) 301 GetProcAddress(ghDll, fnSiReleaseDevice)) == NULL) 302 { 303 nResult = FAILED; 304 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 305 } 306 307 if ((pfnSiButtonPressed = (PFNSI_BUTTONPRESSED) 308 GetProcAddress(ghDll, fnSiButtonPressed)) == NULL) 309 { 310 nResult = FAILED; 311 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 312 } 313 314 if ((pfnSiButtonReleased = (PFNSI_BUTTONRELEASED) 315 GetProcAddress(ghDll, fnSiButtonReleased)) == NULL) 316 { 317 nResult = FAILED; 318 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 319 } 320 321 if ((pfnSiSetUiMode = (PFNSI_SETUIMODE) 322 GetProcAddress(ghDll, fnSiSetUIMode)) == NULL) 323 { 324 nResult = FAILED; 325 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 326 } 327 328 if ((pfnSiGetDevicePort = (PFNSI_GETDEVICEPORT) 329 GetProcAddress(ghDll, fnSiGetDevicePort)) == NULL) 330 { 331 nResult = FAILED; 332 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 333 } 334 335 if ((pfnSiGetDriverInfo = (PFNSI_GETDRIVERINFO) 336 GetProcAddress(ghDll, fnSiGetDriverInfo)) == NULL) 337 { 338 nResult = FAILED; 339 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 340 } 341 342 if ((pfnSiGetLibraryInfo = (PFNSI_GETLIBRARYINFO) 343 GetProcAddress(ghDll, fnSiGetLibraryInfo)) == NULL) 344 { 345 nResult = FAILED; 346 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 347 } 348 349 if ((pfnSiGetDeviceInfo = (PFNSI_GETDEVICEINFO) 350 GetProcAddress(ghDll, fnSiGetDeviceInfo)) == NULL) 351 { 352 nResult = FAILED; 353 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 354 } 355 356 if ((pfnSpwErrorString = (PFNSPW_ERRORSTRING) 357 GetProcAddress(ghDll, fnSpwErrorString)) == NULL) 358 { 359 nResult = FAILED; 360 nErrorCode = DLL_FUNCTION_LOAD_FAILURE; 361 } 362 } 363 else /* couldn't load DLL */ 364 { 365 nResult = FAILED; 366 nErrorCode = DLL_LOAD_FAILURE; 367 } 368 369 /* set the global variable */ 370 371 gInitStatus = nResult; 372 373 return nErrorCode; 374} 375 376 377/*----------------------------------------------------------------------------- 378 * 379 * enum SpwRetVal SiInitialize (void) 380 * 381 * Args: 382 * 383 * Return Value: 384 * SPW_NO_ERROR No error 385 * SPW_ERROR Initialization error 386 * 387 * Description: 388 * This function initializes the SpaceWare input library. Since most input 389 * functions require that the library be initialized, this function should 390 * be called before any other input functions are called. 391 * 392 *---------------------------------------------------------------------------*/ 393 394enum SpwRetVal 395SiInitialize(void) 396{ 397 enum SpwRetVal tmpRetVal; /* temporary return value */ 398 399 if (gInitStatus != LOADED) 400 { 401 __SiAppInitialize(); 402 if (gInitStatus == FAILED) 403 { 404 return SPW_DLL_LOAD_ERROR; 405 } 406 } 407 408 tmpRetVal = pfnSiInit(); 409 SpwErrorVal = *pDllSpwRetVal; 410 return tmpRetVal; 411} 412 413/*----------------------------------------------------------------------------- 414 * 415 * void SiTerminate (void) 416 * 417 * Args: 418 * None 419 * 420 * Return Value: 421 * None 422 * 423 * Description: 424 * This function must be called to properly shut down the SpaceWare input 425 * library. No other input functions (except SiInit) should be called 426 * afterwards. 427 * 428 *---------------------------------------------------------------------------*/ 429 430void 431SiTerminate(void) 432{ 433 /* It is unlikely that the function table will not have been loaded by the 434 time this is called, but we'll cover the bases anyhow */ 435 if (gInitStatus != LOADED) 436 { 437 SiInitialize(); 438 if (gInitStatus == FAILED) 439 { 440 SpwErrorVal = SPW_DLL_LOAD_ERROR; /* global variable */ 441 return; 442 } 443 444 /* if we weren't returning void, we'd do error handling here */ 445 } 446 447 pfnSiTerminate(); 448 SpwErrorVal = *pDllSpwRetVal; 449 450 /* Unload the DLL to prevent memory leaks */ 451 FreeLibrary(ghDll); 452 453 /* change status in case someone reinitializes */ 454 gInitStatus = NOT_LOADED; 455} 456 457/*----------------------------------------------------------------------------- 458 * 459 * int SiGetNumDevices (void) 460 * 461 * Args: 462 * 463 * Return Value: 464 * If the SpaceWare input library is initialized, the number of devices is 465 * returned and SpwErrorVal is set to SPW_NO_ERROR. Otherwise, the return 466 * code is -1 and SpwErrorVal is set to either SI_UNINITIALIZED or one of 467 * the other standard error codes. 468 * 469 * Description: 470 * This function returns the number of input devices detected by the 471 * driver. 472 * 473 *---------------------------------------------------------------------------*/ 474 475int 476SiGetNumDevices (void) 477{ 478 int tmpRetVal; /* temporary return value */ 479 480 if (gInitStatus != LOADED) 481 { 482 SiInitialize(); 483 if (gInitStatus == FAILED) 484 { 485 SpwErrorVal = SPW_DLL_LOAD_ERROR; /* global variable */ 486 return -1; 487 } 488 } 489 490 tmpRetVal = pfnSiGetNumDevices(); 491 SpwErrorVal = *pDllSpwRetVal; 492 return tmpRetVal; 493} 494 495/*----------------------------------------------------------------------------- 496 * 497 * SiDevID SiGetDeviceID (SiHdl hdl) 498 * 499 * Args: 500 * hdl (r/o) SpaceWare handle 501 * 502 * Return Value: 503 * If there is no error, the device ID is returned and SpwErrorVal is set 504 * to SPW_NO_ERROR. Otherwise, the return value is SI_NO_DEVICE and 505 * SpwErrorVal is set to either SI_BAD_HANDLE (if the SpaceWare handle is 506 * invalid) or one of the other standard error codes. 507 * 508 * Description: 509 * Given a SpaceWare handle, this function returns the ID of the 510 * associated device. 511 * 512 *---------------------------------------------------------------------------*/ 513 514SiDevID 515SiGetDeviceID (SiHdl hdl) 516{ 517 SiDevID tmpRetVal; /* temporary return value */ 518 519 if (gInitStatus != LOADED) 520 { 521 SiInitialize(); 522 if (gInitStatus == FAILED) 523 { 524 SpwErrorVal = SPW_DLL_LOAD_ERROR; /* global variable */ 525 return SI_NO_DEVICE; 526 } 527 } 528 529 tmpRetVal = pfnSiGetDeviceID(hdl); 530 SpwErrorVal = *pDllSpwRetVal; 531 return tmpRetVal; 532} 533 534/*----------------------------------------------------------------------------- 535 * 536 * SiDevID SiDeviceIndex (int idx) 537 * 538 * Args: 539 * idx (r/o) Device index (zero relative) 540 * 541 * Return Value: 542 * If there is no error, the device ID is returned and SpwErrorVal is set 543 * to SPW_NO_ERROR. Otherwise, the return value is SI_NO_DEVICE and 544 * SpwErrorVal is set to either SPW_ERROR (if the device index is invalid), 545 * SI_UNINITIALIZED, or SI_NO_DRIVER. 546 * 547 * Description: 548 * Given a device index, SiDeviceIndex returns the associated device ID. 549 * This routine is particularly useful with the function SiGetDevicePort. 550 * 551 *---------------------------------------------------------------------------*/ 552 553SiDevID 554SiDeviceIndex (int idx) 555{ 556 SiDevID tmpRetVal; /* temporary return value */ 557 558 if (gInitStatus != LOADED) 559 { 560 SiInitialize(); 561 if (gInitStatus == FAILED) 562 { 563 SpwErrorVal = SPW_DLL_LOAD_ERROR; /* global variable */ 564 return SI_NO_DEVICE; 565 } 566 } 567 568 tmpRetVal = pfnSiDeviceIndex(idx); 569 SpwErrorVal = *pDllSpwRetVal; 570 return tmpRetVal; 571} 572 573/*----------------------------------------------------------------------------- 574 * 575 * int SiDispatch (SiHdl hdl, SiGetEventData *pData, SiSpwEvent *pEvent, 576 * SiSpwHandlers *pHandlers) 577 * 578 * Args: 579 * hdl (r/o) SpaceWare handle 580 * pData (r/o) Pntr to platform specific data (as passed to SiGetEvent) 581 * pEvent (r/o) Pntr to SpaceWare event (as returned by SiGetEvent) 582 * pHandlers (r/o) Pntr to SpaceWare event handlers 583 * 584 * Return Value: 585 * Value returned by called event handler or zero if handler not defined. 586 * 587 * Description: 588 * Provided as a companion to SiGetEvent, this function calls the appro- 589 * priate handler to process the SpaceWare event returned by SiGetEvent. 590 * The SiSpwHandlers structure contains one handler for each event type. 591 * An event type can be ignored by setting the func member of the appro- 592 * priate SiEventHandler structure to NULL. Unlike the handler for 593 * SiGetEvent, there is no specific use for the function return value of 594 * these handlers -- the interpretation is entirely the caller's. 595 * 596 *---------------------------------------------------------------------------*/ 597 598int 599SiDispatch (SiHdl hdl, SiGetEventData *pData, 600 SiSpwEvent *pEvent, SiSpwHandlers *pDHandlers) 601{ 602 int tmpRetVal; /* temporary return value */ 603 604 if (gInitStatus != LOADED) 605 { 606 SiInitialize(); 607 if (gInitStatus == FAILED) 608 { 609 return 0; 610 } 611 } 612 613 tmpRetVal = pfnSiDispatch(hdl, pData, pEvent, pDHandlers); 614 SpwErrorVal = *pDllSpwRetVal; 615 return tmpRetVal; 616} 617 618/*----------------------------------------------------------------------------- 619 * 620 * void SiOpenWinInit (SiOpenData *pData, HWND hWnd) 621 * 622 * Args: 623 * pData (w/o) Pointer to storage for returned platform specific data 624 * hWnd (r/o) Window handle 625 * 626 * Return Value: 627 * Nothing 628 * 629 * Description: 630 * This function initializes the Windows platform specific data for a 631 * subsequent call to SiOpen. 632 * 633 *---------------------------------------------------------------------------*/ 634 635void 636SiOpenWinInit (SiOpenData *pData, HWND hWnd) 637{ 638 if (gInitStatus != LOADED) 639 { 640 SiInitialize(); 641 if (gInitStatus == FAILED) 642 { 643 pData = NULL; 644 hWnd = NULL; 645 return; 646 } 647 } 648 649 pfnSiOpenWinInit(pData, hWnd); 650 SpwErrorVal = *pDllSpwRetVal; 651} 652 653/*----------------------------------------------------------------------------- 654 * 655 * SiHdl SiOpen (char *pAppName, SiDevID devID, SiTypeMask *pTMask, int mode, 656 * SiOpenData *pData) 657 * 658 * Args: 659 * pAppName (r/o) Pointer to application name 660 * devID (r/o) Device ID or SI_ANY_DEVICE 661 * pTMask (r/o) Pointer to device type mask or SI_NO_MASK 662 * mode (r/o) SpaceWare event retrieval method: SI_EVENT or SI_POLL 663 * pData (r/o) Pointer to platform specific data if mode is SI_EVENT 664 * 665 * Return Value: 666 * SpaceWare handle or SI_NO_HANDLE if error. SpwErrorVal is set to one 667 * of the following: 668 * 669 * SPW_NO_ERROR No error 670 * SPW_ERROR Device could not be opened 671 * SI_BAD_ID Invalid device ID 672 * SI_BAD_VALUE Invalid argument 673 * SI_UNSUPPORTED Specified retrieval method is unsupported 674 * 675 * Description: 676 * SiOpen is called to open a device for input and (sometimes) output 677 * access. The device in which to open is indicated via the device ID 678 * (devID) and a device type mask (pTMask). If the ID of a particular 679 * device is known, it is passed in devID. If the ID is not known or the 680 * application simply doesn't care which device is selected, devID is passed 681 * as SI_ANY_DEVICE. 682 * 683 * Irrespective of the device ID, the device type mask indicates which 684 * device types are permitted. The type may be constrained to particular 685 * devices, classes, or any combination thereof. The mask is created via 686 * the function SiSetTypeMask (see the definition of that function for more 687 * information). If the application doesn't wish to constrain the selection 688 * to any particular types or classes, pTMask may be passed as SI_NO_MASK. 689 * This is the equivalent of passing a mask set to SI_ALL_TYPES. 690 * 691 * The following table shows how a device is selected based on the device ID 692 * and type mask. In those cases where SI_ANY_DEVICE is specified, the 693 * order in which the devices are searched is the same order as indexed by 694 * the function SiDevIndex. 695 * 696 * devID pTMask Device selected 697 * 698 * SI_ANY_DEVICE SI_NO_MASK The first available device in the list. 699 * 700 * A device ID SI_NO_MASK The device matching the specified ID if 701 * it's available. 702 * 703 * SI_ANY_DEVICE A type mask The first available device in the list 704 * with a type or class that is specified 705 * in the mask. 706 * 707 * A device ID A type mask The device matching the specified ID if 708 * its type or class matches one specified 709 * in the mask and it's available. 710 * 711 * Note that some SpaceWare implementations will run only if all of the 712 * configured devices are attached and working properly. Thus, all of the 713 * devices are available. Other implementations may run with some devices 714 * not working. These constitute unavailable devices. 715 * 716 * The mode argument specifies how the application intends to retrieve 717 * data from the device. SI_EVENT indicates that the application should 718 * be informed, via a system event message, whenever device data is 719 * pending. The message is acknowledged by a call to SiGetEvent. When 720 * this mode is selected, pData points to the platform specific informa- 721 * tion necessary for the API to generate system event messages. The mode 722 * SI_POLL indicates that the application will check for data from the 723 * device by calling SiGetEvent regularly. For this mode, pData is passed 724 * as NULL. 725 * 726 *---------------------------------------------------------------------------*/ 727 728SiHdl 729SiOpen (char *pAppName, SiDevID devID, SiTypeMask *pTMask, int mode, 730 SiOpenData *pData) 731{ 732 SiHdl tmpRetVal; /* temporary return value */ 733 734 if (gInitStatus != LOADED) 735 { 736 SiInitialize(); 737 if (gInitStatus == FAILED) 738 { 739 SpwErrorVal = SPW_DLL_LOAD_ERROR; 740 return NULL; 741 } 742 } 743 744 tmpRetVal = pfnSiOpen(pAppName, devID, pTMask, mode, pData); 745 SpwErrorVal = *pDllSpwRetVal; 746 return tmpRetVal; 747 748} 749 750/*----------------------------------------------------------------------------- 751 * 752 * enum SpwRetVal SiClose (SiHdl hdl) 753 * 754 * Args: 755 * hdl (r/o) SpaceWare handle 756 * 757 * Return Value: 758 * SPW_NO_ERROR No error 759 * SPW_ERROR Close error 760 * SI_BAD_HANDL Invalid SpaceWare handle 761 * 762 * Description: 763 * This function closes a device. Once closed, the SpaceWare handle is 764 * no longer valid. 765 * 766 *---------------------------------------------------------------------------*/ 767 768enum 769SpwRetVal SiClose (SiHdl hdl) 770{ 771 enum SpwRetVal tmpRetVal; /* temporary return value */ 772 773 if (gInitStatus != LOADED) 774 { 775 SiInitialize(); 776 if (gInitStatus == FAILED) 777 { 778 return SPW_DLL_LOAD_ERROR; 779 } 780 } 781 782 tmpRetVal = pfnSiClose(hdl); 783 SpwErrorVal = *pDllSpwRetVal; 784 return tmpRetVal; 785 786} 787 788/*----------------------------------------------------------------------------- 789 * 790 * SPWbool SiIsSpaceWareEvent (SiGetEventData *pData, SiHdl *pHdl) 791 * 792 * Args: 793 * pData (r/o) Pointer to platform specific data 794 * pHdl (w/o) Pointer to storage for returned SpaceWare handle 795 * 796 * Return Value: 797 * SPW_TRUE if pData refers to a SpaceWare event, otherwise SPW_FALSE. 798 * 799 * Description: 800 * This function determines whether or not the data addressed by pData per- 801 * tains to a SpaceWare event. If so, the handle for which the event is 802 * intended is returned. 803 * 804 * Notes: 805 * NULL may be passed for pHdl if the return of the intended handle is not 806 * required. 807 * 808 *---------------------------------------------------------------------------*/ 809 810SPWbool 811SiIsSpaceWareEvent(SiGetEventData *pData, SiHdl *pHdl) 812{ 813 SPWbool tmpRetVal; /* temporary return value */ 814 815 if (gInitStatus != LOADED) 816 { 817 SiInitialize(); 818 if (gInitStatus == FAILED) 819 { 820 return SPW_FALSE; 821 } 822 } 823 824 tmpRetVal = pfnSiIsSpaceWareEvent(pData, pHdl); 825 SpwErrorVal = *pDllSpwRetVal; 826 return tmpRetVal; 827} 828 829/*----------------------------------------------------------------------------- 830 * 831 * void SiGetEventWinInit (SiGetEventData *pData, 832 * UINT msg, WPARAM wParam, LPARAM lParam) 833 * 834 * Args: 835 * pData (w/o) Pointer to storage for returned platform specific data 836 * msg (r/o) Windows message 837 * wParam (r/o) Parameter #1 838 * lParam (r/o) Parameter #2 839 * 840 * Return Value: 841 * Nothing 842 * 843 * Description: 844 * This function initializes the Windows platform specific data for a 845 * subsequent call to SiGetEvent. 846 * 847 *---------------------------------------------------------------------------*/ 848 849void 850SiGetEventWinInit (SiGetEventData *pData, UINT msg, WPARAM wParam, 851 LPARAM lParam) 852{ 853 if (gInitStatus != LOADED) 854 { 855 SiInitialize(); 856 if (gInitStatus == FAILED) 857 { 858 return; 859 } 860 } 861 862 pfnSiGetEventWinInit(pData, msg, wParam, lParam); 863 SpwErrorVal = *pDllSpwRetVal; 864} 865 866/*----------------------------------------------------------------------------- 867 * 868 * enum SpwRetVal SiGetEvent (SiHdl hdl, int flags, 869 * SiGetEventData *pData, SiSpwEvent *pEvent) 870 * 871 * Args: 872 * hdl (r/o) SpaceWare handle 873 * flags (r/o) Processing flags 874 * pData (r/o) Pointer to platform specific data 875 * pEvent (w/o) Pointer to storage for returned SpaceWare event 876 * 877 * Return Value: 878 * SI_BAD_HANDLE Invalid SpaceWare handle 879 * SI_NOT_EVENT The event is not a SpaceWare event or no event pending 880 * SI_IS_EVENT The event is a SpaceWare event 881 * SI_SKIP_EVENT The event is a SpaceWare event but it should be skipped 882 * 883 * Description: 884 * This function determines if device data is pending and if so, returns 885 * the data as a SpaceWare event. See the "SpaceWare Universal API" 886 * specification for a complete description of this function. 887 * 888 *---------------------------------------------------------------------------*/ 889 890enum SpwRetVal 891SiGetEvent (SiHdl hdl, int flags, SiGetEventData *pData, 892 SiSpwEvent *pEvent) 893{ 894 enum SpwRetVal tmpRetVal; /* temporary return value */ 895 896 if (gInitStatus != LOADED) 897 { 898 SiInitialize(); 899 if (gInitStatus == FAILED) 900 { 901 return SPW_DLL_LOAD_ERROR; 902 } 903 } 904 905 tmpRetVal = pfnSiGetEvent(hdl, flags, pData, pEvent); 906 SpwErrorVal = *pDllSpwRetVal; 907 return tmpRetVal; 908} 909 910/*----------------------------------------------------------------------------- 911 * 912 * enum SpwRetVal SiBeep (SiHdl hdl, char *pString) 913 * 914 * Args: 915 * hdl (r/o) SpaceWare handle 916 * pString (r/o) Pointer to beep description string 917 * 918 * Return Value: 919 * SPW_NO_ERROR No error 920 * SI_BAD_HANDLE Invalid SpaceWare handle 921 * SI_BAD_VALUE Bad string 922 * 923 * Description: 924 * If supported, this function causes the input device to emit a sequence 925 * of tones and pauses. Each character of the string represents either a 926 * tone or a delay. Lowercase letters [a-z] represent a tone, uppercase 927 * letters [A-Z] represent a pause. The closer the letter is to the 928 * beginning of the alphabet the shorter the pause or tone ('a' or 'A' is 929 * 1/32 second, 'b' or 'B' is 2/32 second, etc). Up to 14 characters in 930 * a string are processed, additional characters are ignored. 931 * 932 *---------------------------------------------------------------------------*/ 933 934enum SpwRetVal 935SiBeep(SiHdl hdl, char *pString) 936{ 937 enum SpwRetVal tmpRetVal; /* temporary return value */ 938 939 if (gInitStatus != LOADED) 940 { 941 SiInitialize(); 942 if (gInitStatus == FAILED) 943 { 944 return SPW_DLL_LOAD_ERROR; 945 } 946 } 947 948 tmpRetVal = pfnSiBeep(hdl, pString); 949 SpwErrorVal = *pDllSpwRetVal; 950 return tmpRetVal; 951} 952 953/*----------------------------------------------------------------------------- 954 * 955 * enum SpwRetVal SiRezero (SiHdl hdl) 956 * 957 * Args: 958 * hdl (r/o) SpaceWare handle 959 * 960 * Return Value: 961 * SPW_NO_ERROR No error 962 * SI_BAD_HANDLE Invalid SpaceWare handle 963 * 964 * Description: 965 * This function causes the input device's current setting to be defined 966 * as the rest position. Movement away from this position will cause 967 * motion events. This can be used to eliminate drift or to set up a 968 * constant motion. 969 * 970 *---------------------------------------------------------------------------*/ 971 972enum SpwRetVal 973SiRezero (SiHdl hdl) 974{ 975 enum SpwRetVal tmpRetVal; /* temporary return value */ 976 977 if (gInitStatus != LOADED) 978 { 979 SiInitialize(); 980 if (gInitStatus == FAILED) 981 { 982 return SPW_DLL_LOAD_ERROR; 983 } 984 } 985 986 tmpRetVal = pfnSiRezero(hdl); 987 SpwErrorVal = *pDllSpwRetVal; 988 return tmpRetVal; 989} 990 991/*----------------------------------------------------------------------------- 992 * 993 * enum SpwRetVal SiGrabDevice (SiHdl hdl, SPWbool exclusive) 994 * 995 * Args: 996 * hdl (r/o) SpaceWare handle 997 * exclusive (r/o) Exclusive grab flag 998 * 999 * Return Value: 1000 * SPW_NO_ERROR No error 1001 * SPW_ERROR Grab failed 1002 * SI_BAD_HANDLE Invalid SpaceWare handle 1003 * 1004 * Description: 1005 * This function is used to "grab" or capture a device in multi-tasking 1006 * environments. For an exclusive capture, the application retains control 1007 * of the device regardless of which window has the focus. For a non- 1008 * exclusive capture, the application retains control of the device only if 1009 * no other application, sharing the same device, has the focus. Some 1010 * SpaceWare implementations only allow one non-exclusive grab. Others 1011 * allow multiple non-exclusive grabs and provide an interface for inter- 1012 * actively selecting the current non-exclusive grab application. An exclu- 1013 * sive grab fails if another application has already exclusively captured 1014 * the device. A non-exclusive grab fails if the SpaceWare implementation 1015 * only allows one non-exclusive grab and another application has already 1016 * non-exclusively captured the device. Note that an exclusive grab should 1017 * be used sparingly if at all. 1018 * 1019 *---------------------------------------------------------------------------*/ 1020 1021enum SpwRetVal 1022SiGrabDevice (SiHdl hdl, SPWbool exclusive) 1023{ 1024 enum SpwRetVal tmpRetVal; /* temporary return value */ 1025 1026 if (gInitStatus != LOADED) 1027 { 1028 SiInitialize(); 1029 if (gInitStatus == FAILED) 1030 { 1031 return SPW_DLL_LOAD_ERROR; 1032 } 1033 } 1034 1035 tmpRetVal = pfnSiGrabDevice(hdl, exclusive); 1036 SpwErrorVal = *pDllSpwRetVal; 1037 return tmpRetVal; 1038} 1039 1040/*----------------------------------------------------------------------------- 1041 * 1042 * enum SpwRetVal SiReleaseDevice (SiHdl hdl) 1043 * 1044 * Args: 1045 * hdl (r/o) SpaceWare handle 1046 * 1047 * Return Value: 1048 * SPW_NO_ERROR No error 1049 * SPW_ERROR Device not captured 1050 * SI_BAD_HANDLE Invalid SpaceWare handle 1051 * 1052 * Description: 1053 * This function releases a device that has been captured via the routine 1054 * SiGrabDevice. A captured device is automatically released when closed. 1055 * 1056 *---------------------------------------------------------------------------*/ 1057 1058enum SpwRetVal 1059SiReleaseDevice (SiHdl hdl) 1060{ 1061 enum SpwRetVal tmpRetVal; /* temporary return value */ 1062 1063 if (gInitStatus != LOADED) 1064 { 1065 SiInitialize(); 1066 if (gInitStatus == FAILED) 1067 { 1068 return SPW_DLL_LOAD_ERROR; 1069 } 1070 } 1071 1072 tmpRetVal = pfnSiReleaseDevice(hdl); 1073 SpwErrorVal = *pDllSpwRetVal; 1074 return tmpRetVal; 1075} 1076 1077/*----------------------------------------------------------------------------- 1078 * 1079 * int SiButtonPressed (SiSpwEvent *pEvent) 1080 * 1081 * Args: 1082 * pEvent (r/o) Pointer to SpaceWare event 1083 * 1084 * Return Value: 1085 * Button number or SI_NO_BUTTON if not a button or combo event or no 1086 * button was pressed. If it's not a button or combo event, SpwErrorVal 1087 * is set to SPW_ERROR otherwise SpwErrorVal is SPW_NO_ERROR. 1088 * 1089 * Description: 1090 * Given a button or combo event, this function returns the number of the 1091 * button pressed. In the event that multiple buttons are pressed, the 1092 * lowest button number is returned. 1093 * 1094 *---------------------------------------------------------------------------*/ 1095 1096int 1097SiButtonPressed (SiSpwEvent *pEvent) 1098{ 1099 int tmpRetVal; /* temporary return value */ 1100 1101 if (gInitStatus != LOADED) 1102 { 1103 SiInitialize(); 1104 if (gInitStatus == FAILED) 1105 { 1106 SpwErrorVal = SPW_DLL_LOAD_ERROR; 1107 return SI_NO_BUTTON; 1108 } 1109 } 1110 1111 tmpRetVal = pfnSiButtonPressed(pEvent); 1112 SpwErrorVal = *pDllSpwRetVal; 1113 return tmpRetVal; 1114} 1115 1116/*----------------------------------------------------------------------------- 1117 * 1118 * int SiButtonReleased (SiSpwEvent *pEvent) 1119 * 1120 * Args: 1121 * pEvent (r/o) Pointer to SpaceWare event 1122 * 1123 * Return Value: 1124 * Button number or SI_NO_BUTTON if not a button or combo event or no 1125 * button was released. If it's not a button or combo event, SpwErrorVal 1126 * is set to SPW_ERROR otherwise SpwErrorVal is SPW_NO_ERROR. 1127 * 1128 * Description: 1129 * Given a button or combo event, this function returns the number of the 1130 * button released. In the event that multiple buttons are released, the 1131 * lowest button number is returned. 1132 * 1133 *---------------------------------------------------------------------------*/ 1134 1135int 1136SiButtonReleased (SiSpwEvent *pEvent) 1137{ 1138 int tmpRetVal; /* temporary return value */ 1139 1140 if (gInitStatus != LOADED) 1141 { 1142 SiInitialize(); 1143 if (gInitStatus == FAILED) 1144 { 1145 SpwErrorVal = SPW_DLL_LOAD_ERROR; 1146 return SI_NO_BUTTON; 1147 } 1148 } 1149 1150 tmpRetVal = pfnSiButtonReleased(pEvent); 1151 SpwErrorVal = *pDllSpwRetVal; 1152 return tmpRetVal; 1153} 1154 1155/*----------------------------------------------------------------------------- 1156 * 1157 * enum SpwRetVal SiSetUiMode (SiHdl hdl, SPWuint32 mode) 1158 * 1159 * Args: 1160 * hdl (r/o) SpaceWare handle or SI_ALL_HANDLES 1161 * mode (r/o) UI mode 1162 * 1163 * Return Value: 1164 * SPW_NO_ERROR No error 1165 * SI_BAD_HANDLE Invalid SpaceWare handle 1166 * 1167 * Description: 1168 * This function sets the current User Interface (UI) mode bit mask for a 1169 * specified device. If hdl is SI_ALL_HANDLES, the mask for each open 1170 * device is set. This option is useful if an app uses the same UI mode 1171 * for more than one device. Each set bit in the mask indicates that a 1172 * particular feature is enabled. The bits are defined as follows. 1173 * 1174 * SI_UI_ALL_CONTROLS All controls 1175 * SI_UI_NO_CONTROLS No controls 1176 * SI_UI_FILTERS Filter controls 1177 * SI_UI_FUNC_BUTTONS Function buttons 1178 * SI_UI_RESET_BUTTONS Reset buttons 1179 * SI_UI_SENSITIVITY Sensitivity control 1180 * SI_UI_TUNING Tuning control 1181 * SI_UI_DIALOG_POPUP Dialog popup button (on device) 1182 * 1183 * Note that for SI_UI_ALL_CONTROLS, all bits are set; for SI_UI_NO_CONTROLS, 1184 * no bits are set. 1185 * 1186 *---------------------------------------------------------------------------*/ 1187 1188enum SpwRetVal 1189SiSetUiMode (SiHdl hdl, SPWuint32 mode) 1190{ 1191 enum SpwRetVal tmpRetVal; /* temporary return value */ 1192 1193 if (gInitStatus != LOADED) 1194 { 1195 SiInitialize(); 1196 if (gInitStatus == FAILED) 1197 { 1198 return SPW_DLL_LOAD_ERROR; 1199 } 1200 } 1201 1202 tmpRetVal = pfnSiSetUiMode(hdl, mode); 1203 SpwErrorVal = *pDllSpwRetVal; 1204 return tmpRetVal; 1205} 1206 1207/*----------------------------------------------------------------------------- 1208 * 1209 * enum SpwRetVal SiSetTypeMask (SiTypeMask *pTMask, int type1, ..., 1210 * SI_END_ARGS) 1211 * 1212 * Args: 1213 * pTMask (w/o) Pointer to storage for returned device type mask 1214 * type1 (r/o) First device type 1215 * ... (r/o) Additional device types 1216 * 1217 * Return Value: 1218 * SPW_NO_ERROR No error 1219 * 1220 * Description: 1221 * This function provides compatibility with older software. 1222 * 1223 *---------------------------------------------------------------------------*/ 1224 1225enum SpwRetVal 1226SiSetTypeMask (SiTypeMask *pTMask, int type1, ...) 1227{ 1228 if (gInitStatus != LOADED) 1229 { 1230 SiInitialize(); 1231 if (gInitStatus == FAILED) 1232 { 1233 return SPW_DLL_LOAD_ERROR; 1234 } 1235 } 1236 1237 /* stub function -> return a happy value */ 1238 return SPW_NO_ERROR; 1239} 1240 1241/*----------------------------------------------------------------------------- 1242 * 1243 * enum SpwRetVal SiGetDevicePort (SiDevID devID, SiDevPort *pPort) 1244 * 1245 * Args: 1246 * devID (r/o) Device ID 1247 * pPort (w/o) Pointer to storage for returned device port info 1248 * 1249 * Return Value: 1250 * SPW_NO_ERROR No error 1251 * SI_BAD_ID Invalid device ID 1252 * 1253 * Description: 1254 * The purpose of this function is to provide a correlation between the 1255 * devices and the system ports to which they are connected. Each call 1256 * to SiGetDevicePort returns information for one device. 1257 * 1258 *---------------------------------------------------------------------------*/ 1259 1260enum SpwRetVal 1261SiGetDevicePort (SiDevID devID, SiDevPort *pPort) 1262{ 1263 enum SpwRetVal tmpRetVal; /* temporary return value */ 1264 1265 if (gInitStatus != LOADED) 1266 { 1267 SiInitialize(); 1268 if (gInitStatus == FAILED) 1269 { 1270 return SPW_DLL_LOAD_ERROR; 1271 } 1272 } 1273 1274 tmpRetVal = pfnSiGetDevicePort(devID, pPort); 1275 SpwErrorVal = *pDllSpwRetVal; 1276 return tmpRetVal; 1277} 1278 1279/*----------------------------------------------------------------------------- 1280 * 1281 * enum SpwRetVal SiGetDriverInfo (SiVerInfo *pInfo) 1282 * 1283 * Args: 1284 * pInfo (w/o) Pointer to storage for returned driver version info 1285 * 1286 * Return Value: 1287 * SPW_NO_ERROR No error 1288 * SPW_ERROR This version of the SpaceWare library does not use a driver 1289 * 1290 * Description: 1291 * SiGetDriverInfo returns driver version information. 1292 * 1293 *---------------------------------------------------------------------------*/ 1294 1295enum SpwRetVal 1296SiGetDriverInfo (SiVerInfo *pInfo) 1297{ 1298 enum SpwRetVal tmpRetVal; /* temporary return value */ 1299 1300 if (gInitStatus != LOADED) 1301 { 1302 SiInitialize(); 1303 if (gInitStatus == FAILED) 1304 { 1305 return SPW_DLL_LOAD_ERROR; 1306 } 1307 } 1308 1309 tmpRetVal = pfnSiGetDriverInfo(pInfo); 1310 SpwErrorVal = *pDllSpwRetVal; 1311 return tmpRetVal; 1312} 1313 1314/*----------------------------------------------------------------------------- 1315 * 1316 * void SiGetLibraryInfo (SiVerInfo *pInfo) 1317 * 1318 * Args: 1319 * pInfo (w/o) Pointer to storage for returned library version info 1320 * 1321 * Return Value: 1322 * Nothing. SpwErrorVal is always set to SPW_NO_ERROR by this function. 1323 * 1324 * Description: 1325 * SiGetLibraryInfo returns library version information. 1326 * 1327 *---------------------------------------------------------------------------*/ 1328 1329void 1330SiGetLibraryInfo (SiVerInfo *pInfo) 1331{ 1332 if (gInitStatus != LOADED) 1333 { 1334 SiInitialize(); 1335 if (gInitStatus == FAILED) 1336 { 1337 pInfo = NULL; 1338 return; 1339 } 1340 1341 } 1342 1343 pfnSiGetLibraryInfo(pInfo); 1344 SpwErrorVal = *pDllSpwRetVal; 1345} 1346 1347/*----------------------------------------------------------------------------- 1348 * 1349 * enum SpwRetVal SiGetDeviceInfo (SiHdl hdl, SiDevInfo *pInfo) 1350 * 1351 * Args: 1352 * hdl (r/o) SpaceWare handle 1353 * pInfo (w/o) Pointer to storage for returned device information 1354 * 1355 * Return Value: 1356 * SPW_NO_ERROR No error 1357 * SI_BAD_HANDLE Invalid SpaceWare handle 1358 * 1359 * Description: 1360 * This function returns all sorts of information on the specified device. 1361 * 1362 *---------------------------------------------------------------------------*/ 1363 1364enum SpwRetVal 1365SiGetDeviceInfo (SiHdl hdl, SiDevInfo *pInfo) 1366{ 1367 enum SpwRetVal tmpRetVal; /* temporary return value */ 1368 1369 if (gInitStatus != LOADED) 1370 { 1371 SiInitialize(); 1372 if (gInitStatus == FAILED) 1373 { 1374 return SPW_DLL_LOAD_ERROR; 1375 } 1376 } 1377 1378 tmpRetVal = pfnSiGetDeviceInfo(hdl, pInfo); 1379 SpwErrorVal = *pDllSpwRetVal; 1380 return tmpRetVal; 1381} 1382 1383/*----------------------------------------------------------------------------- 1384 * 1385 * char *SpwErrorString (enum SpwRetVal val) 1386 * 1387 * Parameters: 1388 * val (r/o) Error value 1389 * 1390 * Return: 1391 * Pointer to string containing error message. 1392 * 1393 * Description: 1394 * This function returns a pointer to the error message string associated 1395 * with the given error value. Note that the returned pointer points to 1396 * static memory that is overridden each time SpwErrorString is called. 1397 * 1398 *---------------------------------------------------------------------------*/ 1399 1400char * 1401SpwErrorString (enum SpwRetVal val) 1402{ 1403 1404 if (gInitStatus != LOADED) 1405 { 1406 SiInitialize(); 1407 if (gInitStatus == FAILED) 1408 { 1409 return NULL; 1410 } 1411 } 1412 1413 return (char *) pfnSpwErrorString(val); 1414} 1415 1416#endif /* HAVE_WIN32_API */ 1417 1418 1419