home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / javaio.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  10.2 KB  |  442 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "stdafx.h"
  20.  
  21. #ifdef JAVA_WIN32
  22. // javaio.cpp : implementation file
  23. //
  24.  
  25. #include "mainfrm.h"
  26. #include "javaio.h"
  27. #include "io.h"
  28. #include "prthread.h"
  29. #include "prmon.h"
  30. #include "prfile.h"
  31. #include "prdump.h"
  32.  
  33. #ifdef _DEBUG
  34. #undef THIS_FILE
  35. static char BASED_CODE THIS_FILE[] = __FILE__;
  36. #endif
  37.  
  38.  
  39. // Maximun number of characters in the edit box before truncation occurs...
  40. #define MAX_JAVA_OUTPUT_SIZE        10000
  41. #define JAVA_IO_THREAD_STACK_SIZE   16768
  42.  
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CNSPRStream
  45.  
  46. PRIOMethods CNSPRStream::IOMethods = { CNSPRStream::InitMethod,
  47.                                        CNSPRStream::CloseMethod, 
  48.                                        CNSPRStream::ReadMethod, 
  49.                                        CNSPRStream::WriteMethod };
  50.  
  51. CNSPRStream::CNSPRStream(void)
  52. {
  53. }
  54.  
  55.  
  56. void CNSPRStream::MapFileDescriptor( PROSFD fd )
  57. {
  58.     PR_MapFileHandle( fd, (CNSPRStream *)this, &IOMethods );
  59. }
  60.  
  61.  
  62. int32 CNSPRStream::InitMethod(PRFileDesc * fd)
  63. {
  64.     int32 ret = -1; 
  65.  
  66.     if( fd->instance ) {
  67.         ret = ((CNSPRStream *)(fd->instance))->Init(fd);
  68.     } 
  69.     return( ret );
  70. }
  71.  
  72. int32 CNSPRStream::CloseMethod(PRFileDesc * fd)
  73. {
  74.     int32 ret = -1; 
  75.  
  76.     if( fd->instance ) {
  77.         ret = ((CNSPRStream *)(fd->instance))->Close(fd);
  78.     } 
  79.     return( ret );
  80. }
  81.  
  82.  
  83. int32 CNSPRStream::ReadMethod (PRFileDesc * fd, void *buf, int32 amount)
  84. {
  85.     int32 ret = -1; 
  86.  
  87.     if( fd->instance ) {
  88.         ret = ((CNSPRStream *)(fd->instance))->Read(fd, buf, amount);
  89.     } 
  90.     return( ret );
  91. }
  92.  
  93.  
  94. int32 CNSPRStream::WriteMethod(PRFileDesc * fd, const void *buf, int32 amount)
  95. {
  96.     int32 ret = -1; 
  97.  
  98.     if( fd->instance ) {
  99.         ret = ((CNSPRStream *)(fd->instance))->Write(fd, buf, amount);
  100.     } 
  101.     return( ret );
  102. }
  103.  
  104.  
  105.  
  106. /////////////////////////////////////////////////////////////////////////////
  107. // CJavaStdError
  108.  
  109. CJavaStdError::CJavaStdError(void)
  110. {
  111. }
  112.  
  113.  
  114. int32 CJavaStdError::Init(PRFileDesc *fd)
  115. {
  116.     return( fd->osfd );
  117. }
  118.  
  119.  
  120. int32 CJavaStdError::Close(PRFileDesc *fd)
  121. {
  122.     /* Never close stderr */
  123.     return( -1 );
  124. }
  125.  
  126.  
  127. int32 CJavaStdError::Read(PRFileDesc *fd, void *buf, int32 amount)
  128. {
  129.     /* Cannot read from stderr */
  130.     return( -1 );
  131. }
  132.  
  133.  
  134. int32 CJavaStdError::Write(PRFileDesc *fd, const void *buf, int32 amount)
  135. {
  136.     char buffer[1024];
  137.     int32 size;
  138.     int len;
  139.  
  140.     size = amount;
  141.     while (size) {
  142.         len = size > 1023 ? 1023 : size;
  143.         strncpy( buffer, (const char *)buf, len );
  144.         buffer[len] = '\0';
  145.         size -= len;
  146.  
  147.     //
  148.     // Calling MFC's MessageBox causes a deadlock if the calling thread is NOT the
  149.     // main UI thread of the navigator.  In practice, this is ALWAYS the case :-(
  150.     //
  151.     //AfxGetApp()->GetMainWnd()->MessageBox( buffer, "Java Error" );
  152.     (void)::MessageBox(NULL, buffer, "Java Error", MB_SETFOREGROUND | MB_OK);
  153.     }
  154.     return(amount);
  155. }
  156.  
  157. /////////////////////////////////////////////////////////////////////////////
  158. // CJavaStdOutput
  159.  
  160. #ifdef __BORLANDC__
  161.     static int64 SleepForever = 0x7fffffffffffffff;
  162. #else
  163.     static int64 SleepForever = LL_MAXINT;
  164. #endif
  165.  
  166. CJavaStdOutput::CJavaStdOutput(void)
  167. {
  168.     m_bAutoDelete = TRUE;
  169.  
  170.     m_pOwnThread  = 0;
  171.     m_ThreadId    = 0;
  172.     m_pWnd        = 0;
  173.     m_pOutputMon  = PR_NewNamedMonitor("output-monitor");
  174.  
  175.     m_msgWrite    = ::RegisterWindowMessage("NSPR_ConsoleWrite");
  176. }
  177.  
  178.  
  179. CJavaStdOutput::~CJavaStdOutput()
  180. {
  181.     if( m_pOutputMon ) {
  182.         PR_DestroyMonitor( m_pOutputMon );
  183.         m_pOutputMon = NULL;
  184.     }
  185. }
  186.  
  187.  
  188.  
  189.  
  190. BOOL CJavaStdOutput::PreTranslateMessage(MSG* pMsg)
  191. {
  192.     BOOL bResult;
  193.  
  194.     if( (pMsg->hwnd == 0) && (pMsg->message == m_msgWrite) ) {
  195.         m_pWnd->Display( (const char *)pMsg->lParam, (int32)pMsg->wParam );
  196.         bResult = TRUE;
  197.     } else {
  198.         bResult = CWinThread::PreTranslateMessage(pMsg);
  199.     }
  200.     return bResult;
  201. }
  202.  
  203.  
  204. BOOL CJavaStdOutput::InitInstance(void)
  205. {
  206.     PRThreadStack *ts;
  207.     BOOL bRet = FALSE;
  208.     CWinThread::InitInstance();
  209.  
  210.  
  211.     /* Set up the thread stack information */
  212.     ts = (PRThreadStack*) calloc(1, sizeof(PRThreadStack));
  213.     if( ts ) {
  214.         ts->stackSize = JAVA_IO_THREAD_STACK_SIZE;
  215.  
  216.         m_pOwnThread  = PR_AttachThread("Java IO", 15, ts);
  217.         m_pOwnThread->flags |= _PR_NO_SUSPEND;
  218.         m_ThreadId    = ::GetCurrentThreadId();
  219.  
  220.         if( m_pWnd = new CJavaOutputWnd() ) {
  221.             bRet = m_pWnd->Initialize( m_pOutputMon );
  222.         }
  223.  
  224.     }
  225.  
  226.     return(bRet);
  227. }
  228.     
  229. int CJavaStdOutput::ExitInstance(void)
  230. {
  231.     if( m_pWnd ) {
  232.         delete m_pWnd;
  233.         m_pWnd = NULL;
  234.     }
  235.     if( m_pOwnThread ) {
  236.         PR_DetachThread( m_pOwnThread );
  237.         m_pOwnThread = NULL;
  238.     }
  239.     return CWinThread::ExitInstance();
  240. }
  241.  
  242.  
  243. BOOL CJavaStdOutput::ToggleVisible(void)
  244. {
  245.     BOOL bRet = m_pWnd->IsWindowVisible();
  246.  
  247.     m_pWnd->ShowWindow( bRet ? SW_HIDE : SW_SHOW );
  248.     return( ! bRet );
  249. }
  250.  
  251. BOOL CJavaStdOutput::IsVisible(void)
  252. {
  253.     return m_pWnd->IsWindowVisible();
  254. }
  255.     
  256.  
  257.  
  258. int32 CJavaStdOutput::Init(PRFileDesc *fd)
  259. {
  260.     int32 ret = fd->osfd;
  261.  
  262.     if(! CreateThread(0, JAVA_IO_THREAD_STACK_SIZE, 0)) {
  263.         ret = -1;
  264.     }
  265.     return ret;
  266. }
  267.  
  268.  
  269. int32 CJavaStdOutput::Close(PRFileDesc *fd)
  270. {
  271.     ::PostThreadMessage( m_ThreadId, WM_QUIT, 0, 0 );
  272.     return 0;
  273. }
  274.  
  275.  
  276. int32 CJavaStdOutput::Read(PRFileDesc *fd, void *buf, int32 amount)
  277. {
  278.     /* Cannot read from stdout */
  279.     return( -1 );
  280. }
  281.  
  282.  
  283. int32 CJavaStdOutput::Write(PRFileDesc *fd, const void *buf, int32 amount)
  284. {
  285.     if( PR_CurrentThread() == m_pOwnThread ) {
  286.         m_pWnd->Display((const char *)buf, amount);
  287.     } else {
  288.         PR_EnterMonitor( m_pOutputMon );
  289.         ::PostThreadMessage( m_ThreadId, m_msgWrite, (WPARAM)amount, (LPARAM)buf );
  290.         PR_Wait( m_pOutputMon, SleepForever );
  291.         PR_ExitMonitor( m_pOutputMon);
  292.     }    
  293.     return( amount );
  294. }
  295.  
  296.  
  297.  
  298.  
  299. /////////////////////////////////////////////////////////////////////////////
  300. // CJavaOutputWnd
  301. CJavaOutputWnd::CJavaOutputWnd()
  302. {
  303.     m_pEdit      = 0;
  304.     m_pOutputMon = 0;
  305. }
  306.  
  307.  
  308. CJavaOutputWnd::~CJavaOutputWnd()
  309. {
  310.     if( m_pEdit ) {
  311.         delete m_pEdit;
  312.         m_pEdit = NULL;
  313.     }
  314. }
  315.  
  316.  
  317. BOOL CJavaOutputWnd::Initialize(PRMonitor *pMon)
  318. {
  319.     BOOL bRet;
  320.     RECT rect;
  321.  
  322.     m_pOutputMon = pMon;
  323.  
  324.     // Create the Frame Window
  325.     bRet = CFrameWnd::Create( NULL, "Java Output", 
  326.                    WS_OVERLAPPEDWINDOW | WS_VISIBLE );
  327.     if( bRet ) {
  328.         GetClientRect( &rect );
  329.  
  330.         // Create the Child Edit control used to display the text
  331.         m_pEdit = new CGenericEdit();
  332.         bRet = m_pEdit->Create( WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY,
  333.                                 rect, this, 100 );
  334.  
  335.         // Initialize the font for the edit control...
  336. ///        pContext = CMainFrame::GetLastActiveFrame()->GetMainContext()->GetContext();
  337. ///        if (INTL_CharSetType(pContext) == SINGLEBYTE) {
  338.             m_pEdit->SetFont(CFont::FromHandle((HFONT)GetStockObject(ANSI_FIXED_FONT)));
  339. ///        } else {
  340.             // For multibyte, we can not use ANSI font
  341. ///            m_pEdit->SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)));
  342. ///        }
  343.     }
  344.     return(bRet);
  345.     
  346. }
  347.  
  348.  
  349. void CJavaOutputWnd::Display( const char *buf, int32 amount )
  350. {
  351.     char buffer[90];
  352.     const char *pbuf;
  353.     int32 size;
  354.     int i, j, len;
  355.  
  356.     PR_EnterMonitor( m_pOutputMon );
  357.  
  358.     size = amount;
  359.     pbuf = (const char *)buf;
  360.     while (size) {
  361.         len = size > 79 ? 79 : size;
  362.         i = j = 0;
  363.         // Translate \n to \r\n for the edit box
  364.         while( j<len ) {
  365.             if( pbuf[i] == '\n' ) {
  366.                 buffer[j++] = '\r';
  367.             } 
  368.             buffer[j++] = pbuf[i++];
  369.         }
  370.         buffer[j] = '\0';
  371.         size -= i;
  372.         pbuf += i;
  373.  
  374.         // Truncate the edit box text if it is reaching its limit
  375.         len = m_pEdit->GetWindowTextLength();
  376.         if( len > MAX_JAVA_OUTPUT_SIZE ) {
  377.          len -= (MAX_JAVA_OUTPUT_SIZE/2);
  378.             i = j = 0;
  379.             while ( len > 0) {
  380.                 int k = m_pEdit->LineLength(j++);
  381.  
  382.                 len -= k;
  383.                 i   += k;
  384.             }
  385.             m_pEdit->SetSel( 0, i, TRUE );
  386.             m_pEdit->ReplaceSel( "" );
  387.         }
  388.  
  389.         // Append the new text into the edit box
  390.         m_pEdit->SetSel( m_pEdit->GetWindowTextLength(), -1, TRUE );
  391.         m_pEdit->ReplaceSel( buffer );
  392.     }
  393.  
  394.     PR_Notify( m_pOutputMon );
  395.     PR_ExitMonitor( m_pOutputMon );
  396. }
  397.  
  398.  
  399. afx_msg void CJavaOutputWnd::OnSize(UINT type, int cx, int cy)
  400. {
  401.     if( m_pEdit ) {
  402.         m_pEdit->MoveWindow(0, 0, cx, cy, TRUE);
  403.     }
  404. }
  405.  
  406. afx_msg void CJavaOutputWnd::OnSysCommand(UINT nId, LPARAM lParam)
  407. {
  408.     if( nId == SC_CLOSE ) {
  409.         ShowWindow(SW_HIDE);
  410.     } else {
  411.         CFrameWnd::OnSysCommand(nId, lParam);
  412.     }
  413. }
  414.  
  415. afx_msg void CJavaOutputWnd::OnKeyUp(UINT nChar, UINT nRep, UINT nFlags)
  416. {
  417. #ifdef DEBUG
  418.     if( nChar == VK_F1 ) {
  419.         MessageBeep(0);
  420.         PR_DumpThreads();
  421.         PR_DumpMonitors();
  422.     }
  423. #endif
  424. }
  425.  
  426. #ifndef _AFXDLL
  427. #undef new
  428. #endif
  429. IMPLEMENT_DYNCREATE(CJavaOutputWnd, CFrameWnd)
  430. #ifndef _AFXDLL
  431. #define new DEBUG_NEW
  432. #endif
  433.  
  434. BEGIN_MESSAGE_MAP(CJavaOutputWnd, CFrameWnd)
  435.     ON_WM_SIZE ( )
  436.     ON_WM_SYSCOMMAND ( )
  437.     ON_WM_KEYUP ( )
  438. END_MESSAGE_MAP()
  439.  
  440.  
  441. #endif /* JAVA_WIN32 */
  442.