├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ └── bug_report.md ├── LICENSE ├── README.md ├── docs └── MacTCP_programming.pdf ├── images ├── main-v1.0.png ├── main-v1.1.png ├── server-logs-v1.1.png ├── server-options-v1.1.png ├── youtube.png └── youtube2.png └── mac-cpp-source ├── ChainedTCPHelper.cpp ├── ChainedTCPHelper.h ├── DebugLog.cpp ├── DebugLog.h ├── DialogUtils.h ├── DialogUtils_VarArgs.cpp ├── MiniVNC.µ.bin ├── MiniVNC.µ.rsrc.bin ├── TightVNCSupport.cpp ├── TightVNCSupport.h ├── TightVNCTypes.c ├── TightVNCTypes.h ├── VNCConfig.cpp ├── VNCConfig.h ├── VNCEncodeCursor.cpp ├── VNCEncodeHextile.cpp ├── VNCEncodeHextile.h ├── VNCEncodeRAW.cpp ├── VNCEncodeRAW.h ├── VNCEncodeTRLE.cpp ├── VNCEncodeTRLE.h ├── VNCEncodeTRLEMono.cpp ├── VNCEncodeTight.cpp ├── VNCEncodeTight.h ├── VNCEncodeTiles.h ├── VNCEncodeTilesASM.cpp ├── VNCEncodeTilesC.cpp ├── VNCEncodeZRLE.cpp ├── VNCEncodeZRLE.h ├── VNCEncoder.cpp ├── VNCEncoder.h ├── VNCEncoderZLib.cpp ├── VNCFrameBuffer.cpp ├── VNCFrameBuffer.h ├── VNCPalette.cpp ├── VNCPalette.h ├── VNCPaletteTrueColor.cpp ├── VNCScreenHash.cpp ├── VNCScreenHash.h ├── VNCServer.cpp ├── VNCServer.h ├── VNCStreamReader.cpp ├── VNCStreamReader.h ├── VNCTypes.h ├── libs ├── Ari Halberstadt │ ├── OSUtilities.cpp │ └── OSUtilities.h ├── ChromiVNC │ ├── LICENSE.H │ ├── VNCKeyboard.cpp │ ├── VNCKeyboard.h │ └── keysymdef.h ├── Common Libs │ ├── GestaltUtils.cpp │ └── GestaltUtils.h ├── MacTCP.h ├── compat.h └── miniz-3.0.2 │ ├── ChangeLog.md │ ├── LICENSE │ ├── examples │ ├── example1.c │ ├── example2.c │ ├── example3.c │ ├── example4.c │ ├── example5.c │ └── example6.c │ ├── miniz.c │ ├── miniz.h │ └── readme.md └── main.cpp /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [marciot] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: marciot 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | 12 | A clear and concise description of what the bug is. 13 | 14 | **Remote Computer (please complete)** 15 | 16 | - MiniVNC Version: [e.g. v1.4] 17 | - OS: [e.g. System 7.0.5] 18 | - Model: [e.g. Mac Plus] 19 | - RAM: [e.g. 4MB] 20 | 21 | **Local Computer (please complete)** 22 | 23 | - Client App: [e.g. TightVNC] 24 | - Client Version: [e.g. 2.8.81] 25 | - OS: [e.g. Windows 10] 26 | 27 | **Server Logs (please attach)** 28 | 29 | - Select "Server Options..." from the "Server" menu 30 | - Check "Keep server logs (for debugging)" in the "Server Options" window 31 | - Click "Okay" and then "Start Server" 32 | - Connect to the server and reproduce the problem 33 | - Click on the "Server Logs" window and choose "Save" from the "File" 34 | - If the "Save" option is grayed out: 35 | - Select "Server Logs" from the "Server" menu (to hide the log window) 36 | - Select "Server Logs" from the "Server" menu (to show the log window) 37 | - Choose "Save" from the "File" 38 | - Attach the saved file to this ticket 39 | 40 | **Screenshots** 41 | If applicable, add screenshots to help explain your problem. 42 | 43 | **Additional context** 44 | Add any other context about the problem here. 45 | -------------------------------------------------------------------------------- /docs/MacTCP_programming.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/docs/MacTCP_programming.pdf -------------------------------------------------------------------------------- /images/main-v1.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/images/main-v1.0.png -------------------------------------------------------------------------------- /images/main-v1.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/images/main-v1.1.png -------------------------------------------------------------------------------- /images/server-logs-v1.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/images/server-logs-v1.1.png -------------------------------------------------------------------------------- /images/server-options-v1.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/images/server-options-v1.1.png -------------------------------------------------------------------------------- /images/youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/images/youtube.png -------------------------------------------------------------------------------- /images/youtube2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/images/youtube2.png -------------------------------------------------------------------------------- /mac-cpp-source/ChainedTCPHelper.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "ChainedTCPHelper.h" 19 | 20 | /* Opens the TCP driver and allocates a parameter block for 21 | * subsequent calls. 22 | */ 23 | OSErr ChainedTCPHelper::begin(TCPiopb *pBlock) { 24 | // Open the TCP driver 25 | 26 | ParamBlockRec param; 27 | param.ioParam.ioNamePtr = "\p.IPP"; 28 | param.ioParam.ioPermssn = fsCurPerm; 29 | OSErr err = PBOpen(¶m, false); 30 | if(err != noErr) return err; 31 | 32 | //pBlock->ioCompletion = 0L; 33 | pBlock->ioCRefNum = param.ioParam.ioRefNum; 34 | pBlock->ioResult = 0; 35 | 36 | return err; 37 | } 38 | 39 | /* Requests a new TCP stream in preparation for initiating a connection. 40 | * A buffer must be provided for storing incoming data waiting to be processed. 41 | * Once isReady() is true call getStream() to retreive the stream pointer. 42 | */ 43 | void ChainedTCPHelper::createStream(TCPiopb *pBlock, Ptr recvPtr, unsigned short recvLen, TCPNotifyProcPtr notifyProc) { 44 | pBlock->csCode = TCPCreate; 45 | pBlock->ioResult = 1; 46 | pBlock->csParam.create.rcvBuff = recvPtr; 47 | pBlock->csParam.create.rcvBuffLen = recvLen; 48 | pBlock->csParam.create.notifyProc = notifyProc; 49 | PBControl((ParmBlkPtr)pBlock,true); 50 | } 51 | 52 | /* Attempts to initiate a connection with a host specified by host and port. 53 | */ 54 | void ChainedTCPHelper::openConnection(TCPiopb *pBlock, StreamPtr streamPtr, ip_addr remoteHost, tcp_port remotePort, Byte timeout) { 55 | pBlock->csCode = TCPActiveOpen; 56 | pBlock->ioResult = 1; 57 | pBlock->tcpStream = streamPtr; 58 | pBlock->csParam.open.ulpTimeoutValue = timeout; 59 | pBlock->csParam.open.ulpTimeoutAction = 1; 60 | pBlock->csParam.open.validityFlags = 0xC0; 61 | pBlock->csParam.open.commandTimeoutValue = timeout; 62 | pBlock->csParam.open.remoteHost = remoteHost; 63 | pBlock->csParam.open.remotePort = remotePort; 64 | pBlock->csParam.open.localPort = 0; 65 | pBlock->csParam.open.tosFlags = 0; 66 | pBlock->csParam.open.precedence = 0; 67 | pBlock->csParam.open.dontFrag = 0; 68 | pBlock->csParam.open.timeToLive = 0; 69 | pBlock->csParam.open.security = 0; 70 | pBlock->csParam.open.optionCnt = 0; 71 | PBControl((ParmBlkPtr)pBlock,true); 72 | } 73 | 74 | /* Waits for a connection to be opened on a specified port. If remoteHost and remotePort are given 75 | * it will only accept connections from that host and port, either value can be zero. 76 | */ 77 | void ChainedTCPHelper::waitForConnection(TCPiopb *pBlock, StreamPtr streamPtr, Byte timeout, tcp_port localPort, ip_addr remoteHost, tcp_port remotePort) { 78 | pBlock->csCode = TCPPassiveOpen; 79 | pBlock->ioResult = 1; 80 | pBlock->tcpStream = streamPtr; 81 | pBlock->csParam.open.ulpTimeoutValue = timeout; 82 | pBlock->csParam.open.ulpTimeoutAction = 1; 83 | pBlock->csParam.open.validityFlags = 0xC0; 84 | pBlock->csParam.open.commandTimeoutValue = timeout; 85 | pBlock->csParam.open.remoteHost = remoteHost; 86 | pBlock->csParam.open.remotePort = remotePort; 87 | pBlock->csParam.open.localPort = localPort; 88 | pBlock->csParam.open.tosFlags = 0; 89 | pBlock->csParam.open.precedence = 0; 90 | pBlock->csParam.open.dontFrag = 0; 91 | pBlock->csParam.open.timeToLive = 0; 92 | pBlock->csParam.open.security = 0; 93 | pBlock->csParam.open.optionCnt = 0; 94 | PBControl((ParmBlkPtr)pBlock,true); 95 | } 96 | 97 | /* Returns information about the most recent completed call to waitForConnection() or openConnection() 98 | */ 99 | void ChainedTCPHelper::getRemoteHost(TCPiopb *pBlock, ip_addr *remoteHost, tcp_port *remotePort) { 100 | *remoteHost = pBlock->csParam.open.remoteHost; 101 | *remotePort = pBlock->csParam.open.remotePort; 102 | } 103 | 104 | void ChainedTCPHelper::getLocalHost(TCPiopb *pBlock, ip_addr *localHost, tcp_port *localPort) { 105 | *localHost = pBlock->csParam.open.localHost; 106 | *localPort = pBlock->csParam.open.localPort; 107 | } 108 | 109 | /* Gracefully closes a connection with a remote host. This is not always possible, 110 | and the programmer might have to resort to abort(), described next. */ 111 | 112 | void ChainedTCPHelper::close(TCPiopb *pBlock, StreamPtr streamPtr, Byte timeout) { 113 | pBlock->csCode = TCPClose; 114 | pBlock->ioResult = 1; 115 | pBlock->tcpStream = streamPtr; 116 | pBlock->csParam.close.ulpTimeoutValue = timeout; 117 | pBlock->csParam.close.validityFlags = 0xC0; 118 | pBlock->csParam.close.ulpTimeoutAction = 1; 119 | PBControl((ParmBlkPtr)pBlock,true); 120 | } 121 | 122 | /* Should be called if a close() fails to close a connection properly. 123 | This call should not normally be used to terminate connections. */ 124 | 125 | void ChainedTCPHelper::abort(TCPiopb *pBlock, StreamPtr streamPtr) { 126 | pBlock->csCode = TCPAbort; 127 | pBlock->ioResult = 1; 128 | pBlock->tcpStream = streamPtr; 129 | PBControl((ParmBlkPtr)pBlock,true); 130 | } 131 | 132 | /* ReleaseStream() frees the allocated buffer space for a given connection 133 | stream. This call should be made after close(). */ 134 | 135 | void ChainedTCPHelper::release(TCPiopb *pBlock, StreamPtr streamPtr) { 136 | pBlock->csCode = TCPRelease; 137 | pBlock->ioResult = 1; 138 | pBlock->tcpStream = streamPtr; 139 | PBControl((ParmBlkPtr)pBlock,true); 140 | } 141 | 142 | void ChainedTCPHelper::send(TCPiopb *pBlock, StreamPtr streamPtr, wdsEntry data[], Byte timeout, Boolean push, Boolean urgent) { 143 | pBlock->csCode = TCPSend; 144 | pBlock->ioResult = 1; 145 | pBlock->tcpStream = streamPtr; 146 | pBlock->csParam.send.ulpTimeoutValue = timeout; 147 | pBlock->csParam.send.ulpTimeoutAction = 1; 148 | pBlock->csParam.send.validityFlags = 0xC0; 149 | pBlock->csParam.send.pushFlag = push; 150 | pBlock->csParam.send.urgentFlag = urgent; 151 | pBlock->csParam.send.wdsPtr = (Ptr) data; 152 | PBControl((ParmBlkPtr)pBlock,true); 153 | } 154 | 155 | void ChainedTCPHelper::status(TCPiopb *pBlock, StreamPtr streamPtr) { 156 | pBlock->csCode = TCPStatus; 157 | pBlock->ioResult = 1; 158 | pBlock->tcpStream = streamPtr; 159 | PBControl((ParmBlkPtr)pBlock,true); 160 | } 161 | 162 | void ChainedTCPHelper::receiveNoCopy(TCPiopb *pBlock, StreamPtr streamPtr, rdsEntry data[], unsigned short numRds, Byte timeout) { 163 | pBlock->csCode = TCPNoCopyRcv; 164 | pBlock->ioResult = 1; 165 | pBlock->tcpStream = streamPtr; 166 | pBlock->csParam.receive.commandTimeoutValue = timeout; 167 | pBlock->csParam.receive.rdsPtr = (Ptr) data; 168 | pBlock->csParam.receive.rdsLength = numRds; 169 | PBControl((ParmBlkPtr)pBlock,true); 170 | } 171 | 172 | void ChainedTCPHelper::receiveReturnBuffers(TCPiopb *pBlock) { 173 | pBlock->csCode = TCPRcvBfrReturn; 174 | pBlock->ioResult = 1; 175 | PBControl((ParmBlkPtr)pBlock,true); 176 | } 177 | 178 | void ChainedTCPHelper::receive(TCPiopb *pBlock, StreamPtr streamPtr, Ptr buffer, unsigned short length, Byte timeout) { 179 | pBlock->csCode = TCPRcv; 180 | pBlock->ioResult = 1; 181 | pBlock->tcpStream = streamPtr; 182 | pBlock->csParam.receive.commandTimeoutValue = timeout; 183 | pBlock->csParam.receive.rcvBuff = buffer; 184 | pBlock->csParam.receive.rcvBuffLen = length; 185 | PBControl((ParmBlkPtr)pBlock,true); 186 | } 187 | 188 | void ChainedTCPHelper::getReceiveInfo(TCPiopb *pBlock, unsigned short *rcvLen, Boolean *urgent, Boolean *mark) { 189 | if(rcvLen) *rcvLen = pBlock->csParam.receive.rcvBuffLen; 190 | if(urgent) *urgent = pBlock->csParam.receive.urgentFlag; 191 | if(mark) *mark = pBlock->csParam.receive.markFlag; 192 | } 193 | 194 | void ChainedTCPHelper::then(TCPiopb *pBlock, TCPCompletionPtr proc) { 195 | ExtendedTCPiopb *epb = (ExtendedTCPiopb *)((char*)pBlock - 8); 196 | epb->ourCompletion = proc; 197 | } -------------------------------------------------------------------------------- /mac-cpp-source/ChainedTCPHelper.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "MacTCP.h" 21 | 22 | const long kTimeOut = 120; /* Timeout for TCP commands */ 23 | 24 | struct ExtendedTCPiopb; 25 | 26 | typedef pascal void (*TCPCompletionPtr)(TCPiopb *epb); 27 | 28 | struct ExtendedTCPiopb { 29 | unsigned long ourA5; // Application A5 30 | TCPCompletionPtr ourCompletion; // Address of completion routine written in a high-level language 31 | TCPiopb pb; // Parameter block used to make the call 32 | }; 33 | 34 | class ChainedTCPHelper { 35 | public: 36 | static inline OSErr getResult(TCPiopb *pBlock) {return pBlock->ioResult;} 37 | static inline void clearError(TCPiopb *pBlock) {pBlock->ioResult = noErr;} 38 | static inline StreamPtr getStream(TCPiopb *pBlock) {return pBlock->tcpStream;}; 39 | 40 | static OSErr begin(TCPiopb *pBlock); 41 | 42 | static void createStream(TCPiopb *pBlock, Ptr recvPtr, unsigned short recvLen, TCPNotifyProcPtr notifyProc); 43 | 44 | static void openConnection(TCPiopb *pBlock, StreamPtr streamPtr, ip_addr remoteHost, tcp_port remotePort, Byte timeout = kTimeOut); 45 | static void waitForConnection(TCPiopb *pBlock, StreamPtr streamPtr, Byte timeout, tcp_port localPort, ip_addr remoteHost = 0, tcp_port remotePort = 0); 46 | static void getRemoteHost(TCPiopb *pBlock, ip_addr *remoteHost, tcp_port *remotePort); 47 | static void getLocalHost(TCPiopb *pBlock, ip_addr *localHost, tcp_port *localPort); 48 | 49 | static void close(TCPiopb *pBlock, StreamPtr streamPtr, Byte timeout = kTimeOut); 50 | static void abort(TCPiopb *pBlock, StreamPtr streamPtr); 51 | static void release(TCPiopb *pBlock, StreamPtr streamPtr); 52 | 53 | static void send(TCPiopb *pBlock, StreamPtr streamPtr, wdsEntry data[], Byte timeout = kTimeOut, Boolean push = false, Boolean urgent = false); 54 | static void receive(TCPiopb *pBlock, StreamPtr streamPtr, Ptr buffer, unsigned short length, Byte timeout = kTimeOut); 55 | static void getReceiveInfo(TCPiopb *pBlock, unsigned short *rcvLen, Boolean *urgent = 0,Boolean *mark = 0); 56 | 57 | static void receiveNoCopy(TCPiopb *pBlock, StreamPtr streamPtr, rdsEntry data[], unsigned short numRds, Byte timeout = 0); 58 | static void receiveReturnBuffers(TCPiopb *pBlock); 59 | 60 | static void status(TCPiopb *pBlock, StreamPtr streamPtr); 61 | 62 | static void then(TCPiopb *pBlock, TCPCompletionPtr proc); 63 | }; -------------------------------------------------------------------------------- /mac-cpp-source/DebugLog.cpp: -------------------------------------------------------------------------------- 1 | #include "DebugLog.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define CAPACITY 2048 9 | 10 | /* msgbuf.cpp allows you to defer a printf from an interrupt handler to a later date in the 11 | main event loop, where the memory manager won't hate you. 12 | 13 | Call dprintf() in your interrupt routine, then do_deferred_output in your event loop. */ 14 | 15 | char buffer[CAPACITY]; 16 | int wrpos = 0; 17 | int rdpos = 0; 18 | 19 | // Prints a debugging error message. If the message begins with "-" it will be shown 20 | // on the main VNC user interface. 21 | 22 | void _dprintf(const char* format, ...) { 23 | char str[256]; 24 | 25 | // Do the printf 26 | va_list args; 27 | va_start(args, format); 28 | const int len = vsprintf(str, format, args); 29 | if (len > 255) { 30 | // Abort if we overflow the buffer, shame CodeWarrior does not have svnprintf! 31 | abort(); 32 | } 33 | va_end(args); 34 | 35 | // Copy characters to ring buffer 36 | for(int i = 0; i <= len; i++) { 37 | buffer[wrpos] = str[i]; 38 | wrpos = (wrpos+1) % CAPACITY; 39 | } 40 | } 41 | 42 | void _do_deferred_output() { 43 | char str[256]; 44 | unsigned char len = 0; 45 | while (rdpos != wrpos) { 46 | // Pull character from ring buffer 47 | unsigned char c = buffer[rdpos]; 48 | rdpos = (rdpos+1) % CAPACITY; 49 | 50 | // Output the string 51 | str[len++] = c; 52 | if (c == '\0') { 53 | fputs(str, stdout); 54 | len = 0; 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /mac-cpp-source/DebugLog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "VNCConfig.h" 4 | 5 | void _dprintf(const char* format, ...); 6 | void _do_deferred_output(); 7 | 8 | #define dprintf if (vncConfig.enableLogging) _dprintf 9 | #define do_deferred_output if (vncConfig.enableLogging) _do_deferred_output -------------------------------------------------------------------------------- /mac-cpp-source/DialogUtils.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | ControlHandle FindCHndl(DialogPtr dlg, int item, short *type); 19 | 20 | void ShowStatus(Str255 pStr); 21 | void SetDialogTitle(Str255 pStr); 22 | int ShowAlert(unsigned long type, short id, Str255 pStr); 23 | 24 | void ShowStatus(const char* format, ...); 25 | void SetDialogTitle(const char* format, ...); 26 | int ShowAlert(unsigned long type, short id, const char* format, ...); -------------------------------------------------------------------------------- /mac-cpp-source/DialogUtils_VarArgs.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "DialogUtils.h" 23 | 24 | void ShowStatus(const char* format, ...) { 25 | Str255 pStr; 26 | va_list argptr; 27 | va_start(argptr, format); 28 | vsprintf((char*)pStr + 1, format, argptr); 29 | va_end(argptr); 30 | const short len = strlen((char*)pStr + 1); 31 | pStr[0] = pStr[len] == '\n' ? len - 1 : len; 32 | ShowStatus(pStr); 33 | } 34 | 35 | void SetDialogTitle(const char* format, ...) { 36 | Str255 pStr; 37 | va_list argptr; 38 | va_start(argptr, format); 39 | vsprintf((char*)pStr + 1, format, argptr); 40 | va_end(argptr); 41 | const short len = strlen((char*)pStr + 1); 42 | pStr[0] = pStr[len] == '\n' ? len - 1 : len; 43 | SetDialogTitle(pStr); 44 | } 45 | 46 | int ShowAlert(unsigned long type, short id, const char* format, ...) { 47 | Str255 pStr; 48 | va_list argptr; 49 | va_start(argptr, format); 50 | vsprintf((char*)pStr + 1, format, argptr); 51 | va_end(argptr); 52 | pStr[0] = strlen((char*)pStr + 1); 53 | return ShowAlert(type, id, pStr); 54 | } -------------------------------------------------------------------------------- /mac-cpp-source/MiniVNC.µ.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/mac-cpp-source/MiniVNC.µ.bin -------------------------------------------------------------------------------- /mac-cpp-source/MiniVNC.µ.rsrc.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/mac-cpp-source/MiniVNC.µ.rsrc.bin -------------------------------------------------------------------------------- /mac-cpp-source/TightVNCSupport.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** * MiniVNC (c) 2022-2024 Marcio Teixeira * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * To view a copy of the GNU General Public License, go to the following * * location: . * ****************************************************************************/ #pragma once #include "VNCStreamReader.h" void loadTightSupport(); void sendTightCapabilities(); pascal void tcpSendTightVNCAuthTypes(TCPiopb *pb); DispatchMsgResult dispatchTightClientMessage(MessageData *pb); void returnFromTightVNCMessage(); -------------------------------------------------------------------------------- /mac-cpp-source/TightVNCTypes.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | 19 | #include "TightVNCTypes.h" 20 | 21 | /* 22 | * Reference: 23 | * https://stackoverflow.com/questions/70720527/specification-of-client-uploads-in-tightvnc-rfb 24 | * https://vncdotool.readthedocs.io/en/0.8.0/rfbproto.html#serverinit 25 | * https://github.com/TurboVNC/tightvnc/blob/a235bae328c12fd1c3aed6f3f034a37a6ffbbd22/vnc_unixsrc/include/rfbproto.h#L420 26 | */ 27 | 28 | struct TightVNCServerAuthCaps tightAuthCaps = { 29 | 0, // numberOfTunnelTypes 30 | 2, // numberOfAuthTypes 31 | { 32 | { 1, "STDV", "NOAUTH__"}, 33 | { 2, "STDV", "VNCAUTH_"} 34 | } 35 | }; 36 | 37 | struct TightVNCServerInitCaps tightInitCaps = { 38 | 8, // numberOfServerMesg 39 | 7, // numberOfClientMesg 40 | 3, // numberOfEncodings 41 | 0, // padding 42 | 43 | { 44 | /***** Server Messages *****/ 45 | 46 | { 150, "TGHT", "CUS_EOCU"}, // End of continuous updates 47 | 48 | // Legacy File Transfer Messages 49 | 50 | //{ 130, "TGHT", "FTS_LSDT"}, // File list data 51 | //{ 131, "TGHT", "FTS_DNDT"}, // File download data 52 | //{ 132, "TGHT", "FTS_UPCN"}, // File upload cancel 53 | //{ 133, "TGHT", "FTS_DNFL"}, // File download failed 54 | 55 | // New TightVNC File Transfer Messages: 56 | 57 | //{ 0xFC000101, "TGHT", "FTSCSRLY"}, // Compression support reply 58 | { 0xFC000103, "TGHT", "FTSFLRLY"}, // File list reply 59 | //{ 0xFC000105, "TGHT", "FTSM5RLY"}, // MD5 reply 60 | 61 | { 0xFC000107, "TGHT", "FTSFURLY"}, // Upload start reply 62 | { 0xFC000109, "TGHT", "FTSUDRLY"}, // Upload data reply 63 | { 0xFC00010B, "TGHT", "FTSUERLY"}, // Upload end reply 64 | 65 | //{ 0xFC00010D, "TGHT", "FTSFDRLY"}, // Download start reply 66 | //{ 0xFC00010F, "TGHT", "FTSDDRLY"}, // Download data reply 67 | //{ 0xFC000110, "TGHT", "FTSDERLY"}, // Download end reply 68 | 69 | { 0xFC000112, "TGHT", "FTSMDRLY"}, // Mkdir reply 70 | { 0xFC000114, "TGHT", "FTSFTRLY"}, // File remove reply 71 | //{ 0xFC000116, "TGHT", "FTSFMRLY"}, // File rename reply 72 | //{ 0xFC000118, "TGHT", "FTSDSRLY"}, // Dir size reply 73 | 74 | { 0xFC000119, "TGHT", "FTLRFRLY"}, // Last request failed reply 75 | 76 | /***** Client Messages *****/ 77 | 78 | { 150, "TGHT", "CUC_ENCU"}, // Enable continuous updates 79 | 80 | // Legacy File Transfer Messages 81 | 82 | //{ 130, "TGHT", "FTC_LSRQ"}, // File list request 83 | //{ 131, "TGHT", "FTC_DNRQ"}, // File download request 84 | //{ 132, "TGHT", "FTC_UPRQ"}, // File upload request 85 | //{ 133, "TGHT", "FTC_UPDT"}, // File upload data 86 | //{ 134, "TGHT", "FTC_DNCN"}, // File download cancel 87 | //{ 135, "TGHT", "FTC_UPFL"}, // File upload failed 88 | //{ 136, "TGHT", "FTC_FCDR"}, // File create directory request 89 | 90 | // New TightVNC File Transfer Messages: 91 | 92 | //{ 0xFC000100, "TGHT", "FTCCSRST"}, // Compression support request 93 | { 0xFC000102, "TGHT", "FTCFLRST"}, // File list request 94 | //{ 0xFC000104, "TGHT", "FTCM5RST"}, // MD5 request 95 | 96 | { 0xFC000106, "TGHT", "FTCFURST"}, // Upload start request 97 | { 0xFC000108, "TGHT", "FTCUDRST"}, // Upload data request 98 | { 0xFC00010A, "TGHT", "FTCUERST"}, // Upload end request 99 | 100 | //{ 0xFC00010C, "TGHT", "FTCFDRST"}, // Download start request 101 | //{ 0xFC00010E, "TGHT", "FTCDDRST"}, // Download data request 102 | 103 | { 0xFC000111, "TGHT", "FTCMDRST"}, // Mkdir request (required for upload/download) 104 | { 0xFC000113, "TGHT", "FTCFRRST"}, // File remove request 105 | //{ 0xFC000115, "TGHT", "FTCFMRST"}, // File rename request 106 | //{ 0xFC000117, "TGHT", "FTCDSRST"}, // Dir size request (required for download) 107 | 108 | /***** Encodings *****/ 109 | 110 | { 5, "STDV", "HEXTILE_"}, // Hextile encoding 111 | { 16, "STDV", "ZRLE____"}, // ZRLE encoding 112 | { -239, "TGHT", "RCHCURSR"} // Rich cursor pseudo-encoding 113 | } 114 | }; -------------------------------------------------------------------------------- /mac-cpp-source/TightVNCTypes.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | // Reference: https://libvncserver.sourceforge.net/doc/html/rfbtightproto_8h_source.html 21 | 22 | enum { 23 | mTightVNCExt = -4, // 0xFC 24 | mTightVNCExtFileListReq = 0xFC000102, 25 | mTightVNCExtFUpStartReq = 0xFC000106, 26 | }; 27 | 28 | typedef struct { 29 | unsigned long hi; 30 | unsigned long lo; 31 | } uint64; 32 | 33 | typedef struct { 34 | unsigned long code; 35 | unsigned char vendor[4]; 36 | unsigned char signature[8]; 37 | } TightVNCCapabilites; 38 | 39 | typedef struct { 40 | unsigned long code; 41 | } TightVNCCapReply; 42 | 43 | struct TightVNCServerAuthCaps { 44 | unsigned long numberOfTunnelTypes; 45 | unsigned long numberOfAuthTypes; 46 | TightVNCCapabilites authTypes[2]; 47 | }; 48 | 49 | struct TightVNCServerInitCaps { 50 | unsigned short numberOfServerMesg; 51 | unsigned short numberOfClientMesg; 52 | unsigned short numberOfEncodings; 53 | unsigned short padding; 54 | TightVNCCapabilites serverMsg[18]; 55 | }; 56 | 57 | struct TightVNCFileUploadData { 58 | // Common to all messages 59 | unsigned long pathLen; 60 | const char *pathPtr; 61 | 62 | // Data about the path (filled in by processRequestPath) 63 | Boolean isRoot; 64 | long dirId; 65 | short vRefNum; 66 | 67 | // File List Request 68 | long gmtDelta; 69 | long index; 70 | long nEntries; 71 | 72 | // File Upload Start Request 73 | short fRefNum; 74 | unsigned long compressedSize; 75 | unsigned long uncompressedSize; 76 | }; 77 | 78 | #pragma options align=packed 79 | 80 | struct TightVNCFileListEntry { 81 | uint64 fileSize; 82 | uint64 lastModified; 83 | unsigned short flags; // dir = 1; exe = 2 84 | unsigned long dirNameSize; 85 | /* Followed by char Dirname[dirNameSize] */ 86 | }; 87 | 88 | struct TightVNCFileListReply { 89 | long message; 90 | unsigned char compressionLevel; 91 | unsigned long compressedSize; 92 | unsigned long uncompressedSize; 93 | // Followed by compressed data; 94 | //unsigned long file count; 95 | }; 96 | 97 | #pragma options align=reset 98 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCConfig.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/mac-cpp-source/VNCConfig.cpp -------------------------------------------------------------------------------- /mac-cpp-source/VNCConfig.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/mac-cpp-source/VNCConfig.h -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncodeCursor.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "VNCServer.h" 19 | #include "VNCPalette.h" 20 | #include "VNCEncoder.h" 21 | #include "VNCEncodeCursor.h" 22 | 23 | unsigned long cursorChecksum; 24 | 25 | void VNCEncodeCursor::clear() { 26 | // Force an update 27 | cursorChecksum = !cursorChecksum; 28 | } 29 | 30 | Size VNCEncodeCursor::minBufferSize() { 31 | return sizeof(VNCFBUpdateRect) + 16 * 16 * 4 + 32; 32 | } 33 | 34 | Boolean VNCEncodeCursor::needsUpdate() { 35 | const unsigned long *TheCrsr = (unsigned long*) 0x0844; 36 | unsigned long sum = 0; 37 | for(int i = 0; i < 68 / sizeof(unsigned long); i++) { 38 | sum += TheCrsr[i]; 39 | } 40 | if(cursorChecksum != sum) { 41 | cursorChecksum = sum; 42 | /*#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" 43 | #define BYTE_TO_BINARY(byte) \ 44 | ((byte) & 0x80 ? '1' : '0'), \ 45 | ((byte) & 0x40 ? '1' : '0'), \ 46 | ((byte) & 0x20 ? '1' : '0'), \ 47 | ((byte) & 0x10 ? '1' : '0'), \ 48 | ((byte) & 0x08 ? '1' : '0'), \ 49 | ((byte) & 0x04 ? '1' : '0'), \ 50 | ((byte) & 0x02 ? '1' : '0'), \ 51 | ((byte) & 0x01 ? '1' : '0') 52 | unsigned char *TheCrsr = (unsigned char*) 0x0844; 53 | for(int i = 0; i < 68; i += 2) { 54 | dprintf(BYTE_TO_BINARY_PATTERN BYTE_TO_BINARY_PATTERN "\n", BYTE_TO_BINARY(TheCrsr[i]), BYTE_TO_BINARY(TheCrsr[i+1])); 55 | }*/ 56 | return true; 57 | } 58 | return false; 59 | } 60 | 61 | Boolean VNCEncodeCursor::getChunk(wdsEntry *wds) { 62 | const unsigned short *TheCrsr = (unsigned short*) 0x0844; 63 | VNCFBUpdateRect *cursor = (VNCFBUpdateRect*)fbUpdateBuffer; 64 | cursor->rect.x = TheCrsr[33]; 65 | cursor->rect.y = TheCrsr[32]; 66 | cursor->rect.w = 16; 67 | cursor->rect.h = 16; 68 | cursor->encodingType = mCursorEncoding; 69 | 70 | unsigned char *dst = fbUpdateBuffer + sizeof(VNCFBUpdateRect); 71 | 72 | setupPIXEL(); 73 | 74 | // Send the pixel values for the cursor 75 | for(int y = 0; y < 16; y++) { 76 | unsigned short bits = TheCrsr[y]; 77 | for(int x = 0; x < 16; x++) { 78 | emitColor(dst, (bits & 0x8000) ? VNCPalette::black : VNCPalette::white); 79 | bits <<= 1; 80 | } 81 | } 82 | // Send the bitmask; note that the Mac paints the cursor differently 83 | // than the VNC server does. On the Mac, the mask indicates which screen 84 | // pixels are erased, then the cursor bitmap is XORed onto the screen. 85 | // Certain cursors, such as the i-beam, have no mask and are meant to 86 | // invert the contents of the screen, but would show up blank on the VNC 87 | // server.To fix this, we combine the mask with the cursor bitmap, which 88 | // forces it to be painted, albeit without the XOR effect. 89 | for(int y = 0; y < 16; y++) { 90 | unsigned short mask = TheCrsr[y + 16] | TheCrsr[y]; 91 | *dst++ = mask >> 8; 92 | *dst++ = mask & 0xFF; 93 | } 94 | 95 | wds->length = dst - fbUpdateBuffer; 96 | wds->ptr = (Ptr) fbUpdateBuffer; 97 | return 0; 98 | } 99 | 100 | void VNCEncodeCursor::adjustCursorVisibility (Boolean allowHiding) { 101 | static Boolean hidden = false; 102 | 103 | if(vncConfig.hideCursor && vncServerActive()) { 104 | // If the user tried to move the mouse, unhide it. 105 | Point mousePosition; 106 | GetMouse(&mousePosition); 107 | if((vncLastMousePosition.h != mousePosition.h) || 108 | (vncLastMousePosition.h != mousePosition.h)) { 109 | allowHiding = false; 110 | } 111 | 112 | if((!hidden) && allowHiding) { 113 | HideCursor(); 114 | hidden = true; 115 | } 116 | } 117 | 118 | if(hidden && !(allowHiding && vncServerActive())) { 119 | ShowCursor(); 120 | hidden = false; 121 | } 122 | } 123 | 124 | void VNCEncodeCursor::idleTask() { 125 | adjustCursorVisibility(true); 126 | } -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncodeHextile.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "VNCServer.h" 19 | #include "VNCPalette.h" 20 | #include "VNCEncodeTiles.h" 21 | #include "VNCEncodeHextile.h" 22 | 23 | #include "DebugLog.h" 24 | 25 | #define UPDATE_BUFFER_SIZE 1040 26 | #define UPDATE_MAX_TILES 7 27 | #define DEBUG_SUBRECTS 0 28 | 29 | #define src32 ((unsigned long*)src) 30 | 31 | unsigned int lastBg, lastFg; 32 | 33 | Size VNCEncodeHextile::minBufferSize() { 34 | return UPDATE_BUFFER_SIZE; 35 | } 36 | 37 | void VNCEncodeHextile::begin() { 38 | lastBg = lastFg = -1; 39 | } 40 | 41 | #if !defined(VNC_FB_MONOCHROME) 42 | #define Raw 1 43 | #define BackgroundSpecified 2 44 | #define ForegroundSpecified 4 45 | #define AnySubrects 8 46 | #define SubrectsColored 16 47 | 48 | struct Subrect { 49 | unsigned char c; 50 | unsigned char x; 51 | unsigned char y; 52 | unsigned char w; 53 | unsigned char b; 54 | 55 | inline unsigned char h() {return b - y - 1;}; 56 | inline void h(unsigned char h) {b = y + h + 1;}; 57 | }; 58 | 59 | inline Boolean mergeTop(Subrect *sRects, const Subrect *lastRect, unsigned char *cRects) { 60 | Subrect *candidate = &sRects[cRects[lastRect->x]]; 61 | // Make this a single return statement so the compiler can inline it! 62 | return ((lastRect->y == candidate->b) && // Can we merge with this rectangle? 63 | (lastRect->c == candidate->c) && 64 | (lastRect->w == candidate->w) && 65 | (lastRect->x == candidate->x) && 66 | (lastRect != sRects) && 67 | // If so, grow the found rectangle 68 | (candidate->b++, true)); 69 | } 70 | 71 | unsigned long VNCEncodeHextile::encodeSolidTile(const EncoderPB &epb) { 72 | const unsigned char mask = ((1 << fbDepth) - 1); 73 | const unsigned char color = epb.src[0] & mask; 74 | unsigned char *dst = epb.dst; 75 | *dst++ = BackgroundSpecified; 76 | setupPIXEL(); 77 | emitColor(dst, color); 78 | return dst - epb.dst; 79 | } 80 | 81 | unsigned long VNCEncodeHextile::encodeTile(const EncoderPB &epb) { 82 | unsigned char *start = epb.dst; 83 | unsigned char *dst = epb.dst; 84 | unsigned char *src = epb.src; 85 | 86 | unsigned char scratchSpace[768 + ALIGN_PAD]; 87 | unsigned char *nativeTile = ALIGN_LONG(scratchSpace); 88 | unsigned char *rleTile = nativeTile + 256; 89 | 90 | setupPIXEL(); 91 | 92 | ColorInfo info; 93 | info.nColors = 256; 94 | info.colorSize = 1; 95 | info.packRuns = false; 96 | const unsigned long nativeLen = screenToNative(epb.src, nativeTile, epb.rows, epb.cols, 0); 97 | const unsigned long len = nativeToRle(nativeTile, nativeTile + nativeLen, rleTile, rleTile + 512, fbDepth, &info); 98 | 99 | struct RLEPair { 100 | unsigned char color; 101 | unsigned char count; 102 | } *rle; 103 | 104 | // Create a list of subrects to cover the tile 105 | 106 | unsigned char histogram[256] = {}; 107 | 108 | Subrect sRects[256]; 109 | Subrect *lastRect = sRects; 110 | rle = (RLEPair*) rleTile; 111 | 112 | unsigned char cRects[16] = {0}; 113 | unsigned short rleCount = rle->count + 1; 114 | unsigned char rleColor = rle->color; 115 | for(int y = 0; y < epb.rows; y++) 116 | for(int x = 0; x < epb.cols; ) { 117 | if((rleCount >= epb.cols) && (x == 0)) { 118 | const unsigned char h = rleCount / epb.cols; 119 | lastRect->c = rleColor; 120 | lastRect->x = 0; 121 | lastRect->y = y; 122 | lastRect->w = epb.cols - 1; 123 | lastRect->h(h - 1); 124 | rleCount -= h * epb.cols; 125 | y += h; 126 | if(y == epb.rows) { 127 | x = epb.cols; // Force inner loop to exit 128 | } 129 | } else { 130 | const unsigned char w = min(rleCount, epb.cols - x); 131 | lastRect->c = rleColor; 132 | lastRect->x = x; 133 | lastRect->y = y; 134 | lastRect->w = w - 1; 135 | lastRect->h(0); 136 | rleCount -= w; 137 | x += w; 138 | } 139 | if (!mergeTop(sRects, lastRect, cRects)) { 140 | cRects[lastRect->x] = lastRect - sRects; // Record subrect in column lookup table 141 | histogram[ rleColor ]++; // Tally color 142 | lastRect++; // Move to next tile 143 | } 144 | // Move to the next RLE element 145 | if (rleCount == 0) { 146 | rle++; 147 | rleColor = rle->color; 148 | rleCount = rle->count + 1; 149 | } 150 | } 151 | 152 | // Generate a histogram of rectangles in the tile 153 | 154 | unsigned char bgColor = 0; 155 | unsigned char bgCount = 0; 156 | unsigned char nColors = 0; 157 | unsigned char fgColor; 158 | for(unsigned int i = 0; i < 256; i++) { 159 | if(histogram[i]) { 160 | if(histogram[i] >= bgCount) { 161 | fgColor = bgColor; 162 | bgColor = i; 163 | bgCount = histogram[i]; 164 | } else { 165 | fgColor = i; 166 | } 167 | nColors++; 168 | } 169 | } 170 | 171 | // Figure out how many rects are non-background 172 | 173 | const unsigned int nRects = lastRect - sRects; 174 | const unsigned int nFgRects = nRects - bgCount; 175 | 176 | // Figure out colors 177 | 178 | if (nColors > 1) { 179 | const unsigned int rawTileLen = 1 + 256 * bytesPerColor; 180 | 181 | // Emit two-colored tiles with subrects 182 | if (nColors == 2) { 183 | const unsigned char emitBgColor = (lastBg != bgColor); 184 | const unsigned char emitFgColor = (lastFg != fgColor); 185 | unsigned long twoColorTileLen = 2 + (emitBgColor + emitFgColor) * bytesPerColor + nFgRects * 2; 186 | if ((twoColorTileLen <= rawTileLen) && (twoColorTileLen <= epb.bytesAvail)) { 187 | *dst++ = AnySubrects; 188 | if(emitBgColor) { 189 | *start |= BackgroundSpecified; 190 | emitColor(dst, bgColor); 191 | lastBg = bgColor; 192 | } 193 | if(emitFgColor) { 194 | *start |= ForegroundSpecified; 195 | emitColor(dst, fgColor); 196 | lastFg = fgColor; 197 | } 198 | *dst++ = nFgRects; 199 | for(int i = 0; i < nRects; i++) { 200 | if(sRects[i].c != bgColor) { 201 | *dst++ = (sRects[i].x << 4) | sRects[i].y; 202 | *dst++ = (sRects[i].w << 4) | sRects[i].h(); 203 | } 204 | } 205 | #if USE_SANITY_CHECKS 206 | if (twoColorTileLen != (dst - start)) { 207 | dprintf("Incorrect tile %d length: %ld != %ld\n", start[0], twoColorTileLen, (dst - start)); 208 | } 209 | #endif 210 | return dst - start; 211 | } 212 | } 213 | 214 | // Emit multi-colored tiles with subrects 215 | else { 216 | const unsigned char emitBgColor = (lastBg != bgColor); 217 | const unsigned long multiColorTileLen = 2 + (emitBgColor * bytesPerColor) + (nFgRects * (2 + bytesPerColor)); 218 | if ((multiColorTileLen <= rawTileLen) && (multiColorTileLen <= epb.bytesAvail)) { 219 | *dst++ = AnySubrects | SubrectsColored; 220 | if(lastBg != bgColor) { 221 | *start |= BackgroundSpecified; 222 | emitColor(dst, bgColor); 223 | lastBg = bgColor; 224 | } 225 | *dst++ = nFgRects; 226 | for(int i = 0; i < nRects; i++) { 227 | if(sRects[i].c != bgColor) { 228 | #if DEBUG_SUBRECTS 229 | emitColor(dst, (i * 7) % (1 << fbDepth)); 230 | #else 231 | emitColor(dst, sRects[i].c); 232 | #endif 233 | *dst++ = (sRects[i].x << 4) | sRects[i].y; 234 | *dst++ = (sRects[i].w << 4) | sRects[i].h(); 235 | } 236 | } 237 | lastFg = -1; 238 | #if USE_SANITY_CHECKS 239 | if (multiColorTileLen != (dst - start)) { 240 | dprintf("Incorrect tile %d length: %ld != %ld\n", start[0], multiColorTileLen, (dst - start)); 241 | } 242 | #endif 243 | return dst - start; 244 | } 245 | } 246 | 247 | if (rawTileLen <= epb.bytesAvail) { 248 | // If we get here, emit a raw tile 249 | *dst++ = Raw; 250 | const Boolean canEmitNativeTileAsRaw = (fbDepth == 8) && (!fbPixFormat.trueColor); 251 | if(canEmitNativeTileAsRaw) { 252 | BlockMove(nativeTile,dst,nativeLen); 253 | dst += nativeLen; 254 | } else { 255 | // Emit a raw tile 256 | src = nativeTile; 257 | // Rewrite the tile with expanded colors 258 | const unsigned char rsft = 32 - fbDepth; 259 | const unsigned long lmask = ((unsigned long)-1) << rsft; // Mask for leftmost color in block 260 | unsigned char bitsLeft = 0; 261 | unsigned long packed; 262 | unsigned short pixels = epb.rows * epb.cols; 263 | do { 264 | if(bitsLeft == 0) { 265 | packed = *src32++; 266 | bitsLeft = 32; 267 | } 268 | emitColor(dst, (packed & lmask) >> rsft); 269 | packed <<= fbDepth; 270 | bitsLeft -= fbDepth; 271 | } while(--pixels); 272 | } 273 | 274 | lastBg = lastFg = -1; 275 | #if USE_SANITY_CHECKS 276 | if (rawTileLen != (dst - start)) { 277 | dprintf("Incorrect tile %d length: %d != %ld\n", start[0], rawTileLen, (dst - start)); 278 | } 279 | #endif 280 | return dst - start; 281 | } 282 | } else { 283 | // Otherwise emit a solid tile 284 | const unsigned short solidTileLen = 1 + ((lastBg == bgColor) ? 0 : bytesPerColor); 285 | if (solidTileLen <= epb.bytesAvail) { 286 | *dst++ = 0; 287 | if(lastBg != bgColor) { 288 | *start = BackgroundSpecified; 289 | emitColor(dst, bgColor); 290 | lastBg = bgColor; 291 | } 292 | #if USE_SANITY_CHECKS 293 | if (solidTileLen != (dst - start)) { 294 | dprintf("Incorrect tile %d length: %d != %ld\n", start[0], solidTileLen, (dst - start)); 295 | } 296 | #endif 297 | return dst - start; 298 | } 299 | } 300 | return 0; 301 | } 302 | #endif 303 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncodeHextile.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "MacTCP.h" 21 | #include "VNCEncoder.h" 22 | 23 | class VNCEncodeHextile { 24 | public: 25 | static Size minBufferSize(); 26 | 27 | static void begin(); 28 | static unsigned long encodeSolidTile(const EncoderPB &epb); 29 | static unsigned long encodeTile(const EncoderPB &epb); 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncodeRAW.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "VNCServer.h" 19 | #include "VNCFrameBuffer.h" 20 | #include "VNCEncodeRAW.h" 21 | 22 | int line; 23 | 24 | Size VNCEncodeRaw::minBufferSize() { 25 | return 0; 26 | } 27 | 28 | void VNCEncodeRaw::begin() { 29 | line = 0; 30 | } 31 | 32 | Boolean VNCEncodeRaw::getChunk(EncoderPB &epb) { 33 | const unsigned char *src = VNCFrameBuffer::getPixelAddr(fbUpdateRect.x, fbUpdateRect.y + line); 34 | BlockMove(src, epb.dst, fbUpdateRect.w); 35 | epb.bytesWritten = fbUpdateRect.w; 36 | return ++line < h; 37 | } 38 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncodeRAW.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "MacTCP.h" 21 | #include "VNCEncoder.h" 22 | 23 | class VNCEncodeRaw { 24 | public: 25 | static Size minBufferSize(); 26 | 27 | static void begin(); 28 | static Boolean getChunk(EncoderPB &epb); 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncodeTRLE.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "MacTCP.h" 21 | #include "VNCEncoder.h" 22 | 23 | asm Boolean getChunkMonochrome(int x, int y, int w, int h, wdsEntry *wdsPtr); 24 | 25 | class VNCEncodeTRLE { 26 | public: 27 | static Size minBufferSize(); 28 | static void begin(); 29 | 30 | static unsigned long encodeSolidTile(const EncoderPB &epb); 31 | static unsigned long encodeTile(const EncoderPB &pb); 32 | }; 33 | 34 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncodeTRLEMono.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "VNCServer.h" 19 | #include "VNCFrameBuffer.h" 20 | #include "VNCEncodeTRLE.h" 21 | 22 | #define DEBUG_SOLID_TILE 0 // Set to one to show solid tiles 23 | #define USE_ENCODER 0 // 0: Assembly; 1: Hybrid; 2: C++ 24 | 25 | #define TileRaw 0 26 | #define TileSolid 1 27 | #define Tile2Color 2 28 | #define TileReuse 127 29 | #define TilePlainRLE 128 30 | 31 | extern int tile_y; 32 | extern unsigned char lastTile; 33 | 34 | /** 35 | * This is a fast version of a B&W tile encoder. On entry: 36 | * 37 | * a0: Points to the source tile on the screen 38 | * a1: Points to the output buffer 39 | * d0: The number of rows in the tile 40 | * 41 | * This function will modify registers a0-a2 and d0-d2 42 | */ 43 | static asm unsigned short _encodeTile(const unsigned char *src:__A0, unsigned char *dst:__A1, unsigned short rows:__D0) { 44 | #define src a0 45 | #define dst a1 46 | #define stride a2 47 | 48 | #define rows d0 49 | #define tmp d1 50 | #define start d2 51 | 52 | #ifndef VNC_BYTES_PER_LINE 53 | movea.w fbStride,stride 54 | suba.w #2,stride 55 | #else 56 | movea.w #(VNC_BYTES_PER_LINE - 2),stride 57 | #endif 58 | move.l dst,start // Make a copy of dst 59 | btst #0,start 60 | bne uStart // Is dst starting on an odd address? 61 | bra aStart 62 | 63 | aStart: 64 | move.b #Tile2Color,tmp 65 | cmp.b lastTile,tmp 66 | beq aReusePalette 67 | aWritePalette: 68 | move.b tmp,lastTile 69 | move.b tmp,(dst)+ // Packed tile type 70 | move.b #00,(dst)+ 71 | move.b #01,(dst)+ 72 | bra uCopyWhitePixels 73 | aReusePalette: 74 | move.b #127,(dst)+ // Packed tile type with reused palette 75 | bra uCopyWhitePixels 76 | 77 | uStart: 78 | move.b #Tile2Color,tmp 79 | cmp.b lastTile,tmp 80 | beq uReusePalette 81 | uWritePalette: 82 | move.b tmp,lastTile 83 | move.b tmp,(dst)+ // Packed tile type 84 | move.w #0001,(dst)+ 85 | bra aCopyWhitePixels 86 | uReusePalette: 87 | move.b #127,(dst)+ // Packed tile type with reused palette 88 | bra aCopyWhitePixels 89 | 90 | // Aligned writes for 68000 91 | aCopyWhitePixels: 92 | clr.b tmp // Clear condition codes 93 | bra aEntry 94 | // Loop and copy white pixels, break on non-white 95 | aCopy1: 96 | move.w (src)+,(dst)+ // Copy two bytes 97 | adda.w stride,src // Move to next row 98 | aEntry: 99 | dbne rows, aCopy1 // ...fall through on non-white pixel 100 | bne aNonWhiteTile 101 | bra uSolidWhiteTile 102 | 103 | // Continue copying pixels, not a all-white tile 104 | aCopy2: 105 | move.w (src)+,(dst)+ // Copy two bytes 106 | adda.w stride,src // Move to next row 107 | aNonWhiteTile: 108 | dbra rows, aCopy2 109 | bra done 110 | 111 | // Unaligned writes for 68000 112 | uCopyWhitePixels: 113 | clr.b tmp // Clear condition codes 114 | bra uEntry 115 | uCopy1: 116 | move.b (src)+,(dst)+ // Copy two bytes 117 | bne uNonWhiteTile1 118 | move.b (src)+,(dst)+ 119 | adda.w stride,src // Move to next row 120 | uEntry: 121 | dbne rows, uCopy1 122 | bne uNonWhiteTile 123 | bra aSolidWhiteTile 124 | 125 | // Continue copying pixels, not a all-white tile 126 | uCopy2: 127 | move.b (src)+,(dst)+ // Copy two bytes 128 | uNonWhiteTile1: 129 | move.b (src)+,(dst)+ 130 | adda.w stride,src // Move to next row 131 | uNonWhiteTile: 132 | dbra rows, uCopy2 133 | 134 | done: 135 | // Copy number of bytes written to dst to return value 136 | suba.l start,dst 137 | move.l dst,d0 138 | rts 139 | 140 | aSolidWhiteTile: 141 | move.b #TileSolid,lastTile 142 | // Rewrite tile as solid 143 | movea.l start,dst 144 | move.w #(TileSolid<<8)+DEBUG_SOLID_TILE,(dst)+ 145 | moveq #2,d0 146 | rts 147 | 148 | uSolidWhiteTile: 149 | moveq #TileSolid,tmp 150 | move.b tmp,lastTile 151 | // Rewrite tile as solid 152 | movea.l start,dst 153 | move.b tmp,(dst)+ 154 | move.b #DEBUG_SOLID_TILE,(dst)+ 155 | moveq #2,d0 156 | rts 157 | 158 | #undef src 159 | #undef dst 160 | #undef stride 161 | #undef start 162 | #undef rows 163 | } 164 | 165 | #if USE_ENCODER == 0 166 | asm Boolean getChunkMonochrome(int x, int y, int w, int h, wdsEntry *wdsPtr) { 167 | #define xArg 8(a6) 168 | #define yArg 10(a6) 169 | #define wArg 12(a6) 170 | #define hArg 14(a6) 171 | #define wdsArg 16(a6) 172 | 173 | #define tmp d1 174 | #define tiles d3 175 | #define rows d4 176 | 177 | #define src a3 178 | #define dst a4 179 | #define wds a3 180 | 181 | link a6,#0000 // Link for debugger 182 | movem.l d3-d4/a2-a4,-(a7) // Save registers 183 | 184 | movea.l fbUpdateBuffer,dst 185 | 186 | // Compute the source location 187 | // src = vncBits.baseAddr + width/8 * (tile_y + y) + x/8 188 | lea vncBits,src 189 | move.l struct(BitMap.baseAddr)(src),src 190 | // Add width/8 * (tile_y + y) 191 | move.w yArg,tmp 192 | add.w tile_y,tmp 193 | #if VNC_FB_WIDTH == 512 194 | lsl.w #6,tmp 195 | ext.l tmp 196 | #else 197 | #if !defined(VNC_BYTES_PER_LINE) 198 | mulu fbStride,tmp 199 | #else 200 | mulu #VNC_BYTES_PER_LINE,tmp 201 | #endif 202 | #endif 203 | adda.l tmp,src 204 | // Add x/8 205 | move.w xArg,tmp 206 | lsr.w #3,tmp 207 | ext.l tmp 208 | adda.l tmp,src 209 | 210 | // Compute tiles: 211 | // tiles = w/16 212 | move.w wArg,tiles 213 | lsr.w #4,tiles 214 | 215 | // Figure out rows 216 | // rows = min(16, h - tile_y) 217 | move.w hArg,rows 218 | sub.w tile_y,rows 219 | moveq #16,tmp 220 | cmp.w tmp,rows 221 | blt tileEntry 222 | move.w tmp,rows 223 | bra tileEntry 224 | tileLoop: 225 | movea.l src,a0 226 | movea.l dst,a1 227 | move.w rows,d0 228 | jsr _encodeTile 229 | 230 | adda.w d0,dst 231 | addq.w #2,src 232 | tileEntry: 233 | dbra tiles,tileLoop 234 | 235 | // Figure out the length of the data 236 | suba.l fbUpdateBuffer,dst 237 | // Write out the wds entry 238 | movea.l wdsArg,wds 239 | move.l fbUpdateBuffer, struct(wdsEntry.ptr)(wds) 240 | move.w dst, struct(wdsEntry.length)(wds) 241 | 242 | // Prepare for the next row 243 | addi.w #16,tile_y 244 | move.w hArg,d0 245 | cmp.w tile_y,d0 246 | sgt d0 247 | 248 | movem.l (a7)+,d3-d4/a2-a4 // Save registers 249 | unlk a6 250 | rts 251 | 252 | #undef xArg 253 | #undef yArg 254 | #undef wArg 255 | #undef hArg 256 | #undef wdsArg 257 | 258 | #undef tmp 259 | #undef tiles 260 | #undef rows 261 | 262 | #undef src 263 | #undef dst 264 | #undef wds 265 | } 266 | #elif USE_ENCODER == 1 267 | /** 268 | * With "src" pointing to the first byte of a 16x16 tile on the screen, this function will write 269 | * "rows" as a two-color or solid tile and return the number of bytes written. 270 | */ 271 | static asm unsigned short encodeTile(const unsigned char *src:__A0, unsigned char *dst:__A1, unsigned short rows:__D0) { 272 | link a6,#0000 // Link for debugger 273 | movem.l a2,-(a7) // Save registers 274 | jsr _encodeTile 275 | movem.l (a7)+,a2 // Restore registers 276 | unlk a6 277 | rts 278 | } 279 | 280 | Boolean GET_CHUNK(int x, int y, int w, int h, wdsEntry *wds); 281 | 282 | Boolean GET_CHUNK(int x, int y, int w, int h, wdsEntry *wds) { 283 | const char rows = min(16, h - tile_y); 284 | unsigned char *dst = fbUpdateBuffer; 285 | unsigned char *src = VNCFrameBuffer::getPixelAddr(x, y + tile_y); 286 | unsigned char tiles = w/16; 287 | while(tiles--) { 288 | dst += encodeTile(src, dst, rows); 289 | src += 2; 290 | } 291 | 292 | wds->length = dst - fbUpdateBuffer; 293 | wds->ptr = (Ptr) fbUpdateBuffer; 294 | 295 | // Prepare for the next row 296 | tile_y += 16; 297 | 298 | return tile_y < h; 299 | } 300 | #else 301 | // C++ Reference Encoder 302 | 303 | #define TILE_LINE(ROW) if(rows == ROW) goto done; \ 304 | *dst++ = src[0 + ROW * VNC_BYTES_PER_LINE]; \ 305 | *dst++ = src[1 + ROW * VNC_BYTES_PER_LINE]; 306 | 307 | unsigned short encodeTile(const unsigned char *src, unsigned char *dst, unsigned short rows); 308 | 309 | unsigned short encodeTile(const unsigned char *src, unsigned char *dst, unsigned short rows) { 310 | unsigned char *start = dst; 311 | 312 | if(tile_y && dst != fbUpdateBuffer) { 313 | // Packed pallete type with pallete reused from previous tile 314 | *dst++ = 127; 315 | } else { 316 | // Packed pallete type with palleteSize = 2 317 | *dst++ = 2; // Packed pallete type 318 | *dst++ = 0; // Black CPIXEL 319 | *dst++ = 1; // White CPIXEL 320 | } 321 | 322 | // Encode the packed data for a 16x16 tile 323 | TILE_LINE(0); 324 | TILE_LINE(1); 325 | TILE_LINE(2); 326 | TILE_LINE(3); 327 | TILE_LINE(4); 328 | TILE_LINE(5); 329 | TILE_LINE(6); 330 | TILE_LINE(7); 331 | TILE_LINE(8); 332 | TILE_LINE(9); 333 | TILE_LINE(10); 334 | TILE_LINE(11); 335 | TILE_LINE(12); 336 | TILE_LINE(13); 337 | TILE_LINE(14); 338 | TILE_LINE(15); 339 | done: 340 | 341 | return dst - start; 342 | } 343 | 344 | Boolean VNCEncodeTRLE::getChunk(int x, int y, int w, int h, wdsEntry *wds) { 345 | const char rows = min(16, h - tile_y); 346 | unsigned char *dst = fbUpdateBuffer; 347 | unsigned char *src = VNCFrameBuffer::getPixelAddr(x, y + tile_y); 348 | unsigned char tiles = w/16; 349 | while(tiles--) { 350 | dst += encodeTile(src, dst, rows); 351 | src += 2; 352 | } 353 | 354 | wds->length = dst - fbUpdateBuffer; 355 | wds->ptr = (Ptr) fbUpdateBuffer; 356 | 357 | // Prepare for the next row 358 | tile_y += 16; 359 | 360 | return tile_y < h; 361 | } 362 | #endif -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncodeTight.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "VNCServer.h" 19 | #include "VNCPalette.h" 20 | #include "VNCFrameBuffer.h" 21 | #include "VNCEncodeTight.h" 22 | 23 | 24 | #define ROL(A,B) ((A << B) | (A >> (sizeof(A)*8 - B))) 25 | #define ROR(A,B) ((A >> B) | (A << (sizeof(A)*8 - B))) 26 | #define src16 ((unsigned short*)src) 27 | #define dst16 ((unsigned short*)dst) 28 | #define src32 ((unsigned long*)src) 29 | 30 | extern int tile_x, tile_y; 31 | 32 | Size VNCEncodeTight::minBufferSize() { 33 | return 0; 34 | } 35 | 36 | void VNCEncodeTight::begin() { 37 | tile_x = tile_y = 0; 38 | } 39 | 40 | #define src32 ((unsigned long*)src) 41 | 42 | Boolean VNCEncodeTight::getChunk(wdsEntry *wds) { 43 | #ifdef VNC_FB_BITS_PER_PIX 44 | const unsigned char fbDepth = VNC_FB_BITS_PER_PIX; 45 | #endif 46 | #ifdef VNC_BYTES_PER_LINE 47 | const unsigned long fbStride = VNC_BYTES_PER_LINE; 48 | #endif 49 | 50 | const int stripeWidth = 32; 51 | const int longsPerRow = stripeWidth * fbDepth / 8 / sizeof(unsigned long); 52 | 53 | const int tile_top = tile_y; 54 | 55 | const unsigned char numPix = sizeof(unsigned long) * 8 / fbDepth; 56 | const unsigned long rmask = (1 << fbDepth) - 1; // Mask for rightmost color in block 57 | 58 | const unsigned char *src = VNCFrameBuffer::getPixelAddr(fbUpdateRect.x + tile_x, fbUpdateRect.y + tile_y); 59 | unsigned long colors = *src32; 60 | unsigned char lastColor = ROL(colors,fbDepth) & rmask; 61 | 62 | unsigned char cMap[256] = {0}; 63 | unsigned char cPal[256] = {lastColor}; 64 | unsigned char cIndx = 0; 65 | unsigned char extraColors = 0; // Count of colors - 1 66 | 67 | unsigned char consecutive_rows = 0; 68 | unsigned char row_1st_cidx = lastColor; 69 | unsigned char row_2nd_cidx = lastColor; 70 | 71 | const unsigned char* row_src = src; 72 | const unsigned char* row_end = src + longsPerRow * sizeof(unsigned long); 73 | 74 | restartRow: 75 | unsigned short outBits = 1; 76 | unsigned char *dst = fbUpdateBuffer; 77 | Boolean firstRowPixel = true; 78 | 79 | src = row_src; 80 | 81 | for(;;) { 82 | colors = *src32++; 83 | 84 | unsigned char n = numPix - 1; 85 | do { 86 | // Extract left-most color value 87 | colors = ROL(colors, fbDepth); 88 | const unsigned char color = colors & rmask; 89 | 90 | // Process the color 91 | if (color != lastColor) { 92 | lastColor = color; 93 | 94 | // Perform color mapping 95 | cIndx = cMap[color]; 96 | if ((cIndx == 0) && (color != cPal[0])) { 97 | // Add new color to color table 98 | cIndx = ++extraColors; 99 | cMap[color] = cIndx; 100 | cPal[cIndx] = color; 101 | 102 | // If we have a color we have not seen before... 103 | if (extraColors < 3) { 104 | if (tile_y != tile_top) { 105 | // ...emit previous rows as a solid or two-color tile? 106 | goto emitTile; 107 | } else { 108 | // Re-emit the row 109 | goto restartRow; 110 | } 111 | } 112 | } 113 | 114 | // Keep tally of consecutive solid rows 115 | if (consecutive_rows && (cIndx != row_1st_cidx) && (cIndx != row_2nd_cidx)) { 116 | if (row_1st_cidx == row_2nd_cidx) { 117 | row_1st_cidx = cIndx; 118 | } else { 119 | consecutive_rows = 0; 120 | } 121 | } 122 | } 123 | 124 | if (firstRowPixel) { 125 | firstRowPixel = false; 126 | // Write out the row of pixels 127 | if (consecutive_rows++ == 0) { 128 | row_1st_cidx = cIndx; 129 | row_2nd_cidx = cIndx; 130 | } 131 | } 132 | 133 | /* If we have a solid tile, don't write out anything 134 | ...if we are a two-color tile, write out a bit per color 135 | ...otherwise write out a full byte per color. 136 | */ 137 | if (extraColors != 0) { 138 | if (extraColors == 1) { 139 | // Write out colors as bits 140 | outBits = (outBits << 1) | cIndx; 141 | if (outBits & 0x10) { 142 | *dst++ = outBits; 143 | outBits = 1; 144 | } 145 | } else { 146 | // Write out indices as bytes 147 | *dst++ = cIndx; 148 | } 149 | } 150 | } while (--n != -1); 151 | 152 | #if SANITY_CHECK 153 | if (outBits != 1) { 154 | dprintf("Stripe width not a multiple of 8 pixels\n"); 155 | } 156 | #endif 157 | 158 | if (src == row_end) { 159 | // Move to the next row 160 | row_src += fbStride; 161 | row_end += fbStride; 162 | src = row_src; 163 | if (++tile_y == fbUpdateRect.h) { 164 | break; 165 | } 166 | firstRowPixel = true; 167 | } 168 | } // for(;;) 169 | 170 | emitTile: 171 | const size_t pixelDataLen = dst - fbUpdateBuffer; 172 | 173 | if (extraColors == 0) { 174 | *dst++ = 0x80; // Fill compression 175 | *dst++ = 255; // Red 176 | *dst++ = 255; // Green 177 | *dst++ = 255; // Blue 178 | return 4; 179 | } else { 180 | // Compute the compact data length represenation 181 | unsigned char lenData[4], lenSize = 0; 182 | for (size_t remainder = pixelDataLen; remainder; remainder >>= 7) { 183 | lenData[lenSize++] = remainder & 0x7F; 184 | } 185 | 186 | // Make space for the header 187 | const size_t headerSize = 3 + 3 * (extraColors + 1) + lenSize + pixelDataLen; 188 | BlockMove (fbUpdateBuffer, fbUpdateBuffer + headerSize, pixelDataLen); 189 | 190 | // Write out the header 191 | dst = fbUpdateBuffer; 192 | *dst++ = 0x40; // Basic compression 193 | *dst++ = 1; // PaletteFilter 194 | *dst++ = extraColors; // Number of colors minus 1 195 | for (int i = 0; i <= extraColors; i++) { 196 | emitColor (dst, i); 197 | } 198 | BlockMove (lenData, dst, lenSize); 199 | } 200 | 201 | // Prepare to advance to the next tile 202 | if (tile_y == fbUpdateRect.h) { 203 | tile_y = 0; 204 | tile_x += stripeWidth; 205 | } 206 | return tile_x >= fbUpdateRect.h; 207 | } 208 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncodeTight.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "MacTCP.h" 21 | #include "VNCEncoder.h" 22 | 23 | class VNCEncodeTight { 24 | public: 25 | static Size minBufferSize(); 26 | static void begin(); 27 | 28 | static Boolean getChunk(wdsEntry *wds); 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncodeTiles.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #define USE_ASM_CODE 1 21 | 22 | struct ColorInfo { 23 | unsigned char colorPal[127]; 24 | unsigned char colorMap[256]; 25 | unsigned int runsOfOne; 26 | unsigned int nColors; 27 | unsigned char colorSize; 28 | unsigned char packRuns; 29 | }; 30 | 31 | unsigned short screenToNative(const unsigned char *src, unsigned char *dst, short rows, short cols, ColorInfo *colorInfo); 32 | unsigned short nativeToRle(const unsigned char *src, unsigned char *end, unsigned char *dst, const unsigned char *stop, unsigned char depth, ColorInfo *cInfo); 33 | unsigned short nativeToPacked(const unsigned char *src, unsigned char *dst, const unsigned char* end, const char inDepth, const char outDepth, ColorInfo *colorInfo); 34 | unsigned short nativeToColors(const unsigned char *start, unsigned char *end, ColorInfo *colorInfo); 35 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncodeZRLE.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "VNCEncoder.h" 19 | #include "VNCEncodeTRLE.h" 20 | #include "VNCEncodeZRLE.h" 21 | 22 | #if !defined(VNC_FB_MONOCHROME) 23 | #if VNC_COMPRESSION_LEVEL < 2 24 | #define UPDATE_BUFFER_SIZE 16L*1024 25 | #else 26 | #define UPDATE_BUFFER_SIZE 10L*1024 27 | #endif 28 | 29 | Size VNCEncodeZRLE::minBufferSize() { 30 | return UPDATE_BUFFER_SIZE; 31 | } 32 | #endif -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncodeZRLE.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "MacTCP.h" 21 | #include "VNCEncoder.h" 22 | 23 | class VNCEncodeZRLE { 24 | public: 25 | static Size minBufferSize(); 26 | }; 27 | 28 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncoder.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "MacTCP.h" 21 | #include "VNCFrameBuffer.h" 22 | 23 | enum { 24 | EncoderDefer = 0, 25 | EncoderReady = 1, 26 | EncoderError = -1 27 | }; 28 | 29 | struct EncoderPB { 30 | unsigned int rows, cols; 31 | unsigned char *src; 32 | unsigned char *dst; 33 | unsigned long bytesAvail; 34 | unsigned long bytesWritten; 35 | }; 36 | 37 | class VNCEncoder { 38 | public: 39 | static OSErr setup(); 40 | static OSErr destroy(); 41 | static OSErr freeMemory(); 42 | 43 | static void clear(); 44 | static int begin(); 45 | static void clientEncoding(unsigned long encoding, Boolean hasMore); 46 | static unsigned long getEncoding(); 47 | static char *getEncoderName(unsigned long encoding); 48 | static Boolean getUncompressedChunk(EncoderPB &epb); 49 | static Boolean getChunk(wdsEntry *wds); 50 | static OSErr fbSyncTasks(); 51 | 52 | static int encoderSetup(); 53 | 54 | static OSErr compressSetup(); 55 | static void compressBegin(); 56 | static void compressReset(); 57 | static void compressDestroy(); 58 | 59 | static unsigned int numOfSubrects(); 60 | static void getSubrect(VNCRect *rect); 61 | static Boolean isNewSubrect(); 62 | static Boolean encoderNeedsZLib(); 63 | 64 | static Boolean getCompressedChunk(EncoderPB &epb); 65 | static Boolean getCompressedChunk(wdsEntry *wds); 66 | }; 67 | 68 | extern unsigned char selectedEncoder; 69 | extern unsigned char *fbUpdateBuffer; 70 | 71 | #define ALIGN_PAD 3 72 | #define ALIGN_LONG(PTR) (PTR) + (sizeof(unsigned long) - (unsigned long)(PTR) % sizeof(unsigned long)) 73 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCEncoderZLib.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "GestaltUtils.h" 19 | 20 | #include "VNCTypes.h" 21 | #include "VNCServer.h" 22 | #include "VNCEncoder.h" 23 | #include "DebugLog.h" 24 | 25 | #define MINIZ_NO_ARCHIVE_APIS 26 | #define MINIZ_NO_ARCHIVE_WRITING_APIS 27 | #define MINIZ_NO_TIME 28 | #define MINIZ_NO_ZLIB_APIS 29 | #define MINIZ_NO_MALLOC 30 | #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 31 | #define MINIZ_LITTLE_ENDIAN 0 32 | #define MINIZ_HAS_64BIT_REGISTERS 0 33 | #define MINIZ_HAS_64BIT_INTEGERS 0 34 | 35 | #include "miniz.h" 36 | 37 | // tdefl_compressor contains all the state needed by the low-level compressor so it's a pretty big struct (~300k). 38 | // This example makes it a global vs. putting it on the stack, of course in real-world usage you'll probably malloc() or new it. 39 | static tdefl_compressor *g_deflator = 0; 40 | 41 | #if !USE_IN_PLACE_COMPRESSION 42 | // COMP_OUT_BUF_SIZE is the size of the output buffer used during compression. 43 | // COMP_OUT_BUF_SIZE must be >= 1 44 | #define COMP_OUT_BUF_SIZE (50l*1024) 45 | static unsigned char *s_outbuf = 0; 46 | #endif 47 | 48 | OSErr VNCEncoder::compressSetup() { 49 | // Make sure the compression buffer is allocated 50 | if (g_deflator == NULL) { 51 | g_deflator = (tdefl_compressor*)NewPtr(sizeof(tdefl_compressor)); 52 | dprintf("Reserved %ld bytes for ZLib compressor object\n", sizeof(tdefl_compressor)); 53 | if (MemError() != noErr) { 54 | dprintf("Failed to allocate compressor\n"); 55 | return MemError(); 56 | } 57 | compressReset(); 58 | vncFlags.zLibLoaded = true; 59 | } 60 | 61 | // Make sure the compression objects are allocated 62 | #if !USE_IN_PLACE_COMPRESSION 63 | if (s_outbuf == NULL) { 64 | dprintf("Reserved %ld bytes for ZLib output buffer\n", COMP_OUT_BUF_SIZE); 65 | s_outbuf = (unsigned char*)NewPtr(COMP_OUT_BUF_SIZE); 66 | if (MemError() != noErr) { 67 | dprintf("Failed to allocate output buffer\n"); 68 | return MemError(); 69 | } 70 | } 71 | #endif 72 | 73 | // Make sure the "ANSI Libraries" segment is loaded 74 | strlen(""); 75 | 76 | return noErr; 77 | } 78 | 79 | void VNCEncoder::compressDestroy() { 80 | DisposePtr((Ptr)g_deflator); 81 | #if !USE_IN_PLACE_COMPRESSION 82 | DisposePtr((Ptr)s_outbuf); 83 | #endif 84 | g_deflator = NULL; 85 | #if !USE_IN_PLACE_COMPRESSION 86 | s_outbuf = NULL; 87 | #endif 88 | vncFlags.zLibLoaded = false; 89 | } 90 | 91 | void VNCEncoder::compressReset() { 92 | if (g_deflator) { 93 | const int level = vncConfig.zLibLevel; 94 | 95 | // The number of dictionary probes to use at each compression level (0-10). 0=implies fastest/minimal possible probing. 96 | const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; 97 | 98 | // create tdefl() compatible flags (we have to compose the low-level flags ourselves, or use tdefl_create_comp_flags_from_zip_params() but that means MINIZ_NO_ZLIB_APIS can't be defined). 99 | mz_uint comp_flags = TDEFL_WRITE_ZLIB_HEADER | 100 | s_tdefl_num_probes[MZ_MIN(10, level)] | 101 | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); 102 | if (level == 0) { 103 | comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; 104 | } 105 | 106 | // Initialize the low-level compressor. 107 | dprintf("Initializing ZLib at compression level %d [ResEdit]\n", level); 108 | tdefl_status status = tdefl_init(g_deflator, NULL, NULL, comp_flags); 109 | if (status != TDEFL_STATUS_OKAY) { 110 | dprintf("tdefl_init() failed!\n"); 111 | return; 112 | } 113 | } 114 | } 115 | 116 | 117 | #if USE_IN_PLACE_COMPRESSION 118 | Boolean VNCEncoder::getCompressedChunk(EncoderPB &epb) { 119 | // Write the uncompressed data slightly ahead of the 120 | // compressed data, to leave room for zLib to work: 121 | 122 | const unsigned long zLibScratchSpace = 1024; 123 | 124 | // Compress the data 125 | unsigned char *max = epb.dst + epb.bytesAvail; 126 | unsigned char *next_out = epb.dst + sizeof(unsigned long); // Leave space for the zLib length 127 | unsigned char *next_in; 128 | 129 | size_t avail_out; 130 | size_t avail_in = 0; 131 | size_t total_in = 0; 132 | size_t total_out = 0; 133 | Boolean gotMoreAfterwards = true; 134 | Boolean gotMore = true; 135 | 136 | // Compression. 137 | for (;;) { 138 | // ZLib compressed all previous tile data, so get more to compress 139 | if (gotMore && (avail_in == 0)) { 140 | next_in = next_out + zLibScratchSpace; 141 | if (next_in >= max) { 142 | dprintf("Temp buffer insufficient for uncompressed data. Aborting!\n"); 143 | break; 144 | } 145 | 146 | EncoderPB epb2 = epb; 147 | epb2.dst = next_in; 148 | epb2.bytesAvail = max - next_in; 149 | 150 | gotMoreAfterwards = VNCEncoder::getUncompressedChunk(epb2); 151 | gotMore = gotMoreAfterwards && !VNCEncoder::isNewSubrect(); 152 | 153 | avail_in = epb2.bytesWritten; 154 | avail_out = next_in - next_out; 155 | } 156 | 157 | // Compress as much of the input as possible (or all of it) to the output buffer. 158 | 159 | size_t in_bytes = avail_in; 160 | size_t out_bytes = avail_out; 161 | tdefl_status status = tdefl_compress(g_deflator, next_in, &in_bytes, next_out, &out_bytes, gotMore ? TDEFL_NO_FLUSH : TDEFL_SYNC_FLUSH); 162 | 163 | next_in += in_bytes; 164 | avail_in -= in_bytes; 165 | total_in += in_bytes; 166 | 167 | next_out += out_bytes; 168 | avail_out -= out_bytes; 169 | total_out += out_bytes; 170 | 171 | if ((status == TDEFL_STATUS_OKAY) && (avail_out != 0) && !gotMore ) { 172 | // Compression completed successfully. 173 | #if LOG_COMPRESSION_STATS 174 | dprintf("Deflated %ld bytes to %ld (%ld%%)\n", total_in, total_out, (total_out * 100) / total_in); 175 | #endif 176 | break; 177 | } 178 | else if (status != TDEFL_STATUS_OKAY) { 179 | // Compression somehow failed. 180 | dprintf("tdefl_compress() failed with status %d!\n", status); 181 | break; 182 | } 183 | 184 | /* Because we are compressing in-place, adjust avail_out to be the 185 | * gap between where the last compressed data was written, and 186 | * the start of the uncompressed data. 187 | */ 188 | avail_out = next_in - next_out; 189 | 190 | if (avail_out == 0) { 191 | // Try to move the remaining uncompressed data to the end of 192 | // the buffer to make room for further compression 193 | unsigned char* copy_to = max - avail_in; 194 | if (copy_to <= next_in) { 195 | dprintf("Output buffer insufficient for compressed stream. Aborting!\n"); 196 | break; 197 | } 198 | if (avail_in) { 199 | dprintf("Moved %ld bytes of data to free up %ld bytes of space in compression buffer!\n", avail_in, copy_to - next_out); 200 | BlockMove((Ptr)next_in, (Ptr)copy_to, avail_in); 201 | } 202 | next_in = copy_to; 203 | avail_out = next_in - next_out; 204 | } 205 | } 206 | 207 | // Write the length byte 208 | *((unsigned long*)epb.dst) = total_out; 209 | 210 | // Send the data 211 | if(total_out > 0xFFFF) { 212 | dprintf("too much data to send!\n"); 213 | } else { 214 | epb.bytesWritten = total_out + sizeof(unsigned long); 215 | } 216 | return gotMoreAfterwards; 217 | } 218 | #else 219 | Boolean VNCEncoder::getCompressedChunk(wdsEntry *wds) { 220 | // Compress the data 221 | unsigned char *next_in; 222 | unsigned char *next_out = s_outbuf; 223 | 224 | next_out += sizeof(unsigned long); // Leave space for the zLib length 225 | 226 | size_t avail_out = COMP_OUT_BUF_SIZE; 227 | size_t avail_in = 0; 228 | size_t total_in = 0; 229 | size_t total_out = 0; 230 | Boolean gotMoreAfterwards = true; 231 | Boolean gotMore = true; 232 | 233 | // Compression. 234 | for (;;) { 235 | if (!avail_in && gotMore) { 236 | EncoderPB epb; 237 | epb.dst = fbUpdateBuffer; 238 | epb.bytesAvail = fbUpdateBufferSize; 239 | gotMoreAfterwards = getUncompressedChunk(epb); 240 | gotMore = gotMoreAfterwards && !VNCEncoder::isNewSubrect(); 241 | avail_in = epb.bytesWritten; 242 | next_in = fbUpdateBuffer; 243 | } 244 | 245 | // Compress as much of the input as possible (or all of it) to the output buffer. 246 | 247 | size_t in_bytes = avail_in; 248 | size_t out_bytes = avail_out; 249 | tdefl_status status = tdefl_compress(g_deflator, next_in, &in_bytes, next_out, &out_bytes, gotMore ? TDEFL_NO_FLUSH : TDEFL_SYNC_FLUSH); 250 | 251 | next_in += in_bytes; 252 | avail_in -= in_bytes; 253 | total_in += in_bytes; 254 | 255 | next_out += out_bytes; 256 | avail_out -= out_bytes; 257 | total_out += out_bytes; 258 | 259 | if (avail_out == 0) { 260 | dprintf("Output buffer full!\n"); 261 | break; 262 | } 263 | 264 | if ((status == TDEFL_STATUS_OKAY) && !gotMore) { 265 | // Compression completed successfully. 266 | #if LOG_COMPRESSION_STATS 267 | dprintf("Deflated %ld bytes to %ld (%ld%%).\n", total_in, total_out, 100L - (total_out * 100) / total_in); 268 | #endif 269 | break; 270 | } 271 | else if (status != TDEFL_STATUS_OKAY) { 272 | // Compression somehow failed. 273 | dprintf("tdefl_compress() failed with status %d!\n", status); 274 | break; 275 | } 276 | } 277 | 278 | // Write the length byte 279 | unsigned long *header = (unsigned long*)s_outbuf; 280 | *header = total_out; 281 | 282 | // Send the data 283 | if(total_out > 0xFFFF) { 284 | dprintf("too much data to send!\n"); 285 | } else { 286 | wds->length = total_out + sizeof(unsigned long); 287 | wds->ptr = (Ptr) s_outbuf; 288 | } 289 | return gotMoreAfterwards; 290 | } 291 | #endif 292 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCFrameBuffer.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "GestaltUtils.h" 19 | #include "DialogUtils.h" 20 | 21 | #include "VNCServer.h" 22 | #include "VNCPalette.h" 23 | #include "VNCFrameBuffer.h" 24 | 25 | const unsigned long &ScrnBase = *(unsigned long*) 0x824; 26 | 27 | BitMap vncBits = {0}; 28 | 29 | #ifndef VNC_FB_WIDTH 30 | unsigned int fbStride; 31 | unsigned int fbWidth; 32 | unsigned int fbHeight; 33 | #endif 34 | #ifndef VNC_FB_BITS_PER_PIX 35 | unsigned long fbDepth; 36 | #endif 37 | 38 | OSErr VNCFrameBuffer::setup() { 39 | if (checkScreenResolution()) { 40 | vncBits.baseAddr = (Ptr) ScrnBase; 41 | } 42 | #if defined(VNC_FB_MONOCHROME) 43 | else { 44 | #ifdef VNC_FB_WIDTH 45 | const unsigned int fbWidth = VNC_FB_WIDTH; 46 | #endif 47 | #ifdef VNC_FB_HEIGHT 48 | const unsigned int fbHeight = VNC_FB_HEIGHT; 49 | #endif 50 | // We are on a color Mac, create a virtual B&W map 51 | vncBits.rowBytes = fbWidth/8; 52 | vncBits.baseAddr = NewPtr((unsigned long)fbWidth/8 * fbHeight); 53 | SetRect(&vncBits.bounds, 0, 0, fbWidth, fbHeight); 54 | OSErr err = MemError(); 55 | if (err != noErr) 56 | return err; 57 | } 58 | #endif 59 | 60 | // Create the color palette 61 | 62 | OSErr err = VNCPalette::setup(); 63 | if (err != noErr) 64 | return err; 65 | 66 | idleTask(); 67 | return noErr; 68 | } 69 | 70 | OSErr VNCFrameBuffer::destroy() { 71 | if(vncBits.baseAddr && vncBits.baseAddr != (Ptr) ScrnBase) { 72 | DisposePtr((Ptr)vncBits.baseAddr); 73 | vncBits.baseAddr = 0; 74 | } 75 | VNCPalette::destroy(); 76 | return noErr; 77 | } 78 | 79 | Boolean VNCFrameBuffer::checkScreenResolution() { 80 | // Assume a monochrome screen 81 | 82 | int gdWidth = qd.screenBits.bounds.right; 83 | int gdHeight = qd.screenBits.bounds.bottom; 84 | int gdDepth = 1; 85 | int gdStride = gdWidth/8; 86 | 87 | // Update values if this machine has Color QuickDraw 88 | 89 | if(HasColorQD()) { 90 | GDPtr gdp = *GetMainDevice(); 91 | PixMapPtr gpx = *(gdp->gdPMap); 92 | 93 | gdWidth = gdp->gdRect.right; 94 | gdHeight = gdp->gdRect.bottom; 95 | gdDepth = gpx->pixelSize; 96 | gdStride = gpx->rowBytes & 0x3FFF; 97 | } 98 | 99 | #if defined(VNC_FB_WIDTH) && defined(VNC_FB_HEIGHT) && defined(VNC_FB_BITS_PER_PIX) 100 | Boolean isMatch = gdWidth == VNC_FB_WIDTH && gdHeight == VNC_FB_HEIGHT && gdDepth == VNC_FB_BITS_PER_PIX; 101 | if (!isMatch) { 102 | ShowAlert('ERR', 128, "This build of Mini VNC will only work at %d x %d with %d colors.", VNC_FB_WIDTH, VNC_FB_HEIGHT, VNC_FB_PALETTE_SIZE); 103 | } 104 | #elif defined(VNC_FB_BITS_PER_PIX) 105 | Boolean isMatch = gdDepth == VNC_FB_BITS_PER_PIX; 106 | if (!isMatch) { 107 | ShowAlert('ERR', 128, "This build of Mini VNC will only work with %d colors.", VNC_FB_PALETTE_SIZE); 108 | } 109 | #else 110 | Boolean isMatch = (gdDepth == 1) || (gdDepth == 2) || (gdDepth == 4) || (gdDepth == 8); 111 | if (!isMatch) { 112 | ShowAlert('ERR', 128, "Please set your monitor to Black & White, 4, 16 or 256 grays or colors."); 113 | } 114 | #endif 115 | 116 | // Update the constants 117 | #ifndef VNC_FB_WIDTH 118 | fbWidth = gdWidth; 119 | fbHeight = gdHeight; 120 | fbStride = gdStride; 121 | #endif 122 | #ifndef VNC_FB_BITS_PER_PIX 123 | fbDepth = gdDepth; 124 | #endif 125 | 126 | return isMatch; 127 | } 128 | 129 | void VNCFrameBuffer::idleTask() { 130 | #if defined(VNC_FB_MONOCHROME) 131 | if (vncBits.baseAddr && (vncBits.baseAddr != (Ptr) ScrnBase)) { 132 | // We are on a color Mac, do a dithered copy 133 | CopyBits(&qd.screenBits, &vncBits, &vncBits.bounds, &vncBits.bounds, srcCopy, NULL); 134 | } 135 | #endif 136 | } 137 | 138 | unsigned char *VNCFrameBuffer::getBaseAddr() { 139 | return (unsigned char*) vncBits.baseAddr; 140 | } -------------------------------------------------------------------------------- /mac-cpp-source/VNCFrameBuffer.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "VNCConfig.h" 21 | #include "VNCTypes.h" 22 | 23 | #ifndef VNC_FB_WIDTH 24 | extern unsigned int fbStride; 25 | extern unsigned int fbWidth; 26 | extern unsigned int fbHeight; 27 | #endif 28 | #ifndef VNC_FB_BITS_PER_PIX 29 | extern unsigned long fbDepth; 30 | #endif 31 | 32 | 33 | extern BitMap vncBits; 34 | 35 | class VNCFrameBuffer { 36 | public: 37 | static OSErr setup(); 38 | static OSErr destroy(); 39 | static void idleTask(); 40 | static void fill(); 41 | static unsigned char *getBaseAddr(); 42 | static Boolean checkScreenResolution(); 43 | static Boolean hasColorQuickdraw(); 44 | 45 | static unsigned char *getPixelAddr(unsigned int x, unsigned int y) { 46 | #if !defined(VNC_BYTES_PER_LINE) && !defined(VNC_FB_BITS_PER_PIX) 47 | return getBaseAddr() + (unsigned long)fbStride * y + x * fbDepth / 8; 48 | #elif !defined(VNC_BYTES_PER_LINE) 49 | return getBaseAddr() + (unsigned long)fbStride * y + x/VNC_FB_PIX_PER_BYTE; 50 | #else 51 | return getBaseAddr() + (unsigned long)VNC_BYTES_PER_LINE * y + x/VNC_FB_PIX_PER_BYTE; 52 | #endif 53 | } 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCPalette.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "DebugLog.h" 19 | #include "GestaltUtils.h" 20 | 21 | #include "VNCConfig.h" 22 | #include "VNCServer.h" 23 | #include "VNCPalette.h" 24 | #include "VNCEncoder.h" 25 | 26 | #include "VNCTypes.h" 27 | 28 | extern unsigned long ctSeed; 29 | 30 | unsigned char VNCPalette::black, VNCPalette::white, bytesPerColor; 31 | VNCPixelFormat fbPixFormat; 32 | VNCPixelFormat pendingPixFormat; 33 | 34 | unsigned long *vncTrueColors = 0; 35 | 36 | OSErr VNCPalette::setup() { 37 | ctSeed = 10; 38 | return noErr; 39 | } 40 | 41 | OSErr VNCPalette::destroy() { 42 | if (vncTrueColors) { 43 | DisposePtr((Ptr)vncTrueColors); 44 | vncTrueColors = 0; 45 | } 46 | return noErr; 47 | } 48 | 49 | Size VNCPalette::minBufferSize() { 50 | return 256 * sizeof(VNCColor); 51 | } 52 | 53 | void VNCPalette::beginNewSession(const VNCPixelFormat &format) { 54 | pendingPixFormat.bitsPerPixel = 0; 55 | BlockMove(&format, &fbPixFormat, sizeof(VNCPixelFormat)); 56 | vncFlags.fbColorMapNeedsUpdate = true; 57 | } 58 | 59 | void VNCPalette::setPixelFormat(const VNCPixelFormat &format) { 60 | BlockMove(&format, &pendingPixFormat, sizeof(VNCPixelFormat)); 61 | } 62 | 63 | Boolean VNCPalette::hasChangesPending() { 64 | return VNCPalette::hasWaitingColorMapUpdate() || pendingPixFormat.bitsPerPixel; 65 | } 66 | 67 | Boolean VNCPalette::hasWaitingColorMapUpdate() { 68 | return vncFlags.fbColorMapNeedsUpdate && !fbPixFormat.trueColor; 69 | } 70 | 71 | VNCColor *VNCPalette::getWaitingColorMapUpdate(unsigned int *paletteSize) { 72 | #ifdef VNC_FB_BITS_PER_PIX 73 | const unsigned char fbDepth = VNC_FB_BITS_PER_PIX; 74 | #endif 75 | VNCColor *result = NULL; 76 | if (hasWaitingColorMapUpdate()) { 77 | *paletteSize = 1 << fbDepth; 78 | result = (VNCColor*) fbUpdateBuffer; 79 | } 80 | vncFlags.fbColorMapNeedsUpdate = false; 81 | return result; 82 | } 83 | 84 | void VNCPalette::setIndexedColor(unsigned int i, int red, int green, int blue) { 85 | VNCColor *vncColors = (VNCColor *)fbUpdateBuffer; 86 | vncColors[i].red = red; 87 | vncColors[i].green = green; 88 | vncColors[i].blue = blue; 89 | } 90 | 91 | void VNCPalette::idleTask() { 92 | #if !defined(VNC_FB_MONOCHROME) 93 | if (hasColorQD) { 94 | checkColorTable(); 95 | } 96 | #endif 97 | } 98 | 99 | OSErr VNCPalette::fbSyncTasks() { 100 | if (!vncBits.baseAddr) return noErr; 101 | 102 | // Handle any changes to the pixel format 103 | 104 | if (!hasColorQD 105 | #if defined(VNC_FB_MONOCHROME) 106 | || true 107 | #endif 108 | ) { 109 | if (vncFlags.fbColorMapNeedsUpdate) { 110 | // Set up the monochrome palette 111 | setIndexedColor(0, -1, -1, -1); 112 | setIndexedColor(1, 0, 0, 0); 113 | VNCPalette::white = 0; 114 | VNCPalette::black = 1; 115 | } 116 | return noErr; 117 | } 118 | 119 | #if !defined(VNC_FB_MONOCHROME) 120 | return updateColorTable(); 121 | #endif 122 | } 123 | 124 | void VNCPalette::prepareColorRoutines(Boolean isCPIXEL) { 125 | bytesPerColor = fbPixFormat.bitsPerPixel / 8; 126 | if (fbPixFormat.trueColor) { 127 | prepareTrueColorRoutines(isCPIXEL); 128 | } 129 | } -------------------------------------------------------------------------------- /mac-cpp-source/VNCPalette.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "VNCTypes.h" 21 | 22 | extern unsigned char bytesPerColor; 23 | extern VNCPixelFormat fbPixFormat; 24 | 25 | class VNCPalette { 26 | public: 27 | static unsigned char black, white; 28 | 29 | static OSErr setup(); 30 | static OSErr destroy(); 31 | 32 | static Size minBufferSize(); 33 | 34 | static Boolean hasChangesPending(); 35 | static Boolean hasWaitingColorMapUpdate(); 36 | static VNCColor *getWaitingColorMapUpdate(unsigned int *paletteSize); 37 | 38 | static OSErr fbSyncTasks(); 39 | static void idleTask(); 40 | 41 | static void beginNewSession(const VNCPixelFormat &format); 42 | static void setPixelFormat(const VNCPixelFormat &format); 43 | 44 | static void setIndexedColor(unsigned int i, int red, int green, int blue); 45 | 46 | static void prepareColorRoutines(Boolean isCPIXEL); 47 | 48 | static void checkColorTable(); 49 | static OSErr updateColorTable(); 50 | 51 | static void prepareTrueColorRoutines(Boolean isCPIXEL); 52 | static unsigned char *emitTrueColor(unsigned char *dst, unsigned char color); 53 | 54 | #define setupPIXEL() {VNCPalette::prepareColorRoutines(false);} 55 | #define setupCPIXEL() {VNCPalette::prepareColorRoutines(true);} 56 | 57 | #define emitColor(A,B) {if (!fbPixFormat.trueColor) {*A++ = B;} else {A = VNCPalette::emitTrueColor(A, B);} } 58 | }; -------------------------------------------------------------------------------- /mac-cpp-source/VNCPaletteTrueColor.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "DebugLog.h" 19 | #include "GestaltUtils.h" 20 | 21 | #include "VNCConfig.h" 22 | #include "VNCServer.h" 23 | #include "VNCPalette.h" 24 | #include "VNCEncoder.h" 25 | 26 | #include "VNCTypes.h" 27 | 28 | static unsigned char pixelShift; 29 | static unsigned long pixelMask; 30 | 31 | unsigned long ctSeed; 32 | extern unsigned long *vncTrueColors; 33 | 34 | extern VNCPixelFormat pendingPixFormat; 35 | 36 | static void setTrueColor(unsigned int i, int red, int green, int blue) { 37 | const unsigned long r = ((unsigned long)red) * fbPixFormat.redMax / 0xFFFF; 38 | const unsigned long g = ((unsigned long)green) * fbPixFormat.greenMax / 0xFFFF; 39 | const unsigned long b = ((unsigned long)blue) * fbPixFormat.blueMax / 0xFFFF; 40 | const unsigned long color = (r << fbPixFormat.redShift) | (g << fbPixFormat.greenShift) | (b << fbPixFormat.blueShift); 41 | if(fbPixFormat.bigEndian) { 42 | vncTrueColors[i] = color; 43 | } else { 44 | vncTrueColors[i] = ((color & 0x000000ff) << 24u) | 45 | ((color & 0x0000ff00) << 8u) | 46 | ((color & 0x00ff0000) >> 8u) | 47 | ((color & 0xff000000) >> 24u); 48 | } 49 | } 50 | 51 | void VNCPalette::checkColorTable() { 52 | // Find the color table associated with the device 53 | GDHandle gdh = GetMainDevice(); 54 | PixMapHandle gpx = (*gdh)->gdPMap; 55 | CTabHandle gct = (*gpx)->pmTable; 56 | 57 | // If the color table has changed, inform the interrupt routine 58 | if(gct && (*gct)->ctSeed != ctSeed) { 59 | vncFlags.fbColorMapNeedsUpdate = true; 60 | } 61 | } 62 | 63 | OSErr VNCPalette::updateColorTable() { 64 | #if !defined(VNC_FB_MONOCHROME) 65 | // Handle any changes to bits per pixel 66 | 67 | if (pendingPixFormat.bitsPerPixel) { 68 | BlockMove(&pendingPixFormat, &fbPixFormat, sizeof(VNCPixelFormat)); 69 | pendingPixFormat.bitsPerPixel = 0; 70 | dprintf("Changed pixel format.\n"); 71 | vncFlags.fbColorMapNeedsUpdate = true; 72 | } 73 | 74 | // Handle any changes to the color palette 75 | 76 | if (vncFlags.fbColorMapNeedsUpdate) { 77 | #ifdef VNC_FB_BITS_PER_PIX 78 | const unsigned char fbDepth = VNC_FB_BITS_PER_PIX; 79 | #endif 80 | const unsigned int nColors = 1 << fbDepth; 81 | 82 | // Allocate the color table, if necessary 83 | 84 | if (fbPixFormat.trueColor && (vncTrueColors == NULL)) { 85 | const unsigned long size = nColors * sizeof(unsigned long); 86 | vncTrueColors = (unsigned long *) NewPtr(size); 87 | if (MemError() != noErr) { 88 | dprintf("Failed to allocate true color table\n", size); 89 | return MemError(); 90 | } 91 | dprintf("Reserved %ld bytes for true color table\n", size); 92 | } 93 | 94 | // Find the color table associated with the device 95 | GDHandle gdh = GetMainDevice(); 96 | PixMapHandle gpx = (*gdh)->gdPMap; 97 | CTabHandle gct = (*gpx)->pmTable; 98 | if(gct) { 99 | if(nColors == ((*gct)->ctSize + 1)) { 100 | // Store a copy of the indexed color table so that 101 | // the interrupt routine can find it 102 | for(unsigned int i = 0; i < nColors; i++) { 103 | const RGBColor &rgb = (*gct)->ctTable[i].rgb; 104 | if (fbPixFormat.trueColor) { 105 | setTrueColor(i, rgb.red, rgb.green, rgb.blue); 106 | } else { 107 | setIndexedColor(i, rgb.red, rgb.green, rgb.blue); 108 | } 109 | } 110 | ctSeed = (*gct)->ctSeed; 111 | // Grab the white and black indices 112 | GrafPtr savedPort; 113 | GetPort (&savedPort); 114 | CGrafPort cPort; 115 | OpenCPort(&cPort); 116 | VNCPalette::black = cPort.fgColor; 117 | VNCPalette::white = cPort.bkColor; 118 | CloseCPort(&cPort); 119 | SetPort(savedPort); 120 | 121 | dprintf("Color palette ready (size:%d b:%d w:%d)\n", nColors, VNCPalette::black, VNCPalette::white); 122 | } else { 123 | dprintf("Palette size mismatch!\n"); 124 | } 125 | } else { 126 | dprintf("Failed to get graphics device!\n"); 127 | } 128 | } // vncFlags.fbColorMapNeedsUpdate 129 | #endif 130 | return noErr; 131 | } 132 | 133 | void VNCPalette::prepareTrueColorRoutines(Boolean isCPIXEL) { 134 | if (isCPIXEL) { 135 | // Determine representation of CPIXEL 136 | const unsigned long colorBits = ((unsigned long)fbPixFormat.redMax << fbPixFormat.redShift) | 137 | ((unsigned long)fbPixFormat.greenMax << fbPixFormat.greenShift) | 138 | ((unsigned long)fbPixFormat.blueMax << fbPixFormat.blueShift); 139 | if((fbPixFormat.bitsPerPixel == 32) && (colorBits == 0x00FFFFFF)) { 140 | bytesPerColor = 3; 141 | } 142 | //dprintf("Bytes per CPIXEL %d (ColorBits: %lx)\n", bytesPerColor, colorBits); 143 | } 144 | pixelShift = (sizeof(unsigned long) - bytesPerColor) * 8; 145 | pixelMask = (1UL << pixelShift) - 1 ; 146 | if (!fbPixFormat.bigEndian) { 147 | pixelShift = 0; 148 | } 149 | } 150 | 151 | #pragma a6frames off 152 | #pragma optimize_for_size off 153 | #pragma code68020 on 154 | 155 | unsigned char *VNCPalette::emitTrueColor(unsigned char *dst, unsigned char color) { 156 | const unsigned long packed = vncTrueColors[color] << pixelShift; 157 | *(unsigned long *)dst = (((*(unsigned long *)dst) ^ packed) & pixelMask) ^ packed; 158 | return dst + bytesPerColor; 159 | } 160 | 161 | #pragma optimize_for_size reset 162 | #pragma a6frames reset 163 | #pragma code68020 reset 164 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCScreenHash.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "VNCTypes.h" 21 | #include 22 | 23 | #define requestAlreadyScheduled -999 24 | 25 | typedef pascal void (*HashCallbackPtr)(int x, int y, int w, int h); 26 | 27 | class VNCScreenHash { 28 | private: 29 | static pascal void myVBLTask(VBLTaskPtr theVBL); 30 | static asm pascal void preVBLTask(); 31 | static OSErr makeVBLTaskPersistent(VBLTaskPtr task); 32 | static OSErr disposePersistentVBLTask(VBLTaskPtr task); 33 | 34 | static OSErr initVBLTask(); 35 | static OSErr destroyVBLTask(); 36 | static OSErr runVBLTask(); 37 | 38 | static void beginCompute(); 39 | static void computeHashes(unsigned int rows); 40 | static void computeHashesFast(unsigned int rows); 41 | static void computeHashesFastest(unsigned int rows); 42 | static void computeDirty(int &x, int &y, int &w, int &h); 43 | static void endCompute(); 44 | public: 45 | static OSErr setup(); 46 | static OSErr destroy(); 47 | static OSErr requestDirtyRect(HashCallbackPtr); 48 | }; -------------------------------------------------------------------------------- /mac-cpp-source/VNCServer.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "ChainedTCPHelper.h" 21 | 22 | #include "VNCConfig.h" 23 | #include "VNCTypes.h" 24 | 25 | enum VNCState { 26 | VNC_STOPPED, 27 | VNC_STARTING, 28 | VNC_WAITING, 29 | VNC_CONNECTED, 30 | VNC_RUNNING, 31 | VNC_STOPPING, 32 | VNC_ERROR 33 | }; 34 | 35 | struct VNCFlags { 36 | unsigned short fbColorMapNeedsUpdate : 1; 37 | unsigned short fbUpdateInProgress : 1; 38 | unsigned short fbUpdatePending : 1; 39 | unsigned short fbUpdateContinuous : 1; 40 | unsigned short clientTakesRaw : 1; 41 | unsigned short clientTakesHextile : 1; 42 | unsigned short clientTakesTRLE : 1; 43 | unsigned short clientTakesZRLE : 1; 44 | unsigned short clientTakesCursor : 1; 45 | unsigned short clientTakesContUpdt : 1; 46 | unsigned short clientTakesFence : 1; 47 | unsigned short clientTakesTightEnc : 1; 48 | unsigned short clientTakesTightAuth : 1; 49 | unsigned short forceVNCAuth : 1; 50 | unsigned short zLibLoaded : 1; 51 | }; 52 | 53 | #define VNC_FLAGS_DEFAULTS { \ 54 | false, /* fbColorMapNeedsUpdate */ \ 55 | false, /* fbUpdateInProgress */ \ 56 | false, /* fbUpdatePending */ \ 57 | false, /* fbUpdateContinuous */ \ 58 | false, /* clientTakesRaw */ \ 59 | false, /* clientTakesHexTile */ \ 60 | false, /* clientTakesTRLE */ \ 61 | false, /* clientTakesZRLE */ \ 62 | false, /* clientTakesCursor */ \ 63 | false, /* clientTakesContUpdt */ \ 64 | false, /* clientTakesFence */ \ 65 | false, /* clientTakesTightAuth */ \ 66 | false, /* forceVNCAuth */ \ 67 | false /* zLibLoaded */ \ 68 | } 69 | 70 | Boolean _tcpSuccess(TCPiopb *pb, unsigned int line); 71 | #define tcpSuccess(A) _tcpSuccess(A,__LINE__) 72 | 73 | extern ExtendedTCPiopb epb_send, epb_recv; 74 | extern ChainedTCPHelper tcp; 75 | extern wdsEntry myWDS[]; 76 | extern rdsEntry myRDS[]; 77 | extern StreamPtr stream; 78 | extern VNCClientMessages vncClientMessage; 79 | extern VNCServerMessages vncServerMessage; 80 | 81 | extern VNCState vncState; 82 | extern VNCConfig vncConfig; 83 | extern VNCFlags vncFlags; 84 | extern Point vncLastMousePosition; 85 | 86 | extern VNCRect fbUpdateRect; 87 | 88 | extern Boolean runFBSyncedTasks; 89 | extern pascal void vncFBSyncTasksDone(); 90 | 91 | pascal void tcpSendAuthResult(TCPiopb *pb); 92 | pascal void tcpSendAuthChallenge(TCPiopb *pb); 93 | pascal void tcpFinishMultiPartMessage(TCPiopb *pb); 94 | 95 | void tcpSendReply(Ptr ptr, size_t length, TCPCompletionPtr proc); 96 | void vncSendReplyMessage(unsigned char message, TCPCompletionPtr proc); 97 | 98 | OSErr vncServerStart(); 99 | OSErr vncServerStop(); 100 | OSErr vncServerError(); 101 | OSErr vncServerIdleTask(); 102 | Boolean vncServerStopped(); 103 | Boolean vncServerActive(); 104 | 105 | // Constants for specialized builds 106 | 107 | #if defined(VNC_FB_RES_512_342) 108 | // Plus, SE, Classic, SE/30 109 | #define VNC_FB_WIDTH 512 110 | #define VNC_FB_HEIGHT 342 111 | #define VNC_FB_MONOCHROME 112 | #elif defined(VNC_FB_RES_512_384) 113 | // Classic II, all others 114 | #define VNC_FB_WIDTH 512 115 | #define VNC_FB_HEIGHT 384 116 | 117 | #elif defined(VNC_FB_RES_640_480) 118 | // Mac II, LC, etc 119 | #define VNC_FB_WIDTH 640 120 | #define VNC_FB_HEIGHT 480 121 | 122 | #elif defined(VNC_FB_RES_608_431) 123 | // Apple Lisa w/ Screen Kit 124 | #define VNC_FB_WIDTH 608 125 | #define VNC_FB_HEIGHT 431 126 | 127 | #elif defined(VNC_FB_RES_720_364) 128 | // Apple Lisa 129 | #define VNC_FB_WIDTH 720 130 | #define VNC_FB_HEIGHT 364 131 | 132 | #elif defined(VNC_FB_RES_1024_768) 133 | #define VNC_FB_WIDTH 1024 134 | #define VNC_FB_HEIGHT 768 135 | #endif 136 | 137 | #if defined(VNC_FB_MONOCHROME) 138 | #define VNC_FB_BITS_PER_PIX 1 139 | 140 | #elif defined(VNC_FB_4_COLORS) 141 | #define VNC_FB_BITS_PER_PIX 2 142 | 143 | #elif defined(VNC_FB_16_COLORS) 144 | #define VNC_FB_BITS_PER_PIX 4 145 | 146 | #elif defined(VNC_FB_256_COLORS) 147 | #define VNC_FB_BITS_PER_PIX 8 148 | #endif 149 | 150 | #define VNC_FB_PIX_PER_BYTE (8 / VNC_FB_BITS_PER_PIX) 151 | #define VNC_FB_PALETTE_SIZE (1 << VNC_FB_BITS_PER_PIX) 152 | 153 | #ifdef VNC_FB_WIDTH 154 | #define VNC_BYTES_PER_LINE (VNC_FB_WIDTH / VNC_FB_PIX_PER_BYTE) 155 | #endif 156 | 157 | #define min(A,B) ((A) < (B) ? (A) : (B)) 158 | #define max(A,B) ((A) > (B) ? (A) : (B)) 159 | 160 | #define ZERO_ANY(T, a, n) do{\ 161 | T *a_ = (a);\ 162 | size_t n_ = (n);\ 163 | for (; n_ > 0; --n_, ++a_)\ 164 | *a_ = (T) 0;\ 165 | } while (0) 166 | -------------------------------------------------------------------------------- /mac-cpp-source/VNCStreamReader.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "GestaltUtils.h" 19 | 20 | #include "VNCStreamReader.h" 21 | 22 | StreamReader inStream; 23 | 24 | void StreamReader::setPosition(unsigned short pos) { 25 | position = pos; 26 | for (rdsPtr = myRDS; rdsPtr->length != 0; rdsPtr++) { 27 | if (pos >= rdsPtr->length) { 28 | pos -= rdsPtr->length; 29 | } else { 30 | src = rdsPtr->ptr + pos; 31 | rdsLeft = rdsPtr->length - pos; 32 | break; 33 | } 34 | } 35 | } 36 | 37 | /* 38 | * Returns a pointer to a contiguous block of unread 39 | * data and populates length with the bytes available. 40 | * 41 | * On the 68000, returns a pointer only if the data 42 | * word aligned. 43 | */ 44 | void const *StreamReader::getAlignedBlock(size_t *length) { 45 | if (hasColorQD || (((unsigned long)src & 0x01) == 0)) { 46 | *length = rdsLeft; 47 | return src; 48 | } else { 49 | return 0; 50 | } 51 | } 52 | 53 | size_t StreamReader::copyTo(void *dst, size_t len) { 54 | size_t bytesCopied = 0; 55 | while (rdsLeft) { 56 | const size_t bytesToCopy = min(len - bytesCopied, rdsLeft); 57 | if (dst) { 58 | BlockMove(src, dst, bytesToCopy); 59 | (Ptr)dst += bytesToCopy; 60 | } 61 | src += bytesToCopy; 62 | bytesCopied += bytesToCopy; 63 | rdsLeft -= bytesToCopy; 64 | position += bytesToCopy; 65 | 66 | if (bytesCopied == len) { 67 | break; 68 | } 69 | 70 | // Advance to the next rds 71 | if (rdsPtr->length != 0) { 72 | rdsPtr++; 73 | src = rdsPtr->ptr; 74 | rdsLeft = rdsPtr->length; 75 | } 76 | } 77 | return bytesCopied; 78 | } -------------------------------------------------------------------------------- /mac-cpp-source/VNCStreamReader.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "VNCServer.h" 21 | 22 | #define kNumRDS 5 /* Larger numbers increase read performance */ 23 | 24 | class StreamReader { 25 | private: 26 | char const *src; 27 | rdsEntry *rdsPtr; 28 | unsigned short rdsLeft; 29 | unsigned short position; 30 | public: 31 | inline char const *getDataBlock(size_t *length) { 32 | *length = rdsLeft; 33 | return src; 34 | } 35 | 36 | inline unsigned short getPosition() { 37 | return position; 38 | } 39 | 40 | inline size_t avail() { 41 | return rdsLeft; 42 | } 43 | 44 | inline Boolean finished() { 45 | return rdsLeft == 0; 46 | } 47 | 48 | inline size_t skip(size_t len) { 49 | return copyTo(NULL, len); 50 | } 51 | 52 | void setPosition(unsigned short pos); 53 | void const * getAlignedBlock(size_t *length); 54 | size_t copyTo(void *dst, size_t len); 55 | }; 56 | 57 | extern StreamReader inStream; 58 | 59 | enum DispatchMsgResult { 60 | msgTooShort = 0, // false 61 | nextMessage = 1, // true 62 | returnToCaller = -1, // true 63 | badContext = -2 64 | }; 65 | 66 | enum CallContext { 67 | asInterrupt, 68 | asMainLoop 69 | }; 70 | 71 | struct MessageData { 72 | CallContext context; 73 | 74 | const VNCClientMessages *msgPtr; 75 | size_t msgAvail; 76 | size_t msgSize; 77 | }; 78 | 79 | #define offsetof(st, m) ((Size)((char *)&((st *)0)->m - (char *)0)) 80 | #define endof(st, m) (offsetof(st,m) + sizeof(((st *)0)->m)) 81 | 82 | #define READ_ALL(arg) \ 83 | pb->msgSize = sizeof(pb->msgPtr->arg); \ 84 | if (pb->msgSize > pb->msgAvail) return msgTooShort; 85 | #define READ_STR(arg) \ 86 | pb->msgSize += pb->msgPtr->arg; \ 87 | if (pb->msgSize > pb->msgAvail) return msgTooShort; 88 | #define READ_TO(arg) \ 89 | pb->msgSize = endof(VNCClientMessages, arg); \ 90 | if (pb->msgSize > pb->msgAvail) return msgTooShort; 91 | #define MUST_COPY() \ 92 | if (pb->msgPtr != (const VNCClientMessages *)&vncClientMessage) return msgTooShort; 93 | #define MAIN_LOOP_ONLY() \ 94 | if (pb->context == asInterrupt) return badContext; 95 | #define DISPATCH_MESSAGE(func, arg) \ 96 | READ_ALL(arg); \ 97 | func(pb->msgPtr->arg); \ 98 | break; 99 | #define DISPATCH_MSGWSTR(func, arg, lenarg) \ 100 | READ_ALL(arg); \ 101 | READ_STR(arg.lenarg); \ 102 | func(pb->msgPtr->arg, ((const char *)pb->msgPtr) + sizeof(pb->msgPtr->arg)); \ 103 | break; -------------------------------------------------------------------------------- /mac-cpp-source/VNCTypes.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * MiniVNC (c) 2022-2024 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #pragma once 19 | 20 | #include "TightVNCTypes.h" 21 | 22 | enum { 23 | mConnectionFailed = 0, 24 | mNoAuthentication = 1, 25 | mVNCAuthentication = 2, 26 | mTightAuth = 16 27 | }; 28 | 29 | enum { 30 | mAuthOK = 0, 31 | mAuthFailed = 1, 32 | mAuthTooMany = 2 33 | }; 34 | 35 | enum { 36 | mSetPixelFormat = 0, 37 | mSetEncodings = 2, 38 | mFBUpdateRequest = 3, 39 | mKeyEvent = 4, 40 | mPointerEvent = 5, 41 | mClientCutText = 6, 42 | mEnableContUpdate = 150, 43 | mClientFence = 248 44 | }; 45 | 46 | enum { 47 | mFBUpdate = 0, 48 | mSetCMapEntries = 1, 49 | mBell = 2, 50 | mServerCutText = 3, 51 | mEndOfContUpdate = 150, 52 | mServerFence = 248 53 | }; 54 | 55 | enum { 56 | mFenceBlockBefore = 1, 57 | mFenceBlockAfter = 2, 58 | mFenceSyncNext = 3, 59 | mFenceRequest = 0x80000000, 60 | mFenceReqMask = 0x7F000000 61 | }; 62 | 63 | /* 64 | * References: 65 | * https://www.iana.org/assignments/rfb/rfb.xhtml 66 | * https://en.wikipedia.org/wiki/RFB_protocol 67 | * https://vncdotool.readthedocs.io/en/0.8.0/rfbproto.html#encodings 68 | * https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst 69 | */ 70 | enum { 71 | mRawEncoding = 0, 72 | mCopyRectEncoding = 1, 73 | mRREEncoding = 2, 74 | mCoRREEncoding = 4, 75 | mHextileEncoding = 5, 76 | mZLibEncoding = 6, 77 | mTightEncoding = 7, 78 | mZHextileEncoding = 8, 79 | mUltraEncoding = 9, 80 | mTRLEEncoding = 15, 81 | mZRLEEncoding = 16, 82 | mH264Encoding = 50, 83 | mVMWareMinEnc = 0x574d5600, 84 | mVMWareMaxEnc = 0x574d56ff, 85 | mTightQtyMaxEnc = -23, 86 | mTightQtyMinEnc = -32, 87 | mTightPNGEncoding = -140, 88 | mNewFBSizEncoding = -223, 89 | mLastRectEncoding = -224, 90 | mMousePosEncoding = -232, 91 | mCursorEncoding = -239, 92 | mXCursorEncoding = -240, 93 | mTightCmpMaxEnc = -247, 94 | mTightCmpMinEnc = -256, 95 | mQMUPtrChangeEnc = -257, 96 | mQMUExtKeyEnc = -258, 97 | mQMUAudioEnc = -259, 98 | mGIIEncoding = -305, 99 | mDeskNameEncoding = -307, 100 | mExtDesktopSizEnc = -308, 101 | mFenceEncoding = -312, 102 | mContUpdtEncoding = -313, 103 | mCrsrWithAlphaEnc = -314, 104 | mJPEGQtyMaxEnc = -412, 105 | mJPEGQtyMinEnc = -512, 106 | mJPEGSubMaxEnc = -763, 107 | mJPEGSubMinEnc = -768 108 | }; 109 | 110 | struct VNCRect { 111 | unsigned short x; 112 | unsigned short y; 113 | unsigned short w; 114 | unsigned short h; 115 | }; 116 | 117 | struct VNCPixelFormat { 118 | unsigned char bitsPerPixel; 119 | unsigned char depth; 120 | unsigned char bigEndian; 121 | unsigned char trueColor; 122 | unsigned short redMax; 123 | unsigned short greenMax; 124 | unsigned short blueMax; 125 | unsigned char redShift; 126 | unsigned char greenShift; 127 | unsigned char blueShift; 128 | unsigned char padding[3]; 129 | }; 130 | 131 | struct VNCServerProto { 132 | char version[12]; 133 | }; 134 | 135 | struct VNCServerInit { 136 | unsigned short fbWidth; 137 | unsigned short fbHeight; 138 | VNCPixelFormat format; 139 | unsigned long nameLength; 140 | char name[10]; 141 | }; 142 | 143 | struct VNCServerAuthTypeList { 144 | unsigned char numberOfAuthTypes; 145 | unsigned char authTypes[1]; 146 | }; 147 | 148 | struct VNCServerAuthType { 149 | unsigned long type; 150 | unsigned char challenge[16]; 151 | }; 152 | 153 | struct VNCServerAuthChallenge { 154 | unsigned char challenge[16]; 155 | }; 156 | 157 | struct VNCServerAuthResult { 158 | unsigned long result; 159 | }; 160 | 161 | struct VNCSetPixFormat { 162 | unsigned char message; 163 | unsigned char padding[3]; 164 | VNCPixelFormat format; 165 | }; 166 | 167 | struct VNCSetEncoding { 168 | unsigned char message; 169 | unsigned char padding; 170 | unsigned short numberOfEncodings; 171 | unsigned long encoding; 172 | }; 173 | 174 | struct VNCColor { 175 | unsigned short red; 176 | unsigned short green; 177 | unsigned short blue; 178 | }; 179 | 180 | struct VNCSetColorMapHeader { 181 | unsigned char message; 182 | unsigned char padding; 183 | unsigned short firstColor; 184 | unsigned short numColors; 185 | }; 186 | 187 | struct VNCFBUpdateReq{ 188 | unsigned char message; 189 | unsigned char incremental; 190 | VNCRect rect; 191 | }; 192 | 193 | struct VNCFBUpdate { 194 | unsigned char message; 195 | unsigned char padding; 196 | unsigned short numRects; 197 | }; 198 | 199 | struct VNCFBUpdateRect { 200 | VNCRect rect; 201 | long encodingType; 202 | }; 203 | 204 | struct VNCKeyEvent { 205 | unsigned char message; 206 | unsigned char down; 207 | unsigned short padding; 208 | unsigned long key; 209 | }; 210 | 211 | struct VNCPointerEvent { 212 | unsigned char message; 213 | unsigned char btnMask; 214 | unsigned short x; 215 | unsigned short y; 216 | }; 217 | 218 | struct VNCClientCutText { 219 | unsigned char message; 220 | unsigned char padding[3]; 221 | unsigned long length; 222 | }; 223 | 224 | struct VNCEnableContUpdates{ 225 | unsigned char message; 226 | unsigned char enable; 227 | VNCRect rect; 228 | }; 229 | 230 | struct VNCFenceMessage { 231 | unsigned char message; 232 | unsigned char padding[3]; 233 | unsigned long flags; 234 | unsigned char length; 235 | }; 236 | 237 | union VNCClientMessages { 238 | unsigned char message; 239 | VNCSetPixFormat pixFormat; 240 | VNCSetEncoding setEncoding; 241 | VNCFBUpdateReq fbUpdateReq; 242 | VNCKeyEvent keyEvent; 243 | VNCPointerEvent pointerEvent; 244 | VNCClientCutText cutText; 245 | VNCEnableContUpdates contUpdt; 246 | VNCFenceMessage fence; 247 | 248 | // TightVNC Messages 249 | long tightVncExtMsg; 250 | TightVNCCapReply tightCapReq; 251 | TightVNCFileUploadData tightFileUploadData; 252 | }; 253 | 254 | union VNCServerMessages { 255 | unsigned char message; 256 | unsigned long tightMessage; 257 | VNCServerProto protocol; 258 | VNCServerAuthTypeList authTypeList; 259 | VNCServerAuthType authType; 260 | VNCServerAuthChallenge authChallenge; 261 | VNCServerAuthResult authResult; 262 | VNCServerInit init; 263 | VNCFBUpdate fbUpdate; 264 | VNCFBUpdateRect fbUpdateRect; 265 | VNCSetColorMapHeader fbColorMap; 266 | VNCFenceMessage fence; 267 | }; 268 | 269 | typedef unsigned long size_t; 270 | -------------------------------------------------------------------------------- /mac-cpp-source/libs/Ari Halberstadt/OSUtilities.cpp: -------------------------------------------------------------------------------- 1 | /* (c) Copyright 1994 Ari Halberstadt */ 2 | 3 | #include 4 | #include 5 | #include 6 | //#include 7 | 8 | #include "OSUtilities.h" 9 | 10 | /*----------------------------------------------------------------------------*/ 11 | /* functions for determining features of the operating environment */ 12 | /*----------------------------------------------------------------------------*/ 13 | 14 | /* return number of toolbox traps */ 15 | short TrapNumToolbox(void) 16 | { 17 | short result = 0; 18 | 19 | if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap)) 20 | result = 0x0200; 21 | else 22 | result = 0x0400; 23 | return(result); 24 | } 25 | 26 | /* return the type of the trap */ 27 | TrapType TrapTypeGet(short trap) 28 | { 29 | return((trap & 0x0800) > 0 ? ToolTrap : OSTrap); 30 | } 31 | 32 | /* true if the trap is available */ 33 | Boolean TrapAvailable(short trap) 34 | { 35 | TrapType type; 36 | 37 | type = TrapTypeGet(trap); 38 | if (type == ToolTrap) { 39 | trap &= 0x07FF; 40 | if (trap >= TrapNumToolbox()) 41 | trap = _Unimplemented; 42 | } 43 | return(NGetTrapAddress(trap, type) != NGetTrapAddress(_Unimplemented, ToolTrap)); 44 | } 45 | 46 | /* true if gestalt trap is available */ 47 | Boolean GestaltAvailable(void) 48 | { 49 | static Boolean initialized, available; 50 | 51 | if (! initialized) { 52 | available = TrapAvailable(0xA1AD); 53 | initialized = true; 54 | } 55 | return(available); 56 | } 57 | 58 | /* return gestalt response, or 0 if error or gestalt not available */ 59 | long GestaltResponse(OSType selector) 60 | { 61 | long response, result; 62 | 63 | response = result = 0; 64 | if (GestaltAvailable() && Gestalt(selector, &response) == noErr) 65 | result = response; 66 | return(result); 67 | } 68 | 69 | /* test bit in gestalt response; false if error or gestalt not available */ 70 | Boolean GestaltBitTst(OSType selector, short bit) 71 | { 72 | return((GestaltResponse(selector) & (1 << bit)) != 0); 73 | } 74 | 75 | /* true if the WaitNextEvent trap is available */ 76 | Boolean MacHasWNE(void) 77 | { 78 | static Boolean initialized; 79 | static Boolean wne; 80 | 81 | if (! initialized) { 82 | /* do only once for efficiency */ 83 | wne = TrapAvailable(_WaitNextEvent); 84 | initialized = true; 85 | } 86 | return(wne); 87 | } 88 | 89 | /*----------------------------------------------------------------------------*/ 90 | /* event utilities */ 91 | /*----------------------------------------------------------------------------*/ 92 | 93 | /* Call GetNextEvent or WaitNextEvent, depending on which one is available. 94 | The parameters to this function are identical to those to WaitNextEvent. 95 | If GetNextEvent is called the extra parameters are ignored. */ 96 | Boolean EventGet(short mask, EventRecord *event, 97 | ThreadTicksType sleep, RgnHandle cursor) 98 | { 99 | Boolean result = false; 100 | 101 | if (MacHasWNE()) 102 | result = WaitNextEvent(mask, event, sleep, cursor); 103 | else { 104 | SystemTask(); 105 | result = GetNextEvent(mask, event); 106 | } 107 | if (! result) { 108 | /* make sure it's a null event, even if the system thinks otherwise, e.g., 109 | some desk accessory events (see comment in TransSkell event loop) */ 110 | event->what = nullEvent; 111 | } 112 | return(result); 113 | } 114 | 115 | /*----------------------------------------------------------------------------*/ 116 | /* dialog utilities */ 117 | /*----------------------------------------------------------------------------*/ 118 | 119 | /* set the text of the dialog item */ 120 | void SetDText(DialogPtr dlg, short item, const Str255 str) 121 | { 122 | short type; 123 | Handle hitem; 124 | Rect box; 125 | 126 | GetDItem(dlg, item, &type, &hitem, &box); 127 | SetIText(hitem, str); 128 | } 129 | 130 | /* set the text of the dialog item to the number */ 131 | void SetDNum(DialogPtr dlg, short item, long num) 132 | { 133 | Str255 str; 134 | 135 | NumToString(num, str); 136 | SetDText(dlg, item, str); 137 | } -------------------------------------------------------------------------------- /mac-cpp-source/libs/Ari Halberstadt/OSUtilities.h: -------------------------------------------------------------------------------- 1 | /* (c) Copyright 1994 Ari Halberstadt */ 2 | 3 | typedef long ThreadTicksType; /* clock ticks */ 4 | 5 | Boolean EventGet(short mask, EventRecord *event, ThreadTicksType sleep, RgnHandle cursor); 6 | void SetDText(DialogPtr dlg, short item, const Str255 str); 7 | void SetDNum(DialogPtr dlg, short item, long num); 8 | 9 | short TrapNumToolbox(void); 10 | TrapType TrapTypeGet(short trap); 11 | Boolean TrapAvailable(short trap); 12 | Boolean GestaltAvailable(void); 13 | long GestaltResponse(OSType selector); 14 | Boolean GestaltBitTst(OSType selector, short bit); 15 | Boolean MacHasWNE(void); -------------------------------------------------------------------------------- /mac-cpp-source/libs/ChromiVNC/VNCKeyboard.cpp: -------------------------------------------------------------------------------- 1 | // The routines in this file taken more or less unchanged from ChromiVNC Server v3.40 alpha5 2 | // (c) 2005-2005 Jonathan "Chromatix" Morton 3 | 4 | // This source file is part of the TridiaVNC package, as originally developed by Jonathan "Chromatix" Morton for Tridia Corporation. 5 | 6 | // TridiaVNC is distributed under the GNU General Public Licence (GPL). You may modify, copy, and/or distribute this program as much 7 | // as you please, provided you remain within the terms of the GPL. You may use Version 2 of the GPL, or, at your option, any later 8 | // version. The current version as of 9th October 2000 is reproduced below for your convenience; the most up-to-date version can 9 | // be found on http://www.fsf.org/. TridiaVNC is Free Software; it has no warranty, not even the normally implied warranties such 10 | // as "fitness for purpose" and so on. 11 | 12 | #include "LICENSE.h" 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "VNCKeyboard.h" 19 | #include "keysymdef.h" 20 | 21 | // From https://opensource.apple.com/source/python/python-3/python/Mac/Lib/Carbon/Events.py.auto.html 22 | 23 | #define kNullCharCode 0 24 | #define kHomeCharCode 1 25 | #define kEnterCharCode 3 26 | #define kEndCharCode 4 27 | #define kHelpCharCode 5 28 | #define kBellCharCode 7 29 | #define kBackspaceCharCode 8 30 | #define kTabCharCode 9 31 | #define kLineFeedCharCode 10 32 | #define kVerticalTabCharCode 11 33 | #define kPageUpCharCode 11 34 | #define kFormFeedCharCode 12 35 | #define kPageDownCharCode 12 36 | #define kReturnCharCode 13 37 | #define kFunctionKeyCharCode 16 38 | #define kEscapeCharCode 27 39 | #define kClearCharCode 27 40 | #define kLeftArrowCharCode 28 41 | #define kRightArrowCharCode 29 42 | #define kUpArrowCharCode 30 43 | #define kDownArrowCharCode 31 44 | #define kDeleteCharCode 127 45 | #define kNonBreakingSpaceCharCode 202 46 | 47 | enum { 48 | shiftKeyCode = 0x38, 49 | controlKeyCode = 0x3B, 50 | optionKeyCode = 0x3A, 51 | cmdKeyCode = 0x37 52 | }; 53 | 54 | // The following macros modify a LowMem global as well as our internal idea of the keyboard. 55 | #define PRESSKEY(_code) { getKeyBuffer[_code / 8] |= (1 << (_code % 8)); ((unsigned char *) 0x174)[_code / 8] |= (1 << (_code % 8)); } 56 | #define RELEASEKEY(_code) { getKeyBuffer[_code / 8] &= ~(1 << (_code % 8)); ((unsigned char *) 0x174)[_code / 8] &= ~(1 << (_code % 8)); } 57 | #define BITKEY(_code) (getKeyBuffer[_code / 8] & (1 << (_code % 8))) 58 | 59 | EventModifiers modifiedKeys; 60 | unsigned char getKeyBuffer[16], transMap[256][4]; 61 | 62 | void VNCKeyboard::Setup() { 63 | // for the GetKeys patch 64 | for(int c=0; c < 16; c++) 65 | getKeyBuffer[c] = 0; 66 | // for translating keysyms to keycodes 67 | Ptr theKCHR = (char *) ::GetScriptManagerVariable(smKCHRCache); 68 | unsigned long state, theChar; 69 | for(int c=3; c >= 0; c--) { 70 | for(int d=0; d < 256; d++) 71 | transMap[d][c] = 0xFF; 72 | modifiedKeys = ((c & 2) ? optionKey : 0) | ((c & 1) ? shiftKey : 0); 73 | for(int d=0; d < 127; d++) { 74 | state = 0; 75 | theChar = ::KeyTranslate(theKCHR, (d | modifiedKeys), &state) & 0xFF; 76 | if(theChar != 0 && transMap[theChar][c] == 0xFF) 77 | transMap[theChar][c] = d; 78 | } 79 | } 80 | } 81 | 82 | // Simulates pressing or releasing the key represented by keysym, values for which are defined by the X protocol. 83 | 84 | void VNCKeyboard::PressKey(unsigned long keysym, Boolean down) { 85 | EvQElPtr queueEntry = nil; 86 | EventRecord ev; 87 | Boolean modifier = false, onKeyPad = false; 88 | int modifierMask = 0; 89 | int theChar = 0, theKeyCode = 0; 90 | 91 | // Prepare the event record 92 | ev.what = down ? keyDown : keyUp; 93 | ev.modifiers = modifiedKeys; 94 | 95 | // Translate the X11 keysym into MacRoman encoding 96 | // Pay particular attention to modifier keys... 97 | switch(keysym) { 98 | case XK_Shift_L: 99 | case XK_Shift_R: 100 | modifier = true; 101 | modifierMask = shiftKey; 102 | theKeyCode = shiftKeyCode; 103 | break; 104 | 105 | case XK_Control_L: 106 | case XK_Control_R: 107 | modifier = true; 108 | modifierMask = controlKey; 109 | theKeyCode = controlKeyCode; 110 | break; 111 | 112 | case XK_Caps_Lock: 113 | modifier = true; 114 | modifierMask = alphaLock; 115 | theKeyCode = 0x39; 116 | break; 117 | 118 | // The Emacs META key, or the "space cadet" SUPER/HYPER keys, analogous to the Command key 119 | case XK_Meta_L: 120 | case XK_Meta_R: 121 | case XK_Super_L: 122 | case XK_Super_R: 123 | case XK_Hyper_L: 124 | case XK_Hyper_R: 125 | modifier = true; 126 | modifierMask = cmdKey; 127 | theKeyCode = cmdKeyCode; 128 | break; 129 | 130 | case XK_Alt_L: 131 | case XK_Alt_R: 132 | modifier = true; 133 | modifierMask = optionKey; 134 | theKeyCode = optionKeyCode; 135 | break; 136 | 137 | // That's all the modifiers - now test for 'special' keys 138 | case XK_BackSpace: 139 | theChar = kBackspaceCharCode; 140 | break; 141 | 142 | case XK_Tab: 143 | theChar = kTabCharCode; 144 | break; 145 | 146 | case XK_Return: 147 | theChar = kReturnCharCode; 148 | break; 149 | 150 | case XK_Escape: 151 | theChar = kEscapeCharCode; 152 | break; 153 | 154 | case XK_KP_Delete: 155 | onKeyPad = true; 156 | case XK_Delete: 157 | theChar = kDeleteCharCode; 158 | break; 159 | 160 | case XK_KP_Home: 161 | onKeyPad = true; 162 | case XK_Home: 163 | theChar = kHomeCharCode; 164 | break; 165 | 166 | case XK_KP_End: 167 | onKeyPad = true; 168 | case XK_End: 169 | theChar = kEndCharCode; 170 | break; 171 | 172 | case XK_KP_Page_Up: 173 | onKeyPad = true; 174 | case XK_Page_Up: 175 | theChar = kPageUpCharCode; 176 | break; 177 | 178 | case XK_KP_Page_Down: 179 | onKeyPad = true; 180 | case XK_Page_Down: 181 | theChar = kPageDownCharCode; 182 | break; 183 | 184 | case XK_KP_Left: 185 | onKeyPad = true; 186 | case XK_Left: 187 | theChar = kLeftArrowCharCode; 188 | break; 189 | 190 | case XK_KP_Right: 191 | onKeyPad = true; 192 | case XK_Right: 193 | theChar = kRightArrowCharCode; 194 | break; 195 | 196 | case XK_KP_Up: 197 | onKeyPad = true; 198 | case XK_Up: 199 | theChar = kUpArrowCharCode; 200 | break; 201 | 202 | case XK_KP_Down: 203 | onKeyPad = true; 204 | case XK_Down: 205 | theChar = kDownArrowCharCode; 206 | break; 207 | 208 | // The keypad is a strange beast. It generates a separate set of X11 keysyms and can be interpreted differently by Mac apps. 209 | case XK_KP_Multiply: 210 | theChar = '*'; 211 | onKeyPad = true; 212 | break; 213 | 214 | case XK_KP_Add: 215 | theChar = '+'; 216 | onKeyPad = true; 217 | break; 218 | 219 | case XK_KP_Subtract: 220 | theChar = '-'; 221 | onKeyPad = true; 222 | break; 223 | 224 | case XK_KP_Decimal: 225 | theChar = '.'; 226 | onKeyPad = true; 227 | break; 228 | 229 | case XK_KP_Divide: 230 | theChar = '/'; 231 | onKeyPad = true; 232 | break; 233 | 234 | case XK_KP_0: 235 | case XK_KP_1: 236 | case XK_KP_2: 237 | case XK_KP_3: 238 | case XK_KP_4: 239 | case XK_KP_5: 240 | case XK_KP_6: 241 | case XK_KP_7: 242 | case XK_KP_8: 243 | case XK_KP_9: 244 | theChar = (keysym - XK_KP_0) + '0'; 245 | onKeyPad = true; 246 | break; 247 | 248 | // Hmmm... it's not a modifier, and it's not special. Wonder if it's plain ASCII? 249 | default: 250 | if(keysym < 0x20 || keysym > 0x7E) { 251 | // Nope! Ignore it, it might do something *very* strange. 252 | //#warning FIXME! Implement high-order ASCII translation from Latin-1 to MacRoman 253 | return; 254 | } 255 | // US-ASCII can go in without modification. 256 | theChar = keysym & 0x7F; 257 | break; 258 | } 259 | 260 | if(modifier) { 261 | if(down) { 262 | PRESSKEY(theKeyCode); 263 | modifiedKeys |= modifierMask; 264 | } else { 265 | RELEASEKEY(theKeyCode); 266 | modifiedKeys &= ~modifierMask; 267 | } 268 | } 269 | 270 | ev.modifiers = modifiedKeys; 271 | 272 | // If Ctrl+Alt are held down, treat it as a Command key hold. This works around keyboards 273 | // which don't have any kind of META key, and brain-dead VNC clients which don't send it even if present. 274 | if((ev.modifiers & (optionKey | controlKey | cmdKey)) == (optionKey | controlKey)) { 275 | ev.modifiers &= ~(optionKey | controlKey); 276 | ev.modifiers |= cmdKey; 277 | } 278 | 279 | if(modifier) { 280 | if (ev.modifiers & optionKey) 281 | PRESSKEY(optionKeyCode) 282 | else 283 | RELEASEKEY(optionKeyCode) 284 | 285 | if (ev.modifiers & controlKey) 286 | PRESSKEY(controlKeyCode) 287 | else 288 | RELEASEKEY(controlKeyCode) 289 | 290 | if (ev.modifiers & cmdKey) 291 | PRESSKEY(cmdKeyCode) 292 | else 293 | RELEASEKEY(cmdKeyCode) 294 | 295 | return; 296 | } 297 | 298 | // Search for the correct KeyCode (plus any additional modifiers) to match the character... 299 | theKeyCode = 0xFF; 300 | for(int d=0; d < 3; d++) { 301 | if(transMap[theChar][d] != 0xFF) { 302 | theKeyCode = transMap[theChar][d]; 303 | ev.modifiers |= ((d & 2) ? optionKey : 0) | ((d & 1) ? shiftKey : 0); 304 | break; 305 | } 306 | } 307 | 308 | // Didn't find a key to match? Oops. Bye! 309 | if(theKeyCode > 0x7F) 310 | return; 311 | 312 | // Update the GetKeys map 313 | if(down) 314 | getKeyBuffer[theKeyCode / 8] |= (1 << (theKeyCode % 8)); 315 | else 316 | getKeyBuffer[theKeyCode / 8] &= ~(1 << (theKeyCode % 8)); 317 | 318 | // Retranslate the keycode using *all* the modifiers. This may result in zero, one or two characters... 319 | Ptr theKCHR = (char *) ::GetScriptManagerVariable(smKCHRCache); 320 | static unsigned long state = 0; 321 | short mods = ev.modifiers; 322 | long result = ::KeyTranslate(theKCHR, theKeyCode | mods, &state); 323 | 324 | // Extract Character #1 325 | if(result & 0xFF0000) { 326 | ev.message = ((result >> 16) & 0xFF) | ((int) theKeyCode << 8); 327 | ::PPostEvent(ev.what, ev.message, &queueEntry); 328 | if(queueEntry) 329 | queueEntry->evtQModifiers = mods; 330 | } 331 | 332 | // Extract Character #2 333 | if(result & 0xFF) { 334 | ev.message = (result & 0xFF) | ((int) theKeyCode << 8); 335 | ::PPostEvent(ev.what, ev.message, &queueEntry); 336 | if(queueEntry) 337 | queueEntry->evtQModifiers = mods; 338 | } 339 | 340 | // The following was producing quite an appreciable slowdown... we might lose keypresses, however. 341 | // LThread::Yield(); 342 | } 343 | 344 | // Overlay the remotely-pressed keys with those already pressed. 345 | 346 | void VNCKeyboard::GetKeys(UInt32 *theKeys) 347 | { 348 | char *outKeys = (char *) theKeys; 349 | 350 | for(int c=0; c < 16; c++) 351 | outKeys[c] |= getKeyBuffer[c]; 352 | } -------------------------------------------------------------------------------- /mac-cpp-source/libs/ChromiVNC/VNCKeyboard.h: -------------------------------------------------------------------------------- 1 | // The routines in this file taken more or less unchanged from ChromiVNC Server v3.40 alpha5 2 | // (c) 2005-2005 Jonathan "Chromatix" Morton 3 | 4 | // This source file is part of the TridiaVNC package, as originally developed by Jonathan "Chromatix" Morton for Tridia Corporation. 5 | 6 | // TridiaVNC is distributed under the GNU General Public Licence (GPL). You may modify, copy, and/or distribute this program as much 7 | // as you please, provided you remain within the terms of the GPL. You may use Version 2 of the GPL, or, at your option, any later 8 | // version. The current version as of 9th October 2000 is reproduced below for your convenience; the most up-to-date version can 9 | // be found on http://www.fsf.org/. TridiaVNC is Free Software; it has no warranty, not even the normally implied warranties such 10 | // as "fitness for purpose" and so on. 11 | 12 | #include "LICENSE.h" 13 | 14 | 15 | #include "LICENSE.h" 16 | 17 | class VNCKeyboard { 18 | public: 19 | static void Setup(); 20 | static void PressKey(unsigned long keysym, Boolean down); 21 | static void GetKeys(UInt32 *theKeys); 22 | }; -------------------------------------------------------------------------------- /mac-cpp-source/libs/ChromiVNC/keysymdef.h: -------------------------------------------------------------------------------- 1 | // ================================================ 2 | // keysymdef.h 3 | // - Defines enough of the X11 keysyms for our purposes. Compiled from XFree86 3.3.2. 4 | // ================================================ 5 | // This source file is part of the TridiaVNC package, as originally developed by Jonathan "Chromatix" Morton for Tridia Corporation. 6 | // TridiaVNC is released under the GNU General Public Licence (GPL). Please read the file "LICENSE.H" for more information. 7 | // If this file is not present, please contact Jonathan at or write to the Free Software Foundation, 8 | // whose contact details can be found on http://www.fsf.org/. 9 | 10 | #include "LICENSE.H" 11 | 12 | #define XK_VoidSymbol 0xFFFFFF 13 | 14 | #define XK_space 0x020 15 | 16 | #define XK_BackSpace 0xFF08 17 | #define XK_Tab 0xFF09 18 | #define XK_Linefeed 0xFF0A 19 | #define XK_Clear 0xFF0B 20 | #define XK_Return 0xFF0D 21 | #define XK_Pause 0xFF13 22 | #define XK_Scroll_Lock 0xFF14 23 | #define XK_Sys_Req 0xFF15 24 | #define XK_Escape 0xFF1B 25 | 26 | #define XK_Delete 0xFFFF 27 | 28 | #define XK_Print 0xFF61 29 | #define XK_dead_grave 0xFE50 30 | #define XK_dead_acute 0xFE51 31 | #define XK_dead_circumflex 0xFE52 32 | #define XK_dead_tilde 0xFE53 33 | 34 | #define XK_Home 0xFF50 35 | #define XK_Left 0xFF51 36 | #define XK_Up 0xFF52 37 | #define XK_Right 0xFF53 38 | #define XK_Down 0xFF54 39 | #define XK_Page_Up 0xFF55 40 | #define XK_Page_Down 0xFF56 41 | #define XK_End 0xFF57 42 | #define XK_Begin 0xFF58 43 | 44 | #define XK_Select 0xFF60 45 | #define XK_Print 0xFF61 46 | #define XK_Execute 0xFF62 47 | #define XK_Insert 0xFF63 48 | 49 | #define XK_Cancel 0xFF69 50 | #define XK_Help 0xFF6A 51 | #define XK_Break 0xFF6B 52 | #define XK_Num_Lock 0xFF7F 53 | 54 | #define XK_KP_Space 0xFF80 55 | #define XK_KP_Tab 0xFF89 56 | #define XK_KP_Enter 0xFF8D 57 | 58 | #define XK_KP_Home 0xFF95 59 | #define XK_KP_Left 0xFF96 60 | #define XK_KP_Up 0xFF97 61 | #define XK_KP_Right 0xFF98 62 | #define XK_KP_Down 0xFF99 63 | #define XK_KP_Prior 0xFF9A 64 | #define XK_KP_Page_Up 0xFF9A 65 | #define XK_KP_Next 0xFF9B 66 | #define XK_KP_Page_Down 0xFF9B 67 | #define XK_KP_End 0xFF9C 68 | #define XK_KP_Begin 0xFF9D 69 | #define XK_KP_Insert 0xFF9E 70 | #define XK_KP_Delete 0xFF9F 71 | #define XK_KP_Equal 0xFFBD 72 | #define XK_KP_Multiply 0xFFAA 73 | #define XK_KP_Add 0xFFAB 74 | #define XK_KP_Separator 0xFFAC 75 | #define XK_KP_Subtract 0xFFAD 76 | #define XK_KP_Decimal 0xFFAE 77 | #define XK_KP_Divide 0xFFAF 78 | 79 | #define XK_KP_0 0xFFB0 80 | #define XK_KP_1 0xFFB1 81 | #define XK_KP_2 0xFFB2 82 | #define XK_KP_3 0xFFB3 83 | #define XK_KP_4 0xFFB4 84 | #define XK_KP_5 0xFFB5 85 | #define XK_KP_6 0xFFB6 86 | #define XK_KP_7 0xFFB7 87 | #define XK_KP_8 0xFFB8 88 | #define XK_KP_9 0xFFB9 89 | 90 | #define XK_F1 0xFFBE 91 | #define XK_F2 0xFFBF 92 | #define XK_F3 0xFFC0 93 | #define XK_F4 0xFFC1 94 | #define XK_F5 0xFFC2 95 | #define XK_F6 0xFFC3 96 | #define XK_F7 0xFFC4 97 | #define XK_F8 0xFFC5 98 | #define XK_F9 0xFFC6 99 | #define XK_F10 0xFFC7 100 | #define XK_F11 0xFFC8 101 | #define XK_F12 0xFFC9 102 | #define XK_F13 0xFFCA 103 | #define XK_F14 0xFFCB 104 | #define XK_F15 0xFFCC 105 | #define XK_F16 0xFFCD 106 | #define XK_F17 0xFFCE 107 | #define XK_F18 0xFFCF 108 | #define XK_F19 0xFFD0 109 | #define XK_F20 0xFFD1 110 | #define XK_F21 0xFFD2 111 | #define XK_F22 0xFFD3 112 | #define XK_F23 0xFFD4 113 | #define XK_F24 0xFFD5 114 | 115 | 116 | #define XK_Shift_L 0xFFE1 117 | #define XK_Shift_R 0xFFE2 118 | #define XK_Control_L 0xFFE3 119 | #define XK_Control_R 0xFFE4 120 | #define XK_Caps_Lock 0xFFE5 121 | #define XK_Shift_Lock 0xFFE6 122 | #define XK_Meta_L 0xFFE7 123 | #define XK_Meta_R 0xFFE8 124 | #define XK_Super_L 0xFFEB /* Left super */ 125 | #define XK_Super_R 0xFFEC /* Right super */ 126 | #define XK_Hyper_L 0xFFED /* Left hyper */ 127 | #define XK_Hyper_R 0xFFEE /* Right hyper */ 128 | #define XK_Alt_L 0xFFE9 129 | #define XK_Alt_R 0xFFEA 130 | 131 | 132 | -------------------------------------------------------------------------------- /mac-cpp-source/libs/Common Libs/GestaltUtils.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Common Libraries (c) 1994 Marcio Teixeira * 3 | * * 4 | * This program is free software: you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation, either version 3 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * To view a copy of the GNU General Public License, go to the following * 15 | * location: . * 16 | ****************************************************************************/ 17 | 18 | #include "GestaltUtils.h" 19 | 20 | short hasColorQD = 0; 21 | long gSysVers = 0; 22 | 23 | short HasColorQD() { 24 | OSErr err; 25 | long tmpLong; 26 | 27 | hasColorQD = 0; 28 | 29 | if (!TrapAvailable(_Gestalt)) { 30 | SysEnvRec mySys; 31 | err = SysEnvirons( curSysEnvVers, &mySys ); 32 | if( err != envNotPresent ) 33 | hasColorQD = (mySys.hasColorQD) ? 1 : 0; 34 | } else { 35 | err = Gestalt(gestaltQuickdrawVersion, &tmpLong); 36 | if( tmpLong >= gestalt8BitQD ) 37 | hasColorQD = 1; 38 | if( tmpLong >= gestalt32BitQD ) 39 | hasColorQD = 2; 40 | } 41 | 42 | return hasColorQD; 43 | } 44 | 45 | long GetSysVersion() { 46 | OSErr err = Gestalt(gestaltSystemVersion, &gSysVers); 47 | return gSysVers; 48 | } 49 | 50 | short GestaltTestAttr( OSType selector, long responseBit ) { 51 | if (TrapAvailable(_Gestalt)) { 52 | long tmpLong; 53 | OSErr err = Gestalt( selector, &tmpLong ); 54 | return err == noErr && BitTst(&tmpLong, 31 - responseBit); 55 | } 56 | return false; 57 | } 58 | 59 | short GestaltTestMin( OSType selector, long minMask ) { 60 | if (TrapAvailable(_Gestalt)) { 61 | long tmpLong; 62 | OSErr err = Gestalt( selector, &tmpLong ); 63 | if( err != noErr ) 64 | return( FALSE ); 65 | return( tmpLong >= minMask ); 66 | } 67 | return false; 68 | } 69 | 70 | /*Boolean TrapAvailable(short trapWord) { 71 | TrapType trapType = (trapWord & 0x0800) ? ToolTrap : OSTrap; 72 | return ((trapType == ToolTrap) && 73 | ((trapWord & 0x03FF) >= 0x0200) && 74 | (GetToolboxTrapAddress(0xA86E) == GetToolboxTrapAddress(0xAA6E))) 75 | ? false 76 | : NGetTrapAddress(trapWord, trapType) != GetToolboxTrapAddress(_Unimplemented); 77 | }*/ -------------------------------------------------------------------------------- /mac-cpp-source/libs/Common Libs/GestaltUtils.h: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | 3 | Gestalt.h 4 | 5 | AUTHOR: Marcio Luis Teixeira 6 | CREATED: 9/18/94 7 | 8 | LAST REVISION: 9/18/94 9 | 10 | (c) 1994 by Marcio Luis Teixeira. 11 | All rights reserved. 12 | 13 | *************************************************************/ 14 | 15 | extern short hasColorQD; 16 | extern long gSysVers; 17 | 18 | short HasColorQD( void ); 19 | long GetSysVersion( void ); 20 | short GestaltTestAttr( OSType selector, long responseBit ); 21 | short GestaltTestMin( OSType selector, long minMask ); 22 | Boolean TrapAvailable( short trapWord ); -------------------------------------------------------------------------------- /mac-cpp-source/libs/MacTCP.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/mac-cpp-source/libs/MacTCP.h -------------------------------------------------------------------------------- /mac-cpp-source/libs/compat.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMPAT_ #define _COMPAT_ /* compiler ifdef things */ #ifdef THINK_C #ifndef nil #define nil 0L #endif #define CR '\r' #define LF '\n' #define CRSTR "\r" #define LFSTR "\n" #define CRLF "\r\n" #define QDARROW arrow #define QDTHEPORT thePort #define QDSCREENBITS screenBits #define QDBLACK black #define QDDKGRAY dkGray #define okButton OK #define cancelButton Cancel /*#define c2pstr CtoPstr #define p2cstr PtoCstr*/ #define PROTOS #else #define PROTOS #define CR '\n' #define LF '\r' #define CRSTR "\n" #define LFSTR "\r" #define CRLF "\n\r" #define QDARROW qd.arrow #define QDTHEPORT qd.thePort #define QDSCREENBITS qd.screenBits #define QDBLACK qd.black #define QDDKGRAY qd.dkGray #define okButton ok #define cancelButton cancel #endif typedef unsigned char UInt8; typedef unsigned short UInt16; typedef unsigned long UInt32; typedef signed char SInt8; typedef unsigned char byte; #endif -------------------------------------------------------------------------------- /mac-cpp-source/libs/miniz-3.0.2/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013-2014 RAD Game Tools and Valve Software 2 | Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC 3 | 4 | All Rights Reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /mac-cpp-source/libs/miniz-3.0.2/examples/example1.c: -------------------------------------------------------------------------------- 1 | // example1.c - Demonstrates miniz.c's compress() and uncompress() functions (same as zlib's). 2 | // Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. 3 | #include 4 | #include "miniz.h" 5 | typedef unsigned char uint8; 6 | typedef unsigned short uint16; 7 | typedef unsigned int uint; 8 | 9 | // The string to compress. 10 | static const char *s_pStr = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 11 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 12 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 13 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 14 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 15 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \ 16 | "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."; 17 | 18 | int main(int argc, char *argv[]) 19 | { 20 | uint step = 0; 21 | int cmp_status; 22 | uLong src_len = (uLong)strlen(s_pStr); 23 | uLong cmp_len = compressBound(src_len); 24 | uLong uncomp_len = src_len; 25 | uint8 *pCmp, *pUncomp; 26 | uint total_succeeded = 0; 27 | (void)argc, (void)argv; 28 | 29 | printf("miniz.c version: %s\n", MZ_VERSION); 30 | 31 | do 32 | { 33 | // Allocate buffers to hold compressed and uncompressed data. 34 | pCmp = (mz_uint8 *)malloc((size_t)cmp_len); 35 | pUncomp = (mz_uint8 *)malloc((size_t)src_len); 36 | if ((!pCmp) || (!pUncomp)) 37 | { 38 | printf("Out of memory!\n"); 39 | return EXIT_FAILURE; 40 | } 41 | 42 | // Compress the string. 43 | cmp_status = compress(pCmp, &cmp_len, (const unsigned char *)s_pStr, src_len); 44 | if (cmp_status != Z_OK) 45 | { 46 | printf("compress() failed!\n"); 47 | free(pCmp); 48 | free(pUncomp); 49 | return EXIT_FAILURE; 50 | } 51 | 52 | printf("Compressed from %u to %u bytes\n", (mz_uint32)src_len, (mz_uint32)cmp_len); 53 | 54 | if (step) 55 | { 56 | // Purposely corrupt the compressed data if fuzzy testing (this is a very crude fuzzy test). 57 | uint n = 1 + (rand() % 3); 58 | while (n--) 59 | { 60 | uint i = rand() % cmp_len; 61 | pCmp[i] ^= (rand() & 0xFF); 62 | } 63 | } 64 | 65 | // Decompress. 66 | cmp_status = uncompress(pUncomp, &uncomp_len, pCmp, cmp_len); 67 | total_succeeded += (cmp_status == Z_OK); 68 | 69 | if (step) 70 | { 71 | printf("Simple fuzzy test: step %u total_succeeded: %u\n", step, total_succeeded); 72 | } 73 | else 74 | { 75 | if (cmp_status != Z_OK) 76 | { 77 | printf("uncompress failed!\n"); 78 | free(pCmp); 79 | free(pUncomp); 80 | return EXIT_FAILURE; 81 | } 82 | 83 | printf("Decompressed from %u to %u bytes\n", (mz_uint32)cmp_len, (mz_uint32)uncomp_len); 84 | 85 | // Ensure uncompress() returned the expected data. 86 | if ((uncomp_len != src_len) || (memcmp(pUncomp, s_pStr, (size_t)src_len))) 87 | { 88 | printf("Decompression failed!\n"); 89 | free(pCmp); 90 | free(pUncomp); 91 | return EXIT_FAILURE; 92 | } 93 | } 94 | 95 | free(pCmp); 96 | free(pUncomp); 97 | 98 | step++; 99 | 100 | // Keep on fuzzy testing if there's a non-empty command line. 101 | } while (argc >= 2); 102 | 103 | printf("Success.\n"); 104 | return EXIT_SUCCESS; 105 | } 106 | -------------------------------------------------------------------------------- /mac-cpp-source/libs/miniz-3.0.2/examples/example2.c: -------------------------------------------------------------------------------- 1 | // example2.c - Simple demonstration of miniz.c's ZIP archive API's. 2 | // Note this test deletes the test archive file "__mz_example2_test__.zip" in the current directory, then creates a new one with test data. 3 | // Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. 4 | 5 | #if defined(__GNUC__) 6 | // Ensure we get the 64-bit variants of the CRT's file I/O calls 7 | #ifndef _FILE_OFFSET_BITS 8 | #define _FILE_OFFSET_BITS 64 9 | #endif 10 | #ifndef _LARGEFILE64_SOURCE 11 | #define _LARGEFILE64_SOURCE 1 12 | #endif 13 | #endif 14 | 15 | #include 16 | #include "miniz.h" 17 | 18 | typedef unsigned char uint8; 19 | typedef unsigned short uint16; 20 | typedef unsigned int uint; 21 | 22 | // The string to compress. 23 | static const char *s_pTest_str = 24 | "MISSION CONTROL I wouldn't worry too much about the computer. First of all, there is still a chance that he is right, despite your tests, and" \ 25 | "if it should happen again, we suggest eliminating this possibility by allowing the unit to remain in place and seeing whether or not it" \ 26 | "actually fails. If the computer should turn out to be wrong, the situation is still not alarming. The type of obsessional error he may be" \ 27 | "guilty of is not unknown among the latest generation of HAL 9000 computers. It has almost always revolved around a single detail, such as" \ 28 | "the one you have described, and it has never interfered with the integrity or reliability of the computer's performance in other areas." \ 29 | "No one is certain of the cause of this kind of malfunctioning. It may be over-programming, but it could also be any number of reasons. In any" \ 30 | "event, it is somewhat analogous to human neurotic behavior. Does this answer your query? Zero-five-three-Zero, MC, transmission concluded."; 31 | 32 | static const char *s_pComment = "This is a comment"; 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | int i, sort_iter; 37 | mz_bool status; 38 | size_t uncomp_size; 39 | mz_zip_archive zip_archive; 40 | void *p; 41 | const int N = 50; 42 | char data[2048]; 43 | char archive_filename[64]; 44 | static const char *s_Test_archive_filename = "__mz_example2_test__.zip"; 45 | 46 | assert((strlen(s_pTest_str) + 64) < sizeof(data)); 47 | 48 | printf("miniz.c version: %s\n", MZ_VERSION); 49 | 50 | (void)argc, (void)argv; 51 | 52 | // Delete the test archive, so it doesn't keep growing as we run this test 53 | remove(s_Test_archive_filename); 54 | 55 | // Append a bunch of text files to the test archive 56 | for (i = (N - 1); i >= 0; --i) 57 | { 58 | sprintf(archive_filename, "%u.txt", i); 59 | sprintf(data, "%u %s %u", (N - 1) - i, s_pTest_str, i); 60 | 61 | // Add a new file to the archive. Note this is an IN-PLACE operation, so if it fails your archive is probably hosed (its central directory may not be complete) but it should be recoverable using zip -F or -FF. So use caution with this guy. 62 | // A more robust way to add a file to an archive would be to read it into memory, perform the operation, then write a new archive out to a temp file and then delete/rename the files. 63 | // Or, write a new archive to disk to a temp file, then delete/rename the files. For this test this API is fine. 64 | status = mz_zip_add_mem_to_archive_file_in_place(s_Test_archive_filename, archive_filename, data, strlen(data) + 1, s_pComment, (uint16)strlen(s_pComment), MZ_BEST_COMPRESSION); 65 | if (!status) 66 | { 67 | printf("mz_zip_add_mem_to_archive_file_in_place failed!\n"); 68 | return EXIT_FAILURE; 69 | } 70 | } 71 | 72 | // Add a directory entry for testing 73 | status = mz_zip_add_mem_to_archive_file_in_place(s_Test_archive_filename, "directory/", NULL, 0, "no comment", (uint16)strlen("no comment"), MZ_BEST_COMPRESSION); 74 | if (!status) 75 | { 76 | printf("mz_zip_add_mem_to_archive_file_in_place failed!\n"); 77 | return EXIT_FAILURE; 78 | } 79 | 80 | // Now try to open the archive. 81 | memset(&zip_archive, 0, sizeof(zip_archive)); 82 | 83 | status = mz_zip_reader_init_file(&zip_archive, s_Test_archive_filename, 0); 84 | if (!status) 85 | { 86 | printf("mz_zip_reader_init_file() failed!\n"); 87 | return EXIT_FAILURE; 88 | } 89 | 90 | // Get and print information about each file in the archive. 91 | for (i = 0; i < (int)mz_zip_reader_get_num_files(&zip_archive); i++) 92 | { 93 | mz_zip_archive_file_stat file_stat; 94 | if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) 95 | { 96 | printf("mz_zip_reader_file_stat() failed!\n"); 97 | mz_zip_reader_end(&zip_archive); 98 | return EXIT_FAILURE; 99 | } 100 | 101 | printf("Filename: \"%s\", Comment: \"%s\", Uncompressed size: %u, Compressed size: %u, Is Dir: %u\n", file_stat.m_filename, file_stat.m_comment, (uint)file_stat.m_uncomp_size, (uint)file_stat.m_comp_size, mz_zip_reader_is_file_a_directory(&zip_archive, i)); 102 | 103 | if (!strcmp(file_stat.m_filename, "directory/")) 104 | { 105 | if (!mz_zip_reader_is_file_a_directory(&zip_archive, i)) 106 | { 107 | printf("mz_zip_reader_is_file_a_directory() didn't return the expected results!\n"); 108 | mz_zip_reader_end(&zip_archive); 109 | return EXIT_FAILURE; 110 | } 111 | } 112 | } 113 | 114 | // Close the archive, freeing any resources it was using 115 | mz_zip_reader_end(&zip_archive); 116 | 117 | // Now verify the compressed data 118 | for (sort_iter = 0; sort_iter < 2; sort_iter++) 119 | { 120 | memset(&zip_archive, 0, sizeof(zip_archive)); 121 | status = mz_zip_reader_init_file(&zip_archive, s_Test_archive_filename, sort_iter ? MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY : 0); 122 | if (!status) 123 | { 124 | printf("mz_zip_reader_init_file() failed!\n"); 125 | return EXIT_FAILURE; 126 | } 127 | 128 | for (i = 0; i < N; i++) 129 | { 130 | sprintf(archive_filename, "%u.txt", i); 131 | sprintf(data, "%u %s %u", (N - 1) - i, s_pTest_str, i); 132 | 133 | // Try to extract all the files to the heap. 134 | p = mz_zip_reader_extract_file_to_heap(&zip_archive, archive_filename, &uncomp_size, 0); 135 | if (!p) 136 | { 137 | printf("mz_zip_reader_extract_file_to_heap() failed!\n"); 138 | mz_zip_reader_end(&zip_archive); 139 | return EXIT_FAILURE; 140 | } 141 | 142 | // Make sure the extraction really succeeded. 143 | if ((uncomp_size != (strlen(data) + 1)) || (memcmp(p, data, strlen(data)))) 144 | { 145 | printf("mz_zip_reader_extract_file_to_heap() failed to extract the proper data\n"); 146 | mz_free(p); 147 | mz_zip_reader_end(&zip_archive); 148 | return EXIT_FAILURE; 149 | } 150 | 151 | printf("Successfully extracted file \"%s\", size %u\n", archive_filename, (uint)uncomp_size); 152 | printf("File data: \"%s\"\n", (const char *)p); 153 | 154 | // We're done. 155 | mz_free(p); 156 | } 157 | 158 | // Close the archive, freeing any resources it was using 159 | mz_zip_reader_end(&zip_archive); 160 | } 161 | 162 | printf("Success.\n"); 163 | return EXIT_SUCCESS; 164 | } 165 | -------------------------------------------------------------------------------- /mac-cpp-source/libs/miniz-3.0.2/examples/example3.c: -------------------------------------------------------------------------------- 1 | // example3.c - Demonstrates how to use miniz.c's deflate() and inflate() functions for simple file compression. 2 | // Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. 3 | // For simplicity, this example is limited to files smaller than 4GB, but this is not a limitation of miniz.c. 4 | #include 5 | #include 6 | #include "miniz.h" 7 | 8 | typedef unsigned char uint8; 9 | typedef unsigned short uint16; 10 | typedef unsigned int uint; 11 | 12 | #define my_max(a,b) (((a) > (b)) ? (a) : (b)) 13 | #define my_min(a,b) (((a) < (b)) ? (a) : (b)) 14 | 15 | #define BUF_SIZE (1024 * 1024) 16 | static uint8 s_inbuf[BUF_SIZE]; 17 | static uint8 s_outbuf[BUF_SIZE]; 18 | 19 | int main(int argc, char *argv[]) 20 | { 21 | const char *pMode; 22 | FILE *pInfile, *pOutfile; 23 | uint infile_size; 24 | int level = Z_BEST_COMPRESSION; 25 | z_stream stream; 26 | int p = 1; 27 | const char *pSrc_filename; 28 | const char *pDst_filename; 29 | long file_loc; 30 | 31 | printf("miniz.c version: %s\n", MZ_VERSION); 32 | 33 | if (argc < 4) 34 | { 35 | printf("Usage: example3 [options] [mode:c or d] infile outfile\n"); 36 | printf("\nModes:\n"); 37 | printf("c - Compresses file infile to a zlib stream in file outfile\n"); 38 | printf("d - Decompress zlib stream in file infile to file outfile\n"); 39 | printf("\nOptions:\n"); 40 | printf("-l[0-10] - Compression level, higher values are slower.\n"); 41 | return EXIT_FAILURE; 42 | } 43 | 44 | while ((p < argc) && (argv[p][0] == '-')) 45 | { 46 | switch (argv[p][1]) 47 | { 48 | case 'l': 49 | { 50 | level = atoi(&argv[1][2]); 51 | if ((level < 0) || (level > 10)) 52 | { 53 | printf("Invalid level!\n"); 54 | return EXIT_FAILURE; 55 | } 56 | break; 57 | } 58 | default: 59 | { 60 | printf("Invalid option: %s\n", argv[p]); 61 | return EXIT_FAILURE; 62 | } 63 | } 64 | p++; 65 | } 66 | 67 | if ((argc - p) < 3) 68 | { 69 | printf("Must specify mode, input filename, and output filename after options!\n"); 70 | return EXIT_FAILURE; 71 | } 72 | else if ((argc - p) > 3) 73 | { 74 | printf("Too many filenames!\n"); 75 | return EXIT_FAILURE; 76 | } 77 | 78 | pMode = argv[p++]; 79 | if (!strchr("cCdD", pMode[0])) 80 | { 81 | printf("Invalid mode!\n"); 82 | return EXIT_FAILURE; 83 | } 84 | 85 | pSrc_filename = argv[p++]; 86 | pDst_filename = argv[p++]; 87 | 88 | printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename); 89 | 90 | // Open input file. 91 | pInfile = fopen(pSrc_filename, "rb"); 92 | if (!pInfile) 93 | { 94 | printf("Failed opening input file!\n"); 95 | return EXIT_FAILURE; 96 | } 97 | 98 | // Determine input file's size. 99 | fseek(pInfile, 0, SEEK_END); 100 | file_loc = ftell(pInfile); 101 | fseek(pInfile, 0, SEEK_SET); 102 | 103 | if ((file_loc < 0) || ((mz_uint64)file_loc > INT_MAX)) 104 | { 105 | // This is not a limitation of miniz or tinfl, but this example. 106 | printf("File is too large to be processed by this example.\n"); 107 | return EXIT_FAILURE; 108 | } 109 | 110 | infile_size = (uint)file_loc; 111 | 112 | // Open output file. 113 | pOutfile = fopen(pDst_filename, "wb"); 114 | if (!pOutfile) 115 | { 116 | printf("Failed opening output file!\n"); 117 | return EXIT_FAILURE; 118 | } 119 | 120 | printf("Input file size: %u\n", infile_size); 121 | 122 | // Init the z_stream 123 | memset(&stream, 0, sizeof(stream)); 124 | stream.next_in = s_inbuf; 125 | stream.avail_in = 0; 126 | stream.next_out = s_outbuf; 127 | stream.avail_out = BUF_SIZE; 128 | 129 | if ((pMode[0] == 'c') || (pMode[0] == 'C')) 130 | { 131 | // Compression. 132 | uint infile_remaining = infile_size; 133 | 134 | if (deflateInit(&stream, level) != Z_OK) 135 | { 136 | printf("deflateInit() failed!\n"); 137 | return EXIT_FAILURE; 138 | } 139 | 140 | for ( ; ; ) 141 | { 142 | int status; 143 | if (!stream.avail_in) 144 | { 145 | // Input buffer is empty, so read more bytes from input file. 146 | uint n = my_min(BUF_SIZE, infile_remaining); 147 | 148 | if (fread(s_inbuf, 1, n, pInfile) != n) 149 | { 150 | printf("Failed reading from input file!\n"); 151 | return EXIT_FAILURE; 152 | } 153 | 154 | stream.next_in = s_inbuf; 155 | stream.avail_in = n; 156 | 157 | infile_remaining -= n; 158 | //printf("Input bytes remaining: %u\n", infile_remaining); 159 | } 160 | 161 | status = deflate(&stream, infile_remaining ? Z_NO_FLUSH : Z_FINISH); 162 | 163 | if ((status == Z_STREAM_END) || (!stream.avail_out)) 164 | { 165 | // Output buffer is full, or compression is done, so write buffer to output file. 166 | uint n = BUF_SIZE - stream.avail_out; 167 | if (fwrite(s_outbuf, 1, n, pOutfile) != n) 168 | { 169 | printf("Failed writing to output file!\n"); 170 | return EXIT_FAILURE; 171 | } 172 | stream.next_out = s_outbuf; 173 | stream.avail_out = BUF_SIZE; 174 | } 175 | 176 | if (status == Z_STREAM_END) 177 | break; 178 | else if (status != Z_OK) 179 | { 180 | printf("deflate() failed with status %i!\n", status); 181 | return EXIT_FAILURE; 182 | } 183 | } 184 | 185 | if (deflateEnd(&stream) != Z_OK) 186 | { 187 | printf("deflateEnd() failed!\n"); 188 | return EXIT_FAILURE; 189 | } 190 | } 191 | else if ((pMode[0] == 'd') || (pMode[0] == 'D')) 192 | { 193 | // Decompression. 194 | uint infile_remaining = infile_size; 195 | 196 | if (inflateInit(&stream)) 197 | { 198 | printf("inflateInit() failed!\n"); 199 | return EXIT_FAILURE; 200 | } 201 | 202 | for ( ; ; ) 203 | { 204 | int status; 205 | if (!stream.avail_in) 206 | { 207 | // Input buffer is empty, so read more bytes from input file. 208 | uint n = my_min(BUF_SIZE, infile_remaining); 209 | 210 | if (fread(s_inbuf, 1, n, pInfile) != n) 211 | { 212 | printf("Failed reading from input file!\n"); 213 | return EXIT_FAILURE; 214 | } 215 | 216 | stream.next_in = s_inbuf; 217 | stream.avail_in = n; 218 | 219 | infile_remaining -= n; 220 | } 221 | 222 | status = inflate(&stream, Z_SYNC_FLUSH); 223 | 224 | if ((status == Z_STREAM_END) || (!stream.avail_out)) 225 | { 226 | // Output buffer is full, or decompression is done, so write buffer to output file. 227 | uint n = BUF_SIZE - stream.avail_out; 228 | if (fwrite(s_outbuf, 1, n, pOutfile) != n) 229 | { 230 | printf("Failed writing to output file!\n"); 231 | return EXIT_FAILURE; 232 | } 233 | stream.next_out = s_outbuf; 234 | stream.avail_out = BUF_SIZE; 235 | } 236 | 237 | if (status == Z_STREAM_END) 238 | break; 239 | else if (status != Z_OK) 240 | { 241 | printf("inflate() failed with status %i!\n", status); 242 | return EXIT_FAILURE; 243 | } 244 | } 245 | 246 | if (inflateEnd(&stream) != Z_OK) 247 | { 248 | printf("inflateEnd() failed!\n"); 249 | return EXIT_FAILURE; 250 | } 251 | } 252 | else 253 | { 254 | printf("Invalid mode!\n"); 255 | return EXIT_FAILURE; 256 | } 257 | 258 | fclose(pInfile); 259 | if (EOF == fclose(pOutfile)) 260 | { 261 | printf("Failed writing to output file!\n"); 262 | return EXIT_FAILURE; 263 | } 264 | 265 | printf("Total input bytes: %u\n", (mz_uint32)stream.total_in); 266 | printf("Total output bytes: %u\n", (mz_uint32)stream.total_out); 267 | printf("Success.\n"); 268 | return EXIT_SUCCESS; 269 | } 270 | -------------------------------------------------------------------------------- /mac-cpp-source/libs/miniz-3.0.2/examples/example4.c: -------------------------------------------------------------------------------- 1 | // example4.c - Uses tinfl.c to decompress a zlib stream in memory to an output file 2 | // Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. 3 | #include "miniz.h" 4 | #include 5 | #include 6 | 7 | typedef unsigned char uint8; 8 | typedef unsigned short uint16; 9 | typedef unsigned int uint; 10 | 11 | #define my_max(a,b) (((a) > (b)) ? (a) : (b)) 12 | #define my_min(a,b) (((a) < (b)) ? (a) : (b)) 13 | 14 | static int tinfl_put_buf_func(const void* pBuf, int len, void *pUser) 15 | { 16 | return len == (int)fwrite(pBuf, 1, len, (FILE*)pUser); 17 | } 18 | 19 | int main(int argc, char *argv[]) 20 | { 21 | int status; 22 | FILE *pInfile, *pOutfile; 23 | uint infile_size, outfile_size; 24 | size_t in_buf_size; 25 | uint8 *pCmp_data; 26 | long file_loc; 27 | 28 | if (argc != 3) 29 | { 30 | printf("Usage: example4 infile outfile\n"); 31 | printf("Decompresses zlib stream in file infile to file outfile.\n"); 32 | printf("Input file must be able to fit entirely in memory.\n"); 33 | printf("example3 can be used to create compressed zlib streams.\n"); 34 | return EXIT_FAILURE; 35 | } 36 | 37 | // Open input file. 38 | pInfile = fopen(argv[1], "rb"); 39 | if (!pInfile) 40 | { 41 | printf("Failed opening input file!\n"); 42 | return EXIT_FAILURE; 43 | } 44 | 45 | // Determine input file's size. 46 | fseek(pInfile, 0, SEEK_END); 47 | file_loc = ftell(pInfile); 48 | fseek(pInfile, 0, SEEK_SET); 49 | 50 | if ((file_loc < 0) || ((mz_uint64)file_loc > INT_MAX)) 51 | { 52 | // This is not a limitation of miniz or tinfl, but this example. 53 | printf("File is too large to be processed by this example.\n"); 54 | return EXIT_FAILURE; 55 | } 56 | 57 | infile_size = (uint)file_loc; 58 | 59 | pCmp_data = (uint8 *)malloc(infile_size); 60 | if (!pCmp_data) 61 | { 62 | printf("Out of memory!\n"); 63 | return EXIT_FAILURE; 64 | } 65 | if (fread(pCmp_data, 1, infile_size, pInfile) != infile_size) 66 | { 67 | printf("Failed reading input file!\n"); 68 | return EXIT_FAILURE; 69 | } 70 | 71 | // Open output file. 72 | pOutfile = fopen(argv[2], "wb"); 73 | if (!pOutfile) 74 | { 75 | printf("Failed opening output file!\n"); 76 | return EXIT_FAILURE; 77 | } 78 | 79 | printf("Input file size: %u\n", infile_size); 80 | 81 | in_buf_size = infile_size; 82 | status = tinfl_decompress_mem_to_callback(pCmp_data, &in_buf_size, tinfl_put_buf_func, pOutfile, TINFL_FLAG_PARSE_ZLIB_HEADER); 83 | if (!status) 84 | { 85 | printf("tinfl_decompress_mem_to_callback() failed with status %i!\n", status); 86 | return EXIT_FAILURE; 87 | } 88 | 89 | outfile_size = ftell(pOutfile); 90 | 91 | fclose(pInfile); 92 | if (EOF == fclose(pOutfile)) 93 | { 94 | printf("Failed writing to output file!\n"); 95 | return EXIT_FAILURE; 96 | } 97 | 98 | printf("Total input bytes: %u\n", (uint)in_buf_size); 99 | printf("Total output bytes: %u\n", outfile_size); 100 | printf("Success.\n"); 101 | return EXIT_SUCCESS; 102 | } 103 | -------------------------------------------------------------------------------- /mac-cpp-source/libs/miniz-3.0.2/examples/example5.c: -------------------------------------------------------------------------------- 1 | // example5.c - Demonstrates how to use miniz.c's low-level tdefl_compress() and tinfl_inflate() API's for simple file to file compression/decompression. 2 | // The low-level API's are the fastest, make no use of dynamic memory allocation, and are the most flexible functions exposed by miniz.c. 3 | // Public domain, April 11 2012, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. 4 | // For simplicity, this example is limited to files smaller than 4GB, but this is not a limitation of miniz.c. 5 | 6 | // Purposely disable a whole bunch of stuff this low-level example doesn't use. 7 | #define MINIZ_NO_STDIO 8 | #define MINIZ_NO_ARCHIVE_APIS 9 | #define MINIZ_NO_TIME 10 | #define MINIZ_NO_ZLIB_APIS 11 | #define MINIZ_NO_MALLOC 12 | #include "miniz.h" 13 | 14 | // Now include stdio.h because this test uses fopen(), etc. (but we still don't want miniz.c's stdio stuff, for testing). 15 | #include 16 | #include 17 | 18 | typedef unsigned char uint8; 19 | typedef unsigned short uint16; 20 | typedef unsigned int uint; 21 | 22 | #define my_max(a,b) (((a) > (b)) ? (a) : (b)) 23 | #define my_min(a,b) (((a) < (b)) ? (a) : (b)) 24 | 25 | // IN_BUF_SIZE is the size of the file read buffer. 26 | // IN_BUF_SIZE must be >= 1 27 | #define IN_BUF_SIZE (1024*512) 28 | static uint8 s_inbuf[IN_BUF_SIZE]; 29 | 30 | // COMP_OUT_BUF_SIZE is the size of the output buffer used during compression. 31 | // COMP_OUT_BUF_SIZE must be >= 1 and <= OUT_BUF_SIZE 32 | #define COMP_OUT_BUF_SIZE (1024*512) 33 | 34 | // OUT_BUF_SIZE is the size of the output buffer used during decompression. 35 | // OUT_BUF_SIZE must be a power of 2 >= TINFL_LZ_DICT_SIZE (because the low-level decompressor not only writes, but reads from the output buffer as it decompresses) 36 | //#define OUT_BUF_SIZE (TINFL_LZ_DICT_SIZE) 37 | #define OUT_BUF_SIZE (1024*512) 38 | static uint8 s_outbuf[OUT_BUF_SIZE]; 39 | 40 | // tdefl_compressor contains all the state needed by the low-level compressor so it's a pretty big struct (~300k). 41 | // This example makes it a global vs. putting it on the stack, of course in real-world usage you'll probably malloc() or new it. 42 | tdefl_compressor g_deflator; 43 | 44 | int main(int argc, char *argv[]) 45 | { 46 | const char *pMode; 47 | FILE *pInfile, *pOutfile; 48 | uint infile_size; 49 | int level = 9; 50 | int p = 1; 51 | const char *pSrc_filename; 52 | const char *pDst_filename; 53 | const void *next_in = s_inbuf; 54 | size_t avail_in = 0; 55 | void *next_out = s_outbuf; 56 | size_t avail_out = OUT_BUF_SIZE; 57 | size_t total_in = 0, total_out = 0; 58 | long file_loc; 59 | 60 | assert(COMP_OUT_BUF_SIZE <= OUT_BUF_SIZE); 61 | 62 | printf("miniz.c example5 (demonstrates tinfl/tdefl)\n"); 63 | 64 | if (argc < 4) 65 | { 66 | printf("File to file compression/decompression using the low-level tinfl/tdefl API's.\n"); 67 | printf("Usage: example5 [options] [mode:c or d] infile outfile\n"); 68 | printf("\nModes:\n"); 69 | printf("c - Compresses file infile to a zlib stream in file outfile\n"); 70 | printf("d - Decompress zlib stream in file infile to file outfile\n"); 71 | printf("\nOptions:\n"); 72 | printf("-l[0-10] - Compression level, higher values are slower, 0 is none.\n"); 73 | return EXIT_FAILURE; 74 | } 75 | 76 | while ((p < argc) && (argv[p][0] == '-')) 77 | { 78 | switch (argv[p][1]) 79 | { 80 | case 'l': 81 | { 82 | level = atoi(&argv[1][2]); 83 | if ((level < 0) || (level > 10)) 84 | { 85 | printf("Invalid level!\n"); 86 | return EXIT_FAILURE; 87 | } 88 | break; 89 | } 90 | default: 91 | { 92 | printf("Invalid option: %s\n", argv[p]); 93 | return EXIT_FAILURE; 94 | } 95 | } 96 | p++; 97 | } 98 | 99 | if ((argc - p) < 3) 100 | { 101 | printf("Must specify mode, input filename, and output filename after options!\n"); 102 | return EXIT_FAILURE; 103 | } 104 | else if ((argc - p) > 3) 105 | { 106 | printf("Too many filenames!\n"); 107 | return EXIT_FAILURE; 108 | } 109 | 110 | pMode = argv[p++]; 111 | if (!strchr("cCdD", pMode[0])) 112 | { 113 | printf("Invalid mode!\n"); 114 | return EXIT_FAILURE; 115 | } 116 | 117 | pSrc_filename = argv[p++]; 118 | pDst_filename = argv[p++]; 119 | 120 | printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename); 121 | 122 | // Open input file. 123 | pInfile = fopen(pSrc_filename, "rb"); 124 | if (!pInfile) 125 | { 126 | printf("Failed opening input file!\n"); 127 | return EXIT_FAILURE; 128 | } 129 | 130 | // Determine input file's size. 131 | fseek(pInfile, 0, SEEK_END); 132 | file_loc = ftell(pInfile); 133 | fseek(pInfile, 0, SEEK_SET); 134 | 135 | if ((file_loc < 0) || ((mz_uint64)file_loc > INT_MAX)) 136 | { 137 | // This is not a limitation of miniz or tinfl, but this example. 138 | printf("File is too large to be processed by this example.\n"); 139 | return EXIT_FAILURE; 140 | } 141 | 142 | infile_size = (uint)file_loc; 143 | 144 | // Open output file. 145 | pOutfile = fopen(pDst_filename, "wb"); 146 | if (!pOutfile) 147 | { 148 | printf("Failed opening output file!\n"); 149 | return EXIT_FAILURE; 150 | } 151 | 152 | printf("Input file size: %u\n", infile_size); 153 | 154 | if ((pMode[0] == 'c') || (pMode[0] == 'C')) 155 | { 156 | // The number of dictionary probes to use at each compression level (0-10). 0=implies fastest/minimal possible probing. 157 | static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; 158 | 159 | tdefl_status status; 160 | uint infile_remaining = infile_size; 161 | 162 | // create tdefl() compatible flags (we have to compose the low-level flags ourselves, or use tdefl_create_comp_flags_from_zip_params() but that means MINIZ_NO_ZLIB_APIS can't be defined). 163 | mz_uint comp_flags = TDEFL_WRITE_ZLIB_HEADER | s_tdefl_num_probes[MZ_MIN(10, level)] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); 164 | if (!level) 165 | comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; 166 | 167 | // Initialize the low-level compressor. 168 | status = tdefl_init(&g_deflator, NULL, NULL, comp_flags); 169 | if (status != TDEFL_STATUS_OKAY) 170 | { 171 | printf("tdefl_init() failed!\n"); 172 | return EXIT_FAILURE; 173 | } 174 | 175 | avail_out = COMP_OUT_BUF_SIZE; 176 | 177 | // Compression. 178 | for ( ; ; ) 179 | { 180 | size_t in_bytes, out_bytes; 181 | 182 | if (!avail_in) 183 | { 184 | // Input buffer is empty, so read more bytes from input file. 185 | uint n = my_min(IN_BUF_SIZE, infile_remaining); 186 | 187 | if (fread(s_inbuf, 1, n, pInfile) != n) 188 | { 189 | printf("Failed reading from input file!\n"); 190 | return EXIT_FAILURE; 191 | } 192 | 193 | next_in = s_inbuf; 194 | avail_in = n; 195 | 196 | infile_remaining -= n; 197 | //printf("Input bytes remaining: %u\n", infile_remaining); 198 | } 199 | 200 | in_bytes = avail_in; 201 | out_bytes = avail_out; 202 | // Compress as much of the input as possible (or all of it) to the output buffer. 203 | status = tdefl_compress(&g_deflator, next_in, &in_bytes, next_out, &out_bytes, infile_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH); 204 | 205 | next_in = (const char *)next_in + in_bytes; 206 | avail_in -= in_bytes; 207 | total_in += in_bytes; 208 | 209 | next_out = (char *)next_out + out_bytes; 210 | avail_out -= out_bytes; 211 | total_out += out_bytes; 212 | 213 | if ((status != TDEFL_STATUS_OKAY) || (!avail_out)) 214 | { 215 | // Output buffer is full, or compression is done or failed, so write buffer to output file. 216 | uint n = COMP_OUT_BUF_SIZE - (uint)avail_out; 217 | if (fwrite(s_outbuf, 1, n, pOutfile) != n) 218 | { 219 | printf("Failed writing to output file!\n"); 220 | return EXIT_FAILURE; 221 | } 222 | next_out = s_outbuf; 223 | avail_out = COMP_OUT_BUF_SIZE; 224 | } 225 | 226 | if (status == TDEFL_STATUS_DONE) 227 | { 228 | // Compression completed successfully. 229 | break; 230 | } 231 | else if (status != TDEFL_STATUS_OKAY) 232 | { 233 | // Compression somehow failed. 234 | printf("tdefl_compress() failed with status %i!\n", status); 235 | return EXIT_FAILURE; 236 | } 237 | } 238 | } 239 | else if ((pMode[0] == 'd') || (pMode[0] == 'D')) 240 | { 241 | // Decompression. 242 | uint infile_remaining = infile_size; 243 | 244 | tinfl_decompressor inflator; 245 | tinfl_init(&inflator); 246 | 247 | for ( ; ; ) 248 | { 249 | size_t in_bytes, out_bytes; 250 | tinfl_status status; 251 | if (!avail_in) 252 | { 253 | // Input buffer is empty, so read more bytes from input file. 254 | uint n = my_min(IN_BUF_SIZE, infile_remaining); 255 | 256 | if (fread(s_inbuf, 1, n, pInfile) != n) 257 | { 258 | printf("Failed reading from input file!\n"); 259 | return EXIT_FAILURE; 260 | } 261 | 262 | next_in = s_inbuf; 263 | avail_in = n; 264 | 265 | infile_remaining -= n; 266 | } 267 | 268 | in_bytes = avail_in; 269 | out_bytes = avail_out; 270 | status = tinfl_decompress(&inflator, (const mz_uint8 *)next_in, &in_bytes, s_outbuf, (mz_uint8 *)next_out, &out_bytes, (infile_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0) | TINFL_FLAG_PARSE_ZLIB_HEADER); 271 | 272 | avail_in -= in_bytes; 273 | next_in = (const mz_uint8 *)next_in + in_bytes; 274 | total_in += in_bytes; 275 | 276 | avail_out -= out_bytes; 277 | next_out = (mz_uint8 *)next_out + out_bytes; 278 | total_out += out_bytes; 279 | 280 | if ((status <= TINFL_STATUS_DONE) || (!avail_out)) 281 | { 282 | // Output buffer is full, or decompression is done, so write buffer to output file. 283 | uint n = OUT_BUF_SIZE - (uint)avail_out; 284 | if (fwrite(s_outbuf, 1, n, pOutfile) != n) 285 | { 286 | printf("Failed writing to output file!\n"); 287 | return EXIT_FAILURE; 288 | } 289 | next_out = s_outbuf; 290 | avail_out = OUT_BUF_SIZE; 291 | } 292 | 293 | // If status is <= TINFL_STATUS_DONE then either decompression is done or something went wrong. 294 | if (status <= TINFL_STATUS_DONE) 295 | { 296 | if (status == TINFL_STATUS_DONE) 297 | { 298 | // Decompression completed successfully. 299 | break; 300 | } 301 | else 302 | { 303 | // Decompression failed. 304 | printf("tinfl_decompress() failed with status %i!\n", status); 305 | return EXIT_FAILURE; 306 | } 307 | } 308 | } 309 | } 310 | else 311 | { 312 | printf("Invalid mode!\n"); 313 | return EXIT_FAILURE; 314 | } 315 | 316 | fclose(pInfile); 317 | if (EOF == fclose(pOutfile)) 318 | { 319 | printf("Failed writing to output file!\n"); 320 | return EXIT_FAILURE; 321 | } 322 | 323 | printf("Total input bytes: %u\n", (mz_uint32)total_in); 324 | printf("Total output bytes: %u\n", (mz_uint32)total_out); 325 | printf("Success.\n"); 326 | return EXIT_SUCCESS; 327 | } 328 | -------------------------------------------------------------------------------- /mac-cpp-source/libs/miniz-3.0.2/examples/example6.c: -------------------------------------------------------------------------------- 1 | // example6.c - Demonstrates how to miniz's PNG writer func 2 | // Public domain, April 11 2012, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c. 3 | // Mandlebrot set code from http://rosettacode.org/wiki/Mandelbrot_set#C 4 | // Must link this example against libm on Linux. 5 | 6 | // Purposely disable a whole bunch of stuff this low-level example doesn't use. 7 | #define MINIZ_NO_STDIO 8 | #define MINIZ_NO_TIME 9 | #define MINIZ_NO_ZLIB_APIS 10 | #include "miniz.h" 11 | 12 | // Now include stdio.h because this test uses fopen(), etc. (but we still don't want miniz.c's stdio stuff, for testing). 13 | #include 14 | #include 15 | #include 16 | 17 | typedef unsigned char uint8; 18 | typedef unsigned short uint16; 19 | typedef unsigned int uint; 20 | 21 | typedef struct 22 | { 23 | uint8 r, g, b; 24 | } rgb_t; 25 | 26 | static void hsv_to_rgb(int hue, int min, int max, rgb_t *p) 27 | { 28 | const int invert = 0; 29 | const int saturation = 1; 30 | const int color_rotate = 0; 31 | 32 | if (min == max) max = min + 1; 33 | if (invert) hue = max - (hue - min); 34 | if (!saturation) { 35 | p->r = p->g = p->b = 255 * (max - hue) / (max - min); 36 | return; 37 | } else { 38 | const double h_dbl = fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6); 39 | const double c_dbl = 255 * saturation; 40 | const double X_dbl = c_dbl * (1 - fabs(fmod(h_dbl, 2) - 1)); 41 | const int h = (int)h_dbl; 42 | const int c = (int)c_dbl; 43 | const int X = (int)X_dbl; 44 | 45 | p->r = p->g = p->b = 0; 46 | 47 | switch(h) { 48 | case 0: p->r = c; p->g = X; return; 49 | case 1: p->r = X; p->g = c; return; 50 | case 2: p->g = c; p->b = X; return; 51 | case 3: p->g = X; p->b = c; return; 52 | case 4: p->r = X; p->b = c; return; 53 | default:p->r = c; p->b = X; 54 | } 55 | } 56 | } 57 | 58 | int main(int argc, char *argv[]) 59 | { 60 | // Image resolution 61 | const int iXmax = 4096; 62 | const int iYmax = 4096; 63 | 64 | // Output filename 65 | static const char *pFilename = "mandelbrot.png"; 66 | 67 | int iX, iY; 68 | const double CxMin = -2.5; 69 | const double CxMax = 1.5; 70 | const double CyMin = -2.0; 71 | const double CyMax = 2.0; 72 | 73 | double PixelWidth = (CxMax - CxMin) / iXmax; 74 | double PixelHeight = (CyMax - CyMin) / iYmax; 75 | 76 | // Z=Zx+Zy*i ; Z0 = 0 77 | double Zx, Zy; 78 | double Zx2, Zy2; // Zx2=Zx*Zx; Zy2=Zy*Zy 79 | 80 | int Iteration; 81 | const int IterationMax = 200; 82 | 83 | // bail-out value , radius of circle 84 | const double EscapeRadius = 2; 85 | double ER2=EscapeRadius * EscapeRadius; 86 | 87 | uint8 *pImage = (uint8 *)malloc(iXmax * 3 * iYmax); 88 | 89 | // world ( double) coordinate = parameter plane 90 | double Cx,Cy; 91 | 92 | int MinIter = 9999, MaxIter = 0; 93 | 94 | (void)argc, (void)argv; 95 | 96 | for(iY = 0; iY < iYmax; iY++) 97 | { 98 | Cy = CyMin + iY * PixelHeight; 99 | if (fabs(Cy) < PixelHeight/2) 100 | Cy = 0.0; // Main antenna 101 | 102 | for(iX = 0; iX < iXmax; iX++) 103 | { 104 | uint8 *color = pImage + (iX * 3) + (iY * iXmax * 3); 105 | 106 | Cx = CxMin + iX * PixelWidth; 107 | 108 | // initial value of orbit = critical point Z= 0 109 | Zx = 0.0; 110 | Zy = 0.0; 111 | Zx2 = Zx * Zx; 112 | Zy2 = Zy * Zy; 113 | 114 | for (Iteration=0;Iteration> 8; 124 | color[2] = 0; 125 | 126 | if (Iteration < MinIter) 127 | MinIter = Iteration; 128 | if (Iteration > MaxIter) 129 | MaxIter = Iteration; 130 | } 131 | } 132 | 133 | for(iY = 0; iY < iYmax; iY++) 134 | { 135 | for(iX = 0; iX < iXmax; iX++) 136 | { 137 | uint8 *color = (uint8 *)(pImage + (iX * 3) + (iY * iXmax * 3)); 138 | 139 | uint Iterations = color[0] | (color[1] << 8U); 140 | 141 | hsv_to_rgb((int)Iterations, MinIter, MaxIter, (rgb_t *)color); 142 | } 143 | } 144 | 145 | // Now write the PNG image. 146 | { 147 | size_t png_data_size = 0; 148 | void *pPNG_data = tdefl_write_image_to_png_file_in_memory_ex(pImage, iXmax, iYmax, 3, &png_data_size, 6, MZ_FALSE); 149 | if (!pPNG_data) 150 | fprintf(stderr, "tdefl_write_image_to_png_file_in_memory_ex() failed!\n"); 151 | else 152 | { 153 | FILE *pFile = fopen(pFilename, "wb"); 154 | fwrite(pPNG_data, 1, png_data_size, pFile); 155 | fclose(pFile); 156 | printf("Wrote %s\n", pFilename); 157 | } 158 | 159 | // mz_free() is by default just an alias to free() internally, but if you've overridden miniz's allocation funcs you'll probably need to call mz_free(). 160 | mz_free(pPNG_data); 161 | } 162 | 163 | free(pImage); 164 | 165 | return EXIT_SUCCESS; 166 | } 167 | -------------------------------------------------------------------------------- /mac-cpp-source/libs/miniz-3.0.2/readme.md: -------------------------------------------------------------------------------- 1 | ## Miniz 2 | 3 | Miniz is a lossless, high performance data compression library in a single source file that implements the zlib (RFC 1950) and Deflate (RFC 1951) compressed data format specification standards. It supports the most commonly used functions exported by the zlib library, but is a completely independent implementation so zlib's licensing requirements do not apply. Miniz also contains simple to use functions for writing .PNG format image files and reading/writing/appending .ZIP format archives. Miniz's compression speed has been tuned to be comparable to zlib's, and it also has a specialized real-time compressor function designed to compare well against fastlz/minilzo. 4 | 5 | ## Usage 6 | 7 | Releases are available at the [releases page](https://github.com/richgel999/miniz/releases) as a pair of `miniz.c`/`miniz.h` files which can be simply added to a project. To create this file pair the different source and header files are [amalgamated](https://www.sqlite.org/amalgamation.html) during build. Alternatively use as cmake or meson module (or build system of your choice). 8 | 9 | ## Features 10 | 11 | * MIT licensed 12 | * A portable, single source and header file library written in plain C. Tested with GCC, clang and Visual Studio. 13 | * Easily tuned and trimmed down by defines 14 | * A drop-in replacement for zlib's most used API's (tested in several open source projects that use zlib, such as libpng and libzip). 15 | * Fills a single threaded performance vs. compression ratio gap between several popular real-time compressors and zlib. For example, at level 1, miniz.c compresses around 5-9% better than minilzo, but is approx. 35% slower. At levels 2-9, miniz.c is designed to compare favorably against zlib's ratio and speed. See the miniz performance comparison page for example timings. 16 | * Not a block based compressor: miniz.c fully supports stream based processing using a coroutine-style implementation. The zlib-style API functions can be called a single byte at a time if that's all you've got. 17 | * Easy to use. The low-level compressor (tdefl) and decompressor (tinfl) have simple state structs which can be saved/restored as needed with simple memcpy's. The low-level codec API's don't use the heap in any way. 18 | * Entire inflater (including optional zlib header parsing and Adler-32 checking) is implemented in a single function as a coroutine, which is separately available in a small (~550 line) source file: miniz_tinfl.c 19 | * A fairly complete (but totally optional) set of .ZIP archive manipulation and extraction API's. The archive functionality is intended to solve common problems encountered in embedded, mobile, or game development situations. (The archive API's are purposely just powerful enough to write an entire archiver given a bit of additional higher-level logic.) 20 | 21 | ## Building miniz - Using vcpkg 22 | 23 | You can download and install miniz using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager: 24 | 25 | git clone https://github.com/Microsoft/vcpkg.git 26 | cd vcpkg 27 | ./bootstrap-vcpkg.sh 28 | ./vcpkg integrate install 29 | ./vcpkg install miniz 30 | 31 | The miniz port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. 32 | 33 | ## Known Problems 34 | 35 | * No support for encrypted archives. Not sure how useful this stuff is in practice. 36 | * Minimal documentation. The assumption is that the user is already familiar with the basic zlib API. I need to write an API wiki - for now I've tried to place key comments before each enum/API, and I've included 6 examples that demonstrate how to use the module's major features. 37 | 38 | ## Special Thanks 39 | 40 | Thanks to Alex Evans for the PNG writer function. Also, thanks to Paul Holden and Thorsten Scheuermann for feedback and testing, Matt Pritchard for all his encouragement, and Sean Barrett's various public domain libraries for inspiration (and encouraging me to write miniz.c in C, which was much more enjoyable and less painful than I thought it would be considering I've been programming in C++ for so long). 41 | 42 | Thanks to Bruce Dawson for reporting a problem with the level_and_flags archive API parameter (which is fixed in v1.12) and general feedback, and Janez Zemva for indirectly encouraging me into writing more examples. 43 | 44 | ## Patents 45 | 46 | I was recently asked if miniz avoids patent issues. miniz purposely uses the same core algorithms as the ones used by zlib. The compressor uses vanilla hash chaining as described [here](https://datatracker.ietf.org/doc/html/rfc1951#section-4). Also see the [gzip FAQ](https://web.archive.org/web/20160308045258/http://www.gzip.org/#faq11). In my opinion, if miniz falls prey to a patent attack then zlib/gzip are likely to be at serious risk too. 47 | -------------------------------------------------------------------------------- /mac-cpp-source/main.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marciot/mac-minivnc/5941457e1fca5f676dadea0008f64225a4543a27/mac-cpp-source/main.cpp --------------------------------------------------------------------------------