Back to index

lightning-sunbird  0.9+nobinonly
plugin.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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 Communicator client 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 #define INCL_GPI
00039 #define INCL_WIN
00040 #include <os2.h>
00041 #include <assert.h>
00042 
00043 #include "npnulos2.h"
00044 
00045 #include "plugin.h"
00046 #include "utils.h"
00047 #include "dialogs.h"
00048 #include "dbg.h"
00049 #include "nsIServiceManager.h"
00050 #include "nsIPref.h"
00051 
00052 nsIServiceManager * gServiceManager = NULL;
00053 
00054 static char szNullPluginWindowClassName[] = CLASS_NULL_PLUGIN;
00055 
00056 MRESULT EXPENTRY PluginWndProc(HWND, ULONG, MPARAM, MPARAM);
00057 
00058 static char szDefaultPluginFinderURL[] = DEFAULT_PLUGINFINDER_URL;
00059 static char szPageUrlForJavaScript[] = PAGE_URL_FOR_JAVASCRIPT;
00060 static char szPageUrlForJVM[] = JVM_SMARTUPDATE_URL;
00061 //static char szPluginFinderCommandFormatString[] = PLUGINFINDER_COMMAND;
00062 static char szPluginFinderCommandBeginning[] = PLUGINFINDER_COMMAND_BEGINNING;
00063 static char szPluginFinderCommandEnd[] = PLUGINFINDER_COMMAND_END;
00064 
00065 BOOL RegisterNullPluginWindowClass()
00066 {
00067   return WinRegisterClass( (HAB)0, szNullPluginWindowClassName, (PFNWP)PluginWndProc, 0, sizeof(ULONG));
00068 }
00069 
00070 void UnregisterNullPluginWindowClass()
00071 {
00072 }
00073 
00074 /*********************************************/
00075 /*                                           */
00076 /*       CPlugin class implementation        */
00077 /*                                           */
00078 /*********************************************/
00079 
00080 CPlugin::CPlugin(HMODULE hInst, 
00081                  NPP pNPInstance, 
00082                  SHORT wMode, 
00083                  NPMIMEType pluginType, 
00084                  PSZ szPageURL, 
00085                  PSZ szFileURL, 
00086                  PSZ szFileExtension,
00087                  BOOL bHidden) :
00088   m_hInst(hInst),
00089   m_pNPInstance(pNPInstance),
00090   m_wMode(wMode),
00091   m_hWnd(NULL),
00092   m_hWndParent(NULL),
00093   m_hIcon(NULL),
00094   m_szURLString(NULL),
00095   m_szCommandMessage(NULL),
00096   m_bWaitingStreamFromPFS(FALSE),
00097   m_PFSStream(NULL),
00098   m_bHidden(bHidden),
00099   m_pNPMIMEType(NULL),
00100   m_szPageURL(NULL),
00101   m_szFileURL(NULL),
00102   m_szFileExtension(NULL),
00103   m_hWndDialog(NULL),
00104   m_bOnline(TRUE),
00105   m_bJava(TRUE),
00106   m_bJavaScript(TRUE),
00107   m_bSmartUpdate(TRUE)
00108 {
00109   dbgOut1("CPlugin::CPlugin()");
00110   assert(m_hInst != NULL);
00111   assert(m_pNPInstance != NULL);
00112 
00113   if(pluginType && *pluginType)
00114   {
00115     m_pNPMIMEType = (NPMIMEType)new char[strlen((PSZ)pluginType) + 1];
00116     if(m_pNPMIMEType != NULL)
00117       strcpy((PSZ)m_pNPMIMEType, pluginType);
00118   }
00119 
00120   if(szPageURL && *szPageURL)
00121   {
00122     m_szPageURL = new char[strlen(szPageURL) + 1];
00123     if(m_szPageURL != NULL)
00124       strcpy(m_szPageURL, szPageURL);
00125   }
00126   
00127   if(szFileURL && *szFileURL)
00128   {
00129     m_szFileURL = new char[strlen(szFileURL) + 1];
00130     if(m_szFileURL != NULL)
00131       strcpy(m_szFileURL, szFileURL);
00132   }
00133 
00134   if(szFileExtension && *szFileExtension)
00135   {
00136     m_szFileExtension = new char[strlen(szFileExtension) + 1];
00137     if(m_szFileExtension != NULL)
00138       strcpy(m_szFileExtension, szFileExtension);
00139   }
00140 
00141   m_hIcon = WinLoadPointer(HWND_DESKTOP, m_hInst, IDI_PLUGICON);
00142 
00143   char szString[1024] = {'\0'};
00144   WinLoadString((HAB)0, m_hInst, IDS_CLICK_TO_GET, sizeof(szString), szString);
00145   if(*szString)
00146   {
00147     m_szCommandMessage = new char[strlen(szString) + 1];
00148     if(m_szCommandMessage != NULL)
00149       strcpy(m_szCommandMessage, szString);
00150   }
00151 }
00152 
00153 CPlugin::~CPlugin()
00154 {
00155   dbgOut1("CPlugin::~CPlugin()");
00156 
00157   if(m_pNPMIMEType != NULL)
00158   {
00159     delete [] m_pNPMIMEType;
00160     m_pNPMIMEType = NULL;
00161   }
00162 
00163   if(m_szPageURL != NULL)
00164   {
00165     delete [] m_szPageURL;
00166     m_szPageURL = NULL;
00167   }
00168 
00169   if(m_szFileURL != NULL)
00170   {
00171     delete [] m_szFileURL;
00172     m_szFileURL = NULL;
00173   }
00174 
00175   if(m_szFileExtension != NULL)
00176   {
00177     delete [] m_szFileExtension;
00178     m_szFileExtension = NULL;
00179   }
00180 
00181   if(m_szURLString != NULL)
00182   {
00183     delete [] m_szURLString;
00184     m_szURLString = NULL;
00185   }
00186 
00187   if(m_hIcon != NULL)
00188   {
00189     WinDestroyPointer(m_hIcon);
00190     m_hIcon = NULL;
00191   }
00192 
00193   if(m_szCommandMessage != NULL)
00194   {
00195     delete [] m_szCommandMessage;
00196     m_szCommandMessage = NULL;
00197   }
00198 }
00199 
00200 BOOL CPlugin::init(HWND hWndParent)
00201 {
00202   dbgOut1("CPlugin::init()");
00203 
00204   nsISupports * sm = NULL;
00205   nsIPref * nsPrefService = NULL;
00206   PRBool bSendUrls = PR_FALSE; // default to false if problem getting pref
00207 
00208   // note that Mozilla will add reference, so do not forget to release
00209   NPN_GetValue(NULL, NPNVserviceManager, &sm);
00210 
00211   // do a QI on the service manager we get back to ensure it's the one we are expecting
00212   if(sm) {
00213     sm->QueryInterface(NS_GET_IID(nsIServiceManager), (void**)&gServiceManager);
00214     NS_RELEASE(sm);
00215   }
00216   
00217   if (gServiceManager) {
00218     // get service using its contract id and use it to allocate the memory
00219     gServiceManager->GetServiceByContractID(NS_PREF_CONTRACTID, NS_GET_IID(nsIPref), (void **)&nsPrefService);
00220     if(nsPrefService) {      
00221       nsPrefService->GetBoolPref("application.use_ns_plugin_finder", &bSendUrls);
00222       NS_RELEASE(nsPrefService);
00223     }
00224   }
00225   m_bSmartUpdate = bSendUrls;
00226 
00227   if(!m_bHidden)
00228   {
00229     assert(WinIsWindow((HAB)0, hWndParent));
00230 
00231     if(WinIsWindow((HAB)0, hWndParent))
00232       m_hWndParent = hWndParent;
00233 
00234     RECTL rcParent;
00235     WinQueryWindowRect(m_hWndParent, &rcParent);
00236 
00237     m_hWnd = WinCreateWindow(m_hWndParent,
00238                              szNullPluginWindowClassName, 
00239                              "NULL Plugin", 
00240                              0,
00241                              0,0, rcParent.xRight, rcParent.yTop,
00242                              m_hWndParent,
00243                              HWND_TOP,
00244                              255,
00245                              (PVOID)this,
00246                              0);
00247 
00248     WinSetPresParam(m_hWnd, PP_FONTNAMESIZE, 10, (PVOID)"9.WarpSans");
00249 
00250     assert(m_hWnd != NULL);
00251     if((m_hWnd == NULL) || (!WinIsWindow((HAB)0, m_hWnd)))
00252       return FALSE;
00253 
00254 //    UpdateWindow(m_hWnd);
00255     WinShowWindow(m_hWnd, TRUE);
00256   }
00257 
00258   if(IsNewMimeType((PSZ)m_pNPMIMEType) || m_bHidden)
00259     showGetPluginDialog();
00260 
00261   return TRUE;
00262 }
00263 
00264 void CPlugin::shut()
00265 {
00266   dbgOut1("CPlugin::shut()");
00267 
00268   if(m_hWndDialog != NULL)
00269   {
00270     WinDismissDlg(m_hWndDialog, DID_CANCEL);
00271     m_hWndDialog = NULL;
00272   }
00273 
00274   if(m_hWnd != NULL)
00275   {
00276     WinDestroyWindow(m_hWnd);
00277     m_hWnd = NULL;
00278   }
00279 
00280   // we should release the service manager
00281   NS_IF_RELEASE(gServiceManager);
00282   gServiceManager = NULL;
00283 }
00284 
00285 HWND CPlugin::getWindow()
00286 {
00287   return m_hWnd;
00288 }
00289 
00290 BOOL CPlugin::useDefaultURL_P()
00291 {
00292   if((m_szPageURL == NULL) && (m_szFileURL == NULL))
00293     return TRUE;
00294   else
00295     return FALSE;
00296 }
00297 
00298 BOOL CPlugin::doSmartUpdate_P()
00299 {
00300   // due to current JavaScript problems never do it smart for now 5.1.98
00301   return FALSE;
00302 
00303   if(m_bOnline && m_bJava && m_bJavaScript && m_bSmartUpdate && useDefaultURL_P())
00304     return TRUE;
00305   else
00306     return FALSE;
00307 }
00308 
00309 PSZ CPlugin::createURLString()
00310 {
00311   if(m_szURLString != NULL)
00312   {
00313     delete [] m_szURLString;
00314     m_szURLString = NULL;
00315   }
00316 
00317   // check if there is file URL first
00318   if(!m_bSmartUpdate && m_szFileURL != NULL)
00319   {
00320     m_szURLString = new char[strlen(m_szFileURL) + 1];
00321     if(m_szURLString == NULL)
00322       return NULL;
00323     strcpy(m_szURLString, m_szFileURL);
00324     return m_szURLString;
00325   }
00326   
00327   // if not get the page URL
00328   char * szAddress = NULL;
00329   char *urlToOpen = NULL;
00330   char contentTypeIsJava = 0;
00331 
00332   if (NULL != m_pNPMIMEType) {
00333     contentTypeIsJava = (0 == strcmp("application/x-java-vm",
00334                                  m_pNPMIMEType)) ? 1 : 0;
00335   }
00336   
00337   if(!m_bSmartUpdate && m_szPageURL != NULL && !contentTypeIsJava)
00338   {
00339     szAddress = new char[strlen(m_szPageURL) + 1];
00340     if(szAddress == NULL)
00341       return NULL;
00342     strcpy(szAddress, m_szPageURL);
00343 
00344     m_szURLString = new char[strlen(szAddress) + 1 +
00345                              strlen((PSZ)m_pNPMIMEType) + 1];
00346 
00347     if(m_szURLString == NULL)
00348       return NULL;
00349 
00350     // Append the MIME type to the URL
00351     sprintf(m_szURLString, "%s?%s", szAddress, (PSZ)m_pNPMIMEType);
00352   }
00353   else // default
00354   {
00355     if(!m_bSmartUpdate)
00356     {
00357       urlToOpen = szDefaultPluginFinderURL;
00358       
00359       if (contentTypeIsJava) {
00360         urlToOpen = szPageUrlForJVM;
00361       }
00362 
00363       szAddress = new char[strlen(urlToOpen) + 1];
00364       if(szAddress == NULL)
00365         return NULL;
00366       strcpy(szAddress, urlToOpen);
00367 
00368       m_szURLString = new char[strlen(szAddress) + 10 +
00369                                strlen((PSZ)m_pNPMIMEType) + 1];
00370 
00371       if(m_szURLString == NULL)
00372         return NULL;
00373 
00374       // Append the MIME type to the URL
00375       sprintf(m_szURLString, "%s?mimetype=%s",
00376               szAddress, (PSZ)m_pNPMIMEType);
00377     }
00378     else
00379     {
00380       urlToOpen = szPageUrlForJavaScript;
00381 
00382       if (contentTypeIsJava) {
00383        urlToOpen = szPageUrlForJVM;
00384       }
00385 
00386       // wsprintf doesn't like null pointers on NT or 98, so
00387       // change any null string pointers to null strings
00388       if (!m_szPageURL) {
00389         m_szPageURL = new char[1];
00390         m_szPageURL[0] = '\0';
00391       }
00392 
00393       if (!m_szFileURL) {
00394         m_szFileURL = new char[1];
00395         m_szFileURL[0] = '\0';
00396       }
00397 
00398       m_szURLString = new char[strlen(szPluginFinderCommandBeginning) + strlen(urlToOpen) + 10 + 
00399                                strlen((PSZ)m_pNPMIMEType) + 13 +
00400                                strlen((PSZ)m_szPageURL) + 11 + 
00401                                strlen((PSZ)m_szFileURL) +
00402                                strlen(szPluginFinderCommandEnd) + 1];
00403       sprintf(m_szURLString, "%s%s?mimetype=%s&pluginspage=%s&pluginurl=%s%s",
00404               szPluginFinderCommandBeginning, urlToOpen, 
00405               (PSZ)m_pNPMIMEType, m_szPageURL, m_szFileURL, szPluginFinderCommandEnd);
00406     }
00407   }
00408 
00409   if(szAddress != NULL)
00410     delete [] szAddress;
00411 
00412   return m_szURLString;
00413 }
00414 
00415 void CPlugin::getPluginRegular()
00416 {
00417   assert(m_bOnline);
00418 
00419   char * szURL = createURLString();
00420 
00421   assert(szURL != NULL);
00422   if(szURL == NULL)
00423     return;
00424 
00425   dbgOut3("CPlugin::getPluginRegular(), %#08x '%s'", m_pNPInstance, szURL);
00426 
00427   NPN_GetURL(m_pNPInstance, szURL, NULL);
00428   m_bWaitingStreamFromPFS = TRUE;
00429 }
00430 
00431 void CPlugin::getPluginSmart()
00432 {
00433 /*
00434   static char szJSString[2048];
00435 
00436   sprintf(szJSString, 
00437            szPluginFinderCommandFormatString, 
00438            szDefaultPluginFinderURL, 
00439            m_pNPMIMEType, 
00440            (m_szFileExtension != NULL) ? m_szFileExtension : szDefaultFileExt);
00441 
00442   dbgOut3("%#08x '%s'", m_pNPInstance, szJSString);
00443 
00444   assert(*szJSString);
00445 
00446   NPN_GetURL(m_pNPInstance, szJSString, "smartupdate_plugin_finder");
00447 */
00448 }
00449 
00450 void CPlugin::showGetPluginDialog()
00451 {
00452   assert(m_pNPMIMEType != NULL);
00453   if(m_pNPMIMEType == NULL)
00454     return;
00455 
00456   // Get environment
00457   BOOL bOffline = FALSE;
00458 
00459   NPN_GetValue(m_pNPInstance, NPNVisOfflineBool, (void *)&bOffline);
00460   NPN_GetValue(m_pNPInstance, NPNVjavascriptEnabledBool, (void *)&m_bJavaScript);
00461   //NPN_GetValue(m_pNPInstance, NPNVasdEnabledBool, (void *)&m_bSmartUpdate);
00462 
00463   m_bOnline = !bOffline;
00464 
00465 #ifdef OJI
00466   if(m_bOnline && m_bJavaScript && m_bSmartUpdate && useDefaultURL_P())
00467   {
00468     JRIEnv *penv = NPN_GetJavaEnv();
00469     m_bJava = (penv != NULL);
00470   }
00471 #else
00472   m_bJava = FALSE;
00473 #endif
00474   
00475   dbgOut1("Environment:");
00476   dbgOut2("%s", m_bOnline ? "On-line" : "Off-line");
00477   dbgOut2("Java %s", m_bJava ? "Enabled" : "Disabled");
00478   dbgOut2("JavaScript %s", m_bJavaScript ? "Enabled" : "Disabled");
00479   dbgOut2("SmartUpdate %s", m_bSmartUpdate ? "Enabled" : "Disabled");
00480 
00481   if((!m_bSmartUpdate && (m_szPageURL != NULL) || (m_szFileURL != NULL)) || !m_bJavaScript)
00482   {
00483     int iRet = WinDlgBox(HWND_DESKTOP, m_hWnd, (PFNWP)GetPluginDialogProc, m_hInst,
00484                                   IDD_PLUGIN_DOWNLOAD, (PVOID)this);
00485     if(iRet != IDC_GET_PLUGIN)
00486       return;
00487   }
00488   else
00489      getPlugin();
00490 }
00491 
00492 void CPlugin::getPlugin()
00493 {
00494   if(m_szCommandMessage != NULL)
00495   {
00496     delete [] m_szCommandMessage;
00497     m_szCommandMessage = NULL;
00498   }
00499 
00500   char szString[1024] = {'\0'};
00501   WinLoadString((HAB)0, m_hInst, IDS_CLICK_WHEN_DONE, sizeof(szString), szString);
00502   if(*szString)
00503   {
00504     m_szCommandMessage = new char[strlen(szString) + 1];
00505     if(m_szCommandMessage != NULL)
00506       strcpy(m_szCommandMessage, szString);
00507   }
00508 
00509   WinInvalidateRect(m_hWnd, NULL, TRUE);
00510 //  UpdateWindow(m_hWnd);
00511 
00512   getPluginRegular();
00513 }
00514 
00515 //*******************
00516 // NP API handles
00517 //*******************
00518 void CPlugin::resize()
00519 {
00520   dbgOut1("CPlugin::resize()");
00521 }
00522 
00523 void CPlugin::print(NPPrint * pNPPrint)
00524 {
00525   dbgOut1("CPlugin::print()");
00526 
00527   if(pNPPrint == NULL)
00528     return;
00529 }
00530 
00531 void CPlugin::URLNotify(const char * szURL)
00532 {
00533   dbgOut2("CPlugin::URLNotify(), URL '%s'", szURL);
00534 
00535   NPStream * pStream = NULL;
00536   char buf[256];
00537 
00538   assert(m_hInst != NULL);
00539   assert(m_pNPInstance != NULL);
00540   
00541   int iSize = WinLoadString((HAB)0, m_hInst, IDS_GOING2HTML, sizeof(buf), buf);
00542 
00543   NPError rc = NPN_NewStream(m_pNPInstance, "text/html", "asd_plugin_finder", &pStream);
00544   if (rc != NPERR_NO_ERROR)
00545     return;
00546 
00547   //char buf[] = "<html>\n<body>\n\n<h2 align=center>NPN_NewStream / NPN_Write - This seems to work.</h2>\n\n</body>\n</html>";
00548   
00549   NPN_Write(m_pNPInstance, pStream, iSize, buf);
00550 
00551   NPN_DestroyStream(m_pNPInstance, pStream, NPRES_DONE);
00552 }
00553 
00554 NPError CPlugin::newStream(NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
00555 {
00556   if (!m_bWaitingStreamFromPFS)
00557     return NPERR_NO_ERROR;
00558 
00559   m_bWaitingStreamFromPFS = FALSE;
00560   m_PFSStream = stream;
00561 
00562   if (stream) {
00563     if (type && !strcmp(type, "application/x-xpinstall"))
00564       NPN_GetURL(m_pNPInstance, stream->url, "_self");
00565     else
00566       NPN_GetURL(m_pNPInstance, stream->url, "_blank");
00567   }
00568 
00569   return NPERR_NO_ERROR;
00570 }
00571 
00572 NPError CPlugin::destroyStream(NPStream *stream, NPError reason)
00573 {
00574   if (stream == m_PFSStream)
00575     m_PFSStream = NULL;
00576 
00577   return NPERR_NO_ERROR;
00578 }
00579 
00580 BOOL CPlugin::readyToRefresh()
00581 {
00582   char szString[1024] = {'\0'};
00583   WinLoadString((HAB)0, m_hInst, IDS_CLICK_WHEN_DONE, sizeof(szString), szString);
00584   if(m_szCommandMessage == NULL)
00585     return FALSE;
00586 
00587   return (strcmp(m_szCommandMessage, szString) == 0);
00588 }
00589 
00590 //***************************
00591 // Windows message handlers
00592 //***************************
00593 void CPlugin::onCreate(HWND hWnd)
00594 {
00595   m_hWnd = hWnd;
00596 }
00597 
00598 void CPlugin::onLButtonUp(HWND hWnd, int x, int y, UINT keyFlags)
00599 {
00600   if(!readyToRefresh())
00601     showGetPluginDialog();
00602   else
00603     NPN_GetURL(m_pNPInstance, "javascript:navigator.plugins.refresh(true)", "_self");
00604 }
00605 
00606 void CPlugin::onRButtonUp(HWND hWnd, int x, int y, UINT keyFlags)
00607 {
00608   if(!readyToRefresh())
00609     showGetPluginDialog();
00610   else
00611     NPN_GetURL(m_pNPInstance, "javascript:navigator.plugins.refresh(true)", "_self");
00612 }
00613 
00614 static void DrawCommandMessage(HPS hPS, PSZ szString, PRECTL lprc)
00615 {
00616   if(szString == NULL)
00617     return;
00618 
00619   POINTL ptls[5];
00620   GpiQueryTextBox(hPS, strlen(szString), szString, 5, ptls);
00621 
00622   /* If the text won't fit, don't draw anything */
00623   if (ptls[TXTBOX_CONCAT].x > lprc->xRight)
00624      return;
00625 
00626   RECTL rcText = rcText = *lprc; 
00627 
00628   /* Reduce top of rectangle by twice the icon size so the */
00629   /* text draws below the icon */
00630   rcText.yTop -= 80;
00631 
00632   WinDrawText(hPS, strlen(szString), szString, &rcText, 0, 0,
00633               DT_TEXTATTRS | DT_CENTER | DT_VCENTER);
00634 }
00635 
00636 #define INSET 1
00637 
00638 void CPlugin::onPaint(HWND hWnd)
00639 {
00640   RECTL rc;
00641   HDC hPS;
00642   int x, y;
00643 
00644   hPS = WinBeginPaint(hWnd, NULLHANDLE, NULL);
00645   GpiErase(hPS);
00646   WinQueryWindowRect(hWnd, &rc);
00647 
00648   x = (rc.xRight / 2) - (40 / 2);
00649   y = (rc.yTop / 2) - ((40) / 2);
00650 
00651   /* Only draw the icon if it fits */
00652   if(rc.xRight > (40 + 6 + INSET) && rc.yTop > (40 + 6 + INSET) )
00653   {
00654     if(m_hIcon != NULL)
00655       WinDrawPointer(hPS, x, y, m_hIcon, DP_NORMAL);
00656   }
00657 
00658   POINTL pt[5];
00659 
00660   // white piece
00661   GpiSetColor(hPS, CLR_WHITE);
00662 
00663   pt[0].x = 1 + INSET;
00664   pt[0].y = 1 + INSET;
00665   GpiMove(hPS, &pt[0]);
00666 
00667   pt[0].x = rc.xRight - 2 - INSET;
00668   pt[0].y = 1 + INSET;
00669   pt[1].x = rc.xRight - 2 - INSET;
00670   pt[1].y = rc.yTop -1 - INSET;
00671 
00672   GpiPolyLine(hPS, 2, pt);
00673 
00674   pt[0].x = 2 + INSET;
00675   pt[0].y = 3 + INSET;
00676   GpiMove(hPS, &pt[0]);
00677 
00678   pt[0].x = 2 + INSET;
00679   pt[0].y = rc.yTop - 3 - INSET;
00680   pt[1].x = rc.xRight - 4 - INSET;
00681   pt[1].y = rc.yTop - 3 - INSET;
00682 
00683   GpiPolyLine(hPS, 2, pt);
00684 
00685   // pale gray pieces 
00686   GpiSetColor(hPS, CLR_PALEGRAY);
00687   pt[0].x = INSET;
00688   pt[0].y = 1 + INSET;
00689   GpiMove(hPS, &pt[0]);
00690 
00691   pt[0].x = INSET;
00692   pt[0].y = rc.yTop - 1 - INSET;
00693   pt[1].x = rc.xRight - 2 - INSET;
00694   pt[1].y = rc.yTop - 1 - INSET;
00695 
00696   GpiPolyLine(hPS, 2, pt);
00697 
00698   pt[0].x = rc.xRight - 3 - INSET;
00699   pt[0].y = rc.yTop - 2 - INSET;
00700   GpiMove(hPS, &pt[0]);
00701 
00702   pt[0].x = rc.xRight - 3 - INSET;
00703   pt[0].y = 2 + INSET;
00704   pt[1].x = 2 + INSET;
00705   pt[1].y = 2 + INSET;
00706 
00707   GpiPolyLine(hPS, 2, pt);
00708 
00709   // dark gray piece
00710   GpiSetColor(hPS, CLR_DARKGRAY);
00711 
00712   pt[0].x = 1 + INSET;
00713   pt[0].y = 2 + INSET;
00714   GpiMove(hPS, &pt[0]);
00715 
00716   pt[0].x = 1 + INSET;
00717   pt[0].y = rc.yTop - 2 - INSET;
00718   pt[1].x = rc.xRight - 4 - INSET;
00719   pt[1].y = rc.yTop - 2 - INSET;
00720 
00721   GpiPolyLine(hPS, 2, pt);
00722 
00723   // black piece
00724   GpiSetColor(hPS, CLR_BLACK);
00725 
00726   pt[0].x = rc.xRight - 1 - INSET;
00727   pt[0].y = rc.yTop - 1 - INSET;
00728   GpiMove(hPS, &pt[0]);
00729 
00730   pt[0].x = rc.xRight - 1 - INSET;
00731   pt[0].y = 0 + INSET;
00732   pt[1].x = 0 + INSET;
00733   pt[1].y = 0 + INSET;
00734 
00735   GpiPolyLine(hPS, 2, pt);
00736 
00737   /* Offset rectangle by size of highlight(3) + 1 as well as inset */
00738   /* so that text is not drawn over the border */
00739   rc.xLeft += 4+INSET;
00740   rc.xRight -= 4+INSET;
00741   rc.yTop -= 4+INSET;
00742   rc.yBottom += 4+INSET;
00743 
00744   DrawCommandMessage(hPS, m_szCommandMessage, &rc);
00745 
00746   WinEndPaint (hPS);
00747 }
00748 
00749 //**************************
00750 // Plugin window procedure
00751 //**************************
00752 MRESULT EXPENTRY NP_LOADDS PluginWndProc(HWND hWnd, ULONG message, MPARAM mp1, MPARAM mp2)
00753 {
00754   CPlugin *pPlugin = (CPlugin *)WinQueryWindowULong(hWnd, QWL_USER);
00755                         
00756   switch(message)
00757   {
00758     case WM_CREATE:
00759       pPlugin = (CPlugin *)(((PCREATESTRUCT)mp2)->pCtlData);
00760       assert(pPlugin != NULL);
00761       WinSetWindowULong(hWnd, QWL_USER, (ULONG)pPlugin);
00762       pPlugin->onCreate(hWnd);
00763       return 0L;
00764     case WM_BUTTON1UP:
00765       pPlugin->onLButtonUp(hWnd,0,0,0);
00766       return 0L;
00767     case WM_BUTTON2UP:
00768       pPlugin->onRButtonUp(hWnd,0,0,0);
00769       return 0L;
00770     case WM_PAINT:
00771       pPlugin->onPaint(hWnd);
00772       return 0L;
00773     case WM_MOUSEMOVE:
00774       dbgOut1("MouseMove");
00775       break;
00776 
00777     default:
00778       break;
00779   }
00780   return(WinDefWindowProc(hWnd, message, mp1, mp2));
00781 }