/******************************************************************** * vncview.cc - main program code for VNCview GS *******************************************************************/ #if __ORCAC__ #pragma lint -1 segment "VNCview GS"; #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 "readtcp.h" #include "menus.h" #include "colortables.h" #include "mouse.h" #include "keyboard.h" #include "clipboard.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 #define chkTuneMarinetti 20 #define txtPreferredEncoding 24 #define radRaw 25 #define radHextile 26 static 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 */ static Ref startStopParm; /* tool start/shutdown parameter */ BOOLEAN colorTablesComplete = FALSE; /* Are the big color tables complete */ static Handle dpHndl; /* direct page space for assembly routines */ extern void *dpPtr; /* pointer to DP for assembly routines */ /* Connection options */ int hRez = 320; BOOLEAN requestSharedSession = TRUE; BOOLEAN allowClipboardTransfers = TRUE; BOOLEAN emulate3ButtonMouse = TRUE; BOOLEAN viewOnlyMode = FALSE; BOOLEAN useHextile = FALSE; BOOLEAN tuneMarinetti = TRUE; char vncServer[257]; char vncPassword[10]; static void Quit (void); /*************************************************************** * DrawContents - Draw the contents of the active port ***************************************************************/ #pragma databank 1 static void DrawContents (void) { PenNormal(); /* use a "normal" pen */ DrawControls(GetPort()); /* draw controls in window */ } #pragma databank 0 /*************************************************************** * DoAbout - Draw our about box ***************************************************************/ static void DoAbout (void) { #define alertID 1 /* alert string resource ID */ AlertWindow(awCString+awResource, NULL, alertID); #undef alertID } /*************************************************************** * DoNewConnection - Show the New Connection window ***************************************************************/ static void DoNewConnection (void) { 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 */ if (cursor) { InitCursor(); free(cursor); cursor = NULL; } }; } /*************************************************************** * DoLEEdit - Handle edit menu items for LineEdit controls * Parameters: * editAction: Action selected from edit menu ***************************************************************/ static 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. ***************************************************************/ static 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: Quit(); 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 ***************************************************************/ static 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 chkTuneMarinetti: tuneMarinetti = !tuneMarinetti; break; case txtTransfers: allowClipboardTransfers = !allowClipboardTransfers; SetCtlValueByID(allowClipboardTransfers, newConnWindow, chkClipboard); break; case radRaw: useHextile = FALSE; break; case radHextile: useHextile = TRUE; 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 ***************************************************************/ static 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 */ static 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. * We set SCBs for color table 7 in StartUpTools or QDStartUp. */ SetColorTable(7, &gray640Colors); } static void Quit (void) { /* Done with event loop - now quitting */ if (vncConnected) /* Disconnect if still connected */ CloseTCPConnection(); if (readBufferHndl) DisposeHandle(readBufferHndl); /* Get rid of TCPIP read buffer hndl */ if (dpHndl) DisposeHandle(dpHndl); if (cursor) free(cursor); /* 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 */ exit(0); } /*************************************************************** * Main - Initial startup function ***************************************************************/ int main (void) { int event; /* event type returned by TaskMaster */ #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: "); } readBufferHndl = NewHandle(1, userid(), 0, NULL); if (toolerror()) goto oomQuit; dpHndl = NewHandle(0x0100, userid(), attrLocked|attrFixed|attrPage|attrNoCross|attrBank, 0x00000000); if (toolerror()) goto oomQuit; dpPtr = *dpHndl; 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); Quit(); /* Can't proceed, so just quit */ } else /* Marinetti loaded successfully */ TCPIPStartUp(); /* ... so activate it now */ if (toolerror()) { /* Get handle for TCPIP read buffer */ oomQuit: SysBeep(); InitCursor(); AlertWindow(awResource, NULL, outOfMemoryError); Quit(); } 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(); else if (colorTablesComplete == FALSE) if (MakeBigColorTables(256)) colorTablesComplete = TRUE; } Quit(); }