зеркало из https://github.com/mozilla/pjs.git
760 строки
20 KiB
C++
760 строки
20 KiB
C++
/*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "MPL"); you may not use this file
|
|
* except in compliance with the MPL. You may obtain a copy of
|
|
* the MPL at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the MPL is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the MPL for the specific language governing
|
|
* rights and limitations under the MPL.
|
|
*
|
|
* The Original Code is XMLterm.
|
|
*
|
|
* The Initial Developer of the Original Code is Ramalingam Saravanan.
|
|
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
|
|
* Copyright (C) 1999 Ramalingam Saravanan. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
|
*/
|
|
|
|
// mozLineTerm.cpp: class implementing mozILineTerm/mozILineTermAux interfaces,
|
|
// providing an XPCOM/XPCONNECT wrapper for the LINETERM module
|
|
|
|
#include "stdio.h"
|
|
|
|
#include "nspr.h"
|
|
#include "nscore.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsString.h"
|
|
#include "prlog.h"
|
|
#include "nsIAllocator.h"
|
|
|
|
#include "nsIServiceManager.h"
|
|
#include "nsIPref.h"
|
|
#include "nsIPrincipal.h"
|
|
|
|
#include "nsIDocument.h"
|
|
#include "nsIDOMHTMLDocument.h"
|
|
|
|
#include "mozXMLT.h"
|
|
#include "mozXMLTermUtils.h"
|
|
#include "mozLineTerm.h"
|
|
#include "lineterm.h"
|
|
|
|
#define MAXCOL 4096 // Maximum columns in line buffer
|
|
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
|
|
|
static NS_DEFINE_IID(kILineTermIID, MOZILINETERM_IID);
|
|
static NS_DEFINE_IID(kILineTermAuxIID, MOZILINETERMAUX_IID);
|
|
|
|
static NS_DEFINE_IID(kLineTermCID, MOZLINETERM_CID);
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// mozLineTerm, mozLineTermAux factories
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
nsresult
|
|
NS_NewLineTerm(mozILineTerm** aLineTerm)
|
|
{
|
|
NS_PRECONDITION(aLineTerm != nsnull, "null ptr");
|
|
if (! aLineTerm)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*aLineTerm = new mozLineTerm();
|
|
if (! *aLineTerm)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
NS_ADDREF(*aLineTerm);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
NS_NewLineTermAux(mozILineTermAux** aLineTermAux)
|
|
{
|
|
NS_PRECONDITION(aLineTermAux != nsnull, "null ptr");
|
|
if (! aLineTermAux)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*aLineTermAux = new mozLineTerm();
|
|
if (! *aLineTermAux)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
NS_ADDREF(*aLineTermAux);
|
|
return NS_OK;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// mozLineTerm implementaion
|
|
/////////////////////////////////////////////////////////////////////////
|
|
PRBool mozLineTerm::mLoggingEnabled = PR_FALSE;
|
|
|
|
mozLineTerm::mozLineTerm() :
|
|
mCursorRow(0),
|
|
mCursorColumn(0),
|
|
mSuspended(PR_FALSE),
|
|
mEchoFlag(PR_TRUE),
|
|
mObserver(nsnull),
|
|
mCookie(nsAutoString()),
|
|
mLastTime(LL_ZERO)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
mLTerm = lterm_new();
|
|
}
|
|
|
|
|
|
mozLineTerm::~mozLineTerm()
|
|
{
|
|
lterm_delete(mLTerm);
|
|
mObserver = nsnull;
|
|
}
|
|
|
|
|
|
// Implement AddRef and Release
|
|
NS_IMPL_ADDREF(mozLineTerm)
|
|
NS_IMPL_RELEASE(mozLineTerm)
|
|
|
|
|
|
NS_IMETHODIMP
|
|
mozLineTerm::QueryInterface(REFNSIID aIID,void** aInstancePtr)
|
|
{
|
|
if (aInstancePtr == NULL) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
// Always NULL result, in case of failure
|
|
*aInstancePtr = NULL;
|
|
|
|
//XMLT_LOG(mozLineTerm::QueryInterface,30,("0x%x\n",aIID));
|
|
|
|
if ( aIID.Equals(kISupportsIID)) {
|
|
*aInstancePtr = NS_STATIC_CAST(nsISupports*,
|
|
NS_STATIC_CAST(mozILineTermAux*,this));
|
|
|
|
} else if ( aIID.Equals(NS_GET_IID(mozILineTerm)) ) {
|
|
*aInstancePtr = NS_STATIC_CAST(mozILineTerm*,
|
|
NS_STATIC_CAST(mozILineTermAux*,this));
|
|
|
|
} else if ( aIID.Equals(NS_GET_IID(mozILineTermAux)) ) {
|
|
*aInstancePtr = NS_STATIC_CAST(mozILineTermAux*,this);
|
|
|
|
} else {
|
|
return NS_ERROR_NO_INTERFACE;
|
|
}
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
/** Checks if preference settings are secure for LineTerm creation and use
|
|
*/
|
|
NS_IMETHODIMP mozLineTerm::ArePrefsSecure(PRBool *_retval)
|
|
{
|
|
nsresult result;
|
|
|
|
XMLT_LOG(mozLineTerm::ArePrefsSecure,30,("\n"));
|
|
|
|
if (!_retval)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
*_retval = PR_FALSE;
|
|
|
|
nsIPref* prefService;
|
|
nsServiceManager::GetService(kPrefServiceCID, NS_GET_IID(nsIPref),
|
|
(nsISupports**) &prefService);
|
|
if (!prefService)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
// Check if Components JS object is secure
|
|
PRBool checkXPC;
|
|
result = prefService->GetBoolPref("security.checkxpconnect", &checkXPC);
|
|
if (NS_FAILED(result))
|
|
return NS_ERROR_FAILURE;
|
|
|
|
if (!checkXPC) {
|
|
XMLT_ERROR("mozLineTerm::ArePrefsSecure: Error - Please add the line\n"
|
|
" pref(\"security.checkxpcconnect\",true);\n"
|
|
"to your preferences file (.mozilla/prefs.js)\n");
|
|
*_retval = PR_FALSE;
|
|
#if 0 // Temporarily comented out
|
|
return NS_OK;
|
|
#endif
|
|
}
|
|
|
|
nsCAutoString secString ("security.policy.");
|
|
/* Get global policy name. */
|
|
char *policyStr;
|
|
|
|
result = prefService->CopyCharPref("javascript.security_policy", &policyStr);
|
|
if (NS_SUCCEEDED(result) && policyStr) {
|
|
secString.Append(policyStr);
|
|
nsAllocator::Free(policyStr);
|
|
} else {
|
|
secString.Append("default");
|
|
}
|
|
|
|
secString.Append(".htmldocument.cookie");
|
|
|
|
char* prefStr = secString.ToNewCString();
|
|
XMLT_LOG(mozLineTerm::ArePrefsSecure,32, ("prefStr=%s\n", prefStr));
|
|
|
|
char *secLevelString;
|
|
result = prefService->CopyCharPref(prefStr, &secLevelString);
|
|
nsAllocator::Free(prefStr);
|
|
|
|
if (NS_FAILED(result) || !secLevelString)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
XMLT_LOG(mozLineTerm::ArePrefsSecure,32,
|
|
("secLevelString=%s\n", secLevelString));
|
|
|
|
*_retval = (PL_strcmp(secLevelString, "sameOrigin") == 0);
|
|
nsAllocator::Free(secLevelString);
|
|
|
|
if (!(*_retval)) {
|
|
XMLT_ERROR("mozLineTerm::ArePrefsSecure: Error - Please add the line\n"
|
|
" pref(\"security.policy.default.htmldocument.cookie\",\"sameOrigin\");\n"
|
|
"to your preferences file (.mozilla/prefs.js)\n");
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
/** Checks document principal to ensure it has LineTerm creation privileges.
|
|
* Returns the principal string if the principal is secure,
|
|
* and a (zero length) null string if the principal is insecure.
|
|
*/
|
|
NS_IMETHODIMP mozLineTerm::GetSecurePrincipal(nsIDOMDocument *domDoc,
|
|
char** aPrincipalStr)
|
|
{
|
|
XMLT_LOG(mozLineTerm::GetSecurePrincipal,30,("\n"));
|
|
|
|
nsresult result;
|
|
|
|
if (!aPrincipalStr)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
*aPrincipalStr = nsnull;
|
|
|
|
// Get principal string
|
|
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
|
if (!doc)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
result = doc->GetPrincipal(getter_AddRefs(principal));
|
|
if (NS_FAILED(result))
|
|
return result;
|
|
|
|
#if 0 // Temporarily comented out, because ToString is not immplemented
|
|
result = principal->ToString(aPrincipalStr);
|
|
if (NS_FAILED(result) || !*aPrincipalStr)
|
|
return NS_ERROR_FAILURE;
|
|
#else
|
|
const char temStr[] = "unknown";
|
|
PRInt32 temLen = strlen(temStr);
|
|
*aPrincipalStr = strncpy((char*) nsAllocator::Alloc(temLen+1),
|
|
temStr, temLen+1);
|
|
#endif
|
|
|
|
XMLT_LOG(mozLineTerm::GetSecurePrincipal,32,("aPrincipalStr=%s\n",
|
|
*aPrincipalStr));
|
|
|
|
// Check if principal is secure
|
|
PRBool insecure = PR_FALSE;
|
|
if (insecure) {
|
|
// Return null string
|
|
XMLT_ERROR("mozLineTerm::GetSecurePrincipal: Error - "
|
|
"Insecure document principal %s\n", *aPrincipalStr);
|
|
nsAllocator::Free(*aPrincipalStr);
|
|
*aPrincipalStr = (char*) nsAllocator::Alloc(1);
|
|
**aPrincipalStr = '\0';
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
/** Open LineTerm without callback
|
|
*/
|
|
NS_IMETHODIMP mozLineTerm::Open(const PRUnichar *command,
|
|
const PRUnichar *initInput,
|
|
const PRUnichar *promptRegexp,
|
|
PRInt32 options, PRInt32 processType,
|
|
nsIDOMDocument *domDoc)
|
|
{
|
|
if (mSuspended) {
|
|
XMLT_ERROR("mozLineTerm::Open: Error - LineTerm %d is suspended\n",
|
|
mLTerm);
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsAutoString aCookie;
|
|
return OpenAux(command, initInput, promptRegexp,
|
|
options, processType,
|
|
24, 80, 0, 0,
|
|
domDoc, nsnull, aCookie);
|
|
}
|
|
|
|
|
|
/** Open LineTerm, with an Observer for callback to process new input/output
|
|
*/
|
|
NS_IMETHODIMP mozLineTerm::OpenAux(const PRUnichar *command,
|
|
const PRUnichar *initInput,
|
|
const PRUnichar *promptRegexp,
|
|
PRInt32 options, PRInt32 processType,
|
|
PRInt32 nRows, PRInt32 nCols,
|
|
PRInt32 xPixels, PRInt32 yPixels,
|
|
nsIDOMDocument *domDoc,
|
|
nsIObserver* anObserver,
|
|
nsString& aCookie)
|
|
{
|
|
nsresult result;
|
|
|
|
XMLT_LOG(mozLineTerm::Open,20,("\n"));
|
|
|
|
// Ensure that preferences are secure for LineTerm creation and use
|
|
PRBool arePrefsSecure;
|
|
result = ArePrefsSecure(&arePrefsSecure);
|
|
#if 0 // Temporarily comented out
|
|
if (NS_FAILED(result) || !arePrefsSecure)
|
|
return NS_ERROR_FAILURE;
|
|
#endif
|
|
|
|
// Ensure that document principal is secure for LineTerm creation
|
|
char* securePrincipal;
|
|
result = GetSecurePrincipal(domDoc, &securePrincipal);
|
|
if (NS_FAILED(result))
|
|
return NS_ERROR_FAILURE;
|
|
|
|
if (strlen(securePrincipal) == 0) {
|
|
nsAllocator::Free(securePrincipal);
|
|
XMLT_ERROR("mozLineTerm::OpenAux: Error - "
|
|
"Failed to create LineTerm for insecure document principal\n");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLDocument> domHTMLDoc = do_QueryInterface(domDoc);
|
|
if (!domHTMLDoc)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
// Ensure that cookie attribute of document is defined
|
|
nsAutoString cookiePrefix ( NS_ConvertASCIItoUCS2("xmlterm=") );
|
|
nsAutoString cookieStr;
|
|
result = domHTMLDoc->GetCookie(cookieStr);
|
|
|
|
if (NS_SUCCEEDED(result) &&
|
|
(cookieStr.Length() > cookiePrefix.Length()) &&
|
|
(cookieStr.Find(cookiePrefix) == 0)) {
|
|
// Cookie value already defined for document; simply copy it
|
|
mCookie = cookieStr;
|
|
|
|
} else {
|
|
// Create random session cookie
|
|
nsAutoString cookieValue;
|
|
result = mozXMLTermUtils::RandomCookie(cookieValue);
|
|
if (NS_FAILED(result))
|
|
return result;
|
|
|
|
mCookie = cookiePrefix;
|
|
mCookie += cookieValue;
|
|
|
|
// Set new cookie value
|
|
result = domHTMLDoc->SetCookie(mCookie);
|
|
if (NS_FAILED(result))
|
|
return result;
|
|
}
|
|
|
|
// Return copy of cookie to caller
|
|
aCookie = mCookie;
|
|
|
|
mObserver = anObserver; // non-owning reference
|
|
|
|
// Convert cookie to CString
|
|
char* cookieCStr = mCookie.ToNewCString();
|
|
XMLT_LOG(mozLineTerm::Open,22, ("mCookie=%s\n", cookieCStr));
|
|
|
|
// Convert initInput to CString
|
|
nsCAutoString initCStr;
|
|
initCStr.AssignWithConversion(initInput);
|
|
XMLT_LOG(mozLineTerm::Open,22, ("initInput=%s\n", initCStr.GetBuffer()));
|
|
|
|
// List of prompt delimiters
|
|
static const PRInt32 PROMPT_DELIMS = 5;
|
|
UNICHAR prompt_regexp[PROMPT_DELIMS+1];
|
|
ucscopy(prompt_regexp, "#$%>?", PROMPT_DELIMS+1);
|
|
PR_ASSERT(ucslen(prompt_regexp) == PROMPT_DELIMS);
|
|
|
|
if (anObserver != nsnull) {
|
|
result = lterm_open(mLTerm, NULL, cookieCStr, initCStr.GetBuffer(),
|
|
prompt_regexp, options, processType,
|
|
nRows, nCols, xPixels, yPixels,
|
|
mozLineTerm::Callback, (void *) this);
|
|
} else {
|
|
result = lterm_open(mLTerm, NULL, cookieCStr, initCStr.GetBuffer(),
|
|
prompt_regexp, options, processType,
|
|
nRows, nCols, xPixels, yPixels,
|
|
NULL, NULL);
|
|
}
|
|
|
|
// Free cookie CString
|
|
nsAllocator::Free(cookieCStr);
|
|
|
|
if (mLoggingEnabled) {
|
|
// Log time stamp for LineTerm open operation
|
|
nsAutoString timeStamp;
|
|
result = mozXMLTermUtils::TimeStamp(0, mLastTime, timeStamp);
|
|
if (NS_SUCCEEDED(result)) {
|
|
char* temStr = timeStamp.ToNewCString();
|
|
fprintf(stderr, "<TS %s> LineTerm %d opened by principal %s\n",
|
|
temStr, mLTerm, securePrincipal);
|
|
nsAllocator::Free(temStr);
|
|
}
|
|
}
|
|
|
|
if (result == 0) {
|
|
return NS_OK;
|
|
} else {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
}
|
|
|
|
|
|
/** GTK-style callback funtion for mozLineTerm object
|
|
*/
|
|
void mozLineTerm::Callback(gpointer data,
|
|
gint source,
|
|
GdkInputCondition condition)
|
|
{
|
|
mozLineTerm* lineTerm = (mozLineTerm*) data;
|
|
|
|
//XMLT_LOG(mozLineTerm::Callback,50,("\n"));
|
|
|
|
PR_ASSERT(lineTerm != nsnull);
|
|
PR_ASSERT(lineTerm->mObserver != nsnull);
|
|
|
|
lineTerm->mObserver->Observe((nsISupports*) lineTerm, nsnull, nsnull);
|
|
return;
|
|
}
|
|
|
|
/** Suspends (or restores) LineTerm activity depending upon aSuspend
|
|
*/
|
|
NS_IMETHODIMP mozLineTerm::SuspendAux(PRBool aSuspend)
|
|
{
|
|
mSuspended = aSuspend;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
/** Close LineTerm (a Finalize method)
|
|
*/
|
|
NS_IMETHODIMP mozLineTerm::Close(const PRUnichar* aCookie)
|
|
{
|
|
if (!mCookie.EqualsWithConversion(aCookie)) {
|
|
XMLT_ERROR("mozLineTerm::Close: Error - Cookie mismatch\n");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
if (mSuspended) {
|
|
XMLT_ERROR("mozLineTerm::Close: Error - LineTerm %d is suspended\n",
|
|
mLTerm);
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
if (lterm_close(mLTerm) == 0) {
|
|
return NS_OK;
|
|
} else {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
mObserver = nsnull;
|
|
}
|
|
|
|
|
|
/** Close LineTerm (a Finalize method)
|
|
*/
|
|
NS_IMETHODIMP mozLineTerm::CloseAux(void)
|
|
{
|
|
if (lterm_close(mLTerm) == 0) {
|
|
return NS_OK;
|
|
} else {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
mObserver = nsnull;
|
|
}
|
|
|
|
|
|
/** Close all LineTerm instances
|
|
*/
|
|
NS_IMETHODIMP mozLineTerm::CloseAllAux(void)
|
|
{
|
|
lterm_close_all();
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
/** Resizes XMLterm to match a resized window.
|
|
* @param nRows number of rows
|
|
* @param nCols number of columns
|
|
*/
|
|
NS_IMETHODIMP mozLineTerm::ResizeAux(PRInt32 nRows, PRInt32 nCols)
|
|
{
|
|
int retCode;
|
|
|
|
XMLT_LOG(mozLineTerm::ResizeAux,30,("nRows=%d, nCols=%d\n", nRows, nCols));
|
|
|
|
// Resize LTERM
|
|
retCode = lterm_resize(mLTerm, (int) nRows, (int) nCols);
|
|
if (retCode < 0)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
/** Writes a string to LTERM
|
|
*/
|
|
NS_IMETHODIMP mozLineTerm::Write(const PRUnichar *buf,
|
|
const PRUnichar* aCookie)
|
|
{
|
|
if (!mCookie.EqualsWithConversion(aCookie)) {
|
|
XMLT_ERROR("mozLineTerm::Write: Error - Cookie mismatch\n");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
if (mSuspended) {
|
|
XMLT_ERROR("mozLineTerm::Write: Error - LineTerm %d is suspended\n",
|
|
mLTerm);
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
XMLT_LOG(mozLineTerm::Write,30,("\n"));
|
|
|
|
nsresult result;
|
|
UNICHAR ubuf[MAXCOL];
|
|
int jLen, retCode;
|
|
PRBool newline = PR_FALSE;
|
|
|
|
jLen = 0;
|
|
while ((jLen < MAXCOL-1) && (buf[jLen] != 0)) {
|
|
if (buf[jLen] == U_LINEFEED)
|
|
newline = PR_TRUE;
|
|
|
|
ubuf[jLen] = (UNICHAR) buf[jLen];
|
|
|
|
if (ubuf[jLen] == U_PRIVATE0) {
|
|
// Hack to handle input of NUL characters in NUL-terminated strings
|
|
// See also: mozXMLTermKeyListener::KeyPress
|
|
ubuf[jLen] = U_NUL;
|
|
}
|
|
|
|
jLen++;
|
|
}
|
|
|
|
if (jLen >= MAXCOL-1) {
|
|
XMLT_ERROR("mozLineTerm::Write: Error - Buffer overflow\n");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
if (mLoggingEnabled && (jLen > 0)) {
|
|
/* Log all input to STDERR */
|
|
ucsprint(stderr, ubuf, jLen);
|
|
|
|
nsAutoString timeStamp;
|
|
result = mozXMLTermUtils::TimeStamp(60, mLastTime, timeStamp);
|
|
|
|
if (NS_SUCCEEDED(result) && (timeStamp.Length() > 0)) {
|
|
char* temStr = timeStamp.ToNewCString();
|
|
fprintf(stderr, "<TS %s>\n", temStr);
|
|
nsAllocator::Free(temStr);
|
|
|
|
} else if (newline) {
|
|
fprintf(stderr, "\n");
|
|
}
|
|
}
|
|
|
|
retCode = lterm_write(mLTerm, ubuf, jLen, LTERM_WRITE_PLAIN_INPUT);
|
|
if (retCode < 0)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP mozLineTerm::Read(PRInt32 *opcodes, PRInt32 *opvals,
|
|
PRInt32 *buf_row, PRInt32 *buf_col,
|
|
const PRUnichar* aCookie,
|
|
PRUnichar **_retval)
|
|
{
|
|
if (!mCookie.EqualsWithConversion(aCookie)) {
|
|
XMLT_ERROR("mozLineTerm::Read: Error - Cookie mismatch\n");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
if (mSuspended) {
|
|
XMLT_ERROR("mozLineTerm::Read: Error - LineTerm %d is suspended\n",
|
|
mLTerm);
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
return ReadAux(opcodes, opvals, buf_row, buf_col, _retval, nsnull);
|
|
}
|
|
|
|
|
|
/** Reads a line from LTERM and returns it as a string (may be null string)
|
|
*/
|
|
NS_IMETHODIMP mozLineTerm::ReadAux(PRInt32 *opcodes, PRInt32 *opvals,
|
|
PRInt32 *buf_row, PRInt32 *buf_col,
|
|
PRUnichar **_retval, PRUnichar **retstyle)
|
|
{
|
|
UNICHAR ubuf[MAXCOL];
|
|
UNISTYLE ustyle[MAXCOL];
|
|
int cursor_row, cursor_col;
|
|
int retCode, j;
|
|
|
|
XMLT_LOG(mozLineTerm::ReadAux,30,("\n"));
|
|
|
|
if (!_retval)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
retCode = lterm_read(mLTerm, 0, ubuf, MAXCOL-1,
|
|
ustyle, opcodes, opvals,
|
|
buf_row, buf_col, &cursor_row, &cursor_col);
|
|
if (retCode < 0)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
if (*opcodes == 0) {
|
|
// Return null pointer(s)
|
|
*_retval = nsnull;
|
|
|
|
if (retstyle)
|
|
*retstyle = nsnull;
|
|
|
|
} else {
|
|
// Return output string
|
|
mCursorRow = cursor_row;
|
|
mCursorColumn = cursor_col;
|
|
|
|
XMLT_LOG(mozLineTerm::ReadAux,72,("cursor_col=%d\n", cursor_col));
|
|
|
|
int allocBytes = sizeof(PRUnichar)*(retCode + 1);
|
|
*_retval = (PRUnichar*) nsAllocator::Alloc(allocBytes);
|
|
|
|
for (j=0; j<retCode; j++)
|
|
(*_retval)[j] = (PRUnichar) ubuf[j];
|
|
|
|
// Insert null string terminator
|
|
(*_retval)[retCode] = 0;
|
|
|
|
if (retstyle != nsnull) {
|
|
// Return style array as well
|
|
*retstyle = (PRUnichar*) nsAllocator::Alloc(allocBytes);
|
|
|
|
for (j=0; j<retCode; j++)
|
|
(*retstyle)[j] = (PRUnichar) ustyle[j];
|
|
|
|
// Insert null string terminator
|
|
(*retstyle)[retCode] = 0;
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP mozLineTerm::GetCookie(nsString& aCookie)
|
|
{
|
|
aCookie = mCookie;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP mozLineTerm::GetCursorRow(PRInt32 *aCursorRow)
|
|
{
|
|
*aCursorRow = mCursorRow;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP mozLineTerm::SetCursorRow(PRInt32 aCursorRow)
|
|
{
|
|
int retCode;
|
|
|
|
if (mSuspended) {
|
|
XMLT_ERROR("mozLineTerm::SetCursorRow: Error - LineTerm %d is suspended\n",
|
|
mLTerm);
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
retCode = lterm_setcursor(mLTerm, aCursorRow, mCursorColumn);
|
|
if (retCode < 0)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP mozLineTerm::GetCursorColumn(PRInt32 *aCursorColumn)
|
|
{
|
|
*aCursorColumn = mCursorColumn;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP mozLineTerm::SetCursorColumn(PRInt32 aCursorColumn)
|
|
{
|
|
int retCode;
|
|
|
|
if (mSuspended) {
|
|
XMLT_ERROR("mozLineTerm::SetCursorColumn: Error - LineTerm %d is suspended\n",
|
|
mLTerm);
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
retCode = lterm_setcursor(mLTerm, mCursorRow, aCursorColumn);
|
|
if (retCode < 0)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP mozLineTerm::GetEchoFlag(PRBool *aEchoFlag)
|
|
{
|
|
*aEchoFlag = mEchoFlag;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP mozLineTerm::SetEchoFlag(PRBool aEchoFlag)
|
|
{
|
|
int result;
|
|
|
|
if (mSuspended) {
|
|
XMLT_ERROR("mozLineTerm::SetEchoFlag: Error - LineTerm %d is suspended\n",
|
|
mLTerm);
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
XMLT_LOG(mozLineTerm::SetEchoFlag,70,("aEchoFlag=0x%x\n", aEchoFlag));
|
|
|
|
if (aEchoFlag) {
|
|
result = lterm_setecho(mLTerm, 1);
|
|
} else {
|
|
result = lterm_setecho(mLTerm, 0);
|
|
}
|
|
|
|
if (result != 0)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
mEchoFlag = aEchoFlag;
|
|
return NS_OK;
|
|
}
|