Post-1.0b1 work in progress from 2004.
This contains partial code for displaying the cursor locally.
This commit is contained in:
parent
fb43622db7
commit
31ff375570
2
README
2
README
|
@ -1,6 +1,6 @@
|
|||
VNCview GS 1.0b1 README
|
||||
|
||||
VNCview GS is a VNC client (viewer) for the Apple IIgs. You can use it to display and interact with the graphical desktop of another computer through your Apple IIgs.
|
||||
VNCview GS is a Virtual Network Computing client (viewer) for the Apple IIgs. You can use it to display and interact with the graphical desktop of another computer through your Apple IIgs.
|
||||
|
||||
System Requirements
|
||||
A (real or emulated) ROM 01 or ROM 3 Apple IIgs
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
#pragma noroot
|
||||
|
||||
#include <window.h>
|
||||
#include <quickdraw.h>
|
||||
#include <qdaux.h>
|
||||
#include <desk.h>
|
||||
#include <memory.h>
|
||||
#include <resources.h>
|
||||
#include <tcpip.h>
|
||||
#include <menu.h>
|
||||
#include <control.h>
|
||||
#include <misctool.h>
|
||||
#include <scrap.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <event.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "vncsession.h"
|
||||
#include "vncview.h"
|
||||
#include "vncdisplay.h"
|
||||
#include "colortables.h"
|
||||
#include "menus.h"
|
||||
#include "clipboard.h"
|
||||
#include "desktopsize.h"
|
||||
#include "mouse.h"
|
||||
#include "keyboard.h"
|
||||
#include "copyrect.h"
|
||||
#include "raw.h"
|
||||
#include "hextile.h"
|
||||
|
||||
/* Update the Scrap Manager clipboard with new data sent from server.
|
||||
*/
|
||||
void DoServerCutText (void) {
|
||||
unsigned long textLen;
|
||||
unsigned long i;
|
||||
|
||||
if (! DoWaitingReadTCP (3)) { /* Read & ignore padding */
|
||||
DoClose(vncWindow);
|
||||
return;
|
||||
}
|
||||
if (! DoWaitingReadTCP (4)) {
|
||||
DoClose(vncWindow);
|
||||
return;
|
||||
}
|
||||
HLock(readBufferHndl);
|
||||
textLen = SwapBytes4((unsigned long) **readBufferHndl);
|
||||
HUnlock(readBufferHndl);
|
||||
|
||||
if (! DoWaitingReadTCP(textLen)) {
|
||||
DoClose(vncWindow);
|
||||
return;
|
||||
};
|
||||
if (allowClipboardTransfers) {
|
||||
ZeroScrap();
|
||||
HLock(readBufferHndl);
|
||||
|
||||
/* Convert lf->cr; Use pointer arithmetic so we can go over 64k */
|
||||
for (i = 0; i < textLen; i++)
|
||||
if (*((*(char **)readBufferHndl)+i) == '\n')
|
||||
*((*(char **)readBufferHndl)+i) = '\r';
|
||||
|
||||
/* Below function call requires <scrap.h> to be fixed */
|
||||
PutScrap(textLen, textScrap, (Pointer) *readBufferHndl);
|
||||
/* Potential errors (e.g. out of memory) ignored */
|
||||
HUnlock(readBufferHndl);
|
||||
}
|
||||
}
|
||||
|
||||
void DoSendClipboard (void) {
|
||||
static struct clientCutText {
|
||||
unsigned char messageType;
|
||||
unsigned char padding1;
|
||||
unsigned int padding2;
|
||||
unsigned long length;
|
||||
} clientCutTextStruct = { 6 /* Message type 6 */ };
|
||||
|
||||
Handle scrapHandle;
|
||||
unsigned long i;
|
||||
|
||||
/* Only proceed if we're connected to the server and not view-only */
|
||||
if (vncConnected && !viewOnlyMode) {
|
||||
clientCutTextStruct.length = GetScrapSize(textScrap);
|
||||
|
||||
if (clientCutTextStruct.length == 0)
|
||||
return;
|
||||
|
||||
clientCutTextStruct.length = SwapBytes4(clientCutTextStruct.length);
|
||||
|
||||
scrapHandle = NewHandle(1, userid(), 0x0000, NULL);
|
||||
GetScrap(scrapHandle, textScrap);
|
||||
if (toolerror())
|
||||
goto end; /* abort if error */
|
||||
if (TCPIPWriteTCP(hostIpid, &clientCutTextStruct.messageType,
|
||||
sizeof(clientCutTextStruct), FALSE, FALSE))
|
||||
goto end; /* abort if error */
|
||||
if (toolerror())
|
||||
goto end;
|
||||
|
||||
clientCutTextStruct.length = SwapBytes4(clientCutTextStruct.length);
|
||||
|
||||
HLock(scrapHandle);
|
||||
/* Convert cr->lf; Use pointer arithmetic so we can go over 64k */
|
||||
for (i = 0; i < clientCutTextStruct.length; i++)
|
||||
if (*((*(char **)scrapHandle)+i) == '\r')
|
||||
*((*(char **)scrapHandle)+i) = '\n';
|
||||
|
||||
TCPIPWriteTCP(hostIpid, (Pointer) *scrapHandle,
|
||||
clientCutTextStruct.length, TRUE, FALSE);
|
||||
/* Can't handle errors usefully here */
|
||||
HUnlock(scrapHandle);
|
||||
|
||||
end:
|
||||
DisposeHandle(scrapHandle);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
extern void DoServerCutText (void);
|
||||
extern void DoSendClipboard (void);
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
#pragma noroot
|
||||
|
||||
#include <window.h>
|
||||
#include <quickdraw.h>
|
||||
#include <qdaux.h>
|
||||
#include <desk.h>
|
||||
#include <memory.h>
|
||||
#include <resources.h>
|
||||
#include <tcpip.h>
|
||||
#include <menu.h>
|
||||
#include <control.h>
|
||||
#include <misctool.h>
|
||||
#include <scrap.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <event.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "vncsession.h"
|
||||
#include "vncview.h"
|
||||
#include "vncdisplay.h"
|
||||
#include "colortables.h"
|
||||
#include "menus.h"
|
||||
#include "clipboard.h"
|
||||
#include "desktopsize.h"
|
||||
#include "mouse.h"
|
||||
#include "keyboard.h"
|
||||
#include "copyrect.h"
|
||||
#include "raw.h"
|
||||
#include "hextile.h"
|
||||
|
||||
void DoCopyRect (void) {
|
||||
/* For use with GetContentOrigin() */
|
||||
unsigned long contentOrigin;
|
||||
Point * contentOriginPtr = (void *) &contentOrigin;
|
||||
|
||||
Rect srcRect;
|
||||
unsigned int *dataPtr; /* Pointer to TCP data that was read */
|
||||
|
||||
//printf("Processing CopyRect rectangle\n");
|
||||
|
||||
if (! DoReadTCP ((unsigned long) 4))
|
||||
return; /* Not ready yet; wait */
|
||||
|
||||
contentOrigin = GetContentOrigin(vncWindow);
|
||||
|
||||
HLock(readBufferHndl);
|
||||
dataPtr = (unsigned int *) ((char *) (*readBufferHndl));
|
||||
srcRect.h1 = SwapBytes2(dataPtr[0]) - contentOriginPtr->h;
|
||||
srcRect.v1 = SwapBytes2(dataPtr[1]) - contentOriginPtr->v;
|
||||
HUnlock(readBufferHndl);
|
||||
|
||||
srcRect.h2 = srcRect.h1 + rectWidth;
|
||||
srcRect.v2 = srcRect.v1 + rectHeight;
|
||||
|
||||
/* Check that the source rect is actually visible; if not, ask the server
|
||||
to send the update using some other encoding.
|
||||
*/
|
||||
if (!RectInRgn(&srcRect, GetVisHandle())) {
|
||||
SendFBUpdateRequest(FALSE, rectX, rectY, rectWidth, rectHeight);
|
||||
displayInProgress = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* We can use the window pointer as a LocInfo pointer because it starts
|
||||
* with a grafPort structure, which in turn starts with a LocInfo structure.
|
||||
*/
|
||||
PPToPort((struct LocInfo *) vncWindow, &srcRect,
|
||||
rectX - contentOriginPtr->h, rectY - contentOriginPtr->v, modeCopy);
|
||||
|
||||
displayInProgress = FALSE;
|
||||
|
||||
NextRect(); /* Prepare for next rect */
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
extern void DoCopyRect (void);
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
vncview.cc: if (cursor) {
|
||||
vncview.cc: free(cursor);
|
||||
vncview.cc: if (cursor)
|
||||
vncview.cc: free(cursor);
|
||||
vncview.cc: InitCursor(); /* Activate pointer cursor */
|
||||
vncview.cc: InitCursor(); /* start the arrow cursor */
|
||||
mouse.cc:unsigned char * cursor = NULL; /* Cursor from server */
|
||||
mouse.cc:/* This routine also maintains the appropriate cursor when using local cursor */
|
||||
mouse.cc: if (cursor && GetCursorAdr() == cursor)
|
||||
mouse.cc: if (cursor && GetCursorAdr() != cursor)
|
||||
mouse.cc: SetCursor(cursor);
|
||||
mouse.cc: unsigned char *cursorPixels;
|
||||
mouse.cc: /* Elements of the cursor structure (which isn't a C struct) */
|
||||
mouse.cc: unsigned int *cursorHeightPtr, *cursorWidthPtr;
|
||||
mouse.cc: unsigned char *cursorImage, *cursorMask;
|
||||
mouse.cc: unsigned char *oldCursor = cursor; /* So we can free() it later */
|
||||
mouse.cc: cursorPixels = (unsigned char *)(*readBufferHndl);
|
||||
mouse.cc: cursor = malloc(8 + 4 * lineWords * rectHeight);
|
||||
mouse.cc: if (cursor == NULL)
|
||||
mouse.cc: cursorHeightPtr = (unsigned int *)(void *)cursor;
|
||||
mouse.cc: cursorWidthPtr = cursorHeightPtr + 1;
|
||||
mouse.cc: cursorImage = cursor + 4;
|
||||
mouse.cc: cursorMask = cursorImage + lineWords * rectHeight * 2;
|
||||
mouse.cc: hotSpotYPtr = (unsigned int *)(cursorMask + lineWords * rectHeight * 2);
|
||||
mouse.cc: *cursorHeightPtr = rectHeight;
|
||||
mouse.cc: *cursorWidthPtr = lineWords;
|
||||
mouse.cc: /* Make cursorImage using translation tables */
|
||||
mouse.cc: /* Make cursorMask from bitmask */
|
||||
mouse.cc: dataPtr = cursorPixels;
|
||||
mouse.cc: maskLine = cursorMask + line * lineWords * 2;
|
||||
mouse.cc: imageLine = cursorImage + line * lineWords * 2;
|
||||
mouse.cc: maskLine = cursorMask + line * lineWords * 2;
|
||||
mouse.cc: imageLine = cursorImage + line * lineWords * 2;
|
||||
mouse.cc: j = cursorPixels + rectWidth * (line + 1) - dataPtr;
|
||||
mouse.cc: SetCursor(cursor);
|
||||
mouse.cc: for (k = cursor; k < cursorImage; k++)
|
||||
mouse.cc: fprintf(foo, "%02X", *(cursorImage + j));
|
||||
mouse.cc: for (k = cursorImage + j; k < cursorImage + j + 4; k = k + 1)
|
|
@ -0,0 +1,84 @@
|
|||
#pragma noroot
|
||||
|
||||
#include <window.h>
|
||||
#include <quickdraw.h>
|
||||
#include <qdaux.h>
|
||||
#include <desk.h>
|
||||
#include <memory.h>
|
||||
#include <resources.h>
|
||||
#include <tcpip.h>
|
||||
#include <menu.h>
|
||||
#include <control.h>
|
||||
#include <misctool.h>
|
||||
#include <scrap.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <event.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "vncsession.h"
|
||||
#include "vncview.h"
|
||||
#include "vncdisplay.h"
|
||||
#include "colortables.h"
|
||||
#include "menus.h"
|
||||
#include "clipboard.h"
|
||||
#include "desktopsize.h"
|
||||
#include "mouse.h"
|
||||
#include "keyboard.h"
|
||||
#include "copyrect.h"
|
||||
#include "raw.h"
|
||||
#include "hextile.h"
|
||||
|
||||
/* This prototype should be in <window.h> but is bogusly commented out there */
|
||||
extern pascal void SetContentOrigin2(Word, Word, Word, GrafPortPtr) inline(0x570E,dispatcher);
|
||||
|
||||
void DoDesktopSize (void) {
|
||||
#define screenTooBigError 2010
|
||||
unsigned long contentOrigin;
|
||||
Point * contentOriginPtr = (void *) &contentOrigin;
|
||||
unsigned int newX, newY;
|
||||
Boolean changeOrigin = FALSE;
|
||||
unsigned int oldWinHeight, oldWinWidth;
|
||||
|
||||
fbWidth = rectWidth;
|
||||
fbHeight = rectHeight;
|
||||
|
||||
if ((fbWidth > 16384) || (fbHeight > 16384)) {
|
||||
AlertWindow(awResource, NULL, screenTooBigError);
|
||||
DoClose(vncWindow);
|
||||
}
|
||||
|
||||
oldWinHeight = winHeight;
|
||||
oldWinWidth = winWidth;
|
||||
winHeight = 174;
|
||||
winWidth = (hRez == 640) ? 613 : 302;
|
||||
if (fbWidth < winWidth)
|
||||
winWidth = fbWidth;
|
||||
if (fbHeight < winHeight)
|
||||
winHeight = fbHeight;
|
||||
if (oldWinHeight != winHeight || oldWinWidth != winWidth)
|
||||
SizeWindow(winWidth, winHeight, vncWindow);
|
||||
|
||||
/* Scroll if area displayed is going away */
|
||||
contentOrigin = GetContentOrigin(vncWindow);
|
||||
newX = contentOriginPtr->h;
|
||||
newY = contentOriginPtr->v;
|
||||
|
||||
if (contentOriginPtr->h + winWidth > fbWidth) {
|
||||
newX = fbWidth - winWidth;
|
||||
changeOrigin = TRUE;
|
||||
}
|
||||
if (contentOriginPtr->v + winHeight > fbHeight) {
|
||||
newY = fbHeight - winHeight;
|
||||
changeOrigin = TRUE;
|
||||
}
|
||||
SetContentOrigin2(1, newX, newY, vncWindow);
|
||||
|
||||
SetDataSize(fbWidth, fbHeight, vncWindow);
|
||||
DrawControls(vncWindow);
|
||||
|
||||
displayInProgress = FALSE;
|
||||
|
||||
NextRect(); /* Prepare for next rect */
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
extern void DoDesktopSize (void);
|
87
handleerr.cc
87
handleerr.cc
|
@ -1,87 +0,0 @@
|
|||
/***************************************************************
|
||||
* HandleError.cc - routines to dosplay error messages
|
||||
***************************************************************/
|
||||
|
||||
#if __ORCAC__
|
||||
#pragma lint -1
|
||||
#pragma noroot
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
#pragma debug 25
|
||||
#endif
|
||||
|
||||
#include <types.h>
|
||||
#include <Resources.h>
|
||||
#include <Window.h>
|
||||
#include <Memory.h>
|
||||
|
||||
/***************************************************************
|
||||
* GetString - Get a string from the resource fork
|
||||
* Parameters:
|
||||
* resourceID - resource ID of the rCString resource
|
||||
* Returns: pointer to the string; NULL for an error
|
||||
* Notes: The string is in a locked resource handle. The caller
|
||||
* should call FreeString when the string is no longer needed.
|
||||
* Failure to do so is not catastrophic; the memory will be
|
||||
* deallocated when the program is shut down.
|
||||
***************************************************************/
|
||||
|
||||
char *GetString (int resourceID)
|
||||
{
|
||||
Handle hndl; /* resource handle */
|
||||
|
||||
hndl = LoadResource(rCString, resourceID);
|
||||
if (toolerror() == 0) {
|
||||
HLock(hndl);
|
||||
return (char *) (*hndl);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* FreeString - Free a resource string
|
||||
* Parameters:
|
||||
* resourceID - resource ID of the rCString to free
|
||||
***************************************************************/
|
||||
|
||||
void FreeString (int resourceID)
|
||||
{
|
||||
ReleaseResource(-3, rCString, resourceID);
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* FlagError - Flag an error
|
||||
* Parameters:
|
||||
* error - error message number
|
||||
* tError - toolbox error code; 0 if none
|
||||
***************************************************************/
|
||||
|
||||
void FlagError (int error, int tError)
|
||||
{
|
||||
#define errorAlert 2000 /* alert resource ID */
|
||||
#define errorBase 2000 /* base resource ID for fortunes */
|
||||
|
||||
char *substArray; /* substitution "array" */
|
||||
char *errorString; /* pointer to the error string */
|
||||
|
||||
/* form the error string */
|
||||
errorString = GetString(errorBase + error);
|
||||
substArray = NULL;
|
||||
if (errorString != NULL) {
|
||||
substArray = (char *)malloc(strlen(substArray)+9);
|
||||
if (substArray != NULL)
|
||||
strcpy(substArray, errorString);
|
||||
FreeString(errorBase + error);
|
||||
}
|
||||
if (substArray != NULL) {
|
||||
if (tError != 0) /* add the tool error number */
|
||||
sprintf(&substArray[strlen(substArray)], " ($%04X)", tError);
|
||||
/* show the alert */
|
||||
AlertWindow(awCString+awResource, (Pointer) &substArray, errorAlert);
|
||||
free(substArray);
|
||||
}
|
||||
|
||||
#undef errorAlert
|
||||
#undef errorBase
|
||||
}
|
|
@ -0,0 +1,301 @@
|
|||
#pragma noroot
|
||||
|
||||
#include <window.h>
|
||||
#include <quickdraw.h>
|
||||
#include <qdaux.h>
|
||||
#include <desk.h>
|
||||
#include <memory.h>
|
||||
#include <resources.h>
|
||||
#include <tcpip.h>
|
||||
#include <menu.h>
|
||||
#include <control.h>
|
||||
#include <misctool.h>
|
||||
#include <scrap.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <event.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "vncsession.h"
|
||||
#include "vncview.h"
|
||||
#include "vncdisplay.h"
|
||||
#include "colortables.h"
|
||||
#include "menus.h"
|
||||
#include "clipboard.h"
|
||||
#include "desktopsize.h"
|
||||
#include "mouse.h"
|
||||
#include "keyboard.h"
|
||||
#include "copyrect.h"
|
||||
#include "raw.h"
|
||||
#include "hextile.h"
|
||||
|
||||
unsigned int hexXTiles, hexYTiles; /* For in-process hextile processing */
|
||||
unsigned int hexXTileNum, hexYTileNum;
|
||||
unsigned int hexTileWidth, hexTileHeight;
|
||||
unsigned char hexBackground, hexForeground;
|
||||
|
||||
static BOOLEAN extraByteAdvance;
|
||||
|
||||
/* Used in Hextile encoding */
|
||||
#define Raw 0x01
|
||||
#define BackgroundSpecified 0x02
|
||||
#define ForegroundSpecified 0x04
|
||||
#define AnySubrects 0x08
|
||||
#define SubrectsColoured 0x10
|
||||
|
||||
#define hexWaitingForSubencoding 1
|
||||
#define hexWaitingForMoreInfo 2
|
||||
#define hexWaitingForSubrect 4
|
||||
#define hexWaitingForRawData 8
|
||||
|
||||
void HexNextTile (void) {
|
||||
hexXTileNum++;
|
||||
if (hexXTileNum == hexXTiles) {
|
||||
hexYTileNum++;
|
||||
if (hexYTileNum == hexYTiles) { /* Done with this Hextile rect */
|
||||
displayInProgress = FALSE;
|
||||
NextRect();
|
||||
return;
|
||||
}
|
||||
hexXTileNum = 0;
|
||||
}
|
||||
|
||||
hexTileWidth = (hexXTileNum == hexXTiles - 1) ?
|
||||
rectWidth - 16 * (hexXTiles - 1) : 16;
|
||||
hexTileHeight = (hexYTileNum == hexYTiles - 1) ?
|
||||
rectHeight - 16 * (hexYTiles - 1) : 16;
|
||||
|
||||
}
|
||||
|
||||
void HexRawDraw (Point *contentOriginPtr, int rectWidth, int rectHeight) {
|
||||
unsigned int i, j; /* Loop indices */
|
||||
unsigned int n = 0;
|
||||
unsigned char *dataPtr;
|
||||
unsigned char pixels[128];
|
||||
|
||||
static Rect srcRect = {0,0,0,0};
|
||||
|
||||
dataPtr = (unsigned char *) *readBufferHndl;
|
||||
|
||||
if ((hRez==640 && (rectWidth & 0x03)) || (hRez==320 && (rectWidth & 0x01)))
|
||||
extraByteAdvance = TRUE;
|
||||
else
|
||||
extraByteAdvance = FALSE;
|
||||
|
||||
for (j = 0; j < rectHeight; j++) {
|
||||
for (i = 0; i < rectWidth; i++) {
|
||||
if (hRez == 640) {
|
||||
switch (i & 0x03) {
|
||||
case 0x00: /* pixels 0, 4, 8, ... */
|
||||
pixels[n] = pixTransTbl[ *(dataPtr +
|
||||
(unsigned long) j*rectWidth + i)
|
||||
] & 0xC0;
|
||||
break;
|
||||
case 0x01: /* pixels 1, 5, 9, ... */
|
||||
pixels[n] += pixTransTbl[ *(dataPtr +
|
||||
(unsigned long) j*rectWidth + i)
|
||||
] & 0x30;
|
||||
break;
|
||||
case 0x02: /* pixels 2, 6, 10, ... */
|
||||
pixels[n] += pixTransTbl[ *(dataPtr +
|
||||
(unsigned long) j*rectWidth + i)
|
||||
] & 0x0C;
|
||||
break;
|
||||
case 0x03: /* pixels 3, 7, 11, ... */
|
||||
pixels[n] += pixTransTbl[ *(dataPtr +
|
||||
(unsigned long) j*rectWidth + i)
|
||||
] & 0x03;
|
||||
n++;
|
||||
} /* switch */
|
||||
} /* if */
|
||||
else { /* 320 mode */
|
||||
switch(i & 0x01) {
|
||||
case 0x00: /* pixels 0, 2, 4, ... */
|
||||
pixels[n] = pixTransTbl[ *(dataPtr +
|
||||
(unsigned long) j*rectWidth + i)
|
||||
] & 0xF0;
|
||||
break;
|
||||
case 0x01: /* pixels 1, 3, 5, ... */
|
||||
pixels[n] += pixTransTbl[ *(dataPtr +
|
||||
(unsigned long) j*rectWidth + i)
|
||||
] & 0x0F;
|
||||
n++;
|
||||
} /* switch */
|
||||
} /* else */
|
||||
} /* i loop */
|
||||
|
||||
/* When not ending a line on a byte boundary, the index isn't updated,
|
||||
* so we do it here.
|
||||
*/
|
||||
if (extraByteAdvance)
|
||||
n++;
|
||||
} /* j loop */
|
||||
|
||||
srcLocInfo.ptrToPixImage = (void *) pixels;
|
||||
srcLocInfo.boundsRect.v2 = rectHeight;
|
||||
/* Since the lines are rounded up to integral numbers of bytes, this
|
||||
* padding must be accounted for here.
|
||||
*/
|
||||
if (hRez == 640) {
|
||||
switch (rectWidth & 0x03) {
|
||||
case 0x00: srcLocInfo.boundsRect.h2 = rectWidth;
|
||||
srcLocInfo.width = rectWidth/4; break;
|
||||
case 0x01: srcLocInfo.boundsRect.h2 = rectWidth+3;
|
||||
srcLocInfo.width = rectWidth/4 + 1; break;
|
||||
case 0x02: srcLocInfo.boundsRect.h2 = rectWidth+2;
|
||||
srcLocInfo.width = rectWidth/4 + 1; break;
|
||||
case 0x03: srcLocInfo.boundsRect.h2 = rectWidth+1;
|
||||
srcLocInfo.width = rectWidth/4 + 1;
|
||||
}
|
||||
}
|
||||
else { /* hRez == 320 */
|
||||
switch (rectWidth & 0x01) {
|
||||
case 0x00: srcLocInfo.boundsRect.h2 = rectWidth;
|
||||
srcLocInfo.width = rectWidth/2; break;
|
||||
case 0x01: srcLocInfo.boundsRect.h2 = rectWidth+1;
|
||||
srcLocInfo.width = rectWidth/2 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
srcRect.v2 = hexTileHeight;
|
||||
srcRect.h2 = hexTileWidth;
|
||||
|
||||
PPToPort(&srcLocInfo, &srcRect,
|
||||
rectX + hexXTileNum * 16 - contentOriginPtr->h,
|
||||
rectY + hexYTileNum * 16 - contentOriginPtr->v, modeCopy);
|
||||
}
|
||||
|
||||
/* The macros below are used in HexDispatch() */
|
||||
#define HexDispatch_NextTile() do { \
|
||||
HexNextTile(); \
|
||||
HUnlock(readBufferHndl); \
|
||||
/* Set up for next time */ \
|
||||
status = hexWaitingForSubencoding; \
|
||||
bytesNeeded = 1; \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
#define HexDispatch_DrawRect(color, X, Y, width, height) do { \
|
||||
SetSolidPenPat((color)); \
|
||||
drawingRect.h1 = rectX + hexXTileNum * 16 + (X) - contentOriginPtr->h; \
|
||||
drawingRect.v1 = rectY + hexYTileNum * 16 + (Y) - contentOriginPtr->v; \
|
||||
drawingRect.h2 = rectX + hexXTileNum * 16 + (X) + (width) - contentOriginPtr->h; \
|
||||
drawingRect.v2 = rectY + hexYTileNum * 16 + (Y) + (height) - contentOriginPtr->v; \
|
||||
PaintRect(&drawingRect); \
|
||||
} while (0)
|
||||
|
||||
#define HexDispatch_DrawBackground() \
|
||||
HexDispatch_DrawRect(hexBackground, 0, 0, hexTileWidth, hexTileHeight)
|
||||
|
||||
void HexDispatch (void) {
|
||||
static unsigned char status = hexWaitingForSubencoding;
|
||||
static unsigned long bytesNeeded = 1;
|
||||
static unsigned char subencoding;
|
||||
static unsigned int numSubrects;
|
||||
int i;
|
||||
/* For use with GetContentOrigin() */
|
||||
unsigned long contentOrigin;
|
||||
Point * contentOriginPtr = (void *) &contentOrigin;
|
||||
int tileBytes;
|
||||
unsigned int srX, srY, srWidth, srHeight;
|
||||
Rect drawingRect;
|
||||
static unsigned char pixels[128];
|
||||
unsigned char *dataPtr;
|
||||
|
||||
contentOrigin = GetContentOrigin(vncWindow);
|
||||
SetPort(vncWindow);
|
||||
|
||||
/* If we don't have the next bit of needed data yet, return. */
|
||||
while (DoReadTCP(bytesNeeded)) {
|
||||
HLock(readBufferHndl);
|
||||
dataPtr = *(unsigned char **) readBufferHndl;
|
||||
/* If we're here, readBufferHndl contains bytesNeeded bytes of data. */
|
||||
switch (status) {
|
||||
case hexWaitingForSubencoding:
|
||||
subencoding = *dataPtr;
|
||||
if (subencoding & Raw) {
|
||||
bytesNeeded = hexTileWidth * hexTileHeight;
|
||||
status = hexWaitingForRawData;
|
||||
}
|
||||
else {
|
||||
bytesNeeded = 0;
|
||||
if (subencoding & BackgroundSpecified)
|
||||
bytesNeeded++;
|
||||
if (subencoding & ForegroundSpecified)
|
||||
bytesNeeded++;
|
||||
if (subencoding & AnySubrects)
|
||||
bytesNeeded++;
|
||||
else if (bytesNeeded == 0) {
|
||||
/* No more data - just draw background */
|
||||
HexDispatch_DrawBackground();
|
||||
HexDispatch_NextTile();
|
||||
}
|
||||
status = hexWaitingForMoreInfo;
|
||||
}
|
||||
break;
|
||||
|
||||
case hexWaitingForRawData:
|
||||
HexRawDraw(contentOriginPtr, hexTileWidth, hexTileHeight);
|
||||
HexDispatch_NextTile();
|
||||
break;
|
||||
|
||||
case hexWaitingForMoreInfo:
|
||||
if (subencoding & BackgroundSpecified) {
|
||||
hexBackground = pixTransTbl[*(dataPtr++)];
|
||||
}
|
||||
if (subencoding & ForegroundSpecified) {
|
||||
hexForeground = pixTransTbl[*(dataPtr++)];
|
||||
}
|
||||
if (subencoding & AnySubrects) {
|
||||
numSubrects = *dataPtr;
|
||||
if (numSubrects) {
|
||||
status = hexWaitingForSubrect;
|
||||
bytesNeeded = numSubrects * ((subencoding & SubrectsColoured) ? 3 : 2);
|
||||
break;
|
||||
}
|
||||
else
|
||||
HexDispatch_NextTile();
|
||||
}
|
||||
else { /* no subrects */
|
||||
HexDispatch_DrawBackground();
|
||||
HexDispatch_NextTile();
|
||||
}
|
||||
|
||||
case hexWaitingForSubrect: {
|
||||
HexDispatch_DrawBackground();
|
||||
while (numSubrects-- > 0) {
|
||||
if (subencoding & SubrectsColoured) {
|
||||
hexForeground = pixTransTbl[*(dataPtr++)];
|
||||
}
|
||||
srX = *dataPtr >> 4;
|
||||
srY = *(dataPtr++) & 0x0F;
|
||||
srWidth = (*dataPtr >> 4) + 1;
|
||||
srHeight = (*(dataPtr++) & 0x0F) + 1;
|
||||
HexDispatch_DrawRect(hexForeground, srX, srY, srWidth, srHeight);
|
||||
}
|
||||
HexDispatch_NextTile();
|
||||
}
|
||||
}
|
||||
HUnlock(readBufferHndl);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when we initially get a Hextile rect; set up to process it */
|
||||
void DoHextileRect (void) {
|
||||
hexXTiles = (rectWidth + 15) / 16;
|
||||
hexYTiles = (rectHeight + 15) / 16;
|
||||
|
||||
hexXTileNum = 0;
|
||||
hexYTileNum = 0;
|
||||
|
||||
displayInProgress = TRUE;
|
||||
|
||||
hexTileWidth = (hexYTileNum == hexXTiles - 1) ?
|
||||
rectWidth - 16 * (hexXTiles - 1) : 16;
|
||||
hexTileHeight = (hexYTileNum == hexYTiles - 1) ?
|
||||
rectHeight - 16 * (hexYTiles - 1) : 16;
|
||||
|
||||
/* Set up for Hextile drawing */
|
||||
srcRect.v1 = 0;
|
||||
srcRect.h1 = 0;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
extern void HexDispatch (void);
|
||||
extern void DoHextileRect (void);
|
|
@ -0,0 +1,153 @@
|
|||
#pragma noroot
|
||||
|
||||
#include <window.h>
|
||||
#include <quickdraw.h>
|
||||
#include <qdaux.h>
|
||||
#include <desk.h>
|
||||
#include <memory.h>
|
||||
#include <resources.h>
|
||||
#include <tcpip.h>
|
||||
#include <menu.h>
|
||||
#include <control.h>
|
||||
#include <misctool.h>
|
||||
#include <scrap.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <event.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "vncsession.h"
|
||||
#include "vncview.h"
|
||||
#include "vncdisplay.h"
|
||||
#include "colortables.h"
|
||||
#include "menus.h"
|
||||
#include "clipboard.h"
|
||||
#include "desktopsize.h"
|
||||
#include "mouse.h"
|
||||
#include "keyboard.h"
|
||||
#include "copyrect.h"
|
||||
#include "raw.h"
|
||||
#include "hextile.h"
|
||||
|
||||
/* Send a KeyEvent message to the server
|
||||
*/
|
||||
void SendKeyEvent (BOOLEAN keyDownFlag, unsigned long key)
|
||||
{
|
||||
struct KeyEvent {
|
||||
unsigned char messageType;
|
||||
unsigned char keyDownFlag;
|
||||
unsigned int padding;
|
||||
unsigned long key;
|
||||
} keyEvent = { 4 /* Message Type 4 */,
|
||||
0,
|
||||
0 /* Zero the padding */
|
||||
};
|
||||
|
||||
keyEvent.keyDownFlag = !!keyDownFlag;
|
||||
keyEvent.key = SwapBytes4(key);
|
||||
TCPIPWriteTCP(hostIpid, &keyEvent.messageType, sizeof(keyEvent),
|
||||
TRUE, FALSE);
|
||||
/* No error checking here -- Can't respond to one usefully. */
|
||||
}
|
||||
|
||||
|
||||
/* Process a key down event and send it on to the server. */
|
||||
void ProcessKeyEvent (void)
|
||||
{
|
||||
unsigned long key = myEvent.message & 0x0000007F;
|
||||
|
||||
if (viewOnlyMode)
|
||||
return;
|
||||
|
||||
/* Deal with extended keys that are mapped as keypad keys */
|
||||
if (myEvent.modifiers & keyPad) {
|
||||
switch (key) {
|
||||
case 0x7A: key = 0xFFBE; break; /* F1 */
|
||||
case 0x78: key = 0xFFBF; break; /* F2 */
|
||||
case 0x63: key = 0xFFC0; break; /* F3 */
|
||||
case 0x76: key = 0xFFC1; break; /* F4 */
|
||||
case 0x60: key = 0xFFC2; break; /* F5 */
|
||||
case 0x61: key = 0xFFC3; break; /* F6 */
|
||||
case 0x62: key = 0xFFC4; break; /* F7 */
|
||||
case 0x64: key = 0xFFC5; break; /* F8 */
|
||||
case 0x65: key = 0xFFC6; break; /* F9 */
|
||||
case 0x6D: key = 0xFFC7; break; /* F10 */
|
||||
case 0x67: key = 0xFFC8; break; /* F11 */
|
||||
case 0x6F: key = 0xFFC9; break; /* F12 */
|
||||
case 0x69: key = 0xFF15; break; /* F13 / PrintScr -> SysRq */
|
||||
case 0x6B: key = 0xFF14; break; /* F14 / ScrLock -> ScrLock */
|
||||
case 0x71: key = 0xFF13; break; /* F15 / Pause -> Pause */
|
||||
case 0x72: key = 0xFF63; break; /* Help / Insert -> Insert */
|
||||
case 0x75: key = 0xFFFF; break; /* Forward delete -> Delete */
|
||||
case 0x73: key = 0xFF50; break; /* Home */
|
||||
case 0x77: key = 0xFF57; break; /* End */
|
||||
case 0x74: key = 0xFF55; break; /* Page Up */
|
||||
case 0x79: key = 0xFF56; break; /* Page Down */
|
||||
}
|
||||
}
|
||||
|
||||
if (key == 0x7f)
|
||||
key = 0xFF08; /* Delete -> BackSpace */
|
||||
|
||||
if (key < 0x20) {
|
||||
if (myEvent.modifiers & controlKey) {
|
||||
if (((myEvent.modifiers & shiftKey) ||
|
||||
(myEvent.modifiers & capsLock))
|
||||
&& !((myEvent.modifiers & shiftKey) &&
|
||||
(myEvent.modifiers & capsLock)))
|
||||
key += 0x40; /* Undo effect of control on upper-case char. */
|
||||
else
|
||||
key += 0x60; /* Undo effect of control */
|
||||
}
|
||||
else switch (key) {
|
||||
case 0x1B: key = 0xFF1B; break; /* Escape */
|
||||
case 0x09: key = 0xFF09; break; /* Tab */
|
||||
case 0x0D: key = 0xFF0D; break; /* Return / Enter */
|
||||
case 0x08: key = 0xFF51; break; /* Left arrow */
|
||||
case 0x0B: key = 0xFF52; break; /* Up arrow */
|
||||
case 0x15: key = 0xFF53; break; /* Right arrow */
|
||||
case 0x0A: key = 0xFF54; break; /* Down arrow */
|
||||
case 0x18: key = 0xFF0B; break; /* Clear / NumLock -> Clear */
|
||||
}
|
||||
}
|
||||
|
||||
/* Test if we seem to have a valid character and return if we don't.
|
||||
This should never return, unless there are bugs in this routine or
|
||||
TaskMaster gives us bogus keycodes. The test would need to be updated
|
||||
if we ever start generating valid keycodes outside of these ranges.
|
||||
*/
|
||||
if ((key & 0xFF80) != 0xFF00 && (key & 0xFF80) != 0x0000)
|
||||
return;
|
||||
|
||||
SendKeyEvent(TRUE, key);
|
||||
SendKeyEvent(FALSE, key);
|
||||
}
|
||||
|
||||
/* Send modifier keys that have changed since last update */
|
||||
void SendModifiers (void) {
|
||||
static unsigned int oldModifiers = 0x00FF; /* So it runs 1st time */
|
||||
unsigned int modifiers;
|
||||
|
||||
modifiers = myEvent.modifiers & 0x1B00;
|
||||
|
||||
/* If unchanged, do nothing. */
|
||||
if (modifiers == oldModifiers)
|
||||
return;
|
||||
|
||||
/* Apple key is sent as "meta" */
|
||||
if ((modifiers & appleKey) != (oldModifiers & appleKey))
|
||||
SendKeyEvent(modifiers & appleKey, 0xFFE7);
|
||||
|
||||
if ((modifiers & shiftKey) != (oldModifiers & shiftKey))
|
||||
SendKeyEvent(modifiers & shiftKey, 0xFFE1);
|
||||
|
||||
/* Option key is sent as "alt," as per its labelling on some keyboards */
|
||||
if ((modifiers & optionKey) != (oldModifiers & optionKey))
|
||||
SendKeyEvent(modifiers & optionKey, 0xFFE9);
|
||||
|
||||
if ((modifiers & controlKey) != (oldModifiers & controlKey))
|
||||
SendKeyEvent(modifiers & controlKey, 0xFFE3);
|
||||
|
||||
oldModifiers = modifiers;
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
extern void ProcessKeyEvent (void);
|
||||
extern void SendModifiers (void);
|
92
make
92
make
|
@ -1,86 +1,42 @@
|
|||
unset exit
|
||||
|
||||
set link false
|
||||
set vncview false
|
||||
set vncsession false
|
||||
set vncdisplay false
|
||||
set colortables false
|
||||
set rezfork false
|
||||
|
||||
clearmem
|
||||
|
||||
newer vncview.a vncview.cc
|
||||
if {status} != 0
|
||||
set vncview true
|
||||
set link true
|
||||
for {header} in vncview vncsession vncdisplay colortables menus \
|
||||
desktopsize mouse keyboard copyrect raw hextile clipboard
|
||||
unset exit
|
||||
newer VNCview.GS {header}.h
|
||||
if {status} != 0
|
||||
set exit on
|
||||
delete -P -W =.a
|
||||
end
|
||||
end
|
||||
|
||||
for file in vncview vncsession vncdisplay colortables \
|
||||
desktopsize mouse keyboard copyrect raw hextile clipboard
|
||||
unset exit
|
||||
newer {file}.a {file}.cc
|
||||
if {status} != 0
|
||||
set exit on
|
||||
compile +O {file}.cc keep={file}
|
||||
set link true
|
||||
end
|
||||
|
||||
newer vncsession.a vncsession.cc
|
||||
if {status} != 0
|
||||
set vncsession true
|
||||
set link true
|
||||
end
|
||||
|
||||
newer vncview.a vncview.h
|
||||
if {status} != 0
|
||||
set vncview true
|
||||
set link true
|
||||
end
|
||||
|
||||
newer vncsession.a vncview.h
|
||||
if {status} != 0
|
||||
set vncsession true
|
||||
set link true
|
||||
end
|
||||
|
||||
newer vncsession.a vncsession.h
|
||||
if {status} != 0
|
||||
set vncsession true
|
||||
set link true
|
||||
end
|
||||
|
||||
newer vncview.a vncsession.h
|
||||
if {status} != 0
|
||||
set vncview true
|
||||
set link true
|
||||
end
|
||||
|
||||
newer vncdisplay.a vncdisplay.cc
|
||||
if {status} != 0
|
||||
set vncdisplay true
|
||||
set link true
|
||||
end
|
||||
|
||||
newer colortables.a colortables.cc
|
||||
if {status} != 0
|
||||
set colortables true
|
||||
set link true
|
||||
end
|
||||
|
||||
unset exit
|
||||
newer vncview.rezfork vncview.rez
|
||||
if {status} != 0
|
||||
set rezfork true
|
||||
end
|
||||
|
||||
set exit on
|
||||
|
||||
if {rezfork} == true
|
||||
set exit on
|
||||
compile vncview.rez keep=vncview.rezfork
|
||||
copy -C -P -R vncview.rezfork VNCview.GS
|
||||
end
|
||||
if {vncview} == true
|
||||
compile +O vncview.cc keep=vncview
|
||||
end
|
||||
if {vncsession} == true
|
||||
compile +O vncsession.cc keep=vncsession
|
||||
end
|
||||
if {vncdisplay} == true
|
||||
compile +O vncdisplay.cc keep=vncdisplay
|
||||
end
|
||||
if {colortables} == true
|
||||
compile +O colortables.cc keep=colortables
|
||||
end
|
||||
|
||||
if {link} == true
|
||||
link vncview vncsession vncdisplay colortables keep=VNCview.GS
|
||||
link vncview vncsession vncdisplay colortables \
|
||||
desktopsize mouse keyboard copyrect raw hextile clipboard \
|
||||
keep=VNCview.GS
|
||||
filetype VNCview.GS S16 $DB03
|
||||
end
|
||||
|
|
|
@ -0,0 +1,321 @@
|
|||
#pragma noroot
|
||||
|
||||
#include <window.h>
|
||||
#include <quickdraw.h>
|
||||
#include <qdaux.h>
|
||||
#include <desk.h>
|
||||
#include <memory.h>
|
||||
#include <resources.h>
|
||||
#include <tcpip.h>
|
||||
#include <menu.h>
|
||||
#include <control.h>
|
||||
#include <misctool.h>
|
||||
#include <scrap.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <event.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "vncsession.h"
|
||||
#include "vncview.h"
|
||||
#include "vncdisplay.h"
|
||||
#include "colortables.h"
|
||||
#include "menus.h"
|
||||
#include "clipboard.h"
|
||||
#include "desktopsize.h"
|
||||
#include "mouse.h"
|
||||
#include "keyboard.h"
|
||||
#include "copyrect.h"
|
||||
#include "raw.h"
|
||||
#include "hextile.h"
|
||||
|
||||
unsigned char * cursor = NULL; /* Cursor from server */
|
||||
|
||||
/* Send a DoPointerEvent reflecting the status of the mouse to the server */
|
||||
/* This routine also maintains the appropriate cursor when using local cursor */
|
||||
void DoPointerEvent (void) {
|
||||
static struct {
|
||||
unsigned char messageType;
|
||||
unsigned char buttonMask;
|
||||
unsigned int xPos;
|
||||
unsigned int yPos;
|
||||
} pointerEventStruct = { 5 /* message type */ };
|
||||
|
||||
Point mouseCoords;
|
||||
unsigned long contentOrigin;
|
||||
Point * contentOriginPtr = (void *) &contentOrigin;
|
||||
RegionHndl contentRgnHndl;
|
||||
unsigned int oldButtonMask;
|
||||
GrafPortPtr winPtr;
|
||||
unsigned long key1 = 0x0000; /* Keys to release & re-press, if any */
|
||||
unsigned long key2 = 0x0000;
|
||||
|
||||
if (viewOnlyMode)
|
||||
return;
|
||||
|
||||
mouseCoords = myEvent.where;
|
||||
|
||||
SetPort(vncWindow);
|
||||
|
||||
/* Check if mouse is in content region of VNC window; don't send mouse
|
||||
* updates if it isn't.
|
||||
*/
|
||||
if (FindWindow(&winPtr, myEvent.where.h, myEvent.where.v) != wInContent ||
|
||||
winPtr != vncWindow) {
|
||||
if (cursor && GetCursorAdr() == cursor)
|
||||
InitCursor();
|
||||
return;
|
||||
}
|
||||
|
||||
GlobalToLocal(&mouseCoords);
|
||||
|
||||
contentOrigin = GetContentOrigin(vncWindow);
|
||||
mouseCoords.h += contentOriginPtr->h;
|
||||
mouseCoords.v += contentOriginPtr->v;
|
||||
|
||||
mouseCoords.h = SwapBytes2(mouseCoords.h);
|
||||
mouseCoords.v = SwapBytes2(mouseCoords.v);
|
||||
|
||||
/* Set up correct state of mouse buttons */
|
||||
oldButtonMask = pointerEventStruct.buttonMask;
|
||||
pointerEventStruct.buttonMask = 0x00;
|
||||
|
||||
if ((myEvent.modifiers & btn0State) == 0x00) { /* Mouse button pressed */
|
||||
if (emulate3ButtonMouse) {
|
||||
if (myEvent.modifiers & optionKey) {
|
||||
pointerEventStruct.buttonMask = 0x02;
|
||||
key1 = 0xFFE9;
|
||||
}
|
||||
if (myEvent.modifiers & appleKey) {
|
||||
pointerEventStruct.buttonMask |= 0x04;
|
||||
key2 = 0xFFE7;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no modifiers, just send a normal left click. */
|
||||
if (pointerEventStruct.buttonMask == 0x00)
|
||||
pointerEventStruct.buttonMask = 0x01;
|
||||
}
|
||||
if ((myEvent.modifiers & btn1State) == 0x00) /* If 2nd (right) */
|
||||
pointerEventStruct.buttonMask |= 0x04; /* button is pressed */
|
||||
|
||||
/* Don't waste bandwidth by sending update if mouse hasn't changed.
|
||||
* This may occasionally result in an initial mouse update not being
|
||||
* sent. If this occurs, the user can simply move the mouse slightly
|
||||
* in order to send it.
|
||||
*/
|
||||
if ( (pointerEventStruct.xPos == mouseCoords.h) &&
|
||||
(pointerEventStruct.yPos == mouseCoords.v) &&
|
||||
(pointerEventStruct.buttonMask == oldButtonMask) )
|
||||
return;
|
||||
|
||||
pointerEventStruct.xPos = mouseCoords.h;
|
||||
pointerEventStruct.yPos = mouseCoords.v;
|
||||
|
||||
if (key1)
|
||||
SendKeyEvent(FALSE, key1);
|
||||
if (key2)
|
||||
SendKeyEvent(FALSE, key2);
|
||||
|
||||
TCPIPWriteTCP(hostIpid, (Pointer) &pointerEventStruct.messageType,
|
||||
sizeof(pointerEventStruct), TRUE, FALSE);
|
||||
/* Can't do useful error checking here */
|
||||
|
||||
if (key1)
|
||||
SendKeyEvent(TRUE, key1);
|
||||
if (key2)
|
||||
SendKeyEvent(TRUE, key2);
|
||||
|
||||
//printf("Sent mouse update: x = %u, y = %u\n", mouseCoords.h, mouseCoords.v);
|
||||
//printf(" xPos = %x, yPos = %x, buttons = %x\n", pointerEventStruct.xPos, pointerEventStruct.yPos, (int) pointerEventStruct.buttonMask);
|
||||
|
||||
/* Note that we don't have to request a display update here. That has
|
||||
* been or will be done elsewhere when we're ready for it.
|
||||
*/
|
||||
|
||||
if (cursor && GetCursorAdr() != cursor)
|
||||
SetCursor(cursor);
|
||||
}
|
||||
|
||||
void DoCursor (void) {
|
||||
unsigned char *cursorPixels;
|
||||
unsigned char *bitmask;
|
||||
unsigned char *dataPtr;
|
||||
/* Elements of the cursor structure (which isn't a C struct) */
|
||||
unsigned int *cursorHeightPtr, *cursorWidthPtr;
|
||||
unsigned char *cursorImage, *cursorMask;
|
||||
unsigned int *hotSpotYPtr, *hotSpotXPtr;
|
||||
unsigned long bitmaskByte;
|
||||
unsigned long bitmaskLineBytes, lineWords;
|
||||
unsigned int line, n, j; /* Loop counters */
|
||||
unsigned char *maskLine, *imageLine;
|
||||
unsigned char *oldCursor = cursor; /* So we can free() it later */
|
||||
unsigned int outBytes640;
|
||||
unsigned long outBytes320;
|
||||
|
||||
bitmaskLineBytes = (rectWidth + 7) / 8;
|
||||
|
||||
if (!DoReadTCP(rectWidth*rectHeight + bitmaskLineBytes*rectHeight))
|
||||
return; /* Try again later */
|
||||
|
||||
HLock(readBufferHndl);
|
||||
|
||||
cursorPixels = (unsigned char *)(*readBufferHndl);
|
||||
bitmask = (unsigned char *)(*readBufferHndl) + rectWidth*rectHeight;
|
||||
|
||||
if (hRez == 640)
|
||||
lineWords = (rectWidth + 7) / 8 + 1;
|
||||
else /* hRez == 320 */
|
||||
lineWords = (rectWidth + 3) / 4 + 1;
|
||||
|
||||
cursor = malloc(8 + 4 * lineWords * rectHeight);
|
||||
/* Sub-optimal error handling */
|
||||
if (cursor == NULL)
|
||||
return;
|
||||
/* Don't overflow loop indices */
|
||||
if ((lineWords > UINT_MAX) || (rectHeight > UINT_MAX))
|
||||
return;
|
||||
cursorHeightPtr = (unsigned int *)(void *)cursor;
|
||||
cursorWidthPtr = cursorHeightPtr + 1;
|
||||
cursorImage = cursor + 4;
|
||||
cursorMask = cursorImage + lineWords * rectHeight * 2;
|
||||
hotSpotYPtr = (unsigned int *)(cursorMask + lineWords * rectHeight * 2);
|
||||
hotSpotXPtr = hotSpotYPtr + 1;
|
||||
|
||||
*cursorHeightPtr = rectHeight;
|
||||
*cursorWidthPtr = lineWords;
|
||||
*hotSpotYPtr = rectY;
|
||||
*hotSpotXPtr = rectX;
|
||||
|
||||
/* Make cursorImage using translation tables */
|
||||
/* Make cursorMask from bitmask */
|
||||
|
||||
dataPtr = cursorPixels;
|
||||
|
||||
if (hRez == 320) {
|
||||
for (line = 0; line < rectHeight; line++) { /* for each line ... */
|
||||
maskLine = cursorMask + line * lineWords * 2;
|
||||
imageLine = cursorImage + line * lineWords * 2;
|
||||
|
||||
for (j = 0; j < bitmaskLineBytes; j++) {
|
||||
bitmaskByte = *(bitmask + line*bitmaskLineBytes + j);
|
||||
outBytes320 =
|
||||
((bitmaskByte & 0x80) ) + ((bitmaskByte & 0x80) >> 1) +
|
||||
((bitmaskByte & 0x80) >> 2) + ((bitmaskByte & 0x80) >> 3) +
|
||||
((bitmaskByte & 0x40) >> 3) + ((bitmaskByte & 0x40) >> 4) +
|
||||
((bitmaskByte & 0x40) >> 5) + ((bitmaskByte & 0x40) >> 6) +
|
||||
((bitmaskByte & 0x20) << 10) + ((bitmaskByte & 0x20) << 9) +
|
||||
((bitmaskByte & 0x20) << 8) + ((bitmaskByte & 0x20) << 7) +
|
||||
((bitmaskByte & 0x10) << 7) + ((bitmaskByte & 0x10) << 6) +
|
||||
((bitmaskByte & 0x10) << 5) + ((bitmaskByte & 0x10) << 4) +
|
||||
((bitmaskByte & 0x08) << 20) + ((bitmaskByte & 0x08) << 19) +
|
||||
((bitmaskByte & 0x08) << 18) + ((bitmaskByte & 0x08) << 17) +
|
||||
((bitmaskByte & 0x04) << 17) + ((bitmaskByte & 0x04) << 16) +
|
||||
((bitmaskByte & 0x04) << 15) + ((bitmaskByte & 0x04) << 14) +
|
||||
((bitmaskByte & 0x02) << 30) + ((bitmaskByte & 0x02) << 29) +
|
||||
((bitmaskByte & 0x02) << 28) + ((bitmaskByte & 0x02) << 27) +
|
||||
((bitmaskByte & 0x01) << 27) + ((bitmaskByte & 0x01) << 26) +
|
||||
((bitmaskByte & 0x01) << 25) + ((bitmaskByte & 0x01) << 24);
|
||||
*((unsigned long *)maskLine + j) = outBytes320;
|
||||
}
|
||||
*((unsigned int *)maskLine + lineWords - 1) = 0;
|
||||
|
||||
for (n = 0; n < rectWidth/2; n++) {
|
||||
*(imageLine + n) = coltab320[*(dataPtr++)] & 0xF0;
|
||||
*(imageLine + n) += coltab320[*(dataPtr++)] & 0x0F;
|
||||
*(imageLine + n) ^= 0xFF; /* Reverse color */
|
||||
*(imageLine + n) &= *(maskLine + n);
|
||||
}
|
||||
if (rectWidth % 2) {
|
||||
*(imageLine + n) = coltab320[*(dataPtr++)] & 0xF0;
|
||||
*(imageLine + n) ^= 0xFF; /* Reverse color */
|
||||
*(imageLine + n) &= *(maskLine + n);
|
||||
n++;
|
||||
}
|
||||
*(imageLine + n) = 0;
|
||||
*((unsigned int *)imageLine + lineWords - 1) = 0;
|
||||
}
|
||||
}
|
||||
else { /* hRez == 640 */
|
||||
for (line = 0; line < rectHeight; line++) { /* for each line ... */
|
||||
maskLine = cursorMask + line * lineWords * 2;
|
||||
imageLine = cursorImage + line * lineWords * 2;
|
||||
|
||||
for (j = 0; j < bitmaskLineBytes; j++) {
|
||||
bitmaskByte = *(bitmask + line*bitmaskLineBytes + j);
|
||||
outBytes640 =
|
||||
((bitmaskByte & 0x80) ) + ((bitmaskByte & 0xC0) >> 1) +
|
||||
((bitmaskByte & 0x60) >> 2) + ((bitmaskByte & 0x30) >> 3) +
|
||||
((bitmaskByte & 0x10) >> 4) + ((bitmaskByte & 0x08) << 12) +
|
||||
((bitmaskByte & 0x0C) << 11) + ((bitmaskByte & 0x06) << 10) +
|
||||
((bitmaskByte & 0x03) << 9) + ((bitmaskByte & 0x01) << 8);
|
||||
*((unsigned int *)maskLine + j) = outBytes640;
|
||||
}
|
||||
*((unsigned int *)maskLine + lineWords - 1) = 0;
|
||||
|
||||
for (n = 0; n < lineWords * 2 - 4; n++) {
|
||||
*(imageLine + n) = coltab640[*(dataPtr++)] & 0xC0;
|
||||
*(imageLine + n) += coltab640[*(dataPtr++)] & 0x30;
|
||||
*(imageLine + n) += coltab640[*(dataPtr++)] & 0x0C;
|
||||
*(imageLine + n) += coltab640[*(dataPtr++)] & 0x03;
|
||||
*(imageLine + n) ^= 0xFF; /* Reverse color */
|
||||
*(imageLine + n) &= *(maskLine + n);
|
||||
}
|
||||
*(imageLine + n) = 0;
|
||||
j = cursorPixels + rectWidth * (line + 1) - dataPtr;
|
||||
if (j-- > 0) {
|
||||
*(imageLine + n) += coltab640[*(dataPtr++)] & 0xC0;
|
||||
if (j-- > 0) {
|
||||
*(imageLine + n) += coltab640[*(dataPtr++)] & 0x30;
|
||||
if (j-- > 0) {
|
||||
*(imageLine + n) += coltab640[*(dataPtr++)] & 0x0C;
|
||||
if (j-- > 0) {
|
||||
*(imageLine + n) += coltab640[*(dataPtr++)] & 0x03;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*(imageLine + n) ^= 0xFF; /* Reverse color */
|
||||
*(imageLine + n) &= *(maskLine + n);
|
||||
*(unsigned int *)(imageLine + n + 1) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
HUnlock(readBufferHndl);
|
||||
|
||||
if (GetCursorAdr() == oldCursor)
|
||||
SetCursor(cursor);
|
||||
if (oldCursor)
|
||||
free(oldCursor);
|
||||
|
||||
#if 0
|
||||
/***************/
|
||||
{
|
||||
unsigned char * k;
|
||||
FILE *foo = fopen("out.txt", "a");
|
||||
fprintf(foo, "Width = %u, Height = %u, Hotspot X = %u, Hotspot Y = %u:\n",
|
||||
rectWidth, rectHeight, rectX, rectY);
|
||||
fprintf(foo, "\n");
|
||||
for (k = cursor; k < cursorImage; k++)
|
||||
fprintf(foo, "%02X ", *k);
|
||||
for (j = 0; j < lineWords * rectHeight * 4; j++) {
|
||||
fprintf(foo, "%02X", *(cursorImage + j));
|
||||
if ((j+1) % (lineWords * 2) == 0)
|
||||
fprintf(foo, "\n");
|
||||
}
|
||||
for (k = cursorImage + j; k < cursorImage + j + 4; k = k + 1)
|
||||
fprintf(foo, "%02X ", *k);
|
||||
//for (j = 0; j < bitmaskLineBytes*rectHeight; j++) {
|
||||
// fprintf(foo, "%02X", *(bitmask + j));
|
||||
// if ((j+1) % bitmaskLineBytes == 0)
|
||||
// fprintf(foo, "\n");
|
||||
// }
|
||||
fprintf(foo, "\n");
|
||||
fclose(foo);
|
||||
}
|
||||
/***************/
|
||||
#endif
|
||||
|
||||
displayInProgress = FALSE;
|
||||
NextRect(); /* Prepare for next rect */
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
extern unsigned char * cursor; /* Cursor from server */
|
||||
extern void DoPointerEvent (void);
|
||||
extern void DoCursor (void);
|
160
oldDoReadTCP.cc
160
oldDoReadTCP.cc
|
@ -1,160 +0,0 @@
|
|||
|
||||
#if 0
|
||||
/* Old version of DoReadTCP with lots of obfuscated junk in it. Don't use. */
|
||||
BOOLEAN DoReadTCP (unsigned long dataLength, BOOLEAN waitForData) {
|
||||
#define buffTypePointer 0x0000
|
||||
#define buffTypeHandle 0x0001
|
||||
#define buffTypeNewHandle 0x0002
|
||||
|
||||
static srBuff theSRBuff;
|
||||
static rrBuff theRRBuff;
|
||||
unsigned long remainingDataLength = 0;
|
||||
unsigned long initialTime;
|
||||
void * currentDataPtr;
|
||||
static unsigned long bytesBeforeExtraBytes = 0; /* Only valid if */
|
||||
/* extraBytes > 0 */
|
||||
static unsigned long extraBytes = 0;
|
||||
|
||||
restart:
|
||||
|
||||
/* Check if there was extra data left over from the last read */
|
||||
if (extraBytes > 0) {
|
||||
HLock(readBufferHndl);
|
||||
BlockMove((char *)*readBufferHndl + bytesBeforeExtraBytes,
|
||||
*readBufferHndl, extraBytes);
|
||||
HUnlock(readBufferHndl);
|
||||
SetHandleSize(extraBytes, readBufferHndl);
|
||||
|
||||
if (extraBytes >= dataLength) {
|
||||
bytesBeforeExtraBytes = dataLength;
|
||||
extraBytes = extraBytes - dataLength;
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
remainingDataLength = dataLength - extraBytes;
|
||||
theRRBuff.rrPushFlag = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if there is enough data to return. If the waitForData flag is */
|
||||
/* set, wait up to 15 seconds for the data to arrive */
|
||||
initialTime = TickCount();
|
||||
do {
|
||||
if (TickCount() >= initialTime + 15*60) {
|
||||
readError = 1;
|
||||
return FALSE;
|
||||
}
|
||||
TCPIPPoll();
|
||||
if ((TCPIPStatusTCP(hostIpid, &theSRBuff)) &&
|
||||
(theSRBuff.srRcvQueued < dataLength)) {
|
||||
readError = 2;
|
||||
return FALSE;
|
||||
}
|
||||
if (toolerror()) {
|
||||
readError = 3;
|
||||
return FALSE;
|
||||
}
|
||||
if ((theSRBuff.srRcvQueued < dataLength) && (waitForData == FALSE)) {
|
||||
return FALSE;
|
||||
}
|
||||
} while ((theSRBuff.srRcvQueued < dataLength));
|
||||
|
||||
printf("Wanted %lu bytes; %lu bytes available.\n", dataLength, theSRBuff.srRcvQueued);
|
||||
printf("Out of main loop. Started %lu; now %lu.\n", initialTime, TickCount());
|
||||
|
||||
/* Try to read the data */
|
||||
if ((remainingDataLength == 0) &&
|
||||
(TCPIPReadTCP(hostIpid, buffTypeHandle, (Ref) readBufferHndl,
|
||||
dataLength, &theRRBuff)) && (theRRBuff.rrBuffCount < dataLength)) {
|
||||
readError = 4;
|
||||
return FALSE;
|
||||
}
|
||||
if (toolerror()) {
|
||||
readError = 5;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
printf("rrBuffCount (data read) = %lu; dataLength (data requested) = %lu\n", theRRBuff.rrBuffCount, dataLength);
|
||||
|
||||
/* Return successfully if the data was read */
|
||||
if (theRRBuff.rrBuffCount >= dataLength) {
|
||||
if (theRRBuff.rrBuffCount > dataLength) {
|
||||
extraBytes = theRRBuff.rrBuffCount - dataLength;
|
||||
bytesBeforeExtraBytes = dataLength;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
/* An ugly workaround for an apparent Marinetti bug wherein at least the
|
||||
* requested amount of data is supposedly available in its buffers, but
|
||||
* for some reason Marinetti returns less data than that in TCPIPReadTCP().
|
||||
*/
|
||||
#if 1
|
||||
else if ((theRRBuff.rrBuffCount > 0) && /*(extraBytes == 0) &&*/
|
||||
(theRRBuff.rrBuffCount < dataLength)) {
|
||||
char foo[200];
|
||||
char **bar = (char **)&foo;
|
||||
sprintf(foo, "Returned:%lu Wanted:%lu Supposedly available:%lu", (unsigned long)(theRRBuff.rrBuffCount), (unsigned long)dataLength, (unsigned long)(theSRBuff.srRcvQueued));
|
||||
//printf("Handling extra bytes\n");
|
||||
//extraBytes = theRRBuff.rrBuffCount;
|
||||
//bytesBeforeExtraBytes = 0;
|
||||
AlertWindow(awResource, (Pointer)&bar, 10000);
|
||||
//return FALSE;
|
||||
//goto restart;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
/* This may not be necessary and should not normally be used. It */
|
||||
/* continues requesting data until a sufficient amount has been */
|
||||
/* received, which may be necessary when the data stream contains push */
|
||||
/* flags. */
|
||||
else if (theRRBuff.rrPushFlag) {
|
||||
//printf("Handling push flag in middle of data.\n");
|
||||
remainingDataLength = dataLength;
|
||||
SetHandleSize(dataLength, readBufferHndl);
|
||||
HLock(readBufferHndl);
|
||||
currentDataPtr = (*readBufferHndl) + theRRBuff.rrBuffCount;
|
||||
|
||||
while (theRRBuff.rrPushFlag && (remainingDataLength > 0)) {
|
||||
TCPIPPoll();
|
||||
|
||||
if ((TCPIPReadTCP(hostIpid, buffTypeHandle, NULL,
|
||||
remainingDataLength, &theRRBuff)) &&
|
||||
(theRRBuff.rrBuffCount < dataLength)) {
|
||||
readError = 6;
|
||||
return FALSE;
|
||||
}
|
||||
if (toolerror()) {
|
||||
readError = 7;
|
||||
return FALSE;
|
||||
}
|
||||
if (theRRBuff.rrBuffCount > 0) {
|
||||
HandToPtr(theRRBuff.rrBuffHandle, currentDataPtr,
|
||||
(theRRBuff.rrBuffCount < remainingDataLength) ?
|
||||
theRRBuff.rrBuffCount : remainingDataLength);
|
||||
DisposeHandle(theRRBuff.rrBuffHandle);
|
||||
if (theRRBuff.rrBuffCount > remainingDataLength) {
|
||||
extraBytes = theRRBuff.rrBuffCount - dataLength;
|
||||
bytesBeforeExtraBytes = remainingDataLength;
|
||||
theRRBuff.rrBuffCount = remainingDataLength;
|
||||
}
|
||||
currentDataPtr += theRRBuff.rrBuffCount;
|
||||
remainingDataLength -= theRRBuff.rrBuffCount;
|
||||
if (remainingDataLength == 0) {
|
||||
HUnlock(readBufferHndl);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
HUnlock(readBufferHndl);
|
||||
readError = 8;
|
||||
return FALSE;
|
||||
}
|
||||
}
|