/* Hey EMACS -*- linux-c -*- */ /* $Id$ */ /* libticalcs2 - hand-helds support library, a part of the TiLP project * Copyright (C) 1999-2005 Romain LiƩvin * * 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 * (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, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #if defined(__WIN32__) #include #endif #include #include "gettext.h" #include "ticalcs.h" #include "internal.h" #include "logging.h" #include "error.h" #include "calc_xx.h" /*****************/ /* Internal data */ /*****************/ extern const CalcUpdate default_update; static CalcFncts const *const calcs[] = { &calc_00, #ifndef NO_TI73 &calc_73, #endif #ifndef NO_TI82 &calc_82, #endif #ifndef NO_TI83 &calc_83, #endif #ifndef NO_TI83P &calc_83p, #endif #ifndef NO_TI84P &calc_84p, #endif #ifndef NO_TI85 &calc_85, #endif #ifndef NO_TI86 &calc_86, #endif #ifndef NO_TI89 &calc_89, #endif #ifndef NO_TI89T &calc_89t, #endif #ifndef NO_TI92 &calc_92, #endif #ifndef NO_TI92P &calc_92p, #endif #ifndef NO_V200 &calc_v2, #endif #ifndef NO_TI84P_USB &calc_84p_usb, #endif #ifndef NO_TI89T_USB &calc_89t_usb, #endif #ifndef NO_NSPIRE &calc_nsp, #endif #ifndef NO_TI80 &calc_80, #endif #ifndef NO_TI84PC &calc_84pcse, #endif #ifndef NO_TI84PC_USB &calc_84pcse_usb, #endif #ifndef NO_TI83PCE_USB &calc_83pce_usb, #endif #ifndef NO_TI84PCE_USB &calc_84pce_usb, #endif #ifndef NO_TI82A_USB &calc_82a_usb, #endif #ifndef NO_TI84PT_USB &calc_84pt_usb, #endif NULL }; static const uint32_t supported_calcs = (1U << CALC_NONE) #ifndef NO_TI73 | (1U << CALC_TI73) #endif #ifndef NO_TI82 | (1U << CALC_TI82) #endif #ifndef NO_TI83 | (1U << CALC_TI83) #endif #ifndef NO_TI83P | (1U << CALC_TI83P) #endif #ifndef NO_TI84P | (1U << CALC_TI84P) #endif #ifndef NO_TI85 | (1U << CALC_TI85) #endif #ifndef NO_TI86 | (1U << CALC_TI86) #endif #ifndef NO_TI89 | (1U << CALC_TI89) #endif #ifndef NO_TI89T | (1U << CALC_TI89T) #endif #ifndef NO_TI92 | (1U << CALC_TI92) #endif #ifndef NO_TI92P | (1U << CALC_TI92P) #endif #ifndef NO_V200 | (1U << CALC_V200) #endif #ifndef NO_TI84P_USB | (1U << CALC_TI84P_USB) #endif #ifndef NO_TI89T_USB | (1U << CALC_TI89T_USB) #endif #ifndef NO_NSPIRE | (1U << CALC_NSPIRE) #endif #ifndef NO_TI80 | (1U << CALC_TI80) #endif #ifndef NO_TI84PC | (1U << CALC_TI84PC) #endif #ifndef NO_TI84PC_USB | (1U << CALC_TI84PC_USB) #endif #ifndef NO_TI83PCE_USB | (1U << CALC_TI83PCE_USB) #endif #ifndef NO_TI84PCE_USB | (1U << CALC_TI84PCE_USB) #endif #ifndef NO_TI82A_USB | (1U << CALC_TI82A_USB) #endif #ifndef NO_TI84PT_USB | (1U << CALC_TI84PT_USB) #endif ; /****************/ /* Entry points */ /****************/ // not static, must be shared between instances int ticalcs_instance = 0; // counts # of instances /** * ticalcs_library_init: * * This function must be the first one to call. It inits library internals. * * Return value: the instance count. **/ TIEXPORT3 int TICALL ticalcs_library_init(void) { char locale_dir[65536 + 20]; #ifdef __WIN32__ HANDLE hDll; int i; hDll = GetModuleHandle("libticalcs2-12.dll"); GetModuleFileName(hDll, locale_dir, sizeof(locale_dir) - 21); for (i = strlen(locale_dir); i >= 0; i--) { if (locale_dir[i] == '\\') { break; } } locale_dir[i] = '\0'; #ifdef __MINGW32__ strcat(locale_dir, "\\..\\share\\locale"); #else strcat(locale_dir, "\\locale"); #endif #else strncpy(locale_dir, LOCALEDIR, sizeof(locale_dir) - 21); locale_dir[sizeof(locale_dir) - 21] = 0; #endif if (ticalcs_instance) { return (++ticalcs_instance); } ticalcs_info(_("ticalcs library version %s"), LIBCALCS_VERSION); errno = 0; #if defined(ENABLE_NLS) ticalcs_info("setlocale: %s", setlocale(LC_ALL, "")); ticalcs_info("bindtextdomain: %s", bindtextdomain(PACKAGE, locale_dir)); bind_textdomain_codeset(PACKAGE, "UTF-8"/*"ISO-8859-15"*/); ticalcs_info("textdomain: %s", textdomain(NULL)); #endif return (++ticalcs_instance); } /** * ticalcs_library_exit: * * This function must be the last one to call. Used to release internal resources. * * Return value: the instance count. **/ TIEXPORT3 int TICALL ticalcs_library_exit(void) { return (--ticalcs_instance); } /***********/ /* Methods */ /***********/ /** * ticalcs_version_get: * * This function returns the library version like "X.Y.Z". * * Return value: a string. **/ TIEXPORT3 const char *TICALL ticalcs_version_get(void) { return LIBCALCS_VERSION; } /** * ticalcs_supported_calcs: * * This function returns the calcs built into the current binary. * * Return value: an integer containing a binary OR of (1 << CALC_*) values, * where CALC_* values are defined in enum CalcModel. **/ TIEXPORT3 uint32_t TICALL ticalcs_supported_calcs (void) { return supported_calcs; } /** * ticalcs_handle_new: * @model: a hand-held model * * Create a new handle associated with the given cable on the given port. * Must be freed with ticables_handle_del when no longer needed. * Note: the handle is a pointer on an opaque structure and should not be modified. * * Return value: NULL if error, an handle otherwise. **/ TIEXPORT3 CalcHandle* TICALL ticalcs_handle_new(CalcModel model) { CalcHandle *handle = NULL; CalcFncts * calc = NULL; unsigned int i; for (i = 0; i < sizeof(calcs) / sizeof(calcs[0]) - 1; i++) // - 1 for the terminating NULL. { if (calcs[i]->model == (int const)model) { calc = (CalcFncts *)calcs[i]; break; } } if (calc != NULL) { handle = (CalcHandle *)g_malloc0(sizeof(CalcHandle)); if (handle != NULL) { handle->model = model; handle->calc = calc; handle->updat = (CalcUpdate *)&default_update; handle->priv.nsp_src_port = 0x8001; handle->priv.nsp_dst_port = 0x4003; // NSP_PORT_ADDR_REQUEST handle->buffer = (uint8_t *)g_malloc(65536 + 6); if (handle->buffer == NULL) { g_free(handle); handle = NULL; } handle->buffer2 = (uint8_t *)g_malloc(65536 + 6); if (handle->buffer2 == NULL) { g_free(handle->buffer); g_free(handle); handle = NULL; } } } return handle; } /** * ticalcs_handle_del: * @handle: the handle * * Release the cable and free the associated resources. * If cable has not been detached with #ticalcs_cable_detach, * it will be detached. * * Return value: always 0. **/ TIEXPORT3 int TICALL ticalcs_handle_del(CalcHandle* handle) { VALIDATE_HANDLE(handle); if (handle->attached) { ticalcs_cable_detach(handle); } if (handle->buffer2) { g_free(handle->buffer2); } if (handle->buffer) { g_free(handle->buffer); } memset((void *)handle, 0, sizeof(*handle)); g_free(handle); return 0; } /** * ticalcs_handle_show: * @handle: the handle * * Show information stored in the handle. * * Return value: always 0. **/ TIEXPORT3 int TICALL ticalcs_handle_show(CalcHandle* handle) { VALIDATE_HANDLE(handle); ticalcs_info(_("Link calc handle details:")); ticalcs_info(_(" model : %s"), ticalcs_model_to_string(handle->model)); return 0; } /** * ticalcs_cable_attach: * @handle: the handle * @cable: a cable to use * * Attach and open the given cable for use with the hand-held. * * Return value: 0 if successful, an error code otherwise. **/ TIEXPORT3 int TICALL ticalcs_cable_attach(CalcHandle* handle, CableHandle* cable) { int ret; VALIDATE_HANDLE(handle); handle->cable = cable; handle->attached = !0; ret = ticables_cable_open(cable); if (!ret) { handle->open = !0; } return ret; } /** * ticalcs_cable_detach: * @handle: the handle * @cable: a cable to use * * Close and detach the cable associated with the hand-held. * * Return value: 0 if successful, an error code otherwise. **/ TIEXPORT3 int TICALL ticalcs_cable_detach(CalcHandle* handle) { int ret; VALIDATE_HANDLE(handle); ret = ticables_cable_close(handle->cable); if (!ret) { handle->open = 0; handle->attached = 0; handle->cable = NULL; } return ret; } /** * ticalcs_update_set: * @handle: the handle * @update: the callbacks to use * * Set the callbacks to use for the given handle. * * Return value: 0 if successful, an error code otherwise. **/ TIEXPORT3 int TICALL ticalcs_update_set(CalcHandle* handle, CalcUpdate* upd) { VALIDATE_HANDLE(handle); handle->updat = upd; return 0; } /** * ticalcs_model_supports_dbus: * @model: a calculator model taken in #CalcModel. * * Returns whether the given calculator model supports the protocol dubbed DBUS by libticalcs. * That is, the standard protocol used by TI-Z80 and TI-68k calculators over the legacy I/O. * * Return value: nonzero if the calculator supports the DBUS protocol, zero if it doesn't. */ TIEXPORT3 int TICALL ticalcs_model_supports_dbus(CalcModel model) { return ( /*model < CALC_MAX &&*/ ( model == CALC_TI73 || model == CALC_TI82 || model == CALC_TI83 || model == CALC_TI83P || model == CALC_TI84P || model == CALC_TI85 || model == CALC_TI86 || model == CALC_TI89 || model == CALC_TI89T || model == CALC_TI92 || model == CALC_TI92P || model == CALC_V200 || model == CALC_TI80 || model == CALC_TI84PC)); } /** * ticalcs_model_supports_dusb: * @model: a calculator model taken in #CalcModel. * * Returns whether the given calculator model supports the protocol dubbed DUSB by libticalcs. * That is, the standard protocol used by TI-Z80, TI-eZ80 and TI-68k calculators over the USB port. * * Return value: nonzero if the calculator supports the DUSB protocol, zero if it doesn't. */ TIEXPORT3 int TICALL ticalcs_model_supports_dusb(CalcModel model) { return ( /*model < CALC_MAX &&*/ ( model == CALC_TI84P_USB || model == CALC_TI89T_USB || model == CALC_TI84PC_USB || model == CALC_TI83PCE_USB || model == CALC_TI84PCE_USB || model == CALC_TI82A_USB || model == CALC_TI84PT_USB)); } /** * ticalcs_model_supports_nsp: * @model: a calculator model taken in #CalcModel. * * Returns whether the given calculator model supports the protocol dubbed NSP by libticalcs. * That is, the standard protocol used by TI-Nspire calculators over the USB port. * * Return value: nonzero if the calculator supports the NSP protocol, zero if it doesn't. */ TIEXPORT3 int TICALL ticalcs_model_supports_nsp(CalcModel model) { return ( /*model < CALC_MAX &&*/ ( model == CALC_NSPIRE)); }