Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
114
cde/lib/DtTerm/TermPrim/Imakefile
Normal file
114
cde/lib/DtTerm/TermPrim/Imakefile
Normal 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()
|
||||
56
cde/lib/DtTerm/TermPrim/TermHeader.h
Normal file
56
cde/lib/DtTerm/TermPrim/TermHeader.h
Normal 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... */
|
||||
4060
cde/lib/DtTerm/TermPrim/TermPrim.c
Normal file
4060
cde/lib/DtTerm/TermPrim/TermPrim.c
Normal file
File diff suppressed because it is too large
Load Diff
516
cde/lib/DtTerm/TermPrim/TermPrim.h
Normal file
516
cde/lib/DtTerm/TermPrim/TermPrim.h
Normal 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 */
|
||||
250
cde/lib/DtTerm/TermPrim/TermPrimAction.c
Normal file
250
cde/lib/DtTerm/TermPrim/TermPrimAction.c
Normal 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;
|
||||
}
|
||||
44
cde/lib/DtTerm/TermPrim/TermPrimAction.h
Normal file
44
cde/lib/DtTerm/TermPrim/TermPrimAction.h
Normal 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... */
|
||||
2391
cde/lib/DtTerm/TermPrim/TermPrimBuffer.c
Normal file
2391
cde/lib/DtTerm/TermPrim/TermPrimBuffer.c
Normal file
File diff suppressed because it is too large
Load Diff
648
cde/lib/DtTerm/TermPrim/TermPrimBuffer.h
Normal file
648
cde/lib/DtTerm/TermPrim/TermPrimBuffer.h
Normal 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... */
|
||||
160
cde/lib/DtTerm/TermPrim/TermPrimBufferP.h
Normal file
160
cde/lib/DtTerm/TermPrim/TermPrimBufferP.h
Normal 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... */
|
||||
1145
cde/lib/DtTerm/TermPrim/TermPrimBufferWc.c
Normal file
1145
cde/lib/DtTerm/TermPrim/TermPrimBufferWc.c
Normal file
File diff suppressed because it is too large
Load Diff
615
cde/lib/DtTerm/TermPrim/TermPrimCursor.c
Normal file
615
cde/lib/DtTerm/TermPrim/TermPrimCursor.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
23
cde/lib/DtTerm/TermPrim/TermPrimCursor.h
Normal file
23
cde/lib/DtTerm/TermPrim/TermPrimCursor.h
Normal 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... */
|
||||
340
cde/lib/DtTerm/TermPrim/TermPrimData.h
Normal file
340
cde/lib/DtTerm/TermPrim/TermPrimData.h
Normal 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 */
|
||||
476
cde/lib/DtTerm/TermPrim/TermPrimDebug.c
Normal file
476
cde/lib/DtTerm/TermPrim/TermPrimDebug.c
Normal 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();
|
||||
}
|
||||
40
cde/lib/DtTerm/TermPrim/TermPrimDebug.h
Normal file
40
cde/lib/DtTerm/TermPrim/TermPrimDebug.h
Normal 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... */
|
||||
380
cde/lib/DtTerm/TermPrim/TermPrimFunction.c
Normal file
380
cde/lib/DtTerm/TermPrim/TermPrimFunction.c
Normal 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;
|
||||
}
|
||||
60
cde/lib/DtTerm/TermPrim/TermPrimFunction.h
Normal file
60
cde/lib/DtTerm/TermPrim/TermPrimFunction.h
Normal 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... */
|
||||
413
cde/lib/DtTerm/TermPrim/TermPrimGetPty-bsd.c
Normal file
413
cde/lib/DtTerm/TermPrim/TermPrimGetPty-bsd.c
Normal 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"));
|
||||
}
|
||||
181
cde/lib/DtTerm/TermPrim/TermPrimGetPty-clone.c
Normal file
181
cde/lib/DtTerm/TermPrim/TermPrimGetPty-clone.c
Normal 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;
|
||||
}
|
||||
249
cde/lib/DtTerm/TermPrim/TermPrimGetPty-svr4.c
Normal file
249
cde/lib/DtTerm/TermPrim/TermPrimGetPty-svr4.c
Normal 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;
|
||||
}
|
||||
19
cde/lib/DtTerm/TermPrim/TermPrimGetPty.h
Normal file
19
cde/lib/DtTerm/TermPrim/TermPrimGetPty.h
Normal 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... */
|
||||
48
cde/lib/DtTerm/TermPrim/TermPrimI.h
Normal file
48
cde/lib/DtTerm/TermPrim/TermPrimI.h
Normal 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 */
|
||||
634
cde/lib/DtTerm/TermPrim/TermPrimLineDraw.c
Normal file
634
cde/lib/DtTerm/TermPrim/TermPrimLineDraw.c
Normal 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;
|
||||
}
|
||||
21
cde/lib/DtTerm/TermPrim/TermPrimLineDraw.h
Normal file
21
cde/lib/DtTerm/TermPrim/TermPrimLineDraw.h
Normal 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 */
|
||||
63
cde/lib/DtTerm/TermPrim/TermPrimLineDrawP.h
Normal file
63
cde/lib/DtTerm/TermPrim/TermPrimLineDrawP.h
Normal 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 */
|
||||
16
cde/lib/DtTerm/TermPrim/TermPrimLineFont.h
Normal file
16
cde/lib/DtTerm/TermPrim/TermPrimLineFont.h
Normal 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... */
|
||||
51
cde/lib/DtTerm/TermPrim/TermPrimLineFontP.h
Normal file
51
cde/lib/DtTerm/TermPrim/TermPrimLineFontP.h
Normal 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... */
|
||||
48
cde/lib/DtTerm/TermPrim/TermPrimMessageCatI.h
Normal file
48
cde/lib/DtTerm/TermPrim/TermPrimMessageCatI.h
Normal 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... */
|
||||
115
cde/lib/DtTerm/TermPrim/TermPrimOSDepI.h
Normal file
115
cde/lib/DtTerm/TermPrim/TermPrimOSDepI.h
Normal 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... */
|
||||
207
cde/lib/DtTerm/TermPrim/TermPrimP.h
Normal file
207
cde/lib/DtTerm/TermPrim/TermPrimP.h
Normal 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... */
|
||||
222
cde/lib/DtTerm/TermPrim/TermPrimParse.c
Normal file
222
cde/lib/DtTerm/TermPrim/TermPrimParse.c
Normal 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");
|
||||
}
|
||||
37
cde/lib/DtTerm/TermPrim/TermPrimParseTable.c
Normal file
37
cde/lib/DtTerm/TermPrim/TermPrimParseTable.c
Normal 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;
|
||||
30
cde/lib/DtTerm/TermPrim/TermPrimParseTable.h
Normal file
30
cde/lib/DtTerm/TermPrim/TermPrimParseTable.h
Normal 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... */
|
||||
457
cde/lib/DtTerm/TermPrim/TermPrimParser.c
Normal file
457
cde/lib/DtTerm/TermPrim/TermPrimParser.c
Normal 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 */
|
||||
42
cde/lib/DtTerm/TermPrim/TermPrimParser.h
Normal file
42
cde/lib/DtTerm/TermPrim/TermPrimParser.h
Normal 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... */
|
||||
162
cde/lib/DtTerm/TermPrim/TermPrimParserP.h
Normal file
162
cde/lib/DtTerm/TermPrim/TermPrimParserP.h
Normal 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... */
|
||||
420
cde/lib/DtTerm/TermPrim/TermPrimPendingText.c
Normal file
420
cde/lib/DtTerm/TermPrim/TermPrimPendingText.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
107
cde/lib/DtTerm/TermPrim/TermPrimPendingText.h
Normal file
107
cde/lib/DtTerm/TermPrim/TermPrimPendingText.h
Normal 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... */
|
||||
|
||||
54
cde/lib/DtTerm/TermPrim/TermPrimPendingTextP.h
Normal file
54
cde/lib/DtTerm/TermPrim/TermPrimPendingTextP.h
Normal 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... */
|
||||
1552
cde/lib/DtTerm/TermPrim/TermPrimRender.c
Normal file
1552
cde/lib/DtTerm/TermPrim/TermPrimRender.c
Normal file
File diff suppressed because it is too large
Load Diff
64
cde/lib/DtTerm/TermPrim/TermPrimRender.h
Normal file
64
cde/lib/DtTerm/TermPrim/TermPrimRender.h
Normal 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... */
|
||||
176
cde/lib/DtTerm/TermPrim/TermPrimRenderFont.c
Normal file
176
cde/lib/DtTerm/TermPrim/TermPrimRenderFont.c
Normal 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);
|
||||
}
|
||||
22
cde/lib/DtTerm/TermPrim/TermPrimRenderFont.h
Normal file
22
cde/lib/DtTerm/TermPrim/TermPrimRenderFont.h
Normal 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... */
|
||||
234
cde/lib/DtTerm/TermPrim/TermPrimRenderFontSet.c
Normal file
234
cde/lib/DtTerm/TermPrim/TermPrimRenderFontSet.c
Normal 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);
|
||||
}
|
||||
22
cde/lib/DtTerm/TermPrim/TermPrimRenderFontSet.h
Normal file
22
cde/lib/DtTerm/TermPrim/TermPrimRenderFontSet.h
Normal 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... */
|
||||
230
cde/lib/DtTerm/TermPrim/TermPrimRenderLineDraw.c
Normal file
230
cde/lib/DtTerm/TermPrim/TermPrimRenderLineDraw.c
Normal 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);
|
||||
}
|
||||
25
cde/lib/DtTerm/TermPrim/TermPrimRenderLineDraw.h
Normal file
25
cde/lib/DtTerm/TermPrim/TermPrimRenderLineDraw.h
Normal 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... */
|
||||
884
cde/lib/DtTerm/TermPrim/TermPrimRenderMb.c
Normal file
884
cde/lib/DtTerm/TermPrim/TermPrimRenderMb.c
Normal 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);
|
||||
}
|
||||
58
cde/lib/DtTerm/TermPrim/TermPrimRenderP.h
Normal file
58
cde/lib/DtTerm/TermPrim/TermPrimRenderP.h
Normal 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... */
|
||||
295
cde/lib/DtTerm/TermPrim/TermPrimRepType.c
Normal file
295
cde/lib/DtTerm/TermPrim/TermPrimRepType.c
Normal 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);
|
||||
}
|
||||
18
cde/lib/DtTerm/TermPrim/TermPrimRepType.h
Normal file
18
cde/lib/DtTerm/TermPrim/TermPrimRepType.h
Normal 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... */
|
||||
918
cde/lib/DtTerm/TermPrim/TermPrimScroll.c
Normal file
918
cde/lib/DtTerm/TermPrim/TermPrimScroll.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
22
cde/lib/DtTerm/TermPrim/TermPrimScroll.h
Normal file
22
cde/lib/DtTerm/TermPrim/TermPrimScroll.h
Normal 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... */
|
||||
3074
cde/lib/DtTerm/TermPrim/TermPrimSelect.c
Normal file
3074
cde/lib/DtTerm/TermPrim/TermPrimSelect.c
Normal file
File diff suppressed because it is too large
Load Diff
269
cde/lib/DtTerm/TermPrim/TermPrimSelect.h
Normal file
269
cde/lib/DtTerm/TermPrim/TermPrimSelect.h
Normal 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... */
|
||||
|
||||
114
cde/lib/DtTerm/TermPrim/TermPrimSelectP.h
Normal file
114
cde/lib/DtTerm/TermPrim/TermPrimSelectP.h
Normal 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... */
|
||||
754
cde/lib/DtTerm/TermPrim/TermPrimSetPty.c
Normal file
754
cde/lib/DtTerm/TermPrim/TermPrimSetPty.c
Normal 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, <c)) {
|
||||
TMODE (XTTYMODE_dsusp, ltc.t_dsuspc);
|
||||
(void) ioctl(pty, TIOCSLTC, <c);
|
||||
}
|
||||
}
|
||||
#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 *)℘
|
||||
(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
|
||||
21
cde/lib/DtTerm/TermPrim/TermPrimSetPty.h
Normal file
21
cde/lib/DtTerm/TermPrim/TermPrimSetPty.h
Normal 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... */
|
||||
546
cde/lib/DtTerm/TermPrim/TermPrimSetUtmp.c
Normal file
546
cde/lib/DtTerm/TermPrim/TermPrimSetUtmp.c
Normal 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"));
|
||||
}
|
||||
26
cde/lib/DtTerm/TermPrim/TermPrimSetUtmp.h
Normal file
26
cde/lib/DtTerm/TermPrim/TermPrimSetUtmp.h
Normal 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... */
|
||||
634
cde/lib/DtTerm/TermPrim/TermPrimSubproc.c
Normal file
634
cde/lib/DtTerm/TermPrim/TermPrimSubproc.c
Normal 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);
|
||||
}
|
||||
31
cde/lib/DtTerm/TermPrim/TermPrimSubproc.h
Normal file
31
cde/lib/DtTerm/TermPrim/TermPrimSubproc.h
Normal 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... */
|
||||
606
cde/lib/DtTerm/TermPrim/TermPrimUtil.c
Normal file
606
cde/lib/DtTerm/TermPrim/TermPrimUtil.c
Normal 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"));
|
||||
}
|
||||
33
cde/lib/DtTerm/TermPrim/TermPrimUtil.h
Normal file
33
cde/lib/DtTerm/TermPrim/TermPrimUtil.h
Normal 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... */
|
||||
18
cde/lib/DtTerm/TermPrim/TermPrimVersion.c
Normal file
18
cde/lib/DtTerm/TermPrim/TermPrimVersion.c
Normal 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[] = "";
|
||||
63
cde/lib/DtTerm/TermPrim/TermPrimWMProtocols.c
Normal file
63
cde/lib/DtTerm/TermPrim/TermPrimWMProtocols.c
Normal 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);
|
||||
}
|
||||
19
cde/lib/DtTerm/TermPrim/TermPrimWMProtocols.h
Normal file
19
cde/lib/DtTerm/TermPrim/TermPrimWMProtocols.h
Normal 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... */
|
||||
Reference in New Issue
Block a user