/*---------------------------------------------------------------------------*
*
* BinkleyTerm
*
* (C) Copyright 1987-96, Bit Bucket Software Co.
* For license and contact information see /doc/orig_260/license.260.
*
* This version was modified by the BinkleyTerm XE Team.
* For contact information see /doc/team.lst and /doc/join.us.
* For a complete list of changes see /doc/xe_user.doc and /doc/xe_hist.doc.
*
* Filename : $Source: /cvsroot/btxe/btnt/sources/binkdlg.cpp,v $
* Revision : $Revision: 1.1 $
* Tagname : $Name: $
* Last updated: $Date: 2005/01/01 15:18:11 $
* State : $State: Exp $
* Orig. Author: r. hoerner
*
* Description :
* This implements a mechanism for binkley/OS2 to serve a PM programm
* with the current, actual screen output of binkley using a named pipe.
* Binkley sends a code for the actually written window / row in window
* and the written text.
*
* The technique actually used is to copy the text to a temporary storage
* and send it with the necessary control information to a thread, which
* finally sends it to the client program (binkpipe.exe).
*
* The transfer of data between binkleys main thread (in SendToDlg()) and
* the thread that finally writes to the named pipe is managed using a queue.
*
*---------------------------------------------------------------------------*/
#ifdef OS_2
#include "includes.h"
/* --------------------------------------------------------------------- */
PID BinkPID;
BOOL running = FALSE;
CHAR BinkPipe[CCHMAXPATH];
/* --------------------------------------------------------------------- */
VOID
WritePipe (PVOID l)
/* --------------------------------------------------------------------- */
/* NOTE: This thread may NOT use any C-library string functions! */
/* --------------------------------------------------------------------- */
{
REQUESTDATA qData; /* bsedos.h */
PPIPEDATA pData; /* binkpipe.h */
APIRET rc; /* return code */
ULONG ulA, ulB; /* dummies */
ULONG queueSize;
HPIPE hpipe;
HQUEUE hQueue;
CHAR cPrio;
PID thisPID;
l = l;
pData = NULL;
running = TRUE;
rc = DosOpenQueue (&thisPID, &hQueue, (PCSZ) QUEUENAME);
if (!rc)
for (;;)
{
rc = DosReadQueue (hQueue, &qData, &queueSize,
(PPVOID) & pData, 0L, DCWW_WAIT, (PBYTE) & cPrio, 0L);
if (rc == 0 /* no error */
&& (pData != NULL) /* valid pointer */
&& queueSize /* we got at least 1 byte */
&& (qData.pid == BinkPID) /* we got it from ourselves */
&& (qData.ulData == 'BINK')) /* it's not a STOP command */
{
rc = DosOpen ((PSZ) BinkPipe, (PHFILE) & hpipe,
&ulB, 0L, 0,
OPEN_ACTION_OPEN_IF_EXISTS |
OPEN_ACTION_FAIL_IF_NEW,
CLNT_OPEN_MODE,
NULL);
if (rc == 0)
{
rc = DosSetNPHState (hpipe, NP_NOWAIT | NP_READMODE_MESSAGE);
if (rc == 0)
DosWrite (hpipe, pData, queueSize, &ulA);
DosClose (hpipe);
DosFreeMem ((PVOID) pData);
pData = NULL;
}
}
else if ((qData.pid == BinkPID) && (qData.ulData == 'STOP'))
break;
}
if (hQueue)
DosCloseQueue (hQueue);
running = FALSE;
_endthread ();
}
/* --------------------------------------------------------------------- */
VOID
SendToDlg (PSZ text, ULONG row, ULONG col, ULONG window)
/* --------------------------------------------------------------------- */
{
BOOL found;
static HQUEUE hqWrite;
static BOOL goHome = FALSE; /* a firewall semaphore to stop re-entries */
static HWND hwnd = NULLHANDLE; /* the window handle of binkpipe running on */
/* this computer. */
if (goHome) /* needed if this routine calls status_line() */
return;
goHome = TRUE;
found = (bink_pipe != NULL);
if (!found)
found = IsPipeRunning (&hwnd);
if (text == NULL) /* beware of NULL */
text = (PSZ) "empty";
if (found && strlen ((char *) text))
{
PPIPEDATA pData;
CHAR pName[32];
APIRET rc = 0;
ULONG need = sizeof (PIPEDATA) - sizeof (pData->data) + strlen ((char *) text) + 1;
if (!running)
{
sprintf ((char *) pName, PIPE_NAME, TaskNumber); /* create PIPE name */
if (bink_pipe != NULL)
sprintf (BinkPipe, "%s%s", bink_pipe, pName);
else
sprintf (BinkPipe, "%s", pName);
rc = DosCreateQueue (&hqWrite, QUE_FIFO | QUE_NOCONVERT_ADDRESS, (PCSZ) QUEUENAME);
if (!rc && hqWrite)
{
REQUESTDATA qData;
ULONG ulAction;
CHAR cPrio;
USHORT i;
DosWriteQueue (hqWrite, 'BINK', need, pData, 0L);
DosReadQueue (hqWrite, &qData, &ulAction, (PPVOID) & pData,
0L, DCWW_WAIT, (PBYTE) & cPrio, 0L);
BinkPID = qData.pid;
rc = _beginthread (WritePipe, NULL, 32768L, NULL);
if (rc != -1)
{
i = 100;
while (!running && i--)
DosSleep (1L);
}
else
{
DosCloseQueue (hqWrite);
return; /* and let "goHome" untouched. We are finished here! */
}
} /* if create queue "ok" */
else
return; /* and let "goHome" untouched. We are finished here! */
} /* if not running */
if (!rc && running && hqWrite)
{
if (DosAllocMem ((PPVOID) & pData, need, fALLOC))
{
DosWriteQueue (hqWrite, 'STOP', 1L, &found, 0L);
DosSleep (100L);
return; /* and let "goHome" untouched. We are finished here! */
}
if (pData == NULL)
{
DosWriteQueue (hqWrite, 'STOP', 1L, &found, 0L);
DosSleep (100L);
return; /* and let "goHome" untouched. We are finished here! */
}
pData->version = (ULONG) BINKPIPE_VERSION;
pData->window = (ULONG) window;
pData->row = (ULONG) row;
pData->col = (ULONG) col;
memmove (&pData->data, text, strlen ((char *) text) + 1);
DosWriteQueue (hqWrite, 'BINK', need, pData, 0L);
}
if (window == BINK_END)
{
DosWriteQueue (hqWrite, 'STOP', 1L, &found, 0L);
DosSleep (100L);
return; /* and let "goHome" untouched. We are finished here! */
}
}
goHome = FALSE;
}
#else /* #ifdef OS_2 */
void
SendToDlg (char *text, long row, long col, long window)
{
text = text;
row = row;
col = col;
window = window;
}
#endif /* #ifdef OS_2 */
/* $Id: binkdlg.cpp,v 1.1 2005/01/01 15:18:11 vildanov Exp $ */