Compare commits
10 Commits
ce77fec0fe
...
18a363a8e0
Author | SHA1 | Date |
---|---|---|
camh | 18a363a8e0 | |
camh | 167c0f26db | |
camh | bcee165621 | |
camh | 069ba4fd70 | |
camh | cd226cec7f | |
camh | a961612de3 | |
camh | 62e53b6012 | |
Cameron Henlin | 8d0e729faa | |
Cameron Henlin | b27acc5a2d | |
camh | 2b3f87be58 |
|
@ -1,7 +1,7 @@
|
||||||
# Messages For Macintosh
|
# Messages For Macintosh
|
||||||
Messages for Macintosh is a software suite for classic Macintosh (System 2.0 through MacOS 9.2.2) systems to interoperate with Apple iMessages via a familiar interface, with [supporting software](https://github.com/CamHenlin/imessagegraphqlserver) running on a newer Mac computer.
|
Messages for Macintosh is a software suite for classic Macintosh (System 2.0 through MacOS 9.2.2) systems to interoperate with Apple iMessages via a familiar interface, with [supporting software](https://github.com/CamHenlin/imessagegraphqlserver) running on a newer Mac computer.
|
||||||
|
|
||||||
![messages for macintosh](/images/messagesformacintosh.png)
|
![messages for macintosh](https://henlin.net/images/messagesformacintosh.png)
|
||||||
|
|
||||||
## How to use Messages for Macintosh
|
## How to use Messages for Macintosh
|
||||||
There are two setup guides for Messages for Macintosh:
|
There are two setup guides for Messages for Macintosh:
|
||||||
|
@ -13,7 +13,7 @@ There are two setup guides for Messages for Macintosh:
|
||||||
Messages for Macintosh is built on a lot of technologies. The READMEs of each of these is each worth familiarizing yourself with if you would like to contribute to Messages for Macintosh:
|
Messages for Macintosh is built on a lot of technologies. The READMEs of each of these is each worth familiarizing yourself with if you would like to contribute to Messages for Macintosh:
|
||||||
|
|
||||||
- [Retro68](https://github.com/autc04/Retro68) - a GCC-based cross compilation env for classic Macintosh systems
|
- [Retro68](https://github.com/autc04/Retro68) - a GCC-based cross compilation env for classic Macintosh systems
|
||||||
- [Nuklear Quickdraw](https://github.com/CamHenlin/nuklear-quickdraw) - a heavily modified, Macintosh-specific version of [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) allowing a simple way to provide GUI services
|
- [Nuklear Quickdraw](https://github.com/CamHenlin/nuklear-quickdraw) - a heavily modified, classic Macintosh-specific version of [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) allowing a simple way to provide GUI services
|
||||||
- [CoprocessorJS](https://github.com/CamHenlin/coprocessor.js) - a library that allows us to handle nodejs workloads sent over a serial port
|
- [CoprocessorJS](https://github.com/CamHenlin/coprocessor.js) - a library that allows us to handle nodejs workloads sent over a serial port
|
||||||
- [serialperformanceanalyzer](https://github.com/CamHenlin/serialperformanceanalyzer) - used to analyze the performance of many different parts of the application
|
- [serialperformanceanalyzer](https://github.com/CamHenlin/serialperformanceanalyzer) - used to analyze the performance of many different parts of the application
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
IOParam outgoingSerialPortReference;
|
IOParam outgoingSerialPortReference;
|
||||||
IOParam incomingSerialPortReference;
|
IOParam incomingSerialPortReference;
|
||||||
// #define PRINT_ERRORS 1
|
// #define PRINT_ERRORS 1
|
||||||
// #define DEBUGGING 1
|
#define DEBUGGING 1
|
||||||
#define MAX_ATTEMPTS 10
|
#define MAX_ATTEMPTS 10
|
||||||
#define RECEIVE_WINDOW_SIZE 32767 // receive in up to 32kb chunks
|
#define RECEIVE_WINDOW_SIZE 32767 // receive in up to 32kb chunks
|
||||||
#define MAX_RECEIVE_SIZE 32767 // matching RECEIVE_WINDOW_SIZE for now
|
#define MAX_RECEIVE_SIZE 32767 // matching RECEIVE_WINDOW_SIZE for now
|
||||||
|
@ -225,6 +225,7 @@ void readSerialPort(char* output) {
|
||||||
|
|
||||||
// make sure output variable is clear
|
// make sure output variable is clear
|
||||||
memset(output, '\0', MAX_RECEIVE_SIZE);
|
memset(output, '\0', MAX_RECEIVE_SIZE);
|
||||||
|
memset(tempOutput, '\0', MAX_RECEIVE_SIZE);
|
||||||
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
long int totalByteCount = 0;
|
long int totalByteCount = 0;
|
||||||
|
@ -326,7 +327,7 @@ void readSerialPort(char* output) {
|
||||||
|
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
|
|
||||||
writeSerialPortDebug(boutRefNum, "done building temp output\n");
|
writeSerialPortDebug(boutRefNum, "done building temp output");
|
||||||
writeSerialPortDebug(boutRefNum, tempOutput);
|
writeSerialPortDebug(boutRefNum, tempOutput);
|
||||||
|
|
||||||
// char debugOutput[255];
|
// char debugOutput[255];
|
||||||
|
@ -343,7 +344,7 @@ void readSerialPort(char* output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// attach the gathered up output from the buffer to the output variable
|
// attach the gathered up output from the buffer to the output variable
|
||||||
strncat(output, tempOutput, totalByteCount);
|
memcpy(output, tempOutput, totalByteCount);
|
||||||
|
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
writeSerialPortDebug(boutRefNum, "coprocessor.readSerialPort complete, output:");
|
writeSerialPortDebug(boutRefNum, "coprocessor.readSerialPort complete, output:");
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
// #define MAC_APP_DEBUGGING
|
// #define MAC_APP_DEBUGGING
|
||||||
// #define PROFILING 1
|
// #define PROFILING 1
|
||||||
// #define DEBUG_FUNCTION_CALLS
|
#define DEBUG_FUNCTION_CALLS
|
||||||
#ifdef PROFILING
|
#ifdef PROFILING
|
||||||
|
|
||||||
OSErr writeSerialPortProfile(const char* str)
|
OSErr writeSerialPortProfile(const char* str)
|
||||||
|
|
106
nuklear_app.c
106
nuklear_app.c
|
@ -15,69 +15,52 @@
|
||||||
|
|
||||||
// #define MESSAGES_FOR_MACINTOSH_DEBUGGING
|
// #define MESSAGES_FOR_MACINTOSH_DEBUGGING
|
||||||
|
|
||||||
// based on https://github.com/jwerle/strsplit.c -- cleaned up and modified to use strtokm rather than strtok
|
// based on https://github.com/mr21/strsplit.c/blob/master/strsplit.c
|
||||||
int strsplit (const char *str, char *parts[], const char *delimiter) {
|
static char** _strsplit( const char* s, const char* delim, int* nb ) {
|
||||||
|
|
||||||
#ifdef DEBUG_FUNCTION_CALLS
|
#ifdef DEBUG_FUNCTION_CALLS
|
||||||
writeSerialPortDebug(boutRefNum, "DEBUG_FUNCTION_CALLS: strsplit");
|
writeSerialPortDebug(boutRefNum, "DEBUG_FUNCTION_CALLS: _strsplit");
|
||||||
#endif
|
#endif
|
||||||
|
void* data;
|
||||||
|
char* _s = ( char* )s;
|
||||||
|
const char** ptrs;
|
||||||
|
int
|
||||||
|
ptrsSize,
|
||||||
|
nbWords = 1,
|
||||||
|
sLen = strlen( s ),
|
||||||
|
delimLen = strlen( delim );
|
||||||
|
|
||||||
char *pch;
|
while ( ( _s = strstr( _s, delim ) ) ) {
|
||||||
int i = 0;
|
_s += delimLen;
|
||||||
char *copy = NULL;
|
++nbWords;
|
||||||
char *tmp = NULL;
|
|
||||||
|
|
||||||
copy = strdup(str);
|
|
||||||
|
|
||||||
if (! copy) {
|
|
||||||
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
pch = strtokm(copy, delimiter);
|
|
||||||
|
|
||||||
tmp = strdup(pch);
|
|
||||||
|
|
||||||
if (!tmp) {
|
|
||||||
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
parts[i++] = tmp;
|
|
||||||
|
|
||||||
while (pch) {
|
|
||||||
|
|
||||||
pch = strtokm(NULL, delimiter);
|
|
||||||
|
|
||||||
if (NULL == pch) {
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
ptrsSize = ( nbWords + 1 ) * sizeof( char* );
|
||||||
tmp = strdup(pch);
|
ptrs =
|
||||||
|
data = malloc( ptrsSize + sLen + 1 );
|
||||||
if (! tmp) {
|
if ( data ) {
|
||||||
|
*ptrs =
|
||||||
goto bad;
|
_s = strcpy( ( ( char* )data ) + ptrsSize, s );
|
||||||
|
if ( nbWords > 1 ) {
|
||||||
|
while ( ( _s = strstr( _s, delim ) ) ) {
|
||||||
|
*_s = '\0';
|
||||||
|
_s += delimLen;
|
||||||
|
*++ptrs = _s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*++ptrs = NULL;
|
||||||
}
|
}
|
||||||
|
if ( nb ) {
|
||||||
|
*nb = data ? nbWords : 0;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
parts[i++] = tmp;
|
char** strsplit( const char* s, const char* delim ) {
|
||||||
}
|
return _strsplit( s, delim, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
free(copy);
|
char** strsplit_count( const char* s, const char* delim, int* nb ) {
|
||||||
|
return _strsplit( s, delim, nb );
|
||||||
return i;
|
|
||||||
|
|
||||||
bad:
|
|
||||||
|
|
||||||
free(copy);
|
|
||||||
|
|
||||||
for (int j = 0; j < i; j++) {
|
|
||||||
|
|
||||||
free(parts[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void aFailed(char *file, int line) {
|
void aFailed(char *file, int line) {
|
||||||
|
@ -232,8 +215,8 @@ void sendIPAddressToCoprocessor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up function to get messages in current chat
|
// set up function to get messages in current chat
|
||||||
// limit to recent messages
|
// limit to recent messages
|
||||||
// figure out pagination?? button on the top that says "get previous chats"?, TODO
|
// figure out pagination?? button on the top that says "get previous chats"?, TODO
|
||||||
void getMessages(char *thread, int page) {
|
void getMessages(char *thread, int page) {
|
||||||
|
|
||||||
#ifdef DEBUG_FUNCTION_CALLS
|
#ifdef DEBUG_FUNCTION_CALLS
|
||||||
|
@ -296,9 +279,8 @@ void getChatCounts() {
|
||||||
|
|
||||||
strcpy(tempChatCountFunctionResponse, chatCountFunctionResponse);
|
strcpy(tempChatCountFunctionResponse, chatCountFunctionResponse);
|
||||||
int chatCount = 0;
|
int chatCount = 0;
|
||||||
char *(*chats[16])[64];
|
|
||||||
|
|
||||||
chatCount = strsplit(tempChatCountFunctionResponse, (char **)chats, ",");
|
char **chats = strsplit_count(tempChatCountFunctionResponse, ",", &chatCount);
|
||||||
|
|
||||||
for (int chatLoopCounter = 0; chatLoopCounter < chatCount; chatLoopCounter++) {
|
for (int chatLoopCounter = 0; chatLoopCounter < chatCount; chatLoopCounter++) {
|
||||||
|
|
||||||
|
@ -320,9 +302,8 @@ void getChatCounts() {
|
||||||
|
|
||||||
strcpy(tempChatCountFunctionResponse, chatCountFunctionResponse);
|
strcpy(tempChatCountFunctionResponse, chatCountFunctionResponse);
|
||||||
int results = 0;
|
int results = 0;
|
||||||
char *(*chatUpdate[2])[64];
|
|
||||||
|
|
||||||
results = strsplit((char *)chats[chatLoopCounter], (char **)chatUpdate, ":::");
|
char **chatUpdate = strsplit_count((char *)chats[chatLoopCounter], ":::", &results);
|
||||||
|
|
||||||
if (results != 2) {
|
if (results != 2) {
|
||||||
|
|
||||||
|
@ -360,9 +341,8 @@ void getChatCounts() {
|
||||||
sprintf(chatName, "%.63s", &chatFriendlyNames[i * MAX_FRIENDLY_NAME_LENGTH]);
|
sprintf(chatName, "%.63s", &chatFriendlyNames[i * MAX_FRIENDLY_NAME_LENGTH]);
|
||||||
|
|
||||||
int updateResults = 0;
|
int updateResults = 0;
|
||||||
char *(*updatePieces[2])[64];
|
|
||||||
|
|
||||||
updateResults = strsplit(chatName, (char **)updatePieces, " new) ");
|
char **updatePieces = strsplit_count(chatName, " new) ", &updateResults);
|
||||||
|
|
||||||
if (updateResults != 2) {
|
if (updateResults != 2) {
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#define ENABLED_DOUBLE_BUFFERING
|
#define ENABLED_DOUBLE_BUFFERING
|
||||||
#define COMMAND_CACHING
|
#define COMMAND_CACHING
|
||||||
#include "nuklear.h"
|
#include "nuklear.h"
|
||||||
// #define NK_QUICKDRAW_GRAPHICS_DEBUGGING
|
#define NK_QUICKDRAW_GRAPHICS_DEBUGGING
|
||||||
// #define DRAW_BLIT_LOCATION
|
// #define DRAW_BLIT_LOCATION
|
||||||
|
|
||||||
Boolean lastInputWasBackspace;
|
Boolean lastInputWasBackspace;
|
||||||
|
@ -555,6 +555,7 @@ void updateBounds(int top, int bottom, int left, int right) {
|
||||||
// http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/QuickDraw/QuickDraw-102.html#MARKER-9-372
|
// http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/QuickDraw/QuickDraw-102.html#MARKER-9-372
|
||||||
// http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/QuickDraw/QuickDraw-103.html#HEADING103-0
|
// http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/QuickDraw/QuickDraw-103.html#HEADING103-0
|
||||||
const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
|
const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
|
||||||
|
writeSerialPortDebug(boutRefNum, "NK_COMMAND_RECT2");
|
||||||
|
|
||||||
#ifdef COMMAND_CACHING
|
#ifdef COMMAND_CACHING
|
||||||
|
|
||||||
|
@ -567,21 +568,26 @@ void updateBounds(int top, int bottom, int left, int right) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
writeSerialPortDebug(boutRefNum, "NK_COMMAND_RECT3");
|
||||||
|
|
||||||
ForeColor(r->color);
|
ForeColor(r->color);
|
||||||
PenSize(r->line_thickness, r->line_thickness);
|
PenSize(r->line_thickness, r->line_thickness);
|
||||||
|
writeSerialPortDebug(boutRefNum, "NK_COMMAND_RECT4");
|
||||||
|
|
||||||
Rect quickDrawRectangle;
|
Rect quickDrawRectangle;
|
||||||
quickDrawRectangle.top = r->y;
|
quickDrawRectangle.top = r->y;
|
||||||
quickDrawRectangle.left = r->x;
|
quickDrawRectangle.left = r->x;
|
||||||
quickDrawRectangle.bottom = r->y + r->h;
|
quickDrawRectangle.bottom = r->y + r->h;
|
||||||
quickDrawRectangle.right = r->x + r->w;
|
quickDrawRectangle.right = r->x + r->w;
|
||||||
|
writeSerialPortDebug(boutRefNum, "NK_COMMAND_RECT5");
|
||||||
|
|
||||||
#ifdef ENABLED_DOUBLE_BUFFERING
|
#ifdef ENABLED_DOUBLE_BUFFERING
|
||||||
updateBounds(quickDrawRectangle.top, quickDrawRectangle.bottom, quickDrawRectangle.left, quickDrawRectangle.right);
|
updateBounds(quickDrawRectangle.top, quickDrawRectangle.bottom, quickDrawRectangle.left, quickDrawRectangle.right);
|
||||||
#endif
|
#endif
|
||||||
|
writeSerialPortDebug(boutRefNum, "NK_COMMAND_RECT6");
|
||||||
|
|
||||||
FrameRoundRect(&quickDrawRectangle, r->rounding, r->rounding);
|
FrameRoundRect(&quickDrawRectangle, r->rounding, r->rounding);
|
||||||
|
writeSerialPortDebug(boutRefNum, "NK_COMMAND_RECT7 (done)");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1080,6 +1086,7 @@ void updateBounds(int top, int bottom, int left, int right) {
|
||||||
#ifdef COMMAND_CACHING
|
#ifdef COMMAND_CACHING
|
||||||
int lastCalls = 0;
|
int lastCalls = 0;
|
||||||
int currentCalls;
|
int currentCalls;
|
||||||
|
const struct nk_command *lastCmd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NK_API void nk_quickdraw_render(WindowPtr window, struct nk_context *ctx) {
|
NK_API void nk_quickdraw_render(WindowPtr window, struct nk_context *ctx) {
|
||||||
|
@ -1130,7 +1137,6 @@ NK_API void nk_quickdraw_render(WindowPtr window, struct nk_context *ctx) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef COMMAND_CACHING
|
#ifdef COMMAND_CACHING
|
||||||
const struct nk_command *lastCmd;
|
|
||||||
lastCmd = nk_ptr_add_const(struct nk_command, last, 0);
|
lastCmd = nk_ptr_add_const(struct nk_command, last, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1143,14 +1149,25 @@ NK_API void nk_quickdraw_render(WindowPtr window, struct nk_context *ctx) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef COMMAND_CACHING
|
#ifdef COMMAND_CACHING
|
||||||
|
|
||||||
|
#ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING
|
||||||
|
writeSerialPortDebug(boutRefNum, "COMMAND_CACHING: get next cached command");
|
||||||
|
#endif
|
||||||
// TODO: if this becomes worth pursuing later, it causes address errors. I suspect that the memcpy
|
// TODO: if this becomes worth pursuing later, it causes address errors. I suspect that the memcpy
|
||||||
// command that builds up the last variable is not properly allocating memory.
|
// command that builds up the last variable is not properly allocating memory.
|
||||||
// the address error pops up on the line of the conditional itself and can sometimes take hours to trigger.
|
// the address error pops up on the line of the conditional itself and can sometimes take hours to trigger.
|
||||||
if (currentCalls < lastCalls && lastCmd && lastCmd->next) {
|
if (currentCalls < lastCalls - 1 && lastCmd && lastCmd->next) {
|
||||||
|
|
||||||
|
#ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING
|
||||||
|
writeSerialPortDebug(boutRefNum, "COMMAND_CACHING: inside conditional");
|
||||||
|
#endif
|
||||||
|
|
||||||
lastCmd = nk_ptr_add_const(struct nk_command, last, lastCmd->next);
|
lastCmd = nk_ptr_add_const(struct nk_command, last, lastCmd->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NK_QUICKDRAW_GRAPHICS_DEBUGGING
|
||||||
|
writeSerialPortDebug(boutRefNum, "COMMAND_CACHING: done getting lastCmd");
|
||||||
|
#endif
|
||||||
currentCalls++;
|
currentCalls++;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1482,6 +1499,10 @@ NK_API struct nk_context* nk_quickdraw_init(unsigned int width, unsigned int hei
|
||||||
NkQuickDrawFont *quickdrawfont = nk_quickdraw_font_create_from_file();
|
NkQuickDrawFont *quickdrawfont = nk_quickdraw_font_create_from_file();
|
||||||
struct nk_user_font *font = &quickdrawfont->nk;
|
struct nk_user_font *font = &quickdrawfont->nk;
|
||||||
|
|
||||||
|
#ifdef COMMAND_CACHING
|
||||||
|
lastCmd = malloc(sizeof(struct nk_command));
|
||||||
|
#endif
|
||||||
|
|
||||||
last = calloc(1, MAX_MEMORY_IN_KB * 1024);
|
last = calloc(1, MAX_MEMORY_IN_KB * 1024);
|
||||||
buf = calloc(1, MAX_MEMORY_IN_KB * 1024);
|
buf = calloc(1, MAX_MEMORY_IN_KB * 1024);
|
||||||
nk_init_fixed(&quickdraw.nuklear_context, buf, MAX_MEMORY_IN_KB * 1024, font);
|
nk_init_fixed(&quickdraw.nuklear_context, buf, MAX_MEMORY_IN_KB * 1024, font);
|
||||||
|
|
Loading…
Reference in New Issue