Initial import of the CDE 2.1.30 sources from the Open Group.

This commit is contained in:
Peter Howkins
2012-03-10 18:21:40 +00:00
commit 83b6996daa
18978 changed files with 3945623 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
XCOMM $TOG: Imakefile /main/3 1998/03/16 14:41:32 mgreess $
#define DoNormalLib NormalLibDtTerm
#define DoSharedLib SharedLibDtTerm
#define DoDebugLib DebugLibDtTerm
#define DoProfileLib ProfileLibDtTerm
#define LibName DtTerm
#define SoRev SODTTERMREV
#define IncSubdir Dt
#define LibCreate NO
#include <Threads.tmpl>
DEFINES = $(ARCHITECTURE_DEFINES)
INCLUDES = -I.
HEADERS = TermPrim.h TermPrimP.h
SRCS = \
TermPrim.c \
TermPrimAction.c \
TermPrimBuffer.c \
TermPrimBufferWc.c \
TermPrimCursor.c \
TermPrimDebug.c \
TermPrimFunction.c \
TermPrimGetPty.c \
TermPrimLineDraw.c \
TermPrimParse.c \
TermPrimParseTable.c \
TermPrimParser.c \
TermPrimPendingText.c \
TermPrimRender.c \
TermPrimRenderMb.c \
TermPrimRenderFont.c \
TermPrimRenderFontSet.c \
TermPrimRenderLineDraw.c \
TermPrimRepType.c \
TermPrimScroll.c \
TermPrimSelect.c \
TermPrimSetPty.c \
TermPrimSetUtmp.c \
TermPrimSubproc.c \
TermPrimUtil.c \
TermPrimVersion.c \
TermPrimWMProtocols.c
OBJS = \
TermPrim.o \
TermPrimAction.o \
TermPrimBuffer.o \
TermPrimBufferWc.o \
TermPrimCursor.o \
TermPrimDebug.o \
TermPrimFunction.o \
TermPrimGetPty.o \
TermPrimLineDraw.o \
TermPrimParse.o \
TermPrimParseTable.o \
TermPrimParser.o \
TermPrimPendingText.o \
TermPrimRender.o \
TermPrimRenderMb.o \
TermPrimRenderFont.o \
TermPrimRenderFontSet.o \
TermPrimRenderLineDraw.o \
TermPrimRepType.o \
TermPrimScroll.o \
TermPrimSelect.o \
TermPrimSetPty.o \
TermPrimSetUtmp.o \
TermPrimSubproc.o \
TermPrimUtil.o \
TermPrimVersion.o \
TermPrimWMProtocols.o
#include <Library.tmpl>
/* These should be cleaned up. Test SVR4Architecture? */
#ifdef AlphaArchitecture
LinkFile(TermPrimGetPty.c,TermPrimGetPty-bsd.c)
#endif
#ifdef HPArchitecture
# if OSMajorVersion > 9
LinkFile(TermPrimGetPty.c,TermPrimGetPty-svr4.c)
# else
LinkFile(TermPrimGetPty.c,TermPrimGetPty-bsd.c)
# endif
#endif
#ifdef IBMArchitecture
LinkFile(TermPrimGetPty.c,TermPrimGetPty-clone.c)
#endif
#ifdef LinuxArchitecture
LinkFile(TermPrimGetPty.c,TermPrimGetPty-clone.c)
#endif
#ifdef SunArchitecture
LinkFile(TermPrimGetPty.c,TermPrimGetPty-svr4.c)
#endif
#ifdef USLArchitecture
LinkFile(TermPrimGetPty.c,TermPrimGetPty-svr4.c)
#endif
#ifdef UXPArchitecture
LinkFile(TermPrimGetPty.c,TermPrimGetPty-svr4.c)
#endif
SubdirLibraryRule($(OBJS))
DependTarget()

View File

@@ -0,0 +1,56 @@
/*
* $TOG: TermHeader.h /main/3 1999/10/14 16:34:46 mgreess $";
*/
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#ifndef _Dt_TermHeader_h
#define _Dt_TermHeader_h
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/param.h> /* for MIN, MAX macros */
#include <Xm/Xm.h>
#include <X11/Xos.h>
#if defined(linux) || defined(UXPArchitecture) || (defined(USL) && (OSMAJORVERSION > 1))
#define _NFILE FOPEN_MAX
#endif
#ifndef MIN
#define MIN(a,b) (((a) > (b)) ? (b) : (a))
#endif /* MIN */
#ifndef MAX
#define MAX(a,b) (((a) < (b)) ? (b) : (a))
#endif /* MAX */
/******** Conditionally defined macros for thread_safe DtTerm ******/
#ifdef XTHREADS
#define _DtTermWidgetToAppContext(w) \
XtAppContext app = XtWidgetToApplicationContext(w)
#define _DtTermDisplayToAppContext(d) \
XtAppContext app = XtDisplayToApplicationContext(d)
#define _DtTermAppLock(app) XtAppLock(app)
#define _DtTermAppUnlock(app) XtAppUnlock(app)
#define _DtTermProcessLock() XtProcessLock()
#define _DtTermProcessUnlock() XtProcessUnlock()
#else /* XTHREADS */
#define _DtTermWidgetToAppContext(w)
#define _DtTermDisplayToAppContext(d)
#define _DtTermAppLock(app)
#define _DtTermAppUnlock(app)
#define _DtTermProcessLock()
#define _DtTermProcessUnlock()
#endif /* XTHREADS */
#endif /* _Dt_TermHeader_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,516 @@
/* $XConsortium: TermPrim.h /main/1 1996/04/21 19:16:41 drk $ */
/*
* (c) Copyright 1993, 1994 Hewlett-Packard Company
* (c) Copyright 1993, 1994 International Business Machines Corp.
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
* (c) Copyright 1993, 1994 Novell, Inc.
*/
#ifndef _Dt_TermPrim_h
#define _Dt_TermPrim_h
#include <sys/wait.h>
#include <Xm/Xm.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Constants
*/
/* Resources */
#ifndef DtNbackgroundIsSelect
#define DtNbackgroundIsSelect "backgroundIsSelect"
#endif
#ifndef DtNblinkRate
#define DtNblinkRate "blinkRate"
#endif
#ifndef DtNcharCursorStyle
#define DtNcharCursorStyle "charCursorStyle"
#endif
#ifndef DtNconsoleMode
#define DtNconsoleMode "consoleMode"
#endif
#ifndef DtNcsWidth
#define DtNcsWidth "csWidth"
#endif
#ifndef DtNemulationId
#define DtNemulationId "emulationId"
#endif
#ifndef DtNinputVerifyCallback
#define DtNinputVerifyCallback "inputVerifyCallback"
#endif
#ifndef DtNjumpScroll
#define DtNjumpScroll "jumpScroll"
#endif
#ifndef DtNkshMode
#define DtNkshMode "kshMode"
#endif
#ifndef DtNlogFile
#define DtNlogFile "logFile"
#endif
#ifndef DtNlogInhibit
#define DtNlogInhibit "logInhibit"
#endif
#ifndef DtNlogging
#define DtNlogging "logging"
#endif
#ifndef DtNloginShell
#define DtNloginShell "loginShell"
#endif
#ifndef DtNmapOnOutput
#define DtNmapOnOutput "mapOnOutput"
#endif
#ifndef DtNmapOnOutputDelay
#define DtNmapOnOutputDelay "mapOnOutputDelay"
#endif
#ifndef DtNmarginBell
#define DtNmarginBell "marginBell"
#endif
#ifndef DtNnMarginBell
#define DtNnMarginBell "nMarginBell"
#endif
#ifndef DtNoutputLogCallback
#define DtNoutputLogCallback "outputLogCallback"
#endif
#ifndef DtNpointerBlank
#define DtNpointerBlank "pointerBlank"
#endif
#ifndef DtNpointerBlankDelay
#define DtNpointerBlankDelay "pointerBlankDelay"
#endif
#ifndef DtNpointerColor
#define DtNpointerColor "pointerColor"
#endif
#ifndef DtNpointerColorBackground
#define DtNpointerColorBackground "pointerColorBackground"
#endif
#ifndef DtNpointerShape
#define DtNpointerShape "pointerShape"
#endif
#ifndef DtNreverseVideo
#define DtNreverseVideo "reverseVideo"
#endif
#ifndef DtNsaveLines
#define DtNsaveLines "saveLines"
#endif
#ifndef DtNsizeList
#define DtNsizeList "sizeList"
#endif
#ifndef DtNstatusChangeCallback
#define DtNstatusChangeCallback "statusChangeCallback"
#endif
#ifndef DtNstickyNextCursor
#define DtNstickyNextCursor "stickyNextCursor"
#endif
#ifndef DtNstickyPrevCursor
#define DtNstickyPrevCursor "stickyPrevCursor"
#endif
#ifndef DtNsubprocessLoginShell
#define DtNsubprocessLoginShell "subprocessLoginShell"
#endif
#ifndef DtNsubprocessPid
#define DtNsubprocessPid "subprocessPid"
#endif
#ifndef DtNsubprocessExec
#define DtNsubprocessExec "subprocessExec"
#endif
#ifndef DtNsubprocessTerminationCatch
#define DtNsubprocessTerminationCatch "subprocessTerminationCatch"
#endif
#ifndef DtNsubprocessCmd
#define DtNsubprocessCmd "subprocessCmd"
#endif
#ifndef DtNsubprocessArgv
#define DtNsubprocessArgv "subprocessArgv"
#endif
#ifndef DtNsubprocessTerminationCallback
#define DtNsubprocessTerminationCallback "subprocessTerminationCallback"
#endif
#ifndef DtNtermEmulationMode
#define DtNtermEmulationMode "termEmulationMode"
#endif
#ifndef DtNtermDevice
#define DtNtermDevice "termDevice"
#endif
#ifndef DtNtermDeviceAllocate
#define DtNtermDeviceAllocate "termDeviceAllocate"
#endif
#ifndef DtNtermId
#define DtNtermId "termId"
#endif
#ifndef DtNtermName
#define DtNtermName "termName"
#endif
#ifndef DtNtermSlaveName
#define DtNtermSlaveName "termSlaveName"
#endif
#ifndef DtNttyModes
#define DtNttyModes "ttyModes"
#endif
#ifndef DtNuseFontSets
#define DtNuseFontSets "useFontSets"
#endif
#ifndef DtNuseLineDraw
#define DtNuseLineDraw "useLineDraw"
#endif
#ifndef DtNuserFont
#define DtNuserFont "userFont"
#endif
#ifndef DtNuserBoldFont
#define DtNuserBoldFont "userBoldFont"
#endif
#ifndef DtNvisualBell
#define DtNvisualBell "visualBell"
#endif
#ifndef DtNallowSendEvents
#define DtNallowSendEvents "allowSendEvents"
#endif
#ifndef DtNbaseHeight
#define DtNbaseHeight XmNbaseHeight
#endif
#ifndef DtNbaseWidth
#define DtNbaseWidth XmNbaseWidth
#endif
#ifndef DtNcolumns
#define DtNcolumns XmNcolumns
#endif
#ifndef DtNheightInc
#define DtNheightInc XmNheightInc
#endif
#ifndef DtNmarginHeight
#define DtNmarginHeight XmNmarginHeight
#endif
#ifndef DtNmarginWidth
#define DtNmarginWidth XmNmarginWidth
#endif
#ifndef DtNrows
#define DtNrows XmNrows
#endif
#ifndef DtNshadowType
#define DtNshadowType XmNshadowType
#endif
#ifndef DtNverticalScrollBar
#define DtNverticalScrollBar XmNverticalScrollBar
#endif
#ifndef DtNwidthInc
#define DtNwidthInc XmNwidthInc
#endif
#ifndef DtCBackground
#define DtCBackground XmCBackground
#endif
#ifndef DtCBackgroundIsSelect
#define DtCBackgroundIsSelect "BackgroundIsSelect"
#endif
#ifndef DtCBlinkRate
#define DtCBlinkRate "BlinkRate"
#endif
#ifndef DtCCallback
#define DtCCallback XmCCallback
#endif
#ifndef DtCCursor
#define DtCCursor XmCCursor
#endif
#ifndef DtCConsoleMode
#define DtCConsoleMode "ConsoleMode"
#endif
#ifndef DtCCsWidth
#define DtCCsWidth "CsWidth"
#endif
#ifndef DtCCharCursorStyle
#define DtCCharCursorStyle "CharCursorStyle"
#endif
#ifndef DtCEmulationId
#define DtCEmulationId "EmulationId"
#endif
#ifndef DtCForeground
#define DtCForeground XmCForeground
#endif
#ifndef DtCJumpScroll
#define DtCJumpScroll "JumpScroll"
#endif
#ifndef DtCKshMode
#define DtCKshMode "KshMode"
#endif
#ifndef DtCLogFile
#define DtCLogFile "LogFile"
#endif
#ifndef DtCLogInhibit
#define DtCLogInhibit "LogInhibit"
#endif
#ifndef DtCLogging
#define DtCLogging "Logging"
#endif
#ifndef DtCLoginShell
#define DtCLoginShell "LoginShell"
#endif
#ifndef DtCMapOnOutput
#define DtCMapOnOutput "MapOnOutput"
#endif
#ifndef DtCMapOnOutputDelay
#define DtCMapOnOutputDelay "MapOnOutputDelay"
#endif
#ifndef DtCMarginBell
#define DtCMarginBell "MarginBell"
#endif
#ifndef DtCNMarginBell
#define DtCNMarginBell "NMarginBell"
#endif
#ifndef DtCPointerBlank
#define DtCPointerBlank "PointerBlank"
#endif
#ifndef DtCPointerBlankDelay
#define DtCPointerBlankDelay "PointerBlankDelay"
#endif
#ifndef DtCPointerColor
#define DtCPointerColor "PointerColor"
#endif
#ifndef DtCPointerColorBackground
#define DtCPointerColorBackground "PointerColorBackground"
#endif
#ifndef DtCPointerShape
#define DtCPointerShape "PointerShape"
#endif
#ifndef DtCReverseVideo
#define DtCReverseVideo "ReverseVideo"
#endif
#ifndef DtCSaveLines
#define DtCSaveLines "SaveLines"
#endif
#ifndef DtCSizeList
#define DtCSizeList "SizeList"
#endif
#ifndef DtCStickyCursor
#define DtCStickyCursor "StickyCursor"
#endif
#ifndef DtCSubprocessLoginShell
#define DtCSubprocessLoginShell "SubprocessLoginShell"
#endif
#ifndef DtCSubprocessPid
#define DtCSubprocessPid "SubprocessPid"
#endif
#ifndef DtCSubprocessExec
#define DtCSubprocessExec "SubprocessExec"
#endif
#ifndef DtCSubprocessTerminationCatch
#define DtCSubprocessTerminationCatch "SubprocessTerminationCatch"
#endif
#ifndef DtCSubprocessCmd
#define DtCSubprocessCmd "SubprocessCmd"
#endif
#ifndef DtCSubprocessArgv
#define DtCSubprocessArgv "SubprocessArgv"
#endif
#ifndef DtCTermEmulationMode
#define DtCTermEmulationMode "TermEmulationMode"
#endif
#ifndef DtCTermDevice
#define DtCTermDevice "TermDevice"
#endif
#ifndef DtCTermDeviceAllocate
#define DtCTermDeviceAllocate "TermDeviceAllocate"
#endif
#ifndef DtCTermId
#define DtCTermId "TermId"
#endif
#ifndef DtCTermName
#define DtCTermName "TermName"
#endif
#ifndef DtCTermSlaveName
#define DtCTermSlaveName "TermSlaveName"
#endif
#ifndef DtCTtyModes
#define DtCTtyModes "TtyModes"
#endif
#ifndef DtCUseFontSets
#define DtCUseFontSets "UseFontSets"
#endif
#ifndef DtCUseLineDraw
#define DtCUseLineDraw "UseLineDraw"
#endif
#ifndef DtCUserFont
#define DtCUserFont "UserFont"
#endif
#ifndef DtCUserBoldFont
#define DtCUserBoldFont "UserBoldFont"
#endif
#ifndef DtCVisualBell
#define DtCVisualBell "VisualBell"
#endif
#ifndef DtCAllowSendEvents
#define DtCAllowSendEvents "AllowSendEvents"
#endif
#ifndef DtCBaseHeight
#define DtCBaseHeight XmCBaseHeight
#endif
#ifndef DtCBaseWidth
#define DtCBaseWidth XmCBaseWidth
#endif
#ifndef DtCColumns
#define DtCColumns XmCColumns
#endif
#ifndef DtCHeightInc
#define DtCHeightInc XmCHeightInc
#endif
#ifndef DtCMarginHeight
#define DtCMarginHeight XmCMarginHeight
#endif
#ifndef DtCMarginWidth
#define DtCMarginWidth XmCMarginWidth
#endif
#ifndef DtCRows
#define DtCRows XmCRows
#endif
#ifndef DtCShadowType
#define DtCShadowType XmCShadowType
#endif
#ifndef DtCVerticalScrollBar
#define DtCVerticalScrollBar XmCVerticalScrollBar
#endif
#ifndef DtCWidthInc
#define DtCWidthInc XmCWidthInc
#endif
/* Representation types */
#define DtRDtTermCharCursorStyle "DtTermCharCursorStyle"
#define DtRDtTermEmulationMode "DtTermEmulationMode"
#define DtRDtTermTerminalSize "DtTermTerminalSize"
#define DtRDtTermTerminalSizeList "DtTermTerminalSizeList"
/* DtNshadowType values */
#ifndef DtSHADOW_IN
#define DtSHADOW_IN XmSHADOW_IN
#endif
#ifndef DtSHADOW_OUT
#define DtSHADOW_OUT XmSHADOW_OUT
#endif
#ifndef DtSHADOW_ETCHED_IN
#define DtSHADOW_ETCHED_IN XmSHADOW_ETCHED_IN
#endif
#ifndef DtSHADOW_ETCHED_OUT
#define DtSHADOW_ETCHED_OUT XmSHADOW_ETCHED_OUT
#endif
#define DtTERM_CHAR_CURSOR_BOX 0
#define DtTERM_CHAR_CURSOR_BAR 1
#define DtTERM_CHAR_CURSOR_INVISIBLE 2
#define DtTermEMULATIONHP 0
#define DtTermEMULATIONANSI 1
/* Callback reasons */
#define DtCR_TERM_SUBPROCESS_TERMINATION 1
#define DtCR_TERM_STATUS_CHANGE 2
#define DtCR_TERM_INPUT_VERIFY 7
#define DtCR_TERM_OUTPUT_LOG 8
/*
* Types
*/
/* insert char mode */
typedef enum {
DtTERM_INSERT_CHAR_OFF = 0,
DtTERM_INSERT_CHAR_ON,
DtTERM_INSERT_CHAR_ON_WRAP
} DtTermInsertCharMode;
typedef struct {
int reason;
XEvent *event;
int cursorX;
int cursorY;
Boolean capsLock;
Boolean stop;
DtTermInsertCharMode insertCharMode;
Boolean locked;
} DtTermStatusChangeCallbackStruct;
typedef struct {
int reason;
XEvent *event;
pid_t pid;
int status;
} DtTermSubprocessTerminationCallbackStruct;
typedef struct {
int reason;
XEvent *event;
Boolean doit;
unsigned char *text;
int length;
} DtTermInputVerifyCallbackStruct;
typedef struct {
int reason;
XEvent *event;
unsigned char *text;
int length;
} DtTermOutputLogCallbackStruct;
typedef struct _DtTermTerminalSize {
short rows;
short columns;
} DtTermTerminalSize;
typedef struct _DtTermTerminalSizeList {
int numSizes;
DtTermTerminalSize *sizes;
} DtTermTerminalSizeList;
/* Widget class and instance */
typedef struct _DtTermPrimitiveClassRec *DtTermPrimitiveWidgetClass;
typedef struct _DtTermPrimitiveRec *DtTermPrimitiveWidget;
/*
* Data
*/
/* Widget class record */
externalref WidgetClass dtTermPrimitiveWidgetClass;
/*
* Functions
*/
extern Widget DtCreateTermPrimitive(
Widget parent,
char *name,
ArgList arglist,
Cardinal argcount);
extern void DtTermInitialize(void);
extern void DtTermDisplaySend(
Widget widget,
unsigned char *buffer,
int length);
extern void DtTermSubprocSend(
Widget widget,
unsigned char *buffer,
int length);
extern void DtTermSubprocReap(
pid_t pid,
int *stat_loc);
#ifdef __cplusplus
}
#endif
#endif /* _Dt_TermPrim_h */

View File

@@ -0,0 +1,250 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimAction.c /main/1 1996/04/21 19:16:44 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#include "TermHeader.h"
#include "TermPrimDebug.h"
#include "TermPrimP.h"
#include "TermPrimI.h"
#include "TermPrimData.h"
#include "TermPrimAction.h"
#include "TermPrimFunction.h"
static void
invokeAction(Widget w, char *transmitString, TermFunction function, int count)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
if (KEYBOARD_LOCKED(tpd->keyboardLocked)) {
/* keyboard locked -- ring the bell...
*/
(void) _DtTermPrimBell(w);
} else if (tpd->transmitFunctions && transmitString) {
/* transmit functions mode -- transmit them...
*/
(void) _DtTermPrimSendInput(w, (unsigned char *) transmitString,
strlen(transmitString));
} else {
/* perform the function...
*/
(*function)(w, count, fromAction);
#ifdef NOTDEF
/* we need to wait for the scroll to complete before turning
* on the cursor...
*/
(void) _DtTermPrimScrollComplete(w, True);
#endif /* NOTDEF */
(void) _DtTermPrimCursorOn(w);
}
return;
}
typedef struct {
const char *string;
char value;
} EnumType;
static int
stringToEnum(char *c, EnumType *enumTypes, int numEnumTypes)
{
int i;
for (i = 0; i < numEnumTypes; i++) {
if (!strcmp(enumTypes[i].string, c))
return(i);
}
return(-1);
}
/*** INSERT CHAR/LINE *********************************************************
*
* # # # #### ###### ##### #####
* # ## # # # # # #
* # # # # #### ##### # # #
* # # # # # # ##### #
* # # ## # # # # # #
* # # # #### ###### # # #
*
* #
* #### # # ## ##### # # # # # ######
* # # # # # # # # # # # ## # #
* # ###### # # # # # # # # # # #####
* # # # ###### ##### # # # # # # #
* # # # # # # # # # # # # ## #
* #### # # # # # # # ###### # # # ######
*/
void
_DtTermPrimActionInsert(Widget w, XEvent *event,
String *params, Cardinal *num_params)
{
Debug('i', fprintf(stderr,
">>_DtTermPrimActionInsert: not yet implemented\n"));
}
/*** CURSOR MOTION ************************************************************
*
* #### # # ##### #### #### #####
* # # # # # # # # # # #
* # # # # # #### # # # #
* # # # ##### # # # #####
* # # # # # # # # # # # #
* #### #### # # #### #### # #
*
*
* # # #### ##### # #### # #
* ## ## # # # # # # ## #
* # ## # # # # # # # # # #
* # # # # # # # # # # #
* # # # # # # # # # ##
* # # #### # # #### # #
*/
void
_DtTermPrimActionRedrawDisplay(Widget w, XEvent *event,
String *params, Cardinal *num_params)
{
(void) invokeAction(w, NULL, _DtTermPrimFuncRedrawDisplay, 1);
return;
}
void
_DtTermPrimActionReturn(Widget w, XEvent *event,
String *params, Cardinal *num_params)
{
Debug('i', fprintf(stderr,
">>_DtTermPrimActionReturn: not yet implemented\n"));
return;
}
void
_DtTermPrimActionTab(Widget w, XEvent *event,
String *params, Cardinal *num_params)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
Boolean shiftedTab = False;
Boolean numericTab = False;
int i;
(void) _DtTermPrimSendInput(w, (unsigned char *) "\t", 1);
return;
}
/*** STRING *******************************************************************
*
* #### ##### ##### # # # ####
* # # # # # ## # # #
* #### # # # # # # # #
* # # ##### # # # # # ###
* # # # # # # # ## # #
* #### # # # # # # ####
*/
void
_DtTermPrimActionString(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
unsigned char *c;
unsigned char hexVal;
/* this is based on the functionality offered by xterm...
*/
if (*num_params != 1)
return;
/* process hex values... */
if (((*params)[0] == '0') &&
(((*params)[1] == 'x') || ((*params)[1] == 'X')) &&
((*params)[2] != '\0')) {
for (hexVal = 0, c = (unsigned char *) (*params + 2); *c; c++) {
hexVal *= 16;
*c = tolower(*c);
if ((*c >= '0') && (*c <= '9')) {
hexVal += *c - '0';
} else if ((*c >= 'a') && (*c <= 'f')) {
hexVal += *c - 'a' + 10;
} else {
break;
}
}
/* if we hit the end of the string, send the hex value... */
if (*c == '\0') {
(void) _DtTermPrimSendInput(w, &hexVal, 1);
}
} else {
(void) _DtTermPrimSendInput(w, (unsigned char *) *params, strlen(*params));
}
return;
}
/*** KEYMAP *******************************************************************
*
* # # ###### # # # # ## #####
* # # # # # ## ## # # # #
* #### ##### # # ## # # # # #
* # # # # # # ###### #####
* # # # # # # # # #
* # # ###### # # # # # #
*/
void
_DtTermPrimActionKeymap(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
XtTranslations keymap;
char buffer[BUFSIZ];
static XtTranslations original = (XtTranslations) 0;
static XtResource key_resources[] = {
{XtNtranslations, XtCTranslations, XtRTranslationTable,
sizeof(XtTranslations), 0, XtRTranslationTable, (caddr_t) NULL}
};
char mapName[BUFSIZ];
char mapClass[BUFSIZ];
if (*num_params != 1) {
return;
}
_DtTermProcessLock();
if (original == (XtTranslations) 0) {
original = w->core.tm.translations;
}
_DtTermProcessUnlock();
if (!strcmp(params[0], "None")) {
(void) XtOverrideTranslations(w, original);
return;
}
(void) sprintf(mapName, "%sKeymap", params[0]);
(void) strcpy(mapClass, mapName);
mapClass[0] = toupper(mapClass[0]);
(void) XtGetSubresources(w, (XtPointer) &keymap, mapName, mapClass,
key_resources, XtNumber(key_resources), NULL, (Cardinal) 0);
if (keymap != NULL) {
(void) XtOverrideTranslations(w, keymap);
}
return;
}

View File

@@ -0,0 +1,44 @@
/*
* $XConsortium: TermPrimAction.h /main/1 1996/04/21 19:16:47 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimAction_h
#define _Dt_TermPrimAction_h
extern void _DtTermPrimActionKeyInput(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _DtTermPrimActionKeyRelease(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _termActionGrabFocus(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _DtTermPrimActionLeave(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _DtTermPrimActionEnter(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _DtTermPrimActionFocusIn(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _DtTermPrimActionFocusOut(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _DtTermPrimActionInsert(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _DtTermPrimActionKeymap(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _DtTermPrimActionRedrawDisplay(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _DtTermPrimActionReturn(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _DtTermPrimActionStop(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _DtTermPrimActionString(Widget w, XEvent *event,
String *params, Cardinal *num_params);
extern void _DtTermPrimActionTab(Widget w, XEvent *event,
String *params, Cardinal *num_params);
#endif /* _Dt_TermPrimAction_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,648 @@
/*
** $XConsortium: TermPrimBuffer.h /main/1 1996/04/21 19:16:53 drk $
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimBuffer_h
#define _Dt_TermPrimBuffer_h
typedef struct _TermLineSelectionRec *TermLineSelection;
typedef struct _TermBufferRec *TermBuffer;
typedef struct _TermEnhInfoRec *TermEnhInfo;
typedef struct _TermCharInfoRec *TermCharInfo;
#include <Xm/Xm.h>
#include "TermPrimOSDepI.h"
#include "TermPrimRender.h"
#include "TermPrimSelect.h"
#define TermENH_SECURE (1 << 0)
#define TermENH_UNDERLINE (1 << 1)
#define TermENH_OVERSTRIKE (1 << 2)
#define TermIS_SECURE(flags) ((flags) & TermENH_SECURE)
#define TermIS_UNDERLINE(flags) ((flags) & TermENH_UNDERLINE)
#define TermIS_OVERSTRIKE(flags) ((flags) & TermENH_OVERSTRIKE)
typedef unsigned char enhValue;
typedef enhValue *enhValues;
typedef enum _countSpec
{
countAll, countNew
} countSpec;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef unsigned char termChar;
typedef struct _TermEnhInfoRec {
Pixel fg;
Pixel bg;
TermFont font;
unsigned long flags;
} TermEnhInfoRec;
typedef struct _TermCharInfoRec {
union
{
termChar *ptc;
char *pc;
wchar_t *pwc;
} u;
short idx; /* index into line buffer */
short len; /* bytes per character */
short startCol;
short width;
enhValue enh;
short enhLen;
} TermCharInfoRec;
typedef TermBuffer
(*BufferCreateProc)
(
const Widget,
const short,
const short,
const short,
const short,
const short
);
typedef void
(*BufferFreeProc)
(
const TermBuffer
);
typedef void
(*BufferResizeProc)
(
TermBuffer, short *, short *
);
typedef void
(*TermEnhProc)
(
Widget, enhValues, TermEnhInfo
);
typedef void
(*TermEnhClear)
(
TermBuffer,
short,
short,
short
);
typedef void
(*TermEnhInsert)
(
const TermBuffer,
const short,
const short,
short,
const Boolean
);
typedef void
(*TermEnhDelete)
(
TermBuffer,
short,
short,
short
);
typedef int
(*TermEnhSet)
(
TermBuffer,
short,
short,
unsigned char,
enhValue
);
typedef Boolean
(*TermEnhGet)
(
const TermBuffer,
const short,
const short,
enhValue **,
short *,
const countSpec
);
typedef Boolean
(*TermLineSetLen)
(
TermBuffer,
short,
short
);
typedef Boolean
(*TermLineSetWidth)
(
TermBuffer,
short,
short
);
typedef Boolean
(*TermLineClear)
(
TermBuffer,
short,
short
);
#ifdef USE_SUN_WCWIDTH_PATCH
/*
** A small workaround for systems that don't have wcwidth...
*/
int
sun_wcwidth
(
const wchar_t wc
);
#endif /* USE_SUN_WCWIDTH_PATCH */
#ifdef USE_USL_WCWIDTH_PATCH
/*
** A small workaround for systems that don't have wcwidth...
*/
int
usl_wcwidth
(
const wchar_t wc
);
#endif /* USE_USL_WCWIDTH_PATCH */
/*
** Truncate the specified line to the desired width, return
**
** Inputs:
** tb - term buffer to act on
** row - row to truncate
**
** Returns:
** True/False to indicate success or failure
*/
extern Boolean
_DtTermPrimBufferClearLine
(
const TermBuffer tb,
const short row,
short newWidth
);
/*
** Create a new term buffer of the desired dimensions.
**
** Inputs:
** rows - desired number of rows
** cols - desired number of columns
** sizeOfBuffer - bytes per
** sizeOfLine - bytes per line record
** sizeOfEnh - bytes per enhancement chunk
**
** Returns:
** pointer to new TermBuffer, else NULL
*/
extern TermBuffer
_DtTermPrimBufferCreateBuffer
(
const Widget w,
const short rows,
const short cols,
const short sizeOfBuffer,
const short sizeOfLine,
const short sizeOfEnh
);
/*
** replace all characters between startCol, and endCol with spaces,
*/
void
_DtTermPrimBufferErase
(
TermBuffer tb,
short row,
short startCol,
short stopCol
);
/*
** replace all wide characters between startCol, and endCol with spaces,
*/
void
_DtTermPrimBufferEraseWc
(
TermBuffer tb,
short row,
short startCol,
short stopCol
);
/*
** Free all storage allocated to the specified buffer.
**
** Inputs:
** tb - TermBuffer to free
*/
extern void
_DtTermPrimBufferFreeBuffer
(
const TermBuffer tb
);
/*
** Change the dimensions of the specified buffer to the new size.
**
** Inputs:
** *tb - pointer to term buffer to resize
** *newRows - number of rows desired
** *newCols - number of cols desired
**
** Returns:
** potentially adjusted values for newRows and newCols
*/
extern void
_DtTermPrimBufferResizeBuffer
(
TermBuffer *tb,
short *newRows,
short *newCols
);
/*
** Create an enhancement chunk at the specified position.
**
** Inputs:
** tb - term buffer
** row,col - coordinates of new enhancement chunk
**
** Returns:
** True/False depending on success/failure
*/
extern Boolean
_DtTermPrimBufferCreateEnhancement
(
TermBuffer tb,
short row,
short col
);
/*
** Free the enhancement chunk at the specified position.
**
** Inputs:
** tb - term buffer
** row,col - coordinates of new enhancement chunk
**
** Returns:
** True/False depending on success/failure
*/
extern Boolean
_DtTermPrimBufferFreeEnhancement
(
const TermBuffer tb,
const short row,
const short col
);
/*
** Get text from the buffer.
**
** Inputs:
** tb - term buffer
** row,col - coordinates to get text from
** length - length of buffer
** needWideChar - true if need wide characters (not multi-byte chars)
**
** Outputs:
** buffer - pointer to buffer containing text
**
** Returns:
** the actual number of characters in the buffer
*/
extern short
_DtTermPrimBufferGetText
(
const TermBuffer tb,
const short row,
const short col,
const short length,
char *buffer,
const Boolean needWideChar
);
/*
** Return a pointer to the character at the specified position.
**
** Inputs:
** tb - term buffer
** row,col - coordinates of desired character
**
** Returns:
** pointer to desired character
*/
extern termChar *
_DtTermPrimBufferGetCharacterPointer
(
const TermBuffer tb,
const short row,
const short col
);
/*
** Insert 'numChar' characters into the buffer at the specified position.
**
**
*/
extern short
_DtTermPrimBufferInsert
(
const TermBuffer tb,
const short row,
const short col,
const termChar *newChars,
short numChars,
Boolean insertFlag, /* if TRUE, insert, else overwrite */
termChar **returnChars, /* pointer to overflow buffer */
short *returnCount /* count of characters in overflow buffer */
);
/*
** Delete enough characters from the buffer to exceed width.
**
** If returnChars != NULL then the deleted characters are returned
** in a buffer pointed to by returnChars. It is the responsibility
** of the calling function to XtFree the buffer containing returned
** characters when they are no longer needed.
*/
extern void
_DtTermPrimBufferDelete
(
TermBuffer tb,
short *row,
short *col,
short *count,
termChar **returnChars, /* pointer to delete buffer */
short *returnCount /* count of bytes in delete buffer */
);
extern void
_DtTermPrimBufferDeleteWc
(
TermBuffer tb,
short *row,
short *col,
short *count,
termChar **returnChars, /* pointer to delete buffer */
short *returnCount /* count of bytes in delete buffer */
);
extern Boolean
_DtTermPrimBufferSetLineWidth
(
const TermBuffer tb,
const short row,
short newWidth
);
extern short
_DtTermPrimBufferGetLineLength
(
const TermBuffer tb,
const short row
);
extern short
_DtTermPrimBufferGetLineWidth
(
const TermBuffer tb,
const short row
);
extern int
_DtTermPrimBufferSetEnhancement
(
const TermBuffer tb,
const short row,
const short col,
const unsigned char id,
const enhValue value
);
extern Boolean
_DtTermPrimBufferGetEnhancement
(
const TermBuffer tb,
const short row,
const short col,
enhValue **values,
short *count,
const countSpec countWhich
);
/*
** Return the number of rows allocated to the term buffer.
*/
extern short
_DtTermPrimBufferGetRows
(
const TermBuffer tb
);
/*
** Return the number of columns allocated to the term buffer.
*/
extern short
_DtTermPrimBufferGetCols
(
const TermBuffer tb
);
/*
** Set the value of the term buffer's nextBuffer and prevBuffer pointers.
*/
extern void
_DtTermPrimBufferSetLinks
(
const TermBuffer tb,
const TermBuffer prev,
const TermBuffer next
);
/*
** Set the value of the term buffer's selectInfo pointer.
*/
extern void
_DtTermPrimBufferSetSelectInfo
(
const TermBuffer tb,
const TermSelectInfo si
);
extern void
_DtTermPrimBufferMoveLockArea
(
const TermBuffer tb,
const short dest,
const short src,
const short length
);
typedef enum {
insertFromTop,
insertFromBottom
} InsertSource;
extern void
_DtTermPrimBufferInsertLine
(
const TermBuffer tb,
const short dest,
const short length,
const short src
);
extern void
_DtTermPrimBufferInsertLineFromTB
(
const TermBuffer tb,
const short dest,
const short length,
const InsertSource insertSource
);
extern void
_DtTermPrimBufferDeleteLine
(
const TermBuffer tb,
const short source,
const short length,
const short lastUsedRow
);
extern void
_DtTermPrimBufferPadLine
(
const TermBuffer tb,
const short row,
const short newWidth
);
extern void
_DtTermPrimBufferPadLineWc
(
const TermBuffer tb,
const short row,
const short newWidth
);
extern Boolean
_DtTermPrimGetCharacterInfo
(
TermBuffer tb,
short row,
short col,
TermCharInfo charInfo
);
extern short
_DtTermPrimBufferGetNextTab
(
const TermBuffer tb,
short col
);
extern short
_DtTermPrimBufferGetPreviousTab
(
const TermBuffer tb,
short col
);
extern Boolean
_DtTermPrimBufferSetTab
(
const TermBuffer tb,
const short col
);
extern Boolean
_DtTermPrimBufferClearTab
(
const TermBuffer tb,
const short col
);
extern Boolean
_DtTermPrimBufferClearAllTabs
(
const TermBuffer tb
);
/*
** Return the value of the line wrap flag for the current line
*/
extern Boolean
_DtTermPrimBufferTestLineWrapFlag
(
TermBuffer tb,
short row
);
/*
** set the line wrap flag to the desired state
*/
void
_DtTermPrimBufferSetLineWrapFlag
(
TermBuffer tb,
short row,
Boolean state
);
/*
** Return the value of the in selection flag for the current line
*/
extern TermLineSelection
_DtTermPrimBufferGetInSelectionFlag
(
TermBuffer tb,
short row
);
/*
** set the in selection flag to the desired state
*/
void
_DtTermPrimBufferSetInSelectionFlag
(
TermBuffer tb,
short row,
TermLineSelection state
);
#ifdef __cplusplus
} /* close scope of 'extern "C"'... */
#endif /* __cplusplus */
#endif /* _Dt_TermPrimBuffer_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,160 @@
/*
** $TOG: TermPrimBufferP.h /main/2 1997/04/17 18:05:11 samborn $
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimBufferP_h
#define _Dt_TermPrimBufferP_h
#include "TermPrimBuffer.h"
#include "TermPrimSelect.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define VALID_ROW(tb, r) (((r) >= 0) && ((r) < (tb)->term_buffer.rows))
#define VALID_COL(tb, c) (((c) >= 0) && ((c) < (tb)->term_buffer.cols))
#define VALID_LENGTH(tb, l) (((l) >= 0) && ((l) <= (tb)->term_buffer.cols))
/*
** Make it easier to access members of the Terminal Buffer
*/
#define LINES(tb) ((tb)->term_buffer.lines)
#define LINE_OF_TBUF(tb, row) (LINES(tb)[row])
#define ROWS(tb) ((tb)->term_buffer.rows)
#define COLS(tb) ((tb)->term_buffer.cols)
#define MAX_ROWS(tb) ((tb)->term_buffer.maxRows)
#define MAX_COLS(tb) ((tb)->term_buffer.maxCols)
#define TABS(tb) ((tb)->term_buffer.tabs)
#define NUM_ENH_FIELDS(tb) ((tb)->term_buffer.numFields)
#define SIZE_OF_BUFFER(tb) ((tb)->term_buffer.sizeOfBuffer)
#define SIZE_OF_LINE(tb) ((tb)->term_buffer.sizeOfLine)
#define SIZE_OF_ENH(tb) ((tb)->term_buffer.sizeOfEnh)
#define VALUE_LIST(tb) ((tb)->term_buffer.valueList)
#define WIDGET(tb) ((tb)->term_buffer.widget)
/*
** Make it easy to access the term buffer methods
*/
#define BUFFER_CREATE(tb) ((tb)->term_buffer.buffer_create_proc)
#define BUFFER_FREE(tb) ((tb)->term_buffer.buffer_free_proc)
#define BUFFER_RESIZE(tb) ((tb)->term_buffer.buffer_resize_proc)
#define ENH_PROC(tb) ((tb)->term_buffer.enh_proc)
#define CLEAR_ENH(tb) ((tb)->term_buffer.clear_enh)
#define INSERT_ENH(tb) ((tb)->term_buffer.insert_enh)
#define DELETE_ENH(tb) ((tb)->term_buffer.delete_enh)
#define SET_ENH(tb) ((tb)->term_buffer.set_enh)
#define GET_ENH(tb) ((tb)->term_buffer.get_enh)
#define SET_LINE_WIDTH(tb) ((tb)->term_buffer.set_line_width)
#define SET_LINE_LENGTH(tb)((tb)->term_buffer.set_line_len)
#define CLEAR_LINE(tb) ((tb)->term_buffer.clear_line)
#define NEXT_BUFFER(tb) ((tb)->term_buffer.nextBuffer)
#define PREV_BUFFER(tb) ((tb)->term_buffer.prevBuffer)
#define BUFFER_SELECT_INFO(tb) ((tb)->term_buffer.selectInfo)
#define WIDTH(l) ((l)->term_line.width)
#define LENGTH(l) ((l)->term_line.length)
#define BUFFER(l) ((l)->term_line.buffer)
#define WRAPPED(l) ((l)->term_line.wrapped)
#define IN_SELECTION(l) ((l)->term_line.inSelection)
#define IS_IN_SELECTION(l,s,e) \
(!(((l)->term_line.inSelection.selectionStart > e) || \
((l)->term_line.inSelection.selectionEnd < s)))
#define START_SELECTION(l) ((l)->term_line.inSelection.selectionStart)
#define END_SELECTION(l) ((l)->term_line.inSelection.selectionEnd)
#define MIN_SELECTION_COL (0)
#define MAX_SELECTION_COL (32700)
#define NON_SELECTION_COL (-1)
#define BYTES_PER_CHAR(tb) ((tb)->term_buffer.bytesPerChar)
/*
** declare the private enhancement information
*/
typedef struct _TermEnhPart
{
int foo; /* placate the compiler */
} TermEnhPart;
typedef struct _TermEnhRec
{
TermEnhPart term_enh;
} TermEnhRec, *TermEnh;
typedef struct _TermLineSelectionRec
{
short selectionStart;
short selectionEnd;
} TermLineSelectionRec;
/*
** Lines have a column length, and a character length, these two numbers are
** not always equal, since, in some locales (i.e. Japanese) the character
** glyphs can be two columns wide. We also want to know if this line wrapped
** to the following line.
*/
typedef struct _TermLinePart
{
short width; /* single width columns */
short length; /* in characters */
TermLineSelectionRec
inSelection;
Boolean wrapped; /* did this line wrap to the following line? */
termChar *buffer;
} TermLinePart;
typedef struct _TermLineRec
{
TermLinePart term_line;
} TermLineRec, *TermLine;
/*
** This structure defines the buffer instance part
*/
typedef struct _TermBufferPart
{
short rows; /* height (in chars) of character buffer */
short cols; /* width (in single width cols) of buffer */
short maxRows; /* maximum height (before any resize) */
short maxCols; /* maximum width (before any resize) */
short bytesPerChar; /* bytes per character */
Boolean *tabs; /* array of flags showing tab positions*/
unsigned char numFields; /* number of fields in an enhancement */
short sizeOfBuffer; /* bytes per buffer record */
short sizeOfLine; /* bytes per enhancement record */
short sizeOfEnh; /* bytes per line record */
enhValues valueList; /* local storage for enhancement values*/
TermLine *lines;
TermBuffer nextBuffer; /* next term buffer in list */
TermBuffer prevBuffer; /* previous term buffer in list */
TermSelectInfo selectInfo; /* current select info record */
BufferCreateProc buffer_create_proc;
BufferResizeProc buffer_resize_proc;
BufferFreeProc buffer_free_proc;
TermEnhProc enh_proc;
TermEnhClear clear_enh;
TermEnhInsert insert_enh;
TermEnhDelete delete_enh;
TermEnhSet set_enh;
TermEnhGet get_enh;
TermLineSetLen set_line_len;
TermLineSetWidth set_line_width;
TermLineClear clear_line;
Widget widget; /* the widget that created this buffer */
} TermBufferPart;
typedef struct _TermBufferRec
{
TermBufferPart term_buffer;
} TermBufferRec;
#ifdef __cplusplus
} /* close scope of 'extern "C"'... */
#endif /* __cplusplus */
#endif /* _Dt_TermPrimBufferP_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,615 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimCursor.c /main/1 1996/04/21 19:17:13 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#include "TermHeader.h"
#include "TermPrimDebug.h"
#include "TermPrimP.h"
#include "TermPrimData.h"
#include "TermPrimLineDraw.h"
#include "TermPrimBufferP.h"
static void cursorToggle(Widget w);
/*ARGSUSED*/
static void
timeoutCallback(XtPointer client_data, XtIntervalId *id)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) client_data;
struct termData *tpd = tw->term.tpd;
(void) cursorToggle((Widget) tw);
/* add a timeout... */
if (tw->term.blinkRate > 0) {
tpd->cursorTimeoutId =
XtAppAddTimeOut(XtWidgetToApplicationContext((Widget) tw),
tw->term.blinkRate,
(XtTimerCallbackProc) timeoutCallback, (XtPointer) tw);
} else {
tpd->cursorTimeoutId = (XtIntervalId) 0;
}
}
void
_DtTermPrimCursorChangeFocus(Widget w)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
XPoint point;
if (tw->term.hasFocus) {
/* if the input method already didn't have focus or the cursor
* position has changed, then set the input method focus and
* spot location...
*/
if ((!tpd->IMHasFocus) ||
(tpd->IMCursorColumn != tpd->cursorColumn) ||
(tpd->IMCursorRow != tpd->cursorRow)) {
tpd->IMHasFocus = True;
tpd->IMCursorColumn = tpd->cursorColumn;
tpd->IMCursorRow = tpd->cursorRow;
point.x = tpd->IMCursorColumn * tpd->cellWidth + tpd->offsetX;
point.y = tpd->IMCursorRow * tpd->cellHeight + tpd->offsetY +
tpd->ascent;
DebugF('F', 1, fprintf(stderr,
"%s() %s calling %s\n",
"_DtTermPrimCursorChangeFocus",
"hasFocus",
"XmImVaSetFocusValues()"));
(void) XmImVaSetFocusValues(w,
XmNspotLocation, &point,
NULL);
}
/* we want to blink now... */
if (tpd->cursorVisible && (!tpd->cursorTimeoutId) &&
(tw->term.blinkRate > 0) &&
(tpd->cursorState != CURSORoff)) {
Debug('F', fprintf(stderr,
">>we got focus, turning off cursor...\n"));
(void) cursorToggle(w);
/* add a timeout... */
Debug('F', fprintf(stderr, ">>adding a timeout...\n"));
tpd->cursorTimeoutId =
XtAppAddTimeOut(
XtWidgetToApplicationContext(w),
tw->term.blinkRate, timeoutCallback, (XtPointer) w);
}
} else {
if (tpd->IMHasFocus) {
tpd->IMHasFocus = False;
DebugF('F', 1, fprintf(stderr,
"%s() %s calling %s\n",
"_DtTermPrimCursorChangeFocus",
"!hasFocus",
"XmImUnsetFocus()"));
/* remove input method focus... */
(void) XmImUnsetFocus(w);
}
/* we want to stop blinking now... */
if (tpd->cursorTimeoutId && (tpd->cursorState != CURSORoff)) {
Debug('F', fprintf(stderr, ">>we lost focus...\n"));
if (CURSORon == tpd->cursorState) {
/* we need to make the cursor visible... */
Debug('F', fprintf(stderr,
">>turning on the cursor...\n"));
(void) cursorToggle(w);
}
/* we need to kill the timeout... */
Debug('F', fprintf(stderr, ">>removing the timeout...\n"));
(void) XtRemoveTimeOut(tpd->cursorTimeoutId);
tpd->cursorTimeoutId = (XtIntervalId) 0;
} else {
if (tw->term.blinkRate > 0) {
Debug('F', fprintf(stderr,
">>we lost focus, but cursor is not on and blinking...\n"));
}
}
}
}
static void
cursorToggle(Widget w)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
int y;
int height;
int cursorRow;
/* if the cursor is not visible or is off... */
if (!tpd->cursorVisible || (CURSORoff == tpd->cursorState)) {
/* do nothing... */
return;
}
cursorRow = tpd->cursorRow;
if (tpd->useHistoryBuffer) {
/* since topRow is used for history scrolling, move down by the
* (negative) number of rows in topRow...
*/
cursorRow -= tpd->topRow;
}
if (cursorRow < tw->term.rows) {
if (DtTERM_CHAR_CURSOR_BOX == tw->term.charCursorStyle) {
/* draw a box... */
y = cursorRow * tpd->cellHeight + tpd->offsetY;
height = tpd->cellHeight;
} else {
/* draw a line... */
y = cursorRow * tpd->cellHeight + tpd->offsetY +
tpd->ascent + 1;
height = 2;
}
(void) XFillRectangle(XtDisplay(w),
/* Display */
XtWindow(w), /* Window */
tpd->cursorGC.gc, /* GC */
((tpd->cursorColumn >= tw->term.columns) ?
tw->term.columns - 1 :
tpd->cursorColumn) * tpd->cellWidth + tpd->offsetX,
/* x */
y, /* y */
tpd->cellWidth, /* width */
height); /* height */
}
/* toggle the state flag... */
tpd->cursorState = (tpd->cursorState == CURSORon) ? CURSORblink : CURSORon;
return;
}
void
_DtTermPrimCursorOn(Widget w)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
XPoint point;
static Boolean alreadyActive = False;
short chunkWidth;
enhValues enhancements;
unsigned long valueMask = 0L;
XGCValues values;
TermEnhInfoRec enhInfo;
int cursorRow;
/* if we are being called cyclically (by _DtTermPrimScrollWait ->
* _DtTermPrimExposeText -> _DtTermPrimCursorOn), just return...
*/
_DtTermProcessLock();
if (alreadyActive) {
/*DKS!!! vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */
fprintf(stderr, "tell Dave _DtTermPrimCursorOn has alreadyActive == True\n");
/*DKS!!! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
_DtTermProcessUnlock();
return;
}
/* this is where we will actually perform a pending scroll and
* text refresh...
*/
if (tw->term.jumpScroll && tpd->scroll.jump.scrolled) {
/* make sure we don't end up in an infinite loop... */
alreadyActive = True;
Debug('t', fprintf(stderr,
">>_DtTermPrimCursorOn() calling _DtTermPrimScrollWait()\n"));
(void) _DtTermPrimScrollWait(w);
alreadyActive = False;
}
_DtTermProcessUnlock();
#ifdef DISOWN_SELECTION_ON_CURSOR_ON_OR_OFF
if ( _DtTermPrimSelectIsAboveSelection(w,tpd->cursorRow,
tpd->cursorColumn)) {
_DtTermPrimSelectDisown(w) ;
}
#endif /* DISOWN_SELECTION_ON_CURSOR_ON_OR_OFF */
/* update the input method spot location...
*/
if ((tpd->IMCursorColumn != tpd->cursorColumn) ||
(tpd->IMCursorRow != tpd->cursorRow)) {
tpd->IMCursorColumn = tpd->cursorColumn;
tpd->IMCursorRow = tpd->cursorRow;
point.x = tpd->cursorColumn * tpd->cellWidth + tpd->offsetX;
point.y = tpd->cursorRow * tpd->cellHeight + tpd->offsetY + tpd->ascent;
DebugF('F', 1, fprintf(stderr,
"%s() %s calling %s\n",
"_DtTermPrimCursorOn",
"dont care",
"XmImVaSetValues()"));
(void) XmImVaSetValues(w,
XmNspotLocation, &point,
NULL);
}
#ifdef NOT_NEEDED
if (!tw->term.hasFocus) {
(void) fprintf(stderr,
"%s() %s calling %s\n",
"_DtTermPrimCursorOn",
"!hasFocus",
"XmImUnsetFocus()");
(void) XmImUnsetFocus(w);
}
#endif /* NOT_NEEDED */
/* update the scrollbar and position indicator... */
(void) _DtTermPrimCursorUpdate(w);
/* if the cursor is not visible, we are done now... */
if (!tpd->cursorVisible) {
return;
}
/* set up the GC... */
if (!tpd->cursorGC.gc) {
tpd->cursorGC.foreground =
tw->primitive.foreground ^ tw->core.background_pixel;
values.foreground = tpd->cursorGC.foreground;
values.function = GXxor;
tpd->cursorGC.gc = XCreateGC(XtDisplay(w), XtWindow(w),
GCForeground | GCFunction, &values);
}
/* update the cursor's foreground and background...
*/
/* if we are past the lastUsedRow, or the column > width, use color
* pair 0...
*/
/* reasonable defaults... */
enhInfo.fg = tw->primitive.foreground;
enhInfo.bg = tw->core.background_pixel;
if (!((tpd->lastUsedRow <= tpd->topRow + tpd->cursorRow) ||
(_DtTermPrimBufferGetLineWidth(tpd->termBuffer,
tpd->topRow + tpd->cursorRow) <= MIN(tpd->cursorColumn,
tw->term.columns - 1)))) {
/* get the current enhancement to determine the color pair to use...
*/
(void) _DtTermPrimBufferGetEnhancement(tpd->termBuffer,
/* TermBuffer */
tpd->topRow + tpd->cursorRow,
/* row */
MIN(tpd->cursorColumn, tw->term.columns - 1),
/* col */
&enhancements, /* enhancements */
&chunkWidth, /* width */
countNew); /* countWhich */
/* set our font and color from the enhancements... */
if (ENH_PROC(tpd->termBuffer)) {
(void) (*(ENH_PROC(tpd->termBuffer)))(w, enhancements, &enhInfo);
}
}
/* set the GC... */
if (tpd->cursorGC.foreground != enhInfo.fg ^ enhInfo.bg) {
tpd->cursorGC.foreground = enhInfo.fg ^ enhInfo.bg;
values.foreground = enhInfo.fg ^ enhInfo.bg;
valueMask |= GCForeground;
}
if (valueMask) {
(void) XChangeGC(XtDisplay(w), tpd->cursorGC.gc, valueMask, &values);
}
if (tpd->cursorState != CURSORoff) {
return;
}
tpd->cursorState = CURSORon;
(void) cursorToggle(w);
if (tw->term.hasFocus) {
/* add a timeout... */
if (tw->term.blinkRate > 0) {
tpd->cursorTimeoutId =
XtAppAddTimeOut(XtWidgetToApplicationContext(w),
tw->term.blinkRate, (XtTimerCallbackProc) timeoutCallback,
(XtPointer) w);
}
}
}
void
_DtTermPrimCursorUpdate(Widget w)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
Arg arglist[10];
int i;
short value;
Boolean newMaximum = False;
Boolean newValue = False;
/* update the scrollbar... */
if (tw->term.verticalScrollBar) {
i = 0;
if (tpd->useHistoryBuffer) {
#define NO_SCROLL_REGION_HISTORY_SCROLL
#ifdef NO_SCROLL_REGION_HISTORY_SCROLL
value = tw->term.rows;
if ((tpd->scrollLockTopRow <= 0) &&
(tpd->scrollLockBottomRow >= (tw->term.rows - 1))) {
value += tpd->lastUsedHistoryRow;
}
#else /* NO_SCROLL_REGION_HISTORY_SCROLL */
value = tw->term.rows + tpd->lastUsedHistoryRow;
#endif /* NO_SCROLL_REGION_HISTORY_SCROLL */
} else {
value = tpd->lastUsedRow +
(tpd->useHistoryBuffer ? tpd->lastUsedHistoryRow : 0) -
tpd->scrollLockTopRow -
(tw->term.rows - 1 - tpd->scrollLockBottomRow);
/* add in any non-exisstent rows below the last used row...
*/
if (tpd->allowScrollBelowBuffer) {
/* add in a full screen (less one line and protected areas)
* below the last used row...
*/
value += tw->term.rows - 1 -
tpd->scrollLockTopRow -
(tw->term.rows - 1 - tpd->scrollLockBottomRow);
}
}
if (tw->term.verticalScrollBarMaximum != value) {
/* need to set maximum ... */
tw->term.verticalScrollBarMaximum = value;
newMaximum = True;
}
if (tpd->useHistoryBuffer) {
value = tw->term.rows;
} else {
value = tw->term.rows -
tpd->scrollLockTopRow -
(tw->term.rows - 1 - tpd->scrollLockBottomRow);
}
if (tw->term.verticalScrollBarSliderSize != value) {
/* need to set sliderSize ... */
tw->term.verticalScrollBarSliderSize = value;
(void) XtSetArg(arglist[i], XmNsliderSize,
tw->term.verticalScrollBarSliderSize); i++;
newValue = True;
}
/* verticalScrollBarPageIncrement = verticalScrollBarSliderSize... */
if (tw->term.verticalScrollBarPageIncrement != value) {
/* need to set pageIncrement ... */
tw->term.verticalScrollBarPageIncrement = value;
(void) XtSetArg(arglist[i], XmNpageIncrement,
tw->term.verticalScrollBarPageIncrement); i++;
newValue = True;
}
#ifdef NO_SCROLL_REGION_HISTORY_SCROLL
value = tpd->topRow;
if (tpd->useHistoryBuffer && (tpd->scrollLockTopRow <= 0) &&
(tpd->scrollLockBottomRow >= (tw->term.rows - 1))) {
value += tpd->lastUsedHistoryRow;
}
#else /* NO_SCROLL_REGION_HISTORY_SCROLL */
value = tpd->topRow + tpd->lastUsedHistoryRow;
#endif /* NO_SCROLL_REGION_HISTORY_SCROLL */
if (tw->term.verticalScrollBarValue != value) {
/* need to set value... */
tw->term.verticalScrollBarValue = value;
(void) XtSetArg(arglist[i], XmNvalue,
tw->term.verticalScrollBarValue); i++;
newValue = True;
}
/* check and see if value > max - size. If it is, adjust
* maximum...
*/
if (tw->term.verticalScrollBarValue >
tw->term.verticalScrollBarMaximum -
tw->term.verticalScrollBarSliderSize) {
tw->term.verticalScrollBarMaximum =
tw->term.verticalScrollBarValue +
tw->term.verticalScrollBarSliderSize;
newMaximum = True;
}
Debug('b', if (newMaximum || newValue) {
fprintf(stderr, ">>_DtTermPrimCursorUpdate: sb size=%d min=%d max=%d value=%d pginc=%d\n",
tw->term.verticalScrollBarSliderSize,
0,
tw->term.verticalScrollBarMaximum,
tw->term.verticalScrollBarValue,
tw->term.verticalScrollBarPageIncrement);
});
if (newMaximum) {
(void) XtSetArg(arglist[i], XmNmaximum,
tw->term.verticalScrollBarMaximum); i++;
(void) XtSetValues(tw->term.verticalScrollBar, arglist, i);
} else if (newValue) {
/* only need to worry about setting value, slidersize, and
* page increment...
*/
(void) XmScrollBarSetValues(tw->term.verticalScrollBar,
tw->term.verticalScrollBarValue,
/* value */
tw->term.verticalScrollBarSliderSize,
/* slider_size */
1, /* increment */
tw->term.verticalScrollBarPageIncrement,
/* page_increment */
False); /* notify */
}
}
/* invoke any cursor motion callbacks... */
if (tw->term.statusChangeCallback) {
_DtTermPrimInvokeStatusChangeCallback(w);
}
}
void
_DtTermPrimCursorOff(Widget w)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
if (CURSORoff == tpd->cursorState) {
return;
}
if (CURSORblink == tpd->cursorState) {
/* we need to restore the text... */
(void) cursorToggle(w);
}
/* reset the state flag... */
tpd->cursorState = CURSORoff;
/* turn off the timer... */
if (tpd->cursorTimeoutId) {
XtRemoveTimeOut(tpd->cursorTimeoutId);
}
tpd->cursorTimeoutId = (XtIntervalId) 0;
#ifdef DISOWN_SELECTION_ON_CURSOR_ON_OR_OFF
if ( _DtTermPrimSelectIsAboveSelection(w,tpd->cursorRow,
tpd->cursorColumn)) {
_DtTermPrimSelectDisown(w) ;
}
#endif /* DISOWN_SELECTION_ON_CURSOR_ON_OR_OFF */
}
/*
** _DtTermPrimCursorMove
**
** Move the cursor to the specified location, scrolling the screen
** as necessary.
**
** NOTES:
** If the new cursor position is exceeds the line width, the line
** is padded with spaces up to (but not including) the new cursor
** position (just adjust the line width since the line is already
** filled with spaces).
** if (cursorColumn == width)
** then the cursor is at the end of the line
**
** if (cursorColumn > width)
** then the cursor is past the end of the line,
** pad the line by setting width = cursorColumn
*/
void
_DtTermPrimCursorMove
(
Widget w,
int row,
int col
)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
/*
** Constrain col to buffer width.
*/
if (col < 0)
{
col = 0;
}
else if (col >= COLS(tpd->termBuffer))
{
col = COLS(tpd->termBuffer) - 1;
}
tpd->cursorColumn = col;
/*
** Constraint row to >= 0. Height is open ended...
*/
if (row < 0)
{
row = 0;
}
/*
** Scroll the window as necessary.
*/
if (row < tpd->topRow) {
/* scroll so that row is the topRow... */
_DtTermPrimScrollTextTo(w, row);
tpd->cursorRow = 0;
} else if (row >= tpd->topRow + tw->term.rows) {
/* scroll so that row is the bottomRow... */
_DtTermPrimScrollTextTo(w, row - tw->term.rows + 1);
tpd->cursorRow = tw->term.rows - 1;
} else {
/* we just need to move the cursor... */
tpd->cursorRow = row - tpd->topRow;
}
#ifdef NOCODE
/*
** Make sure the line is padded properly.
**
** NOTE: we no longer do this, it might be necessary for hpterm3.0
** but I will double check then
*/
_DtTermPrimRenderPadLine(w);
#endif /* NOCODE */
}
void
_DtTermPrimSetCursorVisible
(
Widget w,
Boolean visible
)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
/* make sure the cursor is off... */
_DtTermPrimCursorOff(w);
if (visible) {
/* turn it on...
*/
tpd->cursorVisible = True;
} else {
/* turn it off...
*/
tpd->cursorVisible = False;
}
}
Boolean
_DtTermPrimGetCursorVisible
(
Widget w
)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
return(tpd->cursorVisible);
}

View File

@@ -0,0 +1,23 @@
/*
* $XConsortium: TermPrimCursor.h /main/1 1996/04/21 19:17:16 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimCursor_h
#define _Dt_TermPrimCursor_h
extern void _DtTermPrimCursorOff(Widget w);
extern void _DtTermPrimCursorOn(Widget w);
extern void _DtTermPrimCursorChangeFocus(Widget w);
extern void _DtTermPrimCursorMove(Widget w, int row, int col);
extern void _DtTermPrimCursorUpdate(Widget w);
extern void _DtTermPrimSetCursorVisible(Widget w, Boolean visible);
extern Boolean _DtTermPrimGetCursorVisible(Widget w);
#endif /* _Dt_TermPrimCursor_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,340 @@
/*
* $XConsortium: TermPrimData.h /main/2 1996/10/30 13:00:24 cde-hp $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
* (c) Copyright 1995 Digital Equipment Corporation *
*/
#ifndef _Dt_TermPrimData_h
#define _Dt_TermPrimData_h
#include "TermHeader.h"
#include "TermPrimBuffer.h"
#include "TermPrimParser.h"
#include "TermPrimPendingText.h"
#include "TermPrimRender.h"
#include "TermPrimSelect.h"
#include "TermPrimLineFont.h"
#include <stdio.h>
#include <limits.h>
#define NUM_FONTS 4
#define KEYBOARD_LOCKED(kbdLocked) ((kbdLocked).escape || \
(kbdLocked).xferPending || \
(kbdLocked).error || \
(kbdLocked).record)
typedef struct {
Font fid;
Pixel foreground;
Pixel background;
GC gc;
} TermGC;
/*
** There are 4 reasons that the keyboard could be locked...
*/
typedef struct _TermKbdLockStatus
{
Boolean escape; /* escape sequence (or auto lock) */
Boolean xferPending; /* a transfer is pending */
Boolean error; /* an error message is being displayed */
Boolean record; /* we're in record mode */
} TermKbdLockStatus;
typedef struct _OnTheSpotData {
short row;
short column;
short start;
short end;
short pre_len;
short cursor;
Boolean under_preedit;
} OnTheSpotDataRec, *OnTheSpotData;
#define PreRow(w) ((w)->term.tpd->onthespot->row)
#define PreColumn(w) ((w)->term.tpd->onthespot->column)
#define PreStart(w) ((w)->term.tpd->onthespot->start)
#define PreEnd(w) ((w)->term.tpd->onthespot->end)
#define PreLen(w) ((w)->term.tpd->onthespot->pre_len)
#define PreCursor(w) ((w)->term.tpd->onthespot->cursor)
#define PreUnder(w) ((w)->term.tpd->onthespot->under_preedit)
typedef struct termData {
/*********************************************************************
* Pty
*/
XtInputId ptyOutputId; /* pty master Xt output id */
XtInputId ptyInputId; /* pty master Xt input id */
/*********************************************************************
* Font
*/
TermFont termFont; /* passed in base term font */
TermFont boldTermFont; /* passed in bold term font */
TermFont defaultTermFont; /* default base term font */
TermFont defaultBoldTermFont; /* default bold term font */
#ifdef DKS
unsigned char renderTermFontsNum; /* number of above fonts */
unsigned char baseFontIndex; /* number of base font */
unsigned char altFontIndex; /* number of alternate font */
#endif /* DKS */
short cellWidth; /* width of base font */
short cellHeight; /* height of base font */
short ascent; /* ascent of base font */
/*********************************************************************
* Buffer
*/
TermBuffer termBuffer; /* character/enhancment buffer */
short bufferRows; /* rows of term buffer memory */
short bufferRowRatio; /* scaled ratio of term buffer
* memory to term window
*/
TermBuffer historyBuffer; /* history character buffer */
short historyBufferRows; /* rows of term history buffer */
short leftMargin; /* left margin */
short rightMargin; /* right margin */
/*
**
*/
short topRow; /* number of top row on screen */
short cursorColumn; /* current cursor position, col */
short cursorRow; /* current cursor position, row */
short lastUsedRow; /* number of last used buffer row.
* if == 0, no rows used, if == 1,
* 1 row used, etc.
*/
short lastUsedHistoryRow;
short offsetX; /* width of internal window
* border. With Motif, this is
* the width of the
* highlightThickness and
* shadowThickness.
*/
short offsetY; /* height of internal window
* border (see above)
*/
/*
** Generic mode information...
*/
Boolean transmitFunctions; /* if true, transmit functions (A) */
Boolean autoWrapRight; /* if true, wrap at right margin (C) */
Boolean wrapRightAfterInsert; /* if true, wrap after insert */
enum {
WRAPbetweenMargins = 0,
WRAPatRightMargin,
WRAPpastRightMargin
} wrapState; /* margin wrap state */
/*
** Memory lock status...
*/
enum {
SCROLL_LOCKoff = 0,
SCROLL_LOCKon,
SCROLL_LOCKprotect
} scrollLockMode; /* memory lock mode */
short scrollLockTopRow; /* bottom of top scroll lock region */
short scrollLockBottomRow; /* top of bottom scroll lock region */
/* for mapOnOutput */
time_t creationTime ;
Boolean windowMapped;
/* pointer blanking */
Boolean pointerFirst; /* for initialization */
Boolean pointerOn; /* Is pointer on? */
XtIntervalId pointerTimeoutID; /* ID of current timeout */
Boolean pointerFrozen; /* Is pointer outside window? */
Cursor noPointer; /* blank pointer pixmap */
/* logging */
FILE *logStream; /* file pointer for logging */
uid_t uid; /* user id of user */
gid_t gid; /* group id of user */
char *shell; /* users shell */
/* these will go away when the associated files are updated...
*/
#define memoryLockRow scrollLockTopRow
#define memoryLockMode scrollLockMode
#define MEMORY_LOCKoff SCROLL_LOCKoff
#define MEMORY_LOCKon SCROLL_LOCKon
#define MEMORY_LOCKprotect SCROLL_LOCKprotect
/*********************************************************************
* Parser
*/
ParserContext context; /* context of the parser */
Boolean parserNotInStartState;
int mbCurMax; /* max bytes per char for locale*/
unsigned char mbPartialChar[MB_LEN_MAX];
/* partial multi-byte char */
int mbPartialCharLen; /* length of above */
/*********************************************************************
* Render GCs
*/
TermGC renderGC; /* GC for rendering text */
TermGC renderReverseGC; /* GC for rendering text */
TermGC clearGC; /* GC for clearing text */
/*********************************************************************
* Cursor
*/
XtIntervalId cursorTimeoutId; /* cursor timeout id */
TermGC cursorGC; /* GC for blinking cursor */
enum {
CURSORon,
CURSORoff,
CURSORblink
} cursorState; /* state of cursor */
Boolean cursorVisible; /* true if cursor is visible */
/*********************************************************************
* Input Method
*/
Boolean IMHasFocus; /* true if IM has focus */
/* The following are in character positions, not pixel positions...
*/
short IMCursorColumn; /* current IM cursor column */
short IMCursorRow; /* current IM cursor row */
/*********************************************************************
* Scroll
*/
/* the following data reflects the copy area in progress to be used
* for filling in possible holes in exposure events...
*/
short scrollSrcX; /* x src coord of scrolled area */
short scrollSrcY; /* y src coord of scrolled area */
short scrollDestX; /* x dest coord of scrolled area*/
short scrollDestY; /* y dest coord of scrolled area*/
short scrollWidth; /* width of scrolled area */
short scrollHeight; /* height of scrolled area */
short scrollTopRow; /* row of scroll top */
short scrollBottomRow; /* row of scroll bottom */
Boolean *scrollRefreshRows; /* flags for rows that need to
* be refreshed after a scroll
*/
Boolean useHistoryBuffer; /* true if separate history buf */
Boolean allowScrollBelowBuffer; /* true allows scrolling below
* the terminal buffer
*/
/* the following is for data for both any current scroll-in-progress
* as well as any pending (queued) scroll...
*/
Boolean scrollInProgress; /* true if scroll in progresss */
union {
struct {
short scrollLines; /* number of lines to scroll */
short scrollsPending; /* number of scrolls pending */
Boolean scrolled; /* true when scrolled, cleared
* when updated
*/
} jump;
struct {
short pendingScrollLines; /* number of lines in pending */
short pendingScrollTopRow; /* top row of pending scroll */
short pendingScrollBottomRow;
/* bottom row of pending scroll */
Boolean pendingScroll; /* True if scroll queued up */
} nojump;
} scroll;
/* the following is for stuffing input data when we have turned off
* input processing during a scroll...
*/
PendingText pendingRead; /* pending read data */
Boolean readInProgress; /* True if now reading from pty */
/*
** Set up a linked list of text chunks, data stored here is waiting
** to be written.
*/
PendingText pendingWrite; /* pending write data */
/*
** Keyboard state information...
*/
TermKbdLockStatus keyboardLocked; /* if true, keyboard is locked */
DtTermInsertCharMode insertCharMode; /* insert char mode */
Boolean autoLineFeed; /* if true, in auto LF mode */
Boolean halfDuplex; /* if true, half duplex */
/*********************************************************************
* Caps lock tracking
*/
Boolean capsLock; /* true == caps lock set */
KeyCode *capsLockKeyCodes; /* keyboard's modifier keymap */
short numCapsLockKeyCodes; /* number of caps lock modifiers*/
/*********************************************************************
* kshmode tracking
*/
unsigned int metaMask; /* mod mask used for meta */
/*********************************************************************
* STOP indicator tracking
*/
Boolean outputStopped; /* true == out from pty stopped */
Boolean oneSecondPause; /* true == esc @ pause */
/*********************************************************************
* Warning/error dialog
*/
Widget warningDialog; /* warning dialog */
Boolean mapWarningDialog; /* map dialog when window mapped*/
Boolean warningDialogMapped; /* true if dialog is mapped */
enum {
userMessage,
memoryFull
} warningDialogType;
/*********************************************************************
* /etc/utmp stuff
*/
char *utmpId; /* id of /etc/utmp entry */
#ifdef UTMPID_PROPERTY_NOTIFY
enum {
utmpIdInvalid = 0,
utmpIdValidNotClear,
utmpIdValid,
utmpIdError
} utmpIdState;
#endif /* UTMPID_PROPERTY_NOTIFY */
#ifdef UTMPID_PIPE_NOTIFY
int utmpNotifyPipe[2];
XtInputId utmpNotifyPipeInputId;
XtInputId utmpNotifyPipeExceptId;
#endif /* UTMPID_PIPE_NOTIFY */
/*
** Selections...
*/
TermSelectInfo selectInfo;
/*
** On the spot input method data
*/
OnTheSpotData onthespot;
} DtTermPrimDataRec, *DtTermPrimData;
#endif /* _Dt_TermPrimData_h */

View File

@@ -0,0 +1,476 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimDebug.c /main/4 1996/11/21 19:58:15 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <varargs.h>
#include "TermHeader.h"
#include "TermPrimDebug.h"
#include <signal.h>
#define X_INCLUDE_STRING_H
#define XOS_USE_NO_LOCKING
#include <X11/Xos_r.h>
unsigned char *debugLevel[256] = { NULL }; /* debug level */
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
int
isDebugFSet(int c, int f)
{
int i;
_DtTermProcessLock();
i = ((f < _TERM_MAX_DEBUG_FLAG) ?
debugLevel[c % 256] &&
(debugLevel[c % 256][__TERM_DEBUG_BYTE(f)] & __TERM_DEBUG_BIT(f)) :
0);
_DtTermProcessUnlock();
return(i);
}
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
static
void
catchExit(void)
{
int a;
int b;
a = 1;
b = a;
a = b;
return;
}
typedef struct _argArray {
char *str;
struct _argArray *next;
} argArray;
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
void
setDebugFlags(char *c1)
{
argArray argHead;
argArray *argPtr;
int i1;
int i2;
char *c2;
char *c3;
char *charList;
char *flagList;
char charArray[BUFSIZ];
unsigned char theseFlags[_TERM_DEBUG_NUM_BYTES];
char startChar;
char endChar;
int startFlag;
int endFlag;
Boolean isValid;
static Boolean catchExitRegistered = False;
_Xstrtokparams strtok_buf;
/* ignore null or empty strings... */
if (!c1 || !*c1) {
return;
}
/* register our catchExit() function... */
_DtTermProcessLock();
if (!catchExitRegistered) {
(void) atexit(catchExit);
catchExitRegistered = True;
}
/* strtok out c1...
*/
/* don't destroy the original string... */
c2 = malloc(strlen(c1) + 1);
(void) strcpy(c2, c1);
argHead.next = (argArray *) 0;
argPtr = &argHead;
while (c3 = _XStrtok(c2, " \t\n", strtok_buf)) {
/* null out c2 so we won't restart strtok... */
c2 = (char *) 0;
argPtr->next = (argArray *) malloc(sizeof(argArray));
argPtr = argPtr->next;
argPtr->next = (argArray *) 0;
argPtr->str = c3;
}
/* run through the linked list and parse each string... */
for (argPtr = argHead.next; argPtr; argPtr = argPtr->next) {
charList = argPtr->str;
flagList = (char *) 0;
if (c2 = strchr(argPtr->str, ':')) {
/* null out the ':'... */
*c2++ = '\0';
flagList = c2;
}
/* fill out the char array... */
for (c2 = charArray; *charList; ) {
isValid = False;
if (isalpha(*charList)) {
isValid = True;
startChar = *charList++;
} else {
startChar = 'A';
}
if (*charList == '-') {
isValid = True;
(void) charList++;
if (isalpha(*charList)) {
endChar = *charList++;
} else {
endChar = 'z';
}
} else {
endChar = startChar;
}
if (isValid) {
while (startChar <= endChar) {
*c2++ = startChar++;
}
/* null term... */
*c2 = '\0';
} else {
break;
}
}
/* fill out theseFlags... */
(void) memset(theseFlags, '\0', sizeof(theseFlags));
if (!flagList || !*flagList) {
flagList = strdup("-");
}
c3 = flagList;
while (flagList = _XStrtok(c3, ",", strtok_buf)) {
/* null out c3 so we won't restart strtok... */
c3 = (char *) 0;
if (!flagList || !*flagList) {
continue;
}
if (isdigit(*flagList)) {
startFlag = strtol(flagList, &flagList, 0);
} else {
startFlag = 0;
}
endFlag = startFlag;
if (*flagList == '-') {
/* we have a range... */
/* skip over the '-'... */
(void) flagList++;
if (isdigit(*flagList)) {
endFlag = strtol(flagList, (char **) 0, 0);
} else {
endFlag = _TERM_MAX_DEBUG_FLAG - 1;
}
}
if (startFlag < 0) {
startFlag = 0;
}
if (endFlag > (_TERM_MAX_DEBUG_FLAG - 1)) {
endFlag = _TERM_MAX_DEBUG_FLAG - 1;
}
for (; startFlag <= endFlag; startFlag++) {
theseFlags[__TERM_DEBUG_BYTE(startFlag)] |=
__TERM_DEBUG_BIT(startFlag);
}
}
/* now run through the the char array and or in these flags... */
for (c2 = charArray; *c2; c2++) {
if (isalpha(*c2)) {
if (!debugLevel[*c2]) {
debugLevel[*c2] =
(unsigned char *) malloc(_TERM_DEBUG_NUM_BYTES);
(void) memset(debugLevel[*c2], '\0', _TERM_DEBUG_NUM_BYTES);
}
for (i1 = 0; i1 < _TERM_DEBUG_NUM_BYTES; i1++) {
debugLevel[*c2][i1] |= theseFlags[i1];
}
}
}
}
/* dump out a list of set flags... */
if (isDebugFSet('v', 0)) {
for (i1 = 0; i1 < 256; i1++) {
if (debugLevel[i1]) {
(void) fprintf(stderr, "debug flag '%c' ", i1);
for (i2 = 0; i2 < _TERM_MAX_DEBUG_FLAG; i2++) {
if (i2 > 0 && (0 == i2 % 50)) {
(void) fputs("\n ", stderr);
}
if (debugLevel[i1][__TERM_DEBUG_BYTE(i2)] &
__TERM_DEBUG_BIT(i2)) {
(void) putc('X', stderr);
} else {
(void) putc('.', stderr);
}
}
(void) putc('\n', stderr);
}
}
}
_DtTermProcessUnlock();
}
static Boolean timedOut;
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
/*ARGSUSED*/
static void
ding(int sig)
{
timedOut = True;
}
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
void
shortSleep(int msec)
{
struct sigaction action;
struct sigaction oldAction;
sigset_t sigset;
sigset_t oldSigset;
struct itimerval itime;
struct itimerval oldItime;
_DtTermProcessLock();
timedOut = False;
/* block SIGALRM... */
(void) sigemptyset(&sigset);
(void) sigaddset(&sigset, SIGALRM);
(void) sigprocmask(SIG_BLOCK, &sigset, &oldSigset);
/* set up a singnal handler for SIGALRM... */
action.sa_handler = ding;
action.sa_flags = 0;
(void) sigemptyset(&action.sa_mask);
(void) sigaction(SIGALRM, &action, &oldAction);
/* set an alarm... */
timerclear(&itime.it_interval);
itime.it_value.tv_usec = msec % 1000000;
itime.it_value.tv_sec = msec / 1000000;
(void) setitimer(ITIMER_REAL, &itime, &oldItime);
/* unblock SIGALRM and wait for a signal... */
(void) sigprocmask(SIG_BLOCK, (sigset_t *) 0, &sigset);
(void) sigdelset(&sigset, SIGALRM);
while (!timedOut) {
sigsuspend(&sigset);
}
/* restore old handler... */
(void) sigaction(SIGALRM, &oldAction, (struct sigaction *) 0);
/* restore old signal mask... */
(void) sigprocmask(SIG_SETMASK, &oldSigset, (sigset_t *) 0);
_DtTermProcessUnlock();
}
static FILE *timeStampFile = (FILE *) 0;
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
void
timeStamp(char *msg)
{
struct timeval tv;
struct timezone tz;
_DtTermProcessLock();
if (!timeStampFile) {
char *c;
char buffer[BUFSIZ];
if (!(c = getenv("timeStampFileName"))) {
(void) sprintf(buffer, "timeStamp-%d", getpid());
c = buffer;
}
if (!(timeStampFile = fopen(c, "a"))) {
_DtTermProcessUnlock();
return;
}
(void) setvbuf(timeStampFile, (char *) 0, _IOLBF, 0);
}
_DtTermProcessUnlock();
(void) gettimeofday(&tv, &tz);
(void) fprintf(timeStampFile, "%lu %ld %s\n", tv.tv_sec, tv.tv_usec,
(msg && *msg) ? msg : "");
}
typedef struct {
char *string;
int value;
} enumName;
static enumName eventTypes[] = {
{"KeyPress", 2},
{"KeyRelease", 3},
{"ButtonPress", 4},
{"ButtonRelease", 5},
{"MotionNotify", 6},
{"EnterNotify", 7},
{"LeaveNotify", 8},
{"FocusIn", 9},
{"FocusOut", 10},
{"KeymapNotify", 11},
{"Expose", 12},
{"GraphicsExpose", 13},
{"NoExpose", 14},
{"VisibilityNotify", 15},
{"CreateNotify", 16},
{"DestroyNotify", 17},
{"UnmapNotify", 18},
{"MapNotify", 19},
{"MapRequest", 20},
{"ReparentNotify", 21},
{"ConfigureNotify", 22},
{"ConfigureRequest", 23},
{"GravityNotify", 24},
{"ResizeRequest", 25},
{"CirculateNotify", 26},
{"CirculateRequest", 27},
{"PropertyNotify", 28},
{"SelectionClear", 29},
{"SelectionRequest", 30},
{"SelectionNotify", 31},
{"ColormapNotify", 32},
{"ClientMessage", 33},
{"MappingNotify", 34},
{"LASTEvent", 35},
{NULL},
};
static enumName notifyModes[] = {
{"NotifyNormal", 0},
{"NotifyGrab", 1},
{"NotifyUngrab", 2},
{"NotifyWhileGrabbed", 3},
{NULL},
};
static enumName notifyDetails[] = {
{"NotifyAncestor", 0},
{"NotifyVirtual", 1},
{"NotifyInferior", 2},
{"NotifyNonlinear", 3},
{"NotifyNonlinearVirtual", 4},
{"NotifyPointer", 5},
{"NotifyPointerRoot", 6},
{"NotifyDetailNone", 7},
{NULL},
};
static enumName boolTypes[] = {
{"True", 1},
{"False", 0},
{NULL},
};
static char *
enumToName
(
enumName *list,
int value
)
{
int i1;
char buffer[BUFSIZ];
static char *retBuffer = (char *) 0;
for (i1 = 0; list[i1].string; i1++) {
if (list[i1].value == value) {
return(list[i1].string);
}
}
(void) sprintf(buffer, "Unknown Value %d", value);
retBuffer = realloc(retBuffer, strlen(buffer));
(void) strcpy(retBuffer, buffer);
return(retBuffer);
}
void
_DtTermPrimDebugDumpEvent
(
FILE *f,
Widget w,
XEvent *ev
)
{
_DtTermProcessLock();
(void) fprintf(f, ">> widget: name=\"%s\" widget=0x%lx window=0x%lx\n",
XtName(w), w, XtWindow(w));
(void) fprintf(f, ">> event {\n");
(void) fprintf(f, ">> type=%s;\n",
enumToName(eventTypes, ev->xany.type));
(void) fprintf(f, ">> serial=%lu\n", ev->xany.serial);
(void) fprintf(f, ">> send_event=%s\n",
enumToName(boolTypes, ev->xany.send_event));
(void) fprintf(f, ">> display=0x%lx\n", ev->xany.display);
(void) fprintf(f, ">> window=0x%lx\n", ev->xany.window);
switch (ev->type) {
case EnterNotify:
case LeaveNotify:
(void) fprintf(f, ">> root=0x%lx\n", ev->xcrossing.root);
(void) fprintf(f, ">> subwindow=0x%lx\n", ev->xcrossing.subwindow);
(void) fprintf(f, ">> mode=%s\n",
enumToName(notifyModes, ev->xcrossing.mode));
(void) fprintf(f, ">> detail=%s\n",
enumToName(notifyDetails, ev->xcrossing.detail));
(void) fprintf(f, ">> focus=%s\n",
enumToName(boolTypes, ev->xcrossing.focus));
break;
case FocusIn:
case FocusOut:
(void) fprintf(f, ">> mode=%s\n",
enumToName(notifyModes, ev->xcrossing.mode));
(void) fprintf(f, ">> detail=%s\n",
enumToName(notifyDetails, ev->xcrossing.detail));
break;
}
(void) fprintf(f, ">> }\n");
_DtTermProcessUnlock();
}

View File

@@ -0,0 +1,40 @@
/*
* $XConsortium: TermPrimDebug.h /main/1 1996/04/21 19:17:24 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimDebug_h
#define _Dt_TermPrimDebug_h
#define isDebugFSet _DtTermPrimIsDebugFSet
#define isDebugSet(c) isDebugFSet((c), 0)
#define setDebugFlags _DtTermPrimSetDebugFlags
#define shortSleep _DtTermPrimShortSleep
#define timeStamp _DtTermPrimTimeStamp
#define debugLevel _DtTermPrimDebugLevel
extern int isDebugFSet(int c, int f);
extern void setDebugFlags(char *c);
extern void shortSleep(int msec);
extern void timeStamp(char *msg);
extern unsigned char *debugLevel[256];
#define _TERM_MAX_DEBUG_FLAG 100
#define __TERM_DEBUG_BIT(x) (1 << (x % 8))
#define __TERM_DEBUG_BYTE(x) (x / 8)
#define _TERM_DEBUG_NUM_BYTES ((_TERM_MAX_DEBUG_FLAG + 7) / 8)
#define DebugF _TERM_DEBUG_FLAG
#define Debug _TERM_DEBUG
#define _TERM_DEBUG_FLAG(c, f, a) \
if (((f) < _TERM_MAX_DEBUG_FLAG) && debugLevel[(c)] && \
(debugLevel[(c)][__TERM_DEBUG_BYTE(f)] & __TERM_DEBUG_BIT(f))) { \
a; fflush(stderr); \
}
#define _TERM_DEBUG(c, a) \
_TERM_DEBUG_FLAG(c, 0, a)
#endif /* _Dt_TermPrimDebug_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,380 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimFunction.c /main/1 1996/04/21 19:17:27 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#include "TermHeader.h"
#include "TermPrimDebug.h"
#include "TermPrimP.h"
#include "TermPrimData.h"
#include "TermPrimFunction.h"
#include "TermPrimSetPty.h"
/******************************************************************************
*
* #### ##### # ######
* # # # # # #
* # # # ### # ##### ###
* # ##### ### # # ###
* # # # # # # # #
* #### # # # ###### # #
*
*
* ##### #### ##### ## #####
* # # # # # # # #
* ##### #### ### # # # #####
* # # # ### # ###### # #
* # # # # # # # # # #
* ##### #### # # # # #####
*/
void
_DtTermPrimFuncLF(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
struct termData *tpd = tw->term.tpd;
/*
** move the insert point...
*/
if (++tpd->cursorRow >= tw->term.rows)
{
/*
** scroll one line...
*/
(void) _DtTermPrimScrollText(w, 1);
tpd->cursorRow = tw->term.rows - 1;
}
(void) _DtTermPrimFillScreenGap(w);
return;
}
void
_DtTermPrimFuncBackspace(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
struct termData *tpd = tw->term.tpd;
if (tpd->cursorColumn > 0) {
(void) tpd->cursorColumn--;
}
return;
}
void
_DtTermPrimFuncCR(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
struct termData *tpd = tw->term.tpd;
tpd->cursorColumn = tpd->leftMargin;
return;
}
/*** CURSOR MOTION ************************************************************
*
* #### # # ##### #### #### #####
* # # # # # # # # # # #
* # # # # # #### # # # #
* # # # ##### # # # #####
* # # # # # # # # # # # #
* #### #### # # #### #### # #
*
*
* # # #### ##### # #### # #
* ## ## # # # # # # ## #
* # ## # # # # # # # # # #
* # # # # # # # # # # #
* # # # # # # # # # ##
* # # #### # # #### # #
*/
void
_DtTermPrimFuncNextLine(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
/* move down...
*/
(void) _DtTermPrimCursorOff(w);
while (count-- > 0) {
if (tpd->cursorRow < tw->term.rows - 1) {
(void) tpd->cursorRow++;
} else {
tpd->cursorRow = 0;
}
}
return;
}
void
_DtTermPrimFuncPreviousLine(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
/* move up...
*/
(void) _DtTermPrimCursorOff(w);
while (count-- > 0) {
if (tpd->cursorRow > 0) {
tpd->cursorRow--;
} else {
tpd->cursorRow = tw->term.rows - 1;
}
}
return;
}
void
_DtTermPrimFuncBackwardCharacter(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
/* move left...
*/
(void) _DtTermPrimCursorOff(w);
while (count-- > 0) {
if (tpd->cursorColumn > 0) {
(void) tpd->cursorColumn--;
} else {
/* past left edge -- wrap up... */
tpd->cursorColumn = tw->term.columns - 1;
if (tpd->cursorRow > 0) {
(void) tpd->cursorRow--;
} else {
/* past first line -- wrap to bottom of screen... */
tpd->cursorRow = tw->term.rows - 1;
}
}
}
return;
}
void
_DtTermPrimFuncForwardCharacter(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
/* move right...
*/
(void) _DtTermPrimCursorOff(w);
while (count-- > 0) {
if (tpd->cursorColumn < tw->term.columns - 1) {
(void) tpd->cursorColumn++;
} else {
/* past right edge -- wrap... */
tpd->cursorColumn = 0;
if (tpd->cursorRow < tw->term.rows - 1) {
(void) tpd->cursorRow++;
} else {
/* past last line -- wrap to top of screen... */
tpd->cursorRow = 0;
}
}
}
return;
}
void
_DtTermPrimFuncReturn(Widget w, int count, FunctionSource functionSource)
{
Debug('i', fprintf(stderr,
">>_DtTermPrimFuncReturn: not yet implemented\n"));
}
void
_DtTermPrimFuncTab(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
struct termData *tpd = tw->term.tpd;
TermBuffer tBuffer = tpd->termBuffer;
short nextTab;
(void) _DtTermPrimCursorOff(w);
if (tpd->cursorColumn < tpd->leftMargin) {
/* move to left margin on current line... */
tpd->cursorColumn = tpd->leftMargin;
} else {
/* Move to the next tab stop. Note that this cursor motion is
* similar to the right arrow cursor motion in that
* it doesn't set the line length until a character is entered.
*/
/* DKS: this code currently enforces tabs at every 8 character
* positions. It needs to be worked on to support the margins/tabs
* buffer...
*/
nextTab = _DtTermPrimBufferGetNextTab(tBuffer, tpd->cursorColumn);
/* check to see if we are past the end of the line... */
if ((nextTab <= 0) || (nextTab >= tpd->rightMargin)) {
/* wrap to next line...
*/
tpd->cursorColumn = tpd->leftMargin;
/* check to see if we scrolled off the bottom of the screen... */
if (++tpd->cursorRow >= tw->term.rows) {
/* scroll one line...
*/
(void)_DtTermPrimScrollText(w, 1);
tpd->cursorRow = tw->term.rows - 1;
}
/* fill any screen gap... */
if (tpd->topRow + tpd->cursorRow >= tpd->lastUsedRow) {
(void) _DtTermPrimFillScreenGap(w);
}
} else {
tpd->cursorColumn = nextTab;
}
}
return;
}
/*** TAB FUNCTIONS ************************************************************
*
* ##### ## #####
* # # # # #
* # # # #####
* # ###### # #
* # # # # #
* # # # #####
*
*
* ###### # # # # #### ##### # #### # # ####
* # # # ## # # # # # # # ## # #
* ##### # # # # # # # # # # # # # ####
* # # # # # # # # # # # # # # #
* # # # # ## # # # # # # # ## # #
* # #### # # #### # # #### # # ####
*/
void
_DtTermPrimFuncTabSet(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
(void) _DtTermPrimBufferSetTab(tpd->termBuffer, tpd->cursorColumn);
}
void
_DtTermPrimFuncTabClear(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
(void) _DtTermPrimBufferClearTab(tpd->termBuffer, tpd->cursorColumn);
}
void
_DtTermPrimFuncTabClearAll(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
(void) _DtTermPrimBufferClearAllTabs(tpd->termBuffer);
}
/*** REDRAW DISPLAY ***********************************************************
*
* # # ## ##### #### # # #
* ## ## # # # # # # # ## #
* # ## # # # # # # # # # #
* # # ###### ##### # ### # # # #
* # # # # # # # # # # ##
* # # # # # # #### # # #
*
*
* ###### # # # # #### ##### # #### # # ####
* # # # ## # # # # # # # ## # #
* ##### # # # # # # # # # # # # # ####
* # # # # # # # # # # # # # # #
* # # # # ## # # # # # # # ## # #
* # #### # # #### # # #### # # ####
*/
void
_DtTermPrimFuncMarginSetLeft(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
if (tpd->cursorColumn < tpd->rightMargin) {
tpd->leftMargin = tpd->cursorColumn;
} else {
_DtTermPrimBell(w);
}
return;
}
void
_DtTermPrimFuncMarginSetRight(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
if (tpd->cursorColumn > tpd->leftMargin) {
tpd->rightMargin = tpd->cursorColumn;
} else {
_DtTermPrimBell(w);
}
return;
}
void
_DtTermPrimFuncMarginClear(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget)w;
struct termData *tpd = tw->term.tpd;
tpd->leftMargin = 0;
tpd->rightMargin = tw->term.columns - 1;
return;
}
/*** REDRAW DISPLAY ***********************************************************
*
* ##### ###### ##### ##### ## # #
* # # # # # # # # # # #
* # # ##### # # # # # # # #
* ##### # # # ##### ###### # ## #
* # # # # # # # # # ## ##
* # # ###### ##### # # # # # #
*
*
* ##### # #### ##### # ## # #
* # # # # # # # # # # #
* # # # #### # # # # # #
* # # # # ##### # ###### #
* # # # # # # # # # #
* ##### # #### # ###### # # #
*/
void
_DtTermPrimFuncRedrawDisplay(Widget w, int count, FunctionSource functionSource)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
(void) XClearArea(XtDisplay(w), XtWindow(w), 0, 0, 0, 0, True);
return;
}

View File

@@ -0,0 +1,60 @@
/*
* $XConsortium: TermPrimFunction.h /main/1 1996/04/21 19:17:30 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimFunction_h
#define _Dt_TermPrimFunction_h
typedef enum {
fromAction,
fromParser,
fromFunctionKey,
fromMenu,
fromOther
} FunctionSource;
typedef void (*TermFunction) (Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncLF(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncBackspace(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncCR(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncNextLine(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncPreviousLine(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncBackwardCharacter(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncForwardCharacter(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncTab(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncTabSet(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncTabClear(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncTabClearAll(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncMarginSetLeft(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncMarginSetRight(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncMarginClear(Widget w, int count,
FunctionSource functionSource);
extern void _DtTermPrimFuncRedrawDisplay(Widget w, int count,
FunctionSource functionSource);
#endif /* _Dt_TermPrimFunction_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,413 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimGetPty-bsd.c /main/4 1996/11/21 19:58:32 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#include "TermPrimDebug.h"
#include "TermHeader.h"
#include <fcntl.h>
#include <termios.h>
#include <sys/wait.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <Xm/Xm.h>
#define X_INCLUDE_GRP_H
#define X_INCLUDE_UNISTD_H
#define XOS_USE_XT_LOCKING
#include <X11/Xos_r.h>
typedef struct _ptyInfo {
char *ptyName;
struct _ptyInfo *next;
struct _ptyInfo *prev;
} ptyInfo;
static ptyInfo _ptyInfoHead;
static ptyInfo *ptyInfoHead = &_ptyInfoHead;
static void
AddPtyInfo
(
char *ptyName
)
{
ptyInfo *ptyInfoTmp;
sigset_t newSigs;
sigset_t oldSigs;
/* malloc a new entry... */
ptyInfoTmp = (ptyInfo *) XtMalloc(sizeof(ptyInfo));
(void) memset(ptyInfoTmp, '\0', sizeof(ptyInfo));
/* fill in the structure... */
ptyInfoTmp->ptyName = (char *) XtMalloc(strlen(ptyName) + 1);
(void) strcpy(ptyInfoTmp->ptyName, ptyName);
/* insert it after the head of the list...
*/
/* block all signals... */
(void) sigfillset(&newSigs);
(void) sigemptyset(&oldSigs);
(void) sigprocmask(SIG_BLOCK, &newSigs, &oldSigs);
/* insert the entry into the list... */
ptyInfoTmp->prev = ptyInfoHead;
ptyInfoTmp->next = ptyInfoHead->next;
ptyInfoHead->next = ptyInfoTmp;
if (ptyInfoTmp->next) {
ptyInfoTmp->next->prev = ptyInfoTmp;
}
/* restore signals... */
(void) sigprocmask(SIG_SETMASK, &oldSigs, (sigset_t *) 0);
}
static void
DeletePtyInfo
(
char *ptyName
)
{
ptyInfo *ptyInfoTmp;
sigset_t newSigs;
sigset_t oldSigs;
/* find the entry... */
for (ptyInfoTmp = ptyInfoHead->next; ptyInfoTmp;
ptyInfoTmp = ptyInfoTmp->next) {
if (!strcmp(ptyInfoTmp->ptyName, ptyName)) {
break;
}
}
/* did we find anything... */
if (!ptyInfoTmp) {
/* not found... */
return;
}
/* delete entry from the list...
*/
/* block all signals... */
(void) sigfillset(&newSigs);
(void) sigemptyset(&oldSigs);
(void) sigprocmask(SIG_BLOCK, &newSigs, &oldSigs);
/* remove it... */
ptyInfoTmp->prev->next = ptyInfoTmp->next;
if (ptyInfoTmp->next) {
ptyInfoTmp->next->prev = ptyInfoTmp->prev;
}
/* restore signals... */
(void) sigprocmask(SIG_SETMASK, &oldSigs, (sigset_t *) 0);
/* free up the data... */
if (ptyInfoTmp->ptyName) {
(void) XtFree(ptyInfoTmp->ptyName);
ptyInfoTmp->ptyName = (char *) 0;
}
(void) XtFree((char *) ptyInfoTmp);
}
#define True 1
#define False 0
static char PTY_dev[] = "/dev";
static char PTY_dev_pty[] = "/dev/pty";
static char PTY_dev_ptym[] = "/dev/ptym";
static char PTY_a_ce_o[] = "abcefghijklmno";
static char PTY_a_ce_z[] = "abcefghijklmnopqrstuvwxyz";
static char PTY_0_9[] = "0123456789";
static char PTY_0_9a_f[] = "0123456789abcdef";
static char PTY_p_z[] = "pqrstuvwxyz";
static char PTY_p_r[] = "pqr";
#define PTY_null (char *) 0
static struct _pty_dirs {
char *pty_dir;
char *ptym_dir;
char *char_1;
char *char_2;
char *char_3;
int fast;
} pty_dirs[] = {
{PTY_dev_pty, PTY_dev_ptym, PTY_a_ce_o, PTY_0_9, PTY_0_9, True},
{PTY_dev_pty, PTY_dev_ptym, PTY_p_z, PTY_0_9, PTY_0_9, True},
{PTY_dev_pty, PTY_dev_ptym, PTY_a_ce_o, PTY_0_9a_f, PTY_null, True},
{PTY_dev_pty, PTY_dev_ptym, PTY_p_z, PTY_0_9a_f, PTY_null, False},
{PTY_dev, PTY_dev, PTY_p_r, PTY_0_9a_f, PTY_null, False},
{PTY_null, PTY_null, PTY_null, PTY_null, PTY_null, False},
};
#ifdef ALPHA_ARCHITECTURE
/* Use openpty() to open Master/Slave pseudo-terminal pair */
/* Current version of openpty() uses non-STREAM device. BSD name space */
#define TTYNAMELEN 25
static int
GetPty(char **ptySlave, char **ptyMaster)
{
int master, slave;
*ptySlave = malloc(TTYNAMELEN);
/* malloc error */
if (!(*ptySlave)) return -1;
if(!openpty(&master, &slave, *ptySlave, NULL, NULL))
{
/* success */
close(slave);
/* add it to the list... */
(void) AddPtyInfo(*ptySlave);
return master;
}
else /* failure */
return -1;
}
#else
static int
GetPty(char **ptySlave, char **ptyMaster)
{
struct _pty_dirs *pty_dirs_ptr;
char *char_1;
char *char_2;
char *char_3;
int first;
int ptyFd;
int ttyFd;
char *ttyDev = (char *) 0;
char *ptyDev = (char *) 0;
for (pty_dirs_ptr = pty_dirs;
pty_dirs_ptr->pty_dir && pty_dirs_ptr->ptym_dir; pty_dirs_ptr++) {
ttyDev = realloc(ttyDev,
(unsigned) (strlen(pty_dirs_ptr->pty_dir) + 8));
ptyDev = realloc(ptyDev,
(unsigned) (strlen(pty_dirs_ptr->ptym_dir) + 8));
if (!ttyDev || !ptyDev) {
(void) perror("malloc");
return(-1);
}
if (isDebugFSet('p', 10)) {
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
return(-1);
}
for (first = 1, char_1 = pty_dirs_ptr->char_1;
(first || !pty_dirs_ptr->fast) && *char_1; char_1++) {
for (char_2 = pty_dirs_ptr->char_2;
(first || !pty_dirs_ptr->fast) && *char_2; char_2++) {
for (char_3 = pty_dirs_ptr->char_3;
(first || !pty_dirs_ptr->fast); ) {
(void) sprintf(ttyDev, char_3 ? "%s/tty%c%c%c" :
"%s/tty%c%c", pty_dirs_ptr->pty_dir,
*char_1, *char_2, char_3 ? *char_3 : 0);
(void) sprintf(ptyDev, char_3 ? "%s/pty%c%c%c" :
"%s/pty%c%c", pty_dirs_ptr->ptym_dir,
*char_1, *char_2, char_3 ? *char_3 : 0);
ptyFd = -1;
ttyFd = -1;
errno = 0;
if ((ptyFd = open(ptyDev, O_RDWR, 0)) >= 0) {
if ((ttyFd = open(ttyDev, O_RDWR | O_NOCTTY, 0)) < 0) {
if (isDebugSet('p'))
(void) perror(ttyDev);
} else {
/* Success...
*/
char *c1;
_Xttynameparams tty_buf;
/* use ttyname so that we get the same
* name for the tty that everyone else will
* use...
*/
if (c1 = _XTtyname(ttyFd, tty_buf)) {
ttyDev = realloc(ttyDev, strlen(c1) + 1);
(void) strcpy(ttyDev, c1);
}
/* change the ownership and mode of the pty.
* This allows us to access the pty when we
* are no longer suid root...
*/
#ifdef HP_ARCHITECTURE
{
struct group *grp;
gid_t gid;
_Xgetgrparams grp_buf;
if (grp = _XGetgrnam("tty", grp_buf)) {
gid = grp->gr_gid;
} else {
gid = 0;
}
(void) endgrent();
(void) chown(ttyDev, getuid(), gid);
(void) chmod(ttyDev, 0620);
}
#else /* HP_ARCHITECTURE */
(void) chown(ttyDev, getuid(), getgid());
(void) chmod(ttyDev, 0622);
#endif /* HP_ARCHITECTURE */
/* close off the pty slave... */
(void) close(ttyFd);
/* add it to the list... */
(void) AddPtyInfo(ttyDev);
/* return file names and pty master... */
*ptySlave = ttyDev;
*ptyMaster = ptyDev;
return(ptyFd);
}
} else {
if (isDebugSet('p'))
(void) perror(ptyDev);
}
/* Failed to open...
*/
if (ptyFd >= 0)
(void) close(ptyFd);
if (ttyFd >= 0)
(void) close(ttyFd);
/* If we either were able to open the pty master (i.e.,
* slave open failed), or the device was busy, keep
* going...
*/
if ((ptyFd < 0) && (errno != EBUSY)) {
first = False;
}
if (!char_3)
break;
(void) char_3++;
if (!*char_3)
break;
}
}
}
}
return(-1);
}
#endif /* ALPHA_ARCHITECTURE */
/* this is a public wrapper around the previous function that runs the
* previous function setuid root...
*/
int
_DtTermPrimGetPty(char **ptySlave, char **ptyMaster)
{
int retValue;
/* this function needs to be suid root... */
(void) _DtTermPrimToggleSuidRoot(True);
retValue = GetPty(ptySlave, ptyMaster);
/* we now need to turn off setuid root... */
(void) _DtTermPrimToggleSuidRoot(False);
return(retValue);
}
static int
SetupPty(char *ptySlave, int ptyFd)
{
#ifdef HP_ARCHITECTURE
{
struct group *grp;
gid_t gid;
_Xgetgrparams grp_buf;
if (grp = _XGetgrnam("tty", grp_buf)) {
gid = grp->gr_gid;
} else {
gid = 0;
}
(void) endgrent();
(void) chown(ptySlave, getuid(), gid);
(void) chmod(ptySlave, 0620);
}
#else /* HP_ARCHITECTURE */
#ifdef ALPHA_ARCHITECTURE
/* code from xterm to setup ownership and permission */
{
struct group *ttygrp;
_Xgetgrparams grp_buf;
if (ttygrp = _XGetgrnam("tty", grp_buf)) {
/* change ownership of tty to real uid, "tty" gid */
chown (ptySlave, getuid(), ttygrp->gr_gid);
chmod (ptySlave, 0620);
}
else {
/* change ownership of tty to real group and user id */
chown (ptySlave, getuid(), getgid());
chmod (ptySlave, 0622);
}
endgrent();
}
#else /* ALPHA_ARCHITECTURE */
(void) chown(ptySlave, getuid(), getgid());
(void) chmod(ptySlave, 0622);
#endif /* ALPHA_ARCHITECTURE */
#endif /* HP_ARCHITECTURE */
return 0;
}
int
_DtTermPrimSetupPty(char *ptySlave, int ptyFd)
{
int retValue;
/* this function needs to be suid root... */
(void) _DtTermPrimToggleSuidRoot(True);
retValue = SetupPty(ptySlave, ptyFd);
/* we now need to turn off setuid root... */
(void) _DtTermPrimToggleSuidRoot(False);
return(retValue);
}
static void
ReleasePty(char *ptySlave)
{
(void) chown(ptySlave, 0, 0);
(void) chmod(ptySlave, 0666);
(void) DeletePtyInfo(ptySlave);
}
void
_DtTermPrimReleasePty(char *ptySlave)
{
/* this function needs to be suid root... */
(void) _DtTermPrimToggleSuidRoot(True);
(void) ReleasePty(ptySlave);
/* we now need to turn off setuid root... */
(void) _DtTermPrimToggleSuidRoot(False);
}
void
_DtTermPrimPtyCleanup()
{
DebugF('s', 10, fprintf(stderr, ">>_DtTermPrimPtyCleanup() starting\n"));
while (ptyInfoHead->next && ptyInfoHead->next->ptyName) {
DebugF('s', 10, fprintf(stderr, ">>releasing pty \"%s\"\n",
ptyInfoHead->next->ptyName));
(void) _DtTermPrimReleasePty(ptyInfoHead->next->ptyName);
}
DebugF('s', 10, fprintf(stderr, ">>_DtTermPrimPtyCleanup() finished\n"));
}

View File

@@ -0,0 +1,181 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$TOG: TermPrimGetPty-clone.c /main/7 1998/04/03 17:11:08 mgreess $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#include "TermPrimDebug.h"
#include "TermHeader.h"
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <signal.h>
#include <Xm/Xm.h>
#ifdef HP_ARCHITECTURE
# define X_INCLUDE_GRP_H
#endif /* HP_ARCHITECTURE */
#define X_INCLUDE_UNISTD_H
#define XOS_USE_XT_LOCKING
#include <X11/Xos_r.h>
#if defined(__AIX)
# define PTY_CLONE_DEVICE "/dev/ptc"
#elif defined(linux)
# define PTY_CLONE_DEVICE "/dev/ptyc"
#endif /* __AIX */
static int
GetPty(char **ptySlave, char **ptyMaster)
{
char *c;
int ptyFd;
int ttyFd;
*ptyMaster = malloc(strlen(PTY_CLONE_DEVICE) + 1);
(void) strcpy(*ptyMaster, PTY_CLONE_DEVICE);
if (isDebugFSet('p', 10)) {
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
return(-1);
}
if ((ptyFd = open(*ptyMaster, O_RDWR, 0))) {
_Xttynameparams tty_buf;
if (c = _XTtyname(ptyFd, tty_buf)) {
*ptySlave = malloc(strlen(c) + 1);
(void) strcpy(*ptySlave, c);
if ((ttyFd = open(*ptySlave, O_RDWR | O_NOCTTY, 0)) < 0) {
/* failure... */
(void) perror(*ptySlave);
(void) close(ptyFd);
} else {
/* success...
*/
/* close off the pty slave... */
(void) close(ttyFd);
/* fix the owner, mode, and group... */
#ifdef HP_ARCHITECTURE
{
struct group *grp;
gid_t gid;
_Xgetgrparams grp_buf;
if (grp = _XGetgrnam("tty", grp_buf)) {
gid = grp->gr_gid;
} else {
gid = 0;
}
(void) endgrent();
(void) chown(*ptySlave, getuid(), gid);
(void) chmod(*ptySlave, 0620);
}
#else /* HP_ARCHITECTURE */
(void) chown(*ptySlave, getuid(), getgid());
(void) chmod(*ptySlave, 0622);
#endif /* HP_ARCHITECTURE */
/* pty master and slave names are already set. Return
* the file descriptor...
*/
return(ptyFd);
}
} else {
/* ttyname on the pty master failed. This should not happen!... */
(void) perror("ttyname");
(void) close(ptyFd);
}
} else {
(void) perror(*ptyMaster);
}
return(-1);
}
/* this is a public wrapper around the previous function that runs the
* previous function setuid root...
*/
int
_DtTermPrimGetPty(char **ptySlave, char **ptyMaster)
{
int retValue;
/* this function needs to be suid root... */
(void) _DtTermPrimToggleSuidRoot(True);
retValue = GetPty(ptySlave, ptyMaster);
/* we now need to turn off setuid root... */
(void) _DtTermPrimToggleSuidRoot(False);
return(retValue);
}
static int
SetupPty(char *ptySlave, int ptyFd)
{
#ifdef HP_ARCHITECTURE
{
struct group *grp;
gid_t gid;
_Xgetgrparams grp_buf;
if (grp = _XGetgrnam("tty", grp_buf)) {
gid = grp->gr_gid;
} else {
gid = 0;
}
(void) endgrent();
(void) chown(ptySlave, getuid(), gid);
(void) chmod(ptySlave, 0620);
}
#else /* HP_ARCHITECTURE */
(void) chown(ptySlave, getuid(), getgid());
(void) chmod(ptySlave, 0622);
#endif /* HP_ARCHITECTURE */
}
int
_DtTermPrimSetupPty(char *ptySlave, int ptyFd)
{
int retValue;
/* this function needs to be suid root... */
(void) _DtTermPrimToggleSuidRoot(True);
retValue = SetupPty(ptySlave, ptyFd);
/* we now need to turn off setuid root... */
(void) _DtTermPrimToggleSuidRoot(False);
return(retValue);
}
static void
ReleasePty(char *ptySlave)
{
(void) chown(ptySlave, 0, 0);
(void) chmod(ptySlave, 0666);
}
void
_DtTermPrimReleasePty(char *ptySlave)
{
/* this function needs to be suid root... */
(void) _DtTermPrimToggleSuidRoot(True);
(void) ReleasePty(ptySlave);
/* we now need to turn off setuid root... */
(void) _DtTermPrimToggleSuidRoot(False);
}
void
_DtTermPrimPtyCleanup()
{
return;
}

View File

@@ -0,0 +1,249 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimGetPty-svr4.c /main/1 1996/04/21 19:17:39 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
/**************************************************************************
*
* Note: This code is based on the pty allocation code from xview. It
* was basically taken intact as were the comments...
*/
#include "TermPrimOSDepI.h"
#include "TermPrimDebug.h"
#include "TermHeader.h"
#include <stropts.h>
#include <sys/conf.h>
#include <sys/stream.h>
#include <sys/termios.h>
#ifdef USE_STREAMS_BUFMOD
#include <sys/bufmod.h>
#endif /* USE_STREAMS_BUFMOD */
#include <errno.h>
/* last ditch fallback. If the clone device is other than /dev/ptmx,
* it should have been set previously...
*/
#ifndef PTY_CLONE_DEVICE
#define PTY_CLONE_DEVICE "/dev/ptmx"
#endif /* PTY_CLONE_DEVICE */
int _DtTermPrimGetPty(char **ptySlave, char **ptyMaster)
{
char *c;
int ptyFd;
int ttyFd;
extern char *ptsname(int fd);
*ptyMaster = malloc(strlen(PTY_CLONE_DEVICE) + 1);
(void) strcpy(*ptyMaster, PTY_CLONE_DEVICE);
if (isDebugFSet('p', 10)) {
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
return(-1);
}
if ((ptyFd = open(*ptyMaster, O_RDWR, 0)) >= 0) {
/* use grantpt to prevent other processes from grabbing the tty that
* goes with the pty master we have opened. It is a mandatory step
* in the SVR4 pty-tty initialization. Note that /dev must be
* mounted read/write...
*/
Debug('T', timeStamp("_DtTermPrimGetPty() calling grantpt()"));
if (grantpt(ptyFd) == -1) {
(void) perror("grantpt");
(void) close(ptyFd);
return(-1);
}
/* Unlock the pty master/slave pair so the slave can be opened later */
Debug('T', timeStamp("_DtTermPrimGetPty() calling unlockpt()"));
if (unlockpt(ptyFd) == -1) {
(void) perror("unlockpt");
(void) close(ptyFd);
return(-1);
}
Debug('T', timeStamp("_DtTermPrimGetPty() unlockpt() finished"));
#ifdef USE_STREAMS_BUFMOD
if (ioctl(ptyFd, I_PUSH, "bufmod") == -1) {
(void) perror("I_PUSH bufmod");
/* We can't push bufmod. This means that we're probably running
* on a generic SVR4 system. We can ignore this error since
* bufmod is used for performance reasons only...
*/
} else {
struct timeval timeval;
struct strioctl cmd;
unsigned int chunk;
/* Note that we're not using SB_SEND_ON_WRITE | SB_DEFER_CHUNK.
* Turns out the shell (or someone down the pty) does an ioctl
* when sending out each prompt. Since this flushes any
* partially filled chunk automatically, we really don't need
* to do this...
*/
chunk = SB_NO_DROPS | SB_NO_PROTO_CVT | SB_NO_HEADER;
cmd.ic_timout = 0;
cmd.ic_cmd = SBIOCSFLAGS;
cmd.ic_len = sizeof(u_long);
cmd.ic_dp = (char *) &chunk;
if (ioctl(ptyFd, I_STR, &cmd) < 0) {
(void) perror("SBIOCSFLAGS");
/* If we pushed bufmod, but this ioctl fails, it means we're
* most likely running on a system with old bufmod (i.e., for
* released OSs this must be Jupiter). We treat this error
* silently so developers and users of the Mars trees don't
* get confused. Treat it like bufmod wasn't there at all...
*/
goto backoff;
}
timeval.tv_usec = 50000;
timeval.tv_sec = 0;
cmd.ic_cmd = SBIOCSTIME;
cmd.ic_timout = 0;
cmd.ic_len = sizeof(timeval);
cmd.ic_dp = (char *) &timeval;
if (ioctl(ptyFd, I_STR, &cmd) < 0) {
/* These are legit errors. If we have new bufmod, this
* should have worked...
*/
(void) perror("BSIOCSTIME");
goto backoff;
}
/* I have made the chunk size the same as the buffer used in the
* ttysw. One could experiment here, but this works...
*/
{
/* struct cbuf *sizeit; */
/* chunk = sizeof(sizeit->cb_buf); */
chunk = 2048; /* taken from xview source def of cbuf... */
}
cmd.ic_cmd = SBIOCSCHUNK;
cmd.ic_len = sizeof(int);
cmd.ic_dp = (char *) &chunk;
if (ioctl(ptyFd, I_STR, &cmd) < 0) {
(void) perror("SBIOCSCHUNK");
goto backoff;
}
/* We certainly don't want to truncate any packets, so set the
* snap length to zero...
*/
chunk = 0;
cmd.ic_cmd = SBIOCSSNAP;
cmd.ic_len = sizeof(int);
cmd.ic_dp = (char *) &chunk;
if (ioctl(ptyFd, I_STR, &cmd) < 0) {
(void) perror("SBIOCSSNAP");
goto backoff;
}
goto ok;
}
backoff:
/* Something didn't work out, so pull bofmod off the stream and
* continue as if it weren't there...
*/
if (ioctl(ptyFd, I_POP, 0) == -1) {
/* bufmod not working or wrong version... */
(void) perror("I_POP bufmod");
}
ok:
#endif /* USE_STREAMS_BUFMOD */
/* get the pty slave name... */
if (c = ptsname(ptyFd)) {
*ptySlave = malloc(strlen(c) + 1);
(void) strcpy(*ptySlave, c);
#ifdef NOTDEF
{
int slaveFd;
char buffer[BUFSIZ];
if ((slaveFd = open(*ptySlave, O_RDWR, 0)) < 0) {
(void) perror(*ptySlave);
(void) fprintf(stderr, "it failed!\n");
(void) sprintf(buffer, "ls -l %s", *ptySlave);
(void) system(buffer);
} else {
(void) close(slaveFd);
}
}
#endif /* NOTDEF */
return(ptyFd);
} else {
/* ptsname on the pty master failed. This should not happen!... */
(void) perror("ptsname");
(void) close(ptyFd);
}
} else {
(void) perror(*ptyMaster);
}
return(-1);
}
int
_DtTermPrimSetupPty(char *ptySlave, int ptyFd)
{
/*
* The following "pushes" were done at GetPty time, but
* they don't seem to stick after the file is closed on
* SVR4.2. Not sure where else this applies.
*/
if (ioctl(ptyFd, I_PUSH, "ptem") == -1) {
(void) perror("Error pushing ptem");
/* exit the subprocess */
return(1);
}
if (ioctl(ptyFd, I_PUSH, "ldterm") == -1) {
(void) perror("Error pushing ldterm");
/* exit the subprocess */
return(1);
}
#ifdef USE_STREAMS_TTCOMPAT
if (ioctl(ptyFd, I_PUSH, "ttcompat") == -1) {
(void) perror("Error pushing ttcompat");
/* exit the subprocess */
return(1);
}
#endif /* USE_STREAMS_TTCOMPAT */
/* success... */
return(0);
}
void
_DtTermPrimReleasePty(char *ptySlave)
{
/* dummy function for STREAMS... */
}
void
_DtTermPrimPtyCleanup()
{
/* dummy function for STREAMS... */
return;
}

View File

@@ -0,0 +1,19 @@
/*
* $XConsortium: TermPrimGetPty.h /main/1 1996/04/21 19:17:42 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimGetPty_h
#define _Dt_TermPrimGetPty_h
int _DtTermPrimGetPty(char **ptySlave, char **ptyMaster);
int _DtTermPrimSetupPty(char *ptySlave, int ptyFd);
void _DtTermPrimReleasePty(char *ptySlave);
void _DtTermPrimPtyCleanup();
#endif /* _Dt_TermPrimGetPty_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,48 @@
/*
* $XConsortium: TermPrimI.h /main/1 1996/04/21 19:17:45 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimI_h
#define _Dt_TermPrimI_h
#include <Xm/Xm.h>
#include <TermPrim.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
extern void _DtTermPrimForcePtyRead(XtPointer client_data, XtIntervalId *id);
extern void _DtTermPrimLoopBackData(Widget w, char *data, int dataLength);
extern void _DtTermPrimDrawShadow(Widget w);
extern void _DtTermPrimStartOrStopPtyInput(Widget w);
extern void _DtTermPrimStartOrStopPtyOutput(Widget w);
extern void _DtTermPrimSendInput(Widget w, unsigned char *buffer, int len);
extern void _DtTermPrimInsertCharUpdate(Widget w, DtTermInsertCharMode insertCharMode);
extern void _DtTermPrimWarningDialog(Widget w, char *msg);
extern void _DtTermPrimPutEnv(char *c1, char *c2);
extern void
_DtTermPrimInvokeStatusChangeCallback
(
Widget w
);
extern void
_DtTermPrimGetFontSet
(
Widget w,
XmFontList fontList,
XFontSet *fontSet,
XFontStruct **font
);
#ifdef __cplusplus
} /* close scope of 'extern "C"'... */
#endif /* __cplusplus */
/* DON'T ADD ANYTHING AFTER THIS #endif... */
#endif /* _Dt_TermPrimI_h */

View File

@@ -0,0 +1,634 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimLineDraw.c /main/1 1996/04/21 19:17:48 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <Xm/Xm.h>
#include "TermPrimLineFontP.h"
#include "TermPrimLineDrawP.h"
#include "TermPrimDebug.h"
#include "TermPrimP.h"
/****************************************************************************
*
* This module is used to implement the line drawing functionality for
* hpterm. It implements a primitive (simple?) font scaling engine that
* converts a set of rectangles, lines, and "stipples" to a line drawing
* font. The font is stored as a single plane pixmap and is rendered by
* performing a copy plane to the target drawable.
*
* To increase the performance, fonts are not free'ed when the reference
* count hits zero. Rather, they are free'ed if the reference count has
* hit zero and a new font is created with different parameters.
*
***************************************************************************/
static LineDrawFontData lineDrawFontDataHead = (LineDrawFontData) 0;
static LineDrawFont lineDrawFontHead = (LineDrawFont) 0;
/* static int numLineDrawFonts = 0; */
static void
ScaleCharacter(
#ifdef USE_PIXMAPS
GC gc, Pixmap bitmap,
ScaledBitmapInfo renderInfo, GlyphInfo glyph,
int width, int height
#else /* USE_PIXMAPS */
ScaledCharInfo renderInfo, GlyphInfo glyph, int width, int height
#endif /* USE_PIXMAPS */
)
{
int j;
#ifdef USE_PIXMAPS
cellPositionType cellX;
cellPositionType cellX;
Pixmap pixmap;
#else /* USE_PIXMAPS */
int k;
int numLines;
#endif /* USE_PIXMAPS */
#ifdef USE_PIXMAPS
/* calculate position of pixmap into which we will draw the glyph...
*/
cellX = (i % 16) * width;
cellY = (i / 16) * height;
renderInfo->cellX = cellX;
renderInfo->cellY = cellY;
#else /* USE_PIXMAPS */
/* malloc storage for the line segments, rectangles, stipples...
*/
/* count the number of lines... */
for (j = 0, numLines = 0; j < glyph->numLines; j++) {
numLines += glyph->lines[j].width;
}
if (numLines > 0) {
/* malloc the line storage... */
renderInfo->segs = (XSegment *)
XtRealloc((void *) renderInfo->segs,
numLines * sizeof(XSegment));
}
renderInfo->numSegs = numLines;
/* rectangles... */
if (glyph->numRects > 0) {
/* malloc the rectangle storage... */
renderInfo->rects = (XRectangle *)
XtRealloc((void *) renderInfo->rects,
glyph->numRects * sizeof(XRectangle));
}
renderInfo->numRects = glyph->numRects;
/* stipples... */
if (glyph->numStipples > 0) {
/* malloc the stipple storage... */
renderInfo->stipples = (XRectangle *)
XtRealloc((void *) renderInfo->stipples,
glyph->numStipples * sizeof(XRectangle));
}
renderInfo->numStipples = glyph->numStipples;
#endif /* USE_PIXMAPS */
/* draw the lines...
*/
#ifndef USE_PIXMAPS
/* reset the counter... */
numLines = 0;
#endif /* USE_PIXMAPS */
/* lines
*/
for (j = 0; j < glyph->numLines; j++) {
/* draw the line segment / scale the line segment... */
int x1;
int x2;
int y1;
int y2;
DebugF('l', 0, fprintf(stderr,
">> line data: x1=%d%+d y1=%d%+d x2=%d%+d y2=%d%+d width=%d",
glyph->lines[j].x1,
glyph->lines[j].x1Offset,
glyph->lines[j].y1,
glyph->lines[j].y1Offset,
glyph->lines[j].x2,
glyph->lines[j].x2Offset,
glyph->lines[j].y2,
glyph->lines[j].y2Offset,
glyph->lines[j].width));
/* scale x1 and x2 to our width... */
x1 = ((width - 1) * glyph->lines[j].x1) / 100;
x2 = ((width - 1) * glyph->lines[j].x2) / 100;
/* scale y1 and y2 to our height... */
y1 = ((height - 1) * glyph->lines[j].y1) / 100;
y2 = ((height - 1) * glyph->lines[j].y2) / 100;
/* add offsets... */
x1 += glyph->lines[j].x1Offset;
x2 += glyph->lines[j].x2Offset;
y1 += glyph->lines[j].y1Offset;
y2 += glyph->lines[j].y2Offset;
#ifdef USE_PIXMAPS
/* add in the line width... */
if (x1 == x2) {
x1 -= (glyph->lines[j].width - 1) / 2;
x2 += glyph->lines[j].width - 1 - (glyph->lines[j].width - 1) / 2;
}
/* add in the line width... */
if (y1 == y2) {
y1 -= (glyph->lines[j].width - 1) / 2;
y2 += glyph->lines[j].width - 1 - (glyph->lines[j].width - 1) / 2;
}
DebugF('l', 0, fprintf(stderr,
">> line: x=%d y=%d width=%d height=%d",
x1, y1, x2 - x1 + 1, y2 - y1 + 1));
/* draw the line (actually, fill the rectangle)... */
(void) XFillRectangle(d, /* display */
pixmap, /* drawable */
gc, /* GC */
cellX + x1, /* x */
cellY + y1, /* y */
x2 - x1 + 1, /* width */
y2 - y1 + 1); /* height */
#else /* USE_PIXMAPS */
if ((x1 == x2) && (y1 != y2)) {
/* vertical lines... */
for (k = 0; k < glyph->lines[j].width; k++) {
renderInfo->segs[numLines + k].x1 =
renderInfo->segs[numLines + k].x2 =
x1 - (glyph->lines[j].width / 2) + k;
renderInfo->segs[numLines + k].y1 = y1;
renderInfo->segs[numLines + k].y2 = y2;
}
} else if ((y1 == y2) && (x1 != x2)) {
/* horizontal lines... */
for (k = 0; k < glyph->lines[j].width ; k++) {
renderInfo->segs[numLines + k].y1 =
renderInfo->segs[numLines + k].y2 =
y2 - (glyph->lines[j].width / 2) + k;
renderInfo->segs[numLines + k].x1 = x1;
renderInfo->segs[numLines + k].x2 = x2;
}
} else {
for (k = 0; k < glyph->lines[j].width; k++) {
renderInfo->segs[numLines + k].y1 =
renderInfo->segs[numLines + k].y2 =
y2 - (glyph->lines[j].width / 2) + k;
renderInfo->segs[numLines + k].x1 = x1 -
glyph->lines[j].width / 2;
renderInfo->segs[numLines + k].x2 = x2 +
glyph->lines[j].width / 2;
}
}
numLines += glyph->lines[j].width;
}
#endif /* USE_PIXMAPS */
/* rectangles...
*/
for (j = 0; j < glyph->numRects; j++) {
/* draw / stipple the rectangles... */
int x1;
int x2;
int y1;
int y2;
/* scale x1 and x2 to our width... */
x1 = ((width - 1) * glyph->rects[j].x1) / 100;
x2 = ((width - 1) * glyph->rects[j].x2) / 100;
/* scale y1 and y2 to our height... */
y1 = ((height - 1) * glyph->rects[j].y1) / 100;
y2 = ((height - 1) * glyph->rects[j].y2) / 100;
/* add offsets... */
x1 += glyph->rects[j].x1Offset;
x2 += glyph->rects[j].x2Offset;
y1 += glyph->rects[j].y1Offset;
y2 += glyph->rects[j].y2Offset;
#ifdef USE_PIXMAPS
DebugF('l', 0, fprintf(stderr,
">> rect: x=%d y=%d width=%d height=%d",
x1, y1, x2 - x1 + 1, y2 - y1 + 1));
/* fill the rectangle... */
(void) XFillRectangle(d, /* display */
pixmap, /* drawable */
gc, /* GC */
cellX + x1, /* x */
cellY + y1, /* y */
x2 - x1 + 1, /* width */
y2 - y1 + 1); /* height */
#else /* USE_PIXMAPS */
renderInfo->rects[j].x = x1;
renderInfo->rects[j].y = y1;
renderInfo->rects[j].width = x2 - x1 + 1;
renderInfo->rects[j].height = y2 - y1 + 1;
#endif /* USE_PIXMAPS */
}
/* stipple in the rectangle...
*/
for (j = 0; j < glyph->numStipples; j++) {
/* stipple the rectangle... */
int x1;
int x2;
int y1;
int y2;
int stippleSize;
#ifdef USE_PIXMAPS
int xIndex;
int yIndex;
#endif /* USE_PIXMAPS */
/* scale x1 and x2 to our width... */
x1 = ((width - 1) * glyph->stipples[j].x1) / 100;
x2 = ((width - 1) * glyph->stipples[j].x2) / 100;
/* scale y1 and y2 to our height... */
y1 = ((height - 1) * glyph->stipples[j].y1) / 100;
y2 = ((height - 1) * glyph->stipples[j].y2) / 100;
stippleSize = glyph->stipples[j].width;
/* add offsets... */
x1 += glyph->stipples[j].x1Offset;
x2 += glyph->stipples[j].x2Offset;
y1 += glyph->stipples[j].y1Offset;
y2 += glyph->stipples[j].y2Offset;
#ifdef USE_PIXMAPS
/* fill in the area... */
for (yIndex = y1; yIndex < y2; yIndex += stippleSize) {
for (xIndex = x1; xIndex < x2; xIndex += stippleSize) {
if (!(((xIndex / stippleSize) % 2) ^
((yIndex / stippleSize) % 2))) {
/* fill this rectangle... */
DebugF('l', 0, fprintf(stderr,
">> stipple: x=%d y=%d width=%d height=%d",
xIndex, yIndex,
(stippleSize <= (x2 - xIndex)) ? stippleSize :
x2 - xIndex,
(stippleSize <= (y2 - yIndex)) ? stippleSize :
y2 - yIndex));
(void) XFillRectangle(d, /* display */
pixmap, /* drawable */
gc, /* GC */
cellX + xIndex, /* x */
cellY + yIndex, /* y */
(stippleSize <= (x2 - xIndex)) ? stippleSize :
x2 - xIndex,
/* width */
(stippleSize <= (y2 - yIndex)) ? stippleSize :
y2 - yIndex);
/* height */
}
}
}
#endif /* USE_PIXMAPS */
}
/* mark this character as completed... */
#ifdef USE_PIXMAPS
renderInfo->scaled = True;
#else /* USE_PIXMAPS */
renderInfo->scaled = True;
#endif /* USE_PIXMAPS */
}
static short *
GetLineDrawFontIndex(GlyphInfo glyphInfo, int numGlyphs)
{
LineDrawFontData lineDrawFontData;
int i;
int j;
for (lineDrawFontData = lineDrawFontDataHead; lineDrawFontData;
lineDrawFontData = lineDrawFontData->next) {
if ((lineDrawFontData->glyphInfo == glyphInfo) &&
lineDrawFontData->numGlyphs == numGlyphs) {
return(lineDrawFontData->lineDrawIndex);
}
}
/* no match. Insert one at the head of the list and fill it out...
*/
lineDrawFontData = (LineDrawFontData) XtMalloc(sizeof(LineDrawFontDataRec));
lineDrawFontData->next = lineDrawFontDataHead;
lineDrawFontDataHead = lineDrawFontData;
lineDrawFontData->glyphInfo = glyphInfo;
lineDrawFontData->numGlyphs = numGlyphs;
/* clear out the array... */
for (i = 0; i < (sizeof(lineDrawFontData->lineDrawIndex) /
sizeof(lineDrawFontData->lineDrawIndex[0])); i++) {
lineDrawFontData->lineDrawIndex[i] = -1;
}
/* fill up the array... */
for (i = 0; i < numGlyphs; i++) {
for (j = 0; glyphInfo[i].chars[j] > 0; j++) {
lineDrawFontData->lineDrawIndex[glyphInfo[i].chars[j] % 256] = i;
}
}
return(lineDrawFontData->lineDrawIndex);
}
LineDrawFont
_DtTermPrimLineDrawCreateFont(Widget w, GlyphInfo glyphInfo, int numGlyphs,
int width, int ascent, int descent)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
int fontNumber;
LineDrawFont lineDrawFont;
int i;
int height = ascent + descent;
#ifdef USE_PIXMAPS
GC gc;
Pixmap pixmap;
#endif /* USE_PIXMAPS */
_DtTermProcessLock();
/* let's look for a line draw font that is already made...
*/
for (lineDrawFont = lineDrawFontHead; lineDrawFont;
lineDrawFont = lineDrawFont->next) {
if ((lineDrawFont->fontValid) &&
(lineDrawFont->width == width) &&
(lineDrawFont->height == height) &&
(lineDrawFont->ascent == ascent) &&
(lineDrawFont->display == XtDisplay(w)) &&
(lineDrawFont->glyphInfo == glyphInfo) &&
(lineDrawFont->numGlyphs == numGlyphs)) {
/* we found a match...
*/
/* bump the reference count... */
(void) lineDrawFont->refCount++;
/* and return this "font"... */
_DtTermProcessUnlock();
return (lineDrawFont);
}
}
/* no match -- we will have to build the font...
*/
/* look for a free slot... */
for (lineDrawFont = lineDrawFontHead; lineDrawFont;
lineDrawFont = lineDrawFont->next) {
if ((lineDrawFont->refCount == 0) &&
(lineDrawFont->glyphInfo == glyphInfo) &&
(lineDrawFont->numGlyphs == numGlyphs)) {
/* found a free slot... */
/* free any valid but unused font in this slot... */
if (lineDrawFont->fontValid) {
#ifdef USE_PIXMAPS
(void) XFreePixmap(lineDrawFont->display,
/* Display */
lineDrawFont->pixmap); /* drawable */
#endif /* USE_PIXMAPS */
lineDrawFont->fontValid = False;
}
break;
}
}
/* did we hit the end of the linked list... */
if (!lineDrawFont) {
/* add a new entry to the head of the linked list... */
lineDrawFont = (LineDrawFont)
XtMalloc(sizeof(LineDrawFontRec));
(void) memset(lineDrawFont, '\0', sizeof(LineDrawFontRec));
lineDrawFont->next = lineDrawFontHead;
lineDrawFontHead = lineDrawFont;
}
lineDrawFont->refCount = 1;
lineDrawFont->fontValid = True;
lineDrawFont->width = width;
lineDrawFont->height = height;
lineDrawFont->ascent = ascent;
lineDrawFont->width = width;
lineDrawFont->display = XtDisplay(w);
lineDrawFont->glyphInfo = glyphInfo;
lineDrawFont->numGlyphs = numGlyphs;
lineDrawFont->glyphIndex = GetLineDrawFontIndex(glyphInfo, numGlyphs);
#ifdef USE_PIXMAPS
/* malloc the cell position for this font (if necessary)... */
if (!lineDrawFont->scaledBitmapInfo) {
lineDrawFont->scaledBitmapInfo = (ScaledBitmapInfo)
XtMalloc(lineDrawFont->numGlyphs * sizeof(ScaledBitmapInfoRec));
/* initialize it... */
(void) memset(lineDrawFont->scaledBitmapInfo, '\0',
lineDrawFont->numGlyphs * sizeof(scaledBitmapInfo));
} else {
/* mark all the characters in the old font as unscaled... */
for (i = 0; i < lineDrawFont->numGlyphs; i++) {
lineDrawFont->scaledBitmapInfo[i].scaled = False;
}
}
#else /* USE_PIXMAPS */
/* malloc the line, rectangle, stipple storage (if necessary)... */
if (!lineDrawFont->scaledCharInfo) {
lineDrawFont->scaledCharInfo = (ScaledCharInfo)
XtMalloc(lineDrawFont->numGlyphs * sizeof(ScaledCharInfoRec));
(void) memset(lineDrawFont->scaledCharInfo, '\0',
lineDrawFont->numGlyphs * sizeof(ScaledCharInfoRec));
} else {
/* mark all the characters in the old font as unscaled... */
for (i = 0; i < lineDrawFont->numGlyphs; i++) {
lineDrawFont->scaledCharInfo[i].scaled = False;
}
}
#endif /* USE_PIXMAPS */
#ifdef USE_PIXMAPS
/* create a pixmap that is 16 characters wide and
* lineDrawFont->numGlyphs / 16 characters high...
*/
pixmap = XCreatePixmap(d,
/* Display */
DefaultRootWindow(d), /* reference window */
width * 16, /* width */
(lineDrawFont->numGlyphs + 15) / 16 * (height),
/* height */
1); /* planes */
lineDrawFont->pixmap = pixmap;
/* we need a GC...
*/
gc = XCreateGC(d, /* Display */
pixmap, /* drawable */
(unsigned long) (0), /* value mask */
(XGCValues *) 0); /* values */
/* clear the pixmap... */
(void) XSetForeground(d, gc, 0);
(void) XFillRectangle(d, /* display */
pixmap, /* drawable */
gc, /* GC */
0, /* x */
0, /* y */
width * 16, /* width */
(lineDrawFont->numGlyphs + 15) / 16 * (height));
/* height */
/* reset the GC so we can fill in the lines and rectangles... */
(void) XSetForeground(d, gc, 1);
#endif /* USE_PIXMAPS */
_DtTermProcessUnlock();
return(lineDrawFont);
}
void
_DtTermPrimLineDrawFreeFont(LineDrawFont lineDrawFont)
{
_DtTermProcessLock();
/* perform a sanity check... */
if (lineDrawFont->refCount <= 0) {
_DtTermProcessUnlock();
return;
}
/* decrement the reference count... */
(void) lineDrawFont->refCount--;
/* we will free the storage if this font is used... */
_DtTermProcessUnlock();
return;
}
void
_DtTermPrimLineDrawImageString(Display *display, Drawable d,
LineDrawFont lineDrawFont,
GC gc, GC clearGC, int x, int y, unsigned char *string, int width)
{
int glyph;
#ifndef USE_PIXMAPS
XSegment segs[20];
XRectangle rects[20];
int i;
#endif /* USE_PIXMAPS */
_DtTermProcessLock();
if (!lineDrawFont || (lineDrawFont->refCount < 0)) {
_DtTermProcessUnlock();
return;
}
#ifndef USE_PIXMAPS
/* clear the area... */
(void) XFillRectangle(display, /* Display */
d, /* Window */
clearGC, /* GC */
x, /* x */
y - lineDrawFont->ascent, /* y */
lineDrawFont->width * width, /* width */
lineDrawFont->height); /* height */
#endif /* USE_PIXMAPS */
/* render the characters... */
for (; width > 0; width--, string++) {
/* look up glyph through the glyph table... */
/* check for valid glyph... */
glyph = lineDrawFont->glyphIndex[*string];
/* if it is invalid, then let's default to space... */
if (glyph < 0)
glyph = lineDrawFont->glyphIndex[' '];
/* if it is still invalid, then let's skip this character... */
if (glyph < 0) {
x += lineDrawFont->width;
continue;
}
#ifdef USE_PIXMAPS
/* render this character... */
(void) XCopyPlane(display, /* Display */
lineDrawFont->pixmap, /* src */
d, /* dest */
gc, /* GC */
lineDrawFont->cellX[glyph], /* src x */
lineDrawFont->cellY[glyph], /* src y */
lineDrawFont->width, /* width */
lineDrawFont->height, /* height */
x, /* dest x */
y - lineDrawFont->ascent, /* dest y */
1); /* plane */
#else /* USE_PIXMAPS */
if (!lineDrawFont->scaledCharInfo[glyph].scaled) {
/* first time, scale this character... */
(void) ScaleCharacter(&(lineDrawFont->scaledCharInfo[glyph]),
&(lineDrawFont->glyphInfo[glyph]), lineDrawFont->width, lineDrawFont->height);
}
if (lineDrawFont->scaledCharInfo[glyph].numSegs > 0) {
for (i = 0; i < lineDrawFont->scaledCharInfo[glyph].numSegs; i++) {
segs[i].x1 = x + lineDrawFont->scaledCharInfo[glyph].segs[i].x1;
segs[i].x2 = x + lineDrawFont->scaledCharInfo[glyph].segs[i].x2;
segs[i].y1 =
y + lineDrawFont->scaledCharInfo[glyph].segs[i].y1 -
lineDrawFont->ascent;
segs[i].y2 =
y + lineDrawFont->scaledCharInfo[glyph].segs[i].y2 -
lineDrawFont->ascent;
}
(void) XDrawSegments(display, /* Display */
d, /* dest */
gc, /* GC */
segs, /* segments */
lineDrawFont->scaledCharInfo[glyph].numSegs);
/* num segs */
}
if (lineDrawFont->scaledCharInfo[glyph].numRects > 0) {
for (i = 0; i < lineDrawFont->scaledCharInfo[glyph].numRects; i++) {
rects[i].x = x + lineDrawFont->scaledCharInfo[glyph].rects[i].x;
rects[i].y =
y + lineDrawFont->scaledCharInfo[glyph].rects[i].y -
lineDrawFont->ascent;
rects[i].width =
lineDrawFont->scaledCharInfo[glyph].rects[i].width;
rects[i].height =
lineDrawFont->scaledCharInfo[glyph].rects[i].height;
}
(void) XFillRectangles(display, /* Display */
d, /* dest */
gc, /* GC */
rects, /* rectangles */
lineDrawFont->scaledCharInfo[glyph].numRects);
/* num rects */
}
#endif /* USE_PIXMAPS */
/* slide over one character... */
x += lineDrawFont->width;
}
_DtTermProcessUnlock();
return;
}

View File

@@ -0,0 +1,21 @@
/*
* $XConsortium: TermPrimLineDraw.h /main/1 1996/04/21 19:17:51 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimLineDraw_h
#define _Dt_TermPrimLineDraw_h
typedef struct _LineDrawFontRec *LineDrawFont;
LineDrawFont _DtTermPrimLineDrawCreateFont(Widget w, GlyphInfo glyphInfo,
int numGlyphs, int width, int ascent, int descent);
void _DtTermPrimLineDrawFreeFont(LineDrawFont lineDrawFont);
void _DtTermPrimLineDrawImageString(Display *display, Drawable d,
LineDrawFont lineDrawFont,
GC gc, GC clearGC, int x, int y, unsigned char *string, int length);
#endif /* _Dt_TermPrimLineDraw_h */

View File

@@ -0,0 +1,63 @@
/*
* $XConsortium: TermPrimLineDrawP.h /main/1 1996/04/21 19:17:54 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimLineDrawP_h
#define _Dt_TermPrimLineDrawP_h
#include "TermPrimLineDraw.h"
typedef short cellPositionType;
typedef char segNumType;
#ifdef USE_PIXMAPS
typedef struct _ScaledBitmapInfoRec {
Boolean scaled;
cellPositionType cellX;
cellPositionType cellY;
} ScaledBitmapInfoRec, *ScaledBitmapInfo;
#else /* USE_PIXMAPS */
typedef struct _ScaledCharInfoRec {
Boolean scaled;
XSegment *segs;
segNumType numSegs;
XRectangle *rects;
segNumType numRects;
XRectangle *stipples;
segNumType numStipples;
} ScaledCharInfoRec, *ScaledCharInfo;
#endif /* USE_PIXMAPS */
/* we will create a linked list of font Data... */
typedef struct _LineDrawFontDataRec {
GlyphInfo glyphInfo;
int numGlyphs;
short lineDrawIndex[256];
struct _LineDrawFontDataRec *next;
} LineDrawFontDataRec, *LineDrawFontData;
typedef struct _LineDrawFontRec {
int refCount;
int width;
int height;
int ascent;
Boolean fontValid;
Pixmap pixmap;
Display *display;
GlyphInfo glyphInfo;
int numGlyphs;
short *glyphIndex;
#ifdef USE_PIXMAPS
ScaledBitmapInfo scaledBitmapInfo;
#else /* USE_PIXMAPS */
ScaledCharInfo scaledCharInfo;
#endif /* USE_PIXMAPS */
struct _LineDrawFontRec *next;
} LineDrawFontRec;
#endif /* _Dt_TermPrimLineDrawP_h */

View File

@@ -0,0 +1,16 @@
/*
* $XConsortium: TermPrimLineFont.h /main/1 1996/04/21 19:17:57 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimLineFont_h
#define _Dt_TermPrimLineFont_h
typedef struct _GlyphInfoRec *GlyphInfo;
#endif /* _Dt_TermPrimLineFont_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,51 @@
/*
* $XConsortium: TermPrimLineFontP.h /main/1 1996/04/21 19:18:00 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimLineFontP_h
#define _Dt_TermPrimLineFontP_h
#include "TermPrimLineFont.h"
typedef char charType;
typedef struct {
char x1;
signed char x1Offset;
char y1;
signed char y1Offset;
char x2;
signed char x2Offset;
char y2;
signed char y2Offset;
char width;
} line;
typedef struct {
char x1;
signed char x1Offset;
char y1;
signed char y1Offset;
char x2;
signed char x2Offset;
char y2;
signed char y2Offset;
} rect;
typedef struct _GlyphInfoRec {
charType *chars;
rect *rects;
char numRects;
line *lines;
char numLines;
line *stipples;
char numStipples;
} GlyphInfoRec;
#endif /* _Dt_TermPrimLineFontP_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,48 @@
/*
* $XConsortium: TermPrimMessageCatI.h /main/2 1996/09/14 14:46:32 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimMessageCatI_h
#define _Dt_TermPrimMessageCatI_h
/*
* macro to get message catalog strings
* This is for dtterm only.
* The set number is for the file e.g. NL_SETN_Syntax is used by
* DtTermSyntax.c.
*/
#include "TermPrimOSDepI.h" /* for NO_MESSAGE_CATALOG */
#define NL_SETN_Main 1
#define NL_SETN_Syntax 2
#define NL_SETN_Function 3
#define NL_SETN_Prim 4
#define NL_SETN_PrimRend 5
#define NL_SETN_View 6
#define NL_SETN_ViewGlobalDialog 7
#define NL_SETN_ViewMenu 8
#define NL_SETN_ViewTerminalDialog 9
#ifndef NO_MESSAGE_CATALOG
extern char *_DtTermPrimGetMessage( char *filename, int set, int n, char *s );
# ifdef __ultrix
# define _CLIENT_CAT_NAME "dtterm.cat"
# else /* __ultrix */
# define _CLIENT_CAT_NAME "dtterm"
# endif /* __ultrix */
# define GETMESSAGE(set, number, string)\
_DtTermPrimGetMessage(_CLIENT_CAT_NAME, set, number, string)
#else
# define GETMESSAGE(set, number, string)\
string
#endif
#endif /* _Dt_TermPrimMessageCatI_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,115 @@
/*
* $TOG: TermPrimOSDepI.h /main/4 1998/03/16 14:41:55 mgreess $";
*/
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
/******************************************************************************
this is a list of OS dependent defines that are available...
XOR_CAPS_LOCK xor caps lock and shift so that lock+shift
acts as a noop for alpha keys
NO_MESSAGE_CATALOG enables the message catalog code
USE_TIOCCONS use TIOCCONS iocto for -C option
USE_SRIOCSREDIR use SRIOCSREDIR ioctl for -C option
SETENV_LINES_AND_COLS set $LINES and $COLUMNS
HAS_SETRESUID os supports setresuid(2) - first choice
HAS_SETEUID os supports seteuid(2) - second choice
HAS_SETREUID os supports setreuid(2) - second choice
USE_STREAMS use streams as opposed to ptys - first choice
USE_STREAMS_TTCOMPAT use ttcompat streams mod
USE_STREAMS_BUFMOD use bofmod streams mod
USE_PTYS use ptys - second choice
USE_CSWIDTH use the csWidth resource to initialize
multi-byte processing in ldterm
USE_SETCSMAP use setcsmap() for multi-byte processing
USE_SUN_WCWIDTH_PATCH use SUN wcwidth() workaround
USE_TIOCBREAK use TIOCBREAK ioctl() to send RS232 break
USE_TCSBRK use TCBRK ioctl() to send RS232 break
USE_TCSBREAK use TCBREAK ioctl() to send RS232 break
USE_TCSENDBREAK use tiocbreak() to send RS232 break
******************************************************************************/
#ifndef _Dt_TermPrimOSDepI_h
#define _Dt_TermPrimOSDepI_h
#ifdef ALPHA_ARCHITECTURE
# define USE_TIOCCONS /* use tioccons for -C */
# define HAS_SETEUID /* seteuid available */
# define HAS_SETREUID /* setreuid available */
# define USE_PTYS /* use ptys */
# define USE_TCSBRK /* use TCSBRK ioctl() */
#endif /* ALPHA_ARCHITECTURE */
#ifdef HP_ARCHITECTURE
# define XOR_CAPS_LOCK /* xor caps lock and shift */
# define USE_TIOCCONS /* use tioccons for -C */
# define SETENV_LINES_AND_COLS /* set $LINES and $COLUMNS */
# define HAS_SETRESUID /* setresuid available */
# if OSMAJORVERSION > 9
# define USE_STREAMS /* use streams */
# define USE_CSWIDTH /* use the csWidth resource to */
/* initialize multi-byte processing */
/* in ldterm */
# define USE_TCSENDBREAK /* use tiocbreak() */
# else /* OSMAJORVERSION > 9 */
# define USE_PTYS /* use ptys */
# define USE_TIOCBREAK /* use TIOCBREAK ioctl() */
# endif /* OSMAJORVERSION > 9 */
#endif /* HP_ARCHITECTURE */
#ifdef LINUX_ARCHITECTURE
# define USE_TIOCCONS /* use tioccons for -C */
# define HAS_SETEUID /* seteuid available */
# define HAS_SETREUID /* setreuid available */
# define USE_TCSENDBREAK /* use tiocbreak() */
#endif /* LINUX_ARCHITECTURE */
#ifdef SUN_ARCHITECTURE
# define XOR_CAPS_LOCK /* xor caps lock and shift */
# define USE_SRIOCSREDIR /* use SRIOCSREDIR ioctl for -C */
# define USE_STREAMS /* use streams */
# define USE_STREAMS_TTCOMPAT /* use ttcompat streams mod */
# define USE_STREAMS_BUFMOD /* use bofmod streams mod */
# define USE_TCSENDBREAK /* use tiocbreak() */
# if (_XOPEN_VERSION == 3)
# define USE_SUN_WCWIDTH_PATCH
# define wcwidth(w) sun_wcwidth(w)
# endif /* (_XOPEN_VERSION == 3) */
#endif /* SUN_ARCHITECTURE */
#ifdef IBM_ARCHITECTURE
/* this seems to be #define'ed in the world of imake... */
# define USE_TIOCCONS /* use tioccons for -C */
# define HAS_SETEUID /* seteuid available */
# define HAS_SETREUID /* setreuid available */
# define USE_PTYS /* use ptys */
# define USE_SETCSMAP /* use setcsmap() for multi-byte*/
# define USE_TCSENDBREAK /* use tiocbreak() */
#endif /* IBM_ARCHITECTURE */
#ifdef USL_ARCHITECTURE
# define XOR_CAPS_LOCK /* xor caps lock and shift */
# define USE_STREAMS /* use streams */
# define USE_STREAMS_TTCOMPAT /* use ttcompat streams mod */
# define USE_TCSENDBREAK /* use tiocbreak() */
#endif /* USL_ARCHITECTURE */
#ifdef UXP_ARCHITECTURE
# define XOR_CAPS_LOCK /* xor caps lock and shift */
# define USE_STREAMS /* use streams */
# define USE_STREAMS_TTCOMPAT /* use ttcompat streams mod */
# define USE_TCSENDBREAK /* use tiocbreak() */
#endif /* UXP_ARCHITECTURE */
#endif /* _Dt_TermPrimOSDepI_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,207 @@
/*
* $XConsortium: TermPrimP.h /main/1 1996/04/21 19:18:08 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimP_h
#define _Dt_TermPrimP_h
#include <Xm/LabelP.h>
#include "TermPrim.h"
#include "TermPrimData.h"
/* include the other internal Term include files...
*/
#include "TermPrimScroll.h"
#include "TermPrimRender.h"
#include "TermPrimCursor.h"
#include "TermPrimLineFont.h"
#include "TermPrimBuffer.h"
#include "TermPrimSubproc.h"
/*
** Now we can choose what shell we want
** NOTE:
** (is it worth making resources for defaultShell
** and defaultShellArgv0?) JRM
*/
#ifdef hpV4
# define DEFAULT_SHELL "/usr/bin/sh"
# define DEFAULT_SHELL_ARGV0 "sh"
#else /* hpV4 */
# define DEFAULT_SHELL "/bin/sh"
# define DEFAULT_SHELL_ARGV0 "sh"
#endif /* hpV4 */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* term class structure... */
typedef int
(*TermInsertProc)
(
Widget w,
unsigned char *buffer,
int length
);
typedef struct _DtTermPrimitiveClassPart
{
StateTable *parser_start_state;
Boolean use_history_buffer;
Boolean allow_scroll_below_buffer;
Boolean wrap_right_after_insert;
BufferCreateProc buffer_create_proc;
BufferFreeProc buffer_free_proc;
TermInsertProc term_insert_proc;
short sizeOfBuffer;
short sizeOfLine;
short sizeOfEnh;
} DtTermPrimitiveClassPart;
/* full class record declaration for Term class... */
typedef struct _DtTermPrimitiveClassRec {
CoreClassPart core_class;
XmPrimitiveClassPart primitive_class;
DtTermPrimitiveClassPart term_primitive_class;
} DtTermPrimitiveClassRec;
externalref DtTermPrimitiveClassRec dtTermPrimitiveClassRec;
/* term instance record... */
typedef struct _DtTermPrimitivePart
{
struct termData *tpd; /* non-widget terminal data */
Widget verticalScrollBar; /* vertical sb to update/track */
short verticalScrollBarValue; /* cached sb value */
short verticalScrollBarMaximum; /* cached sb maximum */
short verticalScrollBarSliderSize; /* cached sb size */
short verticalScrollBarPageIncrement;
/* cached sb page inc */
unsigned char charCursorStyle; /* cursor style: bar or box */
int blinkRate; /* cursor blink rate (0 == no
* blink
*/
Boolean consoleMode; /* true == get console output */
Boolean backgroundIsSelect; /* true == background is select
* color
*/
Boolean visualBell; /* true == visual bell */
Boolean marginBell; /* true == rt margin waring bell*/
int nMarginBell; /* warning bell distance */
Boolean jumpScroll; /* true == jumpscroll,
* false == line by line scroll
*/
Boolean hasFocus; /* true == window has focus
* (and the cursor blinks)
*/
char *emulationId; /* $TERMINAL_EMULATOR variable */
char *termId; /* term ID string for esc seq */
char *termName; /* $TERM string */
char *ttyModes; /* ttyModes string */
char *csWidth; /* csWidth string */
unsigned char shadowType; /* shadow type for term window */
XmFontList fontList; /* fontList for base font */
XmFontList boldFontList; /* fontList for bold font */
XFontStruct *font; /* font for base font */
XFontStruct *boldFont; /* font for bold font */
XFontSet fontSet; /* fontSet generated from either
* the fontList or the font above
*/
XFontSet boldFontSet; /* fontSet generated from either
* the boldFontList or the boldFont
* above
*/
Boolean haveFontSet; /* true == we have a valid fontSet
*/
char *saveLines; /* save lines or screens */
short rows; /* rows of displayed term win */
short columns; /* columns of term win & memory */
Dimension marginHeight; /* width of window's margin */
Dimension marginWidth; /* height of window's margin */
int baseWidth; /* base width for size hints */
int baseHeight; /* base height for size hints */
int widthInc; /* width inc for size hints */
int heightInc; /* height inc for size hints */
int ascent; /* ascent for font */
int pty; /* file descriptor of pty */
Boolean ptyAllocate; /* true, allocate a pty */
char *ptySlaveName; /* name of pty slave device */
int subprocessPid; /* process id of child (shell)
* process
*/
char *subprocessCWD; /* subprocess working directory */
char *subprocessCmd; /* subprocess cmd to exec */
char **subprocessArgv; /* argv to pass to above cmd */
Boolean subprocessLoginShell; /* if true, prepend argv[0] with
* a '-'
*/
Boolean subprocessTerminationCatch; /* if true, catch child exit() */
Boolean subprocessExec; /* if true, exec subprocess */
_termSubprocId subprocessId; /* id of subprocess as returned
* by the subprocess code.
*/
XtCallbackList inputVerifyCallback; /* callback invoked when keyboard
* input or selection input is
* received.
*/
XtCallbackList outputLogCallback; /* callback invoked when pty output
* is received.
*/
XtCallbackList statusChangeCallback;/* callback invoked when there is
* some sort of status change
* (cursor motion, capsLockChange,
* outputStopped, etc). Reason
* indicates which has changed.
*/
XtCallbackList subprocessTerminationCallback;
/* callback invoked by subprocess
* termination (exit())
*/
Boolean kshMode; /* use meta for escape */
Boolean pointerBlank; /* blank pointer after */
int pointerBlankDelay; /* pointerBlankDelay secs */
Cursor pointerShape; /* pointer pixmap */
Pixel pointerColor; /* pointer color */
Pixel pointerColorBackground; /* pointer background color */
Boolean mapOnOutput; /* map term on pty output after */
int mapOnOutputDelay; /* mapOnOutputDelay secs */
Boolean logging; /* copy tty output to file/pipe */
Boolean log_on; /* is log file (pipe) open? */
char * logFile; /* named logFile (default "logFile"*/
Boolean logInhibit; /* don't allow logging */
Boolean reverseVideo; /* true, reverse video on */
uid_t euid_root; /* suid */
uid_t euid_user; /* user id */
Boolean allowSendEvents; /* allow key, button presses */
Boolean allowOsfKeysyms; /* allow osfKeysyms through */
} DtTermPrimitivePart;
/* full instance record declaration... */
typedef struct _DtTermPrimitiveRec {
CorePart core;
XmPrimitivePart primitive;
DtTermPrimitivePart term;
} DtTermPrimitiveRec;
/* private function declarations... */
/* end private function declarations... */
#ifdef __cplusplus
} /* close scope of 'extern "C"'... */
#endif /* __cplusplus */
/*
** Some handy macros.
*/
#define GetParserContext(w) (((DtTermPrimitiveWidget)w)->term.tpd->context)
#endif /* _Dt_TermPrimP_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,222 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimParse.c /main/1 1996/04/21 19:18:12 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#include "TermHeader.h"
#include "TermPrimDebug.h"
#include "TermPrimP.h"
#include "TermPrimData.h"
#include "TermPrimBuffer.h"
#include "TermPrimParseTable.h"
#include "TermPrimFunction.h"
/******************************************************************************
*
* #### ##### # ######
* # # # # # #
* # # # ### # ##### ###
* # ##### ### # # ###
* # # # # # # # #
* #### # # # ###### # #
*
*
* ##### #### ##### ## #####
* # # # # # # # #
* ##### #### ### # # # #####
* # # # ### # ###### # #
* # # # # # # # # # #
* ##### #### # # # # #####
*/
void
_DtTermPrimParseLF
(
Widget w
)
{
(void) _DtTermPrimFuncLF(w, 1, fromParser);
return;
}
void
_DtTermPrimParseBackspace(Widget w)
{
(void) _DtTermPrimFuncBackspace(w, 1, fromParser);
return;
}
void
_DtTermPrimParseTab(Widget w)
{
(void) _DtTermPrimFuncTab(w, 1, fromParser);
return;
}
void
_DtTermPrimParseCR
(
Widget w
)
{
(void) _DtTermPrimFuncCR(w, 1, fromParser);
return;
}
void
_DtTermPrimParseBell(Widget w)
{
(void) _DtTermPrimBell(w);
return;
}
/*** CURSOR MOTION ************************************************************
*
* #### # # ##### #### #### #####
* # # # # # # # # # # #
* # # # # # #### # # # #
* # # # ##### # # # #####
* # # # # # # # # # # # #
* #### #### # # #### #### # #
*
*
* # # #### ##### # #### # #
* ## ## # # # # # # ## #
* # ## # # # # # # # # # #
* # # # # # # # # # # #
* # # # # # # # # # ##
* # # #### # # #### # #
*/
void
_DtTermPrimParseCursorRight(Widget w)
{
(void) _DtTermPrimFuncForwardCharacter(w, 1, fromParser);
return;
}
void
_DtTermPrimParseCursorLeft(Widget w)
{
(void) _DtTermPrimFuncBackwardCharacter(w, 1, fromParser);
return;
}
void
_DtTermPrimParseCursorDown(Widget w)
{
(void) _DtTermPrimFuncNextLine(w, 1, fromParser);
return;
}
void
_DtTermPrimParseCursorUp(Widget w)
{
(void) _DtTermPrimFuncPreviousLine(w, 1, fromParser);
return;
}
/*** TAB FUNCTIONS ************************************************************
*
* ##### ## #####
* # # # # #
* # # # #####
* # ###### # #
* # # # # #
* # # # #####
*
*
* ###### # # # # #### ##### # #### # # ####
* # # # ## # # # # # # # ## # #
* ##### # # # # # # # # # # # # # ####
* # # # # # # # # # # # # # # #
* # # # # ## # # # # # # # ## # #
* # #### # # #### # # #### # # ####
*/
void
_DtTermPrimParseTabSet(Widget w)
{
(void) _DtTermPrimFuncTabSet(w, 1, fromParser);
return;
}
void
_DtTermPrimParseTabClear(Widget w)
{
(void) _DtTermPrimFuncTabClear(w, 1, fromParser);
return;
}
void
_DtTermPrimParseTabClearAll(Widget w)
{
(void) _DtTermPrimFuncTabClearAll(w, 1, fromParser);
return;
}
/*** MARGIN FUNCTION **********************************************************
*
* # # ## ##### #### # # #
* ## ## # # # # # # # ## #
* # ## # # # # # # # # # #
* # # ###### ##### # ### # # # #
* # # # # # # # # # # ##
* # # # # # # #### # # #
*
*
* ###### # # # # #### ##### # #### # # ####
* # # # ## # # # # # # # ## # #
* ##### # # # # # # # # # # # # # ####
* # # # # # # # # # # # # # # #
* # # # # ## # # # # # # # ## # #
* # #### # # #### # # #### # # ####
*/
void
_DtTermPrimParseMarginSetLeft(Widget w)
{
(void) _DtTermPrimFuncMarginSetLeft(w, 1, fromParser);
return;
}
void
_DtTermPrimParseMarginSetRight(Widget w)
{
(void) _DtTermPrimFuncMarginSetRight(w, 1, fromParser);
return;
}
void
_DtTermPrimParseMarginClear(Widget w)
{
(void) _DtTermPrimFuncMarginClear(w, 1, fromParser);
return;
}
/*
** _DtTermPrimParseWriteChar
**
** this should never be called
*/
void
_DtTermPrimParseWriteChar
(
Widget w
)
{
fprintf(stdout, "Oops, somehow _DtTermPrimParseWriteChar got called.\n");
}

View File

@@ -0,0 +1,37 @@
/*
** $XConsortium: TermPrimParseTable.c /main/1 1996/04/21 19:18:15 drk $
*/
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#include "TermHeader.h"
#include "TermPrimP.h"
#include "TermPrimParserP.h"
#include "TermPrimParseTable.h"
static StateTableRec stateStart;
/*
** this is the table used when starting from the initial state
*/
static StateEntryRec
startTable[] =
{
0x07, 0x07, &stateStart, _DtTermPrimParseBell, /* ring the bell */
0x08, 0x08, &stateStart, _DtTermPrimParseBackspace, /* backspace */
0x09, 0x09, &stateStart, _DtTermPrimParseTab, /* horizontal tab */
0x0A, 0x0A, &stateStart, _DtTermPrimParseLF, /* newline */
0x0D, 0x0D, &stateStart, _DtTermPrimParseCR, /* carriage return */
0x00, 0xFF, &stateStart, _DtTermPrimParseWriteChar, /* write to dpy */
};
static StateTableRec stateStart = {True, startTable};
StateTable _DtTermPrimStateStart = &stateStart;

View File

@@ -0,0 +1,30 @@
/*
** $XConsortium: TermPrimParseTable.h /main/1 1996/04/21 19:18:18 drk $
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimParseTable_h
#define _Dt_TermPrimParseTable_h
/* state table declarations... */
extern StateTable _DtTermPrimStateStart;
/* parse functions... */
extern void _hpDefaultF(Widget w);
extern void _DtTermPrimParseBell(Widget w);
extern void _DtTermPrimParseBackspace(Widget w);
extern void _DtTermPrimParseTab(Widget w);
extern void _DtTermPrimParseLF(Widget w);
extern void _DtTermPrimParseCR(Widget w);
extern void _DtTermPrimParseWriteChar(Widget w);
#ifdef __cplusplus
} /* close scope of 'extern "C"'... */
#endif /* __cplusplus */
#endif /* _Dt_TermPrimParseTable_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,457 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$TOG: TermPrimParser.c /main/2 1999/10/15 12:23:41 mgreess $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#include "TermPrimDebug.h"
#include "TermPrimP.h"
#include "TermPrimParserP.h"
#include "TermPrimBuffer.h"
#if defined (__hpux)
/*
* On HP MAXINT is defined in both <values.h> and <sys/param.h>
*/
#undef MAXINT
#endif
#include <values.h>
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
static void
ParseTrap()
{
static int count = 0;
(void) count++;
}
/*
** Parse the character, tell the calling routine if we are not
** in the start state.
*/
Boolean
_DtTermPrimParse
(
Widget w,
unsigned char *parseChar,
int parseCharLen
)
{
ParserContext context = GetParserContext(w);
StateEntry thisEntry;
StateEntry thisPreParseEntry;
#ifdef NOCODE
/*
** This decision should be made somewhere else.
*/
if (tp->t_modes.disp_func == 1)
{
in_disp_func();
return(False);
}
#endif /* NOCODE */
if (parseCharLen == 1) {
*context->inputChar = *parseChar;
} else {
(void) memmove(context->inputChar, parseChar, parseCharLen);
}
context->inputCharLen = parseCharLen;
if (isDebugFSet('p', 1)) {
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
static unsigned char debugChar;
static Boolean first = True;
char *c;
if (parseCharLen == 1) {
_DtTermProcessLock();
if (first) {
if (!(c = getenv("dttermDebugParseChar"))) {
c = "0x03";
}
debugChar = strtol(c, (char **) 0, 0);
first = False;
}
_DtTermProcessUnlock();
if (*parseChar == debugChar) {
ParseTrap();
return;
}
}
}
/*
** Determine which state entry to use.
*/
thisPreParseEntry = context->stateTable->statePreParseEntry;
thisEntry = context->stateTable->stateEntry;
/* first run through the preParse entry... */
if (thisPreParseEntry && (parseCharLen == 1)) {
while ((*parseChar < thisPreParseEntry->lower) ||
(*parseChar > thisPreParseEntry->upper)) {
thisPreParseEntry++;
}
/* if we hit the end, ignore it... */
if ((0x00 == thisPreParseEntry->lower) &&
(0xff == thisPreParseEntry->upper)) {
thisPreParseEntry = (StateEntry) 0;
}
}
/* if we hit a valid preParseEntry, then let's execute it and
* return...
*/
if (thisPreParseEntry) {
/*
** Now change states. If the next state is NULL, stay in the
** current state. This is for parse entries that do not break us
** out of the current parse thread. If we need to bail out of the
** current parse thread, then we have a new state specified and
** will switch to it. We do this before we execute the function
** incase the function needs to change the state as well...
*/
if (thisPreParseEntry->nextState) {
context->stateTable = thisPreParseEntry->nextState;
}
/*
** Execute the action associated with the entry.
*/
if (thisPreParseEntry->action) {
(*thisPreParseEntry->action)(w);
}
return(!context->stateTable->startState);
}
/* HACK ALERT!!!!
*
* We need two different search algorithms - the first to deal
* with single byte characters, the second to deal with multi-byte
* characters. For now, we will match multi-byte character with
* the parse entry that covers 0..255. If we find that this will
* not work for everything, we may need to rethink this.
*/
if (parseCharLen == 1) {
while ((*parseChar < thisEntry->lower) ||
(*parseChar > thisEntry->upper))
{
thisEntry++;
}
} else {
while ((0x00 != thisEntry->lower) ||
(0xff != thisEntry->upper))
{
thisEntry++;
}
}
/*
** Now change states. We do this before we execute the function incase
** the function needs to change the state as well...
*/
context->stateTable = thisEntry->nextState;
/*
** Execute the action associated with the entry.
*/
if (thisEntry->action) {
(*thisEntry->action)(w);
}
return(!context->stateTable->startState);
}
/*
**
** _DtTermPrimParserClrStrParm()
**
** clrStrParm clears the string parameters.
**
*/
void
_DtTermPrimParserClrStrParm
(
Widget w
)
{
ParserContext context = GetParserContext(w);
context->stringParms[0].length = 0;
(void) memset(context->stringParms[0].str, 0x00, STR_SIZE + 1);
context->stringParms[1].length = 0;
(void) memset(context->stringParms[1].str, 0x00, STR_SIZE + 1);
}
/*
**
** _DtTermPrimParserNextState()
**
** nextState is a do nothing routine. It is called when the only
** action that needs to be preformed is changing states in the
** state machine.
**
*/
void
_DtTermPrimParserNextState
(
Widget w
)
{
}
/*
**
** _DtTermPrimParserClearParm()
**
** _DtTermPrimParserClearParm clears all common parameters.
**
*/
void
_DtTermPrimParserClearParm
(
Widget w
)
{
ParserContext context = GetParserContext(w);
int i;
for (i = 0; i < NUM_PARMS; i++) {
context->parms[i] = 0;
}
context->workingNum = 0;
context->workingNumIsDefault = True;
context->sign = TermPARSER_SIGNnone;
}
/*
**
** enterNum()
**
** enterNum enters a numerical parameter.
**
*/
void
_DtTermPrimParserEnterNum
(
Widget w
)
{
ParserContext context = GetParserContext(w);
if ( context->workingNum < MAXINT>>4 )
context->workingNum = context->workingNum * 10 +
(*context->inputChar - '0');
context->workingNumIsDefault = False;
}
void
_DtTermPrimParserSaveSign
(
Widget w
)
{
ParserContext context = GetParserContext(w);
SetSign(context, (*GetInputChar(context) == '-') ? TermPARSER_SIGNnegative :
TermPARSER_SIGNpositive);
}
/*
**
** _DtTermPrimParserNumParmPush()
**
** _DtTermPrimParserNumParmPush() takes the number in workingNum and
** stores it in parm[parmNum].
**
*/
void
_DtTermPrimParserNumParmPush
(
Widget w,
int parmNum
)
{
ParserContext context = GetParserContext(w);
if ( parmNum < NUM_PARMS ) {
context->parms[parmNum] = context->workingNum;
context->workingNum = 0;
context->workingNumIsDefault = False;
}
}
/*
** Initialize the context of the parser.
*/
void
_DtTermPrimParserInitContext
(
Widget w
)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
DtTermPrimData tpd = tw->term.tpd;
tpd->context = (ParserContext) XtMalloc(sizeof(ParserContextRec));
(void) memset(tpd->context, '\0', sizeof(ParserContextRec));
tpd->context->stateTable =
*(((DtTermPrimitiveClassRec *) (tw->core.widget_class))->
term_primitive_class.parser_start_state);
tpd->context->stateName = START;
}
#ifdef TEST
#include <ctype.h>
#define testFunction(f) \
void f ( Widget w ) {printf(#f " called.\n");}
int cursor_col, cursor_row;
int logical_col, logical_row;
testFunction(_termCR)
testFunction(_termLF)
testFunction(_termTab)
testFunction(_termBackspace)
testFunction(RecordDC1Rcvd)
testFunction(_termWriteChar)
testFunction(_DtTermPrimBell)
testFunction(_termShiftOut)
testFunction(_termShiftIn)
testFunction(set_tab)
testFunction(clear_tab)
testFunction(clr_all_tab)
testFunction(set_left_marg)
testFunction(set_right_marg)
testFunction(clear_marg)
testFunction(curs_up)
testFunction(curs_down)
testFunction(curs_right)
testFunction(curs_left)
testFunction(home_down)
testFunction(home_up)
testFunction(clr_display)
testFunction(clear_line)
testFunction(insert_line)
testFunction(delete_line)
testFunction(delete_char)
testFunction(insert_char)
testFunction(off_insert_char)
testFunction(roll_up)
testFunction(roll_down)
testFunction(next_page)
testFunction(prev_page)
testFunction(format_mode_on)
testFunction(format_mode_off)
testFunction(display_func)
testFunction(term_status)
testFunction(rel_curs_pos)
testFunction(abs_curs_pos)
testFunction(enable_key)
testFunction(disable_key)
testFunction(enter_line)
testFunction(back_tab)
testFunction(user_key_menu_on)
testFunction(user_key_menu_off)
testFunction(second_status)
testFunction(mlock_on)
testFunction(mlock_off)
testFunction(start_unprotect)
testFunction(stop_field)
void
_parserPrintContext
(
ParserContext context
)
{
printf(" inputChar : ");
if (isprint(*context->inputChar))
{
printf("'%c'\n", *context->inputChar);
}
else
{
printf("\x2X\n", *context->inputChar);
}
for (i = 0; i < 9; i++)
{
printf(" parm[%d] : %d\n", i, context->parm[i]);
}
printf(" workingNum : %d\n", context->workingNum);
}
void
parseString
(
Widget w;
unsigned char *string
)
{
ParserContext context = GetParserContext(w);
int i;
_parserPrintContext(context);
for (i = 0; i < strlen((char *)string); i++)
{
_DtTermPrimParse(context, string[i]);
_parserPrintContext(context);
}
}
/* the following is to allow for a single main function in the code... */
#define parserMain main
parserMain()
{
parserContext context;
_parserInitContext(&context);
cursor_col = 0;
cursor_row = 0;
logical_col = 5;
logical_row = 5;
printf("\nparsing <esc>&a5r5C\n");
parseString(&context, (unsigned char *)"\033&a5r5C");
printf("\nparsing <esc>a5r35C\n");
parseString(&context, (unsigned char *)"\033&a5r35C");
printf("\nparsing <esc>&a5r3r4c5C\n");
parseString(&context, (unsigned char *)"\033&a5r3r4c5C");
printf("\nparsing <esc>&arC\n");
parseString(&context, (unsigned char *)"\033&arC");
printf("\nparsing <esc>&a5C\n");
parseString(&context, (unsigned char *)"\033&a5C");
printf("\nparsing <esc>&a+5C\n");
parseString(&context, (unsigned char *)"\033&a+5C");
}
#endif /* TEST */

View File

@@ -0,0 +1,42 @@
/*
** $XConsortium: TermPrimParser.h /main/1 1996/04/21 19:18:24 drk $
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimParser_h
#define _Dt_TermPrimParser_h
typedef struct _StateTableRec *StateTable;
typedef struct _ParserContextRec *ParserContext;
extern void
_DtTermPrimParserInitContext
(
Widget w
);
extern Boolean
_DtTermPrimParse
(
Widget w,
unsigned char *parseChar,
int parseCharLength
);
extern void
_DtTermPrimParserNumParmPush
(
Widget w,
int parmNum
);
#ifdef __cplusplus
} /* close scope of 'extern "C"'... */
#endif /* __cplusplus */
#endif /* _Dt_TermPrimParser_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,162 @@
/*
** $XConsortium: TermPrimParserP.h /main/1 1996/04/21 19:18:27 drk $
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimParserP_h
#define _Dt_TermPrimParserP_h
#include "TermPrimParser.h"
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef enum _TermParserSign
{
TermPARSER_SIGNnone = 0,
TermPARSER_SIGNnegative,
TermPARSER_SIGNpositive
} TermParserSign;
#define GetInputChar(context) ((context)->inputChar)
#define GetWorkingNum(context) ((context)->workingNum)
#define GetWorkingNumIsDefault(context) ((context)->workingNumIsDefault)
#define GetSign(context) ((context)->sign)
#define GetParm(context, i) ((context)->parms[i])
#define SetWorkingNum(context, value) (context)->workingNum = (value)
#define SetWorkingNumIsDefault(context, value) \
(context)->workingNumIsDefault = (value)
#define SetSign(context, value) (context)->sign = (value)
#define SetParm(context, i, value) ((context)->parms[i]) = (value)
/*
** seq - parser state machine transition table
*/
typedef struct _StateEntryRec
{
unsigned char lower; /* lower end of character range */
unsigned char upper; /* upper end of character range */
StateTable nextState; /* next state to enter */
void (*action)(); /* index to next runtime routine */
} StateEntryRec, *StateEntry;
typedef struct _StateTableRec
{
Boolean startState; /* is this a start state? */
StateEntry stateEntry; /* state entry table for state */
StateEntry statePreParseEntry;
/* pre-parse state entry table */
} StateTableRec;
/*
** Maximum length of a softkey definition.
*/
#define STR_SIZE 256
typedef struct _stringParameter
{
unsigned char str[STR_SIZE + 1]; /* buffer for string */
unsigned char length; /* length of str */
} stringParameter;
/*
** states in escape sequence parsing
*/
typedef enum _parseState
{
START, /* initial state */
ESCAPE, /* saw an escape */
AMP, /* saw an escape & */
AMP_A, /* saw an escape & a */
AMP_A_SIGN, /* saw an ^[&a- or ^[&a+ */
AMP_A_NUM, /* saw an escape & a num */
AMP_D, /* saw an escape & d */
AMP_F, /* saw an escape & f */
AMP_F_NUM, /* saw an escape & f num */
AMP_F_MIN, /* saw an escape & f - */
AMP_F_MIN_NUM, /* saw an escape & f - num */
AMP_F_STR, /* saw an escape & f string */
AMP_J, /* saw an escape & j */
AMP_J_NUM, /* saw an escape & j num */
AMP_J_NUM_L, /* saw an escape & j num L */
AMP_J_NUM_D,
AMP_K, /* saw an escape & k */
AMP_K_NUM, /* saw an escape & k [0-9]* */
AMP_R, /* saw an escape & r */
AMP_R_NUM, /* saw an escape & r num */
AMP_S, /* saw an escape & s */
AMP_S_0, /* saw an escape & s 0 */
AMP_S_1, /* saw an escape & s 1 */
LPAREN, /* saw an escape ( */
RPAREN, /* saw an escape ) */
ASTERISK, /* saw an escape * */
ASTERISK_D, /* saw an escape * d */
ASTERISK_S, /* saw an escape * s */
AMP_P,
AMP_P_NUM,
AMP_P_NUM_W,
AMP_P_W,
ERROR, /* error in escape sequence */
ASTERISK_X, /* saw an escape * x */
ASTERISK_Y, /* saw an escape * y */
ASTERISK_Y_EXC, /* saw an escape * y ! */
AMP_V, /* saw an escape & v */
AMP_V_ZERO, /* saw an escape & v 0 */
AMP_V_ONE, /* saw an escape & v 1 */
AMP_V_2_7, /* saw an escape & v [2-7] */
AMP_V_DEC, /* saw an escape & v . */
AMP_X, /* saw an escape & x */
AMP_X_0, /* saw an escape & x 0 */
AMP_X_1, /* saw an escape & x 1 */
KJCODE /* Kanji State 1/17/86 NY */
} parseState;
#define NUM_PARMS 20
typedef struct _ParserContextRec
{
/*
** escape sequence parsing variables
*/
StateTable stateTable; /* state table of the current state */
unsigned char inputChar[MB_LEN_MAX];
/* character being parsed */
short inputCharLen; /* length of the above */
parseState stateName; /* enum type with current state */
int workingNum; /* working number for entering parm */
Boolean workingNumIsDefault;
/* true if working num not touched */
TermParserSign sign; /* for numeric sign */
int parms[NUM_PARMS]; /* parameters */
stringParameter stringParms[2];
} ParserContextRec;
/*
** Parser support routines.
*/
extern void _DtTermPrimParserSaveSign ( Widget w);
extern void _DtTermPrimParserNextState(Widget w);
extern void _DtTermPrimParserClearParm(Widget w);
extern void _DtTermPrimParserClrStrParm(Widget w);
extern void _DtTermPrimParserEnterNum(Widget w);
extern void _enterMinNum(Widget w);
extern void _DtTermPrimParserParm1(Widget w);
extern void _DtTermPrimParserParm2(Widget w);
extern void _DtTermPrimParserParm3(Widget w);
extern void _DtTermPrimParserParm4(Widget w);
#ifdef __cplusplus
} /* close scope of 'extern "C"'... */
#endif /* __cplusplus */
#endif /* _Dt_TermPrimParserP_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,420 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$TOG: TermPrimPendingText.c /main/3 1997/07/03 15:40:05 samborn $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#include <stdio.h>
#include <X11/Intrinsic.h>
#include "TermHeader.h"
#include "TermPrimDebug.h"
#include "TermPrimPendingTextP.h"
#ifdef __osf__
#include <termios.h>
#include <poll.h>
#endif /* __osf__ */
static
PendingTextChunk
mallocChunk(int len);
#ifdef DEBUG
void
walkPendingText
(
PendingText list
)
{
PendingTextChunk chunk;
fprintf(stderr, "head: %lx\n", list->head);
fprintf(stderr, "tail: %lx\n", list->tail);
for (chunk = list->head; chunk != list->tail; chunk = chunk->next)
{
fprintf(stderr, "chunk: 0x%lx\n", chunk);
fprintf(stderr, " buffer : %c\n", chunk->buffer[0]);
fprintf(stderr, " buffLen: %d\n", chunk->buffLen);
fprintf(stderr, " bufPtr : %c\n", chunk->bufPtr[0]);
fprintf(stderr, " len : %d\n", chunk->len);
fprintf(stderr, " next : 0x%lx\n", chunk->next);
fprintf(stderr, " prev : 0x%lx\n", chunk->prev);
}
}
#endif /* DEBUG */
/*
** Allocate, and initialize a new PendingTextChunk.
*/
static
PendingTextChunk
mallocChunk(int len)
{
PendingTextChunk newChunk;
Debug('q', fprintf(stderr, ">>mallocChunk() starting\n"));
newChunk = (PendingTextChunk) XtMalloc(sizeof(PendingTextChunkRec));
if (!newChunk)
{
return((PendingTextChunk) NULL);
}
newChunk->buffLen = len;
newChunk->buffer = (unsigned char *) XtMalloc(newChunk->buffLen);
if (!newChunk->buffer)
{
XtFree((char *) newChunk);
return((PendingTextChunk) NULL);
}
/*
** Finish initializing the new chunk.
*/
newChunk->bufPtr = newChunk->buffer;
newChunk->len = 0;
newChunk->next = (PendingTextChunk)NULL;
newChunk->prev = (PendingTextChunk)NULL;
return(newChunk);
}
/*
** Add a new pending text chunk to the end of the list. If possible, reuse
** an existing chunk, else allocate a new one. Return true if successful,
** else return false.
*/
PendingTextChunk
_DtTermPrimPendingTextAppendChunk
(
PendingText list,
int len
)
{
PendingTextChunk newChunk;
Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextAppendChunk() starting\n"));
#ifdef DEBUG
walkPendingText(list);
#endif /* DEBUG */
#ifdef RECYCLE_CHUNKS
if (list->free)
{
/*
** There are chunks on the free list, this will
** be easy.
*/
newChunk = list->free;
}
else
{
/*
** We have no free chunks.
*/
newChunk = mallocChunk(len);
if (!newChunk)
{
return(PendingTextChunk(NULL));
}
}
/*
** append the new chunk to the list...
*/
list->free = list->free->next;
newChunk->next = (PendingTextChunk)NULL;
list->tail->next = newChunk;
list->tail = newChunk;
return(True);
#else /* RECYCLE_CHUNKS */
/*
** Create a new chunk.
*/
newChunk = mallocChunk(len);
if (!newChunk)
{
return((PendingTextChunk)NULL);
}
newChunk->next = list->tail;
newChunk->prev = list->tail->prev;
list->tail->prev->next = newChunk;
list->tail->prev = newChunk;
return(newChunk);
#endif /* RECYCLE_CHUNKS */
}
void
_DtTermPrimPendingTextReplace
(
PendingTextChunk chunk,
unsigned char *buffer,
int bufferLen
)
{
chunk->buffer = (unsigned char *) XtRealloc((char *) chunk->buffer,
bufferLen);
chunk->buffLen = bufferLen;
chunk->bufPtr = chunk->buffer;
chunk->len = bufferLen;
(void) memmove(chunk->buffer, buffer, bufferLen);
}
/*
** Remove a pending text chunk from the head of the list, and add it to
** the free list.
*/
void
_DtTermPrimPendingTextRemoveChunk
(
PendingText list,
PendingTextChunk chunk
)
{
Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextRemoveChunk() starting\n"));
#ifdef DEBUG
walkPendingText(list);
#endif /* DEBUG */
/*
** add the chunk to the free list...
*/
/* don't allow removal of either head or tail... */
if ((chunk == list->head) || (chunk == list->tail)) {
return;
}
chunk->prev->next = chunk->next;
chunk->next->prev = chunk->prev;
#ifdef RECYCLE_CHUNKS
chunk->len = 0;
chunk->next = list->free;
list->free = chunk;
#else /* RECYCLE_CHUNKS */
XtFree((char *) chunk->buffer);
XtFree((char *) chunk);
#endif /* RECYCLE_CHUNKS */
}
/* Check to see if there is any pending text in the pending text list...
*/
Boolean
_DtTermPrimPendingTextIsPending
(
PendingText list
)
{
if (list->head->next != list->tail) {
return(True);
}
return(False);
}
/*
** Get a pending text chunk from the head of the list.
*/
PendingTextChunk
_DtTermPrimPendingTextGetChunk
(
PendingText list
)
{
Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextGetChunk() starting\n"));
#ifdef DEBUG
walkPendingText(list);
#endif /* DEBUG */
if (list->head->next != list->tail) {
return(list->head->next);
} else {
return((PendingTextChunk) 0);
}
}
/*
** Flush a pending text list. This function takes the easy way out of
** calling _DtTermPrimPendingTextGetChunk() to get each chunk and
** _DtTermPrimPendingTextRemoveChunk() to remove them.
*/
void
_DtTermPrimPendingTextFlush
(
PendingText list
)
{
PendingTextChunk chunk;
Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextFlush() starting\n"));
#ifdef DEBUG
walkPendingText(list);
#endif /* DEBUG */
while (chunk = _DtTermPrimPendingTextGetChunk(list)) {
(void) _DtTermPrimPendingTextRemoveChunk(list, chunk);
}
}
/*
** Append the supplied text to the pending text list. Return True if
** all text was appended, else return False.
*/
Boolean
_DtTermPrimPendingTextAppend
(
PendingText list,
unsigned char *text,
int len
)
{
PendingTextChunk newChunk;
PendingTextChunk oldTail;
Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextAppend() starting\n"));
#ifdef DEBUG
walkPendingText(list);
#endif /* DEBUG */
/*
** remember this if we are unable to get all the text
** into the list
*/
oldTail = list->tail->prev;
/*
** add a new chunk to the list
*/
while (len > 0)
{
newChunk = _DtTermPrimPendingTextAppendChunk(list,
(len > DEFAULT_CHUNK_BUF_SIZE) ? DEFAULT_CHUNK_BUF_SIZE : len);
if (!newChunk)
{
/*
** the allocation failed, free up all newly created
** chunks and return...
*/
while (oldTail != list->tail->prev)
{
_DtTermPrimPendingTextRemoveChunk(list, list->tail->prev);
}
return(False);
}
/*
** chunk buffers are a fixed size, copy a much as possible
** from 'text' to the chunk buffer, then adjust 'len'...
*/
newChunk->len = MIN(len, newChunk->buffLen);
(void)memcpy(newChunk->buffer, text, newChunk->len);
len -= newChunk->buffLen;
}
return(True);
}
/*
** Write a pending text chunk from the head of the list.
*/
void
_DtTermPrimPendingTextWrite
(
PendingText list,
int fd
)
{
int bytesWritten = 0;
PendingTextChunk chunk;
Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextWrite() starting\n"));
#ifdef DEBUG
walkPendingText(list);
#endif /* DEBUG */
chunk = list->head->next;
Debug('q', fprintf(stderr, ">> len: %3.3d\n", chunk->len));
Debug('q', fprintf(stderr, ">> bufPtr: <%*.*s>\n",
chunk->len, chunk->len, chunk->bufPtr));
bytesWritten = write(fd, chunk->bufPtr, chunk->len <= MAX_PTY_WRITE ?
chunk->len : MAX_PTY_WRITE);
if (bytesWritten < 0) {
#ifdef DEBUG
fprintf(stderr, "_DtTermPrimPendingTextWrite: write failed\n");
#endif
bytesWritten = 0;
}
if ((chunk->len -= bytesWritten) <= 0) {
/*
** All text in this chunk has been written,
** remove it from the list.
*/
_DtTermPrimPendingTextRemoveChunk(list, chunk);
}
else {
/*
** only some of the text in this chunk was written,
** simply adjust the write pointer...
** (list->head->len was adjusted above)
*/
chunk->bufPtr += bytesWritten;
}
}
PendingText
_DtTermPrimPendingTextCreate(
void
)
{
PendingText ptr;
Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextCreate() starting\n"));
ptr = (PendingText) XtMalloc(sizeof(PendingTextRec));
(void) memset(ptr, '\0', sizeof(PendingTextRec));
ptr->head = (PendingTextChunk) XtMalloc(sizeof(PendingTextChunkRec));
(void) memset(ptr->head, '\0', sizeof(PendingTextChunkRec));
ptr->tail = (PendingTextChunk) XtMalloc(sizeof(PendingTextChunkRec));
(void) memset(ptr->tail, '\0', sizeof(PendingTextChunkRec));
ptr->head->next = ptr->tail;
ptr->tail->prev = ptr->head;
#ifdef DEBUG
walkPendingText(ptr);
#endif /* DEBUG */
return(ptr);
}
void
_DtTermPrimPendingTextDestroy(
PendingText ptr
)
{
PendingTextChunk chunk;
Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextDestroy() starting\n"));
#ifdef DEBUG
#undef DEBUG
walkPendingText(ptr);
#endif /* DEBUG */
if (ptr) {
while (ptr->head) {
chunk = ptr->head;
ptr->head = ptr->head->next;
if (chunk->buffer) {
(void) XtFree((char *) chunk->buffer);
}
(void) XtFree((char *) chunk);
}
(void) XtFree((char *) ptr);
}
}

View File

@@ -0,0 +1,107 @@
/*
** $XConsortium: TermPrimPendingText.h /main/1 1996/04/21 19:18:33 drk $
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimPendingText_h
#define _Dt_TermPrimPendingText_h
#include <X11/Intrinsic.h>
#define TextIsPendingWrite(list) (list.head != NULL)
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct _PendingTextChunkRec *PendingTextChunk;
typedef struct _PendingTextRec *PendingText;
extern
Boolean
_DtTermPrimPendingTextIsPending
(
PendingText list
);
extern
PendingTextChunk
_DtTermPrimPendingTextGetChunk
(
PendingText list
);
extern
PendingTextChunk
_DtTermPrimPendingTextAppendChunk
(
PendingText list,
int len
);
extern
void
_DtTermPrimPendingTextReplace
(
PendingTextChunk chunk,
unsigned char *buffer,
int bufferLen
);
extern
void
_DtTermPrimPendingTextRemoveChunk
(
PendingText list,
PendingTextChunk chunk
);
extern
void
_DtTermPrimPendingTextFlush
(
PendingText list
);
extern
Boolean
_DtTermPrimPendingTextAppendText
(
PendingText list,
unsigned char *text,
int len
);
extern
void
_DtTermPrimPendingTextWrite
(
PendingText list,
int fd
);
extern
PendingText
_DtTermPrimPendingTextCreate
(
void
);
extern
void
_DtTermPrimPendingTextDestroy
(
PendingText ptr
);
#ifdef __cplusplus
} /* close scope of 'extern "C"'... */
#endif /* __cplusplus */
#endif /* _Dt_TermPrimPendingText_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,54 @@
/*
** $TOG: TermPrimPendingTextP.h /main/3 1997/07/03 15:40:29 samborn $
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimPendingTextP_h
#define _Dt_TermPrimPendingTextP_h
#include "TermPrimPendingText.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define DEFAULT_CHUNK_BUF_SIZE 1024
#define TextIsPending(list) (list->head->next != list->tail)
typedef struct _PendingTextChunkRec
{
unsigned char *buffer; /* beginning of buffer */
int buffLen; /* length of buffer */
unsigned char *bufPtr; /* text remaining to be processed */
int len; /* bytes remaining to be processed */
PendingTextChunk next; /* next chunk in list */
PendingTextChunk prev; /* prev chunk in list */
} PendingTextChunkRec;
typedef struct _PendingTextRec
{
PendingTextChunk head;
PendingTextChunk tail;
#ifdef RECYCLE_CHUNKS
PendingTextChunk free;
#endif /* RECYCLE_CHUNKS */
} PendingTextRec;
/*
* define the maximum number of character per write for a pty. This
* makes dtterm behave similarly to xterm and dxterm and worksaround
* the pty flow control problems.
*/
#define MAX_PTY_WRITE 128 /* this is 1/2 POSIX minimum MAX_INPUT */
#ifdef __cplusplus
} /* close scope of 'extern "C"'... */
#endif /* __cplusplus */
#endif /* _Dt_TermPrimPendingTextP_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,64 @@
/*
* $XConsortium: TermPrimRender.h /main/1 1996/04/21 19:18:43 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimRender_h
#define _Dt_TermPrimRender_h
typedef struct _TermFontRec *TermFont;
extern void _DtTermPrimRenderText(
Widget w,
TermFont font,
Pixel fg,
Pixel bg,
unsigned long flags,
int x,
int y,
unsigned char *string,
int len
);
extern void _DtTermPrimDestroyFont(
Widget w,
TermFont font
);
extern void _DtTermPrimBell(Widget w);
extern void _termSetRenderFont(Widget w, TermFont *termFont);
extern void _termSetBufferSize(Widget w, int width, int height,
int xOffset, int yOffset);
extern void _termFreeBuffer(Widget w);
extern void _DtTermPrimRefreshText(Widget w,
short startColumn, short startRow,
short endColumn, short endRow);
extern void _DtTermPrimExposeText(Widget w, int startX, int startY, int endX,
int endY, Boolean isExposeEvent);
extern int _DtTermPrimInsertText(Widget w, unsigned char *buffer, int length);
extern int _DtTermPrimInsertTextWc(Widget w, wchar_t *buffer, int length);
extern Boolean
_DtTermPrimParseInput
(
Widget w,
unsigned char *buffer,
int len,
unsigned char **dangleBuffer,
int *dangleBufferLen
);
extern void _DtTermPrimCursorOff(Widget w);
extern void _DtTermPrimCursorOn(Widget w);
extern void _DtTermPrimCursorChangeFocus(Widget w);
extern XtInputCallbackProc _termReadPty(XtPointer client_data, int *source,
XtInputId *id);
extern void _termCompleteScroll(Widget w);
extern void _DtTermPrimFillScreenGap(Widget w);
extern void _DtTermPrimRenderPadLine(Widget w);
#endif /* _Dt_TermPrimRender_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,176 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimRenderFont.c /main/1 1996/04/21 19:18:47 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#include "TermHeader.h"
#include "TermPrimP.h"
#include "TermPrimDebug.h"
#include "TermPrimRenderP.h"
#include "TermPrimRenderFont.h"
static void
FontRenderFunction(
Widget w,
TermFont font,
Pixel fg,
Pixel bg,
unsigned long flags,
int x,
int y,
unsigned char *string,
int len
)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
XGCValues values;
unsigned long valueMask;
XFontStruct *fontStruct = (XFontStruct *) font->fontInfo;
/* set the renderGC... */
valueMask = (unsigned long) 0;
/* set the foreground... */
if (TermIS_SECURE(flags)) {
if (tpd->renderGC.foreground != bg) {
tpd->renderGC.foreground = bg;
values.foreground = bg;
valueMask |= GCForeground;
}
} else {
if (tpd->renderGC.foreground != fg) {
tpd->renderGC.foreground = fg;
values.foreground = fg;
valueMask |= GCForeground;
}
}
/* set background... */
if (tpd->renderGC.background != bg) {
tpd->renderGC.background = bg;
values.background = bg;
valueMask |= GCBackground;
}
/* set the font for renderGC if necessary */
if (tpd->renderGC.fid != fontStruct->fid) {
tpd->renderGC.fid = fontStruct->fid;
values.font = fontStruct->fid;
valueMask |= GCFont;
}
if (valueMask) {
(void) XChangeGC(XtDisplay(w), tpd->renderGC.gc, valueMask,
&values);
}
/* draw image string a line of text... */
if (isDebugFSet('t', 1)) {
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
/* Fill in the text area so we can see what is going to
* be displayed...
*/
(void) XFillRectangle(XtDisplay(w),
XtWindow(w),
tpd->renderGC.gc,
x,
y,
tpd->cellWidth * len,
tpd->cellHeight);
(void) XSync(XtDisplay(w), False);
(void) shortSleep(100000);
}
(void) XDrawImageString(XtDisplay(w), /* Display */
XtWindow(w), /* Drawable */
tpd->renderGC.gc, /* GC */
x, /* x */
y + fontStruct->ascent, /* y */
(char *) string, /* string */
len); /* length */
/* handle overstrike... */
if (TermIS_OVERSTRIKE(flags)) {
(void) XDrawString(XtDisplay(w), /* Display */
XtWindow(w), /* Drawable */
tpd->renderGC.gc, /* GC */
x + 1, /* x */
y + fontStruct->ascent, /* y */
(char *) string, /* string */
len); /* length */
}
/* handle the underline enhancement... */
/* draw the underline... */
if (TermIS_UNDERLINE(flags)) {
XDrawLine(XtDisplay(w), /* Display */
XtWindow(w), /* Window */
tpd->renderGC.gc, /* GC */
x, /* X1 */
y + tpd->cellHeight - 1, /* Y1 */
x + len * tpd->cellWidth, /* X2 */
y + tpd->cellHeight - 1); /* Y2 */
}
}
static void
FontDestroyFunction(
Widget w,
TermFont font
)
{
(void) XtFree((char *) font);
}
static void
FontExtentsFunction(
Widget w,
TermFont font,
unsigned char *string,
int len,
int *widthReturn,
int *heightReturn,
int *ascentReturn
)
{
XFontStruct *fontStruct = (XFontStruct *) font->fontInfo;
if (widthReturn) {
*widthReturn = len * fontStruct->max_bounds.width;
}
if (heightReturn) {
*heightReturn = fontStruct->ascent + fontStruct->descent;
}
if (ascentReturn) {
*ascentReturn = fontStruct->ascent;
}
return;
}
TermFont
_DtTermPrimRenderFontCreate(
Widget w,
XFontStruct *fontStruct
)
{
TermFont termFont;
termFont = (TermFont) XtMalloc(sizeof(TermFontRec));
termFont->renderFunction = FontRenderFunction;
termFont->destroyFunction = FontDestroyFunction;
termFont->extentsFunction = FontExtentsFunction;
termFont->fontInfo = (XtPointer) fontStruct;
return(termFont);
}

View File

@@ -0,0 +1,22 @@
/*
* $XConsortium: TermPrimRenderFont.h /main/1 1996/04/21 19:18:50 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimRenderFont_h
#define _Dt_TermPrimRenderFont_h
#include "TermPrimRender.h"
#include "TermPrimRenderFont.h"
extern TermFont _DtTermPrimRenderFontCreate(
Widget w,
XFontStruct *fontStruct
);
#endif /* _Dt_TermPrimRenderFont_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,234 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimRenderFontSet.c /main/1 1996/04/21 19:18:53 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#include "TermHeader.h"
#include "TermPrimP.h"
#include "TermPrimDebug.h"
#include "TermPrimRenderP.h"
#include "TermPrimRenderFontSet.h"
typedef struct _TermFontSetRec {
XFontSet fontSet;
int ascent;
int height;
int width;
} TermFontSetRec, *TermFontSet;
static void
FontSetRenderFunction(
Widget w,
TermFont font,
Pixel fg,
Pixel bg,
unsigned long flags,
int x,
int y,
unsigned char *string,
int len
)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
XGCValues values;
unsigned long valueMask;
TermFontSet termFontSet = (TermFontSet) font->fontInfo;
/* set the renderGC... */
valueMask = (unsigned long) 0;
/* set the foreground... */
if (TermIS_SECURE(flags)) {
if (tpd->renderGC.foreground != bg) {
tpd->renderGC.foreground = bg;
values.foreground = bg;
valueMask |= GCForeground;
}
} else {
if (tpd->renderGC.foreground != fg) {
tpd->renderGC.foreground = fg;
values.foreground = fg;
valueMask |= GCForeground;
}
}
/* set background... */
if (tpd->renderGC.background != bg) {
tpd->renderGC.background = bg;
values.background = bg;
valueMask |= GCBackground;
}
/* since Xlib will be mucking with the GC's font under us, we need to
* make sure we trash the cached value...
*/
tpd->renderGC.fid = (Font) 0;
if (valueMask) {
(void) XChangeGC(XtDisplay(w), tpd->renderGC.gc, valueMask,
&values);
}
/* draw image string a line of text... */
if (isDebugFSet('t', 1)) {
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
/* Fill in the text area so we can see what is going to
* be displayed...
*/
(void) XFillRectangle(XtDisplay(w),
XtWindow(w),
tpd->renderGC.gc,
x,
y,
(tpd->mbCurMax == 1) ?
XmbTextEscapement(termFontSet->fontSet, (char *) string, len) :
XwcTextEscapement(termFontSet->fontSet, (wchar_t *) string,
len),
tpd->cellHeight);
(void) XSync(XtDisplay(w), False);
(void) shortSleep(100000);
}
if (tpd->mbCurMax == 1)
{
(void) XmbDrawImageString(XtDisplay(w),/* Display */
XtWindow(w), /* Drawable */
termFontSet->fontSet, /* XFontSet */
tpd->renderGC.gc, /* GC */
x, /* x */
y + termFontSet->ascent, /* y */
(char *)string, /* string */
len); /* length */
/* handle overstrike... */
if (TermIS_OVERSTRIKE(flags)) {
(void) XmbDrawString(XtDisplay(w), /* Display */
XtWindow(w), /* Drawable */
termFontSet->fontSet, /* XFontSet */
tpd->renderGC.gc, /* GC */
x + 1, /* x */
y + termFontSet->ascent, /* y */
(char *)string, /* string */
len); /* length */
}
/* handle the underline enhancement... */
/* draw the underline... */
if (TermIS_UNDERLINE(flags)) {
XDrawLine(XtDisplay(w), /* Display */
XtWindow(w), /* Window */
tpd->renderGC.gc, /* GC */
x, /* X1 */
y + tpd->cellHeight - 1, /* Y1 */
x - 1 + XmbTextEscapement(termFontSet->fontSet,
(char *) string, len), /* X2 */
y + tpd->cellHeight - 1);/* Y2 */
}
}
else
{
(void) XwcDrawImageString(XtDisplay(w), /* Display */
XtWindow(w), /* Drawable */
termFontSet->fontSet, /* XFontSet */
tpd->renderGC.gc, /* GC */
x, /* x */
y + termFontSet->ascent, /* y */
(wchar_t *) string, /* string */
len); /* length */
/* handle overstrike... */
if (TermIS_OVERSTRIKE(flags)) {
(void) XwcDrawString(XtDisplay(w), /* Display */
XtWindow(w), /* Drawable */
termFontSet->fontSet, /* XFontSet */
tpd->renderGC.gc, /* GC */
x + 1, /* x */
y + termFontSet->ascent, /* y */
(wchar_t *) string, /* string */
len); /* length */
}
/* handle the underline enhancement... */
/* draw the underline... */
if (TermIS_UNDERLINE(flags)) {
XDrawLine(XtDisplay(w), /* Display */
XtWindow(w), /* Window */
tpd->renderGC.gc, /* GC */
x, /* X1 */
y + tpd->cellHeight - 1, /* Y1 */
x - 1 + XwcTextEscapement(termFontSet->fontSet,
(wchar_t *) string, len), /* X2 */
y + tpd->cellHeight - 1); /* Y2 */
}
}
}
static void
FontSetDestroyFunction(
Widget w,
TermFont font
)
{
(void) XtFree((char *) font->fontInfo);
(void) XtFree((char *) font);
}
static void
FontSetExtentsFunction(
Widget w,
TermFont font,
unsigned char *string,
int len,
int *widthReturn,
int *heightReturn,
int *ascentReturn
)
{
TermFontSet termFontSet = (TermFontSet) font->fontInfo;
if (widthReturn) {
*widthReturn = len * termFontSet->width;
}
if (heightReturn) {
*heightReturn = termFontSet->height;
}
if (ascentReturn) {
*ascentReturn = termFontSet->ascent;
}
return;
}
TermFont
_DtTermPrimRenderFontSetCreate(
Widget w,
XFontSet fontSet
)
{
TermFont termFont;
TermFontSet termFontSet;
XFontSetExtents *fontSetExtents;
termFont = (TermFont) XtMalloc(sizeof(TermFontRec));
termFont->renderFunction = FontSetRenderFunction;
termFont->destroyFunction = FontSetDestroyFunction;
termFont->extentsFunction = FontSetExtentsFunction;
termFontSet = (TermFontSet) XtMalloc(sizeof(TermFontSetRec));
termFontSet->fontSet = fontSet;
fontSetExtents = XExtentsOfFontSet(fontSet);
termFontSet->width = fontSetExtents->max_logical_extent.width;
termFontSet->height = fontSetExtents->max_logical_extent.height;
termFontSet->ascent = -fontSetExtents->max_logical_extent.y;
termFont->fontInfo = (XtPointer) termFontSet;
return(termFont);
}

View File

@@ -0,0 +1,22 @@
/*
* $XConsortium: TermPrimRenderFontSet.h /main/1 1996/04/21 19:18:56 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimRenderFontSet_h
#define _Dt_TermPrimRenderFontSet_h
#include "TermPrimRender.h"
#include "TermPrimRenderFontSet.h"
extern TermFont _DtTermPrimRenderFontSetCreate(
Widget w,
XFontSet fontSet
);
#endif /* _Dt_TermPrimRenderFontSet_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,230 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimRenderLineDraw.c /main/1 1996/04/21 19:18:59 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#include "TermHeader.h"
#include "TermPrimP.h"
#include "TermPrimDebug.h"
#include "TermPrimRenderP.h"
#include "TermPrimRenderLineDraw.h"
#include "TermPrimLineDrawP.h"
static void
LineDrawRenderFunction(
Widget w,
TermFont font,
Pixel fg,
Pixel bg,
unsigned long flags,
int x,
int y,
unsigned char *rawString,
int len
)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
XGCValues values;
unsigned long valueMask;
LineDrawFont lineDrawFont = (LineDrawFont) font->fontInfo;
unsigned char *string;
if (tpd->mbCurMax > 1) {
/* we have a string of wide chars that need to be converted to
* chars...
*/
wchar_t *wPtr;
unsigned char *ptr;
int i1;
unsigned char mbChar[MB_LEN_MAX];
/* we will need to convert 2 column characters to 2 spaces in
* order to preserve character positions...
*/
string = (unsigned char *) XtMalloc(2 * len);
for (ptr = string, wPtr = (wchar_t *) rawString, i1 = 0; i1 < len;
i1++, wPtr++) {
switch (wcwidth(*wPtr)) {
case 1:
if (wctomb((char *) mbChar, *wPtr) == 1) {
*ptr++ = *mbChar;
} else {
*ptr++ = ' ';
}
break;
case 2:
*ptr++ = ' ';
*ptr++ = ' ';
break;
default:
*ptr++ = ' ';
break;
}
}
len = ptr - string;
} else {
string = rawString;
}
/* set the renderGC... */
valueMask = (unsigned long) 0;
/* set the foreground... */
if (TermIS_SECURE(flags)) {
if (tpd->renderGC.foreground != bg) {
tpd->renderGC.foreground = bg;
values.foreground = bg;
valueMask |= GCForeground;
}
} else {
if (tpd->renderGC.foreground != fg) {
tpd->renderGC.foreground = fg;
values.foreground = fg;
valueMask |= GCForeground;
}
}
/* set background... */
if (tpd->renderGC.background != bg) {
tpd->renderGC.background = bg;
values.background = bg;
valueMask |= GCBackground;
}
if (valueMask) {
(void) XChangeGC(XtDisplay(w), tpd->renderGC.gc, valueMask,
&values);
}
/* we need a clear GC as well...
*/
valueMask = (unsigned long) 0;
if (tpd->renderReverseGC.foreground != bg) {
tpd->renderReverseGC.foreground = bg;
values.foreground = bg;
valueMask |= GCForeground;
}
if (valueMask) {
(void) XChangeGC(XtDisplay(w),
tpd->renderReverseGC.gc, valueMask, &values);
}
/* line draw a line of text... */
if (isDebugFSet('t', 1)) {
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
/* Fill in the text area so we can see what is going to
* be displayed...
*/
(void) XFillRectangle(XtDisplay(w),
XtWindow(w),
tpd->renderGC.gc,
x,
y,
tpd->cellWidth * len,
tpd->cellHeight);
(void) XSync(XtDisplay(w), False);
(void) shortSleep(100000);
}
(void) _DtTermPrimLineDrawImageString(
XtDisplay(w), /* Display */
XtWindow(w), /* Drawable */
lineDrawFont, /* LineDrawFont */
tpd->renderGC.gc, /* GC */
tpd->renderReverseGC.gc, /* clearGC */
x, /* x */
y + lineDrawFont->ascent, /* y */
string, /* string */
len); /* length */
/* we don't support overstrike for line draw... */
/* handle the underline enhancement... */
/* draw the underline... */
if (TermIS_UNDERLINE(flags)) {
XDrawLine(XtDisplay(w), /* Display */
XtWindow(w), /* Window */
tpd->renderGC.gc, /* GC */
x, /* X1 */
y + tpd->cellHeight - 1, /* Y1 */
x + len * tpd->cellWidth, /* X2 */
y + tpd->cellHeight - 1); /* Y2 */
}
if (rawString != string) {
(void) XtFree((char *) string);
}
}
static void
LineDrawDestroyFunction(
Widget w,
TermFont font
)
{
LineDrawFont lineDrawFont = (LineDrawFont) font->fontInfo;
(void) _DtTermPrimLineDrawFreeFont(lineDrawFont);
(void) XtFree((char *) font);
}
static void
LineDrawExtentsFunction(
Widget w,
TermFont font,
unsigned char *string,
int len,
int *widthReturn,
int *heightReturn,
int *ascentReturn
)
{
LineDrawFont lineDrawFont = (LineDrawFont) font->fontInfo;
if (widthReturn) {
*widthReturn = len * lineDrawFont->width;
}
if (heightReturn) {
*heightReturn = lineDrawFont->height;
}
if (ascentReturn) {
*ascentReturn = lineDrawFont->ascent;
}
return;
}
TermFont
_DtTermPrimRenderLineDrawCreate(
Widget w,
GlyphInfo glyphInfo,
int numGlyphs,
int width,
int ascent,
int descent
)
{
TermFont termFont;
termFont = (TermFont) XtMalloc(sizeof(TermFontRec));
termFont->renderFunction = LineDrawRenderFunction;
termFont->destroyFunction = LineDrawDestroyFunction;
termFont->extentsFunction = LineDrawExtentsFunction;
termFont->fontInfo =
(XtPointer)_DtTermPrimLineDrawCreateFont(w, glyphInfo, numGlyphs,
width, ascent, descent);
return(termFont);
}

View File

@@ -0,0 +1,25 @@
/*
* $XConsortium: TermPrimRenderLineDraw.h /main/1 1996/04/21 19:19:02 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimRenderLineDraw_h
#define _Dt_TermPrimRenderLineDraw_h
#include "TermPrimRender.h"
extern TermFont _DtTermPrimRenderLineDrawCreate(
Widget w,
GlyphInfo glyphInfo,
int numGlyphs,
int width,
int ascent,
int descent
);
#endif /* _Dt_TermPrimRenderLineDraw_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,884 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimRenderMb.c /main/1 1996/04/21 19:19:05 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
/*
** This file contains the multi-byte character versions of the render routines.
*/
#include "TermHeader.h"
#include "TermPrimDebug.h"
#include "TermPrimP.h"
#include "TermPrimData.h"
#include "TermPrimLineDraw.h"
#include "TermPrimOSDepI.h"
#include "TermPrimBufferP.h"
#include "TermPrimRenderP.h"
#include "TermPrimSelectP.h"
#include <limits.h>
void
_DtTermPrimRefreshTextWc(Widget w, short startColumn, short startRow,
short endColumn, short endRow)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
TermBuffer tBuffer = tpd->termBuffer;
short lineWidth;
short chunkLineWidth;
wchar_t *linePtr;
wchar_t *wc;
TermFont termFont;
int currentColorPair = 0;
int currentVideo = 0;
short chunkStartColumn;
short chunkWidth;
short chunkLength;
short thisStartColumn;
short thisEndColumn;
enhValues enhancements;
int i1;
int lineNum;
unsigned long valueMask;
GC gc;
XGCValues values;
TermEnhInfoRec enhInfo;
Boolean checkSelection = False;
Boolean inSelection;
int selectionEnd;
Pixel tmpPixel;
XmTextPosition begin, end;
TermCharInfoRec startCharInfo;
DebugF('t', 0, fprintf(stderr, ">>_DtTermPrimRefreshTextWc() starting\n"));
DebugF('t', 0, fprintf(stderr,
">>_DtTermPrimRefreshTextWc() startCol=%hd startRow=%hd endCol=%hd endRow=%hd\n",
startColumn, startRow, endColumn, endRow));
/* clip start/end x/y... */
if (startColumn <= 0)
startColumn = 0;
if (startRow <= 0)
startRow = 0;
if (endColumn >= tw->term.columns)
endColumn = tw->term.columns - 1;
if (endRow >= tw->term.rows)
endRow = tw->term.rows - 1;
/*
** don't display if we are in jump scroll and in the process
** of scrolling and inside the scroll region...
*/
if (tw->term.jumpScroll && tpd->scroll.jump.scrolled) {
/* set all the scrollRefreshRows flags... */
for (; startRow <= endRow; startRow++) {
tpd->scrollRefreshRows[startRow] = True;
}
DebugF('t', 0,
fprintf(stderr,
">>_DtTermPrimRefreshTextWc() jump scroll in progress, no render\n"));
return;
}
if (!tpd->renderGC.gc) {
/* get a drawImageString GC... */
int i;
XGCValues values;
/***********************************************************
* renderGC...
*/
/* set the GC fg and bg... */
values.foreground = tw->primitive.foreground;
values.background = tw->core.background_pixel;
tpd->renderGC.gc = XCreateGC(XtDisplay(w), XtWindow(w),
GCForeground | GCBackground, &values);
/* set the GC cache values... */
tpd->renderGC.foreground = values.foreground;
tpd->renderGC.background = values.background;
tpd->renderGC.fid = (Font) 0;
/***********************************************************
* renderReverseGC...
*/
values.foreground = tw->core.background_pixel;
values.background = tw->primitive.foreground;
tpd->renderReverseGC.gc = XCreateGC(XtDisplay(w), XtWindow(w),
GCForeground | GCBackground, &values);
/* set the GC cache values... */
tpd->renderReverseGC.foreground = values.foreground;
tpd->renderReverseGC.background = values.background;
tpd->renderReverseGC.fid = (Font) 0;
/***********************************************************
* clearGC...
*/
values.foreground = tw->core.background_pixel;
values.background = tw->primitive.foreground;
tpd->clearGC.gc = XCreateGC(XtDisplay(w), XtWindow(w),
GCForeground | GCBackground, &values);
/* set the GC cache values... */
tpd->clearGC.foreground = values.foreground;
tpd->clearGC.background = values.background;
tpd->clearGC.fid = (Font) 0;
}
/* clip start/end x/y... */
if (endColumn >= tw->term.columns)
endColumn = tw->term.columns - 1;
if (endRow >= tw->term.rows)
endRow = tw->term.rows - 1;
for (; startRow <= endRow; startRow++) {
/* if we are refreshing a full line, then we can clear the
* scrollRefreshRows flag for this line...
*/
if ((startColumn == 0) && (endColumn >= tw->term.columns - 1)) {
tpd->scrollRefreshRows[startRow] = False;
}
lineNum = startRow + tpd->topRow;
/* are we in the selected area?... */
if (tpd->useHistoryBuffer)
{
if (_DtTermPrimSelectGetSelection(w, &begin, &end) &&
(begin < end) &&
(lineNum >= (begin / (tpd->selectInfo->columns + 1)) -
tpd->lastUsedHistoryRow) &&
(lineNum <= (end / (tpd->selectInfo->columns + 1)) -
tpd->lastUsedHistoryRow)) {
checkSelection = True;
} else {
checkSelection = False;
}
}
else
{
if (_DtTermPrimSelectGetSelection(w, &begin, &end) &&
(begin < end) &&
(lineNum >= (begin / (tpd->selectInfo->columns + 1))) &&
(lineNum <= (end / (tpd->selectInfo->columns + 1)))) {
checkSelection = True;
} else {
checkSelection = False;
}
}
if (startColumn > endColumn) {
/* nothing to render on this line... */
continue;
}
if (lineNum >= tpd->lastUsedRow) {
/* we are pointing to empty screen space below the last used
* line of the display...
*/
lineWidth = 0;
linePtr = (wchar_t) 0;
thisStartColumn = startColumn;
thisEndColumn = endColumn;
} else if (lineNum < 0) {
if ((tpd->useHistoryBuffer) &&
(-lineNum <= tpd->lastUsedHistoryRow)) {
/* get a line out of the history buffer... */
lineWidth = _DtTermPrimBufferGetLineWidth(tpd->historyBuffer,
tpd->lastUsedHistoryRow + lineNum);
if ((startColumn < lineWidth) &&
_DtTermPrimGetCharacterInfo(tpd->historyBuffer,
tpd->lastUsedHistoryRow + lineNum,
startColumn, &startCharInfo)) {
thisStartColumn = startCharInfo.startCol;
} else {
/* past the last character in this line... */
thisStartColumn = startColumn;
}
/* get the line width and a pointer to the data... */
thisEndColumn = endColumn;
lineWidth = MAX(0, MIN(thisEndColumn - thisStartColumn + 1,
lineWidth - startColumn));
linePtr = startCharInfo.u.pwc;
} else {
/* we are above the history buffer. Should not happen, but...
*/
lineWidth = 0;
linePtr = (wchar_t) 0;
}
} else {
/* adjust startColumn to point to the first column for the
* first character...
*/
lineWidth = _DtTermPrimBufferGetLineWidth(tBuffer, lineNum);
if ((startColumn < lineWidth) &&
_DtTermPrimGetCharacterInfo(tBuffer, lineNum, startColumn,
&startCharInfo)) {
thisStartColumn = startCharInfo.startCol;
} else {
/* past the last character in this line... */
thisStartColumn = startColumn;
}
/* get the line width and a pointer to the data... */
thisEndColumn = endColumn;
lineWidth = MAX(0, MIN(thisEndColumn - thisStartColumn + 1,
lineWidth - thisStartColumn));
linePtr = startCharInfo.u.pwc;
}
chunkStartColumn = thisStartColumn;
while (lineWidth > 0) {
/* get the enhancement values for the first chunk of the
* string...
*/
if (lineNum >= 0) {
(void) _DtTermPrimBufferGetEnhancement(tBuffer,
/* TermBuffer */
lineNum, /* row */
chunkStartColumn, /* col */
&enhancements, /* enhancements */
&chunkWidth, /* width */
countAll); /* countWhich */
} else {
/* get it from the history buffer... */
(void) _DtTermPrimBufferGetEnhancement(tpd->historyBuffer,
/* TermBuffer */
tpd->lastUsedHistoryRow + lineNum,
/* row */
chunkStartColumn, /* col */
&enhancements, /* enhancements */
&chunkWidth, /* width */
countAll); /* countWhich */
}
/* clip chunkWidth... */
if (chunkWidth > lineWidth)
chunkWidth = lineWidth;
/* Are we in the selection area?
* _DtTermPrimSelectIsInSelection clips the chunkWidth to
* the end of the selection if we are...
*/
if (checkSelection &&
_DtTermPrimSelectIsInSelection(w, lineNum, chunkStartColumn,
chunkWidth, &chunkWidth)) {
inSelection = True;
} else {
inSelection = False;
}
/* walk through the linePtr and figure out how many
* wide characters we need to render to fill out this
* chunk, and if the end of this chunk is in the middle
* of a wide character, bump the chunkWidth one column.
*/
for (chunkLineWidth = 0, wc = linePtr;
chunkLineWidth < chunkWidth;
chunkLineWidth += i1, wc++) {
if ((i1 = wcwidth(*wc)) <= 0) {
/* take care of null characters... */
i1 = 1;
}
}
/* adjust for a multi-column character that spans the line
* boundary...
*/
if (chunkLineWidth > chunkWidth) {
chunkWidth = chunkLineWidth;
}
/* set reasonable defaults for our render info... */
enhInfo.fg = tw->primitive.foreground;
enhInfo.bg = tw->core.background_pixel;
enhInfo.font = tpd->defaultTermFont;
enhInfo.flags = (unsigned long) 0;
/* set our font and color from the enhancements... */
if (ENH_PROC(tBuffer)) {
(void) (*(ENH_PROC(tBuffer)))(w, enhancements, &enhInfo);
}
/* are we in the selection area?... */
if (inSelection) {
/* flip fg and bg... */
tmpPixel = enhInfo.fg;
enhInfo.fg = enhInfo.bg;
enhInfo.bg = tmpPixel;
}
/* if secure, we will use a XFillRectangle, and we need
* foreground set to the background...
*/
/* set the renderGC... */
valueMask = (unsigned long) 0;
if (TermIS_SECURE(enhInfo.flags)) {
/* render secure video locally...
*/
if (tpd->renderReverseGC.foreground != enhInfo.bg) {
tpd->renderReverseGC.foreground = enhInfo.bg;
values.foreground = enhInfo.bg;
valueMask |= GCForeground;
}
if (valueMask) {
(void) XChangeGC(XtDisplay(w), tpd->renderReverseGC.gc,
valueMask, &values);
}
(void) XFillRectangle(XtDisplay(w),
XtWindow(w),
tpd->renderReverseGC.gc,
chunkStartColumn * tpd->cellWidth + tpd->offsetX,
startRow * tpd->cellHeight + tpd->offsetY,
tpd->cellWidth * chunkWidth,
tpd->cellHeight);
/* underline as well... */
if (TermIS_UNDERLINE(enhInfo.flags)) {
valueMask = (unsigned long) 0;
if (tpd->renderGC.foreground != enhInfo.fg) {
tpd->renderGC.foreground = enhInfo.fg;
values.foreground = enhInfo.fg;
valueMask |= GCForeground;
}
if (valueMask) {
(void) XChangeGC(XtDisplay(w), tpd->renderGC.gc,
valueMask, &values);
}
(void) XDrawLine(XtDisplay(w),
/* Display */
XtWindow(w), /* Drawable */
tpd->renderGC.gc, /* GC */
chunkStartColumn * tpd->cellWidth + tpd->offsetX,
/* X1 */
startRow * tpd->cellHeight + tpd->offsetY +
tpd->cellHeight - 1,
/* Y1 */
(chunkStartColumn + chunkWidth) * tpd->cellWidth +
tpd->offsetX, /* X2 */
startRow * tpd->cellHeight + tpd->offsetY +
tpd->cellHeight - 1);
/* Y2 */
}
} else {
(void) _DtTermPrimRenderText(
w, /* Widget */
enhInfo.font, /* TermFont */
enhInfo.fg, /* fg Pixel */
enhInfo.bg, /* bg Pixel */
enhInfo.flags, /* flags */
chunkStartColumn * tpd->cellWidth + tpd->offsetX,
/* x */
startRow * tpd->cellHeight + tpd->offsetY,
/* y */
/*DKS: this probably should be changed... */
(termChar *) linePtr, /* string */
wc - linePtr); /* width */
}
chunkStartColumn += chunkWidth;
lineWidth -= chunkWidth;
linePtr = wc;
}
/* clear any extra space in the line. chunkStartColumn now points to
* the end of the line, and lineWidth == 0...
*/
while (thisEndColumn - chunkStartColumn >= 0) {
chunkWidth = thisEndColumn - chunkStartColumn + 1;
if (checkSelection &&
_DtTermPrimSelectIsInSelection(w, lineNum, chunkStartColumn,
chunkWidth, &chunkWidth)) {
/* use the render gc set to the fg color... */
gc = tpd->renderReverseGC.gc;
valueMask = (unsigned long) 0;
if (tpd->renderReverseGC.foreground !=
tw->primitive.foreground) {
tpd->renderReverseGC.foreground = tw->primitive.foreground;
values.foreground = tw->primitive.foreground;
valueMask |= GCForeground;
}
if (valueMask) {
(void) XChangeGC(XtDisplay(w), tpd->renderReverseGC.gc,
valueMask, &values);
}
} else {
/* use the clear GC... */
gc = tpd->clearGC.gc;
}
if (isDebugFSet('t', 1)) {
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
/* Fill in the clear area so we can see what is going to
* be displayed...
*/
(void) XFillRectangle(XtDisplay(w),
XtWindow(w),
tpd->renderGC.gc,
chunkStartColumn * tpd->cellWidth + tpd->offsetX,
startRow * tpd->cellHeight + tpd->offsetY,
chunkWidth * tpd->cellWidth,
tpd->cellHeight);
(void) XSync(XtDisplay(w), False);
(void) shortSleep(100000);
}
(void) XFillRectangle(XtDisplay(w),
/* Display */
XtWindow(w), /* Drawable */
gc, /* GC */
chunkStartColumn * tpd->cellWidth + tpd->offsetX,
/* x */
startRow * tpd->cellHeight + tpd->offsetY,
/* y */
chunkWidth * tpd->cellWidth,
/* width */
tpd->cellHeight); /* height */
chunkStartColumn += chunkWidth;
}
}
DebugF('t', 0, fprintf(stderr, ">>_DtTermPrimRefreshTextWc() finished\n"));
}
/**************************************************************************
* Function:
* _DtTermPrimExposeText(): expose (refresh) the text in rectangular area
*
* Parameters:
* Widget w: widget to expose
* int x: starting x pixel in window
* int y: starting y pixel in window
* int width: width in pixels
* int height: height in pixels
* Boolean isExposeEvent: true, deal with copyarea / expose overlap
*
* Returns:
* <nothing>
*
* Notes:
* This function will redisplay the text in a rectangular exposure
* area. The x, y, width, and height are in absolute pixels. The
* internal x and y offsets will be accounted for, and the minimum
* number of characters will be displayed. The algorithm has been
* tuned (somewhat) and no longer exposes an extra character at the
* end of the refresh lines and an extra line at the bottom of the
* refresh area. This can be verified by using the 't' and 'e'
* debug flags.
*/
void
_DtTermPrimExposeTextMb(Widget w, int x, int y, int width, int height,
Boolean isExposeEvent)
{
struct termData *tpd = ((DtTermPrimitiveWidget) w)->term.tpd;
DebugF('e', 0, fprintf(stderr, ">>exposeText() starting\n"));
DebugF('e', 0, fprintf(stderr,
">>exposeText() startX=%d startY=%d width=%d height=%d\n",
x, y, width, height));
DebugF('e', 0, fprintf(stderr,
">> offsetX=%d offsetY=%d cellHeight=%d cellWidth=%d\n",
tpd->offsetX, tpd->offsetY, tpd->cellHeight, tpd->cellWidth));
/* The following "hack" takes care of the problem of an exposure event
* from the server and a copy area from the client crossing. The
* combination of these two events can cause a race condition which
* manifests itself by leaving a hole in the terminal window. What
* happens is this:
*
* A window is partially obscured. The terminal emulator does a copy
* area (scroll) which includes part of obscured area. Before the
* server processes the copy area, the window is unobscured, and the
* server sends an exposure event back to the client.
*
* - The window is partially obscured.
*
* - The terminal emulator does a copy area (scroll) which includes a
* portion of the obscured area. Normally, the server will generate
* a graphics exposure event for the obscured portion that it can't
* copy which will allow the terminal emulator to update the area.
*
* - Before the server receives the copy area request, the server
* unobscures the window and sends an exposure event for the exposed
* area. (This is where the hack comes into play and refreshes the
* scrolled portion of this area (and possibly some extra space as
* well)).
*
* - The server processes the copy area. Since the area in question is
* no longer obscured, the server will copy blank space and not
* generate a graphics exposure event.
*
* - The terminal emulator processes the exposure event and refreshes
* the exposed area. (This is the hack extends the exposure to cover
* the gap).
*
* - You now have a blank chunk of the terminal window where the
* obscured area was scrolled (without the hack).
*
* Our fix is similar to the one used in xterm. The Motif text widget
* uses a more brute force method and simply extends the exposure event
* to the full height (or width) of the screen in the direction of the
* copy area.
*/
if (isExposeEvent && tpd->scrollInProgress) {
int bothX1;
int bothX2;
int bothY1;
int bothY2;
bothX1 = MAX(tpd->scrollSrcX, x);
bothY1 = MAX(tpd->scrollSrcY, y);
bothX2 = MIN(tpd->scrollSrcX + tpd->scrollWidth, x + width - 1);
bothY2 = MIN(tpd->scrollSrcY + tpd->scrollHeight, y + height - 1);
if ((bothX2 > bothX1) && (bothY2 > bothY1)) {
(void) _DtTermPrimRefreshTextWc(w,
(x - tpd->offsetX + tpd->scrollDestX - tpd->scrollSrcX) /
tpd->cellWidth,
(y - tpd->offsetY + tpd->scrollDestY - tpd->scrollSrcY) /
tpd->cellHeight,
(x + width - 1 - tpd->offsetX + tpd->scrollDestX -
tpd->scrollSrcX) / tpd->cellWidth,
(y + height - 1 - tpd->offsetY + tpd->scrollDestY -
tpd->scrollSrcY) / tpd->cellHeight);
}
}
/* render the text... */
DebugF('t', 0, fprintf(stderr, ">>exposeText() calling _DtTermPrimRefreshTextWc()\n"));
(void) _DtTermPrimRefreshTextWc(w, (x - tpd->offsetX) / tpd->cellWidth,
(y - tpd->offsetY) / tpd->cellHeight,
(x + width - 1 - tpd->offsetX) / tpd->cellWidth,
(y + height - 1 - tpd->offsetY) / tpd->cellHeight);
DebugF('e', 0, fprintf(stderr, ">>exposeText() finished\n"));
}
static short
DoInsertWc(Widget w, wchar_t *wcBuffer, int wcBufferLen, Boolean *wrapped)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
TermBuffer tBuffer = tpd->termBuffer;
short newWidth;
wchar_t *returnChars;
short returnCount;
/*
** before we insert any text, we need to insure that the cursor is on
** a valid buffer row...
*/
if (tpd->topRow + tpd->cursorRow >= tpd->lastUsedRow)
{
(void) _DtTermPrimFillScreenGap(w);
}
/* insert the text... */
returnChars = (wchar_t *) XtMalloc(BUFSIZ * sizeof (wchar_t));
newWidth = _DtTermPrimBufferInsertWc(tBuffer, /* TermBuffer */
tpd->topRow + tpd->cursorRow, /* row */
tpd->cursorColumn, /* column */
wcBuffer, /* newChars */
wcBufferLen, /* numChars */
tpd->insertCharMode != DtTERM_INSERT_CHAR_OFF, /* insert flag */
&returnChars, /* return char ptr */
&returnCount); /* return count ptr */
if ((tpd->insertCharMode != DtTERM_INSERT_CHAR_ON_WRAP) || (returnCount <= 0)) {
(void) XtFree((char *) returnChars);
return(newWidth);
}
/* we are in insert char mode with wrap and we wrapped text off of
* the line...
*/
*wrapped = True;
/* wrap the inserted characters into the following line... */
if (tpd->topRow + tpd->cursorRow + 1 >= tpd->lastUsedRow) {
/* fake cursorRow... */
(void) tpd->cursorRow++;
(void) _DtTermPrimFillScreenGap(w);
(void) tpd->cursorRow--;
}
/*
** Copy the returned characters to a temporary buffer so we don't have to
** worry about _DtTermPrimBufferInsertWc tromping over its overflow buffer...
*/
wcBufferLen = returnCount;
wcBuffer = (wchar_t *)XtMalloc(wcBufferLen);
(void) memcpy(wcBuffer, returnChars, wcBufferLen * sizeof(wchar_t));
/*
** insert the text into the next line...
*/
newWidth = _DtTermPrimBufferInsertWc(tBuffer, /* TermBuffer */
tpd->topRow + tpd->cursorRow + 1, /* row */
0, /* column */
wcBuffer, /* newChars */
wcBufferLen, /* numChars */
tpd->insertCharMode != DtTERM_INSERT_CHAR_OFF, /* insert flag */
&returnChars, /* return char ptr */
&returnCount); /* return count ptr */
(void) XtFree((char *) wcBuffer);
(void) XtFree((char *) returnChars);
return(newWidth);
}
/*
** Insert the supplied text into the TermBuffer, and return a count of the
** number of characters actually inserted.
*/
int
_DtTermPrimInsertTextWc
(
Widget w,
wchar_t *wcBuffer, /* buffer of wide chars */
int wcBufLen /* # of wide chars in the buffer */
)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
TermBuffer tBuffer = tpd->termBuffer;
int i;
short renderStartX;
short renderEndX;
short insertStartX;
short insertCharCount;
short insertCharWidth; /* column width of characters to insert */
short thisCharWidth;
short newWidth;
Boolean needToRender = False;
Boolean wrapped = False;
/* turn off the cursor... */
if (CURSORoff != tpd->cursorState) {
(void) _DtTermPrimCursorOff(w);
}
/* we support two different types of autowrap. The HP style one is where
* you display the character and then wrap if you are at the end of the
* line. The ANSI style one is where you insert the character at the end
* of the line and don't autowrap until you try to insert another
* character...
*/
renderStartX = tpd->cursorColumn;
renderEndX = tpd->cursorColumn;
insertStartX = tpd->cursorColumn;
insertCharCount = 0;
insertCharWidth = 0;
for (i = 0; (i < wcBufLen) && tpd->ptyInputId; i++) {
thisCharWidth = MAX(1, wcwidth(wcBuffer[i]));
/* the following code performs two functions. If we are in
* autowrap, it performs a sanity check on the insert position.
* if we are not in autowrap, it will insure that characters
* inserted after the last position will replace the last
* character...
*/
if (((tpd->cursorColumn + thisCharWidth) > tw->term.columns) &&
!(tpd->autoWrapRight && !tpd->wrapRightAfterInsert)) {
/* blow away the previous character...
*/
tpd->cursorColumn = tw->term.columns - thisCharWidth;
renderStartX = MIN(renderStartX, tpd->cursorColumn);
tpd->wrapState = WRAPpastRightMargin;
}
/* for emulations that wrap after inserting the character, we
* will insert the character and then check for wrap...
*/
if (tpd->wrapRightAfterInsert) {
if (insertCharCount == 0) {
insertStartX = i;
insertCharWidth = 0;
}
(void) insertCharCount++;
insertCharWidth += thisCharWidth;
}
if (((tpd->cursorColumn + insertCharWidth +
(tpd->wrapRightAfterInsert ? 0: thisCharWidth)) >
tw->term.columns) ||
((tpd->cursorColumn + insertCharWidth +
(tpd->wrapRightAfterInsert ? 0 : (thisCharWidth - 1))) ==
tpd->rightMargin + 1)) {
if (tpd->autoWrapRight) {
/* perform an auto wrap...
*/
/* we need to insert any pending characters, and
* render them...
*/
if (insertCharCount) {
newWidth = DoInsertWc(w, &wcBuffer[insertStartX],
insertCharCount, &wrapped);
tpd->cursorColumn += insertCharWidth;
insertCharCount = 0;
if (tpd->insertCharMode == DtTERM_INSERT_CHAR_OFF) {
renderEndX = MAX(renderEndX, tpd->cursorColumn);
} else {
renderEndX = newWidth;
}
needToRender = True;
}
if (needToRender) {
DebugF('t', 0, fprintf(stderr,
">>termInsertText() calling[2] _DtTermPrimRefreshTextWc()\n"));
(void) _DtTermPrimRefreshTextWc(w, renderStartX, tpd->cursorRow,
wrapped ? tw->term.columns : MAX(renderEndX, 0),
tpd->cursorRow);
if (wrapped && (tpd->cursorRow + 1 < tw->term.rows)) {
(void) _DtTermPrimRefreshTextWc(w, 0, tpd->cursorRow + 1,
renderEndX, tpd->cursorRow + 1);
}
wrapped = False;
needToRender = False;
}
tpd->cursorColumn = tpd->leftMargin;
tpd->wrapState = WRAPbetweenMargins;
renderEndX = 0;
_DtTermPrimBufferSetLineWrapFlag(tBuffer,
tpd->topRow + tpd->cursorRow,
True);
if (tpd->cursorRow == tpd->scrollLockBottomRow) {
/* scroll at the bottom of the lock area... */
(void) _DtTermPrimScrollText(w, 1);
(void) _DtTermPrimFillScreenGap(w);
} else if (++tpd->cursorRow >= tw->term.rows) {
/* we are at the bottom row of the locked region.
* Wrap to the beginning of this line...
*/
tpd->cursorRow = tw->term.rows - 1;
} else {
/* we are not at the bottom row. We already have
* wrapped down one line...
*/
}
renderStartX = tpd->cursorColumn;
if (tpd->scroll.nojump.pendingScroll) {
/* If we wrapped the screen, bail out now and we
* will take care of this character when we
* finish the scroll. If we are in wrap after,
* then we need to skip past this character so
* that it doesn't get processed twice...
*/
if (tpd->wrapRightAfterInsert)
(void) i++;
break;
}
} else {
/* overwrite the last character(s) on the line... */
if (insertCharCount > 0) {
newWidth = DoInsertWc(w, &wcBuffer[insertStartX],
insertCharCount, &wrapped);
tpd->cursorColumn += insertCharWidth;
insertCharCount = 0;
if (tpd->insertCharMode == DtTERM_INSERT_CHAR_OFF) {
renderEndX = MAX(renderEndX, tpd->cursorColumn);
} else {
renderEndX = newWidth;
}
needToRender = True;
}
if (tpd->cursorColumn == tpd->rightMargin + 1)
tpd->cursorColumn = tpd->rightMargin;
else
tpd->cursorColumn = tw->term.columns - 1;
}
}
/* for emulations that wrap before inserting the character, we
* will insert the character and then check for wrap...
*/
if (!tpd->wrapRightAfterInsert) {
/* before we insert any text, we need to insure that the
* cursor is on a valid buffer row...
*/
if (insertCharCount == 0) {
insertStartX = i;
insertCharWidth = 0;
}
(void) insertCharCount++;
insertCharWidth += thisCharWidth;
}
}
/* insert and render any remaining text... */
if (insertCharCount > 0) {
/*
** The following code performs two functions. If we are in
** autowrap, it performs a sanity check on the insert position.
** if we are not in autowrap, it will insure that characters
** inserted after the last position will replace the last
** character...
**
** NOTE:
** This is only required in the case that we are trying to
** overwrite the last character on the line with a two column
** character...
*/
if (insertCharCount == 1 &&
thisCharWidth == 2 &&
((tpd->cursorColumn + thisCharWidth) > tw->term.columns) &&
!(tpd->autoWrapRight && !tpd->wrapRightAfterInsert))
{
/*
** blow away the previous character...
*/
tpd->cursorColumn = tw->term.columns - thisCharWidth;
renderStartX = MIN(renderStartX, tpd->cursorColumn);
tpd->wrapState = WRAPpastRightMargin;
}
newWidth = DoInsertWc(w, &wcBuffer[insertStartX],
insertCharCount, &wrapped);
tpd->cursorColumn += insertCharWidth;
insertCharCount = 0;
if (tpd->insertCharMode == DtTERM_INSERT_CHAR_OFF) {
renderEndX = MAX(renderEndX, tpd->cursorColumn);
} else {
renderEndX = newWidth;
}
needToRender = True;
}
if (needToRender) {
renderEndX = MAX(renderEndX, tpd->cursorColumn);
DebugF('t', 0, fprintf(stderr,
">>termInsertText() calling _DtTermPrimRefreshTextWc()\n"));
(void) _DtTermPrimRefreshTextWc(w, renderStartX - 1, tpd->cursorRow,
wrapped ? tw->term.columns : MAX(renderEndX + 1, 0),
tpd->cursorRow);
if (wrapped && (tpd->cursorRow + 1 < tw->term.rows)) {
(void) _DtTermPrimRefreshTextWc(w, 0, tpd->cursorRow + 1,
renderEndX + 1, tpd->cursorRow + 1);
}
wrapped = False;
needToRender = False;
}
return(i);
}

View File

@@ -0,0 +1,58 @@
/*
** $XConsortium: TermPrimRenderP.h /main/1 1996/04/21 19:19:08 drk $
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimRenderP_h
#define _Dt_TermPrimRenderP_h
#include "TermPrimRender.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef void (*TermFontRenderFunction)(
Widget w,
TermFont font,
Pixel fg,
Pixel bg,
unsigned long flags,
int x,
int y,
unsigned char *string,
int len
);
typedef void (*TermFontDestroyFunction)(
Widget w,
TermFont font
);
typedef void (*TermFontExtentsFunction)(
Widget w,
TermFont font,
unsigned char *string,
int len,
int *widthReturn,
int *heightReturn,
int *ascentReturn
);
typedef struct _TermFontRec {
TermFontRenderFunction renderFunction;
TermFontDestroyFunction destroyFunction;
TermFontExtentsFunction extentsFunction;
XtPointer fontInfo;
} TermFontRec;
#ifdef __cplusplus
} /* close scope of 'extern "C"'... */
#endif /* __cplusplus */
#endif /* _Dt_TermPrimRenderP_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,295 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimRepType.c /main/1 1996/04/21 19:19:11 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#include "TermHeader.h"
#include <Xm/RepType.h>
#include "TermPrimP.h"
#include "TermPrimRepType.h"
static void CvtStringToTerminalSizeDestroy
(
XtAppContext app,
XrmValue *to,
XtPointer converter_data,
XrmValue *args,
Cardinal *num_args
);
static void CvtStringToTerminalSizeListDestroy
(
XtAppContext app,
XrmValue *to,
XtPointer converter_data,
XrmValue *args,
Cardinal *num_args
);
static Boolean CvtStringToTerminalSize
(
Display *display,
XrmValue *args,
Cardinal *num_args,
XrmValue *from,
XrmValue *to,
XtPointer *converter_data
);
static Boolean CvtStringToTerminalSizeList
(
Display *display,
XrmValue *args,
Cardinal *num_args,
XrmValue *from,
XrmValue *to,
XtPointer *converter_data
);
static String TermEmulationModeStrings[] = {
"termemulation_hp",
"termemulation_ansi",
};
static String CharCursorStyleStrings[] = {
"char_cursor_box",
"char_cursor_bar",
};
XmRepTypeId _DtTermPrimEmulationMode;
XmRepTypeId _DtTermPrimCharCursorStyle;
void _DtTermPrimInitRepTypes(void)
{
static Boolean first = True;
_DtTermProcessLock();
if (first) {
/* register our resource converters... */
#ifdef NotDefined
(void) XtSetTypeConverter(XmRString, DtRDtTermTerminalSize,
CvtStringToTerminalSize, NULL, 0, XtCacheNone,
CvtStringToTerminalSizeDestroy);
#endif /* NotDefined */
(void) XtSetTypeConverter(XmRString, DtRDtTermTerminalSizeList,
CvtStringToTerminalSizeList, NULL, 0, XtCacheNone,
CvtStringToTerminalSizeListDestroy);
(void) XmRepTypeRegister(DtRDtTermEmulationMode,
TermEmulationModeStrings,
NULL, (unsigned char ) XtNumber(TermEmulationModeStrings));
(void) XmRepTypeRegister(DtRDtTermCharCursorStyle,
CharCursorStyleStrings,
NULL, (unsigned char ) XtNumber(CharCursorStyleStrings));
_DtTermPrimEmulationMode = XmRepTypeGetId(DtRDtTermEmulationMode);
_DtTermPrimCharCursorStyle = XmRepTypeGetId(DtRDtTermCharCursorStyle);
first = False;
}
_DtTermProcessUnlock();
return;
}
#ifdef NotDefined
static void
CvtStringToTerminalSizeDestroy
(
XtAppContext app,
XrmValue *to,
XtPointer converter_data,
XrmValue *args,
Cardinal *num_args
)
{
(void) XtFree(*((char **) to->addr));
}
static Boolean
CvtStringToTerminalSize
(
Display *display,
XrmValue *args,
Cardinal *num_args,
XrmValue *from,
XrmValue *to,
XtPointer *converter_data
)
{
char *str;
static DtTermTerminalSize _size;
DtTermTerminalSize *size = &_size;
char *c1;
str = (char *) from->addr;
if (to->addr) {
if (to->size < sizeof(*size)) {
to->size = sizeof(*size);
return(False);
}
size = (DtTermTerminalSize *)(to->addr);
} else {
to->addr = (XtPointer) size;
to->size = sizeof(DtTermTerminalSize);
}
/* find the separating 'x'... */
c1 = strchr(str, 'x');
/* set default values for rows and columns... */
size->rows = -1;
size->columns = -1;
/* we now have one of 3 possible valid expressions:
* <columns>x<rows> use <columns> and <rows>
* <columns>[x] use <columns> and current rows
* x<rows> use <rows> and current columns
*/
if (c1 && (c1 == str)) {
/* "x<rows>", no columns supplied... */
size->rows = atoi(++c1);
} else {
/* we have a column value before the 'x'... */
size->columns = atoi(str);
if (c1 && *++c1) {
/* we have a an 'x' and a row value after the 'x'... */
size->rows = atoi(c1);
}
}
return(True);
}
#endif /* NotDefined */
static void
CvtStringToTerminalSizeListDestroy
(
XtAppContext app,
XrmValue *to,
XtPointer converter_data,
XrmValue *args,
Cardinal *num_args
)
{
DtTermTerminalSizeList *sizeList;
sizeList = (DtTermTerminalSizeList *) (to->addr);
if (sizeList->sizes) {
(void) XtFree((char *) sizeList->sizes);
}
(void) XtFree((char *) sizeList);
}
static Boolean
CvtStringToTerminalSizeList
(
Display *display,
XrmValue *args,
Cardinal *num_args,
XrmValue *from,
XrmValue *to,
XtPointer *converter_data
)
{
char *str;
static DtTermTerminalSizeList _sizeList;
DtTermTerminalSizeList *sizeList = &_sizeList;
char *c1;
char *c2;
char *tmpStr;
int numSizes = 0;
int sizesSize = 0;
DtTermTerminalSize *sizes = (DtTermTerminalSize *) 0;
str = (char *) from->addr;
if (to->addr) {
if (to->size < sizeof(*sizeList)) {
to->size = sizeof(*sizeList);
return(False);
}
sizeList = (DtTermTerminalSizeList *)(to->addr);
} else {
to->addr = (XtPointer) sizeList;
to->size = sizeof(DtTermTerminalSizeList);
}
sizesSize += 10;
sizes = (DtTermTerminalSize *) XtRealloc((char *) sizes,
sizesSize * sizeof(DtTermTerminalSize));
for (numSizes = 0, c1 = str; c1 && *c1; numSizes++) {
if (numSizes + 1 > sizesSize) {
sizesSize += 10;
sizes = (DtTermTerminalSize *) XtRealloc((char *) sizes,
sizesSize * sizeof(DtTermTerminalSize));
}
sizes[numSizes].rows = 0;
sizes[numSizes].columns = 0;
if (*c1 != 'x') {
/* parse off columns... */
if ((*c1 >= '0') && (*c1 <= '9')) {
sizes[numSizes].columns = (short) strtol(c1, &c1, 10);
} else {
/* skip over all garbage up to possible 'x' */
while (c1 && *c1 && *c1 != 'x' && !isspace(*c1)) {
c1++;
}
}
}
if (*c1 == 'x') {
/* parse off rows... */
(void) c1++;
if ((*c1 >= '0') && (*c1 <= '9')) {
sizes[numSizes].rows = (short) strtol(c1, &c1, 10);
}
}
/* skip over all garbage up to whitespace... */
while (c1 && *c1 && !isspace(*c1)) {
c1++;
}
/* skip over whitespace... */
while (c1 && *c1 && isspace(*c1)) {
c1++;
}
/* check to see if we actually found any numbers */
if ( sizes[numSizes].rows ==0 && sizes[numSizes].columns == 0)
numSizes--;
}
/* we can now allocate our returned size array... */
if ( numSizes <= 0 ) {
numSizes =1;
sizes[0].rows = 24;
sizes[0].columns = 80;
}
sizeList->numSizes = numSizes;
sizeList->sizes = (DtTermTerminalSize *)
XtMalloc(numSizes * sizeof(DtTermTerminalSize));
(void) memcpy(sizeList->sizes, sizes, numSizes *
sizeof(DtTermTerminalSize));
(void) XtFree((char *) sizes);
return(True);
}

View File

@@ -0,0 +1,18 @@
/*
* $XConsortium: TermPrimRepType.h /main/1 1996/04/21 19:19:15 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimRepType_h
#define _Dt_TermPrimRepType_h
#include <Xm/RepType.h>
#include "TermPrim.h"
extern void _DtTermPrimInitRepTypes(void);
#endif /* _Dt_TermPrimRepType_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,918 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimScroll.c /main/1 1996/04/21 19:19:17 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#include "TermHeader.h"
#include "TermPrimDebug.h"
#include "TermPrimP.h"
#include "TermPrimI.h"
#include "TermPrimData.h"
#include "TermPrimBuffer.h"
static void
waitOnCopyArea(Widget w)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
XEvent event;
XEvent *ev = &event;
while (tpd->scrollInProgress) {
(void) XWindowEvent(XtDisplay(w), XtWindow(w), ExposureMask, ev);
switch (ev->type) {
case Expose:
Debug('e', fprintf(stderr,
">>_waitOnCopyArea() Expose event received\n"));
/* refresh the border... */
(void) _DtTermPrimDrawShadow(w);
/* just refresh the exposed area...
*/
Debug('e', fprintf(stderr,
">>_waitOnCopyArea() exposing Expose area\n"));
Debug('e', fprintf(stderr,
">> x=%d y=%d width=%d height=%d\n",
ev->xexpose.x, ev->xexpose.y,
ev->xexpose.width, ev->xexpose.height));
(void) _DtTermPrimExposeText(w, ev->xexpose.x, ev->xexpose.y,
ev->xexpose.width, ev->xexpose.height, True);
break;
case GraphicsExpose:
/* refresh the exposed area and, if this is the last graphics
* exposure, we are done and can fall through to the noExpose
* code...
*/
Debug('e', fprintf(stderr,
">>_DtTermPrimScrollWait() GraphicsExpose event received, count=%d\n",
ev->xgraphicsexpose.count));
Debug('e', fprintf(stderr,
">>_waitOnCopyArea() exposing GraphicsExpose area\n"));
Debug('e', fprintf(stderr,
">> x=%d y=%d width=%d height=%d\n",
ev->xgraphicsexpose.x, ev->xgraphicsexpose.y,
ev->xgraphicsexpose.width, ev->xgraphicsexpose.height));
(void) _DtTermPrimExposeText(w,
ev->xgraphicsexpose.x, ev->xgraphicsexpose.y,
ev->xgraphicsexpose.width, ev->xgraphicsexpose.height,
False);
if (ev->xgraphicsexpose.count > 0) {
/* more to come... */
break;
}
case NoExpose:
/* we are done... */
Debug('e', fprintf(stderr,
">>_waitOnCopyArea() NoExpose event received\n"));
tpd->scrollInProgress = False;
break;
}
}
}
void
_DtTermPrimScrollWait(Widget w)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
int i;
int exposeY;
int exposeHeight;
int scrolledLines;
Debug('s', fprintf(stderr, ">>_DtTermPrimScrollWait() starting\n"));
Debug('s', fprintf(stderr,
">>_DtTermPrimScrollWait() scrollLines=%d, scrollsPending=%d\n",
tpd->scroll.jump.scrollLines, tpd->scroll.jump.scrollsPending));
/* make sure the cursor is off... */
(void) _DtTermPrimCursorOff(w);
if (tpd->scroll.jump.scrollLines != 0) {
/* flush so that we can be sure the output was visible before we
* scroll it off...
*/
(void) XFlush(XtDisplay(w));
/* figure out the height of the copy area... */
if (tpd->scroll.jump.scrollLines > 0) {
/* scrolling memory up... */
Debug('s', fprintf(stderr,
">>_DtTermPrimScrollWait() up, scrollLines=%d cellHeight=%d\n",
tpd->scroll.jump.scrollLines, tpd->cellHeight));
if (tpd->scroll.jump.scrollLines >=
tpd->scrollBottomRow - tpd->scrollTopRow + 1) {
/* a full screen or more -- we can avoid the copy area... */
tpd->scrollHeight = 0;
exposeY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollTopRow);
exposeHeight = tpd->cellHeight *
(tpd->scrollBottomRow - tpd->scrollTopRow + 1);
Debug('s', fprintf(stderr,
">>_DtTermPrimScrollWait() height=%d expose Y=%d height=%d\n",
tpd->scrollHeight, exposeY, exposeHeight));
} else {
tpd->scrollHeight = tpd->cellHeight *
(tpd->scrollBottomRow - tpd->scrollTopRow + 1 -
tpd->scroll.jump.scrollLines);
tpd->scrollSrcY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollTopRow + tpd->scroll.jump.scrollLines);
tpd->scrollDestY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollTopRow);
exposeY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollBottomRow + 1 -
tpd->scroll.jump.scrollLines);
exposeHeight = tpd->cellHeight *
(tpd->scroll.jump.scrollLines);
Debug('s', fprintf(stderr,
">>_DtTermPrimScrollWait() height=%d SrcY=%d DestY=%d expose Y=%d height=%d\n",
tpd->scrollHeight, tpd->scrollSrcY, tpd->scrollDestY,
exposeY, exposeHeight));
}
} else {
/* scrolling memory down... */
Debug('s', fprintf(stderr,
">>_DtTermPrimScrollWait() down, scrollLines=%d cellHeight=%d\n",
tpd->scroll.jump.scrollLines, tpd->cellHeight));
if (tpd->scroll.jump.scrollLines <=
-(tpd->scrollBottomRow - tpd->scrollTopRow + 1)) {
/* a full screen or more -- we can avoid the copy area... */
tpd->scrollHeight = 0;
exposeY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollTopRow);
exposeHeight = tpd->cellHeight *
(tpd->scrollBottomRow - tpd->scrollTopRow + 1);
Debug('s', fprintf(stderr,
">>_DtTermPrimScrollWait() height=%d expose Y=%d height=%d\n",
tpd->scrollHeight, exposeY, exposeHeight));
} else {
/* remember: scrollLines is **NEGATIVE**...
*/
tpd->scrollHeight = tpd->cellHeight * (tpd->scrollBottomRow -
tpd->scrollTopRow + 1 - -tpd->scroll.jump.scrollLines);
tpd->scrollSrcY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollTopRow);
tpd->scrollDestY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollTopRow + -tpd->scroll.jump.scrollLines);
exposeY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollTopRow);
exposeHeight = tpd->cellHeight *
(-tpd->scroll.jump.scrollLines);
Debug('s', fprintf(stderr,
">>_DtTermPrimScrollWait() height=%d SrcY=%d DestY=%d expose Y=%d height=%d\n",
tpd->scrollHeight, tpd->scrollSrcY, tpd->scrollDestY,
exposeY, exposeHeight));
}
}
/* we need to do a copy area... */
if (tpd->scrollHeight > 0) {
/* calculate scroll area... */
tpd->scrollWidth = tpd->cellWidth * tw->term.columns;
tpd->scrollSrcX = tpd->offsetX;
tpd->scrollDestX = tpd->offsetX;
(void) XCopyArea(XtDisplay(w),
/* Display */
XtWindow(w), /* Source */
XtWindow(w), /* Destination */
tpd->renderGC.gc, /* GC */
tpd->scrollSrcX, /* source X */
tpd->scrollSrcY, /* source Y */
tpd->scrollWidth, /* width */
tpd->scrollHeight, /* height */
tpd->scrollDestX, /* destination X */
tpd->scrollDestY); /* destination Y */
tpd->scrollInProgress = True;
}
/* expose the exposed area. We need to expose the exposed area
* as well as any lines that have been changed. While we really
* could just expose the exposed area and then go back and fill
* in any remaining lines that have the flag set, we will first
* fill in any lines above the expose area with their flag set,
* fill in the expose area, and then fill in any lines below
* the expose area with their flag set. This fills things in
* from top to bottom which is much more pleasing visually.
*/
Debug('s', fprintf(stderr,
">>_DtTermPrimScrollWait() exposing scroll area\n"));
Debug('s', fprintf(stderr,
">> x=%d y=%d width=%d height=%d\n",
tpd->offsetX,
exposeY,
tpd->cellWidth * tw->term.columns,
exposeHeight));
/* set scrollLines == 0, or renderText will not render them... */
scrolledLines = tpd->scroll.jump.scrollLines;
tpd->scroll.jump.scrollLines = 0;
/* clear the scrolled flag... */
tpd->scroll.jump.scrolled = False;
/* refresh any lines above the expose zone that have their
* scrollRefreshRows flag set...
*/
for (i = 0; i < (exposeY - tpd->offsetX) / tpd->cellHeight; i++) {
if (tpd->scrollRefreshRows[i]) {
(void) _DtTermPrimRefreshText(w, 0, i, tw->term.columns, i);
}
}
/* expose the refresh expose area... */
(void) _DtTermPrimExposeText(w,
tpd->offsetX,
exposeY,
tpd->cellWidth * tw->term.columns,
exposeHeight,
False);
/* refresh any lines below the expose zone that have their
* scrollRefreshRows flag set...
*/
for (i = (exposeY - tpd->offsetX + exposeHeight) / tpd->cellHeight;
i < tw->term.rows; i++) {
if (tpd->scrollRefreshRows[i]) {
(void) _DtTermPrimRefreshText(w, 0, i, tw->term.columns, i);
}
}
if (tpd->scrollHeight > 0)
tpd->scroll.jump.scrollsPending++;
(void) _DtTermPrimCursorUpdate(w);
} else {
/* scrollLines == 0...
*/
/* flush so that we can be sure the output was visible before we
* scroll it off...
*/
(void) XFlush(XtDisplay(w));
/* clear the scrolled flag... */
tpd->scroll.jump.scrolled = False;
/* refresh any lines below the expose zone that have their
* scrollRefreshRows flag set...
*/
for (i = 0; i < tw->term.rows; i++) {
if (tpd->scrollRefreshRows[i]) {
(void) _DtTermPrimRefreshText(w, 0, i, tw->term.columns, i);
}
}
}
while (tpd->scroll.jump.scrollsPending > 0) {
(void) waitOnCopyArea(w);
tpd->scroll.jump.scrollsPending--;
}
Debug('s', fprintf(stderr, ">>_DtTermPrimScrollWait() finished\n"));
}
static void
doActualScroll(Widget w, int lines)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
int exposeY;
int exposeHeight;
int i;
/* make sure the cursor is off... */
(void) _DtTermPrimCursorOff(w);
/* figure out the height of the copy area... */
if (lines > 0) {
/* scrolling memory up... */
if (lines >= tpd->scrollBottomRow - tpd->scrollTopRow + 1) {
/* we are scrolling a full screen or more, so there is nothing
* to copy...
*/
tpd->scrollHeight = 0;
exposeY = tpd->offsetY + tpd->cellHeight * tpd->scrollTopRow;
exposeHeight = tpd->cellHeight *
(tpd->scrollBottomRow - tpd->scrollTopRow + 1);
} else {
tpd->scrollHeight = tpd->cellHeight *
(tpd->scrollBottomRow - tpd->scrollTopRow + 1 - lines);
tpd->scrollSrcY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollTopRow + lines);
tpd->scrollDestY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollTopRow);
/* expose bottom lines lines... */
exposeY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollBottomRow + 1 - lines);
exposeHeight = tpd->cellHeight * lines;
}
} else {
/* scrolling memory down... */
/* lines are negative -- make positive... */
lines = -lines;
if (lines >= tw->term.rows) {
/* we are scrolling a full screen or more, so there is nothing
* to copy...
*/
tpd->scrollHeight = 0;
exposeY = tpd->offsetY + tpd->cellHeight * tpd->scrollTopRow;
exposeHeight = tpd->cellHeight *
(tpd->scrollBottomRow - tpd->scrollTopRow + 1);
} else {
tpd->scrollHeight = tpd->cellHeight *
(tpd->scrollBottomRow - tpd->scrollTopRow + 1 - lines);
tpd->scrollSrcY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollTopRow);
tpd->scrollDestY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollTopRow + lines);
/* expose top lines lines... */
exposeY = tpd->offsetY + tpd->cellHeight *
(tpd->scrollTopRow);
exposeHeight = tpd->cellHeight * lines;
}
}
/* scroll the display... */
if (tpd->scrollHeight > 0) {
/* calculate scroll area... */
tpd->scrollWidth = tpd->cellWidth * tw->term.columns;
tpd->scrollSrcX = tpd->offsetX;
tpd->scrollDestX = tpd->offsetX;
/* copy the area... */
XCopyArea(XtDisplay(w), /* Display */
XtWindow(w), /* Source */
XtWindow(w), /* Destination */
tpd->renderGC.gc, /* GC */
tpd->scrollSrcX, /* source X */
tpd->scrollSrcY, /* source Y */
tpd->scrollWidth, /* width */
tpd->scrollHeight, /* height */
tpd->scrollDestX, /* destination X */
tpd->scrollDestY); /* destination Y */
tpd->scrollInProgress = True;
}
/* clear the old area... */
(void) XFillRectangle(XtDisplay(w), /* Display */
XtWindow(w), /* Drawable */
tpd->clearGC.gc, /* GC */
tpd->offsetX, /* x */
exposeY, /* y */
tw->term.columns * tpd->cellWidth,
/* width */
exposeHeight); /* height */
/* expose the old area... */
(void) _DtTermPrimExposeText(w,
tpd->offsetX,
exposeY,
tw->term.columns * tpd->cellWidth,
exposeHeight, False);
(void) _DtTermPrimCursorUpdate(w);
}
/**************************************************************************
* Function:
* _DtTermPrimScrollText(): scroll the terminal window
*
* Parameters:
* Widget w: widget to scroll
* int lines: lines to scroll
*
* Returns:
* <nothing>
*
* Notes:
*
* This function will scroll the terminals window. It supports
* both jump scroll and non-jump scroll (single line at a time).
* In jump scroll, the maximum number of lines that will be
* scrolled at a time is the length of the display. This insures
* that all text will be displayed for at least an instant.
*
* In jump scroll mode, scrolling is performed as follows:
*
* - Scroll request is made:
*
* + Number of lines to scroll is incremented.
*
* + If the number of lines is < the length of the screen,
* rendering is discontinued and the actual scroll request is
* delayed until the the cursor is turned back on (i.e.,
* select(2) says there is no more input on the pty).
*
* + If the number of lines is >= the length of the screen, the
* copy area is performed, and the world blocks on exposure
* events on the window. When a no-expose request, or the
* last graphics expose request is received, any remaining
* lines will be queue'ed up.
*
* - The code that processes data coming over the pty determines
* via select(2) that there is no data to be read.
*
* + The copy area is performed, and the world blocks on
* exposure events on the window. When a no-expose request,
* or the last graphics expose request is received, the
* scroll is complete.
*
*
* In non-jump scroll mode, the following actions are performed:
*
* - If there is no scroll in progress, the copy area is performed.
* Any additional input is processed as normal.
*
* - When the generated no-expose or final graphics expose event is
* processed, the pending scroll flag is cleared.
*
* - If there is a scroll in progress, the new scroll is queued up.
* Any remaining pty input will be queued and the pty will be
* dropped from Xt input select.
*
* - When the generated no-expose or final graphics expose event is
* processed, the queued copy area will be performed. Any queued
* pty input will be processed and the pty will be added to the
* Xt input select.
*/
void
_DtTermPrimScrollText(Widget w, short lines)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
short oldTopRow;
short newTopRow;
int lines2;
int i;
/* figure out what our new top row will be. It is limitied by the
* beginning of memory (i.e., we can't scroll above line 0) and the
* lastUsedRow (i.e., we can't scroll the lastUsedRow off the screen).
* we will then use this value to clip lines...
*/
oldTopRow = tpd->topRow;
if (lines > 0) {
newTopRow = tpd->topRow + lines;
/* don't scroll past the lastUsedRow... */
if (newTopRow > (tpd->lastUsedRow - tpd->scrollLockTopRow)) {
newTopRow = tpd->lastUsedRow - tpd->scrollLockTopRow;
}
} else {
if (tpd->useHistoryBuffer) {
if ((tpd->topRow + tpd->lastUsedHistoryRow) >= -lines)
newTopRow = tpd->topRow - -lines;
else
newTopRow = -tpd->lastUsedHistoryRow;
} else {
if (tpd->topRow >= -lines)
newTopRow = tpd->topRow - -lines;
else
newTopRow = 0;
}
}
/* adjust lines to the clipped newTopRow... */
lines = newTopRow - oldTopRow;
/* we don't need to do any for 0... */
if (0 == lines)
return;
if (tw->term.jumpScroll &&
((lines + tpd->scroll.jump.scrollLines) >
(tw->term.rows -
tpd->scrollLockTopRow -
(tw->term.rows - 1 - tpd->scrollLockBottomRow))) ||
((lines + tpd->scroll.jump.scrollLines) <
-(tw->term.rows -
tpd->scrollLockTopRow -
(tw->term.rows - 1 - tpd->scrollLockBottomRow))) ||
(tpd->scrollTopRow != tpd->scrollLockTopRow) ||
(tpd->scrollBottomRow != tpd->scrollLockBottomRow)) {
/* scroll out the queued up jump scroll lines... */
if (tpd->scroll.jump.scrollLines != 0) {
(void) _DtTermPrimScrollWait(w);
}
}
/* move the memory locked region in screen memory...
*/
/* Assuming a 24 line buffer with lock on 10 and 20 and 30 lines
* of screen buffer, with one below and scrolling 3 lines, we do
* the following:
*
* oooooLLLLLLLLLL LLLLo
* ||||||||||||||||||||||||||||||
* 000000000011111111112222222222
* 012345678901234567890123456789
*
* move lines 15-17 to the top of the buffer:
*
* ooooooooLLLLLLLLLL LLLLo
* ||||||||||||||||||||||||||||||
* 111000000000011111112222222222
* 567012345678901234890123456789
*
* move line 29 to the bottom of the unlocked area:
*
* ooooooooLLLLLLLLLL LLLL
* ||||||||||||||||||||||||||||||
* 111000000000011111112222222222
* 567012345678901234890123495678
*
* clear the top2 lines and move it to the bottom of the
* unlocked area:
*
* ooooooLLLLLLLLLL LLLL
* ||||||||||||||||||||||||||||||
* 100000000001111111222221122222
* 701234567890123489012345695678
*
*/
/* if we have a history buffer and we are going to be scrolling lines
* off of the buffer, we should move them into the history buffer.
*/
if ((tpd->scrollLockTopRow == 0) &&
(tpd->scrollLockBottomRow >= (tw->term.rows - 1))) {
/*DKS*/
}
/* first move the top lock area... */
if (tpd->scrollLockTopRow > 0) {
(void) _DtTermPrimBufferMoveLockArea(tpd->termBuffer,
tpd->topRow + lines, tpd->topRow, tpd->scrollLockTopRow);
}
/* now move the bottom lock area... */
if (tpd->scrollLockBottomRow < (tw->term.rows - 1)) {
/* if we are moving up, let's move as many rows as we can from
* bottom offscreen memory...
*/
lines2 = 0;
if ((lines > 0) && (tpd->bufferRows > (tpd->topRow + tw->term.rows))) {
/* clip lines2 to the number of lines that we can obtain
* from the bottom of the buffer...
*/
lines2 = lines;
if (lines2 > (tpd->bufferRows - (tpd->topRow + tw->term.rows))) {
lines2 = tpd->bufferRows - (tpd->topRow + tw->term.rows);
}
if (lines2 > 0) {
/* move them... */
(void) _DtTermPrimBufferMoveLockArea(tpd->termBuffer,
tpd->topRow + tpd->scrollLockBottomRow - lines2,
tpd->topRow + tpd->scrollLockBottomRow,
(tw->term.rows - 1) - tpd->scrollLockBottomRow);
}
}
/* figure out how many lines we will need to take from the
* top...
*/
lines2 = lines - lines2;
if (lines2 > 0) {
for (i = 0; i < lines2; i++) {
(void) _DtTermPrimBufferClearLine(tpd->termBuffer, i, 0);
}
(void) _DtTermPrimBufferMoveLockArea(tpd->termBuffer,
0,
lines2,
tpd->topRow + tpd->scrollLockBottomRow + 1 - lines);
newTopRow -= lines2;
}
}
/* set topRow... */
tpd->topRow = newTopRow;
if (tw->term.jumpScroll) {
/* jump scroll...
*/
/* queue up the lines for scrolling... */
tpd->scroll.jump.scrollLines += lines;
tpd->scroll.jump.scrolled = True;
tpd->scrollTopRow = tpd->scrollLockTopRow;
tpd->scrollBottomRow = tpd->scrollLockBottomRow;
/* scroll out the scrollRefreshRows flags now... */
/* NOTE: we loose the refresh flag for all rows that are scrolled
* off. The result of this is that if we do a scroll up followed
* by a scroll down, we will (at a minimum) refresh the top and
* bottom lines. One workaround would be to tripple the buffer
* and keep the lines that get scrolled off the top or bottom.
* This would probably break something, since there are times
* that the scrolled off line gets modified or even cleared (such
* as delete line off of the top of the display), so this might
* not be a very good idea.
*/
if (lines > 0) {
/* scroll them up... */
for (i = tpd->scrollTopRow;
i <= tpd->scrollBottomRow - lines; i++) {
tpd->scrollRefreshRows[i] =
tpd->scrollRefreshRows[i + lines];
}
/* set the rest... */
for (; i <= tpd->scrollBottomRow; i++) {
tpd->scrollRefreshRows[i] = True;
}
} else {
/* remember, lines is negative... */
for (i = tpd->scrollBottomRow;
i >= tpd->scrollTopRow + -lines; i--) {
tpd->scrollRefreshRows[i] =
tpd->scrollRefreshRows[i - -lines];
}
for (; i >= tpd->scrollTopRow; i--) {
tpd->scrollRefreshRows[i] = True;
}
}
} else {
/* non jump-scroll...
*/
if (tpd->scrollInProgress) {
/* let's queue up the scroll and bail out...
*/
tpd->scroll.nojump.pendingScrollLines += lines;
/*DKS!!! v v v v v v v v v v v v v v v v v v v v v v */
if (tpd->scroll.nojump.pendingScrollLines > 1)
(void) fprintf(stderr,
"tell Dave _DtTermPrimScrollText has pendingScrollLines=%d\n",
tpd->scroll.nojump.pendingScrollLines);
/*DKS!!! ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ */
tpd->scroll.nojump.pendingScroll = True;
tpd->scroll.nojump.pendingScrollTopRow = tpd->scrollLockTopRow;
tpd->scroll.nojump.pendingScrollBottomRow = tpd->scrollLockBottomRow;
(void) _DtTermPrimStartOrStopPtyInput(w);
return;
}
/* no scroll in progress, let's scroll it... */
tpd->scrollTopRow = tpd->scrollLockTopRow;
tpd->scrollBottomRow = tpd->scrollLockBottomRow;
(void) doActualScroll(w, lines);
}
/* This case: (tpd->scrollLockTopRow > 0)
is handled elsewhere.
*/
if ( lines > 0 && tpd->scrollLockBottomRow < (tw->term.rows-1)) {
_DtTermPrimSelectMoveLines(w, tpd->scrollLockTopRow + lines,
tpd->scrollLockTopRow,
tpd->scrollLockBottomRow - tpd->scrollLockTopRow);
}
return;
}
void
_DtTermPrimScrollTextTo(Widget w, short topRow)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
int oldTopRow;
if (topRow == tpd->topRow) {
/* already there... */
return;
}
(void) _DtTermPrimScrollText(w, topRow - tpd->topRow);
return;
}
void
_DtTermPrimScrollTextArea(Widget w, short scrollStart, short scrollLength,
short scrollDistance)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
int oldTopRow;
int exposeY;
int exposeHeight;
int i;
#ifdef NOTDEF
if (scrollDistance > 0) {
/* scrolling text up... */
if (tpd->lastUsedRow <= tpd->topRow + scrollStart) {
/* scrolling past lastUsedRow -- nothing to scroll... */
return;
}
}
#endif /* NOTDEF */
/* clip the length... */
if (scrollStart + scrollLength > tw->term.rows) {
scrollLength = tw->term.rows - scrollStart;
}
/* we don't need to do anything for 0 distance... */
if (0 == scrollDistance) {
return;
}
/* if we are in jumpscroll mode and:
* -our region differs (scrollTopRow and scrollBottomRow), or
* -we are going to queue more lines than the scroll region
* we need to complete the queued scroll...
*/
if (tw->term.jumpScroll &&
((scrollDistance + tpd->scroll.jump.scrollLines > scrollLength) ||
(scrollDistance + tpd->scroll.jump.scrollLines < -scrollLength) ||
(tpd->scrollTopRow != scrollStart) ||
(tpd->scrollBottomRow != scrollStart + scrollLength - 1))) {
/* scroll out the queued up jump scroll lines... */
if (tpd->scroll.jump.scrolled != 0) {
(void) _DtTermPrimScrollWait(w);
}
}
if (tw->term.jumpScroll) {
/* jump scroll...
*/
/* queue up the lines for scrolling... */
tpd->scroll.jump.scrollLines += scrollDistance;
tpd->scroll.jump.scrolled = True;
tpd->scrollTopRow = scrollStart;
tpd->scrollBottomRow = scrollStart + scrollLength - 1;
/* scroll out the scrollRefreshRows flags now... */
if (scrollDistance > 0) {
/* scroll them up... */
for (i = tpd->scrollTopRow;
i <= tpd->scrollBottomRow - scrollDistance; i++) {
tpd->scrollRefreshRows[i] =
tpd->scrollRefreshRows[i + scrollDistance];
}
/* set the rest... */
for (; i <= tpd->scrollBottomRow; i++) {
tpd->scrollRefreshRows[i] = True;
}
} else {
for (i = tpd->scrollBottomRow;
i >= tpd->scrollTopRow + -scrollDistance; i--) {
tpd->scrollRefreshRows[i] =
tpd->scrollRefreshRows[i - -scrollDistance];
}
for (; i >= tpd->scrollTopRow; i--) {
tpd->scrollRefreshRows[i] = True;
}
}
} else {
/* non jump scroll...
*/
if (tpd->scrollInProgress) {
/* let's queue up the scroll and bail out...
*/
tpd->scroll.nojump.pendingScrollLines += scrollDistance;
/*DKS!!! v v v v v v v v v v v v v v v v v v v v v v */
if (tpd->scroll.nojump.pendingScrollLines > 1)
(void) fprintf(stderr,
"tell Dave _DtTermPrimScrollText has pendingScrollLines=%d\n",
tpd->scroll.nojump.pendingScrollLines);
/*DKS!!! ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ */
tpd->scroll.nojump.pendingScroll = True;
tpd->scroll.nojump.pendingScrollTopRow = scrollStart;
tpd->scroll.nojump.pendingScrollBottomRow =
scrollStart + scrollLength - 1;
(void) _DtTermPrimStartOrStopPtyInput(w);
return;
}
/* no scroll in progress, let's scroll it... */
tpd->scrollTopRow = scrollStart;
tpd->scrollBottomRow = scrollStart + scrollLength - 1;
(void) doActualScroll(w, scrollDistance);
tpd->scrollInProgress = True;
}
}
/**************************************************************************
* Function:
* _DtTermPrimScrollComplete(): finish a scroll. This is normall called
* to complete a non-jump scroll, or if it is necessary to
* complete and flush any scroll.
*
* Parameters:
* Widget w: widget to scroll
*
* Returns:
* <nothing>
*
* Notes:
*
* This function is used in non-jump scroll only!!!
*
* This function is called by the Term widget when a no-expose or
* final graphics expose event is received (which was generated by
* the previous scroll's copy area). It will invoke the scroll that
* was queued up and caused pty input to be blocked.
*/
void
_DtTermPrimScrollComplete(Widget w, Boolean flush)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
if (tw->term.jumpScroll) {
/* jump scroll...
*/
if (flush) {
/* we need to finish any pending scrolls...
*/
/* In jump scroll, all we need to do is to invoke the scroll.
* _DtTermPrimScrollWait() will perform the actual copy area and
* wait for the generated graphics expose / no expose events...
*/
if (tpd->scroll.jump.scrolled) {
Debug('s', fprintf(stderr,
">>_DtTermPrimScrollComplete() calling _DtTermPrimScrollWait()\n"));
(void) _DtTermPrimScrollWait(w);
}
}
} else {
/* non-jump scroll...
*/
if (flush && tpd->scrollInProgress) {
/* if we have a pending scroll, we need to wait for it to
* complete. Normally, we would service this out of the
* XtMainLoop() dispatch loop, but for some reason we need
* to do it now.
*/
(void) waitOnCopyArea(w);
tpd->scrollInProgress = False;
}
if (!tw->term.jumpScroll && tpd->scroll.nojump.pendingScroll) {
/* do the queued scroll... */
tpd->scrollTopRow = tpd->scroll.nojump.pendingScrollTopRow;
tpd->scrollBottomRow = tpd->scroll.nojump.pendingScrollBottomRow;
(void) doActualScroll(w, tpd->scroll.nojump.pendingScrollLines);
/* no lines pending, but there is a scroll in progress... */
tpd->scroll.nojump.pendingScrollLines = 0;
tpd->scrollInProgress = True;
tpd->scroll.nojump.pendingScroll = False;
if (flush) {
/* wait for it to complete...
*/
(void) waitOnCopyArea(w);
tpd->scrollInProgress = False;
/* If there is any pending input or if we need to reinstall
* the input select, force a pty read...
*/
(void) XtAppAddTimeOut(XtWidgetToApplicationContext(w),
0, _DtTermPrimForcePtyRead, (XtPointer) w);
}
}
}
}
void
_DtTermPrimScrollCompleteIfNecessary(Widget w, short scrollTopRow,
short scrollBottomRow, short lines)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
short maxJumpScrollLines;
if ((scrollTopRow != tpd->scrollTopRow) ||
(scrollBottomRow != tpd->scrollBottomRow)) {
(void) _DtTermPrimScrollComplete(w, True);
return;
}
if (tw->term.jumpScroll) {
maxJumpScrollLines = tpd->scrollBottomRow - tpd->scrollTopRow + 1;
if ((lines + tpd->scroll.jump.scrollLines > maxJumpScrollLines) ||
(lines + tpd->scroll.jump.scrollLines < -maxJumpScrollLines))
(void) _DtTermPrimScrollComplete(w, True);
return;
} else {
if (!tw->term.jumpScroll && tpd->scroll.nojump.pendingScroll) {
(void) _DtTermPrimScrollComplete(w, True);
return;
}
}
}

View File

@@ -0,0 +1,22 @@
/*
* $XConsortium: TermPrimScroll.h /main/1 1996/04/21 19:19:21 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimScroll_h
#define _Dt_TermPrimScroll_h
extern void _DtTermPrimScrollWait(Widget w);
extern void _DtTermPrimScrollComplete(Widget w, Boolean flush);
extern void _DtTermPrimScrollCompleteIfNecessary(Widget w, short scrollTopRow,
short scrollBottomRow, short lines);
extern void _DtTermPrimScrollText(Widget w, short lines);
extern void _DtTermPrimScrollTextTo(Widget w, short topRow);
extern void _DtTermPrimScrollTextArea(Widget w, short scrollStart,
short scrollLength, short scrollDistance);
#endif /* _Dt_TermPrimScroll_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,269 @@
/*
** $XConsortium: TermPrimSelect.h /main/1 1996/04/21 19:19:28 drk $
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimSelect_h
#define _Dt_TermPrimSelect_h
typedef struct _termSelectInfoRec *TermSelectInfo;
#include "TermPrimBuffer.h"
typedef enum {
TermSelect_NORMAL,
TermSelect_RECTANGULAR
} TermSelectType;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
extern Boolean
_DtTermPrimSelectIsAboveSelection
(
Widget w,
short row,
short col
);
extern void
_DtTermPrimSelectDisownIfNecessary
(
Widget w
);
extern void
_DtTermPrimSelectResize
(
Widget w
);
extern void
_DtTermPrimSelectDeleteLine
(
TermBuffer tb,
short lines /* number of lines */
);
extern void
_DtTermPrimSelectMoveLines
(
Widget w,
short src,
short dest,
short len
);
extern void
_DtTermPrimSelectDeleteLines
(
Widget w,
short src,
short len
);
extern void
_DtTermPrimSelectInsertLines
(
Widget w,
short src,
short len
);
extern
TermSelectInfo
_DtTermPrimSelectCreate
(
Widget w
);
extern
Boolean
_DtTermPrimSelectConvert
(
Widget w,
Atom *selection,
Atom *target,
Atom *type,
XtPointer *value,
unsigned long *length,
int *format
);
extern
void
_DtTermPrimSelectDestroy
(
Widget w,
TermSelectInfo selectInfo
);
extern
Boolean
_DtTermPrimSelectGetSelection
(
Widget w,
XmTextPosition *begin,
XmTextPosition *end
);
extern
Boolean
_termSelectInSelection
(
Widget w,
int row,
XmTextPosition *begin,
short length,
short *selLength
);
extern
void
_DtTermPrimSelectGrabFocus
(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params
);
extern void
_DtTermPrimSelectExtendStart(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params );
extern
void
_DtTermPrimSelectExtend
(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params
);
extern
void
_DtTermPrimSelectExtendEnd
(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params
);
extern
void
_DtTermPrimSelectInsert
(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params
);
void
_DtTermPrimSelectLoseSelection
(
Widget w,
Atom *selection
);
extern
void
_DtTermPrimSelectProcessBDrag
(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params
);
extern
void
_DtTermPrimSelectAll
(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params
);
extern
void
_DtTermPrimSelectPage
(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params
);
extern
void
_DtTermPrimSelectPasteClipboardEventIF
(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params
);
extern
void
_DtTermPrimSelectCopyClipboardEventIF
(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params
);
extern
Boolean
_DtTermPrimSelectPasteClipboard
(
Widget w
);
extern
Boolean
_DtTermPrimSelectCopyClipboard
(
Widget w,
Time copy_time
);
extern
void
_DtTermPrimSelectProcessCancel(
Widget w,
XEvent *event,
String *params,
Cardinal *num_params );
extern
void
_DtTermPrimSelectInitBtnEvents(
Widget w);
#ifdef __cplusplus
} /* close scope of 'extern "C"'... */
#endif /* __cplusplus */
#ifdef DEBUG_INCLUDES
#include "TermPrimSelectP.h"
#endif /* DEBUG_INCLUDES */
#endif /* _Dt_TermPrimSelect_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,114 @@
/*
** $XConsortium: TermPrimSelectP.h /main/1 1996/04/21 19:19:31 drk $
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimSelectP_h
#define _Dt_TermPrimSelectP_h
#include <Xm/Xm.h>
#include "TermPrimSelect.h"
typedef enum { scanLeft, scanRight } TermScanDirection;
typedef struct _termSelectRec
{
XEvent *event;
String *params;
Cardinal *num_params;
} _TermSelectRec;
typedef struct _TermSelectPrimary
{
Atom target;
Time time;
int num_chars;
int ref_count;
} _TermSelectPrimaryRec;
typedef int selectPosition;
typedef struct _TermSelectionHint
{
int x;
int y;
} TermSelectionHint;
/*
** Selection specific information.
*/
typedef struct _termSelectInfoRec
{
Boolean ownPrimary; /* do we own the primary selection? */
Time primaryTime; /* time primary selection acquired */
TermSelectType selectType; /* rectanglar selection ? */
short scanArraySize;
XmTextScanType *scanArray; /* possible values for scanType */
XmTextScanType scanType; /* line, word, character, all */
XtIntervalId selectID; /* AppTimeOut ID */
short rows; /* rows,cols current buffer useful */
short columns; /* for converting position->row,col */
XmTextPosition anchor; /* anchor for extending selecions */
XmTextPosition begin; /* upper left corner of selection */
XmTextPosition end; /* lower right corner of selection */
XmTextPosition origBegin; /* upper left corner of selection */
XmTextPosition origEnd; /* lower right corner of selection */
TermScanDirection extendDir; /* direction to extend selection */
TermScanDirection direction; /* select right or left? */
Time lastTime; /* time of last button press */
Boolean extending; /* true if extending selection */
int threshold; /* minimum # of pixels moved */
TermSelectionHint hint; /* initial coordinates of selection */
TermSelectionHint extend; /* coordinates of extend event */
Boolean cancel; /* used to end scroll selection */
Boolean isScrollUp; /* scroll selection direction */
Boolean sel_start; /* doing selection (True) or drag */
} TermSelectInfoRec;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
static Time
getServerTime
(
Widget w
);
static void
setScanType
(
Widget w,
XEvent *event
);
typedef struct {
Widget widget;
XmTextPosition insert_pos;
int num_chars;
Time timestamp;
Boolean move;
} _DtTermDropTransferRec;
#ifndef _XmConst
#define _XmConst /**/
#endif
void
_DtTermPrimSelect2ButtonMouse(
Widget w,
XEvent *event,
char **params,
Cardinal *num_params
);
#ifdef __cplusplus
} /* close scope of 'extern "C"'... */
#endif /* __cplusplus */
#endif /* _Dt_TermPrimSelectP_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,754 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$TOG: TermPrimSetPty.c /main/2 1998/04/03 17:11:24 mgreess $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#include "TermHeader.h"
#include "TermPrimOSDepI.h"
#include "TermPrimDebug.h"
#include <fcntl.h>
#ifdef ALPHA_ARCHITECTURE
#include <sys/ioctl.h>
#include <sys/ttydev.h>
#endif /* ALPHA_ARCHITECTURE */
#include <termios.h>
#ifdef USE_PTYS
#ifdef HP_ARCHITECTURE
#include <sys/ptyio.h>
#endif /* HP_ARCHITECTURE */
#endif /* USE_PTYS */
#if defined(HP_ARCHITECTURE) && !(OSMAJORVERSION > 9)
#include <bsdtty.h>
#endif /* defined(HP_ARCHITECTURE) && !(OSMAJORVERSION > 9) */
#if defined (USE_SETCSMAP)
#include <langinfo.h>
#include <sys/param.h>
#endif /* (USE_SETCSMAP) */
#ifdef USE_SRIOCSREDIR
#include <sys/strredir.h>
#include <sys/stat.h>
#endif /* USE_SRIOCSREDIR */
#ifdef USE_TIOCCONS
#ifdef IBM_ARCHITECTURE
#include <sys/ioctl.h>
#endif /* IBM_ARCHITECTURE */
#include <sys/stat.h>
#endif /* USE_TIOCCONS */
#ifdef LINUX_ARCHITECTURE
#include <sys/ioctl.h>
#endif /* LINUX_ARCHITECTURE */
#ifdef USE_STREAMS
#include <sys/types.h>
#include <stropts.h>
#include <sys/conf.h>
#endif /* USE_STREAMS */
#if defined (USE_CSWIDTH)
#include <sys/ioctl.h>
#include <sys/eucioctl.h>
#endif /* (USE_CSWIDTH) */
#include <sys/wait.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <Xm/Xm.h>
#define XTTYMODE_intr 0
#define XTTYMODE_quit 1
#define XTTYMODE_erase 2
#define XTTYMODE_kill 3
#define XTTYMODE_eof 4
#define XTTYMODE_eol 5
#define XTTYMODE_swtch 6
#define XTTYMODE_start 7
#define XTTYMODE_stop 8
#define XTTYMODE_brk 9
#define XTTYMODE_susp 10
#define XTTYMODE_dsusp 11
#define XTTYMODE_rprnt 12
#define XTTYMODE_flush 13
#define XTTYMODE_weras 14
#define XTTYMODE_lnext 15
#define NXTTYMODES 16
typedef struct _ttyMode
{
char *name;
int len;
int set;
char value;
}
ttyMode;
ttyMode _DtTermPrimTtyModeList[] =
{
{ "intr" , 4, 0, '\0' }, /* tchars.t_intrc ; VINTR */
{ "quit" , 4, 0, '\0' }, /* tchars.t_quitc ; VQUIT */
{ "erase", 5, 0, '\0' }, /* sgttyb.sg_erase ; VERASE */
{ "kill" , 4, 0, '\0' }, /* sgttyb.sg_kill ; VKILL */
{ "eof" , 3, 0, '\0' }, /* tchars.t_eofc ; VEOF */
{ "eol" , 3, 0, '\0' }, /* VEOL */
{ "swtch", 5, 0, '\0' }, /* VSWTCH */
{ "start", 5, 0, '\0' }, /* tchars.t_startc */
{ "stop" , 4, 0, '\0' }, /* tchars.t_stopc */
{ "brk" , 3, 0, '\0' }, /* tchars.t_brkc */
{ "susp" , 4, 0, '\0' }, /* ltchars.t_suspc */
{ "dsusp", 5, 0, '\0' }, /* ltchars.t_dsuspc */
{ "rprnt", 5, 0, '\0' }, /* ltchars.t_rprntc */
{ "flush", 5, 0, '\0' }, /* ltchars.t_flushc */
{ "weras", 5, 0, '\0' }, /* ltchars.t_werasc */
{ "lnext", 5, 0, '\0' }, /* ltchars.t_lnextc */
{ NULL, 0, 0, '\0' }, /* NULL terminate the array */
};
static int
parseTtyModes
(
char *modeString,
ttyMode *modeList
)
{
ttyMode *pMode;
int c, i;
int modeCount = 0;
/*
** Search to the end of the.
*/
while (1) {
/*
** Skip white space, if this is the end of the list,
** return.
*/
while (*modeString && isascii(*modeString) && isspace(*modeString))
{
modeString++;
}
if (!*modeString)
{
DebugF('p', 2, fprintf(stderr,
">>parseTtyModes() hit end of mode string, return=%d\n",
modeCount));
return(modeCount);
}
/*
** Otherwise, see if 'modeString' is in the list of mode names.
*/
for (pMode = modeList; pMode->name; pMode++)
{
DebugF('p', 2, fprintf(stderr,
">>parseTtyModes() comparing %.*s to %s\n",
pMode->len, modeString, pMode->name));
if (strncmp(modeString, pMode->name, pMode->len) == 0)
{
DebugF('p', 2, fprintf(stderr, ">>parseTtyModes() match!\n"));
break;
}
}
if (!pMode->name)
{
DebugF('p', 2, fprintf(stderr, ">>parseTtyModes() no match\n"));
return(-1);
}
/*
** Now look for a value for the setting.
** (Skip white space, return an error if no value.)
*/
modeString += pMode->len;
while (*modeString && isascii(*modeString) && isspace(*modeString))
{
modeString++;
}
if (!*modeString)
{
DebugF('p', 2, fprintf(stderr,
">>parseTtyModes() missing value\n"));
return(-1);
}
/*
** Make sure we handle control characters correctly.
*/
if (*modeString == '^')
{
modeString++;
/*
** keep control bits
*/
c = ((*modeString == '?') ? 0177 : *modeString & 31);
}
else
{
c = *modeString;
}
/*
** Set the values, and get go back for more.
*/
pMode->value = c;
pMode->set = 1;
modeCount++;
modeString++;
}
/* return(modeCount); */
}
#if defined (USE_CSWIDTH)
#define FIND_NUMBER(x, cp) \
{ \
x = 0; \
while (*cp && isdigit(*cp)) \
{ \
x *= 10; \
x += (*cp - '0'); \
cp++; \
} \
}
/*
** parse the cswidth string
** it should be in the form: X1[[:Y1][,X2[:Y2][,X3[:Y3]]]]
*/
static void
parseCSWidth
(
char *cp,
eucioc_t *wp
)
{
int x;
int i;
/*
** set all cs widths to 0
*/
wp->eucw[1] = wp->eucw[2] = wp->eucw[3] = 0;
wp->scrw[1] = wp->scrw[2] = wp->scrw[3] = 0;
if (!cp)
{
return;
}
DebugF('p', 4, fprintf(stderr,
">>parseCSWidth(): csWidthString %s\n", cp));
for (i = 1; i <= 3; i++)
{
/*
** read Xn
*/
FIND_NUMBER(x, cp);
wp->eucw[i] = x;
if (!*cp)
{
wp->scrw[i] = wp->eucw[i];
return;
}
/*
** Yn might exist
*/
if (*cp == ':')
{
cp++;
FIND_NUMBER(x, cp);
wp->scrw[i] = x;
if (!*cp)
{
return;
}
}
else
{
wp->scrw[i] = wp->eucw[i];
}
cp++;
}
DebugF('p', 4, fprintf(stderr,"parseCSWidth():"));
DebugF('p', 4, fprintf(stderr,
" eucw[1] : %d, scrw[1] : %d\n", wp->eucw[1], wp->scrw[1]));
DebugF('p', 4, fprintf(stderr,
" eucw[2] : %d, scrw[2] : %d\n", wp->eucw[2], wp->scrw[2]));
DebugF('p', 4, fprintf(stderr,
" eucw[3] : %d, scrw[3] : %d\n", wp->eucw[3], wp->scrw[3]));
}
#endif /* (USE_CSWIDTH) */
void _DtTermPrimPtySendBreak(int pty, int msec)
{
#if defined(USE_TIOCBREAK)
(void) ioctl(pty, TIOCBREAK, 0);
#elif defined(USE_TCSBRK)
(void) ioctl(pty, TCSBRK, 0);
#elif defined(USE_TCSENDBREAK)
(void) tcsendbreak(pty, 0);
#else /* none specified... */
There is no RS232 break code specified for this architecture. See
TermPrimOSDepI.h for a list of #defines...
#endif /* rs232 break definition... */
}
void _DtTermPrimPtySetWindowSize(int pty, short pixelWidth, short pixelHeight,
short characterRows, short characterColumns)
{
struct winsize ws;
ws.ws_row = characterRows;
ws.ws_col = characterColumns;
ws.ws_xpixel = pixelWidth;
ws.ws_ypixel = pixelHeight;
(void) ioctl(pty, TIOCSWINSZ, &ws);
}
static struct termios refTio;
static int refValid = 0;
#if defined (USE_CSWIDTH)
/*
** default width settings for ldterm
*/
static eucioc_t refWp;
#endif /* (USE_CSWIDTH) */
void
_DtTermPrimPtyGetDefaultModes()
{
int tty = -1;
int refTty = -1;
#if defined (USE_CSWIDTH)
struct strioctl i_str;
#endif /* (USE_CSWIDTH) */
_DtTermProcessLock();
if (!refValid) {
/* see if we can get a reference tty to get our base reference from...
*/
if ((tty = open("/dev/tty", O_RDONLY, 0)) >= 0) {
if (!tcgetattr(tty, &refTio)) {
/* we got a valid reference tty... */
DebugF('p', 3, fprintf(stderr,
">>_DtTermPrimPtyGetDefaultModes() valid reference \"/dev/tty\"\n"));
refTty = tty;
refValid = 1;
}
}
if (!refValid) {
for (refTty = 0; refTty < 3; refTty++) {
if (!tcgetattr(refTty, &refTio)) {
DebugF('p', 3, fprintf(stderr,
">>_DtTermPrimPtyGetDefaultModes() valid reference \fd %d\n", refTty));
refValid = 1;
break;
}
}
}
#if defined (USE_CSWIDTH)
if (refValid && (MB_CUR_MAX > 1))
{
/*
** we are in a wide character locale, get the current
** width settings...
*/
i_str.ic_cmd = EUC_WGET;
i_str.ic_timout = 0;
i_str.ic_len = sizeof(struct eucioc);
i_str.ic_dp = (char *)&refWp;
(void)ioctl(refTty, I_STR, &i_str);
}
#endif /* (USE_CSWIDTH) */
/* all done...
*/
/* close off the "/dev/tty" fd... */
if (tty >= 0) {
(void) close(tty);
}
}
_DtTermProcessUnlock();
}
void
_DtTermPrimPtyInit
(
int pty,
char *modeString,
char *csWidthString
)
{
struct termios tio;
#if defined (USE_CSWIDTH)
struct strioctl i_str;
eucioc_t wp;
#endif /* (USE_CSWIDTH) */
#if defined (USE_SETCSMAP)
/*
** set thing up so we can use setcsmap()
** for the time being, this is IBM specific
*/
char path[MAXPATHLEN];
int oldStdin = -1;
#endif /* (USE_SETCSMAP) */
#ifdef NOTDEF
#ifdef USE_STREAMS
if (ioctl(pty, I_PUSH, "ptem") < 0) {
(void) perror("I_PUSH ptem");
}
if (ioctl(pty, I_PUSH, "ldterm") < 0) {
(void) perror("I_PUSH ldterm");
}
if (ioctl(pty, I_PUSH, "ttcompat") < 0) {
(void) perror("I_PUSH ttcompat");
}
#endif /* USE_STREAMS */
#endif /* NOTDEF */
if (refValid) {
/* we will start from the reference tty...
*/
/* we already got the termios structure. No need to get again... */
DebugF('p', 3, fprintf(stderr,
">>_DtTermPrimPtyInit() using refTio\n"));
tio = refTio;
#if defined (USE_CSWIDTH)
/*
** use the cs width information from the reference...
*/
wp = refWp;
#endif /* (USE_CSWIDTH) */
/* DKS: are there any other terminal states we need to get?... */
} else {
/* let's set a reasonable default... */
DebugF('p', 3, fprintf(stderr,
">>_DtTermPrimPtyInit() generating default termio\n"));
(void) memset(&tio, '\0', sizeof(tio));
tio.c_iflag = ICRNL | IXON | IXOFF;
tio.c_oflag = OPOST | ONLCR | TAB3;
tio.c_cflag = B9600 | CS8 | CREAD | PARENB | HUPCL;
tio.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK|IEXTEN|ECHOCTL|ECHOKE;
/* DKS: this is termio specific. Do we need it?...
tio.c_line = 0;
*/
tio.c_cc[VINTR] = 0x7f; /* DEL */
tio.c_cc[VQUIT] = '\\' & 0x3f; /* '^\' */
tio.c_cc[VERASE] = '#'; /* '#' */
tio.c_cc[VKILL] = '@'; /* '@' */
tio.c_cc[VEOF] = 'D' & 0x3f; /* '^D' */
tio.c_cc[VEOL] = '@' & 0x3f; /* '^@' */
#ifdef VSWITCH
tio.c_cc[VSWITCH] = '@' & 0x3f; /* '^@' */
#endif /* VSWITCH */
#if defined (USE_CSWIDTH)
/*
** get the cs width information from the resource
*/
parseCSWidth(csWidthString, &wp);
#endif /* (USE_CSWIDTH) */
}
/* now, let's clean up certain flags... */
/* input: nl->nl, don't ignore cr, cr->nl
* turn on IXOFF pacing so that we can do paste without
* overflowing the buffer...
*/
tio.c_iflag &= ~(INLCR | IGNCR);
tio.c_iflag |= ICRNL | IXOFF;
/* output: cr->cr, nl is not return, no delays, nl->cr/nl
*/
tio.c_oflag &= ~(OCRNL | ONLRET | NLDLY | CRDLY | TABDLY |
BSDLY | VTDLY | FFDLY);
tio.c_oflag |= ONLCR;
/* baud rate is 9600 (nice default), turn off clocal and turn on
* hupcl so that the last close will SIGHUP processes running on
* the tty...
*/
tio.c_cflag &= ~(CBAUD | CLOCAL);
tio.c_cflag |= B9600 | HUPCL;
/* enable signals, canonical processing (erase, kill, etc), echo...
*/
tio.c_lflag |= ISIG | ICANON | ECHO | IEXTEN | ECHOCTL | ECHOKE;
/* reset EOL to the default value (ksh mucks this up sometimes)...
*/
tio.c_cc[VEOL] = '@' & 0x3f; /* '^@' */
/* reset EOF to the default value (ksh and csh muck with this)... */
tio.c_cc[VEOF] = 'D' & 0x3f; /* '^D' */
/*
** Now its time to handle the ttyModes
** Decide if the user supplied a ttyModes resource, if so then
** parse it and if it was a legal mode string, pass the parse result
*/
#define TMODE(ind,var) if (_DtTermPrimTtyModeList[ind].set) var = _DtTermPrimTtyModeList[ind].value;
_DtTermProcessLock();
if (modeString)
{
if (parseTtyModes(modeString, _DtTermPrimTtyModeList) < 0)
{
/*
** NOTE: should we prepend the program name to this string?
*/
fprintf(stderr, "Bad tty modes \"%s\"\n", modeString);
}
else
{
TMODE (XTTYMODE_intr, tio.c_cc[VINTR]);
TMODE (XTTYMODE_quit, tio.c_cc[VQUIT]);
TMODE (XTTYMODE_erase, tio.c_cc[VERASE]);
TMODE (XTTYMODE_kill, tio.c_cc[VKILL]);
TMODE (XTTYMODE_eof, tio.c_cc[VEOF]);
TMODE (XTTYMODE_eol, tio.c_cc[VEOL]);
#if defined(HP_ARCHITECTURE)
TMODE (XTTYMODE_swtch, tio.c_cc[VSWTCH]);
TMODE (XTTYMODE_susp, tio.c_cc[VSUSP]);
#if OSMAJORVERSION > 9
/* HP-UX 10.0 supports the new, extended c_cc[] array...
*/
TMODE (XTTYMODE_start, tio.c_cc[VSTART]);
TMODE (XTTYMODE_stop, tio.c_cc[VSTOP]);
TMODE (XTTYMODE_dsusp, tio.c_cc[VDSUSP]);
#ifdef NOTDEF
/* the following two parameters are not supported by
* HP-UX 10.0.
*/
TMODE (XTTYMODE_rprnt, tio.c_cc[VREPRINT]);
TMODE (XTTYMODE_flush, tio.c_cc[VDISCARD]);
#endif /* NOTDEF */
TMODE (XTTYMODE_weras, tio.c_cc[VWERASE]);
TMODE (XTTYMODE_lnext, tio.c_cc[VLNEXT]);
#else /* OSMAJORVERSION > 9 */
{
/* With HP-UX 9.0 (and earlier) we need to set dsuspc
* via the ltchars array. In addition, we have no support
* for rprnt, flush, weras, and lnext...
*/
struct ltchars ltc;
if (!ioctl(pty, TIOCGLTC, &ltc)) {
TMODE (XTTYMODE_dsusp, ltc.t_dsuspc);
(void) ioctl(pty, TIOCSLTC, &ltc);
}
}
#endif /* OSMAJORVERSION > 9 */
#elif defined(IBM_ARCHITECTURE)
TMODE (XTTYMODE_start, tio.c_cc[VSTRT]);
TMODE (XTTYMODE_stop, tio.c_cc[VSTOP]);
TMODE (XTTYMODE_susp, tio.c_cc[VSUSP]);
TMODE (XTTYMODE_dsusp, tio.c_cc[VDSUSP]);
TMODE (XTTYMODE_rprnt, tio.c_cc[VREPRINT]);
TMODE (XTTYMODE_flush, tio.c_cc[VDISCRD]);
TMODE (XTTYMODE_weras, tio.c_cc[VWERSE]);
TMODE (XTTYMODE_lnext, tio.c_cc[VLNEXT]);
#elif defined(SUN_ARCHITECTURE)
TMODE (XTTYMODE_swtch, tio.c_cc[VSWTCH]);
TMODE (XTTYMODE_start, tio.c_cc[VSTART]);
TMODE (XTTYMODE_stop, tio.c_cc[VSTOP]);
TMODE (XTTYMODE_susp, tio.c_cc[VSUSP]);
TMODE (XTTYMODE_dsusp, tio.c_cc[VDSUSP]);
TMODE (XTTYMODE_rprnt, tio.c_cc[VREPRINT]);
TMODE (XTTYMODE_flush, tio.c_cc[VDISCARD]);
TMODE (XTTYMODE_weras, tio.c_cc[VWERASE]);
TMODE (XTTYMODE_lnext, tio.c_cc[VLNEXT]);
#elif defined(ALPHA_ARCHITECTURE)
TMODE (XTTYMODE_start, tio.c_cc[VSTART]);
TMODE (XTTYMODE_stop, tio.c_cc[VSTOP]);
TMODE (XTTYMODE_susp, tio.c_cc[VSUSP]);
TMODE (XTTYMODE_dsusp, tio.c_cc[VDSUSP]);
TMODE (XTTYMODE_rprnt, tio.c_cc[VREPRINT]);
TMODE (XTTYMODE_flush, tio.c_cc[VDISCARD]);
TMODE (XTTYMODE_weras, tio.c_cc[VWERASE]);
TMODE (XTTYMODE_lnext, tio.c_cc[VLNEXT]);
#endif
}
#undef TMODE
}
_DtTermProcessUnlock();
(void) tcsetattr(pty, TCSADRAIN, &tio);
#if defined (USE_CSWIDTH)
if (MB_CUR_MAX > 1)
{
/*
** we are in a wide character locale, set the cs
** width settings...
*/
i_str.ic_cmd = EUC_WSET;
i_str.ic_timout = 0;
i_str.ic_len = sizeof(struct eucioc);
i_str.ic_dp = (char *)&wp;
(void)ioctl(pty, I_STR, &i_str);
}
#endif /* (USE_CSWIDTH) */
#if defined (USE_SETCSMAP)
/*
** NOTE:
** Setcsmap() only operates on STDIN, so we have to do some
** munging around to map the pty to STDIN in order to get
** the desired result. This may seem wasteful, but it
** makes it easier to encapsulate the OS dependencies in
** this function.
*/
if (pty != 0)
{
oldStdin = fcntl(0, F_DUPFD, 1);
(void) close(0);
(void) dup(pty);
}
sprintf(path, "%s%s", CSMAP_DIR, nl_langinfo(CODESET));
if(access(path, E_ACC|R_ACC) == 0)
{
setcsmap(path);
}
if (pty != 0)
{
(void) close(0);
if (oldStdin >= 0)
{
(void) dup(oldStdin);
(void) close(oldStdin);
}
}
#endif /* (USE_SETCSMAP) */
}
#if defined(USE_TIOCCONS)
#ifndef CONSOLE_DEVICE
#define CONSOLE_DEVICE "/dev/console"
#endif /* CONSOLE_DEVICE */
void _DtTermPrimPtyConsoleModeEnable(int pty)
{
struct stat st;
int one = 1;
/* check to see if we are the owner of the device... */
if (!stat(CONSOLE_DEVICE, &st)) {
/* stat succeeded... */
if (st.st_uid == getuid()) {
/* we are the owner, check the access... */
if (!access(CONSOLE_DEVICE, R_OK | W_OK)) {
/* and we can read/write it... */
/* we need to be setuid root... */
(void) _DtTermPrimToggleSuidRoot(True);
if (ioctl(pty, TIOCCONS, &one)) {
/* failure, errno was set... */
(void) perror(CONSOLE_DEVICE);
(void) fprintf(stderr,
"attempt to make tty the console failed\n");
}
/* we no longer need to be suid root... */
(void) _DtTermPrimToggleSuidRoot(False);
} else {
/* we can't read/write it... */
(void) perror(CONSOLE_DEVICE);
(void) fprintf(stderr, "-C console access denied\n");
}
} else {
/* we are not the owner -- return an access owner... */
errno = EACCES;
(void) perror(CONSOLE_DEVICE);
(void) fprintf(stderr, "-C console access denied\n");
}
} else {
/* we were unable to stat the file, errno is already set,
* failure...
*/
(void) perror(CONSOLE_DEVICE);
(void) fprintf(stderr, "-C console access denied\n");
}
}
#elif defined(USE_SRIOCSREDIR)
#ifndef CONSOLE_DEVICE
#define CONSOLE_DEVICE "/dev/console"
#endif /* CONSOLE_DEVICE */
void _DtTermPrimPtyConsoleModeEnable(int pty)
{
struct stat st;
int consoleFd;
/* check to see if we are the owner of the device... */
if (!stat(CONSOLE_DEVICE, &st)) {
/* stat succeeded... */
if (st.st_uid == getuid()) {
/* we are the owner, open the file... */
if ((consoleFd = open("/dev/console", O_RDWR | O_NOCTTY)) >= 0) {
if (ioctl(consoleFd, SRIOCSREDIR, pty) == -1) {
(void) perror(CONSOLE_DEVICE);
(void) fprintf(stderr,
"attempt to make tty the console failed\n");
}
(void) close(consoleFd);
} else {
/* we can't open it for reading and writing... */
(void) perror(CONSOLE_DEVICE);
(void) fprintf(stderr, "-C console access denied\n");
}
} else {
/* we are not the owner -- return an access owner... */
errno = EACCES;
(void) perror(CONSOLE_DEVICE);
(void) fprintf(stderr, "-C console access denied\n");
}
} else {
/* we were unable to stat the file, errno is already set,
* failure...
*/
(void) perror(CONSOLE_DEVICE);
(void) fprintf(stderr, "-C console access denied\n");
}
}
#else
void _DtTermPrimPtyConsoleModeEnable(int pty)
{
(void) fprintf(stderr,
"-C console access not supported on this architecture\n");
}
#endif

View File

@@ -0,0 +1,21 @@
/*
* $XConsortium: TermPrimSetPty.h /main/1 1996/04/21 19:19:37 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimSetPty_h
#define _Dt_TermPrimSetPty_h
void _DtTermPrimPtySendBreak(int pty, int msec);
void _DtTermPrimPtyGetDefaultModes();
void _DtTermPrimPtyInit(int pty, char *modeString, char *csWidthString);
void _DtTermPrimPtySetWindowSize(int pty, short pixelWidth, short pixelHeight,
short characterRows, short characterColumns);
void _DtTermPrimPtyConsoleModeEnable(int pty);
#endif /* _Dt_TermPrimSetPty_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,546 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$TOG: TermPrimSetUtmp.c /main/10 1998/04/03 17:11:42 mgreess $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#include "TermPrimDebug.h"
#include "TermHeader.h"
#include <Xm/Xm.h>
#include <TermPrimP.h>
#include <TermPrimSetUtmp.h>
#include <TermPrimUtil.h>
/* for sigprocmask... */
#include <signal.h>
/* for open... */
#include <fcntl.h>
/* for getpw*() and getlogin() calls... */
#define X_INCLUDE_PWD_H
#define X_INCLUDE_NETDB_H
#define X_INCLUDE_UNISTD_H
#define XOS_USE_XT_LOCKING
#include <X11/Xos_r.h>
#ifdef linux
#define UT_NO_pututline
#endif /* sun */
#ifdef sun
#define UT_UTMPX
#define UT_HOST ut_host
#define UT_HOST_LEN ut_syslen
#define UT_NO_pututline
#endif /* sun */
#ifdef __hpux
#define UT_HOST ut_host
#define UT_ADDR ut_addr
#endif /* __hpux */
#ifdef __AIX
#define UT_HOST ut_host
#define UT_NO_pututline
#endif /* __AIX */
#ifdef __osf__
#define UT_HOST ut_host
#define UT_NO_pututline
#endif /* __osf__ */
/* /etc/utmp include files... */
#ifdef UT_UTMPX
#include <utmpx.h>
#define getutent getutxent
#define getutid getutxid
#define getutline getutxline
#ifdef NOTDEF
#define pututline(entry) updwtmpx(UTMPX_FILE, entry)
#endif /* NOTDEF */
#define pututline pututxline
#define setutent setutxent
#define endutent endutxent
#define utmp utmpx
#define ut_time ut_tv.tv_sec
#else /* UT_UTMPX */
#include <utmp.h>
#endif /* UT_UTMPX */
/* gethostbyname include files... */
#include <sys/socket.h>
#include <netinet/in.h>
typedef struct _utmpInfo {
char *utmpLine;
struct _utmpInfo *next;
struct _utmpInfo *prev;
} utmpInfo;
static utmpInfo _utmpInfoHead;
static utmpInfo *utmpInfoHead = &_utmpInfoHead;
void
_DtTermPrimUtmpAddEntry
(
char *utmpLine
)
{
utmpInfo *utmpInfoTmp;
sigset_t newSigs;
sigset_t oldSigs;
/* malloc a new entry... */
utmpInfoTmp = (utmpInfo *) XtMalloc(sizeof(utmpInfo));
(void) memset(utmpInfoTmp, '\0', sizeof(utmpInfo));
/* fill in the structure... */
utmpInfoTmp->utmpLine = (char *) XtMalloc(strlen(utmpLine) + 1);
(void) strcpy(utmpInfoTmp->utmpLine, utmpLine);
/* insert it after the head of the list...
*/
/* block all signals... */
(void) sigfillset(&newSigs);
(void) sigemptyset(&oldSigs);
(void) sigprocmask(SIG_BLOCK, &newSigs, &oldSigs);
/* insert the entry into the list... */
_DtTermProcessLock();
utmpInfoTmp->prev = utmpInfoHead;
utmpInfoTmp->next = utmpInfoHead->next;
utmpInfoHead->next = utmpInfoTmp;
if (utmpInfoTmp->next) {
utmpInfoTmp->next->prev = utmpInfoTmp;
}
_DtTermProcessUnlock();
/* restore signals... */
(void) sigprocmask(SIG_SETMASK, &oldSigs, (sigset_t *) 0);
}
static void
DeleteUtmpInfo
(
char *utmpLine
)
{
utmpInfo *utmpInfoTmp;
sigset_t newSigs;
sigset_t oldSigs;
_DtTermProcessLock();
/* find the entry... */
for (utmpInfoTmp = utmpInfoHead->next; utmpInfoTmp;
utmpInfoTmp = utmpInfoTmp->next) {
if (!strcmp(utmpInfoTmp->utmpLine, utmpLine)) {
break;
}
}
/* did we find anything... */
if (!utmpInfoTmp) {
/* not found... */
_DtTermProcessUnlock();
return;
}
/* delete entry from the list...
*/
/* block all signals... */
(void) sigfillset(&newSigs);
(void) sigemptyset(&oldSigs);
(void) sigprocmask(SIG_BLOCK, &newSigs, &oldSigs);
/* remove it... */
utmpInfoTmp->prev->next = utmpInfoTmp->next;
if (utmpInfoTmp->next) {
utmpInfoTmp->next->prev = utmpInfoTmp->prev;
}
/* restore signals... */
(void) sigprocmask(SIG_SETMASK, &oldSigs, (sigset_t *) 0);
/* free up the data... */
if (utmpInfoTmp->utmpLine) {
(void) XtFree(utmpInfoTmp->utmpLine);
utmpInfoTmp->utmpLine = (char *) 0;
}
(void) XtFree((char *) utmpInfoTmp);
_DtTermProcessUnlock();
}
static char *userName = (char *) 0;
Atom _DtTermPrim_XA_UtmpLine = (Atom) 0;
#ifdef UT_ADDR
static char *localHostname = (char *) 0;
#endif /* UT_ADDR */
#ifdef UT_NO_pututline
static struct utmp *
_pututline(struct utmp *ut)
{
(void) pututline(ut);
return(ut);
}
#endif /* UT_NO_pututline */
/* the following things should be done in the parent so that they will
* be available to all utmp entry creates which are done in the child.
* If we wait until we do the create, the info will not be passed back
* to the parent, and we will have to do it each and every time...
*/
void
_DtTermPrimUtmpInit(Widget w)
{
char buffer[BUFSIZ];
char *c;
struct passwd * pw_ret;
_Xgetpwparams pw_buf;
char *namebuf;
_Xgetloginparams login_buf;
#ifdef UT_ADDR
struct hostent * name_ret;
_Xgethostbynameparams name_buf;
#endif
_DtTermProcessLock();
if (!userName) {
/* getpw{uid,nam}_r routines fail on IBM when searching passwd info via NIS.
The AIX specific code could be removed after IBM fixes the problem. Note
that there could still be a failure on IBM platform if "USER" env variable
is not defined. In any case, we would really not want to rely on the env
variable.
*/
#if defined(XTHREADS) && defined(XUSE_MTSAFE_API) && defined(AIXV3)
if ((c = getenv("USER")) == NULL) {
#endif
/* get the user's name from:
* -/etc/utmp if possible,
* -/etc/passwd if not.
*/
if ((((namebuf = _XGetlogin(login_buf))) != NULL)
&& (((pw_ret = _XGetpwnam(namebuf, pw_buf))) != NULL)
&& (pw_ret->pw_uid == getuid())) {
userName = XtMalloc(strlen(namebuf) + 1);
(void) strcpy(userName, namebuf);
} else if (((pw_ret = _XGetpwuid(getuid(), pw_buf))) != NULL) {
userName = XtMalloc(strlen(pw_ret->pw_name) + 1);
(void) strcpy(userName, pw_ret->pw_name);
}
#if defined(XTHREADS) && defined(XUSE_MTSAFE_API) && defined(AIXV3)
}
else {
userName = XtMalloc(strlen(c) + 1);
(void) strcpy(userName, c);
}
#endif
}
if (!_DtTermPrim_XA_UtmpLine) {
_DtTermPrim_XA_UtmpLine = XInternAtom(XtDisplay(w), TermUtmpIdString, False);
}
#ifdef UT_ADDR
if (!localHostname && !gethostname(buffer, sizeof(buffer)) &&
(name_ret = _XGethostbyname(buffer, name_buf)) != NULL) {
localHostname = XtMalloc(strlen(buffer) + 1);
(void) strcpy(localHostname, buffer);
}
#endif /* UT_ADDR */
_DtTermProcessUnlock();
}
char *
_DtTermPrimUtmpGetUtLine(int pty, char *ptyName)
{
Boolean closePty = False;
char *c;
#ifdef DKS
/* use the same pty name that everyone else will use (the one
* returned by ttyname())...
*/
_Xttynameparams tty_buf;
/* if we weren't passed a pty, let's try opening ptyName. By using
* O_NOCTTY we are able to open the pty without accidentally becoming
* the session leader for it...
*/
if ((pty < 0) && ((pty = open(ptyName, O_RDWR | O_NOCTTY, 0)) >= 0)) {
closePty = True;
}
/* if we have a pty, use ttyname to get it's "canonical" name... */
if ((pty >= 0) && (c = _XTtyname(pty, tty_buf))) {
ptyName = c;
}
/* close the pty if we opened it... */
if (closePty) {
(void) close(pty);
pty = -1;
}
#endif /* DKS */
if (!strncmp(ptyName, "/dev/", strlen("/dev/"))) {
ptyName = ptyName + strlen("/dev/");
}
c = XtMalloc(strlen(ptyName) + 1);
(void) strcpy(c, ptyName);
return(c);
}
static char *
UtmpEntryCreate(Widget w, pid_t pid, char *utmpLine)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
struct termData *tpd = tw->term.tpd;
struct utmp ut;
struct utmp *utPtr;
char *c;
char *displayName;
time_t now;
Boolean closePty = False;
#ifdef UT_HOST
char *seat;
#endif /* UT_HOST */
#ifdef UT_ADDR
struct sockaddr_in from;
int fromLen;
#endif /* UT_ADDR */
/* initialize utmp stuff, just incase... */
(void) _DtTermPrimUtmpInit(w);
/* set up the entry to search for...
*/
/* create the ut_line... */
(void) strncpy(ut.ut_line, utmpLine, sizeof(ut.ut_line));
ut.ut_type = DEAD_PROCESS;
/* position to entry in utmp file... */
(void) setutent();
if (NULL == (utPtr = getutline(&ut))) {
/* build a base utmp entry... */
utPtr = &ut;
#ifdef __hpux
if (c = strstr(utmpLine, "tty")) {
c += strlen("tty");
} else if (c = strstr(utmpLine, "pts")) {
c += strlen("pts");
} else {
c = utmpLine;
if (strlen(utmpLine) > sizeof(utPtr->ut_id)) {
c += strlen(utmpLine) - sizeof(utPtr->ut_id);
}
}
(void) strncpy(utPtr->ut_id, c, sizeof(utPtr->ut_id));
#else /* __hpux */
#if defined(__AIX) || defined(__osf__)
(void) strncpy(utPtr->ut_id, utmpLine,
sizeof(utPtr->ut_id));
#else /* __AIX || __osf__ */
#if defined(linux) || defined(sun) || defined(USL) || defined(__uxp__)
if (c = strchr(utmpLine, '/')) {
c++;
} else {
c = utmpLine;
}
(void) strncpy(utPtr->ut_id, c, sizeof(utPtr->ut_id));
#else /* linux || sun || USL || __uxp__ */
error out -- missing code for utPtr->ut_id
#endif /* sun */
#endif /* __AIX || __osf__ */
#endif /* __hpux */
}
/* set up the new entry... */
utPtr->ut_type = USER_PROCESS;
#if !defined(linux)
utPtr->ut_exit.e_termination = 0;
utPtr->ut_exit.e_exit = 2;
#endif
(void) strncpy(utPtr->ut_user, (userName && *userName) ? userName : "????",
sizeof(utPtr->ut_user));
(void) strncpy(utPtr->ut_line, utmpLine, sizeof(utPtr->ut_line));
utPtr->ut_pid = pid;
(void) time(&now);
utPtr->ut_time = now;
/* clear and set the host and addr fields... */
#ifdef UT_HOST
(void) memset(utPtr->UT_HOST, '\0', sizeof(utPtr->UT_HOST));
/* stuff the display name into ut_host. We will stuff as much as
* will fit dropping domain chunks as necessary to make it fit. If
* we still can't fit with the entire domain removed, we will truncate
* the display name...
*/
displayName = DisplayString(XtDisplay(w));
(void) strncpy(utPtr->UT_HOST, displayName, sizeof(utPtr->UT_HOST));
#ifdef UT_HOST_LEN
utPtr->UT_HOST_LEN = strlen(displayName + 1);
#endif /* UT_HOST_LEN */
if (sizeof(utPtr->UT_HOST) < strlen(displayName)) {
/* pull off the seat number... */
seat = strchr(displayName, ':');
/* back up through the display name. Each time we hit a '.' that
* signals the start of a new domain chunk, see if we can fit
* the display name (less these domain chunks) plus the seat number
* into the structure...
*/
if (seat - displayName < sizeof(utPtr->UT_HOST)) {
c = utPtr->UT_HOST + (seat - displayName) - 1;
} else {
c = utPtr->UT_HOST + sizeof(utPtr->UT_HOST) - 1;
}
for (; c >= utPtr->UT_HOST; c--) {
/* hit a '.'... */
if ((*c == '.') && (c - utPtr->UT_HOST + strlen(seat) <
sizeof(utPtr->UT_HOST))) {
/* everything left of the dot plus the seat will fit!... */
break;
}
}
if (c >= utPtr->UT_HOST) {
/* we can perform a fit with some domains stripped... */
(void) strncpy(c, seat, sizeof(utPtr->UT_HOST) -
(c - utPtr->UT_HOST));
if ((c - utPtr->UT_HOST) + strlen(seat) < sizeof(utPtr->UT_HOST)) {
/* null out the end of the host name... */
utPtr->UT_HOST[c - utPtr->UT_HOST + strlen(seat)] = '\0';
#ifdef UT_HOST_LEN
utPtr->UT_HOST_LEN = c - utPtr->UT_HOST + strlen(seat) + 1;
#endif /* UT_HOST_LEN */
}
} else {
/* we can't fit even a single full chunk from the domain.
* since it is more important to get the seat number in (the
* host can be obtained from the addr), truncate the host.
*/
(void) strncpy(utPtr->UT_HOST - strlen(seat), seat,
strlen(seat));
#ifdef UT_HOST_LEN
utPtr->UT_HOST_LEN = strlen(seat);
#endif /* UT_HOST_LEN */
}
}
#endif /* UT_HOST */
#ifdef UT_ADDR
(void) memset(&utPtr->ut_addr, '\0', sizeof(utPtr->ut_addr));
/* get the canonical host of the X socket... */
fromLen = sizeof(from);
if (!getpeername(ConnectionNumber(XtDisplay(w)), &from, &fromLen) &&
(from.sin_family == AF_INET)) {
utPtr->ut_addr = from.sin_addr.s_addr;
}
#endif /* UT_ADDR */
/* write it out... */
if (_pututline(utPtr)) {
/* success...
*/
(void) endutent();
return(utmpLine);
}
/* failure... */
(void) endutent();
return((char *) 0);
}
/* this is a public wrapper around the previous function that runs the
* previous function setuid root...
*/
char *
_DtTermPrimUtmpEntryCreate(Widget w, pid_t pid, char *utmpLine)
{
char *retValue;
/* this function needs to be suid root... */
(void) _DtTermPrimToggleSuidRoot(True);
retValue = UtmpEntryCreate(w, pid, utmpLine);
/* we now need to turn off setuid root... */
(void) _DtTermPrimToggleSuidRoot(False);
return(retValue);
}
static void
UtmpEntryDestroy(Widget w, char *utmpLine)
{
struct utmp ut;
struct utmp *utPtr;
time_t now;
ut.ut_type = USER_PROCESS;
(void) strncpy(ut.ut_line, utmpLine, sizeof(ut.ut_line));
(void) setutent();
if (utPtr = getutline(&ut)) {
utPtr->ut_type = DEAD_PROCESS;
#if !defined(linux)
utPtr->ut_exit.e_termination = 0;
utPtr->ut_exit.e_exit = 0;
#endif
(void) time(&now);
utPtr->ut_time = now;
#ifdef UT_HOST
(void) memset(utPtr->ut_host, '\0', sizeof(utPtr->ut_host));
#endif /* UT_HOST */
#ifdef UT_ADDR
(void) memset(&utPtr->ut_addr, '\0', sizeof(utPtr->ut_addr));
#endif /* UT_ADDR */
(void) pututline(utPtr);
}
(void) endutent();
(void) DeleteUtmpInfo(utmpLine);
}
/* this is a public wrapper around the previous function that runs the
* previous function setuid root...
*/
void
_DtTermPrimUtmpEntryDestroy(Widget w, char *utmpLine)
{
/* this function needs to be suid root... */
(void) _DtTermPrimToggleSuidRoot(True);
(void) UtmpEntryDestroy(w, utmpLine);
/* we now need to turn off setuid root... */
(void) _DtTermPrimToggleSuidRoot(False);
}
void
_DtTermPrimUtmpCleanup()
{
DebugF('s', 10, fprintf(stderr, ">>_DtTermPrimUtmpCleanup() starting\n"));
_DtTermProcessLock();
while (utmpInfoHead->next && utmpInfoHead->next->utmpLine) {
DebugF('s', 10, fprintf(stderr, ">>resetting utmp for id \"%s\"\n",
utmpInfoHead->next->utmpLine));
(void) _DtTermPrimUtmpEntryDestroy((Widget) 0,
utmpInfoHead->next->utmpLine);
}
_DtTermProcessUnlock();
DebugF('s', 10, fprintf(stderr, ">>_DtTermPrimUtmpCleanup() finished\n"));
}

View File

@@ -0,0 +1,26 @@
/*
* $XConsortium: TermPrimSetUtmp.h /main/2 1996/10/30 13:01:31 cde-hp $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimSetUtmp_h
#define _Dt_TermPrimSetUtmp_h
#define TermUtmpIdString "__TermUtmpId"
void _DtTermPrimUtmpInit(Widget w);
void _DtTermPrimUtmpAddEntry
(
char *utmpLine
);
char *_DtTermPrimUtmpGetUtLine(int pty, char *ptyName);
char *_DtTermPrimUtmpEntryCreate(Widget w, pid_t pid, char *utmpLine);
void _DtTermPrimUtmpEntryDestroy(Widget w, char *utId);
void _DtTermPrimUtmpCleanup();
#endif /* _Dt_TermPrimSetUtmp_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,634 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$TOG: TermPrimSubproc.c /main/11 1998/04/20 12:45:57 mgreess $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#include "TermHeader.h"
#include <fcntl.h>
#ifdef ALPHA_ARCHITECTURE
/* For TIOCSTTY definitions */
#include <sys/ioctl.h>
#endif /* ALPHA_ARCHITECTURE */
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#define X_INCLUDE_PWD_H
#define X_INCLUDE_UNISTD_H
#define XOS_USE_XT_LOCKING
#include <X11/Xos_r.h>
#include <Xm/Xm.h>
#if defined(HPVUE)
#include <Xv/EnvControl.h>
#else /* HPVUE */
#include <Dt/EnvControlP.h>
#endif /* HPVUE */
#include "TermPrimP.h"
#include "TermPrimI.h"
#include "TermPrimGetPty.h"
#include "TermPrimSetPty.h"
#include "TermPrimSubproc.h"
#include "TermPrimDebug.h"
#include "TermPrimUtil.h"
typedef struct _subprocInfo {
pid_t pid;
int stat_loc;
Widget w;
_termSubprocProc proc;
XtPointer client_data;
XtSignalId signal_id;
struct _subprocInfo *next;
struct _subprocInfo *prev;
} subprocInfo;
static subprocInfo _subprocHead;
static subprocInfo *subprocHead = &_subprocHead;
static pid_t
FakeFork (void)
{
static Boolean debugInit = True;
static int debugForkFailures = 0;
char *c;
if (isDebugFSet('f', 10)) {
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
_DtTermProcessLock();
if (debugInit) {
if (c = getenv("dttermDebugForkFailures")) {
debugForkFailures = strtol(c, (char **) 0, 0);
debugInit = 0;
}
}
if (debugForkFailures > 0) {
/* decrement the number of failures... */
(void) debugForkFailures--;
/* set our error return... */
errno = EAGAIN;
/* and error out... */
_DtTermProcessUnlock();
return(-1);
}
_DtTermProcessUnlock();
}
/* just do a fork()... */
return(fork());
}
/*ARGSUSED*/
static void
InvokeCallbacks(XtPointer client_data, XtSignalId *id)
{
subprocInfo *subprocTmp = (subprocInfo *) client_data;
if (subprocTmp->w && subprocTmp->proc)
(subprocTmp->proc)(subprocTmp->w, subprocTmp->pid, &subprocTmp->stat_loc);
}
_termSubprocId
_DtTermPrimAddSubproc(Widget w,
pid_t pid,
_termSubprocProc proc,
XtPointer client_data)
{
subprocInfo *subprocTmp;
/* malloc a new entry... */
subprocTmp = (subprocInfo *) XtCalloc(1, sizeof(subprocInfo));
/* fill in the structures... */
subprocTmp->pid = pid;
subprocTmp->w = w;
subprocTmp->proc = proc;
subprocTmp->client_data = client_data;
subprocTmp->signal_id = XtAppAddSignal(XtWidgetToApplicationContext(w),
InvokeCallbacks, subprocTmp);
/* insert it after the head of the list... */
_DtTermProcessLock();
subprocTmp->prev = subprocHead;
subprocTmp->next = subprocHead->next;
subprocHead->next = subprocTmp;
if (subprocTmp->next) {
subprocTmp->next->prev = subprocTmp;
}
_DtTermProcessUnlock();
/* return the pointer... */
return((_termSubprocId) subprocTmp);
}
void
_DtTermPrimSubprocRemoveSubproc(Widget w, _termSubprocId id)
{
subprocInfo *subprocTmp = (subprocInfo *) id;
/* remove the entry from the linked list...
*/
/* there will always be a head, so we can always update it... */
_DtTermProcessLock();
subprocTmp->w = NULL;
subprocTmp->prev->next = subprocTmp->next;
if (subprocTmp->next) {
subprocTmp->next->prev = subprocTmp->prev;
}
_DtTermProcessUnlock();
XtRemoveSignal(subprocTmp->signal_id);
/* free our storage... */
(void) XtFree((char *) subprocTmp);
}
/*ARGSUSED*/
static void
ReapChild(int sig)
{
pid_t pid;
int stat_loc;
int err = errno;
/* There may be several children waiting. */
while ((pid = waitpid(-1, &stat_loc, WNOHANG)) > 0)
DtTermSubprocReap(pid, &stat_loc);
/*
* Because our signal handler was installed with sigaction()
* instead of signal() it should remain installed after it is
* invoked, even on SVR4 machines. Otherwise we would need to
* reinstall it each time, creating a race condition in which
* signals could be lost.
*/
/* Preserve errno, like all good signal handlers should. */
errno = err;
}
void
_DtTermPrimSetChildSignalHandler(void)
{
struct sigaction new_action;
new_action.sa_handler = ReapChild;
sigemptyset(&new_action.sa_mask);
new_action.sa_flags = 0;
#ifdef SA_RESTART
new_action.sa_flags |= SA_RESTART;
#endif
/* Use new sigaction() signal handling semantics, not signal(). */
(void) sigaction(SIGCHLD, &new_action, (struct sigaction*) NULL);
}
void
DtTermSubprocReap(pid_t pid, int *stat_loc)
{
/*
* This procedure has special constraints, since it may be invoked
* inside a signal handler. That means it (and anything it calls)
* can only use POSIX async-signal safe library routines. A notable
* omission from the list of reentrant routines is pthread_mutex_lock(),
* which means we cannot call XtProcessLock() or XtAppLock().
*
* That makes it challenging to transfer the pid and stat_loc
* information out of the signal handler to a routine where it is
* safe to invoke callbacks. Storing them in static globals will not
* work, because overlapping signals may arrive. The approach used
* here is imperfect, but the best I could contrive. We block signals
* and then search the global data structures without using any locks.
* The routines that update the subprocHead list try not to leave it
* in a transient inconsistent state, but that cannot be guaranteed.
*/
subprocInfo *subprocTmp;
sigset_t new_sigs;
sigset_t old_sigs;
/*
* Block additional SIGCHLD signals temporarily. This is not
* necessary if the handler was installed with sigaction(), but we
* may be called from an application's signal handler, and it may
* have been installed with signal().
*/
(void) sigemptyset(&new_sigs);
(void) sigaddset(&new_sigs, SIGCHLD);
(void) sigprocmask(SIG_BLOCK, &new_sigs, &old_sigs);
if (pid > 0) {
/* find the subprocInfo structure for this subprocess... */
for (subprocTmp = subprocHead->next;
subprocTmp;
subprocTmp = subprocTmp->next) {
if (subprocTmp->pid == pid) {
if (subprocTmp->w && !subprocTmp->w->core.being_destroyed) {
subprocTmp->stat_loc = *stat_loc;
XtNoticeSignal(subprocTmp->signal_id);
}
break;
}
}
}
/* Restore SIGCHLD handling to its original state. */
(void) sigprocmask(SIG_SETMASK, &old_sigs, NULL);
}
pid_t
_DtTermPrimSubprocExec(Widget w,
char *ptyName,
Boolean consoleMode,
char *cwd,
char *cmd,
char **argv,
Boolean loginShell)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
static char *defaultCmd = (char *) 0;
int i;
int pty;
pid_t pid;
char *c;
int err;
#ifdef MOVE_FDS
int saveFd[3];
#else /* MOVE_FDS */
int savedStderr;
#endif /* MOVE_FDS */
Boolean argvFree = False;
struct sigaction sa;
sigset_t ss;
char buffer[BUFSIZ];
Widget parent;
char *namebuf;
struct passwd * pw;
_Xgetpwparams pw_buf;
_Xgetloginparams login_buf;
#ifdef ALPHA_ARCHITECTURE
/* merge code from xterm, ignore so that TIOCSWINSZ doesn't block */
signal(SIGTTOU, SIG_IGN);
#endif /* ALPHA_ARCHITECTURE */
/* build a default exec command and argv list if one wasn't supplied...
*/
/* cmd... */
/* the command will be taken as follows:
* - from the passed in cmd,
* - from $SHELL,
* - from the /etc/passwd entry for the /etc/utmp entry for this
* terminal,
* - from the /etc/passwd entry for this userid, or
* - /bin/sh.
*/
if (!cmd || !*cmd) {
if (!defaultCmd) {
/* from $SHELL... */
c = getenv("SHELL");
/* if not valid, try the /etc/passwd entry for the username
* associated with the /etc/utmp entry for this tty...
*/
if (!c || !*c) {
/* get the /etc/passwd entry for the username associated with
* /etc/utmp...
*/
if ((namebuf = _XGetlogin(login_buf)) != NULL) {
/* get the user's passwd entry... */
pw = _XGetpwnam(namebuf, pw_buf);
/* if we weren't able to come up with one for the
* username...
*/
if (pw != NULL)
c = pw->pw_shell;
}
}
/* if not valid, try the /etc/passwd entry for the username
* associate with the real uid...
*/
if (!c || !*c) {
/* if we weren't able to come up with one for the userid... */
pw = _XGetpwuid(getuid(), pw_buf);
if (pw != NULL) {
c = pw->pw_shell;
}
}
/* if not valid, use /bin/sh... */
if (!c || !*c) {
c = DEFAULT_SHELL;
}
/* malloc space for this string. It will be free'ed in the
* destroy function...
*/
defaultCmd = XtMalloc(strlen(c) + 1);
(void) strcpy(defaultCmd, c);
}
cmd = defaultCmd;
}
if (!argv) {
/* base it on cmd... */
argv = (char **) XtMalloc(2 * sizeof(char *));
/* if loginShell is set, then pre-pend a '-' to argv[0]. That's
* also why we allocate an extra byte in argv[0]...
*/
argv[0] = XtMalloc(strlen(cmd) + 2);
*argv[0] = '\0';
if (loginShell) {
/* pre-pend an '-' for loginShell... */
(void) strcat(argv[0], "-");
if (c = strrchr(cmd, '/')) {
strcat(argv[0], ++c);
} else {
strcat(argv[0], cmd);
}
} else {
(void) strcat(argv[0], cmd);
}
/* null term the list... */
argv[1] = (char *) 0;
/* we will need to free it up later... */
argvFree = True;
}
#ifdef OLDCODE
/* this is left around from when we were using vfork().... */
/* open the pty slave so that we can set the modes.
*
* NOTE: this code depends on support for the O_NOCTTY ioctl. This
* ioctl allows us to open the device without becoming the
* session group leader for it. If that can't be done, it may
* be necessary to rethink the way we open the pty slave...
*/
if ((pty = open(ptyName, O_RDWR | O_NOCTTY, 0)) < 0) {
(void) perror(ptyName);
return((pid_t) -1);
}
#endif /* OLDCODE */
#ifdef MOVE_FDS
/* move fd[0:2] out of the way for now... */
for (i = 0; i <= 2; i++) {
saveFd[i] = fcntl(i, F_DUPFD, 3);
(void) close(i);
}
#else /* MOVE_FDS */
savedStderr = fcntl(2, F_DUPFD, 3);
#endif /* MOVE_FDS */
/* set close on exec flags on all files... */
for (i = 0; i < _NFILE; i++) {
(void) fcntl(i, F_SETFD, 1);
}
/* fork. We can't use vfork() since we need to do lots of stuff
* below...
*/
if (isDebugSet('T')) {
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
(void) timeStamp("about to fork()");
}
_DtTermProcessLock();
for (i = 0; ((pid = FakeFork()) < 0) && (i < 10); i++) {
/* if we are out of process slots, then let's sleep a bit and
* try again...
*/
if (errno != EAGAIN) {
break;
}
/* give it a chance to clear up... */
(void) sleep((unsigned long) 2);
}
if (pid < 0) {
(void) perror("fork()");
#ifdef OLDCODE
/* this is left around from when we were using vfork().... */
(void) close(pty);
#endif /* OLDCODE */
return((pid_t) - 1);
} else if (pid == 0) {
/* child...
*/
_DtTermProcessUnlock();
#ifdef ALPHA_ARCHITECTURE
/* establish a new session for child */
setsid();
#else
/* do a setpgrp() so that we can... */
(void) setpgrp();
#endif /* ALPHA_ARCHITECTURE */
/* open the pty slave as our controlling terminal... */
pty = open(ptyName, O_RDWR, 0);
if (pty < 0) {
(void) perror(ptyName);
(void) _exit(1);
}
#ifdef ALPHA_ARCHITECTURE
/* BSD needs to do this to acquire pty as controlling terminal */
if (ioctl(pty, TIOCSCTTY, (char *)NULL) < 0) {
(void) close(pty);
(void) perror("Error acquiring pty slave as controlling terminal");
/* exit the subprocess */
_exit(1);
}
/* Do it when no controlling terminal doesn't work for OSF/1 */
_DtTermPrimPtyGetDefaultModes();
#endif /* ALPHA_ARCHITECTURE */
/* set the ownership and mode of the pty... */
(void) _DtTermPrimSetupPty(ptyName, pty);
/* apply the ttyModes... */
_DtTermPrimPtyInit(pty, tw->term.ttyModes, tw->term.csWidth);
/* set the window size... */
_DtTermPrimPtySetWindowSize(pty,
tw->term.columns * tw->term.widthInc +
(2 * (tw->primitive.shadow_thickness +
tw->primitive.highlight_thickness +
tw->term.marginWidth)),
tw->term.rows * tw->term.heightInc +
(2 * (tw->primitive.shadow_thickness +
tw->primitive.highlight_thickness +
tw->term.marginHeight)),
tw->term.rows, tw->term.columns);
/* if we are in console mode, turn it on... */
if (consoleMode) {
_DtTermPrimPtyConsoleModeEnable(pty);
}
#ifdef MOVE_FDS
/* that should have open'ed into fd 0. Dup it into fd's 1 and 2... */
(void) dup(pty);
(void) dup(pty);
#else /* MOVE_FDS */
/* dup pty into fd's 0, 1, and 2... */
for (i = 0; i < 3; i++) {
if (i != pty) {
(void) close(i);
(void) dup(pty);
}
}
if (pty >= 3) {
(void) close(pty);
}
#endif /* MOVE_FDS */
/* reset any alarms... */
(void) alarm(0);
/* reset all signal handlers... */
sa.sa_handler = SIG_DFL;
(void) sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
for (i = 1; i < NSIG; i++) {
(void) sigaction(i, &sa, (struct sigaction *) 0);
}
/* unblock all signals... */
(void) sigemptyset(&ss);
(void) sigprocmask(SIG_SETMASK, &ss, (sigset_t *) 0);
/*
** Restore the original (pre-DT) environment, removing any
** DT-specific environment variables that were added before
** we...
*/
#if defined(HPVUE)
#if (OSMINORVERSION > 01)
(void) VuEnvControl(VUE_ENV_RESTORE_PRE_VUE);
#endif /* (OSMINORVERSION > 01) */
#else /* (HPVUE) */
(void) _DtEnvControl(DT_ENV_RESTORE_PRE_DT);
#endif /* (HPVUE) */
/*
** set a few environment variables of our own...
*/
for (parent = w; !XtIsShell(parent); parent = XtParent(parent))
;
(void) sprintf(buffer, "%ld", XtWindow(parent));
_DtTermPrimPutEnv("WINDOWID=", buffer);
_DtTermPrimPutEnv("DISPLAY=", XDisplayString(XtDisplay(w)));
if (((DtTermPrimitiveWidget)w)->term.emulationId) {
_DtTermPrimPutEnv("TERMINAL_EMULATOR=",
((DtTermPrimitiveWidget)w)->term.emulationId);
}
/* set our utmp entry... */
(void) _DtTermPrimUtmpEntryCreate(w, getpid(),
((DtTermPrimitiveWidget)w)->term.tpd->utmpId);
if (isDebugSet('T')) {
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
(void) timeStamp("about to execvp()");
}
/* turn off suid forever...
*/
_DtTermPrimRemoveSuidRoot();
/* change to the requested directory... */
if (cwd && *cwd) {
(void) chdir(cwd);
}
#ifdef BBA
_bA_dump();
#endif /* BBA */
_DtEnvControl(DT_ENV_RESTORE_PRE_DT);
(void) execvp(cmd, argv);
/* if we got to this point we error'ed out. Let's write out the
* error...
*/
err = errno;
/* restore stderr... */
(void) close(2);
(void) dup(savedStderr);
/* restore errno... */
errno = err;
(void) perror(cmd);
/* and we need to exit the subprocess... */
_exit(1);
}
/* parent...
*/
_DtTermProcessUnlock();
if (isDebugSet('T')) {
#ifdef BBA
#pragma BBA_IGNORE
#endif /*BBA*/
(void) timeStamp("parent resuming");
}
#ifdef MOVE_FDS
/* DKS: we should check this out and see if it is necessary... */
(void) close(0);
(void) close(1);
(void) close(2);
/* move fd[0:2] back in place... */
for (i = 0; i <= 2; i++) {
if (saveFd[i] >= 0) {
(void) fcntl(saveFd[i], F_DUPFD, i);
(void) close(saveFd[i]);
}
}
#else /* MOVE_FDS */
(void) close(savedStderr);
#endif /* MOVE_FDS */
/* clean up malloc'ed memory... */
if (argvFree) {
(void) XtFree(argv[0]);
(void) XtFree((char *) argv);
}
#ifdef OLDCODE
/* since we no longer open it in the parent, we probably don't want
* to close it either...
*/
(void) close(pty);
#endif /* OLDCODE */
/* assume that our child set up a utmp entry (since we have no way
* for it to report to us) and add it to the list to cleanup)...
*/
_DtTermPrimUtmpAddEntry(((DtTermPrimitiveWidget)w)->term.tpd->utmpId);
return(pid);
}

View File

@@ -0,0 +1,31 @@
/*
* $XConsortium: TermPrimSubproc.h /main/3 1996/12/03 12:14:57 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimSubproc_h
#define _Dt_TermPrimSubproc_h
typedef void (*_termSubprocProc)(Widget w, pid_t pid, int *stat_loc);
typedef unsigned long _termSubprocId;
extern _termSubprocId _DtTermPrimAddSubproc(Widget w,
pid_t pid,
_termSubprocProc proc,
XtPointer client_data);
extern void _DtTermPrimSetChildSignalHandler(void);
extern void _DtTermPrimSubprocRemoveSubproc(Widget w, _termSubprocId id);
extern pid_t _DtTermPrimSubprocExec(Widget w,
char *ptyName,
Boolean consoleMode,
char *cwd,
char *cmd,
char **argv,
Boolean loginShell);
#endif /* _Dt_TermPrimSubproc_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,606 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$TOG: TermPrimUtil.c /main/3 1997/04/17 18:25:29 samborn $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#include "TermHeader.h"
#include "TermPrimOSDepI.h"
#include "TermPrimP.h"
#include "TermPrimData.h"
#include "TermPrimUtil.h"
#include "TermPrimDebug.h"
#include "Xm/Xm.h"
#include <errno.h>
#include <signal.h>
#include <sys/file.h>
void _DtTermPrimRemoveSuidRoot();
static void ForceCloseLog(DtTermPrimitiveWidget);
static void PointerMoved(Widget w, XtPointer closure, XEvent *event, Boolean *cont) ;
void _DtTermPrimPointerOff(Widget w, XtIntervalId *id) ;
/*
** the following white pixmap is used to create the noPointer (blank) pointer.
*/
#define whiteW 16
#define whiteH 16
static char whiteBits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static void
InitPointerBlank(Widget w)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
DtTermPrimData tpd = tw->term.tpd;
XColor fg = { 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 };
XColor bg = { 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 };
Pixmap noPointerBitmap;
/*
** set a pointer motion handler...
*/
tpd->pointerTimeoutID = 0 ;
tpd->pointerFrozen = True ;
fg.pixel = bg.pixel = BlackPixelOfScreen(XtScreen(w));
noPointerBitmap = XCreateBitmapFromData(XtDisplay(w),XtWindow(tw),
whiteBits, whiteW, whiteH);
tpd->noPointer = XCreatePixmapCursor(XtDisplay(tw),
noPointerBitmap, /* source bitmap */
noPointerBitmap, /* mask bitmap */
&fg, &bg, /* Do not care */
0, 0); /* hotspot */
XFreePixmap(XtDisplay(w), noPointerBitmap);
XtAddEventHandler((Widget)tw, PointerMotionMask, FALSE, PointerMoved,
(XtPointer)NULL);
tpd->pointerFirst = False ;
}
static void
PointerMoved(Widget w, XtPointer closure, XEvent *event, Boolean *cont)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
DtTermPrimData tpd = tw->term.tpd;
if (!tpd->pointerFrozen) {
if (tpd->pointerOn) {
/*
** pointer is on, just reset the timer...
*/
if (tw->term.pointerBlankDelay) {
/*
** remove the old motion timeout...
*/
if (tpd->pointerTimeoutID)
XtRemoveTimeOut(tpd->pointerTimeoutID);
/*
** and set a new motion timeout...
*/
tpd->pointerTimeoutID =
XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)tw),
(unsigned long) 1000 * tw->term.pointerBlankDelay,
(XtTimerCallbackProc) _DtTermPrimPointerOff,
(XtPointer)tw);
}
} else {
/* pointer is off, turn it on... */
(void) _DtTermPrimPointerOn(w);
}
}
}
void
_DtTermPrimPointerOff(Widget w, XtIntervalId *id)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
DtTermPrimData tpd = tw->term.tpd;
if (tpd->pointerFirst) InitPointerBlank(w) ;
if (tpd->pointerOn) {
/*
** define the window's cursor...
*/
(void) XDefineCursor(XtDisplay(tw), XtWindow(tw), tpd->noPointer);
/*
** remove the motion timeout...
*/
if (tw->term.pointerBlankDelay) {
if (tpd->pointerTimeoutID)
XtRemoveTimeOut(tpd->pointerTimeoutID);
tpd->pointerTimeoutID = 0;
}
/*
** and clear the pointer on flag...
*/
tpd->pointerOn = False;
}
return;
}
void
_DtTermPrimPointerOn(Widget w)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
DtTermPrimData tpd = tw->term.tpd;
if (tpd->pointerFirst) InitPointerBlank(w) ;
if (!tpd->pointerOn) {
/*
** define the window's cursor...
*/
XDefineCursor(XtDisplay(tw), XtWindow(tw), tw->term.pointerShape);
/*
** set a motion timeout...
*/
if (tw->term.pointerBlankDelay) {
if (tpd->pointerTimeoutID)
/*
** remove old timeout...
*/
XtRemoveTimeOut(tpd->pointerTimeoutID);
tpd->pointerTimeoutID =
XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)tw),
(unsigned long) (1000 * tw->term.pointerBlankDelay),
(XtTimerCallbackProc)_DtTermPrimPointerOff, (XtPointer)tw);
}
/*
** and set the pointer on flag...
*/
tpd->pointerOn = True;
}
return;
}
void
_DtTermPrimPointerFreeze(Widget w, Boolean freeze)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
DtTermPrimData tpd = tw->term.tpd;
tpd->pointerFrozen = freeze;
/*
** make sure that the pointer is on...
*/
if (tpd->pointerOn) {
/*
** pointer is on...
*/
if (tw->term.pointerBlankDelay) {
if (freeze) {
/*
** freezing -- turn the timeout off...
*/
if (tpd->pointerTimeoutID)
XtRemoveTimeOut(tpd->pointerTimeoutID);
tpd->pointerTimeoutID = 0;
}
else {
/*
** un freezing -- turn the timeout on...
*/
if (tpd->pointerTimeoutID)
/*
** remove old timeout...
*/
XtRemoveTimeOut(tpd->pointerTimeoutID);
tpd->pointerTimeoutID =
XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)tw),
(unsigned long) 1000 * tw->term.pointerBlankDelay,
(XtTimerCallbackProc) _DtTermPrimPointerOff,
(XtPointer)tw);
}
}
}
else {
/*
** let's turn on the pointer...
** define the window's cursor...
*/
XDefineCursor(XtDisplay(tw), XtWindow(tw), tw->term.pointerShape);
if (freeze)
/*
** the timeout is off, so we don't need to clear it...
*/
/* NOOP */ ;
else
/*
** we are unfreezing -- turn the timeout on...
*/
if (tw->term.pointerBlankDelay) {
if (tpd->pointerTimeoutID)
/*
** remove old timeout...
*/
XtRemoveTimeOut(tpd->pointerTimeoutID);
tpd->pointerTimeoutID =
XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)tw),
(unsigned long) (1000 * tw->term.pointerBlankDelay),
(XtTimerCallbackProc)_DtTermPrimPointerOff,(XtPointer)tw);
}
/*
** and set the flag...
*/
tpd->pointerOn = True;
}
return;
}
void
_DtTermPrimRecolorPointer(Widget w)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
XColor colordefs[2]; /* 0 is foreground, 1 is background */
Display *dpy = XtDisplay(w);
colordefs[0].pixel = tw->term.pointerColor;
colordefs[1].pixel = tw->term.pointerColorBackground;
XQueryColors (dpy, DefaultColormap (dpy, DefaultScreen (dpy)),
colordefs, 2);
XRecolorCursor (dpy, tw->term.pointerShape, colordefs, colordefs+1);
return;
}
/* linked list of log files to flush if we are killed...
*/
typedef struct _logInfo {
FILE *logFile;
struct _logInfo *next;
struct _logInfo *prev;
} logInfo;
static logInfo _logInfoHead;
static logInfo *logInfoHead = &_logInfoHead;
static void
AddLogFileEntry
(
FILE *logFile
)
{
logInfo *logInfoTmp;
sigset_t newSigs;
sigset_t oldSigs;
/* malloc a new entry... */
logInfoTmp = (logInfo *) XtMalloc(sizeof(logInfo));
(void) memset(logInfoTmp, '\0', sizeof(logInfo));
/* fill in the structure... */
logInfoTmp->logFile = logFile;
/* insert it after the head of the list...
*/
/* block all signals... */
(void) sigfillset(&newSigs);
(void) sigemptyset(&oldSigs);
(void) sigprocmask(SIG_BLOCK, &newSigs, &oldSigs);
/* insert the entry into the list... */
_DtTermProcessLock();
logInfoTmp->prev = logInfoHead;
logInfoTmp->next = logInfoHead->next;
logInfoHead->next = logInfoTmp;
if (logInfoTmp->next) {
logInfoTmp->next->prev = logInfoTmp;
}
_DtTermProcessUnlock();
/* restore signals... */
(void) sigprocmask(SIG_SETMASK, &oldSigs, (sigset_t *) 0);
}
static void
DeleteLogFileEntry
(
FILE *logFile
)
{
logInfo *logInfoTmp;
sigset_t newSigs;
sigset_t oldSigs;
/* find the entry... */
_DtTermProcessLock();
for (logInfoTmp = logInfoHead->next; logInfoTmp;
logInfoTmp = logInfoTmp->next) {
if (logInfoTmp->logFile == logFile) {
break;
}
}
/* did we find anything... */
if (!logInfoTmp) {
/* not found... */
_DtTermProcessUnlock();
return;
}
/* delete entry from the list...
*/
/* block all signals... */
(void) sigfillset(&newSigs);
(void) sigemptyset(&oldSigs);
(void) sigprocmask(SIG_BLOCK, &newSigs, &oldSigs);
/* remove it... */
logInfoTmp->prev->next = logInfoTmp->next;
if (logInfoTmp->next) {
logInfoTmp->next->prev = logInfoTmp->prev;
}
/* restore signals... */
(void) sigprocmask(SIG_SETMASK, &oldSigs, (sigset_t *) 0);
/* free up the data... */
(void) XtFree((char *) logInfoTmp);
_DtTermProcessUnlock();
}
#ifdef NOTDEF
void
logpipe(Widget w)
{
win_data *wp = &term->Wp;
if (wp->log_on) { CloseLog(wp); }
}
#endif /* NOTDEF */
void
_DtTermPrimStartLog(Widget w)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
DtTermPrimData tpd = tw->term.tpd;
char *cp;
int i;
if ( tw->term.log_on || tw->term.logInhibit ) { return; }
if (!tw->term.logFile || !*tw->term.logFile) {
tw->term.logFile = "DttermLogXXXXX";
}
if (!strcmp(tw->term.logFile + strlen(tw->term.logFile) - 5, "XXXXX")) {
/* make a local copy in case we are going to change it... */
cp = XtMalloc(strlen(tw->term.logFile) + 1);
(void) strcpy(cp, tw->term.logFile);
(void) mktemp(cp);
if (cp && *cp) {
tw->term.logFile = cp;
} else {
(void) XtFree(cp);
return;
}
}
if ('|' == *tw->term.logFile ) {
/*
** pipe logfile into command
*/
int p[2];
_DtTermProcessLock();
if (pipe(p) < 0 || (i = fork()) < 0) {
_DtTermProcessUnlock();
return;
}
if (i == 0) {
/*
** child
*/
_DtTermProcessUnlock();
/* Remove suid root capability...
*/
(void) _DtTermPrimRemoveSuidRoot();
(void) close(p[1]);
(void) close(0);
(void) dup(p[0]);
(void) close(p[0]);
/*
** set close on exec flag on all other fd's
*/ for (i = 3; i < _NFILE; i++) {
(void) fcntl(i, F_SETFD, 1);
}
/*
** reset signals
*/
(void) signal(SIGHUP, SIG_DFL);
(void) signal(SIGCLD, SIG_DFL);
#ifdef BBA
_bA_dump();
#endif /* BBA */
(void) execl(DEFAULT_SHELL, DEFAULT_SHELL_ARGV0,
"-c", &tw->term.logFile[1], 0);
(void) fprintf(stderr, " Can't exec \"%s\"\n",
&tw->term.logFile[1]);
(void) exit(1);
}
_DtTermProcessUnlock();
(void) close(p[0]);
tpd->logStream = fdopen(p[1], "w");
(void) AddLogFileEntry(tpd->logStream);
(void) signal(SIGPIPE, SIG_IGN);
}
else {
if (access(tw->term.logFile, F_OK) == 0) {
if (access(tw->term.logFile, W_OK) < 0) {
return;
}
} else if (cp = strrchr(tw->term.logFile, '/')) {
*cp = 0;
i = access(tw->term.logFile, W_OK);
*cp = '/';
if (i < 0) {
return;
}
} else if (access(".", W_OK) < 0) {
return;
}
if ((tpd->logStream = fopen(tw->term.logFile, "a")) == NULL) {
return;
}
(void) AddLogFileEntry(tpd->logStream);
(void) chown(tw->term.logFile, getuid(), getgid());
}
tw->term.log_on = True ;
}
static void
ForceCloseLog(DtTermPrimitiveWidget tw)
{
DtTermPrimData tpd = tw->term.tpd;
if (tw->term.log_on)
{
(void) fclose(tpd->logStream);
(void) DeleteLogFileEntry(tpd->logStream);
tw->term.log_on = False;
}
}
void
_DtTermPrimCloseLog(Widget w)
{
DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
DtTermPrimData tpd = tw->term.tpd;
/*
** if we are not logging, or it is inhibited, do nothing
*/
if (!tw->term.log_on || tw->term.logInhibit ) { return; }
(void) fflush(tpd->logStream);
ForceCloseLog(tw);
}
void
_DtTermPrimWriteLog(DtTermPrimitiveWidget tw, char *buffer, int cnt)
{
DtTermPrimData tpd = tw->term.tpd;
if (cnt > 0)
{
_DtTermProcessLock();
(void) fwrite(buffer, cnt, 1, tpd->logStream);
if ((errno == EPIPE) && ferror(tpd->logStream))
{
ForceCloseLog(tw);
}
_DtTermProcessUnlock();
}
}
static Boolean first = True;
static uid_t uid_user;
static uid_t uid_root;
static gid_t gid_user;
static gid_t gid_root;
static void
suidInit()
{
_DtTermProcessLock();
if (first) {
uid_user = getuid();
uid_root = geteuid();
gid_user = getgid();
gid_root = getegid();
first = False;
}
_DtTermProcessUnlock();
}
void
_DtTermPrimRemoveSuidRoot()
{
(void) suidInit();
#if defined(HAS_SETRESUID)
(void) setresgid(gid_user, gid_user, gid_user);
(void) setresuid(uid_user, uid_user, uid_user);
#elif defined(HAS_SETREUID)
(void) setregid(gid_user, gid_user);
(void) setreuid(uid_user, uid_user);
#else /* !HAS_SETRESUID && !HAS_SETREUID */
(void) setgid(gid_user);
(void) setuid(uid_user);
#endif /* !HAS_SETRESUID && !HAS_SETREUID */
}
void
_DtTermPrimToggleSuidRoot(Boolean root)
{
(void) suidInit();
#if defined(HAS_SETRESUID)
(void) setresuid(-1, root ? uid_root : uid_user, -1);
(void) setresgid(-1, root ? gid_root : gid_user, -1);
#elif defined(HAS_SETEUID)
(void) seteuid(root ? uid_root : uid_user);
(void) setegid(root ? gid_root : gid_user);
#endif /* HAS_SETEUID */
}
void
_DtTermPrimLogFileCleanup
(
void
)
{
logInfo *logInfoTmp;
DebugF('s', 10, fprintf(stderr,
">>_DtTermPrimLogFileCleanup() starting\n"));
/* flush all the log files... */
_DtTermProcessLock();
for (logInfoTmp = logInfoHead->next; logInfoTmp;
logInfoTmp = logInfoTmp->next) {
DebugF('s', 10, fprintf(stderr,
">>flushing logfile 0x%lx\n", logInfoTmp->logFile));
(void) fflush(logInfoTmp->logFile);
}
_DtTermProcessUnlock();
DebugF('s', 10, fprintf(stderr,
">>_DtTermPrimLogFileCleanup() finished\n"));
}

View File

@@ -0,0 +1,33 @@
/*
* $XConsortium: TermPrimUtil.h /main/2 1996/09/04 17:34:57 rswiston $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimUtil_h
#define _Dt_TermPrimUtil_h
#include <Xm/Xm.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
extern void _DtTermPrimPointerOn(Widget w);
extern void _DtTermPrimPointerOff(Widget w, XtIntervalId *id) ;
extern void _DtTermPrimPointerFreeze(Widget w, Boolean frozen) ;
extern void _DtTermPrimRecolorPointer(Widget w) ;
extern void _DtTermWriteLog(DtTermPrimitiveWidget tw, char *buffer, int len) ;
extern void _DtTermStartLog(Widget w) ;
extern void _DtTermCloseLog(Widget w) ;
extern void _DtTermPrimFlushLog(Widget w);
extern void _DtTermPrimLogFileCleanup(void);
extern void _DtTermPrimRemoveSuidRoot();
extern void _DtTermPrimToggleSuidRoot(Boolean root);
#endif /* _Dt_TermPrimUtil_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */

View File

@@ -0,0 +1,18 @@
/* $XConsortium: TermPrimVersion.c /main/2 1996/08/30 15:25:43 drk $
*
* (c) Copyright 1996 Digital Equipment Corporation.
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
* (c) Copyright 1993,1994,1996 Novell, Inc.
* (c) Copyright 1996 FUJITSU LIMITED.
* (c) Copyright 1996 Hitachi.
*/
#include <include/hpversion.h>
#ifndef lint
version_tag("DtTermPrimitiveWidget: $XConsortium: TermPrimVersion.c /main/2 1996/08/30 15:25:43 drk $")
#endif /* lint */
char _DtTermPrimPullInTermWhatString[] = "";

View File

@@ -0,0 +1,63 @@
#ifndef lint
#ifdef VERBOSE_REV_INFO
static char rcs_id[] = "$XConsortium: TermPrimWMProtocols.c /main/1 1996/04/21 19:20:04 drk $";
#endif /* VERBOSE_REV_INFO */
#endif /* lint */
/* *
* (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company *
* (c) Copyright 1993, 1994, 1996 International Business Machines Corp. *
* (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994, 1996 Novell, Inc. *
* (c) Copyright 1996 Digital Equipment Corporation. *
* (c) Copyright 1996 FUJITSU LIMITED. *
* (c) Copyright 1996 Hitachi. *
*/
#include "TermHeader.h"
#include "TermPrimDebug.h"
#include <Xm/Xm.h>
#include <Xm/Protocols.h>
static Atom xa_WM_DELETE_WINDOW;
static Atom xa_WM_SAVE_YOURSELF;
static Boolean initialized = False;
static void
protocolsInitialize(Widget topLevel)
{
if (!initialized) {
xa_WM_DELETE_WINDOW = XInternAtom(XtDisplay(topLevel),
"WM_DELETE_WINDOW", False);
xa_WM_SAVE_YOURSELF = XInternAtom(XtDisplay(topLevel),
"WM_SAVE_YOURSELF", False);
initialized = True;
}
}
void
_DtTermPrimAddDeleteWindowCallback(Widget topLevel, XtCallbackProc callback,
XtPointer client_data)
{
/* initialize things... */
_DtTermProcessLock();
if (!initialized)
(void) protocolsInitialize(topLevel);
_DtTermProcessUnlock();
(void) XmAddWMProtocols(topLevel, &xa_WM_DELETE_WINDOW, 1);
(void) XmAddWMProtocolCallback(topLevel, xa_WM_DELETE_WINDOW, callback,
client_data);
}
void
_DtTermPrimAddSaveYourselfCallback(Widget topLevel, XtCallbackProc callback,
XtPointer client_data)
{
/* initialize things... */
_DtTermProcessLock();
if (!initialized)
(void) protocolsInitialize(topLevel);
_DtTermProcessUnlock();
(void) XmAddWMProtocols(topLevel, &xa_WM_SAVE_YOURSELF, 1);
(void) XmAddWMProtocolCallback(topLevel, xa_WM_SAVE_YOURSELF, callback,
client_data);
}

View File

@@ -0,0 +1,19 @@
/*
* $XConsortium: TermPrimWMProtocols.h /main/1 1996/04/21 19:20:07 drk $";
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
#ifndef _Dt_TermPrimWMProtocols_h
#define _Dt_TermPrimWMProtocols_h
extern void _DtTermPrimAddDeleteWindowCallback(Widget topLevel,
XtCallbackProc callback, XtPointer client_data);
extern void _DtTermPrimAddSaveYourselfCallback(Widget topLevel,
XtCallbackProc callback, XtPointer client_data);
#endif /* _Dt_TermPrimWMProtocols_h */
/* DON'T ADD ANYTHING AFTER THIS #endif... */