├── .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
--------------------------------------------------------------------------------