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 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
|
System Requirements
|
||||||
A (real or emulated) ROM 01 or ROM 3 Apple IIgs
|
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
|
unset exit
|
||||||
|
|
||||||
set link false
|
set link false
|
||||||
set vncview false
|
|
||||||
set vncsession false
|
|
||||||
set vncdisplay false
|
|
||||||
set colortables false
|
|
||||||
set rezfork false
|
set rezfork false
|
||||||
|
|
||||||
clearmem
|
clearmem
|
||||||
|
|
||||||
newer vncview.a vncview.cc
|
for {header} in vncview vncsession vncdisplay colortables menus \
|
||||||
if {status} != 0
|
desktopsize mouse keyboard copyrect raw hextile clipboard
|
||||||
set vncview true
|
unset exit
|
||||||
set link true
|
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
|
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
|
end
|
||||||
|
|
||||||
|
unset exit
|
||||||
newer vncview.rezfork vncview.rez
|
newer vncview.rezfork vncview.rez
|
||||||
if {status} != 0
|
if {status} != 0
|
||||||
set rezfork true
|
set exit on
|
||||||
end
|
|
||||||
|
|
||||||
set exit on
|
|
||||||
|
|
||||||
if {rezfork} == true
|
|
||||||
compile vncview.rez keep=vncview.rezfork
|
compile vncview.rez keep=vncview.rezfork
|
||||||
copy -C -P -R vncview.rezfork VNCview.GS
|
copy -C -P -R vncview.rezfork VNCview.GS
|
||||||
end
|
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
|
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
|
filetype VNCview.GS S16 $DB03
|
||||||
end
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HUnlock(readBufferHndl);
|
|
||||||
readError = 9;
|
|
||||||
return FALSE;
|
|
||||||
#undef buffTypeNewHandle
|
|
||||||
}
|
|
||||||
#endif /* 0 */
|
|
|
@ -0,0 +1,396 @@
|
||||||
|
#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"
|
||||||
|
|
||||||
|
/* Data on state of raw rectangle drawing routines */
|
||||||
|
unsigned int lineBytes; /* Number of bytes in a line of GS pixels */
|
||||||
|
unsigned long pixels;
|
||||||
|
|
||||||
|
unsigned int drawingLine; /* Line to be drawn while displaying */
|
||||||
|
static BOOLEAN extraByteAdvance;
|
||||||
|
|
||||||
|
unsigned char *destPtr;
|
||||||
|
|
||||||
|
/* Ends drawing of a raw rectangle when it is complete or aborted
|
||||||
|
* because the rectangle is not visible.
|
||||||
|
*/
|
||||||
|
void StopRawDrawing (void) {
|
||||||
|
HUnlock(readBufferHndl);
|
||||||
|
free(srcLocInfo.ptrToPixImage); /* Allocated as destPtr */
|
||||||
|
|
||||||
|
displayInProgress = FALSE;
|
||||||
|
|
||||||
|
NextRect(); /* Prepare for next rect */
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma optimize 95 /* To work around an ORCA/C optimizer bug */
|
||||||
|
|
||||||
|
/* Draw one or more lines from a raw rectangle
|
||||||
|
*/
|
||||||
|
void RawDraw (void) {
|
||||||
|
unsigned int i; /* Loop indices */
|
||||||
|
unsigned char *dataPtr;
|
||||||
|
unsigned char *lineDataPtr, *initialLineDataPtr;
|
||||||
|
unsigned char *finalDestPtr;
|
||||||
|
static EventRecord unusedEventRec;
|
||||||
|
|
||||||
|
/* For use with GetContentOrigin() */
|
||||||
|
unsigned long contentOrigin;
|
||||||
|
Point * contentOriginPtr = (void *) &contentOrigin;
|
||||||
|
|
||||||
|
SetPort(vncWindow); /* Drawing in VNC window */
|
||||||
|
dataPtr = (unsigned char *) *readBufferHndl;
|
||||||
|
|
||||||
|
/* Check if what we're drawing is visible, and skip any invisible part
|
||||||
|
* by skipping some lines or completely aborting drawing the rectangle.
|
||||||
|
*/
|
||||||
|
if (checkBounds) {
|
||||||
|
Rect drawingRect;
|
||||||
|
|
||||||
|
contentOrigin = GetContentOrigin(vncWindow);
|
||||||
|
drawingRect.h1 = rectX - contentOriginPtr->h;
|
||||||
|
drawingRect.h2 = rectX - contentOriginPtr->h + rectWidth;
|
||||||
|
drawingRect.v1 = rectY - contentOriginPtr->v + drawingLine;
|
||||||
|
drawingRect.v2 = rectY - contentOriginPtr->v + rectHeight;
|
||||||
|
|
||||||
|
if (!RectInRgn(&drawingRect, GetVisHandle())) {
|
||||||
|
StopRawDrawing();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (rectY + drawingLine < contentOriginPtr->v) {
|
||||||
|
destPtr += (unsigned long)lineBytes *
|
||||||
|
(contentOriginPtr->v - rectY - drawingLine);
|
||||||
|
drawingLine = contentOriginPtr->v - rectY;
|
||||||
|
|
||||||
|
if (drawingLine >= rectHeight) { /* Sanity check */
|
||||||
|
StopRawDrawing();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (rectY + rectHeight - 1 > contentOriginPtr->v + winHeight)
|
||||||
|
rectHeight = contentOriginPtr->v + winHeight - rectY + 1;
|
||||||
|
|
||||||
|
checkBounds = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
lineDataPtr = dataPtr + (unsigned long) drawingLine * rectWidth;
|
||||||
|
|
||||||
|
do { /* We short-circuit back to here if there are no events pending */
|
||||||
|
|
||||||
|
finalDestPtr = destPtr + lineBytes - 1;
|
||||||
|
if (hRez == 640) {
|
||||||
|
initialLineDataPtr = lineDataPtr;
|
||||||
|
while (destPtr + 7 < finalDestPtr) { /* Unrolled loop */
|
||||||
|
*(destPtr++) = bigcoltab640a[*(unsigned int*)(void*)lineDataPtr]
|
||||||
|
+ bigcoltab640b[*(unsigned int*)(void*)(lineDataPtr+2)];
|
||||||
|
lineDataPtr += 4;
|
||||||
|
*(destPtr++) = bigcoltab640a[*(unsigned int*)(void*)lineDataPtr]
|
||||||
|
+ bigcoltab640b[*(unsigned int*)(void*)(lineDataPtr+2)];
|
||||||
|
lineDataPtr += 4;
|
||||||
|
*(destPtr++) = bigcoltab640a[*(unsigned int*)(void*)lineDataPtr]
|
||||||
|
+ bigcoltab640b[*(unsigned int*)(void*)(lineDataPtr+2)];
|
||||||
|
lineDataPtr += 4;
|
||||||
|
*(destPtr++) = bigcoltab640a[*(unsigned int*)(void*)lineDataPtr]
|
||||||
|
+ bigcoltab640b[*(unsigned int*)(void*)(lineDataPtr+2)];
|
||||||
|
lineDataPtr += 4;
|
||||||
|
*(destPtr++) = bigcoltab640a[*(unsigned int*)(void*)lineDataPtr]
|
||||||
|
+ bigcoltab640b[*(unsigned int*)(void*)(lineDataPtr+2)];
|
||||||
|
lineDataPtr += 4;
|
||||||
|
*(destPtr++) = bigcoltab640a[*(unsigned int*)(void*)lineDataPtr]
|
||||||
|
+ bigcoltab640b[*(unsigned int*)(void*)(lineDataPtr+2)];
|
||||||
|
lineDataPtr += 4;
|
||||||
|
*(destPtr++) = bigcoltab640a[*(unsigned int*)(void*)lineDataPtr]
|
||||||
|
+ bigcoltab640b[*(unsigned int*)(void*)(lineDataPtr+2)];
|
||||||
|
lineDataPtr += 4;
|
||||||
|
*(destPtr++) = bigcoltab640a[*(unsigned int*)(void*)lineDataPtr]
|
||||||
|
+ bigcoltab640b[*(unsigned int*)(void*)(lineDataPtr+2)];
|
||||||
|
lineDataPtr += 4;
|
||||||
|
}
|
||||||
|
while (destPtr < finalDestPtr) {
|
||||||
|
*(destPtr++) = bigcoltab640a[*(unsigned int*)(void*)lineDataPtr]
|
||||||
|
+ bigcoltab640b[*(unsigned int*)(void*)(lineDataPtr+2)];
|
||||||
|
lineDataPtr += 4;
|
||||||
|
}
|
||||||
|
/* Final byte to produce */
|
||||||
|
*destPtr = pixTransTbl[*(lineDataPtr++)] & 0xC0;
|
||||||
|
for (i = lineDataPtr - initialLineDataPtr; i < rectWidth; i++)
|
||||||
|
switch (i & 0x03) {
|
||||||
|
case 0x01: /* pixels 1, 5, 9, ... */
|
||||||
|
*destPtr += pixTransTbl[*(lineDataPtr++)] & 0x30;
|
||||||
|
break;
|
||||||
|
case 0x02: /* pixels 2, 6, 10, ... */
|
||||||
|
*destPtr += pixTransTbl[*(lineDataPtr++)] & 0x0C;
|
||||||
|
break;
|
||||||
|
case 0x03: /* pixels 3, 7, 11, ... */
|
||||||
|
*destPtr += pixTransTbl[*(lineDataPtr++)] & 0x03;
|
||||||
|
}
|
||||||
|
destPtr++;
|
||||||
|
}
|
||||||
|
else { /* 320 mode */
|
||||||
|
while (destPtr + 7 < finalDestPtr) { /* Unrolled loop */
|
||||||
|
*(destPtr++) = bigcoltab320[*(unsigned int*)(void*)lineDataPtr];
|
||||||
|
lineDataPtr += 2;
|
||||||
|
*(destPtr++) = bigcoltab320[*(unsigned int*)(void*)lineDataPtr];
|
||||||
|
lineDataPtr += 2;
|
||||||
|
*(destPtr++) = bigcoltab320[*(unsigned int*)(void*)lineDataPtr];
|
||||||
|
lineDataPtr += 2;
|
||||||
|
*(destPtr++) = bigcoltab320[*(unsigned int*)(void*)lineDataPtr];
|
||||||
|
lineDataPtr += 2;
|
||||||
|
*(destPtr++) = bigcoltab320[*(unsigned int*)(void*)lineDataPtr];
|
||||||
|
lineDataPtr += 2;
|
||||||
|
*(destPtr++) = bigcoltab320[*(unsigned int*)(void*)lineDataPtr];
|
||||||
|
lineDataPtr += 2;
|
||||||
|
*(destPtr++) = bigcoltab320[*(unsigned int*)(void*)lineDataPtr];
|
||||||
|
lineDataPtr += 2;
|
||||||
|
*(destPtr++) = bigcoltab320[*(unsigned int*)(void*)lineDataPtr];
|
||||||
|
lineDataPtr += 2;
|
||||||
|
}
|
||||||
|
while (destPtr < finalDestPtr) {
|
||||||
|
*(destPtr++) = bigcoltab320[*(unsigned int*)(void*)lineDataPtr];
|
||||||
|
lineDataPtr += 2;
|
||||||
|
}
|
||||||
|
/* Final byte to produce */
|
||||||
|
*destPtr = pixTransTbl[*(lineDataPtr++)] & 0xF0;
|
||||||
|
if (extraByteAdvance)
|
||||||
|
destPtr++; /* Not ending on byte boundary - update index */
|
||||||
|
else
|
||||||
|
*(destPtr++) += pixTransTbl[*(lineDataPtr++)] & 0x0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawingLine++;
|
||||||
|
|
||||||
|
if (pixels > 613 && !(drawingLine & 0x03)) { /* Draw every 4th line */
|
||||||
|
srcRect.v2 = drawingLine;
|
||||||
|
contentOrigin = GetContentOrigin(vncWindow);
|
||||||
|
PPToPort(&srcLocInfo, &srcRect, rectX - contentOriginPtr->h,
|
||||||
|
rectY + srcRect.v1 - contentOriginPtr->v, modeCopy);
|
||||||
|
srcRect.v1 = drawingLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether we're done with this rectangle */
|
||||||
|
if (drawingLine >= rectHeight) {
|
||||||
|
/* Draw final rect, if necessary */
|
||||||
|
if (drawingLine > srcRect.v1) {
|
||||||
|
srcRect.v2 = drawingLine;
|
||||||
|
contentOrigin = GetContentOrigin(vncWindow);
|
||||||
|
PPToPort(&srcLocInfo, &srcRect, rectX - contentOriginPtr->h,
|
||||||
|
rectY + srcRect.v1 - contentOriginPtr->v, modeCopy);
|
||||||
|
}
|
||||||
|
StopRawDrawing();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if there are actually any events that need to be processed.
|
||||||
|
* If not, save time by not going through the whole event loop, but
|
||||||
|
* instead processing the minimum necessary periodic tasks and then
|
||||||
|
* going straight to the next line of data.
|
||||||
|
*/
|
||||||
|
if (EventAvail(0xFFFF, &unusedEventRec))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SystemTask(); /* Let periodic Desk Accesories do their things */
|
||||||
|
TCPIPPoll(); /* Let Marinetti keep processing data */
|
||||||
|
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma optimize -1
|
||||||
|
|
||||||
|
/* Draw one line of Raw data - used if the complete rect isn't yet available */
|
||||||
|
void RawDrawLine (void) {
|
||||||
|
unsigned int i;
|
||||||
|
unsigned char *dataPtr;
|
||||||
|
unsigned long contentOrigin;
|
||||||
|
Point * contentOriginPtr = (void *) &contentOrigin;
|
||||||
|
|
||||||
|
if (hRez == 640) {
|
||||||
|
if (rectWidth & 0x03) /* Width not an exact multiple of 4 */
|
||||||
|
lineBytes = rectWidth/4 + 1;
|
||||||
|
else /* Width is a multiple of 4 */
|
||||||
|
lineBytes = rectWidth/4;
|
||||||
|
}
|
||||||
|
else { /* 320 mode */
|
||||||
|
if (rectWidth & 0x01) /* Width not an exact multiple of 2 */
|
||||||
|
lineBytes = rectWidth/2 + 1;
|
||||||
|
else /* Width is a multiple of 2 */
|
||||||
|
lineBytes = rectWidth/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
destPtr = calloc(lineBytes, 1);
|
||||||
|
if (!destPtr) { /* Couldn't allocate memory */
|
||||||
|
DoClose(vncWindow);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
srcLocInfo.ptrToPixImage = destPtr;
|
||||||
|
srcLocInfo.width = lineBytes;
|
||||||
|
srcLocInfo.boundsRect.v2 = 1;
|
||||||
|
/* 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; break;
|
||||||
|
case 0x01: srcLocInfo.boundsRect.h2 = rectWidth+3; break;
|
||||||
|
case 0x02: srcLocInfo.boundsRect.h2 = rectWidth+2; break;
|
||||||
|
case 0x03: srcLocInfo.boundsRect.h2 = rectWidth+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (rectWidth & 0x01) {
|
||||||
|
case 0x00: srcLocInfo.boundsRect.h2 = rectWidth; break;
|
||||||
|
case 0x01: srcLocInfo.boundsRect.h2 = rectWidth+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't include padding in the area we will actually copy over */
|
||||||
|
srcRect.h2 = rectWidth;
|
||||||
|
srcRect.v1 = 0;
|
||||||
|
srcRect.v2 = 1;
|
||||||
|
|
||||||
|
HLock(readBufferHndl);
|
||||||
|
dataPtr = (unsigned char *) *readBufferHndl;
|
||||||
|
SetPort(vncWindow); /* Drawing in VNC window */
|
||||||
|
|
||||||
|
if (hRez == 640)
|
||||||
|
for (i = 0; i < rectWidth; /* i is incremented in loop */) {
|
||||||
|
switch (i & 0x03) {
|
||||||
|
case 0x00: /* pixels 0, 4, 8, ... */
|
||||||
|
*destPtr = pixTransTbl[dataPtr[i++]] & 0xC0;
|
||||||
|
break;
|
||||||
|
case 0x01: /* pixels 1, 5, 9, ... */
|
||||||
|
*destPtr += pixTransTbl[dataPtr[i++]] & 0x30;
|
||||||
|
break;
|
||||||
|
case 0x02: /* pixels 2, 6, 10, ... */
|
||||||
|
*destPtr += pixTransTbl[dataPtr[i++]] & 0x0C;
|
||||||
|
break;
|
||||||
|
case 0x03: /* pixels 3, 7, 11, ... */
|
||||||
|
*(destPtr++) += pixTransTbl[dataPtr[i++]] & 0x03;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* 320 mode */
|
||||||
|
for (i = 0; i < rectWidth; /* i is incremented in loop */) {
|
||||||
|
if ((i & 0x01) == 0) /* pixels 0, 2, 4, ... */
|
||||||
|
*destPtr = pixTransTbl[dataPtr[i++]] & 0xF0;
|
||||||
|
else { /* pixels 1, 3, 5, ... */
|
||||||
|
*(destPtr++) += pixTransTbl[dataPtr[i++]] & 0x0F;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HUnlock(readBufferHndl);
|
||||||
|
contentOrigin = GetContentOrigin(vncWindow);
|
||||||
|
PPToPort(&srcLocInfo, &srcRect, rectX - contentOriginPtr->h,
|
||||||
|
rectY - contentOriginPtr->v, modeCopy);
|
||||||
|
free(srcLocInfo.ptrToPixImage); /* Allocated as destPtr */
|
||||||
|
|
||||||
|
TCPIPPoll();
|
||||||
|
|
||||||
|
rectHeight--; /* One less line left to draw */
|
||||||
|
rectY++; /* Rest of rect starts one line below this */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process rectangle data in raw encoding and write it to screen.
|
||||||
|
*/
|
||||||
|
void DoRawRect (void) {
|
||||||
|
unsigned long bufferLength;
|
||||||
|
|
||||||
|
pixels = (unsigned long) rectWidth * rectHeight;
|
||||||
|
|
||||||
|
/* Try to read data */
|
||||||
|
if (! DoReadTCP (pixels)) {
|
||||||
|
/* Only support line-by-line drawing if the connection is quite slow;
|
||||||
|
* otherwise it's actually detrimental to overall speed. The Hextile
|
||||||
|
* setting is used as a hint at the connection speed.
|
||||||
|
*/
|
||||||
|
if (useHextile && rectHeight > 1 && DoReadTCP ((unsigned long) rectWidth))
|
||||||
|
RawDrawLine(); /* Some data ready - draw first line */
|
||||||
|
return; /* Not ready yet; wait */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Here if data is ready to be processed */
|
||||||
|
|
||||||
|
if (hRez == 640) {
|
||||||
|
if (rectWidth & 0x03) { /* Width not an exact multiple of 4 */
|
||||||
|
lineBytes = rectWidth/4 + 1;
|
||||||
|
extraByteAdvance = TRUE;
|
||||||
|
}
|
||||||
|
else { /* Width is a multiple of 4 */
|
||||||
|
lineBytes = rectWidth/4;
|
||||||
|
extraByteAdvance = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { /* 320 mode */
|
||||||
|
if (rectWidth & 0x01) { /* Width not an exact multiple of 2 */
|
||||||
|
lineBytes = rectWidth/2 + 1;
|
||||||
|
extraByteAdvance = TRUE;
|
||||||
|
}
|
||||||
|
else { /* Width is a multiple of 2 */
|
||||||
|
lineBytes = rectWidth/2;
|
||||||
|
extraByteAdvance = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferLength = lineBytes * rectHeight;
|
||||||
|
destPtr = calloc(bufferLength, 1);
|
||||||
|
if (!destPtr) { /* Couldn't allocate memory */
|
||||||
|
DoClose(vncWindow);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
srcLocInfo.ptrToPixImage = destPtr;
|
||||||
|
srcLocInfo.width = lineBytes;
|
||||||
|
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; break;
|
||||||
|
case 0x01: srcLocInfo.boundsRect.h2 = rectWidth+3; break;
|
||||||
|
case 0x02: srcLocInfo.boundsRect.h2 = rectWidth+2; break;
|
||||||
|
case 0x03: srcLocInfo.boundsRect.h2 = rectWidth+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (rectWidth & 0x01) {
|
||||||
|
case 0x00: srcLocInfo.boundsRect.h2 = rectWidth; break;
|
||||||
|
case 0x01: srcLocInfo.boundsRect.h2 = rectWidth+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't include padding in the area we will actually copy over */
|
||||||
|
srcRect.h2 = rectWidth;
|
||||||
|
srcRect.v1 = 0;
|
||||||
|
|
||||||
|
displayInProgress = TRUE;
|
||||||
|
drawingLine = 0; /* Drawing first line of rect */
|
||||||
|
checkBounds = TRUE; /* Flag to check bounds when drawing 1st line */
|
||||||
|
HLock(readBufferHndl); /* Lock handle just once for efficiency */
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
extern void RawDraw (void);
|
||||||
|
extern void DoRawRect (void);
|
||||||
|
|
351
test.cc
351
test.cc
|
@ -1,351 +0,0 @@
|
||||||
/********************************************************************
|
|
||||||
* vncview.cc - main program code for VNCview GS
|
|
||||||
********************************************************************/
|
|
||||||
|
|
||||||
#if __ORCAC__
|
|
||||||
#pragma lint -1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
/* #pragma debug 25 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <orca.h>
|
|
||||||
#include <Locator.h>
|
|
||||||
#include <MiscTool.h>
|
|
||||||
#include <Event.h>
|
|
||||||
#include <Menu.h>
|
|
||||||
#include <QuickDraw.h>
|
|
||||||
#include <QDAux.h>
|
|
||||||
#include <Window.h>
|
|
||||||
#include <Desk.h>
|
|
||||||
#include <Resources.h>
|
|
||||||
#include <Memory.h>
|
|
||||||
#include <Control.h>
|
|
||||||
#include <LineEdit.h>
|
|
||||||
#include <TCPIP.h>
|
|
||||||
#include "VNCsession.h"
|
|
||||||
|
|
||||||
#define appleMenu 1
|
|
||||||
#define fileMenu 2
|
|
||||||
#define editMenu 3
|
|
||||||
|
|
||||||
#define appleAbout 257
|
|
||||||
|
|
||||||
#define fileNewConnection 260
|
|
||||||
#define fileReturnToVNCSession 261
|
|
||||||
#define fileClose 255
|
|
||||||
#define fileQuit 256
|
|
||||||
|
|
||||||
#define editUndo 250
|
|
||||||
#define editCut 251
|
|
||||||
#define editCopy 252
|
|
||||||
#define editPaste 253
|
|
||||||
#define editClear 254
|
|
||||||
#define editSendClipboard 262
|
|
||||||
|
|
||||||
#define noMarinettiError 2001
|
|
||||||
#define outOfMemoryError 2002
|
|
||||||
|
|
||||||
#define disconnectTCPIPAlert 2003
|
|
||||||
|
|
||||||
#define NCWindow 1000 /* Offset for "New Connection" */
|
|
||||||
/* window and its controls */
|
|
||||||
#define winNewConnection 1
|
|
||||||
#define btnConnect 1
|
|
||||||
#define btnCancel 2
|
|
||||||
#define linServer 3
|
|
||||||
#define txtServer 4
|
|
||||||
#define txtServerInfo 5
|
|
||||||
#define txtPassword 6
|
|
||||||
#define linPassword 7
|
|
||||||
#define txtDisplay 8
|
|
||||||
#define rectDisplay 9
|
|
||||||
#define radColor 10
|
|
||||||
#define radGray 11
|
|
||||||
#define rad320 12
|
|
||||||
#define rad640 13
|
|
||||||
#define chkLocalPtr 24
|
|
||||||
#define txtPointer 25
|
|
||||||
#define chkShared 16
|
|
||||||
#define chkClipboard 17
|
|
||||||
#define txtTransfers 23
|
|
||||||
#define chkEmul3Btn 18
|
|
||||||
#define chkViewOnly 19
|
|
||||||
#define txtDeleteSends 20
|
|
||||||
#define radDelete 21
|
|
||||||
#define radBackspace 22
|
|
||||||
|
|
||||||
BOOLEAN done = FALSE; /* are we done, yet? */
|
|
||||||
EventRecord myEvent; /* event record for menu mode */
|
|
||||||
GrafPortPtr newConnWindow; /* pointer to new connection window */
|
|
||||||
BOOLEAN vncConnected = FALSE; /* are we connected to a VNC host */
|
|
||||||
|
|
||||||
/* Connection options */
|
|
||||||
BOOLEAN color = TRUE;
|
|
||||||
int hRez = 320;
|
|
||||||
BOOLEAN requestSharedSession = FALSE;
|
|
||||||
BOOLEAN allowClipboardTransfers = TRUE;
|
|
||||||
BOOLEAN emulate3ButtonMouse = FALSE;
|
|
||||||
BOOLEAN viewOnlyMode = FALSE;
|
|
||||||
BOOLEAN localPointer = FALSE;
|
|
||||||
unsigned long deleteKeysym = 0xff08;
|
|
||||||
char vncServer[257];
|
|
||||||
char vncPassword[10];
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* DrawContents - Draw the contents of the active port
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
#pragma databank 1
|
|
||||||
|
|
||||||
void DrawContents (void) {
|
|
||||||
PenNormal(); /* use a "normal" pen */
|
|
||||||
DrawControls(GetPort()); /* draw controls in window */
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma databank 0
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* DoAbout - Draw our about box
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
void DoAbout (void) {
|
|
||||||
#define alertID 1 /* alert string resource ID */
|
|
||||||
|
|
||||||
AlertWindow(awCString+awResource, NULL, alertID);
|
|
||||||
|
|
||||||
#undef alertID
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* DoNewConnection - Show the New Connection window
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
void DoNewConnection (void) {
|
|
||||||
MakeThisCtlTarget(GetCtlHandleFromID(newConnWindow, linServer));
|
|
||||||
ShowWindow(newConnWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* DoClose - Close the frontmost window/connection
|
|
||||||
* Parameters:
|
|
||||||
* wPtr - window to close
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
void DoClose (GrafPortPtr wPtr) {
|
|
||||||
if (wPtr == newConnWindow) {
|
|
||||||
HideWindow(newConnWindow);
|
|
||||||
}
|
|
||||||
else if (wPtr && vncConnected) { /* Close VNC session if no other */
|
|
||||||
/* DisconnectVNCSession(); */ /* are open on top of VNC window */
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* DoLEEdit - Handle edit menu items for LineEdit controls
|
|
||||||
* Parameters:
|
|
||||||
* editAction: Action selected from edit menu
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
void DoLEEdit (int editAction) {
|
|
||||||
CtlRecHndl ctl; /* target control handle */
|
|
||||||
unsigned long id; /* control ID */
|
|
||||||
GrafPortPtr port; /* caller's GrafPort */
|
|
||||||
|
|
||||||
port = GetPort();
|
|
||||||
SetPort(newConnWindow);
|
|
||||||
ctl = FindTargetCtl();
|
|
||||||
id = GetCtlID(ctl);
|
|
||||||
if ((id == linServer) || (id == linPassword)) {
|
|
||||||
LEFromScrap();
|
|
||||||
switch (editAction) {
|
|
||||||
case editCut: if (id == linServer) {
|
|
||||||
LECut((LERecHndl) GetCtlTitle(ctl));
|
|
||||||
};
|
|
||||||
LEToScrap();
|
|
||||||
break;
|
|
||||||
case editCopy: if (id == linServer) {
|
|
||||||
LECopy((LERecHndl) GetCtlTitle(ctl));
|
|
||||||
};
|
|
||||||
LEToScrap();
|
|
||||||
break;
|
|
||||||
case editPaste: LEPaste((LERecHndl) GetCtlTitle(ctl));
|
|
||||||
break;
|
|
||||||
case editClear: LEDelete((LERecHndl) GetCtlTitle(ctl));
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
SetPort(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* HandleMenu - Initialize the menu bar.
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
void HandleMenu (void) {
|
|
||||||
int menuNum, menuItemNum; /* menu number & menu item number */
|
|
||||||
|
|
||||||
menuNum = myEvent.wmTaskData >> 16;
|
|
||||||
menuItemNum = myEvent.wmTaskData;
|
|
||||||
switch (menuItemNum) { /* go handle the menu */
|
|
||||||
case appleAbout: DoAbout(); break;
|
|
||||||
|
|
||||||
case fileNewConnection: DoNewConnection(); break;
|
|
||||||
case fileReturnToVNCSession: break;
|
|
||||||
case fileClose: DoClose(FrontWindow()); break;
|
|
||||||
case fileQuit: done = TRUE; break;
|
|
||||||
|
|
||||||
case editCut: DoLEEdit(editCut); break;
|
|
||||||
case editCopy: DoLEEdit(editCopy); break;
|
|
||||||
case editPaste: DoLEEdit(editPaste); break;
|
|
||||||
case editClear: DoLEEdit(editClear); break;
|
|
||||||
}
|
|
||||||
HiliteMenu(FALSE, menuNum); /* unhighlight the menu */
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* HandleControl - Handle a control press in the New Conn. window
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
void HandleControl (void) {
|
|
||||||
switch (myEvent.wmTaskData4) {
|
|
||||||
case btnConnect: DoConnect(); break;
|
|
||||||
case btnCancel: DoClose(newConnWindow); break;
|
|
||||||
case radColor: color = TRUE; break;
|
|
||||||
case radGray: color = FALSE; break;
|
|
||||||
case rad320: hRez = 320; /* "320x200" */ break;
|
|
||||||
case rad640: hRez = 640; /* "640x200" */ break;
|
|
||||||
case chkShared: requestSharedSession = !requestSharedSession;
|
|
||||||
break;
|
|
||||||
case chkClipboard: allowClipboardTransfers = !allowClipboardTransfers;
|
|
||||||
break;
|
|
||||||
case chkEmul3Btn: emulate3ButtonMouse = !emulate3ButtonMouse; break;
|
|
||||||
case chkViewOnly: viewOnlyMode = !viewOnlyMode; break;
|
|
||||||
case radDelete: deleteKeysym = 0xffff; /* delete -> del */ break;
|
|
||||||
case radBackspace: deleteKeysym = 0xff08; /* delete -> bs */ break;
|
|
||||||
case txtTransfers: allowClipboardTransfers = !allowClipboardTransfers;
|
|
||||||
SetCtlValueByID(!allowClipboardTransfers,
|
|
||||||
newConnWindow, 17); break;
|
|
||||||
case chkLocalPtr: localPointer = !localPointer; break;
|
|
||||||
case txtPointer: SetCtlValueByID(!localPointer, newConnWindow, 24);
|
|
||||||
localPointer = !localPointer; break;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* InitMenus - Initialize the menu bar.
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
void InitMenus (void) {
|
|
||||||
#define menuID 1 /* menu bar resource ID */
|
|
||||||
|
|
||||||
int height; /* height of the largest menu */
|
|
||||||
MenuBarRecHndl menuBarHand; /* for 'handling' the menu bar */
|
|
||||||
|
|
||||||
/* create the menu bar */
|
|
||||||
menuBarHand = NewMenuBar2(refIsResource, menuID, NULL);
|
|
||||||
SetSysBar(menuBarHand);
|
|
||||||
SetMenuBar(NULL);
|
|
||||||
FixAppleMenu(1); /* add desk accessories */
|
|
||||||
height = FixMenuBar(); /* draw the completed menu bar */
|
|
||||||
DrawMenuBar();
|
|
||||||
|
|
||||||
#undef menuID
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* CheckMenus - Check the menus to see if they should be dimmed
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
void CheckMenus (void) {
|
|
||||||
GrafPortPtr activeWindow; /* Front visible window */
|
|
||||||
|
|
||||||
activeWindow = FrontWindow();
|
|
||||||
if (activeWindow) {
|
|
||||||
if (GetSysWFlag(activeWindow)) { /* NDA window is active */
|
|
||||||
EnableMItem(fileClose);
|
|
||||||
EnableMItem(editUndo);
|
|
||||||
EnableMItem(editCut);
|
|
||||||
EnableMItem(editCopy);
|
|
||||||
EnableMItem(editPaste);
|
|
||||||
EnableMItem(editClear);
|
|
||||||
}
|
|
||||||
else if (activeWindow == newConnWindow) { /* New Connection window */
|
|
||||||
EnableMItem(fileClose);
|
|
||||||
DisableMItem(editUndo);
|
|
||||||
EnableMItem(editCut);
|
|
||||||
EnableMItem(editCopy);
|
|
||||||
EnableMItem(editPaste);
|
|
||||||
EnableMItem(editClear);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { /* no editable window on top */
|
|
||||||
DisableMItem(fileClose);
|
|
||||||
DisableMItem(editUndo);
|
|
||||||
DisableMItem(editCut);
|
|
||||||
DisableMItem(editCopy);
|
|
||||||
DisableMItem(editPaste);
|
|
||||||
DisableMItem(editClear);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (vncConnected) { /* VNC connection present */
|
|
||||||
EnableMItem(fileReturnToVNCSession);
|
|
||||||
EnableMItem(fileClose);
|
|
||||||
EnableMItem(editSendClipboard);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DisableMItem(fileReturnToVNCSession);
|
|
||||||
DisableMItem(editSendClipboard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* Main - Initial startup function
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
int main (void) {
|
|
||||||
int event; /* event type returned by TaskMaster */
|
|
||||||
Ref startStopParm; /* tool start/shutdown parameter */
|
|
||||||
|
|
||||||
#define wrNum 1001 /* New Conn. window resource number */
|
|
||||||
|
|
||||||
startStopParm = /* start up the tools */
|
|
||||||
StartUpTools(userid(), 2, 1);
|
|
||||||
if (toolerror() != 0)
|
|
||||||
SysFailMgr(toolerror(), "\pCould not start tools: ");
|
|
||||||
#if 0
|
|
||||||
LoadOneTool(54, 0x200); /* load Marinetti 2.0+ */
|
|
||||||
if (toolerror()) { /* Check that Marinetti is available */
|
|
||||||
SysBeep();
|
|
||||||
AlertWindow(awResource, NULL, noMarinettiError);
|
|
||||||
done = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
TCPIPStartUp();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
InitMenus(); /* set up the menu bar */
|
|
||||||
InitCursor(); /* start the arrow cursor */
|
|
||||||
|
|
||||||
vncConnected = FALSE; /* Initially not connected */
|
|
||||||
|
|
||||||
newConnWindow = NewWindow2("\p New VNC Connection ", 0,
|
|
||||||
DrawContents, NULL, 0x02, wrNum, rWindParam1);
|
|
||||||
#undef wrNum
|
|
||||||
|
|
||||||
DoNewConnection(); /* Display new connection window */
|
|
||||||
|
|
||||||
/* main event loop */
|
|
||||||
myEvent.wmTaskMask = 0x001F71FF;/* let TaskMaster do everything that's needed */
|
|
||||||
while (!done) {
|
|
||||||
CheckMenus();
|
|
||||||
event = TaskMaster(everyEvent, &myEvent);
|
|
||||||
printf("In event loop after TaskMaster\n");
|
|
||||||
}
|
|
||||||
ShutDownTools(1, startStopParm); /* shut down the tools */
|
|
||||||
}
|
|
1078
vncdisplay.cc
1078
vncdisplay.cc
File diff suppressed because it is too large
Load Diff
38
vncdisplay.h
38
vncdisplay.h
|
@ -1,8 +1,41 @@
|
||||||
extern unsigned int fbHeight;
|
extern unsigned int fbHeight;
|
||||||
extern unsigned int fbWidth;
|
extern unsigned int fbWidth;
|
||||||
|
|
||||||
|
extern BOOLEAN displayInProgress;
|
||||||
|
|
||||||
|
extern unsigned int numRects;
|
||||||
|
extern unsigned int rectX;
|
||||||
|
extern unsigned int rectY;
|
||||||
|
extern unsigned int rectWidth;
|
||||||
|
extern unsigned int rectHeight;
|
||||||
|
extern unsigned long rectEncoding;
|
||||||
|
|
||||||
|
#define encodingRaw 0
|
||||||
|
#define encodingCopyRect 1
|
||||||
|
#define encodingRRE 2
|
||||||
|
#define encodingCoRRE 4
|
||||||
|
#define encodingHextile 5
|
||||||
|
#define encodingZRLE 16
|
||||||
|
#define encodingCursor 0xffffff11
|
||||||
|
#define encodingDesktopSize 0xffffff21
|
||||||
|
|
||||||
extern GrafPortPtr vncWindow;
|
extern GrafPortPtr vncWindow;
|
||||||
|
|
||||||
|
/* VNC session window dimensions */
|
||||||
|
extern unsigned int winHeight;
|
||||||
|
extern unsigned int winWidth;
|
||||||
|
|
||||||
|
/* On the next 2 structs, only certain values are permanently zero.
|
||||||
|
* Others are changed later.
|
||||||
|
*/
|
||||||
|
extern struct LocInfo srcLocInfo;
|
||||||
|
|
||||||
|
/* Used by multiple encodings */
|
||||||
|
extern Rect srcRect;
|
||||||
|
extern unsigned char *pixTransTbl;
|
||||||
|
|
||||||
|
extern BOOLEAN checkBounds; /* Adjust drawing to stay in bounds */
|
||||||
|
|
||||||
void InitVNCWindow (void);
|
void InitVNCWindow (void);
|
||||||
|
|
||||||
void SendFBUpdateRequest (BOOLEAN /*incremental*/, unsigned int /*x*/,
|
void SendFBUpdateRequest (BOOLEAN /*incremental*/, unsigned int /*x*/,
|
||||||
|
@ -10,8 +43,3 @@ void SendFBUpdateRequest (BOOLEAN /*incremental*/, unsigned int /*x*/,
|
||||||
|
|
||||||
void ConnectedEventLoop (void);
|
void ConnectedEventLoop (void);
|
||||||
|
|
||||||
void DoSendClipboard (void);
|
|
||||||
void DoPointerEvent (void);
|
|
||||||
|
|
||||||
void ProcessKeyEvent (void);
|
|
||||||
void SendModifiers (void);
|
|
||||||
|
|
|
@ -635,13 +635,15 @@ BOOLEAN FinishVNCHandshaking (void) {
|
||||||
unsigned long firstEncoding;
|
unsigned long firstEncoding;
|
||||||
unsigned long secondEncoding;
|
unsigned long secondEncoding;
|
||||||
unsigned long thirdEncoding;
|
unsigned long thirdEncoding;
|
||||||
|
unsigned long fourthEncoding;
|
||||||
} encodings = {
|
} encodings = {
|
||||||
2, /* Message Type - SetEncodings */
|
2, /* Message Type - SetEncodings */
|
||||||
0, /* padding */
|
0, /* padding */
|
||||||
0, /* number of encodings - set below */
|
0, /* number of encodings - set below */
|
||||||
SwapBytes4(0xffffff21), /* DesktopSize pseudo-encoding */
|
SwapBytes4(0xffffff21), /* DesktopSize pseudo-encoding */
|
||||||
SwapBytes4(1), /* first encoding: CopyRect */
|
SwapBytes4(0xffffff11), /* Cursor pseudo-encoding */
|
||||||
SwapBytes4(5) /* second encoding: Hextile */
|
SwapBytes4(1), /* CopyRect encoding */
|
||||||
|
SwapBytes4(5) /* Hextile encoding */
|
||||||
/* Per the spec, raw encoding is supported even though
|
/* Per the spec, raw encoding is supported even though
|
||||||
* it is not listed here explicitly.
|
* it is not listed here explicitly.
|
||||||
*/
|
*/
|
||||||
|
@ -691,11 +693,11 @@ BOOLEAN FinishVNCHandshaking (void) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (useHextile) {
|
if (useHextile) {
|
||||||
encodings.numberOfEncodings = SwapBytes2(3);
|
encodings.numberOfEncodings = SwapBytes2(4);
|
||||||
encodingInfoSize = sizeof(encodings);
|
encodingInfoSize = sizeof(encodings);
|
||||||
} else {
|
} else {
|
||||||
/* No Hextile */
|
/* No Hextile */
|
||||||
encodings.numberOfEncodings = SwapBytes2(2);
|
encodings.numberOfEncodings = SwapBytes2(3);
|
||||||
encodingInfoSize = sizeof(encodings) - 4;
|
encodingInfoSize = sizeof(encodings) - 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
#include "vncdisplay.h"
|
#include "vncdisplay.h"
|
||||||
#include "menus.h"
|
#include "menus.h"
|
||||||
#include "colortables.h"
|
#include "colortables.h"
|
||||||
|
#include "mouse.h"
|
||||||
|
#include "keyboard.h"
|
||||||
|
#include "clipboard.h"
|
||||||
|
|
||||||
#define noMarinettiError 2001
|
#define noMarinettiError 2001
|
||||||
#define outOfMemoryError 2002
|
#define outOfMemoryError 2002
|
||||||
|
@ -140,6 +143,10 @@ void DoClose (GrafPortPtr wPtr) {
|
||||||
EnableMItem(fileNewConnection);
|
EnableMItem(fileNewConnection);
|
||||||
InitMenus(0);
|
InitMenus(0);
|
||||||
myEvent.wmTaskMask = 0x001F79FF; /* let TaskMaster handle keys again */
|
myEvent.wmTaskMask = 0x001F79FF; /* let TaskMaster handle keys again */
|
||||||
|
if (cursor) {
|
||||||
|
InitCursor();
|
||||||
|
free(cursor);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,6 +360,8 @@ void Quit (void) {
|
||||||
free(bigcoltab640a);
|
free(bigcoltab640a);
|
||||||
if (bigcoltab640b)
|
if (bigcoltab640b)
|
||||||
free(bigcoltab640b);
|
free(bigcoltab640b);
|
||||||
|
if (cursor)
|
||||||
|
free(cursor);
|
||||||
|
|
||||||
/* Ask the user if we should disconnect only if the connection */
|
/* Ask the user if we should disconnect only if the connection */
|
||||||
/* is not "permanent," i.e. started when the system boots up. */
|
/* is not "permanent," i.e. started when the system boots up. */
|
||||||
|
|
Loading…
Reference in New Issue