Got rid of the global gPfd variable. Big time cleanup, made TermParse a
bit more robust with error checks and likes. Removed unused TermPrint.cpp file. I hope I didn't get on your way, Vasilis :) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20333 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
570ab00aa7
commit
63dc9cc262
@ -373,11 +373,11 @@ TermApp::MakeTermWindow(BRect &frame)
|
||||
if (cols < MIN_COLS)
|
||||
gTermPref->setInt32(PREF_COLS, cols = MIN_COLS);
|
||||
|
||||
gPfd = spawn_shell(rows, cols, command, encoding);
|
||||
if (gPfd < 0)
|
||||
return gPfd;
|
||||
int pfd = spawn_shell(rows, cols, command, encoding);
|
||||
if (pfd < 0)
|
||||
return pfd;
|
||||
|
||||
fTermWindow = new TermWindow(frame, fWindowTitle.String(), gPfd);
|
||||
fTermWindow = new TermWindow(frame, fWindowTitle.String(), pfd);
|
||||
fTermWindow->Show();
|
||||
|
||||
return B_OK;
|
||||
|
@ -4,213 +4,29 @@
|
||||
* Parts Copyright (C) 1998,99 Kazuho Okui and Takashi Murai.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <app/Application.h>
|
||||
#include <support/Beep.h>
|
||||
#include <Application.h>
|
||||
#include <Beep.h>
|
||||
#include <Message.h>
|
||||
#include <MessageRunner.h>
|
||||
|
||||
|
||||
#include "TermParse.h"
|
||||
#include "TermView.h"
|
||||
#include "VTparse.h"
|
||||
#include "TermConst.h"
|
||||
#include "CodeConv.h"
|
||||
|
||||
extern int gPfd; // defined Muterminal.cpp
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// PtyReader ... Get character from pty device.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
int32
|
||||
TermParse::PtyReader(void *data)
|
||||
{
|
||||
int nread;
|
||||
uint read_p = 0;
|
||||
|
||||
TermParse *theObj = (TermParse *) data;
|
||||
|
||||
uchar buf [READ_BUF_SIZE];
|
||||
|
||||
while (theObj->fQuitting) {
|
||||
/*
|
||||
* If Pty Buffer nearly full, snooze this thread, and continue.
|
||||
*/
|
||||
if ((read_p - theObj->fParser_p) > READ_BUF_SIZE - 16) {
|
||||
theObj->fLockFlag = READ_BUF_SIZE / 2;
|
||||
acquire_sem (theObj->fReaderLocker);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read PTY.
|
||||
*/
|
||||
nread = read (gPfd, buf,
|
||||
READ_BUF_SIZE - (read_p - theObj->fParser_p));
|
||||
if (nread <= 0) {
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
exit_thread (B_ERROR);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int left = READ_BUF_SIZE - (read_p % READ_BUF_SIZE);
|
||||
int mod = read_p % READ_BUF_SIZE;
|
||||
|
||||
/*
|
||||
* Copy read string to PtyBuffer.
|
||||
*/
|
||||
if (nread >= left) {
|
||||
memcpy (theObj->fReadBuf + mod, buf, left);
|
||||
memcpy (theObj->fReadBuf, buf + left, nread - left);
|
||||
}
|
||||
else {
|
||||
memcpy (theObj->fReadBuf + mod, buf, nread);
|
||||
}
|
||||
read_p += nread;
|
||||
|
||||
/*
|
||||
* Release semaphore. Number of semaphore counter is nread.
|
||||
*/
|
||||
release_sem_etc (theObj->fReaderSem, nread, 0);
|
||||
|
||||
}
|
||||
theObj->fReaderThread = -1;
|
||||
exit_thread (B_OK);
|
||||
return B_OK;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// GetReaderBuf ... Get char pty reader buffer.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uchar
|
||||
TermParse::GetReaderBuf (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
switch (acquire_sem_etc (fReaderSem, 1, B_TIMEOUT, (bigtime_t)10000.0)) {
|
||||
case B_NO_ERROR:
|
||||
break;
|
||||
case B_TIMED_OUT:
|
||||
default:
|
||||
fViewObj->ScrollAtCursor();
|
||||
fViewObj->UpdateLine();
|
||||
|
||||
// Reset cursor blinking time and turn on cursor blinking.
|
||||
fCursorUpdate->SetInterval (1000000);
|
||||
fViewObj->SetCurDraw (CURON);
|
||||
|
||||
// wait new input from pty.
|
||||
acquire_sem (fReaderSem);
|
||||
break;
|
||||
}
|
||||
|
||||
c = fReadBuf[fParser_p % READ_BUF_SIZE];
|
||||
fParser_p++;
|
||||
/*
|
||||
* If PtyReader thread locked, decliment counter and unlock thread.
|
||||
*/
|
||||
if (fLockFlag != 0) {
|
||||
fLockFlag--;
|
||||
if (fLockFlag == 0) {
|
||||
release_sem (fReaderLocker);
|
||||
}
|
||||
}
|
||||
|
||||
fViewObj->SetCurDraw (CUROFF);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// InitTermParse ... Initialize and spawn EscParse thread.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
status_t
|
||||
TermParse::InitTermParse (TermView *inViewObj, CodeConv *inConvObj)
|
||||
{
|
||||
|
||||
fViewObj = inViewObj;
|
||||
fConvObj = inConvObj;
|
||||
|
||||
fCursorUpdate = new BMessageRunner (BMessenger (fViewObj),
|
||||
new BMessage (MSGRUN_CURSOR),
|
||||
1000000);
|
||||
|
||||
if (fParseThread < 0)
|
||||
fParseThread =
|
||||
spawn_thread (EscParse, "EscParse", B_DISPLAY_PRIORITY, this);
|
||||
else
|
||||
return B_BAD_THREAD_ID;
|
||||
|
||||
return (resume_thread ( fParseThread));
|
||||
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// InitPtyReader ... Initialize and spawn PtyReader thread.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
thread_id
|
||||
TermParse::InitPtyReader (TermWindow *inWinObj)
|
||||
{
|
||||
|
||||
fWinObj = inWinObj;
|
||||
|
||||
if (fReaderThread < 0)
|
||||
fReaderThread =
|
||||
spawn_thread (PtyReader, "PtyReader", B_NORMAL_PRIORITY, this);
|
||||
else
|
||||
return B_BAD_THREAD_ID;
|
||||
|
||||
fReaderSem = create_sem (0, "pty_reader_sem");
|
||||
fReaderLocker = create_sem (0, "pty_locker_sem");
|
||||
|
||||
resume_thread (fReaderThread);
|
||||
|
||||
return (fReaderThread);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructer and Destructer.
|
||||
*/
|
||||
|
||||
TermParse::TermParse (void)
|
||||
{
|
||||
|
||||
fParseThread = -1;
|
||||
fReaderThread = -1;
|
||||
fLockFlag = 0;
|
||||
fParser_p = 0;
|
||||
fQuitting = 1;
|
||||
|
||||
}
|
||||
|
||||
TermParse::~TermParse (void)
|
||||
{
|
||||
//status_t sts;
|
||||
|
||||
fQuitting = 0;
|
||||
kill_thread(fParseThread);
|
||||
|
||||
kill_thread(fReaderThread);
|
||||
delete_sem (fReaderSem);
|
||||
delete_sem (fReaderLocker);
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// EscParse ... Escape sequence parse and character encoding.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
extern int utf8_groundtable[]; /* UTF8 Ground table */
|
||||
extern int cs96_groundtable[]; /* CS96 Ground table */
|
||||
extern int iso8859_groundtable[]; /* ISO8859 & EUC Ground table */
|
||||
@ -226,33 +42,225 @@ extern int eigtable[]; /* ESC ignore table */
|
||||
extern int mbcstable[]; /* ESC $ */
|
||||
|
||||
|
||||
/* MuTerminal coding system (global varriable) */
|
||||
// MuTerminal coding system (global varriable)
|
||||
int gNowCoding = M_UTF8;
|
||||
|
||||
#define DEFAULT -1
|
||||
#define NPARAM 10 // Max parameters
|
||||
|
||||
/*
|
||||
* Constructor and Destructor.
|
||||
*/
|
||||
TermParse::TermParse(int fd, TermWindow *inWinObj, TermView *inViewObj, CodeConv *inConvObj)
|
||||
:
|
||||
fFd(fd),
|
||||
fViewObj(inViewObj),
|
||||
fWinObj(inWinObj),
|
||||
fConvObj(inConvObj),
|
||||
fParseThread(-1),
|
||||
fParseSem(-1),
|
||||
fReaderThread(-1),
|
||||
fReaderSem(-1),
|
||||
fReaderLocker(-1),
|
||||
fCursorUpdate(NULL),
|
||||
fParser_p(0),
|
||||
fLockFlag(0),
|
||||
fQuitting(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TermParse::~TermParse()
|
||||
{
|
||||
fQuitting = true;
|
||||
|
||||
delete_sem(fReaderSem);
|
||||
delete_sem(fReaderLocker);
|
||||
|
||||
status_t dummy;
|
||||
wait_for_thread(fParseThread, &dummy);
|
||||
wait_for_thread(fReaderThread, &dummy);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
TermParse::StartThreads()
|
||||
{
|
||||
status_t status = InitPtyReader();
|
||||
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
status = InitTermParse();
|
||||
if (status < B_OK) {
|
||||
//AbortPtyReader();
|
||||
return status;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// PtyReader ... Get character from pty device.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
int32
|
||||
TermParse::PtyReader()
|
||||
{
|
||||
uint read_p = 0;
|
||||
while (!fQuitting) {
|
||||
// If Pty Buffer nearly full, snooze this thread, and continue.
|
||||
if ((read_p - fParser_p) > READ_BUF_SIZE - 16) {
|
||||
fLockFlag = READ_BUF_SIZE / 2;
|
||||
status_t status;
|
||||
do {
|
||||
status = acquire_sem(fReaderLocker);
|
||||
} while (status == B_INTERRUPTED);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
// Read PTY
|
||||
uchar buf[READ_BUF_SIZE];
|
||||
int nread = read(fFd, buf, READ_BUF_SIZE - (read_p - fParser_p));
|
||||
if (nread <= 0) {
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
exit_thread(B_ERROR);
|
||||
}
|
||||
int left = READ_BUF_SIZE - (read_p % READ_BUF_SIZE);
|
||||
int mod = read_p % READ_BUF_SIZE;
|
||||
// Copy read string to PtyBuffer.
|
||||
|
||||
if (nread >= left) {
|
||||
memcpy(fReadBuf + mod, buf, left);
|
||||
memcpy(fReadBuf, buf + left, nread - left);
|
||||
} else
|
||||
memcpy(fReadBuf + mod, buf, nread);
|
||||
|
||||
read_p += nread;
|
||||
|
||||
// Release semaphore. Number of semaphore counter is nread.
|
||||
release_sem_etc(fReaderSem, nread, 0);
|
||||
}
|
||||
|
||||
fReaderThread = -1;
|
||||
exit_thread(B_OK);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// GetReaderBuf ... Get char pty reader buffer.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
status_t
|
||||
TermParse::GetReaderBuf(uchar &c)
|
||||
{
|
||||
status_t status;
|
||||
do {
|
||||
status = acquire_sem_etc(fReaderSem, 1, B_TIMEOUT, 10000);
|
||||
} while (status == B_INTERRUPTED);
|
||||
|
||||
if (status == B_TIMED_OUT) {
|
||||
fViewObj->ScrollAtCursor();
|
||||
fViewObj->UpdateLine();
|
||||
|
||||
// Reset cursor blinking time and turn on cursor blinking.
|
||||
fCursorUpdate->SetInterval (1000000);
|
||||
fViewObj->SetCurDraw (CURON);
|
||||
|
||||
// wait new input from pty.
|
||||
do {
|
||||
status = acquire_sem(fReaderSem);
|
||||
} while (status == B_INTERRUPTED);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
} else if (status == B_OK) {
|
||||
// Do nothing
|
||||
} else
|
||||
return status;
|
||||
|
||||
c = fReadBuf[fParser_p % READ_BUF_SIZE];
|
||||
fParser_p++;
|
||||
// If PtyReader thread locked, decrement counter and unlock thread.
|
||||
if (fLockFlag != 0) {
|
||||
if (--fLockFlag == 0)
|
||||
release_sem(fReaderLocker);
|
||||
}
|
||||
|
||||
fViewObj->SetCurDraw(CUROFF);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// InitTermParse ... Initialize and spawn EscParse thread.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
status_t
|
||||
TermParse::InitTermParse()
|
||||
{
|
||||
if (fParseThread >= 0)
|
||||
return B_ERROR; // we might want to return B_OK instead ?
|
||||
|
||||
fCursorUpdate = new BMessageRunner(BMessenger(fViewObj),
|
||||
new BMessage(MSGRUN_CURSOR), 1000000);
|
||||
|
||||
fParseThread = spawn_thread(_escparse_thread, "EscParse", B_DISPLAY_PRIORITY, this);
|
||||
|
||||
return resume_thread(fParseThread);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// InitPtyReader ... Initialize and spawn PtyReader thread.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
thread_id
|
||||
TermParse::InitPtyReader()
|
||||
{
|
||||
if (fReaderThread >= 0)
|
||||
return B_ERROR; // same as above
|
||||
|
||||
fReaderSem = create_sem(0, "pty_reader_sem");
|
||||
if (fReaderSem < 0)
|
||||
return fReaderSem;
|
||||
|
||||
fReaderLocker = create_sem(0, "pty_locker_sem");
|
||||
if (fReaderLocker < 0) {
|
||||
delete_sem(fReaderSem);
|
||||
return fReaderLocker;
|
||||
}
|
||||
|
||||
fReaderThread = spawn_thread(_ptyreader_thread, "PtyReader", B_NORMAL_PRIORITY, this);
|
||||
if (fReaderThread < 0) {
|
||||
delete_sem(fReaderSem);
|
||||
delete_sem(fReaderLocker);
|
||||
return fReaderThread;
|
||||
}
|
||||
|
||||
return resume_thread(fReaderThread);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
TermParse::EscParse(void *data)
|
||||
TermParse::EscParse()
|
||||
{
|
||||
int tmp;
|
||||
int top, bot;
|
||||
int cs96;
|
||||
uchar curess = 0;
|
||||
|
||||
TermParse *theObj = (TermParse *)data;
|
||||
|
||||
TermView *viewObj = theObj->fViewObj;
|
||||
CodeConv *convObj = theObj->fConvObj;
|
||||
TermView *viewObj = fViewObj;
|
||||
CodeConv *convObj = fConvObj;
|
||||
|
||||
uchar cbuf[4], dstbuf[4];
|
||||
uchar *ptr;
|
||||
|
||||
int *parsestate, *groundtable;
|
||||
int now_coding = -1;
|
||||
|
||||
uchar c;
|
||||
ushort attr = BACKCOLOR;
|
||||
|
||||
int param[NPARAM];
|
||||
@ -262,11 +270,13 @@ TermParse::EscParse(void *data)
|
||||
int width;
|
||||
|
||||
/* default coding system is UTF8 */
|
||||
groundtable = utf8_groundtable;
|
||||
parsestate = groundtable;
|
||||
int *groundtable = utf8_groundtable;
|
||||
int *parsestate = groundtable;
|
||||
|
||||
while (theObj->fQuitting) {
|
||||
c = theObj->GetReaderBuf();
|
||||
while (!fQuitting) {
|
||||
uchar c;
|
||||
if (GetReaderBuf(c) < B_OK)
|
||||
break;
|
||||
|
||||
if (now_coding != gNowCoding) {
|
||||
/*
|
||||
@ -326,7 +336,7 @@ TermParse::EscParse(void *data)
|
||||
case CASE_SS3: /* JIS X 0212 */
|
||||
*ptr++ = curess;
|
||||
*ptr++ = c;
|
||||
*ptr++ = theObj->GetReaderBuf ();
|
||||
GetReaderBuf(*ptr++);
|
||||
*ptr = 0;
|
||||
width = 2;
|
||||
curess = 0;
|
||||
@ -334,7 +344,7 @@ TermParse::EscParse(void *data)
|
||||
|
||||
default: /* JIS X 0208 */
|
||||
*ptr++ = c;
|
||||
*ptr++ = theObj->GetReaderBuf ();
|
||||
GetReaderBuf(*ptr++);
|
||||
*ptr = 0;
|
||||
width = 2;
|
||||
break;
|
||||
@ -356,7 +366,8 @@ TermParse::EscParse(void *data)
|
||||
|
||||
case CASE_PRINT_CS96:
|
||||
cbuf[0] = c | 0x80;
|
||||
cbuf[1] = theObj->GetReaderBuf() | 0x80;
|
||||
GetReaderBuf(cbuf[1]);
|
||||
cbuf[1] |= 0x80;
|
||||
cbuf[2] = 0;
|
||||
width = 2;
|
||||
convObj->ConvertToInternal((char*)cbuf, 2, (char*)dstbuf, M_EUC_JP);
|
||||
@ -381,7 +392,7 @@ TermParse::EscParse(void *data)
|
||||
|
||||
case CASE_SJIS_INSTRING:
|
||||
cbuf[0] = (uchar)c;
|
||||
cbuf[1] = theObj->GetReaderBuf();
|
||||
GetReaderBuf(cbuf[1]);
|
||||
cbuf[2] = '\0';
|
||||
convObj->ConvertToInternal((char*)cbuf, 2, (char*)dstbuf, now_coding);
|
||||
width = 2;
|
||||
@ -390,7 +401,7 @@ TermParse::EscParse(void *data)
|
||||
|
||||
case CASE_UTF8_2BYTE:
|
||||
cbuf[0] = (uchar)c;
|
||||
c = theObj->GetReaderBuf();
|
||||
GetReaderBuf(c);
|
||||
if (groundtable[c] != CASE_UTF8_INSTRING)
|
||||
break;
|
||||
cbuf[1] = (uchar)c;
|
||||
@ -401,12 +412,12 @@ TermParse::EscParse(void *data)
|
||||
|
||||
case CASE_UTF8_3BYTE:
|
||||
cbuf[0] = c;
|
||||
c = theObj->GetReaderBuf();
|
||||
GetReaderBuf(c);
|
||||
if (groundtable[c] != CASE_UTF8_INSTRING)
|
||||
break;
|
||||
cbuf[1] = c;
|
||||
|
||||
c = theObj->GetReaderBuf();
|
||||
GetReaderBuf(c);
|
||||
if (groundtable[c] != CASE_UTF8_INSTRING)
|
||||
break;
|
||||
cbuf[2] = c;
|
||||
@ -427,11 +438,13 @@ TermParse::EscParse(void *data)
|
||||
break;
|
||||
|
||||
case CASE_SCS_STATE:
|
||||
{
|
||||
cs96 = 0;
|
||||
theObj->GetReaderBuf ();
|
||||
uchar dummy;
|
||||
GetReaderBuf(dummy);
|
||||
parsestate = groundtable;
|
||||
break;
|
||||
|
||||
}
|
||||
case CASE_GROUND_STATE:
|
||||
/* exit ignore mode */
|
||||
parsestate = groundtable;
|
||||
@ -781,15 +794,18 @@ TermParse::EscParse(void *data)
|
||||
/* Operating System Command: ESC ] */
|
||||
char string[512];
|
||||
uint32 len = 0;
|
||||
char mode_char = theObj->GetReaderBuf();
|
||||
uchar mode_char;
|
||||
GetReaderBuf(mode_char);
|
||||
if (mode_char != '0'
|
||||
&& mode_char != '1'
|
||||
&& mode_char != '2') {
|
||||
parsestate = groundtable;
|
||||
break;
|
||||
}
|
||||
char current_char = theObj->GetReaderBuf();
|
||||
while ((current_char = theObj->GetReaderBuf()) != 0x7) {
|
||||
uchar current_char;
|
||||
GetReaderBuf(current_char);
|
||||
while (GetReaderBuf(current_char) == B_OK
|
||||
&& current_char != 0x7) {
|
||||
if (!isprint(current_char & 0x7f)
|
||||
|| len+2 >= sizeof(string))
|
||||
break;
|
||||
@ -800,7 +816,7 @@ TermParse::EscParse(void *data)
|
||||
switch (mode_char) {
|
||||
case '0':
|
||||
case '2':
|
||||
theObj->fWinObj->SetTitle(string);
|
||||
fWinObj->SetTitle(string);
|
||||
break;
|
||||
case '1':
|
||||
break;
|
||||
@ -847,8 +863,23 @@ TermParse::EscParse(void *data)
|
||||
break;
|
||||
}
|
||||
}
|
||||
theObj->fParseThread = -1;
|
||||
fParseThread = -1;
|
||||
exit_thread(B_OK);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/* static */
|
||||
int32
|
||||
TermParse::_ptyreader_thread(void *data)
|
||||
{
|
||||
return reinterpret_cast<TermParse *>(data)->PtyReader();
|
||||
}
|
||||
|
||||
|
||||
/* static */
|
||||
int32
|
||||
TermParse::_escparse_thread(void *data)
|
||||
{
|
||||
return reinterpret_cast<TermParse *>(data)->EscParse();
|
||||
}
|
||||
|
@ -31,8 +31,9 @@
|
||||
#ifndef TERMPARSE_H
|
||||
#define TERMPARSE_H
|
||||
|
||||
#include <kernel/OS.h>
|
||||
#include <OS.h>
|
||||
#include <MessageRunner.h>
|
||||
|
||||
#include "TermConst.h"
|
||||
|
||||
class TermView;
|
||||
@ -42,56 +43,52 @@ class TermWindow;
|
||||
//PtyReader buffer size.
|
||||
#define READ_BUF_SIZE 2048
|
||||
|
||||
class TermParse : public BHandler
|
||||
{
|
||||
class TermParse : public BHandler {
|
||||
public:
|
||||
TermParse (void);
|
||||
~TermParse (void);
|
||||
TermParse(int fd, TermWindow *inWinObj, TermView *inViewObj, CodeConv *inConvObj);
|
||||
~TermParse();
|
||||
|
||||
// Initialize TermParse and PtyReader thread.
|
||||
status_t InitTermParse (TermView *inViewObj, CodeConv *inConvObj);
|
||||
thread_id InitPtyReader (TermWindow *inWinObj);
|
||||
|
||||
// Delete TermParse and PtyReader thread.
|
||||
status_t AbortTermParse (void);
|
||||
status_t AbortPtyReader (void);
|
||||
|
||||
status_t StartThreads();
|
||||
|
||||
private:
|
||||
//
|
||||
// Hook Functions.
|
||||
//
|
||||
// Initialize TermParse and PtyReader thread.
|
||||
status_t InitTermParse();
|
||||
status_t InitPtyReader();
|
||||
|
||||
// Delete TermParse and PtyReader thread.
|
||||
status_t AbortTermParse();
|
||||
status_t AbortPtyReader();
|
||||
|
||||
// Escape Sequance parse thread.
|
||||
static int32 EscParse (void *);
|
||||
int32 EscParse();
|
||||
int32 PtyReader();
|
||||
|
||||
// Pty device reader thread.
|
||||
static int32 PtyReader (void *);
|
||||
static int32 _ptyreader_thread(void *);
|
||||
static int32 _escparse_thread(void *);
|
||||
|
||||
// Reading ReadBuf at one Char.
|
||||
uchar GetReaderBuf (void);
|
||||
// Reading ReadBuf at one Char.
|
||||
status_t GetReaderBuf(uchar &c);
|
||||
|
||||
TermView *fViewObj;
|
||||
TermWindow *fWinObj;
|
||||
CodeConv *fConvObj;
|
||||
int fFd;
|
||||
|
||||
TermView *fViewObj;
|
||||
TermWindow *fWinObj;
|
||||
CodeConv *fConvObj;
|
||||
|
||||
thread_id fParseThread;
|
||||
sem_id fParseSem;
|
||||
thread_id fParseThread;
|
||||
sem_id fParseSem;
|
||||
|
||||
thread_id fReaderThread;
|
||||
sem_id fReaderSem;
|
||||
sem_id fReaderLocker;
|
||||
thread_id fReaderThread;
|
||||
sem_id fReaderSem;
|
||||
sem_id fReaderLocker;
|
||||
|
||||
BMessageRunner *fCursorUpdate;
|
||||
BMessageRunner *fCursorUpdate;
|
||||
|
||||
uint fParser_p; /* EscParse reading buffer pointer */
|
||||
int fLockFlag; /* PtyReader lock flag */
|
||||
uint fParser_p; /* EscParse reading buffer pointer */
|
||||
int fLockFlag; /* PtyReader lock flag */
|
||||
|
||||
bool fQuitting;
|
||||
|
||||
uchar fReadBuf[READ_BUF_SIZE]; /* Reading buffer */
|
||||
bool fQuitting;
|
||||
|
||||
uchar fReadBuf[READ_BUF_SIZE]; /* Reading buffer */
|
||||
};
|
||||
|
||||
#endif // TERMPARSE_H
|
||||
|
@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-4 Kian Duffy <myob@users.sourceforge.net>
|
||||
* Parts Copyright (C) 1998,99 Kazuho Okui and Takashi Murai.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files or portions
|
||||
* thereof (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject
|
||||
* to the following conditions:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice
|
||||
* in the binary, as well as this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided with
|
||||
* the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <PrintJob.h>
|
||||
|
||||
#include "TermView.h"
|
||||
|
||||
BMessage *setup = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// DoPageSetUp ()
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
TermView::DoPageSetup()
|
||||
{
|
||||
BPrintJob job("Page Setup");
|
||||
|
||||
if (setup) {
|
||||
job.SetSettings(setup);
|
||||
}
|
||||
|
||||
if (job.ConfigPage() == B_OK) {
|
||||
delete setup;
|
||||
setup = job.Settings();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// DoPrint ()
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
TermView::DoPrint()
|
||||
{
|
||||
status_t result = B_OK;
|
||||
BPrintJob job("document's name");
|
||||
|
||||
// If we have no setup message, we should call ConfigPage()
|
||||
// You must use the same instance of the BPrintJob object
|
||||
// (you can't call the previous "PageSetup()" function, since it
|
||||
// creates its own BPrintJob object).
|
||||
|
||||
if (!setup) {
|
||||
result = job.ConfigPage();
|
||||
if (result == B_OK) {
|
||||
// Get the user Settings
|
||||
setup = job.Settings();
|
||||
}
|
||||
}
|
||||
|
||||
if (result == B_OK) {
|
||||
// Setup the driver with user settings
|
||||
job.SetSettings(setup);
|
||||
|
||||
result = job.ConfigJob();
|
||||
if (result == B_OK) {
|
||||
// WARNING: here, setup CANNOT be NULL.
|
||||
if (setup == NULL) {
|
||||
// something's wrong, handle the error and bail out
|
||||
}
|
||||
delete setup;
|
||||
|
||||
// Get the user Settings
|
||||
setup = job.Settings();
|
||||
|
||||
// Now you have to calculate the number of pages
|
||||
// (note: page are zero-based)
|
||||
int32 firstPage = job.FirstPage();
|
||||
int32 lastPage = job.LastPage();
|
||||
|
||||
// Verify the range is correct
|
||||
// 0 ... LONG_MAX -> Print all the document
|
||||
// n ... LONG_MAX -> Print from page n to the end
|
||||
// n ... m -> Print from page n to page m
|
||||
|
||||
// if (lastPage > your_document_last_page)
|
||||
// last_page = your_document_last_page;
|
||||
|
||||
int32 nbPages = lastPage - firstPage + 1;
|
||||
|
||||
// Verify the range is correct
|
||||
if (nbPages <= 0)
|
||||
return; // ERROR;
|
||||
|
||||
// Now you can print the page
|
||||
job.BeginJob();
|
||||
|
||||
// Print all pages
|
||||
bool can_continue = job.CanContinue();
|
||||
|
||||
for (int i=firstPage ; can_continue && i<=lastPage ; i++) {
|
||||
// Draw all the needed views
|
||||
//job.DrawView(this, this->Bounds(), pointOnPage);
|
||||
|
||||
// If the document have a lot of pages, you can update a BStatusBar, here
|
||||
// or else what you want...
|
||||
//update_status_bar(i-firstPage, nbPages);
|
||||
|
||||
// Spool the page
|
||||
job.SpoolPage();
|
||||
|
||||
// Cancel the job if needed.
|
||||
// You can for exemple verify if the user pressed the ESC key
|
||||
// or (SHIFT + '.')...
|
||||
//if (user_has_canceled) {
|
||||
// tell the print_server to cancel the printjob
|
||||
//job.CancelJob();
|
||||
//can_continue = false;
|
||||
//break;
|
||||
//}
|
||||
|
||||
// Verify that there was no error (disk full for exemple)
|
||||
can_continue = job.CanContinue();
|
||||
}
|
||||
|
||||
// Now, you just have to commit the job!
|
||||
if (can_continue)
|
||||
job.CommitJob();
|
||||
else
|
||||
result = B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -63,8 +63,9 @@ const static rgb_color kTermColorTable[16] = {
|
||||
};
|
||||
|
||||
|
||||
TermView::TermView(BRect frame, CodeConv *inCodeConv)
|
||||
TermView::TermView(BRect frame, CodeConv *inCodeConv, int fd)
|
||||
: BView(frame, "termview", B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS),
|
||||
fTerminalFd(fd),
|
||||
fFontWidth(0),
|
||||
fFontHeight(0),
|
||||
fFontAscent(0),
|
||||
@ -1119,7 +1120,7 @@ TermView::UpdateSIGWINCH()
|
||||
struct winsize ws;
|
||||
ws.ws_row = fTermRows;
|
||||
ws.ws_col = fTermColumns;
|
||||
ioctl(gPfd, TIOCSWINSZ, &ws);
|
||||
ioctl(fTerminalFd, TIOCSWINSZ, &ws);
|
||||
kill(-sh_pid, SIGWINCH);
|
||||
|
||||
fFrameResized = 0;
|
||||
@ -1139,11 +1140,11 @@ TermView::DeviceStatusReport(int n)
|
||||
switch (n) {
|
||||
case 5:
|
||||
len = sprintf(sbuf,"\033[0n") ;
|
||||
write(gPfd, sbuf, len);
|
||||
write(fTerminalFd, sbuf, len);
|
||||
break ;
|
||||
case 6:
|
||||
len = sprintf(sbuf,"\033[%d;%dR", fTermRows, fTermColumns) ;
|
||||
write(gPfd, sbuf, len);
|
||||
write(fTerminalFd, sbuf, len);
|
||||
break ;
|
||||
default:
|
||||
return;
|
||||
@ -1316,7 +1317,7 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
||||
|
||||
// If bytes[0] equal intr charactor,
|
||||
// send signal to shell process group.
|
||||
tcgetattr(gPfd, &tio);
|
||||
tcgetattr(fTerminalFd, &tio);
|
||||
if (*bytes == tio.c_cc[VINTR]) {
|
||||
if (tio.c_lflag & ISIG)
|
||||
kill(-sh_pid, SIGINT);
|
||||
@ -1330,24 +1331,24 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
||||
case B_RETURN:
|
||||
c = 0x0d;
|
||||
if (key == RETURN_KEY || key == ENTER_KEY) {
|
||||
write(gPfd, &c, 1);
|
||||
write(fTerminalFd, &c, 1);
|
||||
return;
|
||||
} else {
|
||||
write(gPfd, bytes, numBytes);
|
||||
write(fTerminalFd, bytes, numBytes);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case B_LEFT_ARROW:
|
||||
if (key == LEFT_ARROW_KEY) {
|
||||
write(gPfd, LEFT_ARROW_KEY_CODE, sizeof(LEFT_ARROW_KEY_CODE)-1);
|
||||
write(fTerminalFd, LEFT_ARROW_KEY_CODE, sizeof(LEFT_ARROW_KEY_CODE)-1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case B_RIGHT_ARROW:
|
||||
if (key == RIGHT_ARROW_KEY) {
|
||||
write(gPfd, RIGHT_ARROW_KEY_CODE, sizeof(RIGHT_ARROW_KEY_CODE)-1);
|
||||
write(fTerminalFd, RIGHT_ARROW_KEY_CODE, sizeof(RIGHT_ARROW_KEY_CODE)-1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -1362,7 +1363,7 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
||||
}
|
||||
|
||||
if (key == UP_ARROW_KEY) {
|
||||
write(gPfd, UP_ARROW_KEY_CODE, sizeof(UP_ARROW_KEY_CODE)-1);
|
||||
write(fTerminalFd, UP_ARROW_KEY_CODE, sizeof(UP_ARROW_KEY_CODE)-1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -1375,21 +1376,21 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
||||
}
|
||||
|
||||
if (key == DOWN_ARROW_KEY) {
|
||||
write(gPfd, DOWN_ARROW_KEY_CODE, sizeof(DOWN_ARROW_KEY_CODE)-1);
|
||||
write(fTerminalFd, DOWN_ARROW_KEY_CODE, sizeof(DOWN_ARROW_KEY_CODE)-1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case B_INSERT:
|
||||
if (key == INSERT_KEY) {
|
||||
write(gPfd, INSERT_KEY_CODE, sizeof(INSERT_KEY_CODE)-1);
|
||||
write(fTerminalFd, INSERT_KEY_CODE, sizeof(INSERT_KEY_CODE)-1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case B_HOME:
|
||||
if (key == HOME_KEY) {
|
||||
write(gPfd, HOME_KEY_CODE, sizeof(HOME_KEY_CODE)-1);
|
||||
write(fTerminalFd, HOME_KEY_CODE, sizeof(HOME_KEY_CODE)-1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -1404,7 +1405,7 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
||||
}
|
||||
|
||||
if (key == PAGE_UP_KEY) {
|
||||
write(gPfd, PAGE_UP_KEY_CODE, sizeof(PAGE_UP_KEY_CODE)-1);
|
||||
write(fTerminalFd, PAGE_UP_KEY_CODE, sizeof(PAGE_UP_KEY_CODE)-1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -1417,14 +1418,14 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
||||
}
|
||||
|
||||
if (key == PAGE_DOWN_KEY) {
|
||||
write(gPfd, PAGE_DOWN_KEY_CODE, sizeof(PAGE_DOWN_KEY_CODE)-1);
|
||||
write(fTerminalFd, PAGE_DOWN_KEY_CODE, sizeof(PAGE_DOWN_KEY_CODE)-1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case B_END:
|
||||
if (key == END_KEY) {
|
||||
write(gPfd, END_KEY_CODE, sizeof(END_KEY_CODE)-1);
|
||||
write(fTerminalFd, END_KEY_CODE, sizeof(END_KEY_CODE)-1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -1432,7 +1433,7 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
||||
case B_FUNCTION_KEY:
|
||||
for (c = 0; c < 12; c++) {
|
||||
if (key == function_keycode_table[c]) {
|
||||
write(gPfd, function_key_char_table[c], 5);
|
||||
write(fTerminalFd, function_key_char_table[c], 5);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1447,12 +1448,12 @@ TermView::KeyDown(const char *bytes, int32 numBytes)
|
||||
if (gNowCoding != M_UTF8) {
|
||||
int cnum = fCodeConv->ConvertFromInternal(bytes, numBytes,
|
||||
(char *)dstbuf, gNowCoding);
|
||||
write(gPfd, dstbuf, cnum);
|
||||
write(fTerminalFd, dstbuf, cnum);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
write(gPfd, bytes, numBytes);
|
||||
write(fTerminalFd, bytes, numBytes);
|
||||
}
|
||||
|
||||
|
||||
@ -1534,7 +1535,7 @@ TermView::MessageReceived(BMessage *msg)
|
||||
|
||||
case MENU_CLEAR_ALL:
|
||||
DoClearAll();
|
||||
write(gPfd, ctrl_l, 1);
|
||||
write(fTerminalFd, ctrl_l, 1);
|
||||
break;
|
||||
|
||||
case MSGRUN_CURSOR:
|
||||
@ -1726,10 +1727,10 @@ TermView::WritePTY(const uchar *text, int numBytes)
|
||||
uchar *destBuffer = (uchar *)malloc(numBytes * 3);
|
||||
numBytes = fCodeConv->ConvertFromInternal((char*)text, numBytes,
|
||||
(char*)destBuffer, gNowCoding);
|
||||
write(gPfd, destBuffer, numBytes);
|
||||
write(fTerminalFd, destBuffer, numBytes);
|
||||
free(destBuffer);
|
||||
} else {
|
||||
write(gPfd, text, numBytes);
|
||||
write(fTerminalFd, text, numBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ public:
|
||||
//
|
||||
// Constructor, Destructor, and Initializer.
|
||||
//
|
||||
TermView (BRect frame, CodeConv *inCodeConv);
|
||||
TermView (BRect frame, CodeConv *inCodeConv, int fd);
|
||||
~TermView ();
|
||||
|
||||
//
|
||||
@ -272,6 +272,7 @@ private:
|
||||
* DATA Member.
|
||||
*/
|
||||
|
||||
int fTerminalFd;
|
||||
//
|
||||
// Font and Width.
|
||||
//
|
||||
|
@ -58,9 +58,9 @@ extern int gNowCoding; /* defined TermParce.cpp */
|
||||
void SetCoding(int);
|
||||
|
||||
|
||||
TermWindow::TermWindow(BRect frame, const char* title, int gPfd)
|
||||
TermWindow::TermWindow(BRect frame, const char* title, int fd)
|
||||
: BWindow(frame, title, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE),
|
||||
fPfd(gPfd)
|
||||
fPfd(fd)
|
||||
{
|
||||
InitWindow();
|
||||
|
||||
@ -115,7 +115,7 @@ TermWindow::InitWindow(void)
|
||||
textframe.top = fMenubar->Bounds().bottom + 1.0;
|
||||
|
||||
fCodeConv = new CodeConv();
|
||||
fTermView = new TermView(Bounds(), fCodeConv);
|
||||
fTermView = new TermView(Bounds(), fCodeConv, fPfd);
|
||||
|
||||
/*
|
||||
* MuTerm has two views. BaseView is window base view.
|
||||
@ -132,7 +132,6 @@ TermWindow::InitWindow(void)
|
||||
gTermPref->getInt32(PREF_COLS), 1);
|
||||
|
||||
int width, height;
|
||||
|
||||
fTermView->GetFontSize(&width, &height);
|
||||
SetSizeLimits(MIN_COLS * width, MAX_COLS * width,
|
||||
MIN_COLS * height, MAX_COLS * height);
|
||||
@ -170,11 +169,10 @@ TermWindow::InitWindow(void)
|
||||
fEditmenu->SetTargetForItems(fTermView);
|
||||
|
||||
// Initialize TermParse
|
||||
|
||||
gNowCoding = longname2op(gTermPref->getString(PREF_TEXT_ENCODING));
|
||||
fTermParse = new TermParse();
|
||||
fTermParse->InitPtyReader(this);
|
||||
fTermParse->InitTermParse(fTermView, fCodeConv);
|
||||
fTermParse = new TermParse(fPfd, this, fTermView, fCodeConv);
|
||||
if (fTermParse->StartThreads() < B_OK)
|
||||
return;
|
||||
|
||||
// Set Coding.
|
||||
|
||||
|
@ -33,8 +33,6 @@
|
||||
#include "TermApp.h"
|
||||
#include "PrefHandler.h"
|
||||
|
||||
/* global varriables */
|
||||
int gPfd; /* pesudo tty fd */
|
||||
|
||||
PrefHandler *gTermPref; /* Preference temporary */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user