This program has never worked very well, and it may still not work very well. This commit removes the ancient C++ headers and uses modern replacements with some changes required due to the different interfaces. It builds a lot cleaner, and no longer does stupid things like deleteing char *, ostream.str()'s, and the like. This program could be really useful if it worked well. Some thought should be givien in the future to decouple this SW from dtappbuilder and maybe just rewrite from scratch.
729 lines
16 KiB
C
729 lines
16 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
//%% (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.
|
|
//%% $XConsortium: DtTt.C /main/4 1996/03/19 10:47:59 barstow $
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
|
|
#include <sstream>
|
|
|
|
#include <Xm/TextF.h>
|
|
#include <Dt/SpinBox.h>
|
|
#include <Dt/HelpDialog.h>
|
|
#include "tt_c++.h"
|
|
#include "DtTt.h"
|
|
#include "messageProps_ui.h"
|
|
#include "patternProps_ui.h"
|
|
|
|
static const char ** dtTtProcids = 0;
|
|
static const void ** dtTtProcidClientDatums = 0;
|
|
static unsigned int dtTtProcidsCount = 0;
|
|
static Tt_pattern * dtTtPatterns = 0;
|
|
static unsigned int dtTtPatternsCount = 0;
|
|
static Tt_message * dtTtMessages = 0;
|
|
static unsigned int dtTtMessagesCount = 0;
|
|
static Tt_pattern ** dtTtDtSessions = 0;
|
|
static unsigned int dtTtDtSessionsCount = 0;
|
|
static Tt_pattern ** dtTtDtFiles = 0;
|
|
static unsigned int dtTtDtFilesCount = 0;
|
|
|
|
int _DtTtPatsNameKey = (int) (long) DtTtNth;
|
|
extern Tt_pattern snoopPat;
|
|
|
|
int
|
|
listGrow(
|
|
void ** pList,
|
|
unsigned int & listCount,
|
|
size_t elemSize
|
|
)
|
|
{
|
|
void *newList;
|
|
newList = realloc( *pList, (1 + listCount) * elemSize );
|
|
if (newList == 0) {
|
|
return 0;
|
|
}
|
|
*pList = newList;
|
|
listCount++;
|
|
return 1;
|
|
}
|
|
|
|
XmString
|
|
DtTtStatusString(
|
|
Tt_status status
|
|
)
|
|
{
|
|
char *s = tt_status_string( status );
|
|
XmString s2 = XmStringCreateLocalized( s );
|
|
tt_free( s );
|
|
return s2;
|
|
}
|
|
|
|
Tt_status
|
|
DtTtCreated(
|
|
DtTtType type,
|
|
const void * entity,
|
|
const void * clientData
|
|
)
|
|
{
|
|
Tt_status status = tt_ptr_error( entity );
|
|
if ((tt_is_err( status )) || (entity == 0)) {
|
|
return TT_OK;
|
|
}
|
|
switch (type) {
|
|
char *proc;
|
|
case DTTT_PROCID:
|
|
proc = strdup( (const char *)entity );
|
|
if (proc == 0) {
|
|
return TT_ERR_NOMEM;
|
|
}
|
|
if (! listAppend( dtTtProcids, dtTtProcidsCount, const char *,
|
|
proc ))
|
|
{
|
|
return TT_ERR_NOMEM;
|
|
}
|
|
dtTtProcidsCount--; // shared by both lists
|
|
if (! listAppend( dtTtProcidClientDatums, dtTtProcidsCount,
|
|
const void *, clientData ))
|
|
{
|
|
return TT_ERR_NOMEM;
|
|
}
|
|
break;
|
|
case DTTT_MESSAGE:
|
|
if (DtTtIndex( type, entity ) >= 0) {
|
|
return TT_OK;
|
|
}
|
|
if (! listAppend( dtTtMessages, dtTtMessagesCount, Tt_message,
|
|
(const Tt_message)entity ))
|
|
{
|
|
return TT_ERR_NOMEM;
|
|
}
|
|
break;
|
|
case DTTT_PATTERN:
|
|
if (DtTtIndex( type, entity ) >= 0) {
|
|
return TT_OK;
|
|
}
|
|
if (! listAppend( dtTtPatterns, dtTtPatternsCount, Tt_pattern,
|
|
(const Tt_pattern)entity ))
|
|
{
|
|
return TT_ERR_NOMEM;
|
|
}
|
|
break;
|
|
case DTTT_PTYPE:
|
|
case DTTT_OTYPE:
|
|
case DTTT_OBJECT:
|
|
case DTTT_SESSION:
|
|
case DTTT_DTSESSION:
|
|
case DTTT_DTFILE:
|
|
case DTTT_OP:
|
|
abort();
|
|
break;
|
|
}
|
|
return TT_OK;
|
|
}
|
|
|
|
Tt_status
|
|
DtTtCreated(
|
|
DtTtType type,
|
|
Tt_pattern * entity,
|
|
const char * name
|
|
)
|
|
{
|
|
if ((tt_is_err( tt_ptr_error( entity ) )) || (entity == 0)) {
|
|
return TT_OK;
|
|
}
|
|
if ((tt_is_err( tt_ptr_error( name ) )) || (name == 0)) {
|
|
return TT_OK;
|
|
}
|
|
switch (type) {
|
|
case DTTT_PROCID:
|
|
case DTTT_MESSAGE:
|
|
case DTTT_PATTERN:
|
|
case DTTT_PTYPE:
|
|
case DTTT_OTYPE:
|
|
case DTTT_OBJECT:
|
|
case DTTT_SESSION:
|
|
case DTTT_OP:
|
|
abort();
|
|
break;
|
|
case DTTT_DTSESSION:
|
|
tt_pattern_user_set( *entity, _DtTtPatsNameKey,
|
|
strdup( name ));
|
|
if (DtTtIndex( type, entity ) >= 0) {
|
|
return TT_OK;
|
|
}
|
|
if (! listAppend( dtTtDtSessions, dtTtDtSessionsCount,
|
|
Tt_pattern *, (Tt_pattern *)entity ))
|
|
{
|
|
return TT_ERR_NOMEM;
|
|
}
|
|
break;
|
|
case DTTT_DTFILE:
|
|
tt_pattern_user_set( *entity, _DtTtPatsNameKey,
|
|
strdup( name ));
|
|
if (DtTtIndex( type, entity ) >= 0) {
|
|
return TT_OK;
|
|
}
|
|
if (! listAppend( dtTtDtFiles, dtTtDtFilesCount,
|
|
Tt_pattern *, (Tt_pattern *)entity ))
|
|
{
|
|
return TT_ERR_NOMEM;
|
|
}
|
|
break;
|
|
}
|
|
while (*entity != 0) {
|
|
DtTtCreated( DTTT_PATTERN, *entity );
|
|
entity++;
|
|
}
|
|
return TT_OK;
|
|
}
|
|
|
|
void *
|
|
DtTtNth(
|
|
DtTtType type,
|
|
int n
|
|
)
|
|
{
|
|
switch (type) {
|
|
case DTTT_PROCID:
|
|
if ((n < 0) || (n >= dtTtProcidsCount)) {
|
|
return 0;
|
|
}
|
|
return (void *)dtTtProcids[ n ];
|
|
case DTTT_MESSAGE:
|
|
if ((n < 0) || (n >= dtTtMessagesCount)) {
|
|
return 0;
|
|
}
|
|
return dtTtMessages[ n ];
|
|
case DTTT_PATTERN:
|
|
if ((n < 0) || (n >= dtTtPatternsCount)) {
|
|
return 0;
|
|
}
|
|
return dtTtPatterns[ n ];
|
|
case DTTT_DTSESSION:
|
|
if ((n < 0) || (n >= dtTtDtSessionsCount)) {
|
|
return 0;
|
|
}
|
|
return dtTtDtSessions[ n ];
|
|
case DTTT_DTFILE:
|
|
if ((n < 0) || (n >= dtTtDtFilesCount)) {
|
|
return 0;
|
|
}
|
|
return dtTtDtFiles[ n ];
|
|
case DTTT_OP:
|
|
return tttk_op_string( (Tttk_op)(n+1) );
|
|
}
|
|
}
|
|
|
|
void *
|
|
DtTtNthClientDatum(
|
|
DtTtType type,
|
|
int n
|
|
)
|
|
{
|
|
switch (type) {
|
|
case DTTT_PROCID:
|
|
if ((n < 0) || (n >= dtTtProcidsCount)) {
|
|
return 0;
|
|
}
|
|
return (void *)dtTtProcidClientDatums[ n ];
|
|
default:
|
|
abort();
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void
|
|
DtTtNthClientDatumSet(
|
|
DtTtType type,
|
|
int n,
|
|
const void * clientData
|
|
)
|
|
{
|
|
switch (type) {
|
|
case DTTT_PROCID:
|
|
if ((n < 0) || (n >= dtTtProcidsCount)) {
|
|
return;
|
|
}
|
|
dtTtProcidClientDatums[ n ] = clientData;
|
|
return;
|
|
default:
|
|
abort();
|
|
}
|
|
}
|
|
|
|
int
|
|
DtTtIndex(
|
|
DtTtType type,
|
|
const void * entity
|
|
)
|
|
{
|
|
Tt_status status = tt_ptr_error( entity );
|
|
if ((tt_is_err( status )) || (entity == 0)) {
|
|
return -1;
|
|
}
|
|
switch (type) {
|
|
int i;
|
|
case DTTT_PROCID:
|
|
for (i = dtTtProcidsCount - 1; i >= 0; i--) {
|
|
if (strcmp( dtTtProcids[i], (char *)entity) == 0) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
case DTTT_MESSAGE:
|
|
for (i = dtTtMessagesCount - 1; i >= 0; i--) {
|
|
if (dtTtMessages[i] == entity) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
case DTTT_PATTERN:
|
|
for (i = dtTtPatternsCount - 1; i >= 0; i--) {
|
|
if (dtTtPatterns[i] == entity) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
case DTTT_DTSESSION:
|
|
for (i = dtTtDtSessionsCount - 1; i >= 0; i--) {
|
|
if (dtTtDtSessions[i] == entity) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
case DTTT_DTFILE:
|
|
for (i = dtTtDtFilesCount - 1; i >= 0; i--) {
|
|
if (dtTtDtFiles[i] == entity) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
case DTTT_OP:
|
|
for (i = 1; i < TTDT_OP_LAST; i++) {
|
|
if (0 == strcmp( tttk_op_string( (Tttk_op)i ),
|
|
(char *)entity ))
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
Tt_status
|
|
DtTtDestroyed(
|
|
DtTtType type,
|
|
const void * entity
|
|
)
|
|
{
|
|
Tt_status status = tt_ptr_error( entity );
|
|
if ((tt_is_err( status )) || (entity == 0)) {
|
|
return TT_OK;
|
|
}
|
|
switch (type) {
|
|
int i, j;
|
|
Tt_pattern *pats;
|
|
case DTTT_PROCID:
|
|
for (i = dtTtProcidsCount - 1; i >= 0; i--) {
|
|
if (strcmp( dtTtProcids[i], (char *)entity) == 0) {
|
|
break;
|
|
}
|
|
}
|
|
if (i < 0) {
|
|
return TT_WRN_NOTFOUND;
|
|
}
|
|
for (j = i; j < dtTtProcidsCount - 1; j++) {
|
|
dtTtProcids[j] = dtTtProcids[j+1];
|
|
}
|
|
for (j = i; j < dtTtProcidsCount - 1; j++) {
|
|
dtTtProcidClientDatums[j] =
|
|
dtTtProcidClientDatums[j+1];
|
|
}
|
|
dtTtProcidsCount--;
|
|
break;
|
|
case DTTT_MESSAGE:
|
|
for (i = dtTtMessagesCount - 1; i >= 0; i--) {
|
|
if (dtTtMessages[i] == entity) {
|
|
break;
|
|
}
|
|
}
|
|
if (i < 0) {
|
|
return TT_WRN_NOTFOUND;
|
|
}
|
|
for (j = i; j < dtTtMessagesCount - 1; j++) {
|
|
dtTtMessages[j] = dtTtMessages[j+1];
|
|
}
|
|
dtTtMessagesCount--;
|
|
break;
|
|
case DTTT_PATTERN:
|
|
if (snoopPat == entity) snoopPat = 0;
|
|
for (i = dtTtPatternsCount - 1; i >= 0; i--) {
|
|
if (dtTtPatterns[i] == entity) {
|
|
break;
|
|
}
|
|
}
|
|
if (i < 0) {
|
|
return TT_WRN_NOTFOUND;
|
|
}
|
|
for (j = i; j < dtTtPatternsCount - 1; j++) {
|
|
dtTtPatterns[j] = dtTtPatterns[j+1];
|
|
}
|
|
dtTtPatternsCount--;
|
|
break;
|
|
case DTTT_DTSESSION:
|
|
for (i = dtTtDtSessionsCount - 1; i >= 0; i--) {
|
|
if (dtTtDtSessions[i] == entity) {
|
|
break;
|
|
}
|
|
}
|
|
if (i < 0) {
|
|
return TT_WRN_NOTFOUND;
|
|
}
|
|
pats = (Tt_pattern *)entity;
|
|
while (*pats != 0) {
|
|
DtTtDestroyed( DTTT_PATTERN, *pats );
|
|
pats++;
|
|
}
|
|
for (j = i; j < dtTtDtSessionsCount - 1; j++) {
|
|
dtTtDtSessions[j] = dtTtDtSessions[j+1];
|
|
}
|
|
dtTtDtSessionsCount--;
|
|
break;
|
|
case DTTT_DTFILE:
|
|
for (i = dtTtDtFilesCount - 1; i >= 0; i--) {
|
|
if (dtTtDtFiles[i] == entity) {
|
|
break;
|
|
}
|
|
}
|
|
if (i < 0) {
|
|
return TT_WRN_NOTFOUND;
|
|
}
|
|
pats = (Tt_pattern *)entity;
|
|
while (*pats != 0) {
|
|
DtTtDestroyed( DTTT_PATTERN, *pats );
|
|
pats++;
|
|
}
|
|
for (j = i; j < dtTtDtFilesCount - 1; j++) {
|
|
dtTtDtFiles[j] = dtTtDtFiles[j+1];
|
|
}
|
|
dtTtDtFilesCount--;
|
|
break;
|
|
}
|
|
return TT_OK;
|
|
}
|
|
|
|
Tt_status
|
|
DtTtSetLabel(
|
|
Widget labelWidget,
|
|
const char *string
|
|
)
|
|
{
|
|
if (labelWidget == 0) {
|
|
return TT_OK;
|
|
}
|
|
XmString labelXmString = XmStringCreateLocalized( (String)string );
|
|
XtVaSetValues( labelWidget, XmNlabelString, labelXmString, NULL );
|
|
XmStringFree( labelXmString );
|
|
return TT_OK;
|
|
}
|
|
|
|
Tt_status
|
|
DtTtSetLabel(
|
|
Widget labelWidget,
|
|
const char *func,
|
|
void *val
|
|
)
|
|
{
|
|
Tt_status status = tt_ptr_error( val );
|
|
std::ostringstream errStream;
|
|
errStream << func << " = " << val << " (" << status << ")" << ends;
|
|
const char *label = errStream.str().c_str();
|
|
DtTtSetLabel( labelWidget, label );
|
|
return status;
|
|
}
|
|
|
|
Tt_status
|
|
DtTtSetLabel(
|
|
Widget labelWidget,
|
|
const char *func,
|
|
Tt_status status
|
|
)
|
|
{
|
|
std::ostringstream errStream;
|
|
errStream << func << " = " << status << ends;
|
|
const char *label = errStream.str().c_str();
|
|
DtTtSetLabel( labelWidget, label );
|
|
return status;
|
|
}
|
|
|
|
int
|
|
DtTtSetLabel(
|
|
Widget labelWidget,
|
|
const char *func,
|
|
int returnVal
|
|
)
|
|
{
|
|
std::ostringstream errStream;
|
|
errStream << func << " = " << returnVal << ends;
|
|
const char *label = errStream.str().c_str();
|
|
DtTtSetLabel( labelWidget, label );
|
|
return returnVal;
|
|
}
|
|
|
|
|
|
static XmString *
|
|
_DtTtChoices(
|
|
Tt_pattern ** pPats,
|
|
int count
|
|
)
|
|
{
|
|
// XXX when to free?
|
|
XmString *items = (XmString *)XtMalloc( count * sizeof( XmString ));
|
|
if (items == 0) {
|
|
return 0;
|
|
}
|
|
for (int i = 0; i < count; i++) {
|
|
std::ostringstream itemStream;
|
|
itemStream << (void *)pPats[ i ];
|
|
char *name = (char *)
|
|
tt_pattern_user( *pPats[ i ], _DtTtPatsNameKey );
|
|
if (! tt_is_err( tt_ptr_error( name ))) {
|
|
itemStream << " " << name;
|
|
tt_free( name );
|
|
}
|
|
itemStream << ends;
|
|
char *string = const_cast<char *>(itemStream.str().c_str());
|
|
items[ i ] = XmStringCreateLocalized( string );
|
|
}
|
|
return items;
|
|
}
|
|
|
|
XmString *
|
|
_DtTtChoices(
|
|
DtTtType type,
|
|
int * itemCount
|
|
)
|
|
{
|
|
*itemCount = 0;
|
|
switch (type) {
|
|
XmString *items;
|
|
int i;
|
|
int opCount;
|
|
case DTTT_PROCID:
|
|
items = (XmString *)
|
|
XtMalloc( dtTtProcidsCount * sizeof( XmString ));
|
|
if (items == 0) {
|
|
return 0;
|
|
}
|
|
*itemCount = dtTtProcidsCount;
|
|
for (i = 0; i < dtTtProcidsCount; i++) {
|
|
items[ i ] = XmStringCreateLocalized(
|
|
(String)dtTtProcids[ i ] );
|
|
}
|
|
return items;
|
|
case DTTT_MESSAGE:
|
|
items = (XmString *)
|
|
XtMalloc( dtTtMessagesCount * sizeof( XmString ));
|
|
if (items == 0) {
|
|
return 0;
|
|
}
|
|
*itemCount = dtTtMessagesCount;
|
|
for (i = 0; i < dtTtMessagesCount; i++) {
|
|
std::ostringstream itemStream;
|
|
itemStream << (void *)dtTtMessages[ i ];
|
|
char *op = tt_message_op( dtTtMessages[ i ] );
|
|
if (! tt_is_err( tt_ptr_error( op ))) {
|
|
itemStream << " " << op;
|
|
tt_free( op );
|
|
}
|
|
char *id = tt_message_id( dtTtMessages[ i ] );
|
|
if (! tt_is_err( tt_ptr_error( id ))) {
|
|
itemStream << " " << id;
|
|
tt_free( id );
|
|
}
|
|
itemStream << ends;
|
|
char *string = const_cast<char *>(itemStream.str().c_str());
|
|
items[ i ] = XmStringCreateLocalized( string );
|
|
}
|
|
return items;
|
|
case DTTT_PATTERN:
|
|
items = (XmString *)
|
|
XtMalloc( dtTtPatternsCount * sizeof( XmString ));
|
|
if (items == 0) {
|
|
return 0;
|
|
}
|
|
*itemCount = dtTtPatternsCount;
|
|
for (i = 0; i < dtTtPatternsCount; i++) {
|
|
std::ostringstream itemStream;
|
|
itemStream << (void *)dtTtPatterns[ i ] << ends;
|
|
items[ i ] = XmStringCreateLocalized(
|
|
const_cast<char *>(itemStream.str().c_str()) );
|
|
}
|
|
return items;
|
|
case DTTT_DTSESSION:
|
|
*itemCount = dtTtDtSessionsCount;
|
|
return _DtTtChoices( dtTtDtSessions, dtTtDtSessionsCount );
|
|
case DTTT_DTFILE:
|
|
*itemCount = dtTtDtFilesCount;
|
|
return _DtTtChoices( dtTtDtFiles, dtTtDtFilesCount );
|
|
case DTTT_OP:
|
|
// XXX when to free? ditto for each case
|
|
opCount = ((int)TTDT_OP_LAST) - 1;
|
|
items = (XmString *)
|
|
XtMalloc( opCount * sizeof( XmString ));
|
|
if (items == 0) {
|
|
return 0;
|
|
}
|
|
*itemCount = opCount;
|
|
for (i = 1; i <= opCount; i++) {
|
|
items[ i-1 ] = XmStringCreateLocalized(
|
|
(String)tttk_op_string( (Tttk_op)i ));
|
|
}
|
|
return items;
|
|
}
|
|
}
|
|
|
|
#if defined(aix)
|
|
#define AIX_CONST_STRING (char *)
|
|
#else
|
|
#define AIX_CONST_STRING
|
|
#endif
|
|
|
|
void
|
|
_DtOpen(
|
|
Widget label,
|
|
const char * cmd,
|
|
const char * tempnamTemplate
|
|
)
|
|
{
|
|
char *file = tempnam( 0, AIX_CONST_STRING tempnamTemplate );
|
|
std::ostringstream cmdStream;
|
|
cmdStream << cmd << " > " << file << ends;
|
|
int sysStat = system( cmdStream.str().c_str() );
|
|
if (! WIFEXITED( sysStat )) {
|
|
std::ostringstream func;
|
|
func << "system( \"" << cmdStream.str() << "\" )" << ends;
|
|
DtTtSetLabel( label, func.str().c_str(), sysStat );
|
|
return;
|
|
}
|
|
if (WEXITSTATUS( sysStat ) != 0) {
|
|
DtTtSetLabel( label, cmdStream.str().c_str(), WEXITSTATUS( sysStat ));
|
|
return;
|
|
}
|
|
_DtOpen( label, file );
|
|
}
|
|
|
|
void
|
|
_DtOpen(
|
|
Widget label,
|
|
const char * file
|
|
)
|
|
{
|
|
std::ostringstream labelStream;
|
|
labelStream << "dtaction Open " << file << ends;
|
|
DtTtSetLabel( label, labelStream.str().c_str() );
|
|
|
|
std::ostringstream cmd;
|
|
cmd << "( unset TT_TRACE_SCRIPT; if dtaction Open " << file
|
|
<< "; then :; else textedit " << file << "; fi; sleep 600; rm -f "
|
|
<< file << " ) &" << ends;
|
|
system( cmd.str().c_str() );
|
|
}
|
|
|
|
void
|
|
_DtOpen(
|
|
Widget label,
|
|
void * buf,
|
|
size_t len,
|
|
const char * tempnamTemplate
|
|
)
|
|
{
|
|
char *file = tempnam( 0, AIX_CONST_STRING tempnamTemplate );
|
|
int fd = open( file, O_WRONLY|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR );
|
|
if (write( fd, buf, len ) < 0) {
|
|
DtTtSetLabel( label, file, errno );
|
|
return;
|
|
}
|
|
close( fd );
|
|
_DtOpen( label, file );
|
|
}
|
|
|
|
void
|
|
_DtMan(
|
|
Widget label,
|
|
const char * topic
|
|
)
|
|
{
|
|
std::ostringstream labelStream;
|
|
labelStream << "dtaction Dtmanpageview " << topic << ends;
|
|
DtTtSetLabel( label, labelStream.str().c_str() );
|
|
|
|
std::ostringstream cmd;
|
|
cmd << "unset TT_TRACE_SCRIPT; if dtaction Dtmanpageview " << topic
|
|
<< "; then :; else cmdtool -c man " << topic << "; fi &" << ends;
|
|
system( cmd.str().c_str() );
|
|
}
|
|
|
|
Boolean
|
|
_DtCanHelp(
|
|
const char *topics
|
|
)
|
|
{
|
|
if (topics == 0) return False;
|
|
if (strchr( topics, ' ' ) != 0) {
|
|
// Must not be a list of man pages
|
|
return False;
|
|
}
|
|
return True;
|
|
}
|
|
|
|
Boolean
|
|
_DtHelped(
|
|
Widget helpDialog
|
|
)
|
|
{
|
|
char *topics;
|
|
XtVaGetValues( helpDialog, DtNstringData, &topics, NULL );
|
|
if (! _DtCanHelp( topics )) {
|
|
return False;
|
|
}
|
|
char *newTopics = strdup( topics );
|
|
const char *whiteSpace = "(12345689) \t:-,.*\n";
|
|
const char *topic = strtok( newTopics, whiteSpace );
|
|
while (topic != 0) {
|
|
_DtMan( 0, topic );
|
|
topic = strtok( 0, whiteSpace );
|
|
}
|
|
free( newTopics );
|
|
return True;
|
|
}
|