Free the lizard
git-svn-id: svn://10.0.0.236/trunk@10 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
441
mozilla/cmd/winfe/javaio.cpp
Executable file
441
mozilla/cmd/winfe/javaio.cpp
Executable file
@@ -0,0 +1,441 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#ifdef JAVA_WIN32
|
||||
// javaio.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "mainfrm.h"
|
||||
#include "javaio.h"
|
||||
#include "io.h"
|
||||
#include "prthread.h"
|
||||
#include "prmon.h"
|
||||
#include "prfile.h"
|
||||
#include "prdump.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char BASED_CODE THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
|
||||
// Maximun number of characters in the edit box before truncation occurs...
|
||||
#define MAX_JAVA_OUTPUT_SIZE 10000
|
||||
#define JAVA_IO_THREAD_STACK_SIZE 16768
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CNSPRStream
|
||||
|
||||
PRIOMethods CNSPRStream::IOMethods = { CNSPRStream::InitMethod,
|
||||
CNSPRStream::CloseMethod,
|
||||
CNSPRStream::ReadMethod,
|
||||
CNSPRStream::WriteMethod };
|
||||
|
||||
CNSPRStream::CNSPRStream(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CNSPRStream::MapFileDescriptor( PROSFD fd )
|
||||
{
|
||||
PR_MapFileHandle( fd, (CNSPRStream *)this, &IOMethods );
|
||||
}
|
||||
|
||||
|
||||
int32 CNSPRStream::InitMethod(PRFileDesc * fd)
|
||||
{
|
||||
int32 ret = -1;
|
||||
|
||||
if( fd->instance ) {
|
||||
ret = ((CNSPRStream *)(fd->instance))->Init(fd);
|
||||
}
|
||||
return( ret );
|
||||
}
|
||||
|
||||
int32 CNSPRStream::CloseMethod(PRFileDesc * fd)
|
||||
{
|
||||
int32 ret = -1;
|
||||
|
||||
if( fd->instance ) {
|
||||
ret = ((CNSPRStream *)(fd->instance))->Close(fd);
|
||||
}
|
||||
return( ret );
|
||||
}
|
||||
|
||||
|
||||
int32 CNSPRStream::ReadMethod (PRFileDesc * fd, void *buf, int32 amount)
|
||||
{
|
||||
int32 ret = -1;
|
||||
|
||||
if( fd->instance ) {
|
||||
ret = ((CNSPRStream *)(fd->instance))->Read(fd, buf, amount);
|
||||
}
|
||||
return( ret );
|
||||
}
|
||||
|
||||
|
||||
int32 CNSPRStream::WriteMethod(PRFileDesc * fd, const void *buf, int32 amount)
|
||||
{
|
||||
int32 ret = -1;
|
||||
|
||||
if( fd->instance ) {
|
||||
ret = ((CNSPRStream *)(fd->instance))->Write(fd, buf, amount);
|
||||
}
|
||||
return( ret );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CJavaStdError
|
||||
|
||||
CJavaStdError::CJavaStdError(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int32 CJavaStdError::Init(PRFileDesc *fd)
|
||||
{
|
||||
return( fd->osfd );
|
||||
}
|
||||
|
||||
|
||||
int32 CJavaStdError::Close(PRFileDesc *fd)
|
||||
{
|
||||
/* Never close stderr */
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
|
||||
int32 CJavaStdError::Read(PRFileDesc *fd, void *buf, int32 amount)
|
||||
{
|
||||
/* Cannot read from stderr */
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
|
||||
int32 CJavaStdError::Write(PRFileDesc *fd, const void *buf, int32 amount)
|
||||
{
|
||||
char buffer[1024];
|
||||
int32 size;
|
||||
int len;
|
||||
|
||||
size = amount;
|
||||
while (size) {
|
||||
len = size > 1023 ? 1023 : size;
|
||||
strncpy( buffer, (const char *)buf, len );
|
||||
buffer[len] = '\0';
|
||||
size -= len;
|
||||
|
||||
//
|
||||
// Calling MFC's MessageBox causes a deadlock if the calling thread is NOT the
|
||||
// main UI thread of the navigator. In practice, this is ALWAYS the case :-(
|
||||
//
|
||||
//AfxGetApp()->GetMainWnd()->MessageBox( buffer, "Java Error" );
|
||||
(void)::MessageBox(NULL, buffer, "Java Error", MB_SETFOREGROUND | MB_OK);
|
||||
}
|
||||
return(amount);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CJavaStdOutput
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
static int64 SleepForever = 0x7fffffffffffffff;
|
||||
#else
|
||||
static int64 SleepForever = LL_MAXINT;
|
||||
#endif
|
||||
|
||||
CJavaStdOutput::CJavaStdOutput(void)
|
||||
{
|
||||
m_bAutoDelete = TRUE;
|
||||
|
||||
m_pOwnThread = 0;
|
||||
m_ThreadId = 0;
|
||||
m_pWnd = 0;
|
||||
m_pOutputMon = PR_NewNamedMonitor("output-monitor");
|
||||
|
||||
m_msgWrite = ::RegisterWindowMessage("NSPR_ConsoleWrite");
|
||||
}
|
||||
|
||||
|
||||
CJavaStdOutput::~CJavaStdOutput()
|
||||
{
|
||||
if( m_pOutputMon ) {
|
||||
PR_DestroyMonitor( m_pOutputMon );
|
||||
m_pOutputMon = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BOOL CJavaStdOutput::PreTranslateMessage(MSG* pMsg)
|
||||
{
|
||||
BOOL bResult;
|
||||
|
||||
if( (pMsg->hwnd == 0) && (pMsg->message == m_msgWrite) ) {
|
||||
m_pWnd->Display( (const char *)pMsg->lParam, (int32)pMsg->wParam );
|
||||
bResult = TRUE;
|
||||
} else {
|
||||
bResult = CWinThread::PreTranslateMessage(pMsg);
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
BOOL CJavaStdOutput::InitInstance(void)
|
||||
{
|
||||
PRThreadStack *ts;
|
||||
BOOL bRet = FALSE;
|
||||
CWinThread::InitInstance();
|
||||
|
||||
|
||||
/* Set up the thread stack information */
|
||||
ts = (PRThreadStack*) calloc(1, sizeof(PRThreadStack));
|
||||
if( ts ) {
|
||||
ts->stackSize = JAVA_IO_THREAD_STACK_SIZE;
|
||||
|
||||
m_pOwnThread = PR_AttachThread("Java IO", 15, ts);
|
||||
m_pOwnThread->flags |= _PR_NO_SUSPEND;
|
||||
m_ThreadId = ::GetCurrentThreadId();
|
||||
|
||||
if( m_pWnd = new CJavaOutputWnd() ) {
|
||||
bRet = m_pWnd->Initialize( m_pOutputMon );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return(bRet);
|
||||
}
|
||||
|
||||
int CJavaStdOutput::ExitInstance(void)
|
||||
{
|
||||
if( m_pWnd ) {
|
||||
delete m_pWnd;
|
||||
m_pWnd = NULL;
|
||||
}
|
||||
if( m_pOwnThread ) {
|
||||
PR_DetachThread( m_pOwnThread );
|
||||
m_pOwnThread = NULL;
|
||||
}
|
||||
return CWinThread::ExitInstance();
|
||||
}
|
||||
|
||||
|
||||
BOOL CJavaStdOutput::ToggleVisible(void)
|
||||
{
|
||||
BOOL bRet = m_pWnd->IsWindowVisible();
|
||||
|
||||
m_pWnd->ShowWindow( bRet ? SW_HIDE : SW_SHOW );
|
||||
return( ! bRet );
|
||||
}
|
||||
|
||||
BOOL CJavaStdOutput::IsVisible(void)
|
||||
{
|
||||
return m_pWnd->IsWindowVisible();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32 CJavaStdOutput::Init(PRFileDesc *fd)
|
||||
{
|
||||
int32 ret = fd->osfd;
|
||||
|
||||
if(! CreateThread(0, JAVA_IO_THREAD_STACK_SIZE, 0)) {
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int32 CJavaStdOutput::Close(PRFileDesc *fd)
|
||||
{
|
||||
::PostThreadMessage( m_ThreadId, WM_QUIT, 0, 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32 CJavaStdOutput::Read(PRFileDesc *fd, void *buf, int32 amount)
|
||||
{
|
||||
/* Cannot read from stdout */
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
|
||||
int32 CJavaStdOutput::Write(PRFileDesc *fd, const void *buf, int32 amount)
|
||||
{
|
||||
if( PR_CurrentThread() == m_pOwnThread ) {
|
||||
m_pWnd->Display((const char *)buf, amount);
|
||||
} else {
|
||||
PR_EnterMonitor( m_pOutputMon );
|
||||
::PostThreadMessage( m_ThreadId, m_msgWrite, (WPARAM)amount, (LPARAM)buf );
|
||||
PR_Wait( m_pOutputMon, SleepForever );
|
||||
PR_ExitMonitor( m_pOutputMon);
|
||||
}
|
||||
return( amount );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CJavaOutputWnd
|
||||
CJavaOutputWnd::CJavaOutputWnd()
|
||||
{
|
||||
m_pEdit = 0;
|
||||
m_pOutputMon = 0;
|
||||
}
|
||||
|
||||
|
||||
CJavaOutputWnd::~CJavaOutputWnd()
|
||||
{
|
||||
if( m_pEdit ) {
|
||||
delete m_pEdit;
|
||||
m_pEdit = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL CJavaOutputWnd::Initialize(PRMonitor *pMon)
|
||||
{
|
||||
BOOL bRet;
|
||||
RECT rect;
|
||||
|
||||
m_pOutputMon = pMon;
|
||||
|
||||
// Create the Frame Window
|
||||
bRet = CFrameWnd::Create( NULL, "Java Output",
|
||||
WS_OVERLAPPEDWINDOW | WS_VISIBLE );
|
||||
if( bRet ) {
|
||||
GetClientRect( &rect );
|
||||
|
||||
// Create the Child Edit control used to display the text
|
||||
m_pEdit = new CGenericEdit();
|
||||
bRet = m_pEdit->Create( WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY,
|
||||
rect, this, 100 );
|
||||
|
||||
// Initialize the font for the edit control...
|
||||
/// pContext = CMainFrame::GetLastActiveFrame()->GetMainContext()->GetContext();
|
||||
/// if (INTL_CharSetType(pContext) == SINGLEBYTE) {
|
||||
m_pEdit->SetFont(CFont::FromHandle((HFONT)GetStockObject(ANSI_FIXED_FONT)));
|
||||
/// } else {
|
||||
// For multibyte, we can not use ANSI font
|
||||
/// m_pEdit->SetFont(CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FIXED_FONT)));
|
||||
/// }
|
||||
}
|
||||
return(bRet);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CJavaOutputWnd::Display( const char *buf, int32 amount )
|
||||
{
|
||||
char buffer[90];
|
||||
const char *pbuf;
|
||||
int32 size;
|
||||
int i, j, len;
|
||||
|
||||
PR_EnterMonitor( m_pOutputMon );
|
||||
|
||||
size = amount;
|
||||
pbuf = (const char *)buf;
|
||||
while (size) {
|
||||
len = size > 79 ? 79 : size;
|
||||
i = j = 0;
|
||||
// Translate \n to \r\n for the edit box
|
||||
while( j<len ) {
|
||||
if( pbuf[i] == '\n' ) {
|
||||
buffer[j++] = '\r';
|
||||
}
|
||||
buffer[j++] = pbuf[i++];
|
||||
}
|
||||
buffer[j] = '\0';
|
||||
size -= i;
|
||||
pbuf += i;
|
||||
|
||||
// Truncate the edit box text if it is reaching its limit
|
||||
len = m_pEdit->GetWindowTextLength();
|
||||
if( len > MAX_JAVA_OUTPUT_SIZE ) {
|
||||
len -= (MAX_JAVA_OUTPUT_SIZE/2);
|
||||
i = j = 0;
|
||||
while ( len > 0) {
|
||||
int k = m_pEdit->LineLength(j++);
|
||||
|
||||
len -= k;
|
||||
i += k;
|
||||
}
|
||||
m_pEdit->SetSel( 0, i, TRUE );
|
||||
m_pEdit->ReplaceSel( "" );
|
||||
}
|
||||
|
||||
// Append the new text into the edit box
|
||||
m_pEdit->SetSel( m_pEdit->GetWindowTextLength(), -1, TRUE );
|
||||
m_pEdit->ReplaceSel( buffer );
|
||||
}
|
||||
|
||||
PR_Notify( m_pOutputMon );
|
||||
PR_ExitMonitor( m_pOutputMon );
|
||||
}
|
||||
|
||||
|
||||
afx_msg void CJavaOutputWnd::OnSize(UINT type, int cx, int cy)
|
||||
{
|
||||
if( m_pEdit ) {
|
||||
m_pEdit->MoveWindow(0, 0, cx, cy, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
afx_msg void CJavaOutputWnd::OnSysCommand(UINT nId, LPARAM lParam)
|
||||
{
|
||||
if( nId == SC_CLOSE ) {
|
||||
ShowWindow(SW_HIDE);
|
||||
} else {
|
||||
CFrameWnd::OnSysCommand(nId, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
afx_msg void CJavaOutputWnd::OnKeyUp(UINT nChar, UINT nRep, UINT nFlags)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if( nChar == VK_F1 ) {
|
||||
MessageBeep(0);
|
||||
PR_DumpThreads();
|
||||
PR_DumpMonitors();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef _AFXDLL
|
||||
#undef new
|
||||
#endif
|
||||
IMPLEMENT_DYNCREATE(CJavaOutputWnd, CFrameWnd)
|
||||
#ifndef _AFXDLL
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
||||
BEGIN_MESSAGE_MAP(CJavaOutputWnd, CFrameWnd)
|
||||
ON_WM_SIZE ( )
|
||||
ON_WM_SYSCOMMAND ( )
|
||||
ON_WM_KEYUP ( )
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
#endif /* JAVA_WIN32 */
|
||||
Reference in New Issue
Block a user