From 16f792352e0873a7471991d16b008ba939b103c1 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Wed, 23 Sep 2015 18:46:47 -0500 Subject: [PATCH] VNCview GS 1.0a1 sources --- ._README | Bin 0 -> 1210 bytes README | 71 ++++ Screen.0 | Bin 0 -> 32768 bytes colortables.h | 153 +++++++ doreadtcp | 40 ++ handleerr.cc | 87 ++++ handleerr.h | 33 ++ make | 76 ++++ make.debug | 62 +++ make.errors | 62 +++ make.optimize | 62 +++ menus.h | 19 + oldDoReadTCP.cc | 160 ++++++++ outlog.fbsd | 121 ++++++ outlog.mac | 19 + outlog.win | 14 + test.cc | 351 ++++++++++++++++ vncdisplay.cc | 1030 +++++++++++++++++++++++++++++++++++++++++++++++ vncdisplay.h | 17 + vnclog | 70 ++++ vncsession.cc | 706 ++++++++++++++++++++++++++++++++ vncsession.h | 36 ++ vncview.cc | 468 +++++++++++++++++++++ vncview.h | 30 ++ vncview.rez | 930 ++++++++++++++++++++++++++++++++++++++++++ 25 files changed, 4617 insertions(+) create mode 100644 ._README create mode 100644 README create mode 100644 Screen.0 create mode 100644 colortables.h create mode 100644 doreadtcp create mode 100644 handleerr.cc create mode 100644 handleerr.h create mode 100644 make create mode 100644 make.debug create mode 100644 make.errors create mode 100644 make.optimize create mode 100644 menus.h create mode 100644 oldDoReadTCP.cc create mode 100644 outlog.fbsd create mode 100644 outlog.mac create mode 100644 outlog.win create mode 100644 test.cc create mode 100644 vncdisplay.cc create mode 100644 vncdisplay.h create mode 100644 vnclog create mode 100644 vncsession.cc create mode 100644 vncsession.h create mode 100644 vncview.cc create mode 100644 vncview.h create mode 100644 vncview.rez diff --git a/._README b/._README new file mode 100644 index 0000000000000000000000000000000000000000..cc6971697fbf911abf7a9d306b5d6ada774b5e0a GIT binary patch literal 1210 zcmd5)u}T9$5S>jf+$$tfb^8=<5Tg!750-CgQaG)s01e z@8|@&C$6wlH$AuiY~%g5BWbbKoJv-LLJqgHnVcADIU;u-VfdQ`8J~@BBeO_9_;%ls zp>z6Pqlw($@@KyT{r@qdCGK!w5!N@2EXXzNAQV?5o*ito8r$ip?bt3Q>>xCWc+-uC zzi7_}p_7a$dY;X1+;3alX4Cq`Z8Tzg9yN`EyWk^841^4Y0Q3I)$DS#P} zx~B0N*gXFN68t+C;1&gdVk4c`_yN_?SP!iJ%-iR!<+|N7~df| j=LyvntOWbwzWr7O*vUKAbout VNCview GS...: Displays information about the program +File->New Connection: Allows you to configure and establish a new connection +File->Close: Closes current window or connection. You can connect again afterward. +File->Quit: Quits VNCview GS, closing any open connection +Edit->Undo: Only used by NDAs +Edit->Cut/Copy/Paste/Clear: Used in New VNC Connection window input boxes and NDAs +Edit->Show Clipboard: Displays the current contents of the IIgs clipboard +Edit->Send Clipboard: Transfers the contents of the IIgs clipboard to the server + +VNC Server Interoperability +VNCview GS should be able to connect with any VNC server that fully implements the RFB protocol as published by RealVNC Ltd. or its predecessors, though in practice it seems to work better with some servers than with others. Here is a list of some VNC servers for widespread platforms; many others are also available. + +Microsoft Windows & *nix (X11): RealVNC, http://www.realvnc.com/ +Mac OS X: OSXvnc, http://www.redstonesoftware.com/vnc.html +Classic Mac OS: ChromiVNC, http://www.chromatix.uklinux.net/vnc/ + +Troubleshooting +If you are experiencing problems, it may be helpful to try removing, rearranging, or even adding system extensions. This may eliminate assorted problems associated with Marinetti and its interaction with other components of the system. Upgrading to the latest version of Marinetti (3.0b1 as of this writing) may also be helpful. + +If these steps fail to resolve your problems or if you have other questions, comments, or bug reports, I can be contacted at SHeumann@myrealbox.com. + +Please be aware that VNCview GS is alpha-quality software. It generally works for me, but it has not been extensively tested in diverse environments, and it is not feature-complete (features that I hope to implement in the future include optional protocol elements that should improve speed and responsiveness). + +License +This program, "VNCview GS," is copyright (C) 2002-2004 Stephen Heumann. All rights reserved. This program contains material from the ORCA/C Run-Time Libraries, copyright 1987-1996 by Byte Works, Inc. Used with permission. + +Redistribution and use, with or without modification, are permitted provided that the following conditions are met: +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. +2. Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENT DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + \ No newline at end of file diff --git a/Screen.0 b/Screen.0 new file mode 100644 index 0000000000000000000000000000000000000000..2442890e47a33e942641779615f92342917a6f47 GIT binary patch literal 32768 zcmeI*L2AP=5CA|0dJTF(|7xdc-<5|nf6xz<#kCL7$smeFGP*3wN@zWn@yR%)u}7{$ zkD|Y>`@^q`ukz#9C(yUr`Rnu>`|X?3-5@}K009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!Cs=f!}o6GwrZBqxW~K-W#} zmLvW@n@g%WLW-aHMr`w2`m0A=>TO=u^%0kPn@?*!;!= initialTime + 15*60) + return FALSE; + if (TCPIPStatusTCP(hostIpid, &theSRBuff)) + return FALSE; + if (toolerror()) + return FALSE; + if ((theSRBuff.srRcvQueued < dataLength) && (waitForData == FALSE)) + return FALSE; + TCPIPPoll(); + } while ((theSRBuff.srRcvQueued < dataLength)); + + do { + if (TCPIPReadTCP(hostIpid, buffTypePointer, (Ref) dataBuffPtr, + remainingDataLength, &theRRBuff)) + return FALSE; + if (toolerror()) + return FALSE; + + if (theRRBuff.rrBuffCount == remainingDataLength) + return TRUE; + dataBuffPtr += theRRBuff.rrBuffCount; + remainingDataLength -= theRRBuff.rrBuffCount; + TCPIPPoll(); + } while (theRRBuff.rrMoreFlag); + + #undef buffTypeNewHandle diff --git a/handleerr.cc b/handleerr.cc new file mode 100644 index 0000000..f3f97a9 --- /dev/null +++ b/handleerr.cc @@ -0,0 +1,87 @@ +/*************************************************************** +* HandleError.cc - routines to dosplay error messages +***************************************************************/ + +#if __ORCAC__ +#pragma lint -1 +#pragma noroot +#endif + +#if DEBUG +#pragma debug 25 +#endif + +#include +#include +#include +#include + +/*************************************************************** +* 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 +} diff --git a/handleerr.h b/handleerr.h new file mode 100644 index 0000000..37f4737 --- /dev/null +++ b/handleerr.h @@ -0,0 +1,33 @@ +/*************************************************************** +* HandleError.h - header file for error handling routines +***************************************************************/ + +/*************************************************************** +* 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. +***************************************************************/ + +extern char *GetString (int resourceID); + +/*************************************************************** +* FreeString - Free a resource string +* Parameters: +* resourceID - resource ID of the rCString to free +***************************************************************/ + +extern void FreeString (int resourceID); + +/*************************************************************** +* FlagError - Flag an error +* Parameters: +* error - error message number +* tError - toolbox error code; 0 if none +***************************************************************/ + +extern void FlagError (int error, int tError); diff --git a/make b/make new file mode 100644 index 0000000..77316f3 --- /dev/null +++ b/make @@ -0,0 +1,76 @@ +unset exit + +set link false +set vncview false +set vncsession false +set vncdisplay false +set rezfork false + +clearmem + +newer vncview.a vncview.cc +if {status} != 0 + set vncview true + 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 vncview.rezfork vncview.rez +if {status} != 0 + set rezfork true +end + +set exit on + +if {rezfork} == true + 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 {link} == true + link vncview vncsession vncdisplay keep=VNCview.GS + filetype VNCview.GS S16 $DB03 +end diff --git a/make.debug b/make.debug new file mode 100644 index 0000000..d44218c --- /dev/null +++ b/make.debug @@ -0,0 +1,62 @@ +unset exit + +set link false +set vncview false +set vncsession false +set rezfork false + +newer vncview.a vncview.cc +if {status} != 0 + set vncview true + 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 vncview.rezfork vncview.rez +if {status} != 0 + set rezfork true +end + +set exit on +if {rezfork} == true + compile vncview.rez keep=vncview.rezfork + copy -C -P -R vncview.rezfork vncview.gs +end +if {vncview} == true + compile +D vncview.cc keep=vncview +end +if {vncsession} == true + compile +D vncsession.cc keep=vncsession +end +if {link} == true + link vncview vncsession keep=vncview.gs +end diff --git a/make.errors b/make.errors new file mode 100644 index 0000000..d1f6ede --- /dev/null +++ b/make.errors @@ -0,0 +1,62 @@ +unset exit + +set link false +set vncview false +set vncsession false +set rezfork false + +newer vncview.a vncview.cc +if {status} != 0 + set vncview true + 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 vncview.rezfork vncview.rez +if {status} != 0 + set rezfork true +end + +set exit on +if {rezfork} == true + compile vncview.rez keep=vncview.rezfork > vncview.err >& vncview.err + copy -C -P -R vncview.rezfork vncview.gs +end +if {vncview} == true + compile vncview.cc keep=vncview cc=(-dDEBUG 1) > vncview.err >& vncview.err +end +if {vncsession} == true + compile vncsession.cc keep=vncsession cc=(-dDEBUG 1) > vncview.err >& vncview.err +end +if {link} == true + link vncview vncsession keep=vncview.gs > vncview.err >& vncview.err +end diff --git a/make.optimize b/make.optimize new file mode 100644 index 0000000..8b4f26e --- /dev/null +++ b/make.optimize @@ -0,0 +1,62 @@ +unset exit + +set link false +set vncview false +set vncsession false +set rezfork false + +newer vncview.a vncview.cc +if {status} != 0 + set vncview true + 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 vncview.rezfork vncview.rez +if {status} != 0 + set rezfork true +end + +set exit on +if {rezfork} == true + 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 {link} == true + link vncview vncsession keep=vncview.gs +end diff --git a/menus.h b/menus.h new file mode 100644 index 0000000..8419476 --- /dev/null +++ b/menus.h @@ -0,0 +1,19 @@ +#define appleMenu 1 +#define fileMenu 2 +#define editMenu 3 + +#define appleAbout 257 + +#define fileNewConnection 260 +#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 editShowClipboard 261 + +#define noKB 100 diff --git a/oldDoReadTCP.cc b/oldDoReadTCP.cc new file mode 100644 index 0000000..034253b --- /dev/null +++ b/oldDoReadTCP.cc @@ -0,0 +1,160 @@ + +#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 */ diff --git a/outlog.fbsd b/outlog.fbsd new file mode 100644 index 0000000..583a1db --- /dev/null +++ b/outlog.fbsd @@ -0,0 +1,121 @@ +Requested 12 bytes, 12 bytes reported available, 12 bytes returned +Requested 4 bytes, 20 bytes reported available, 4 bytes returned +Requested 16 bytes, 16 bytes reported available, 16 bytes returned +Requested 4 bytes, 4 bytes reported available, 4 bytes returned +Requested 2 bytes, 67 bytes reported available, 2 bytes returned +Requested 2 bytes, 65 bytes reported available, 2 bytes returned +Requested 16 bytes, 63 bytes reported available, 16 bytes returned +Requested 4 bytes, 47 bytes reported available, 4 bytes returned +Requested 43 bytes, 43 bytes reported available, 43 bytes returned +Requested 1 bytes, 1024 bytes reported available, 1 bytes returned +Requested 15 bytes, 2047 bytes reported available, 15 bytes returned +Requested 106662 bytes, 106662 bytes reported available, 106662 bytes returned +Requested 1 bytes, 190 bytes reported available, 1 bytes returned +Requested 15 bytes, 189 bytes reported available, 15 bytes returned +Requested 174 bytes, 174 bytes reported available, 174 bytes returned +Requested 1 bytes, 1024 bytes reported available, 1 bytes returned +Requested 15 bytes, 2047 bytes reported available, 15 bytes returned +Requested 101924 bytes, 101924 bytes reported available, 101924 bytes returned +Requested 1 bytes, 1024 bytes reported available, 1 bytes returned +Requested 15 bytes, 2047 bytes reported available, 15 bytes returned +Requested 101758 bytes, 101758 bytes reported available, 101758 bytes returned +Requested 1 bytes, 182 bytes reported available, 1 bytes returned +Requested 15 bytes, 181 bytes reported available, 15 bytes returned +Requested 166 bytes, 166 bytes reported available, 166 bytes returned +Requested 1 bytes, 1024 bytes reported available, 1 bytes returned +Requested 15 bytes, 2047 bytes reported available, 15 bytes returned +Requested 101758 bytes, 101758 bytes reported available, 101758 bytes returned +Requested 1 bytes, 1024 bytes reported available, 1 bytes returned +Requested 15 bytes, 2047 bytes reported available, 15 bytes returned +Requested 101758 bytes, 101758 bytes reported available, 101758 bytes returned +Requested 1 bytes, 1024 bytes reported available, 1 bytes returned +Requested 15 bytes, 2047 bytes reported available, 15 bytes returned +Requested 71514 bytes, 71514 bytes reported available, 71514 bytes returned +Requested 1 bytes, 1024 bytes reported available, 1 bytes returned +Requested 15 bytes, 2047 bytes reported available, 15 bytes returned +Requested 71514 bytes, 71514 bytes reported available, 71514 bytes returned +Requested 1 bytes, 1024 bytes reported available, 1 bytes returned +Requested 15 bytes, 1023 bytes reported available, 15 bytes returned +Requested 4 bytes, 1008 bytes reported available, 4 bytes returned +Requested 12 bytes, 1004 bytes reported available, 12 bytes returned +Requested 4 bytes, 992 bytes reported available, 4 bytes returned +Requested 12 bytes, 988 bytes reported available, 12 bytes returned +Requested 4 bytes, 976 bytes reported available, 4 bytes returned +Requested 12 bytes, 1484 bytes reported available, 12 bytes returned +Requested 4 bytes, 4544 bytes reported available, 4 bytes returned +Requested 12 bytes, 5052 bytes reported available, 12 bytes returned +Requested 261 bytes, 6513 bytes reported available, 261 bytes returned +Requested 12 bytes, 6252 bytes reported available, 12 bytes returned +Requested 6240 bytes, 6240 bytes reported available, 6240 bytes returned +Requested 1 bytes, 1024 bytes reported available, 1 bytes returned +Requested 15 bytes, 2047 bytes reported available, 15 bytes returned +Requested 4 bytes, 4080 bytes reported available, 4 bytes returned +Requested 12 bytes, 5100 bytes reported available, 12 bytes returned +Requested 4 bytes, 6561 bytes reported available, 4 bytes returned +Requested 12 bytes, 6557 bytes reported available, 12 bytes returned +Requested 4 bytes, 6545 bytes reported available, 4 bytes returned +Requested 12 bytes, 6541 bytes reported available, 12 bytes returned +Requested 4 bytes, 6529 bytes reported available, 4 bytes returned +Requested 12 bytes, 6525 bytes reported available, 12 bytes returned +Requested 261 bytes, 6513 bytes reported available, 261 bytes returned +Requested 12 bytes, 6252 bytes reported available, 12 bytes returned +Requested 6240 bytes, 6240 bytes reported available, 6240 bytes returned +Requested 1 bytes, 1024 bytes reported available, 1 bytes returned +Requested 15 bytes, 2047 bytes reported available, 15 bytes returned +Requested 4 bytes, 4080 bytes reported available, 4 bytes returned +Requested 12 bytes, 5100 bytes reported available, 12 bytes returned +Requested 4 bytes, 6561 bytes reported available, 4 bytes returned +Requested 12 bytes, 6557 bytes reported available, 12 bytes returned +Requested 4 bytes, 6545 bytes reported available, 4 bytes returned +Requested 12 bytes, 6541 bytes reported available, 12 bytes returned +Requested 4 bytes, 6529 bytes reported available, 4 bytes returned +Requested 12 bytes, 6525 bytes reported available, 12 bytes returned +Requested 261 bytes, 6513 bytes reported available, 261 bytes returned +Requested 12 bytes, 6252 bytes reported available, 12 bytes returned +Requested 6240 bytes, 6240 bytes reported available, 6240 bytes returned +Requested 1 bytes, 1024 bytes reported available, 1 bytes returned +Requested 15 bytes, 2047 bytes reported available, 15 bytes returned +Requested 4 bytes, 3056 bytes reported available, 4 bytes returned +Requested 12 bytes, 3052 bytes reported available, 12 bytes returned +Requested 4 bytes, 6561 bytes reported available, 4 bytes returned +Requested 12 bytes, 6557 bytes reported available, 12 bytes returned +Requested 4 bytes, 6545 bytes reported available, 4 bytes returned +Requested 12 bytes, 6541 bytes reported available, 12 bytes returned +Requested 4 bytes, 6529 bytes reported available, 4 bytes returned +Requested 12 bytes, 6525 bytes reported available, 12 bytes returned +Requested 261 bytes, 6513 bytes reported available, 261 bytes returned +Requested 12 bytes, 6252 bytes reported available, 12 bytes returned +Requested 6240 bytes, 6240 bytes reported available, 6240 bytes returned +Requested 1 bytes, 512 bytes reported available, 1 bytes returned +Requested 15 bytes, 1535 bytes reported available, 15 bytes returned +Requested 4 bytes, 3568 bytes reported available, 4 bytes returned +Requested 12 bytes, 4588 bytes reported available, 12 bytes returned +Requested 4 bytes, 6561 bytes reported available, 4 bytes returned +Requested 12 bytes, 6557 bytes reported available, 12 bytes returned +Requested 4 bytes, 6545 bytes reported available, 4 bytes returned +Requested 12 bytes, 6541 bytes reported available, 12 bytes returned +Requested 4 bytes, 6529 bytes reported available, 4 bytes returned +Requested 12 bytes, 6525 bytes reported available, 12 bytes returned +Requested 261 bytes, 6513 bytes reported available, 261 bytes returned +Requested 12 bytes, 6252 bytes reported available, 12 bytes returned +Requested 6240 bytes, 6240 bytes reported available, 6240 bytes returned +Requested 1 bytes, 1024 bytes reported available, 1 bytes returned +Requested 15 bytes, 2047 bytes reported available, 15 bytes returned +Requested 4 bytes, 4080 bytes reported available, 4 bytes returned +Requested 12 bytes, 5100 bytes reported available, 12 bytes returned +Requested 4 bytes, 7136 bytes reported available, 4 bytes returned +Requested 12 bytes, 8156 bytes reported available, 12 bytes returned +Requested 4 bytes, 10192 bytes reported available, 4 bytes returned +Requested 12 bytes, 11212 bytes reported available, 12 bytes returned +Requested 4 bytes, 13248 bytes reported available, 4 bytes returned +Requested 12 bytes, 14268 bytes reported available, 12 bytes returned +Requested 4 bytes, 16304 bytes reported available, 4 bytes returned +Requested 12 bytes, 16300 bytes reported available, 12 bytes returned +Requested 4 bytes, 16288 bytes reported available, 4 bytes returned +Requested 12 bytes, 19868 bytes reported available, 12 bytes returned +Requested 4 bytes, 21392 bytes reported available, 4 bytes returned +Requested 12 bytes, 22412 bytes reported available, 12 bytes returned +Requested 3654 bytes, 24448 bytes reported available, 1920 bytes returned + Error: rrMoreFlag = 22528, rrPushFlag = 0, rrUrgentFlag = 0 +Requested 3654 bytes, 36484 bytes reported available, 3654 bytes returned +Requested 12 bytes, 54334 bytes reported available, 12 bytes returned diff --git a/outlog.mac b/outlog.mac new file mode 100644 index 0000000..e021ce9 --- /dev/null +++ b/outlog.mac @@ -0,0 +1,19 @@ +Requested 12 bytes, 12 bytes reported available, 12 bytes returned +Requested 4 bytes, 4 bytes reported available, 4 bytes returned +Requested 2 bytes, 24 bytes reported available, 2 bytes returned +Requested 2 bytes, 25 bytes reported available, 2 bytes returned +Requested 16 bytes, 23 bytes reported available, 16 bytes returned +Requested 4 bytes, 7 bytes reported available, 4 bytes returned +Requested 3 bytes, 3 bytes reported available, 3 bytes returned +Requested 1 bytes, 416 bytes reported available, 1 bytes returned +Requested 15 bytes, 1215 bytes reported available, 15 bytes returned +Requested 118400 bytes, 118536 bytes reported available, 92000 bytes returned + Error: rrMoreFlag = 26536, rrPushFlag = 0, rrUrgentFlag = 0 +Requested 118400 bytes, 119792 bytes reported available, 116192 bytes returned + Error: rrMoreFlag = 3600, rrPushFlag = 0, rrUrgentFlag = 0 +Requested 118400 bytes, 119136 bytes reported available, 114736 bytes returned + Error: rrMoreFlag = 4400, rrPushFlag = 0, rrUrgentFlag = 0 +Requested 118400 bytes, 118992 bytes reported available, 114592 bytes returned + Error: rrMoreFlag = 4400, rrPushFlag = 0, rrUrgentFlag = 0 +Requested 118400 bytes, 119312 bytes reported available, 115088 bytes returned + Error: rrMoreFlag = 4224, rrPushFlag = 0, rrUrgentFlag = 0 diff --git a/outlog.win b/outlog.win new file mode 100644 index 0000000..ac7700f --- /dev/null +++ b/outlog.win @@ -0,0 +1,14 @@ +Requested 12 bytes, 12 bytes reported available, 12 bytes returned +Requested 4 bytes, 4 bytes reported available, 4 bytes returned +Requested 16 bytes, 16 bytes reported available, 16 bytes returned +Requested 4 bytes, 4 bytes reported available, 4 bytes returned +Requested 2 bytes, 24 bytes reported available, 2 bytes returned +Requested 2 bytes, 30 bytes reported available, 2 bytes returned +Requested 16 bytes, 28 bytes reported available, 16 bytes returned +Requested 4 bytes, 12 bytes reported available, 4 bytes returned +Requested 8 bytes, 8 bytes reported available, 8 bytes returned +Requested 1 bytes, 540 bytes reported available, 1 bytes returned +Requested 15 bytes, 1611 bytes reported available, 3 bytes returned + Error: rrMoreFlag = 1608, rrPushFlag = 0, rrUrgentFlag = 0 +Requested 15 bytes, 35984 bytes reported available, 15 bytes returned +Requested 1 bytes, 40257 bytes reported available, 1 bytes returned diff --git a/test.cc b/test.cc new file mode 100644 index 0000000..1d4cbcd --- /dev/null +++ b/test.cc @@ -0,0 +1,351 @@ +/******************************************************************** +* vncview.cc - main program code for VNCview GS +********************************************************************/ + +#if __ORCAC__ +#pragma lint -1 +#endif + +#if DEBUG +/* #pragma debug 25 */ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 */ + } diff --git a/vncdisplay.cc b/vncdisplay.cc new file mode 100644 index 0000000..a047fec --- /dev/null +++ b/vncdisplay.cc @@ -0,0 +1,1030 @@ +#include +#include +#include +#include +#include +#include "vncsession.h" +#include "vncview.h" +#include "vncdisplay.h" +#include "colortables.h" +#include "menus.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned int fbHeight; +unsigned int fbWidth; + +BOOLEAN displayInProgress; +unsigned int drawingLine; /* Line to be drawn while displaying */ + +unsigned int numRects; +unsigned int rectX; +unsigned int rectY; +unsigned int rectWidth; +unsigned int rectHeight; +unsigned long rectEncoding; + +unsigned int hexXTiles, hexYTiles; /* For in-process hextile processing */ +unsigned int hexXTileNum, hexYTileNum; +unsigned int hexTileWidth, hexTileHeight; +unsigned char hexBackground, hexForeground; + +BOOLEAN extraByteAdvance; + +#define encodingRaw 0 +#define encodingCopyRect 1 +#define encodingRRE 2 +#define encodingCoRRE 4 +#define encodingHextile 5 +#define encodingZRLE 16 +#define encodingCursor 0xffffff11 +#define encodingDesktopSize 0xffffff21 + +/* Used in Hextile encoding */ +#define Raw 0x01 +#define BackgroundSpecified 0x02 +#define ForegroundSpecified 0x04 +#define AnySubrects 0x08 +#define SubrectsColoured 0x10 + +#define hexWaitingForSubencoding 1 +#define hexWaitingForBackground 2 +#define hexWaitingForForeground 3 +#define hexWaitingForAnySubrects 4 +#define hexWaitingForSubrect 5 +#define hexWaitingForRawData 6 + +GrafPortPtr vncWindow; + +/* Data on state of raw rectangle drawing routines */ +unsigned long n; +/* On the next 2 structs, only certain values are permanently zero. + * Others are changed later. + */ +static struct LocInfo srcLocInfo = {0, 0, 0, {0, 0, 0, 0} }; +static Rect srcRect = {0, 0, 0, 0}; +unsigned char *destPtr; +unsigned char *pixTransTbl; + +#define txtColor 10 +#define txtGray 11 +#define txtTransfers 23 + +/* Send a request to be sent the data to redraw the window when part of it has + * been erased. It will be a while before the data is fully redrawn, but this + * is an unavoidable penalty of opening other windows over the main VNC window. + */ +#pragma databank 1 +void VNCRedraw (void) { + RegionHndl updateRgnHndl; + + updateRgnHndl = vncWindow->visRgn; + + SendFBUpdateRequest(FALSE, + (**updateRgnHndl).rgnBBox.h1, + (**updateRgnHndl).rgnBBox.v1, + (**updateRgnHndl).rgnBBox.h2 - (**updateRgnHndl).rgnBBox.h1, + (**updateRgnHndl).rgnBBox.v2 - (**updateRgnHndl).rgnBBox.v1); + } +#pragma databank 0 + +/* Change Super Hi-Res display to the specified resolution (640 or 320). + * Uses the procedure described in IIgs Tech Note #4. + */ +void ChangeResolution(int rez) { + static Handle dpSpace; + unsigned int masterSCB; + + /* Set up pixel translation table for correct graphics mode */ + if (hRez == 320) + pixTransTbl = coltab320; + else /* 640 mode */ + pixTransTbl = coltab640; + + /* Check if we need to change modes */ + masterSCB = GetMasterSCB(); + if ( ( (masterSCB & 0x80) && (rez == 640)) || + (!(masterSCB & 0x80) && (rez == 320)) ) { + return; /* Already in right mode, so don't change things */ + } + + /* Perform the basic procedure described in IIgs TN #4 */ + CloseAllNDAs(); + QDAuxShutDown(); + QDShutDown(); + if (dpSpace == NULL) + dpSpace = NewHandle(0x0300, userid(), + attrLocked|attrFixed|attrNoCross|attrBank, 0x00000000); + QDStartUp((Word) *dpSpace, (rez == 640) ? 0x87 : 0x00, 0, userid()); + /* SCB 0x87 gives 640 mode with our custom gray palette */ + GrafOff(); + QDAuxStartUp(); + ClampMouse(0, (rez == 640) ? 639 : 319, 0, 199); + HomeMouse(); + ShowCursor(); + WindNewRes(); + InitPalette(); /* Set up Apple menu colors before it is redrawn */ + MenuNewRes(); + CtlNewRes(); + RefreshDesktop(NULL); + GrafOn(); + + /* Position new connection window at default location for new mode */ + if (hRez == 320) { + MoveControl(25, 64, GetCtlHandleFromID(newConnWindow, txtColor)); + MoveControl(25, 87, GetCtlHandleFromID(newConnWindow, txtGray)); + MoveControl(134, 91, GetCtlHandleFromID(newConnWindow, txtTransfers)); + MoveWindow(2, 42, newConnWindow); + } + else { + MoveControl(35, 64, GetCtlHandleFromID(newConnWindow, txtColor)); + MoveControl(35, 87, GetCtlHandleFromID(newConnWindow, txtGray)); + MoveControl(144, 91, GetCtlHandleFromID(newConnWindow, txtTransfers)); + MoveWindow(162, 42, newConnWindow); + } + } + +/* Display the VNC session window, first changing to the appropriate + * resolution (as specified by the user) if necessary. + */ +void InitVNCWindow(void) { +#define wrNum640 1003 +#define wrNum320 1004 + + ChangeResolution(hRez); + vncWindow = NewWindow2(NULL, 0, VNCRedraw, NULL, 0x02, + (hRez == 640) ? wrNum640 : wrNum320, + rWindParam1); + + SetDataSize(fbWidth, fbHeight, vncWindow); + DrawControls(vncWindow); + + /* We also take the opportunity here to initialize the rectangle info. */ + numRects = 0; + +#undef wrNum320 +#undef wrNum640 + } + +/* Send a request to the VNC server to update the information for a portion of + * the frame buffer. + */ +void SendFBUpdateRequest (BOOLEAN incremental, unsigned int x, unsigned int y, + unsigned int width, unsigned int height) { + + struct FBUpdateRequest { + unsigned char messageType; + unsigned char incremental; + unsigned int x; + unsigned int y; + unsigned int width; + unsigned int height; + } fbUpdateRequest = {3 /* Message type 3 */}; + + fbUpdateRequest.incremental = !!incremental; + fbUpdateRequest.x = SwapBytes2(x); + fbUpdateRequest.y = SwapBytes2(y); + fbUpdateRequest.width = SwapBytes2(width); + fbUpdateRequest.height = SwapBytes2(height); + + TCPIPWriteTCP(hostIpid, &fbUpdateRequest.messageType, + sizeof(fbUpdateRequest), TRUE, FALSE); + /* No error checking here -- Can't respond to one usefully. */ + } + +/* 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. */ +} + +/* Start responding to a FramebufferUpdate from the server + */ +void DoFBUpdate (void) { + unsigned int *dataPtr; /* Pointer to header data */ + + if (!DoWaitingReadTCP(15)) { + DoClose(vncWindow); + //printf("Closing in DoFBUpdate\n"); + return; + } + HLock(readBufferHndl); + dataPtr = (unsigned int *) (((char *) (*readBufferHndl)) + 1); + numRects = SwapBytes2(dataPtr[0]); /* Get data */ + rectX = SwapBytes2(dataPtr[1]); + rectY = SwapBytes2(dataPtr[2]); + rectWidth = SwapBytes2(dataPtr[3]); + rectHeight = SwapBytes2(dataPtr[4]); + rectEncoding = SwapBytes4(*(unsigned long *)(dataPtr + 5)); + HUnlock(readBufferHndl); + //printf("New Rect: X = %u, Y = %u, Width = %u, Height = %u\n", rectX, rectY, rectWidth, rectHeight); + } + +/* The server should never send a color map, since we don't use a mapped + * representation for pixel values. If a malfunctioning server tries to + * send us one, though, we read and ignore it. This procedure could lock + * up the system for several seconds or longer while reading data, which + * would be bad but for the fact that it will never be called if the server + * is actually working correctly. + */ +void DoSetColourMapEntries (void) { + unsigned int numColors; + + DoWaitingReadTCP(3); + DoWaitingReadTCP(2); + HLock(readBufferHndl); + numColors = SwapBytes2((unsigned int) **readBufferHndl); + HUnlock(readBufferHndl); + for (; numColors > 0; numColors--) { + DoWaitingReadTCP(6); + } + } + +/* 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 to be fixed */ + PutScrap(textLen, textScrap, (Pointer) *readBufferHndl); + /* Potential errors (e.g. out of memory) ignored */ + HUnlock(readBufferHndl); + } + } + +/* Send a DoPointerEvent reflecting the status of the mouse to the server */ +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) + 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. + */ +} + +/* Here when we're done processing one rectangle and ready to start the next. + * If last FramebufferUpdate had multiple rectangles, we set up for next one. + * If no more rectangles are available, we send a FramebufferUpdateRequest. + */ +void NextRect (void) { + unsigned int *dataPtr; + + numRects--; + if (numRects) { /* Process next rectangle */ + if (!DoWaitingReadTCP(12)) { + //printf("Closing in NextRect\n"); + DoClose(vncWindow); + return; + } + HLock(readBufferHndl); + dataPtr = (unsigned int *) ((char *) (*readBufferHndl)); + rectX = SwapBytes2(dataPtr[0]); + rectY = SwapBytes2(dataPtr[1]); + rectWidth = SwapBytes2(dataPtr[2]); + rectHeight = SwapBytes2(dataPtr[3]); + rectEncoding = SwapBytes4(*(unsigned long *)(dataPtr + 4)); + HUnlock(readBufferHndl); + //printf("New Rect: X = %u, Y = %u, Width = %u, Height = %u\n", rectX, rectY, rectWidth, rectHeight); + } + else { /* No more rectangles from last update */ + unsigned long contentOrigin; + Point * contentOriginPtr = (void *) &contentOrigin; + + contentOrigin = GetContentOrigin(vncWindow); + SendFBUpdateRequest(TRUE, contentOriginPtr->h, contentOriginPtr->v, + (hRez == 640) ? 614 : 302, 174); + } + } + +/* Draw one or more lines from a raw rectangle + */ +void RawDraw (void) { + unsigned int i; /* Loop indices */ + unsigned char *dataPtr; + + /* For use with GetContentOrigin() */ + unsigned long contentOrigin; + Point * contentOriginPtr = (void *) &contentOrigin; + + + SetPort(vncWindow); /* Drawing in VNC window */ + dataPtr = (unsigned char *) *readBufferHndl; + + for (i = 0; i < rectWidth; i++) { + if (hRez == 640) { + switch (i & 0x03) { + case 0x00: /* pixels 0, 4, 8, ... */ + *(destPtr + n) = pixTransTbl[ *(dataPtr + + (unsigned long) drawingLine*rectWidth + i) + ] & 0xC0; + break; + case 0x01: /* pixels 1, 5, 9, ... */ + *(destPtr + n) += pixTransTbl[ *(dataPtr + + (unsigned long) drawingLine*rectWidth + i) + ] & 0x30; + break; + case 0x02: /* pixels 2, 6, 10, ... */ + *(destPtr + n) += pixTransTbl[ *(dataPtr + + (unsigned long) drawingLine*rectWidth + i) + ] & 0x0C; + break; + case 0x03: /* pixels 3, 7, 11, ... */ + *(destPtr + n) += pixTransTbl[ *(dataPtr + + (unsigned long) drawingLine*rectWidth + i) + ] & 0x03; + n++; + } + } + else { /* 320 mode */ + switch(i & 0x01) { + case 0x00: /* pixels 0, 2, 4, ... */ + *(destPtr + n) = pixTransTbl[ *(dataPtr + + (unsigned long) drawingLine*rectWidth + i) + ] & 0xF0; + break; + case 0x01: /* pixels 1, 3, 5, ... */ + *(destPtr + n) += pixTransTbl[ *(dataPtr + + (unsigned long) drawingLine*rectWidth + i) + ] & 0x0F; + n++; + } + } + } + + /* When not ending a line on a byte boundary, the index isn't updated, + * so we do it here. + */ + if (extraByteAdvance) + n++; + srcRect.v1 = drawingLine; + srcRect.v2 = drawingLine + 1; + contentOrigin = GetContentOrigin(vncWindow); + PPToPort(&srcLocInfo, &srcRect, rectX - contentOriginPtr->h, + rectY + drawingLine - contentOriginPtr->v, modeCopy); + + //printf("Painted at x = %u, y = %u\n", rectX-contentOriginPtr->h, rectY + drawingLine - contentOriginPtr->v); + + /* Check whether we're done with this rectangle */ + if (drawingLine < rectHeight - 1) { + drawingLine++; + return; + } + + /* We only get here when we're completely done with the rectangle, + * so we can clean up stuff that we don't need anymore and prepare for + * the next one. + */ + + HUnlock(readBufferHndl); + free(destPtr); + + displayInProgress = FALSE; + + NextRect(); /* Prepare for next rect */ +} + +/* Process rectangle data in raw encoding and write it to screen. + */ +void DoRawRect (void) { + unsigned long bufferLength; + unsigned int lineBytes; /* Number of bytes in a line of GS pixels */ + + /* Try to read data */ + if (! DoReadTCP ((unsigned long) rectWidth*rectHeight)) + 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 = malloc(bufferLength); + if (!destPtr) { /* Couldn't allocate memory */ + DoClose(vncWindow); + return; + } + memset(destPtr, 0, bufferLength); + n = 0; + + srcLocInfo.portSCB = (hRez == 640) ? 0x87 : 0x00; + srcLocInfo.ptrToPixImage = destPtr; + srcLocInfo.width = lineBytes; + srcLocInfo.boundsRect.v2 = rectHeight; + /* Since the lines are rounded up to integral numbers of byter, 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; + + displayInProgress = TRUE; + drawingLine = 0; /* Drawing first line of rect */ + HLock(readBufferHndl); /* Lock handle just once for efficiency */ + } + +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 */ + } + +void HexNextTile (void) { + hexXTileNum++; + if (hexXTileNum == hexXTiles) { + hexYTileNum++; + if (hexYTileNum == hexYTiles) { /* Done with this Hextile rect */ + displayInProgress = FALSE; + NextRect(); + return; + } + hexXTileNum = 0; + } + + hexTileWidth = (hexYTileNum == hexXTiles - 1) ? + rectWidth - 16 * (hexXTiles - 1) : 16; + hexTileHeight = (hexYTileNum == hexYTiles - 1) ? + rectHeight - 16 * (hexYTiles - 1) : 16; + } + +/* The macro below is used in HexDispatch() */ +#define HexDispatch_NextTile() do { \ + /* Draw the tile */ \ + srcRect.v2 = hexTileHeight; \ + srcRect.h2 = hexTileWidth; \ + srcLocInfo.ptrToPixImage = (void *) pixels; \ + \ + contentOrigin = GetContentOrigin(vncWindow); \ + \ + /*PPToPort(&srcLocInfo, &srcRect, \ + rectX + hexXTileNum * 16 - contentOriginPtr->h, \ + rectY + hexYTileNum * 16 - contentOriginPtr->v, modeCopy); \ + */ \ + HexNextTile(); \ + /* Set up for next time */ \ + status = hexWaitingForSubencoding; \ + bytesNeeded = 1; \ + return; \ + } while (0) + +#define HexDispatch_DrawBackground() do { \ + SetSolidPenPat(/*hexBackground*/0xaaaa); \ + contentOrigin = GetContentOrigin(vncWindow); \ + drawingRect.h1 = rectX + hexXTileNum * 16 - contentOriginPtr->h; \ + drawingRect.v1 = rectY + hexYTileNum * 16 - contentOriginPtr->v; \ + drawingRect.h2 = rectX + hexXTileNum * 16 - contentOriginPtr->h + hexTileWidth; \ + drawingRect.v2 = rectY + hexYTileNum * 16 - contentOriginPtr->v + hexTileHeight; \ + PaintRect(&drawingRect); \ + /* This paints more pixels than necessary for small tiles \ + * but that causes no harm and may be more efficient than \ + * doing the multipication every time. \ + */ \ + /*tileBytes = (hRez == 320) ? 128 : 64; \ + for (i = 0; i < tileBytes; i++) \ + pixels[0][i] = hexBackground; */ \ + } while (0); + + +void HexDispatch (void) { + static unsigned char status = hexWaitingForSubencoding; + static unsigned long bytesNeeded = 1; + static char subencoding; + static unsigned int numSubrects; + static unsigned char pixels[8][16]; + int i; + /* For use with GetContentOrigin() */ + unsigned long contentOrigin; + Point * contentOriginPtr = (void *) &contentOrigin; + int tileBytes; + unsigned int srX, srY, srWidth, srHeight; + Rect drawingRect; + + /* If we don't have the next bit of needed data yet, return. */ + while (DoReadTCP(bytesNeeded)) { + HLock(readBufferHndl); + /* If we're here, readBufferHndl contains bytesNeeded bytes of data. */ + switch (status) { + case hexWaitingForSubencoding: + subencoding = **(unsigned char **)readBufferHndl; + if (subencoding & Raw) { + bytesNeeded = hexTileWidth * hexTileHeight; + status = hexWaitingForRawData; + } + else { + if (subencoding & BackgroundSpecified) { + bytesNeeded = 1; + status = hexWaitingForBackground; + } + else { + HexDispatch_DrawBackground(); + if (subencoding & ForegroundSpecified) { + bytesNeeded = 1; + status = hexWaitingForForeground; + } + else if (subencoding & AnySubrects) { + bytesNeeded = 1; + status = hexWaitingForAnySubrects; + } + else + HexDispatch_NextTile(); + } + } + break; + case hexWaitingForRawData: + /* FIXME - Draw raw data */ + HexDispatch_NextTile(); + break; + case hexWaitingForBackground: + hexBackground = pixTransTbl[**(unsigned char **)readBufferHndl]; + HexDispatch_DrawBackground(); + if (subencoding & ForegroundSpecified) { + bytesNeeded = 1; + status = hexWaitingForForeground; + } + else if (subencoding & AnySubrects) { + bytesNeeded = 1; + status = hexWaitingForAnySubrects; + } + else + HexDispatch_NextTile(); + break; + case hexWaitingForForeground: + hexForeground = pixTransTbl[**(unsigned char **)readBufferHndl]; + if (subencoding & AnySubrects) { + bytesNeeded = 1; + status = hexWaitingForAnySubrects; + } + else + HexDispatch_NextTile(); + break; + case hexWaitingForAnySubrects: + numSubrects = **(unsigned char **) readBufferHndl; + if (numSubrects) { + status = hexWaitingForSubrect; + bytesNeeded = (subencoding & SubrectsColoured) ? 3 : 2; + } + else + HexDispatch_NextTile(); + break; + case hexWaitingForSubrect: + if (subencoding & SubrectsColoured) { + hexForeground = pixTransTbl[**(unsigned char **)readBufferHndl]; + } + srX = (**(unsigned char **) readBufferHndl) >> 4; + srY = (**(unsigned char **) readBufferHndl) & 0x0F; + srWidth = (*(*(unsigned char **) readBufferHndl + 1)) >> 4 + 1; + srHeight = (*(*(unsigned char **) readBufferHndl + 1)) & 0x04 + 1; + numSubrects--; + if (numSubrects) { + bytesNeeded = (subencoding & SubrectsColoured) ? 3 : 2; + } + else + 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 */ + srcLocInfo.portSCB = (hRez == 640) ? 0x87 : 0x00; + srcLocInfo.width = (hRez == 640) ? 4 : 8; + srcLocInfo.boundsRect.h2 = 16; + srcLocInfo.boundsRect.v2 = 16; + srcRect.v1 = 0; + srcRect.h1 = 0; + + } + +void ConnectedEventLoop (void) { + unsigned char messageType; +#define FBUpdate 0 +#define SetColourMapEntries 1 +#define Bell 2 +#define ServerCutText 3 + + if (FrontWindow() != vncWindow && menuOffset == noKB) + InitMenus(0); + else if (FrontWindow() == vncWindow && menuOffset != noKB) + InitMenus(noKB); + + if (displayInProgress) { + switch (rectEncoding) { + case encodingRaw: RawDraw(); + return; + case encodingHextile: HexDispatch(); + return; + default: DoClose(vncWindow); + return; + } + } + else if (numRects) { + switch (rectEncoding) { + case encodingHextile: + DoHextileRect(); + return; + case encodingRaw: DoRawRect(); + return; + case encodingCopyRect: + DoCopyRect(); + return; + default: DisplayConnectStatus ( + "\pInvalid rectangle from server.", FALSE); + DoClose(vncWindow); + //printf("Closing due to bad rectangle encoding %lu\n", rectEncoding); + //printf("rectX = %u, rectY = %u, rectWidth = %u, rectHeight = %u\n", rectX, rectY, rectWidth, rectHeight); + return; + } + } + else if (DoReadTCP(1)) { /* Read message type byte */ + HLock(readBufferHndl); + messageType = ((unsigned char) **readBufferHndl); + HUnlock(readBufferHndl); + switch (messageType) { + case FBUpdate: DoFBUpdate(); + break; + case SetColourMapEntries: DoSetColourMapEntries(); + break; + case Bell: SysBeep(); + break; + case ServerCutText: DoServerCutText(); + break; + default: DisplayConnectStatus ( + "\pInvalid message from server.", + FALSE); + DoClose(vncWindow); + //printf("Closing due to bad message from server\n"); + return; + } + } + } + +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); + } + } + +/* 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; +} diff --git a/vncdisplay.h b/vncdisplay.h new file mode 100644 index 0000000..2950413 --- /dev/null +++ b/vncdisplay.h @@ -0,0 +1,17 @@ +extern unsigned int fbHeight; +extern unsigned int fbWidth; + +extern GrafPortPtr vncWindow; + +void InitVNCWindow (void); + +void SendFBUpdateRequest (BOOLEAN /*incremental*/, unsigned int /*x*/, + unsigned int /*y*/, unsigned int /*width*/, unsigned int /*height*/); + +void ConnectedEventLoop (void); + +void DoSendClipboard (void); +void DoPointerEvent (void); + +void ProcessKeyEvent (void); +void SendModifiers (void); diff --git a/vnclog b/vnclog new file mode 100644 index 0000000..8033793 --- /dev/null +++ b/vnclog @@ -0,0 +1,70 @@ +here +here2 +Sent mouse update: x = 6656, y = 1024 + xPos = 1a00, yPos = 400, buttons = 0 +here +here2 +New Rect: X = 0, Y = 0, Width = 304, Height = 175 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here +here2 +here diff --git a/vncsession.cc b/vncsession.cc new file mode 100644 index 0000000..437a0da --- /dev/null +++ b/vncsession.cc @@ -0,0 +1,706 @@ +/********************************************************************* +* vncsession.cc - Routines for initiating/conducting a VNC session +* with the remote host +*********************************************************************/ + +#if __ORCAC__ +#pragma lint -1 +#pragma noroot +#endif + +#if DEBUG +/* #pragma debug 25 */ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vncview.h" +#include "vncsession.h" +#include "vncdisplay.h" +#include "menus.h" + +#define linServer 3 +#define linPassword 7 + +#define noCryptoError 2005 +#define authFailedError 2006 +#define authTooManyError 2007 +#define noTCPIPConnectionError 2011 +#define badGetIpidError 2012 +#define badOptionNegotiationError 2013 +#define badHandshakingError 2014 +#define badReadTCPError 2015 + +GrafPortPtr connectStatusWindowPtr = NULL; + +unsigned int hostIpid; +void ** readBufferHndl; /* Handle to the data read by the last + * DoReadTCP call. Copy this elsewhere if more + * data may be read while it is still in use. + */ +BOOLEAN readError; +BOOLEAN alerted = FALSE; + +#define buffTypePointer 0x0000 /* For TCPIPReadTCP() */ +#define buffTypeHandle 0x0001 +#define buffTypeNewHandle 0x0002 + +#define vncConnectionFailed SwapBytes4(0) +#define vncNoAuthentication SwapBytes4(1) +#define vncVNCAuthentication SwapBytes4(2) + +/*************************************************************** +* DoConnect - establish connection to server +***************************************************************/ + +void DoConnect (void) { + int i; /* loop counter */ + + /* Get server & password */ + + GetLETextByID(newConnWindow, linServer, (StringPtr) vncServer); + GetLETextByID(newConnWindow, linPassword, (StringPtr) vncPassword); + + /* Try to establish connection before continuing; if unsuccessful, stop */ + if (ConnectTCPIP() == FALSE) { + SysBeep(); + AlertWindow(awResource, NULL, noTCPIPConnectionError); + return; + } + + if (GetIpid() == FALSE) { + SysBeep(); + AlertWindow(awResource, NULL, badGetIpidError); + return; + } + + if (DoVNCHandshaking() == FALSE) { + SetHandleSize(1,readBufferHndl); + CloseConnectStatusWindow(); + InitCursor(); + SysBeep(); + if (alerted == FALSE) + AlertWindow(awResource, NULL, badHandshakingError); + else + alerted = FALSE; + return; + } + if (FinishVNCHandshaking() == FALSE) { + SetHandleSize(1,readBufferHndl); + CloseConnectStatusWindow(); + InitCursor(); + AlertWindow(awResource, NULL, badOptionNegotiationError); + SysBeep(); + return; + } + + InitVNCWindow(); + + CloseConnectStatusWindow(); + InitCursor(); + + DoClose(newConnWindow); + DisableMItem(fileNewConnection); + + myEvent.wmTaskMask = 0x001D79FE; /* don't let TaskMaster process keys */ + InitMenus(noKB); + vncConnected = TRUE; + } + +/******************************************************************* +* DisplayConnectStatus - Display modal dialog with status information +* statusString - P-String to display +* cancelMessage - determines whether to display string about OA-. +*******************************************************************/ + +void DisplayConnectStatus(char *statusString, BOOLEAN cancelMessage) { + #define wrNum 1002 + #define cancelStr 10002 + + GrafPortPtr oldPort; + Rect bigRect = {0,9,15,293}; + + if (connectStatusWindowPtr == NULL) { + connectStatusWindowPtr = NewWindow2(NULL, NULL, NULL, NULL, + 0x02, wrNum, rWindParam1); + } + + if (connectStatusWindowPtr != NULL) { /* Only draw if window was */ + if (GetMasterSCB() & 0x0080) /* If in 640 mode... */ + MoveWindow(169, 85, connectStatusWindowPtr); + else /* If in 320 mode... */ + MoveWindow(9, 85, connectStatusWindowPtr); + + oldPort = GetPort(); /* created successfully */ + SetPort(connectStatusWindowPtr); + EraseRect(&bigRect); /* Clipped to window's GrafPort */ + MoveTo(bigRect.h1, 13); + DrawStringWidth(0x6000, (Long) statusString, bigRect.h2 - bigRect.h1); + if (cancelMessage) { + MoveTo(bigRect.h1, 24); + DrawStringWidth(0x0002, cancelStr, bigRect.h2 - bigRect.h1); + } + SetPort(oldPort); + } + + #undef wrNum + #undef cancelStr + } + +/*********************************************************************** +* DisplayConnectStatusFromTool - Can be passed to Marinetti +***********************************************************************/ +#pragma databank 1 /* Set data bank register to access globals. */ +#pragma toolparms 1 /* Use tool-style stack model */ +void DisplayConnectStatusFromTool (char *statusString) { + DisplayConnectStatus(statusString, TRUE); + } +#pragma toolparms 0 /* Use ORCA stack model */ +#pragma databank 0 /* Must restore data bank register on exit */ + +/*********************************************************************** +* CloseConnectStatusWindow - Close connect status window (if open) +***********************************************************************/ +void CloseConnectStatusWindow (void) { + if (connectStatusWindowPtr != NULL) { + CloseWindow(connectStatusWindowPtr); + connectStatusWindowPtr = NULL; + } + } + +/*********************************************************************** +* ConnectTCPIP - Try to establish a TCP/IP connection through Marinetti +***********************************************************************/ +BOOLEAN ConnectTCPIP (void) +{ + BOOLEAN connected = FALSE; /* Are we connected to the network now? */ + + if (TCPIPGetConnectStatus() == FALSE) { /* If no TCP/IP connection... */ + WaitCursor(); + TCPIPConnect(&DisplayConnectStatusFromTool); + if (!toolerror()) + connected = TRUE; + CloseConnectStatusWindow(); + InitCursor(); + } + else /* Already connected */ + return TRUE; + + if (connected) + return TRUE; + return FALSE; +} + +/*********************************************************************** +* GetIpid() - parse the server name and attempt to get an ipid for it +***********************************************************************/ +BOOLEAN GetIpid (void) +{ + #define baseDisplayNum 5900 + + int i; + long hostPort; + cvtRec hostInfo; + static dnrBuffer dnrInfo; + unsigned long initialTime; + + /* Find ":" character that delimits name (or IP) from display number */ + for (i = vncServer[0]; isdigit(vncServer[i]) && i>0; i--); + + /* Set port to connect to */ + if (sscanf(&vncServer[i], ":%ld", &hostPort) == 0) + hostPort = 0; + hostPort += baseDisplayNum; + + /* Modify the string so it only contains the hostname or IP */ + if (vncServer[i] == ':') { + vncServer[0] = i - 1; + vncServer[i] = 0; + } + + /* If it's an IP address, then put it in the record */ + if (TCPIPValidateIPString(vncServer)) + TCPIPConvertIPToHex(&hostInfo, vncServer); + else { /* Do a DNS lookup */ + hostInfo.cvtPort = TCPIPMangleDomainName(0xF800, vncServer); + TCPIPDNRNameToIP(vncServer, &dnrInfo); + if (toolerror()) + return FALSE; + WaitCursor(); + DisplayConnectStatus("\pResolving domain name...", FALSE); + initialTime = TickCount(); + while (dnrInfo.DNRstatus == DNR_Pending) { + if (TickCount() >= initialTime + 15*60) + break; + TCPIPPoll(); /* Call TCPIPPoll() so that */ + } /* Marinetti can process data */ + CloseConnectStatusWindow(); + InitCursor(); + if (dnrInfo.DNRstatus == DNR_OK) + hostInfo.cvtIPAddress == dnrInfo.DNRIPaddress; + else + return FALSE; + } + + hostIpid = TCPIPLogin(userid(), hostInfo.cvtIPAddress, (int) hostPort, + 0x0010 /* minimize latency */, + 0x0040 /* Normal TTL*/); + if (toolerror()) + return FALSE; + + if (TCPIPOpenTCP(hostIpid) == tcperrOK) + if (!toolerror()) + return TRUE; + + return FALSE; + + #undef baseDisplayNum + } + + +/* Read data, waiting for up to 15 seconds for the data to be ready */ +BOOLEAN DoWaitingReadTCP(unsigned long dataLength) { + unsigned long stopTime; + BOOLEAN result = FALSE; + + stopTime = TickCount() + 15 * 60; + do { + result = DoReadTCP(dataLength); + } while (result == FALSE && TickCount() < stopTime); + + return result; + } + + +/* Fix things when TCPIPReadTCP returns less data than it's supposed to */ +BOOLEAN ReadFixup (unsigned long requested, unsigned long returned) { + static rrBuff theRRBuff; + + SetHandleSize(requested, readBufferHndl); + if (toolerror()) + return FALSE; + + do { + TCPIPPoll(); + if (TCPIPReadTCP(hostIpid, buffTypeNewHandle, NULL, + requested-returned, &theRRBuff) != tcperrOK) + return FALSE; + if (toolerror()) + return FALSE; + + if (theRRBuff.rrBuffCount == 0) /* To avoid infinite loops */ + return FALSE; + + HandToPtr(theRRBuff.rrBuffHandle, (char *)*readBufferHndl + returned, + theRRBuff.rrBuffCount); + + returned += theRRBuff.rrBuffCount; + + } while (returned < requested); + + return TRUE; + } + +/********************************************************************** +* DoReadTCP() - Issue TCPIPReadTCP() call w/ appropriate parameters +* Return value = did the read succeed? +**********************************************************************/ +BOOLEAN DoReadTCP (unsigned long dataLength) { + static srBuff theSRBuff; + static rrBuff theRRBuff; + + TCPIPPoll(); + + if (TCPIPStatusTCP(hostIpid, &theSRBuff) != tcperrOK) + return FALSE; + if (toolerror()) + return FALSE; + + if (theSRBuff.srRcvQueued < dataLength) + return FALSE; + + if (TCPIPReadTCP(hostIpid, buffTypeHandle, (Ref) readBufferHndl, + dataLength, &theRRBuff) != tcperrOK) + return FALSE; + if (toolerror()) + return FALSE; + + if (theRRBuff.rrBuffCount != dataLength) + return ReadFixup(dataLength, theRRBuff.rrBuffCount); + + return TRUE; + } + + +/********************************************************************** +* DoVNCHandshaking() - Establish connection to VNC server +**********************************************************************/ +BOOLEAN DoVNCHandshaking (void) { + #define connectionFailedAlert 2004 + #define badRFBVersionAlert 2008 + #define badAuthTypeAlert 2009 + static char versionString[12]; + unsigned long reasonLength; + char *errorString; + + WaitCursor(); + DisplayConnectStatus("\pConnecting to VNC server...", FALSE); + + /* Read RFB version string from the server */ + strcpy(versionString, ""); + if (! DoWaitingReadTCP(12)) + return FALSE; + HLock(readBufferHndl); + if ( ! ((strncmp((char *)*readBufferHndl, "RFB ", 4) == 0) && + (strncmp((char *)*readBufferHndl+4, RFBMAJORVERSIONSTR, 3) >= 0) && + (strncmp((char *)*readBufferHndl+7, ".", 1) == 0) && + (strncmp((char *)*readBufferHndl+11, "\n", 1) == 0))) { + HUnlock(readBufferHndl); + InitCursor(); + AlertWindow(awResource, NULL, badRFBVersionAlert); + alerted = TRUE; + return FALSE; + } + HUnlock(readBufferHndl); + + strcpy(versionString, RFBVERSIONSTR); + if (TCPIPWriteTCP(hostIpid, versionString, 12, TRUE, FALSE)) { + return FALSE; + } + if (toolerror()) { + return FALSE; + } + + if (! DoWaitingReadTCP(4)) { /* Read authentication type */ + return FALSE; + } + HLock(readBufferHndl); + switch ((unsigned long) (**readBufferHndl)) { + case vncConnectionFailed: HUnlock(readBufferHndl); + if (! DoWaitingReadTCP(4)) + return FALSE; + if (toolerror()) + return FALSE; + HLock(readBufferHndl); + reasonLength = SwapBytes4(**readBufferHndl); + HUnlock(readBufferHndl); + if (! DoWaitingReadTCP(reasonLength)) + return FALSE; + if (toolerror()) + return FALSE; + SetHandleSize( + GetHandleSize(readBufferHndl)+1, + readBufferHndl); + if (! toolerror()) { + HLock(readBufferHndl); + *((char *) *readBufferHndl+reasonLength) + = 0; + InitCursor(); + AlertWindow(awResource, + (Pointer) readBufferHndl, + connectionFailedAlert); + alerted = TRUE; + HUnlock(readBufferHndl); + } + return FALSE; + case vncNoAuthentication: break; + case vncVNCAuthentication: if (DoDES()) + break; + HUnlock(readBufferHndl); + return FALSE; + default: HUnlock(readBufferHndl); + AlertWindow(awResource, NULL, + badAuthTypeAlert); + alerted = TRUE; + return FALSE; + } + + HUnlock(readBufferHndl); + return TRUE; + #undef connectionFailedAlert + #undef badRFBVersionAlert + #undef badAuthTypeAlert + } + +/********************************************************************** +* DoDES() - Try to do DES (aka VNC) authentication +**********************************************************************/ +BOOLEAN DoDES (void) { + /* This reverses the order of the low 7 bits of a byte. */ + /* Uses the high bit (7) as scratch space. */ + #define SwitchBits(x) do { x &= 0x7f; /* Clear 7 */ \ + x ^= (x << 7) & 0x80; /* 0 -> 7 */ \ + x &= 0xfe; /* Clear 0 */ \ + x ^= (x >> 6) & 0x01; /* 6 -> 0 */ \ + x &= 0xbf; /* Clear 6 */ \ + x ^= (x >> 1) & 0x40; /* 7 -> 6 */ \ + x &= 0x7f; /* Clear 7 */ \ + x ^= (x << 6) & 0x80; /* 1 -> 7 */ \ + x &= 0xfd; /* Clear 1 */ \ + x ^= (x >> 4) & 0x02; /* 5 -> 1 */ \ + x &= 0xdf; /* Clear 5 */ \ + x ^= (x >> 2) & 0x20; /* 7 -> 5 */ \ + x &= 0x7f; /* Clear 7 */ \ + x ^= (x << 5) & 0x80; /* 2 -> 7 */ \ + x &= 0xfb; /* Clear 2 */ \ + x ^= (x >> 2) & 0x04; /* 4 -> 2 */ \ + x &= 0xef; /* Clear 4 */ \ + x ^= (x >> 3) & 0x10; /* 7 -> 4 */ \ + } while (0) + #define statusOK SwapBytes4(0) + #define statusFailed SwapBytes4(1) + #define statusTooMany SwapBytes4(2) + unsigned char theResponse[16]; + unsigned char theKey[8]; + BOOLEAN success; + BOOLEAN startedCrypto = FALSE; /* True if we started CryptoTool */ + Handle dpSpace; + int i; + + DisplayConnectStatus("\pAuthenticating...", FALSE); + + if (!(CryptoStatus() && !toolerror())) { /* if Crypto isn't started */ + startedCrypto = TRUE; + LoadOneTool(129, 0x100); /* load Crypto tool 1.0+ */ + if (toolerror()) { /* Check that it is available */ + AlertWindow(awResource, NULL, noCryptoError); + alerted = TRUE; + return FALSE; + } + + dpSpace = NewHandle(0x0100, userid(), + attrLocked|attrFixed|attrNoCross|attrBank, 0x00000000); + CryptoStartUp((Word) *dpSpace); + } + + if (! (DoWaitingReadTCP(16))) { + success = FALSE; + goto UnloadCrypto; + } + + /* Pad password with nulls, as per VNC precedent */ + for (i=vncPassword[0]+1; i<=8; i++) + vncPassword[i] = 0; + + /* Flip bits around to be in format expected by CryptoTool */ + for (i=1; i<9; i++) + SwitchBits(vncPassword[i]); + + /* Shift password to form 56-bit key */ + vncPassword[1] <<= 1; + vncPassword[1] += (vncPassword[2] & 0x7f) >> 6; + vncPassword[2] <<= 2; + vncPassword[2] += (vncPassword[3] & 0x7f) >> 5; + vncPassword[3] <<= 3; + vncPassword[3] += (vncPassword[4] & 0x7f) >> 4; + vncPassword[4] <<= 4; + vncPassword[4] += (vncPassword[5] & 0x7f) >> 3; + vncPassword[5] <<= 5; + vncPassword[5] += (vncPassword[6] & 0x7f) >> 2; + vncPassword[6] <<= 6; + vncPassword[6] += (vncPassword[7] & 0x7f) >> 1; + vncPassword[7] <<= 7; + vncPassword[7] += vncPassword[8] & 0x7f; + + DESAddParity(theKey, &vncPassword[1]); + + HLock(readBufferHndl); + DESCipher(theResponse, theKey, *(char **)readBufferHndl, modeEncrypt); + DESCipher(&theResponse[8], theKey, *(char **)readBufferHndl+8, modeEncrypt); + HUnlock(readBufferHndl); + + if (TCPIPWriteTCP(hostIpid, theResponse, sizeof(theResponse), TRUE, FALSE)) + { + success = FALSE; + goto UnloadCrypto; + } + if (toolerror()) { + success = FALSE; + goto UnloadCrypto; + } + if (! (DoWaitingReadTCP(4))) { + success = FALSE; + goto UnloadCrypto; + } + + HLock(readBufferHndl); + if ((**readBufferHndl) == statusOK) { + success = TRUE; + goto UnloadCrypto; + } + else if ((**readBufferHndl) == statusFailed) { + InitCursor(); + AlertWindow(awResource, NULL, authFailedError); + alerted = TRUE; + success = FALSE; + goto UnloadCrypto; + } + else if ((**readBufferHndl) == statusTooMany) { + InitCursor(); + AlertWindow(awResource, NULL, authTooManyError); + alerted = TRUE; + success = FALSE; + goto UnloadCrypto; + } + /* else */ + success = FALSE; + + UnloadCrypto: + + HUnlock(readBufferHndl); + + if (startedCrypto) { + CryptoShutDown(); /* Shut down Crypto tool set */ + DisposeHandle(dpSpace); + UnloadOneTool(129); + } + return success; + +#undef statusOK +#undef statusFailed +#undef statusTooMany +#undef SwitchBits + } + +/********************************************************************** +* FinishVNCHandshaking() - Complete VNC protocol initialization +**********************************************************************/ +BOOLEAN FinishVNCHandshaking (void) { +#define screenTooBigError 2010 + unsigned char sharedFlag; + unsigned long serverNameLen; + struct PixelFormat { + unsigned char messageType; + unsigned char padding1; + unsigned int padding2; + unsigned char bitsPerPixel; + unsigned char depth; + unsigned char bigEndianFlag; + unsigned char trueColorFlag; + unsigned int redMax; + unsigned int greenMax; + unsigned int blueMax; + unsigned char redShift; + unsigned char greenShift; + unsigned char blueShift; + unsigned char padding3; + unsigned int padding4; + } pixelFormat = { + 0 /* message type - SetPixelFormat */, + 0,0 /* padding */, + 8 /* bpp */, + 8 /* depth */, + 0 /* big endian flag - irrelevant */, + TRUE /* true color flag */, + SwapBytes2(7) /* red-max */, + SwapBytes2(7) /* green-max */, + SwapBytes2(3) /* blue-max */, + 0 /* red-shift */, + 3 /* green-shift */, + 6 /* blue-shift */, + 0,0 /* padding */ + }; + + struct Encodings { + unsigned char messageType; + unsigned char padding; + unsigned int numberOfEncodings; + unsigned long firstEncoding; + //unsigned long secondEncoding; + } encodings = { + 2, /* Message Type - SetEncodings */ + 0, /* padding */ + SwapBytes2(1), /* number of encodings */ + SwapBytes4(1) /* first encoding: CopyRect */ + //SwapBytes4(5) /* second encoding: Hextile */ + /* Per the spec, raw encoding is supported even though + * it is not listed here explicitly. + */ + }; + + DisplayConnectStatus("\pNegotiating protocol options...", FALSE); + + /* ClientInitialisation */ + sharedFlag = !!requestSharedSession; + if (TCPIPWriteTCP(hostIpid, &sharedFlag, sizeof(sharedFlag), TRUE, FALSE)) + return FALSE; + if (toolerror()) + return FALSE; + + /* ServerInitialisation */ + if (! DoWaitingReadTCP(2)) + return FALSE; + HLock(readBufferHndl); + fbWidth = SwapBytes2(**(unsigned **)readBufferHndl); + HUnlock(readBufferHndl); + if (! DoWaitingReadTCP(2)) + return FALSE; + HLock(readBufferHndl); + fbHeight = SwapBytes2(**(unsigned **)readBufferHndl); + HUnlock(readBufferHndl); + + if ((fbWidth > 16384) || (fbHeight > 16384)) { + AlertWindow(awResource, NULL, screenTooBigError); + return FALSE; + } + + /* Ignore server's pixel format and display name */ + if (! DoWaitingReadTCP(16)) + return FALSE; + if (! DoWaitingReadTCP(4)) + return FALSE; + HLock(readBufferHndl); + serverNameLen = SwapBytes4(**(unsigned long **)readBufferHndl); + HUnlock(readBufferHndl); + if (! DoWaitingReadTCP(serverNameLen)) + return FALSE; + + if (TCPIPWriteTCP(hostIpid, &pixelFormat.messageType, sizeof(pixelFormat), + TRUE, FALSE)) + return FALSE; + if (toolerror()) + return FALSE; + + if (TCPIPWriteTCP(hostIpid, &encodings.messageType, sizeof(encodings), + TRUE, FALSE)) + return FALSE; + if (toolerror()) + return FALSE; + + return TRUE; +#undef screenTooBigError + } + + +/********************************************************************** +* CloseTCPConnection() - Close the TCP connection to the host +**********************************************************************/ +void CloseTCPConnection (void) { + TCPIPCloseTCP(hostIpid); + WaitCursor(); + DisplayConnectStatus("\pClosing VNC session...", FALSE); + do { + TCPIPPoll(); + TCPIPLogout(hostIpid); + } while (toolerror() == terrSOCKETOPEN); + CloseConnectStatusWindow(); + InitCursor(); + } diff --git a/vncsession.h b/vncsession.h new file mode 100644 index 0000000..813a8d7 --- /dev/null +++ b/vncsession.h @@ -0,0 +1,36 @@ +/******************************************************************** +* vncsession.h - functions for establishing connection to VNC server +* and communicating with it +********************************************************************/ + +#include + +#define RFBVERSIONSTR "RFB 003.003\n" +#define RFBMAJORVERSIONSTR "003" + +#define SwapBytes2(x) (((unsigned int)x << 8) | ((unsigned int)x >> 8)) +#define SwapBytes4(x) (((unsigned long)x << 24) | \ + ((unsigned long)x >> 24) | \ + (((unsigned long)x & 0x0000FF00) << 8) | \ + (((unsigned long)x & 0x00FF0000) >> 8)) + +extern BOOLEAN readError; + +extern GrafPortPtr connectStatusWindowPtr; + +extern void ** readBufferHndl; + +extern unsigned int hostIpid; + +extern void DisplayConnectStatus(char *, BOOLEAN); + +extern void DoConnect (void); +extern BOOLEAN GetIpid (void); +extern BOOLEAN ConnectTCPIP (void); +extern BOOLEAN DoReadTCP (unsigned long); +extern BOOLEAN DoWaitingReadTCP(unsigned long); +extern void CloseTCPConnection (void); +extern BOOLEAN DoDES (void); +extern BOOLEAN DoVNCHandshaking(void); +extern BOOLEAN FinishVNCHandshaking(void); +extern void CloseConnectStatusWindow (void); diff --git a/vncview.cc b/vncview.cc new file mode 100644 index 0000000..166c42b --- /dev/null +++ b/vncview.cc @@ -0,0 +1,468 @@ +/******************************************************************** +* vncview.cc - main program code for VNCview GS +*******************************************************************/ + +#if __ORCAC__ +#pragma lint -1 +#endif + +#if DEBUG +/* #pragma debug 25 */ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vncview.h" +#include "VNCsession.h" +#include "vncdisplay.h" +#include "menus.h" + +#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 txtColor 10 +#define txtGray 11 +#define rad320 12 +#define rad640 13 +#define chkShared 16 +#define chkClipboard 17 +#define txtTransfers 23 +#define chkEmul3Btn 18 +#define chkViewOnly 19 + +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 */ +int menuOffset; /* Indicates which menu bar is active */ + +/* Connection options */ +int hRez = 320; +BOOLEAN requestSharedSession = TRUE; +BOOLEAN allowClipboardTransfers = TRUE; +BOOLEAN emulate3ButtonMouse = TRUE; +BOOLEAN viewOnlyMode = FALSE; +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) { + unsigned int masterSCB; + + masterSCB = GetMasterSCB(); + MakeThisCtlTarget(GetCtlHandleFromID(newConnWindow, linServer)); + ShowWindow(newConnWindow); + SelectWindow(newConnWindow); + } + +/*************************************************************** +* DoClose - Close the frontmost window/connection +* Parameters: +* wPtr - window to close +***************************************************************/ + +void DoClose (GrafPortPtr wPtr) { + if (wPtr == newConnWindow) { + HideWindow(wPtr); + } + else if (wPtr && vncConnected) { /* Close VNC session window */ + CloseWindow(wPtr); + CloseTCPConnection(); + vncConnected = FALSE; + EnableMItem(fileNewConnection); + InitMenus(0); + myEvent.wmTaskMask = 0x001F79FF; /* let TaskMaster handle keys again */ + }; + } + +/*************************************************************** +* 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 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; + case editShowClipboard: ShowClipboard(0x8000, 0); break; + case editSendClipboard: DoSendClipboard(); 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 txtColor: SetCtlValueByID(TRUE, newConnWindow, + rad320); + /* Fall through */ + case rad320: hRez = 320; /* "320x200" */ break; + case txtGray: SetCtlValueByID(TRUE, newConnWindow, + rad640); + /* Fall through */ + 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 txtTransfers: allowClipboardTransfers = !allowClipboardTransfers; + SetCtlValueByID(allowClipboardTransfers, + newConnWindow, chkClipboard); break; + }; + } + +/*************************************************************** +* InitMenus - Initialize the menu bar. +***************************************************************/ + +void InitMenus (int offset) { + #define menuID 1 /* menu bar resource ID */ + + int height; /* height of the largest menu */ + MenuBarRecHndl menuBarHand = 0; /* for 'handling' the menu bar */ + MenuBarRecHndl oldMenuBarHand; + /* create the menu bar */ + oldMenuBarHand = menuBarHand; + menuBarHand = NewMenuBar2(refIsResource, menuID+offset, NULL); + SetSysBar(menuBarHand); + SetMenuBar(NULL); + FixAppleMenu(1); /* add desk accessories */ + height = FixMenuBar(); /* draw the completed menu bar */ + DrawMenuBar(); + if (oldMenuBarHand) + DisposeHandle((Handle) oldMenuBarHand); + + menuOffset = offset; /* So we can tell which menu is active */ + + #undef menuID + } + +/*************************************************************** +* CheckMenus - Check the menus to see if they should be dimmed +***************************************************************/ + +void CheckMenus (void) { + GrafPortPtr activeWindow; /* Front visible window */ + static GrafPortPtr lastActiveWindow; + + activeWindow = FrontWindow(); + + /* Speed up common case (no change since last time) */ + if (activeWindow == lastActiveWindow) + return; + + lastActiveWindow = activeWindow; + + 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 if (activeWindow == vncWindow) { + DisableMItem(editUndo); + DisableMItem(editCopy); + DisableMItem(editCut); + DisableMItem(editPaste); + DisableMItem(editClear); + } + } + else { /* no editable window on top */ + DisableMItem(fileClose); + DisableMItem(editUndo); + DisableMItem(editCut); + DisableMItem(editCopy); + DisableMItem(editPaste); + DisableMItem(editClear); + }; + + if (vncConnected) { /* VNC connection present */ + DisableMItem(fileNewConnection); + EnableMItem(fileClose); + if (viewOnlyMode) + DisableMItem(editSendClipboard); + else + EnableMItem(editSendClipboard); + } + else { + DisableMItem(editSendClipboard); + } + } + +/* InitScreen - Set up color tables and SCBs to appropriate values + */ +void InitScreen (void) { + static ColorTable gray640Colors = { + 0x0000, 0x0555, 0x0AAA, 0x0FFF, 0x0000, 0x0555, 0x0AAA, 0x0FFF, + 0x0000, 0x0555, 0x0AAA, 0x0FFF, 0x0000, 0x0555, 0x0AAA, 0x0FFF + }; + + /* Apple menu uses color tables 1 through 6 */ + SetColorTable(7, &gray640Colors); + SetAllSCBs(0x87); /* 640 mode with gray640Colors */ + InitPalette(); /* Restore Apple Menu colors */ + } + +#if 0 +void SetupCursor (int rez) { + static struct { + Word cursorHeight; + Word cursorWidth; + Byte cursorImage[]; + Byte cursorMask[]; + Word hotSpotY; + Word hotSpotX; + } smallCursor = { + 6, 3, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00 + }, + 1, 1 + }; + + SetCursor((Pointer) smallCursor); + } +#endif + +/*************************************************************** +* 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) { + GrafOff(); + SysFailMgr(toolerror(), "\pCould not start tools: "); + } + LoadOneTool(54, 0x200); /* load Marinetti 2.0+ */ + if (toolerror()) { /* Check that Marinetti is available */ + SysBeep(); /* Can't load Marinetti.. */ + InitCursor(); /* Activate pointer cursor */ + AlertWindow(awResource, NULL, noMarinettiError); + done = TRUE; /* Can't proceed, so just quit */ + } + else /* Marinetti loaded successfully */ + TCPIPStartUp(); /* ... so activate it now */ + + readBufferHndl = NewHandle(1, userid(), 0, NULL); + if (toolerror()) { /* Get handle for TCPIP read buffer */ + done = TRUE; + SysBeep(); + InitCursor(); + AlertWindow(awResource, NULL, outOfMemoryError); + } + + InitScreen(); /* Set up color tables */ + + LoadScrap(); /* put scrap in memory */ + InitMenus(0); /* 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 = 0x001F79FF; /* let TaskMaster do everything needed */ + while (!done) { + CheckMenus(); + event = TaskMaster(everyEvent, &myEvent); + if (vncConnected) + SendModifiers(); + switch (event) { + case wInSpecial: + case wInMenuBar: HandleMenu(); + break; + case wInGoAway: DoClose((GrafPortPtr) myEvent.wmTaskData); + break; + case wInControl: HandleControl(); + break; + case wInContent: if (vncWindow && ((GrafPortPtr) + myEvent.wmTaskData == vncWindow)) + DoPointerEvent(); + break; + case nullEvt: if (vncConnected) DoPointerEvent(); + break; + case keyDownEvt: + case autoKeyEvt: ProcessKeyEvent(); + } + if (vncConnected) + ConnectedEventLoop(); + } + + /* Done with event loop - now quitting */ + if (vncConnected) /* Disconnect if still connected */ + CloseTCPConnection(); + + DisposeHandle(readBufferHndl); /* Get rid of TCPIP read buffer hndl */ + + /* Ask the user if we should disconnect only if the connection */ + /* is not "permanent," i.e. started when the system boots up. */ + if (TCPIPGetConnectStatus() && (!TCPIPGetBootConnectFlag())) + if (AlertWindow(awResource+awButtonLayout, NULL, disconnectTCPIPAlert)) + { + WaitCursor(); + /* Must use force flag below because Marinetti will still count + * our ipid as logged in (proventing non-forced disconnect) + * for several minutes after the TCPIPLogout call. */ + TCPIPDisconnect(TRUE, &DisplayConnectStatus); + if (connectStatusWindowPtr != NULL) + CloseWindow(connectStatusWindowPtr); + } + + UnloadScrap(); /* Save scrap to disk */ + + TCPIPShutDown(); /* Shut down Marinetti */ + UnloadOneTool(54); + ShutDownTools(1, startStopParm); /* shut down the tools */ + } diff --git a/vncview.h b/vncview.h new file mode 100644 index 0000000..b002633 --- /dev/null +++ b/vncview.h @@ -0,0 +1,30 @@ +/******************************************************************** +* vncview.h - functions not directly related to VNC session +********************************************************************/ + +#include + +extern GrafPortPtr newConnWindow; + +extern int menuOffset; + +/* Connection options */ +extern BOOLEAN color; +extern int hRez; +extern int vRez; +extern BOOLEAN requestSharedSession; +extern BOOLEAN allowClipboardTransfers; +extern BOOLEAN emulate3ButtonMouse; +extern BOOLEAN viewOnlyMode; +extern BOOLEAN localPointer; +extern unsigned long deleteKeysym; +extern char vncServer[257]; +extern char vncPassword[10]; + +extern EventRecord myEvent; /* Event Record for TaskMaster */ +extern BOOLEAN vncConnected; /* Is the GS desktop active */ + +extern void DoClose (GrafPortPtr wPtr); +extern void DrawContents (void); +extern void InitMenus (int); +/* extern void SetupCursor (int); */ diff --git a/vncview.rez b/vncview.rez new file mode 100644 index 0000000..7c20aff --- /dev/null +++ b/vncview.rez @@ -0,0 +1,930 @@ +/*--------------------------------------------------------------*/ +/* Main resources for VNCview GS */ +/*--------------------------------------------------------------*/ + +#include "types.rez" + +/*- Constants --------------------------------------------------*/ + +#define appleMenu 1 +#define fileMenu 2 +#define editMenu 3 +#define editUndo 250 +#define editCut 251 +#define editCopy 252 +#define editPaste 253 +#define editClear 254 +#define editSendClipboard 262 +#define editShowClipboard 261 +#define fileNewConnection 260 +#define fileClose 255 +#define fileQuit 256 +#define appleAbout 257 + +#define noKB 100 + +#define noMarinettiError 2001 +#define outOfMemoryError 2002 + +#define disconnectTCPIPAlert 2003 +#define connectionFailedAlert 2004 +#define noCryptoError 2005 +#define authFailedError 2006 +#define authTooManyError 2007 +#define badRFBVersionAlert 2008 +#define badAuthTypeAlert 2009 +#define screenTooBigError 2010 +#define noTCPIPConnectionError 2011 +#define badGetIpidError 2012 +#define badOptionNegotiationError 2013 +#define badHandshakingError 2014 +#define badReadTCPError 2015 + +#define linedColors 1 + +#define NCWindow 1000 /* Offset for "New Connection" */ + /* window and its controls */ + +#define VNCWindow 3000 + +#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 txtColor 10 +#define txtGray 11 +#define rad320 12 +#define rad640 13 +#define chkShared 16 +#define chkClipboard 17 +#define txtTransfers 23 +#define chkEmul3Btn 18 +#define chkViewOnly 19 + +/*- Tools ------------------------------------------------------*/ + +resource rToolStartup(1) { + mode640, + { + 3, $0302, /* Misc Tool */ + 4, $0307, /* QuickDraw II */ + 5, $0304, /* Desk Manager */ + 6, $0301, /* Event Manager */ +/* 8, $0303, /* Sound Tools */ + 11, $0300, /* Integer Math Tool Set */ + 14, $0303, /* Window Manager */ + 15, $0303, /* Menu Manager */ + 16, $0303, /* Control Manager */ + 18, $0304, /* QuickDraw II Auxiliary */ +/* 19, $0301, /* Print Manager */ + 20, $0303, /* LineEdit Tool Set */ + 21, $0304, /* Dialog Manager */ + 22, $0301, /* Scrap Manager */ +/* 23, $0303, /* SFO */ +/* 25, $0104, /* Note Synthesizer */ + 27, $0303, /* Font Manager */ + 28, $0303, /* List Manager */ +/* 34, $0103 /* TextEdit Tool Set */ + } + }; + +/*- Menu Bar ---------------------------------------------------*/ + +resource rMenuBar (1) { /* the menu bar */ + { + appleMenu, /* resource numbers for the menus */ + fileMenu, + editMenu + }; + }; + +resource rMenu (appleMenu) { /* the Apple menu */ + appleMenu, /* menu ID */ + refIsResource*menuTitleRefShift /* flags */ + + refIsResource*itemRefShift + + fAllowCache, + appleMenu, /* menu title resource ID */ + {appleAbout}; /* menu item resource IDs */ + }; + +resource rMenu (fileMenu) { /* the File menu */ + fileMenu, /* menu ID */ + refIsResource*menuTitleRefShift /* flags */ + + refIsResource*itemRefShift + + fAllowCache, + fileMenu, /* menu title resource ID */ + { /* menu item resource IDs */ + fileNewConnection, + fileClose, + fileQuit + }; + }; + +resource rMenu (editMenu) { /* the Edit menu */ + editMenu, /* menu ID */ + refIsResource*menuTitleRefShift /* flags */ + + refIsResource*itemRefShift + + fAllowCache, + editMenu, /* menu title resource ID */ + { /* menu item resource IDs */ + editUndo, + editCut, + editCopy, + editPaste, + editClear, + editShowClipboard, + editSendClipBoard + }; + }; + +resource rMenuItem (editUndo) { /* Undo menu item */ + editUndo, /* menu item ID */ + "Z","z", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift /* flags */ + + fDivider, + editUndo /* menu item title resource ID */ + }; + +resource rMenuItem (editCut) { /* Cut menu item */ + editCut, /* menu item ID */ + "X","x", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift, /* flags */ + editCut /* menu item title resource ID */ + }; + +resource rMenuItem (editCopy) { /* Copy menu item */ + editCopy, /* menu item ID */ + "C","c", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift, /* flags */ + editCopy /* menu item title resource ID */ + }; + +resource rMenuItem (editPaste) { /* Paste menu item */ + editPaste, /* menu item ID */ + "V","v", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift, /* flags */ + editPaste /* menu item title resource ID */ + }; + +resource rMenuItem (editClear) { /* Clear menu item */ + editClear, /* menu item ID */ + "","", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift /* flags */ + + fDivider, + editClear /* menu item title resource ID */ + }; + +resource rMenuItem (editShowClipboard) { + editShowClipboard, + "","", + 0, + refIsResource*itemTitleRefShift, + editShowClipboard + }; + +resource rMenuItem (editSendClipboard) { + editSendClipboard, + "","", + 0, + refIsResource*itemTitleRefShift, + editSendClipboard + }; + +resource rMenuItem (fileNewConnection) { /* New menu item */ + fileNewConnection, /* menu item ID */ + "N","n", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift, /* flags */ + fileNewConnection /* menu item title resource ID */ + }; + +resource rMenuItem (fileClose) { /* Close menu item */ + fileClose, /* menu item ID */ + "W","w", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift /* flags */ + + fDivider, + fileClose /* menu item title resource ID */ + }; + +resource rMenuItem (fileQuit) { /* Quit menu item */ + fileQuit, /* menu item ID */ + "Q","q", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift, /* flags */ + fileQuit /* menu item title resource ID */ + }; + +resource rMenuItem (appleAbout) { /* About menu item */ + appleAbout, /* menu item ID */ + "","", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift /* flags */ + + fDivider, + appleAbout /* menu item title resource ID */ + }; + + /* the various strings */ +resource rPString (appleMenu, noCrossBank) {"@"}; +resource rPString (fileMenu, noCrossBank) {" File "}; +resource rPString (editMenu, noCrossBank) {" Edit "}; +resource rPString (editUndo, noCrossBank) {"Undo"}; +resource rPString (editCut, noCrossBank) {"Cut"}; +resource rPString (editCopy, noCrossBank) {"Copy"}; +resource rPString (editPaste, noCrossBank) {"Paste"}; +resource rPString (editClear, noCrossBank) {"Clear"}; +resource rPString (editShowClipboard, noCrossBank) + {"Show Clipboard"}; +resource rPString (editSendClipboard, noCrossBank) + {"Send Clipboard"}; +resource rPString (fileNewConnection, noCrossBank) + {"New Connection..."}; +resource rPString (fileClose, noCrossBank) {"Close"}; +resource rPString (fileQuit, noCrossBank) {"Quit"}; +resource rPString (appleAbout, noCrossBank) {"About VNCview GS..."}; + +/*- Alternative Menu Items without Keyboard Equivalents --------*/ + +resource rMenuBar (1+noKB) { /* the menu bar */ + { + appleMenu, /* resource numbers for the menus */ + fileMenu+noKB, + editMenu+noKB + }; + }; + +resource rMenu (fileMenu+noKB) { /* the File menu */ + fileMenu, /* menu ID */ + refIsResource*menuTitleRefShift /* flags */ + + refIsResource*itemRefShift + + fAllowCache, + fileMenu, /* menu title resource ID */ + { /* menu item resource IDs */ + fileNewConnection+noKB, + fileClose+noKB, + fileQuit+noKB + }; + }; + +resource rMenu (editMenu+noKB) { /* the Edit menu */ + editMenu, /* menu ID */ + refIsResource*menuTitleRefShift /* flags */ + + refIsResource*itemRefShift + + fAllowCache, + editMenu, /* menu title resource ID */ + { /* menu item resource IDs */ + editUndo+noKB, + editCut+noKB, + editCopy+noKB, + editPaste+noKB, + editClear, + editShowClipboard, + editSendClipBoard + }; + }; + +resource rMenuItem (editUndo+noKB) { /* Undo menu item */ + editUndo, /* menu item ID */ + "","", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift /* flags */ + + fDivider, + editUndo /* menu item title resource ID */ + }; + +resource rMenuItem (editCut+noKB) { /* Cut menu item */ + editCut, /* menu item ID */ + "","", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift, /* flags */ + editCut /* menu item title resource ID */ + }; + +resource rMenuItem (editCopy+noKB) { /* Copy menu item */ + editCopy, /* menu item ID */ + "","", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift, /* flags */ + editCopy /* menu item title resource ID */ + }; + +resource rMenuItem (editPaste+noKB) { /* Paste menu item */ + editPaste, /* menu item ID */ + "","", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift, /* flags */ + editPaste /* menu item title resource ID */ + }; + +resource rMenuItem (fileNewConnection+noKB) { /* New menu item */ + fileNewConnection, /* menu item ID */ + "","", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift, /* flags */ + fileNewConnection /* menu item title resource ID */ + }; + +resource rMenuItem (fileClose+noKB) { /* Close menu item */ + fileClose, /* menu item ID */ + "","", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift /* flags */ + + fDivider, + fileClose /* menu item title resource ID */ + }; + +resource rMenuItem (fileQuit+noKB) { /* Quit menu item */ + fileQuit, /* menu item ID */ + "","", /* key equivalents */ + 0, /* check character */ + refIsResource*itemTitleRefShift, /* flags */ + fileQuit /* menu item title resource ID */ + }; + +/*- About Box --------------------------------------------------*/ + +resource rAlertString (1) { + "93:" + "VNCview GS 1.0a1\n" + "Copyright \$A9 2002\$D12004 by Stephen Heumann\n" + "\n" + "This program contains material from the ORCA/C Run-Time Libraries, " + "Copyright 1987-1996 by Byte Works Inc. Used with permission.\n" + ":^#0\$00"; + }; + +/*- Resources used by Finder, etc. -----------------------------*/ + +resource rVersion (1) { + { + 1,0,0, /* Version number */ + alpha, 1, /* Release version */ + }, + verUS, /* Region code */ + "VNCview GS", /* Title */ + "Copyright \$A9 2002\$D12004\n" + "by Stephen Heumann" + }; + +resource rBundle (1, preload, nospecialmemory) { + 1, /* Icon ID */ + 1, /* rBundle ID */ + { /* OneDoc structure to match the program */ + { + $81, + {0}, + {1}, + {2} + }, + $00000005, + matchFileType {{$B3}}, + empty {}, + matchFilename {{"VNCview.GS"}}, + empty {}, + empty {}, + empty {}, + empty {}, + empty {}, + empty {}, + empty {}, + empty {}, + empty {} + } + }; + +resource rIcon (1, preload, nospecialmemory) { + $8000, + 22, + 24, + $"000000000000000000000000" + $"0F8EFF00F0FF00F0F0FFFFF0" + $"0F45FF0F000F0F00F0FFFFF0" + $"000000000000000000000000" + $"0F99FF00FFF0F00FFFFFF0F0" + $"0F99FF0F0F00F0FFFFFFF030" + $"0000000000000000000000F0" + $"0999999999999999999990F0" + $"099FFFF000F0F00FFF999030" + $"09FFFFFFFFFFFFFFFFF99030" + $"09F88FFFFF88F1111FF99030" + $"09FF88FFF88FF1FFF1F99030" + $"09FF88FFF88FF1FFF1F99030" + $"09FFF88F88FFFFFFFFF99030" + $"09FFF88F88FFFF4444F99030" + $"09FFFF888FFFF4FFFFF99030" + $"09FFFF888FFFF4FFFFF99030" + $"09FFFFF8FFFFFF4444F99030" + $"09FFFFFFFFFFFFFFFFF990F0" + $"000000000000000000000000" + $"0F3FFFFFF33333333333F0F0" + $"000000000000000000000000", + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" + $"FFFFFFFFFFFFFFFFFFFFFFFF" +}; + +resource rIcon (2, preload, nospecialmemory) { + 0x8000, + 8, + 8, + $"F8F8F11F" + $"F8F8F1F1" + $"F8F8F1F1" + $"F8F8FFFF" + $"F8F8FF44" + $"F8F8F4FF" + $"FF8FF4FF" + $"FF8FFF44", + $"0F0F0FF0" + $"0F0F0F0F" + $"0F0F0F0F" + $"0F0F0000" + $"0F0F00FF" + $"0F0F0F00" + $"00F00F00" + $"00F000FF" +}; + + +/*- Error handler ----------------------------------------------*/ + +resource rAlertString (noMarinettiError) { + "42:" + "Could not load the Marinetti TCP/IP stack. Please ensure that " + "you have Marinetti 2.0 or later installed on this computer." + ":^#5\$00"; + }; + +resource rAlertString (noCryptoError) { + "42:" + "Could not load the Crypto tool set. Please install the crypto " + "tool set version 1.0 or later to use passwords in VNCview GS." + ":^#6\$00"; + }; + +resource rAlertString (outOfMemoryError) { + "42:" + "Could not allocate sufficient memory. Please reduce memory " + "usage and run VNCview GS again." + ":^#5\$00"; + }; + +resource rAlertString (disconnectTCPIPAlert) { + "20:" + "Do you want to disconnect your TCP/IP connection?" + ":^#3:#2\$00"; + }; + +resource rAlertString (authFailedError) { + "52:" + "Authentication failed. Please re-type your password and try again." + ":^#6\$00"; + }; + +resource rAlertString (authTooManyError) { + "72:" + "Authentication has failed too many times. Please check that you are " + "using the correct password and wait a while before connecting again." + ":^#6\$00"; + }; + +resource rAlertString (connectionFailedAlert) { + "92;" + "Connection failed:\n" + "*0" + ";^#6\$00"; + }; + +resource rAlertString (badRFBVersionAlert) { + "42:" + "The server reported an RFB protocal version incompatible with VNCview " + "GS or is not an RFB server." + ":^#6\$00"; + }; + +resource rAlertString (badAuthTypeAlert) { + "42:" + "The connection failed because the server requested an authentication " + "type not recognized by VNCview GS." + ":^#6\$00"; + }; + +resource rAlertString (noTCPIPConnectionError) { + "32:" + "A TCP/IP connection could not be established." + ":^#6\$00"; + }; + +resource rAlertString (badGetIpidError) { + "42:" + "There was an error while resolving the hostname you provided or " + "preparing to connect to it." + ":^#6\$00"; + }; + +resource rAlertString (badOptionNegotiationError) { + "32:" + "There was an error while negotiating protocol options." + ":^#6\$00"; + }; + +resource rAlertString (badHandshakingError) { + "32:" + "There was an error while establishing a VNC connection with the server." + ":^#6\$00"; + }; + +resource rAlertString (screenTooBigError) { + "72:" + "The server's framebuffer resolution is too big for VNCview GS. " + "VNCview GS does not support resolutions greater than 16,384 by 16,384." + ":^#6\$00"; + }; + +#if 0 +resource rAlertString (badReadTCPError) { + "72:" + "The TCP/IP stack did not return the amount of data expected. This " + "may be indicative of a bug in Marinetti or in the VNC server software." + ":^#6\$00"; + }; +#endif + +resource rAlertString (10000) { + "72:" + "*0" + ":^#6\$00"; + }; + +/*- New VNC Connection window resources ----------------------------------*/ + +resource rWindParam1 (NCWindow+winNewConnection) { + fTitle+fClose+fFlex+fMove, /* wFrameBits */ + nil, /* wTitle */ + 0, /* wRefCon */ + {0,0,0,0}, /* ZoomRect */ + nil, /* wColor ID */ + {0,0}, /* Origin */ + {0,0}, /* data size */ + {0,0}, /* max height-width */ + {0,0}, /* scroll vertical, horizontal */ + {0,0}, /* page vertical, horizontal */ + 0, /* wInfoRefCon */ + 0, /* wInfoHeight */ + {42,162,170,478}, /* wPosition */ + infront, /* wPlane */ + NCWindow+winNewConnection, /* wStorage */ + $0009 /* wInVerb */ + }; + +resource rControlList (NCWindow+winNewConnection) {{ + NCWindow+btnConnect, + NCWindow+btnCancel, + NCWindow+linServer, + NCWindow+txtServer, + NCWindow+txtServerInfo, + NCWindow+txtPassword, + NCWindow+linPassword, + NCWindow+txtDisplay, + NCWindow+rectDisplay, + NCWindow+rad320, + NCWindow+txtColor, + NCWindow+rad640, + NCWindow+txtGray, + NCWindow+chkShared, + NCWindow+chkClipboard, + NCWindow+txtTransfers, + NCWindow+chkEmul3Btn, + NCWindow+chkViewOnly, + }}; + +resource rControlTemplate (NCWindow+btnConnect) { + btnConnect, /* Control ID */ + {108,217,0,0}, /* Control Rect */ + SimpleButtonControl {{ + $0001, /* flags */ + $3002, /* more flags */ + 0, /* refcon */ + NCWindow+btnConnect, /* Title Ref */ + nil, /* color table ref */ + {"\$0D","\$0D",0,0} /* key equivalents (esc) */ + }}; + }; +resource rPString (NCWindow+btnConnect) {"Connect"}; + +resource rControlTemplate (NCWindow+btnCancel) { + btnCancel, /* Control ID */ + {108,128,0,0}, /* Control Rect */ + SimpleButtonControl {{ + $0000, /* flags */ + $3002, /* more flags */ + 0, /* refcon */ + NCWindow+btnCancel, /* Title Ref */ + nil, /* color table ref */ + {"\$1B","\$1B",0,0} /* key equivalents (esc) */ + }}; + }; +resource rPString (NCWindow+btnCancel) {"Cancel"}; + +resource rControlTemplate (NCWindow+linServer) { + linServer, + {4,87,16,310}, + editLineControl {{ + $0000, + $7000, + 0, + 255, /* Max Size */ + 0 /* text ref */ + }}; + }; + +resource rControlTemplate (NCWindow+txtServer) { + txtServer, + {5,3,15,86}, + statTextControl {{ + $0004, + $1002, + 0, + NCWindow+txtServer /* Title ref */ + }}; + }; +resource rTextForLETextBox2 (NCWindow+txtServer) {"VNC Server:"}; + +resource rControlTemplate (NCWindow+txtServerInfo) { + txtServerInfo, + {16,0,26,316}, + statTextControl {{ + $0000, + $1002, + 0, + NCWindow+txtServerInfo /* Title ref */ + }}; + }; +resource rTextForLETextBox2 (NCWindow+txtServerInfo) { + "\$01J\$01\$00Use \$01S\$03\$00host:display\$01S\$00\$00 " + "(or \$01S\$03\$00host\$01S\$00\$00 for display 0)." + }; + +resource rControlTemplate (NCWindow+txtPassword) { + txtPassword, + {29,15,38,86}, + statTextControl {{ + $0004, + $1002, + 0, + NCWindow+txtPassword /* Title ref */ + }}; + }; +resource rTextForLETextBox2 (NCWindow+txtPassword) {"Password:"}; + +resource rControlTemplate (NCWindow+linPassword) { + linPassword, + {28,87,39,310}, + editLineControl {{ + $0000, + $7000, + 0, + 8, /* Max Size */ + 0, /* text ref */ + $D7 /* password character */ + }}; + }; + +resource rControlTemplate (NCWindow+txtDisplay) { + txtDisplay, + {43,13,52,73}, + statTextControl {{ + $0000, + $1002, + 0, + NCWindow+txtDisplay /* Title ref */ + }}; + }; +resource rTextForLETextBox2 (NCWindow+txtDisplay) {" Display "}; + +resource rControlTemplate (NCWindow+rectDisplay) { + NCWindow+rectDisplay, + {47,3,100,111}, + rectangleControl {{ + $FF01, + $1000, + 0 + }}; + }; + +resource rControlTemplate (NCWindow+rad320) { + rad320, + {55,10,0,0}, + RadioControl {{ + $0002, + $1002, + 0, + NCWindow+rad320, /* Title ref */ + 1 /* initial value */ + }}; + }; +resource rPString (NCWindow+rad320) {"320 x 200"}; + +resource rControlTemplate (NCWindow+txtColor) { + txtColor, + {64,35,73,90}, + statTextControl {{ + $000C, + $1002, + 0, + NCWindow+txtColor /* Title ref */ + }}; + }; +resource rTextForLETextBox2 (NCWindow+txtColor) {"Color"}; + +resource rControlTemplate (NCWindow+rad640) { + rad640, + {78,10,0,0}, + RadioControl {{ + $0002, + $1002, + 0, + NCWindow+rad640, /* Title ref */ + 0 /* initial value */ + }}; + }; +resource rPString (NCWindow+rad640) {"640 x 200"}; + +resource rControlTemplate (NCWindow+txtGray) { + txtGray, + {87,35,96,109}, + statTextControl {{ + $000C, + $1002, + 0, + NCWindow+txtGray /* Title ref */ + }}; + }; +resource rTextForLETextBox2 (NCWindow+txtGray) {"Grayscale"}; + +resource rControlTemplate (NCWindow+chkShared) { + chkShared, + {43,117,0,0}, + CheckControl {{ + $0000, + $1002, + 0, + NCWindow+chkShared, /* Title ref */ + 1 /* initial value */ + }}; + }; +resource rPString (NCWindow+chkShared) {"Request Shared Session"}; + +resource rControlTemplate (NCWindow+chkClipboard) { + chkClipboard, + {82,117,0,0}, + CheckControl {{ + $0000, + $1002, + 0, + NCWindow+chkClipboard, /* Title ref */ + 1 /* initial value */ + }}; + }; +resource rPString (NCWindow+chkClipboard) {"Allow Clipboard"}; + +resource rControlTemplate (NCWindow+txtTransfers) { + txtTransfers, + {91,144,100,310}, + statTextControl {{ + $000C, + $1002, + 0, + NCWindow+txtTransfers /* Title ref */ + }}; + }; +resource rTextForLETextBox2 (NCWindow+txtTransfers) {"Transfers from Server"}; + +resource rControlTemplate (NCWindow+chkEmul3Btn) { + chkEmul3Btn, + {56,117,0,0}, + CheckControl {{ + $0000, + $1002, + 0, + NCWindow+chkEmul3Btn, /* Title ref */ + 1 /* initial value */ + }}; + }; +resource rPString (NCWindow+chkEmul3Btn) {"Emulate 3-Button Mouse"}; + +resource rControlTemplate (NCWindow+chkViewOnly) { + chkViewOnly, + {69,117,0,0}, + CheckControl {{ + $0000, + $1002, + 0, + NCWindow+chkViewOnly, /* Title ref */ + 0 /* initial value */ + }}; + }; +resource rPString (NCWindow+chkViewOnly) {"View Only Mode"}; + +/*- TCP/IP Connection Status window resources ----------------------*/ + +resource rWindParam1 (1002) { + fVis + fAlert, /* wFrameBits */ + nil, /* wTitle */ + 0, /* wRefCon */ + {0,0,0,0}, /* ZoomRect */ + nil, /* wColor ID */ + {0,0}, /* Origin */ + {0,0}, /* data size */ + {0,0}, /* max height-width */ + {0,0}, /* scroll vertical, horizontal */ + {0,0}, /* page vertical, horizontal */ + 0, /* wInfoRefCon */ + 0, /* wInfoHeight */ + {85,169,115,471}, /* wPosition */ + infront, /* wPlane */ + nil, /* wStorage */ + $0000 /* wInVerb */ + }; + +resource rPString(10002) {"Press \$11. to cancel."}; + +/*- VNC Session Window Resources -----------------------------------------*/ + +/* 640 mode */ +resource rWindParam1 (1003) { + fRScroll + fBScroll + fVis + fCtlTie + fGrow, /* wFrameBits */ + nil, /* wTitle */ + 0, /* wRefCon */ + {0,0,0,0}, /* ZoomRect */ + 1, /* wColor ID */ + {0,0}, /* Origin */ + {0,0}, /* data size */ + {0,0}, /* max height-width */ + {8,8}, /* scroll vertical, horizontal */ + {0,608}, /* page vertical, horizontal */ + 0, /* wInfoRefCon */ + 0, /* wInfoHeight */ + {13,1,187,614}, /* wPosition */ + infront, /* wPlane */ + nil, /* wStorage */ + $0800 /* wInVerb */ + }; + +/* 320 mode */ +resource rWindParam1 (1004) { + fRScroll + fBScroll + fVis + fCtlTie + fGrow, /* wFrameBits */ + nil, /* wTitle */ + 0, /* wRefCon */ + {0,0,0,0}, /* ZoomRect */ + 1, /* wColor ID */ + {0,0}, /* Origin */ + {0,0}, /* data size */ + {0,0}, /* max height-width */ + {8,8}, /* scroll vertical, horizontal */ + {0,0}, /* page vertical, horizontal */ + 0, /* wInfoRefCon */ + 0, /* wInfoHeight */ + {13,1,187,303}, /* wPosition */ + infront, /* wPlane */ + nil, /* wStorage */ + $0800 /* wInVerb */ + }; + +resource rWindColor (1) { + 0x00F0, + 0x0FA0, + 0x020F, + 0xF0AA, + 0x00F0 + };