Back to index

lightning-sunbird  0.9+nobinonly
plugin.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include <windows.h>
00039 #include <windowsx.h>
00040 #include <assert.h>
00041 
00042 #include "resource.h"
00043 
00044 #include "plugin.h"
00045 #include "helpers.h"
00046 #include "guihlp.h"
00047 #include "logger.h"
00048 #include "scripter.h"
00049 #include "guiprefs.h"
00050 #include "winutils.h"
00051 
00052 extern HINSTANCE hInst;
00053 extern CLogger * pLogger;
00054 
00055 /***********************************************/
00056 /*                                             */
00057 /*       CPlugin class implementation          */
00058 /*                                             */
00059 /***********************************************/
00060 
00061 CPlugin::CPlugin(NPP pNPInstance, WORD wMode) :
00062   CPluginBase(pNPInstance, wMode),
00063   m_hInst(hInst),
00064   m_hWnd(NULL),
00065   m_hWndManual(NULL),
00066   m_hWndAuto(NULL),
00067   m_hWndParent(NULL),
00068   m_hWndStandAloneLogWindow(NULL),
00069   m_bPluginReady(FALSE),
00070   m_hWndLastEditFocus(NULL),
00071   m_iWidth(200),
00072   m_iHeight(500)
00073 {
00074   restorePreferences();
00075   pLogger->setLogToFileFlag(m_Pref_bToFile);
00076   pLogger->blockDumpToFile(FALSE);
00077 }
00078 
00079 CPlugin::~CPlugin()
00080 {
00081   savePreferences();
00082 }
00083 
00084 static char szSection[] = SECTION_PREFERENCES;
00085 static char szYes[] = ENTRY_YES;
00086 static char szNo[] = ENTRY_NO;
00087 
00088 void CPlugin::restorePreferences()
00089 {
00090   char szFileName[_MAX_PATH];
00091   GetINIFileName(m_hInst, szFileName, sizeof(szFileName));
00092 
00093   char sz[256];
00094   XP_GetPrivateProfileString(szSection, KEY_AUTO_MODE, ENTRY_NO, sz, sizeof(sz), szFileName);
00095   m_Pref_ShowGUI = (strcmpi(sz, ENTRY_YES) == 0) ? sg_auto : sg_manual;
00096 
00097   XP_GetPrivateProfileString(szSection, KEY_LOG_FILE, "Test.log", sz, sizeof(sz), szFileName);
00098   strcpy(m_Pref_szLogFile, sz);
00099 
00100   XP_GetPrivateProfileString(szSection, KEY_SCRIPT_FILE, "Test.pts", sz, sizeof(sz), szFileName);
00101   strcpy(m_Pref_szScriptFile, sz);
00102 
00103   XP_GetPrivateProfileString(szSection, KEY_TO_FILE, ENTRY_NO, sz, sizeof(sz), szFileName);
00104   m_Pref_bToFile = (strcmpi(sz, ENTRY_YES) == 0) ? TRUE : FALSE;
00105 
00106   XP_GetPrivateProfileString(szSection, KEY_TO_FRAME, ENTRY_YES, sz, sizeof(sz), szFileName);
00107   m_Pref_bToFrame = (strcmpi(sz, ENTRY_YES) == 0) ? TRUE : FALSE;
00108 
00109   XP_GetPrivateProfileString(szSection, KEY_FLUSH_NOW, ENTRY_YES, sz, sizeof(sz), szFileName);
00110   m_Pref_bFlushNow = (strcmpi(sz, ENTRY_YES) == 0) ? TRUE : FALSE;
00111 
00112   XP_GetPrivateProfileString(szSection, KEY_REMEMBER_LAST_API_CALL, ENTRY_YES, sz, sizeof(sz), szFileName);
00113   m_Pref_bRememberLastCall = (strcmpi(sz, ENTRY_YES) == 0) ? TRUE : FALSE;
00114 
00115   XP_GetPrivateProfileString(szSection, KEY_STAND_ALONE, ENTRY_NO, sz, sizeof(sz), szFileName);
00116   m_Pref_bStandAlone = (strcmpi(sz, ENTRY_YES) == 0) ? TRUE : FALSE;
00117 
00118   XP_GetPrivateProfileString(szSection, KEY_AUTOSTART_SCRIPT, ENTRY_NO, sz, sizeof(sz), szFileName);
00119   m_Pref_bAutoStartScript = (strcmpi(sz, ENTRY_YES) == 0) ? TRUE : FALSE;
00120 }
00121 
00122 void CPlugin::savePreferences()
00123 {
00124   char szFileName[_MAX_PATH];
00125   GetINIFileName(m_hInst, szFileName, sizeof(szFileName));
00126 
00127   XP_WritePrivateProfileString(szSection, KEY_AUTO_MODE, (m_Pref_ShowGUI == sg_auto) ? szYes : szNo, szFileName);
00128   XP_WritePrivateProfileString(szSection, KEY_LOG_FILE, m_Pref_szLogFile, szFileName);
00129   XP_WritePrivateProfileString(szSection, KEY_SCRIPT_FILE, m_Pref_szScriptFile, szFileName);
00130   XP_WritePrivateProfileString(szSection, KEY_TO_FILE, m_Pref_bToFile ? szYes : szNo, szFileName);
00131   XP_WritePrivateProfileString(szSection, KEY_TO_FRAME, m_Pref_bToFrame ? szYes : szNo, szFileName);
00132   XP_WritePrivateProfileString(szSection, KEY_FLUSH_NOW, m_Pref_bFlushNow ? szYes : szNo, szFileName);
00133   XP_WritePrivateProfileString(szSection, KEY_REMEMBER_LAST_API_CALL, m_Pref_bRememberLastCall ? szYes : szNo, szFileName);
00134   XP_WritePrivateProfileString(szSection, KEY_STAND_ALONE, m_Pref_bStandAlone ? szYes : szNo, szFileName);
00135   XP_WritePrivateProfileString(szSection, KEY_AUTOSTART_SCRIPT, m_Pref_bAutoStartScript ? szYes : szNo, szFileName);
00136 }
00137 
00138 void CPlugin::updatePrefs(GUIPrefs prefs, int iValue, char * szValue)
00139 {
00140   switch(prefs)
00141   {
00142     case gp_mode:
00143       m_Pref_ShowGUI = (ShowGUI)iValue;
00144       break;
00145     case gp_logfile:
00146       if(szValue && (strlen(szValue) < sizeof(m_Pref_szLogFile)))
00147         strcpy(m_Pref_szLogFile, szValue);
00148       break;
00149     case gp_scriptfile:
00150       if(szValue && (strlen(szValue) < sizeof(m_Pref_szScriptFile)))
00151         strcpy(m_Pref_szScriptFile, szValue);
00152       break;
00153     case gp_tofile:
00154       m_Pref_bToFile = (BOOL)iValue;
00155       break;
00156     case gp_toframe:
00157       m_Pref_bToFrame = (BOOL)iValue;
00158       break;
00159     case gp_flush:
00160       m_Pref_bFlushNow = (BOOL)iValue;
00161       break;
00162     case gp_rememberlast:
00163       m_Pref_bRememberLastCall = (BOOL)iValue;
00164       break;
00165     case gp_standalone:
00166       m_Pref_bStandAlone = (BOOL)iValue;
00167       break;
00168     case gp_autostartscript:
00169       m_Pref_bAutoStartScript = (BOOL)iValue;
00170       break;
00171     default:
00172       break;
00173   }
00174 }
00175 
00176 void CPlugin::getModulePath(LPSTR szPath, int iSize)
00177 {
00178   GetModulePath(m_hInst, szPath, iSize);
00179 }
00180 
00181 void CPlugin::getLogFileName(LPSTR szLogFileName, int iSize)
00182 {
00183   if(getMode() == NP_EMBED)
00184   {
00185     char sz[256];
00186     getModulePath(szLogFileName, iSize);
00187     Edit_GetText(GetDlgItem(m_hWnd, IDC_EDIT_LOG_FILE_NAME), sz, sizeof(sz));
00188     if(!strlen(sz))
00189       strcpy(sz, m_Pref_szLogFile);
00190     strcat(szLogFileName, sz);
00191   }
00192   else
00193     CPluginBase::getLogFileName(szLogFileName, iSize);
00194 }
00195 
00196 BOOL CALLBACK NP_LOADDS TesterDlgProc(HWND, UINT, WPARAM, LPARAM);
00197 
00198 static char szStandAlonePluginWindowClassName[] = "StandAloneWindowClass";
00199 
00200 BOOL CPlugin::initStandAlone()
00201 {
00202   HWND hWndParent = NULL;
00203 
00204   // ensure window class
00205   WNDCLASS wc;
00206   wc.style         = 0; 
00207   wc.lpfnWndProc   = DefWindowProc; 
00208   wc.cbClsExtra    = 0; 
00209   wc.cbWndExtra    = 0; 
00210   wc.hInstance     = hInst; 
00211   wc.hIcon         = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON_APP)); 
00212   wc.hCursor       = LoadCursor(0, IDC_ARROW); 
00213   wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
00214   wc.lpszMenuName  = NULL; 
00215   wc.lpszClassName = szStandAlonePluginWindowClassName;
00216 
00217   // just register the window class, if class already exists GetLastError() 
00218   // will return ERROR_CLASS_ALREADY_EXISTS, let's not care about it
00219   RegisterClass(&wc);
00220 
00221   hWndParent = CreateWindow(szStandAlonePluginWindowClassName, 
00222                             "The Tester Plugin", 
00223                             WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE | WS_MINIMIZEBOX, 
00224                             0, 0, 800, 600, 
00225                             GetDesktopWindow(), NULL, m_hInst, NULL);
00226 
00227 //  m_hWndStandAloneLogWindow = CreateWindow("LISTBOX", "", 
00228   //                                          WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL | LBS_NOINTEGRALHEIGHT, 
00229     //                                        200, 3, 590, 562, 
00230       //                                      hWndParent, NULL, m_hInst, NULL);
00231 
00232   m_hWndStandAloneLogWindow = CreateWindow("EDIT", "", 
00233                                             WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_READONLY,
00234                                             200, 3, 590, 562, 
00235                                             hWndParent, NULL, m_hInst, NULL);
00236   if(!IsWindow(hWndParent))
00237     return FALSE;
00238 
00239   m_hWndParent = hWndParent;
00240 
00241   HFONT hFont = GetStockFont(DEFAULT_GUI_FONT);
00242   SetWindowFont(m_hWndStandAloneLogWindow, hFont, FALSE);
00243 
00244   CreateDialogParam(m_hInst, MAKEINTRESOURCE(IDD_DIALOG_TESTER), m_hWndParent, (DLGPROC)TesterDlgProc, (LPARAM)this);
00245 
00246   m_bPluginReady = (m_hWnd != NULL);
00247 
00248   return m_bPluginReady;
00249 }
00250 
00251 void CPlugin::shutStandAlone()
00252 {
00253   // we don't care  about unregistering window class, let it be in the system
00254 
00255   if (isStandAlone() && m_hWndParent) 
00256     DestroyWindow(m_hWndParent);
00257 
00258   m_bPluginReady = FALSE;
00259 }
00260 
00261 BOOL CPlugin::initEmbed(DWORD dwInitData)
00262 {
00263   if (m_bPluginReady)
00264     return TRUE;
00265 
00266   HWND hWndParent = (HWND)dwInitData;
00267 
00268   if(!IsWindow(hWndParent))
00269     return FALSE;
00270 
00271   m_hWndParent = hWndParent;
00272 
00273   CreateDialogParam(m_hInst, MAKEINTRESOURCE(IDD_DIALOG_TESTER), m_hWndParent, (DLGPROC)TesterDlgProc, (LPARAM)this);
00274 
00275   m_bPluginReady = (m_hWnd != NULL);
00276 
00277   return m_bPluginReady;
00278 }
00279 
00280 BOOL CPlugin::initFull(DWORD dwInitData)
00281 {
00282   m_bPluginReady = CPluginBase::initFull(dwInitData);
00283   return m_bPluginReady;
00284 }
00285 
00286 void CPlugin::shutEmbed()
00287 {
00288   if(m_hWnd != NULL)
00289   {
00290     DestroyWindow(m_hWnd);
00291     m_hWnd = NULL;
00292   }
00293 
00294   m_bPluginReady = FALSE;
00295 }
00296 
00297 void CPlugin::shutFull()
00298 {
00299   CPluginBase::shutFull();
00300   m_bPluginReady = FALSE;
00301 }
00302 
00303 BOOL CPlugin::isInitialized()
00304 {
00305   return m_bPluginReady;
00306 }
00307 
00308 void CPlugin::onInit(HWND hWnd, HWND hWndManual, HWND hWndAuto)
00309 {
00310   assert(hWnd != NULL);
00311   assert(hWndManual != NULL);
00312   assert(hWndAuto != NULL);
00313 
00314   m_hWnd = hWnd;
00315   m_hWndManual = hWndManual;
00316   m_hWndAuto = hWndAuto;
00317 
00318   pLogger->setShowImmediatelyFlag(IsDlgButtonChecked(m_hWnd, IDC_CHECK_SHOW_LOG) == BST_CHECKED);
00319   pLogger->setLogToFrameFlag(IsDlgButtonChecked(m_hWnd, IDC_CHECK_LOG_TO_FRAME) == BST_CHECKED);
00320   pLogger->setLogToFileFlag(IsDlgButtonChecked(m_hWnd, IDC_CHECK_LOG_TO_FILE) == BST_CHECKED);
00321 }
00322 
00323 BOOL CPlugin::isStandAlone()
00324 {
00325   return m_Pref_bStandAlone;
00326 }
00327 
00328 void CPlugin::outputToNativeWindow(LPSTR szString)
00329 {
00330   if (!m_hWndStandAloneLogWindow)
00331     return;
00332 
00333   // VERSION FOR EDIT BOX
00334 
00335   static char text[16384];
00336 
00337   if (strlen(szString)) {
00338     int length = Edit_GetTextLength(m_hWndStandAloneLogWindow);
00339     if ((length + strlen(szString)) > sizeof(text))
00340       strcpy(text, szString);
00341     else {
00342       Edit_GetText(m_hWndStandAloneLogWindow, text, sizeof(text));
00343       strcat(text, szString);
00344     }
00345 
00346     Edit_SetText(m_hWndStandAloneLogWindow, text);
00347     int lines = Edit_GetLineCount(m_hWndStandAloneLogWindow);
00348     Edit_Scroll(m_hWndStandAloneLogWindow, lines, 0);
00349   }
00350   else
00351     Edit_SetText(m_hWndStandAloneLogWindow, ""); // clear the window
00352 
00353 /*
00354   // VERSION FOR LISTBOX
00355 
00356   // parse the string and add lines to the listbox
00357   char *p = 0;
00358   char *newline = szString;
00359 
00360   for (;;) {
00361     // could be either \r\n or \n, we don't need them at all for the listbox
00362     p = strchr(newline, '\n');
00363     if (!p)
00364       break;
00365 
00366     if (*(p - 1) == '\r')
00367       *(p - 1) = '\0';
00368     else
00369       *p = '\0';
00370 
00371     char line[512];
00372     strcpy(line, newline);
00373 
00374     ListBox_AddString(m_hWndStandAloneLogWindow, line);
00375     int count = ListBox_GetCount(m_hWndStandAloneLogWindow);
00376     if(count == 32767)
00377       ListBox_ResetContent(m_hWndStandAloneLogWindow);
00378     ListBox_SetCaretIndex(m_hWndStandAloneLogWindow, count - 1);
00379     UpdateWindow(m_hWndStandAloneLogWindow);
00380 
00381     // restore the original
00382     if (*p == '\n')
00383       *(p - 1) = '\r';
00384     else
00385       *p = '\n';
00386 
00387     newline = ++p;
00388   }
00389 */
00390 }
00391 
00392 int CPlugin::messageBox(LPSTR szMessage, LPSTR szTitle, UINT uStyle)
00393 {
00394   return MessageBox(m_hWnd, szMessage, szTitle, uStyle);
00395 }
00396 
00397 void CPlugin::onDestroy()
00398 {
00399   m_hWnd = NULL;
00400 }
00401 
00402 void CPlugin::onLogToFile(BOOL bLogToFile)
00403 {
00404   pLogger->setLogToFileFlag(bLogToFile);
00405   if(!bLogToFile)
00406     pLogger->closeLogToFile();
00407 }
00408 
00409 const HINSTANCE CPlugin::getInstance()
00410 {
00411   return m_hInst;
00412 }
00413 
00414 const HWND CPlugin::getWindow()
00415 {
00416   return m_hWnd;
00417 }
00418 
00419 const HWND CPlugin::getParent()
00420 {
00421   return m_hWndParent;
00422 }
00423 
00424 void CPlugin::showGUI(ShowGUI sg)
00425 {
00426   switch (sg)
00427   {
00428     case sg_manual:
00429       ShowWindow(m_hWndManual, SW_SHOW);
00430       ShowWindow(m_hWndAuto, SW_HIDE);
00431       break;
00432     case sg_auto:
00433       ShowWindow(m_hWndManual, SW_HIDE);
00434       ShowWindow(m_hWndAuto, SW_SHOW);
00435       break;
00436     default:
00437       assert(0);
00438       break;
00439   }
00440 }
00441 
00442 DWORD CPlugin::makeNPNCall(NPAPI_Action action, DWORD dw1, DWORD dw2, DWORD dw3, 
00443                            DWORD dw4, DWORD dw5, DWORD dw6, DWORD dw7)
00444 {
00445   DWORD dwRet = CPluginBase::makeNPNCall(action, dw1, dw2, dw3, dw4, dw5, dw6, dw7);
00446 
00447     // update GUI for Manual mode action
00448   if((getMode() == NP_EMBED) && (IsWindowVisible(m_hWndManual)))
00449   {
00450     switch (action)
00451     {
00452       case action_npn_new_stream:
00453       case action_npn_destroy_stream:
00454       case action_npn_mem_alloc:
00455       case action_npn_mem_free:
00456         updateUI(m_hWndManual);
00457         break;
00458       default:
00459         break;
00460     }
00461   }
00462 
00463   return dwRet;
00464 }
00465 
00466 void CPlugin::autoStartScriptIfNeeded()
00467 {
00468   if (!m_Pref_bAutoStartScript)
00469     return;
00470 
00471   CScripter scripter;
00472   scripter.associate(this);
00473 
00474   char szFileName[_MAX_PATH];
00475   getModulePath(szFileName, sizeof(szFileName));
00476   strcat(szFileName, m_Pref_szScriptFile);
00477 
00478   if(scripter.createScriptFromFile(szFileName))
00479   {
00480     int iRepetitions = scripter.getCycleRepetitions();
00481     int iDelay = scripter.getCycleDelay();
00482     if(iDelay < 0)
00483       iDelay = 0;
00484 
00485     assert(pLogger != NULL);
00486     pLogger->resetStartTime();
00487 
00488     for(int i = 0; i < iRepetitions; i++)
00489     {
00490       scripter.executeScript();
00491       if(iDelay != 0)
00492         XP_Sleep(iDelay);
00493     }
00494   }
00495   else
00496   {
00497     MessageBox(NULL, "Script file not found or invalid", "", MB_OK | MB_ICONERROR);
00498   }
00499 }
00500 
00501 // Creation and destruction
00502 CPluginBase * CreatePlugin(NPP instance, uint16 mode)
00503 {
00504   CPlugin * pPlugin = new CPlugin(instance, mode);
00505   return (CPluginBase *)pPlugin;
00506 }
00507 
00508 void DestroyPlugin(CPluginBase * pPlugin)
00509 {
00510   if(pPlugin != NULL)
00511     delete (CPlugin *)pPlugin;
00512 }