// ScripterCallback.cpp : // // A loadable module that connects a windows named pipe // to a registered service function that is able to // process a single command at a time. // // The service function is provided by the application // and not by libscript. mod_script_pipe was developed for // Audacity. Because it forwards commands // rather than handling them itself it can be used in // other projects too. #include #include "ScripterCallback.h" //#include "../lib_widget_extra/ShuttleGuiBase.h" #include "../../src/ShuttleGui.h" #ifdef NOT_DEFINED // This is 'traditional code' for DLLs, which we're not // using. //#include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } #endif extern void PipeServer(); extern "C" { typedef SCRIPT_PIPE_DLL_IMPORT int (*tpExecScriptServerFunc)( wxString * pIn, wxString * pOut); static tpExecScriptServerFunc pScriptServerFn=NULL; wxString Str2; wxArrayString aStr; unsigned int currentLine; size_t currentPosition; // Send the received command to Audacity and build an array of response lines. // The response lines can be retrieved by calling DoSrvMore repeatedly. int DoSrv(char *pIn) { wxString Str1(pIn, wxConvISO8859_1); Str1.Replace( wxT("\r"), wxT("")); Str1.Replace( wxT("\n"), wxT("")); Str2 = wxEmptyString; (*pScriptServerFn)( &Str1 , &Str2); Str2 += wxT('\n'); size_t outputLength = Str2.Length(); aStr.Clear(); size_t iStart = 0; size_t i; for(i = 0; i < outputLength; ++i) { if( Str2[i] == wxT('\n') ) { aStr.Add( Str2.Mid( iStart, i-iStart) + wxT("\n") ); iStart = i+1; } } currentLine = 0; currentPosition = 0; return 1; } size_t smin(size_t a, size_t b) { return a < b ? a : b; } // Write up to nMax characters of the prepared (by DoSrv) response lines. // Returns the number of characters sent, including null. // Zero returned if and only if there's nothing else to send. int DoSrvMore(char *pOut, size_t nMax) { wxASSERT(currentLine >= 0); wxASSERT(currentPosition >= 0); size_t totalLines = aStr.GetCount(); while (currentLine < totalLines) { wxString lineString = aStr[currentLine]; size_t lineLength = lineString.Length(); size_t charsLeftInLine = lineLength - currentPosition; wxASSERT(charsLeftInLine >= 0); if (charsLeftInLine == 0) { // Move to next line ++currentLine; currentPosition = 0; } else { // Write as much of the rest of the line as will fit in the buffer size_t charsToWrite = smin(charsLeftInLine, nMax - 1); memcpy(pOut, lineString.Mid(currentPosition, currentPosition + charsToWrite).mb_str(), charsToWrite); pOut[charsToWrite] = '\0'; currentPosition += charsToWrite; // Need to cast to prevent compiler warnings int charsWritten = static_cast(charsToWrite + 1); // (Check cast was safe) wxASSERT(static_cast(charsWritten) == charsToWrite + 1); return charsWritten; } } return 0; } int SCRIPT_PIPE_DLL_API RegScriptServerFunc( tpExecScriptServerFunc pFn ) { if( pFn ) { pScriptServerFn = pFn; PipeServer(); } return 4; } // This is an example of an exported function. int SCRIPT_PIPE_DLL_API ExtensionModuleInit(int ix) { // pExecFunc = NULL; ix;// compiler food. #if defined(_DEBUG) wxLogDebug(wxT("Got into DLL")); #endif // Here is proof that the DLL was dynamically loaded and this Init function // called. //wxDialog Dlg( (wxWindow*)NULL, (wxWindowID)-1, wxT("mod-script-pipe - Dialog Loaded by Plug In"), wxPoint(0,0)); #if 0 ShuttleGui S( &Dlg, eIsCreating ); S.StartStatic( "Scripter Initialising" ); S.StartHorizontalLay(); S.Id(wxID_CANCEL).AddButton( "Cancel" ); S.Id(wxID_OK).AddButton( "OK" )->SetFocus(); S.EndHorizontalLay(); S.EndStatic(); #endif /* Dlg.Fit(); Dlg.Move( 100,100 ); int id = Dlg.ShowModal(); */ //printf("id = %d\n", id); // return -1 for cancel, anything else for OK. // return (id==wxID_CANCEL)?-1:42; return 0; } wxString SCRIPT_PIPE_DLL_API GetVersionString() { return SCRIPT_PIPE_VERSION_STRING; } } // End extern "C"