diff --git a/src/conio/cterm.c b/src/conio/cterm.c index 1388bb373ebbad53bc4b47f09e44f4b38a6e0d32..f3753008d52496be12053b5576d4128bbf045d76 100644 --- a/src/conio/cterm.c +++ b/src/conio/cterm.c @@ -4399,7 +4399,7 @@ cterm_reset(struct cterminal *cterm) struct cterminal* cterm_init(int height, int width, int xpos, int ypos, int backlines, int backcols, struct vmem_cell *scrollback, int emulation) { - char *revision="$Revision: 1.315 $"; + char *revision="$Revision: 1.316 $"; char *in; char *out; struct cterminal *cterm; diff --git a/src/conio/cterm.txt b/src/conio/cterm.txt index 4cc6fcc37f8bcf88a2cc039d07719f882b45e363..9caaab6526ae09b678f283c30e25d7702e2ecae5 100644 --- a/src/conio/cterm.txt +++ b/src/conio/cterm.txt @@ -316,17 +316,29 @@ ESC _ Application Program String (APS) will be drawn from the source image, cleared bits will not be drawn. Requires MW= and MH= to be specified. + MBUF + Uses the loaded mask buffer. The PPM file may be raw (preferred) or text. SyncTERM does not support more than 255 values per colour channel and assumes it is correctly using the BT.709 gamma transfer. + APS SyncTERM:C;LoadPPM Ps... Ps0 + Loads a PPM to a buffer. Ps0 is the filename + B=# + Selects the buffer (0 or 1 only) to paste from. + + APS SyncTERM:C;LoadPBM Ps... Ps0 + Loads a PBM to a buffer. Ps0 is the filename + APS SyncTERM:P;Copy Ps... Copies a portion of the screen into an internal buffer for use with the Paste function. Defaults to copying the entire screen. + B=# + Selects the buffer (0 or 1 only) to copy to. X=# Sets the left X position on the screen to start copying at. Default = 0. @@ -343,7 +355,9 @@ ESC _ Application Program String (APS) APS SyncTERM:P,Paste Ps... Pastes from the copied buffer. Supports the same options as the Cache DrawPPM command except for the - filename. + filename, and adds the B= option. + B=# + Selects the buffer (0 or 1 only) to paste from. ESC c Reset to Initial State (RIS) Resets all the terminal settings, clears the screen, and homes diff --git a/src/syncterm/term.c b/src/syncterm/term.c index cd0f5c702a770d46c3d8cd9a05f3d79a9b82053e..53d5c860660328aadaca0c505beb5777c89f477a 100644 --- a/src/syncterm/term.c +++ b/src/syncterm/term.c @@ -54,7 +54,8 @@ static struct vmem_cell winbuf[(TRANSFER_WIN_WIDTH + 2) * (TRANSFER_WIN_HEIGHT + static struct text_info trans_ti; static struct text_info log_ti; -static struct ciolib_pixels *pixmap_buffer; +static struct ciolib_pixels *pixmap_buffer[2]; +static struct ciolib_mask *mask_buffer; static uint8_t pnm_gamma[256]; bool pnm_gamma_initialized = false; @@ -2830,6 +2831,7 @@ draw_ppm_str_handler(char *str, size_t slen, char *fn, void *apcd) unsigned long mw = 0; // Width of the mask unsigned long mh = 0; // Height of the mask size_t mlen = 0; + bool mbuf = false; for (p = str + 18; p && *p == ';'; p = strchr(p + 1, ';')) { val = NULL; @@ -2881,7 +2883,9 @@ draw_ppm_str_handler(char *str, size_t slen, char *fn, void *apcd) p2 = strchr(p + 7, ';'); if (p2 == NULL) goto done; - freemask(ctmask); + if (!mbuf) + freemask(ctmask); + mbuf = false; ctmask = NULL; free(mask); mask = strndup(p + 7, p2 - p - 7); @@ -2892,13 +2896,21 @@ draw_ppm_str_handler(char *str, size_t slen, char *fn, void *apcd) if (p2 == NULL) goto done; FREE_AND_NULL(mask); - freemask(ctmask); + if (!mbuf) + freemask(ctmask); + mbuf = false; ctmask = alloc_ciolib_mask(0, 0); ctmask->bits = b64_decode_alloc(p + 6, p2 - p + 5, &mlen); if (ctmask->bits == NULL) goto done; continue; // Avoid val check } + else if (strncmp(p + 2, "BUF", 3) == 0) { + freemask(ctmask); + ctmask = NULL; + mbuf = true; + continue; // Avoid val check + } break; } if (val == NULL || p[3] != '=') @@ -2944,16 +2956,77 @@ draw_ppm_str_handler(char *str, size_t slen, char *fn, void *apcd) goto done; } + if (mbuf) + ctmask = mask_buffer; + if (ppmp != NULL) setpixels(dx, dy, dx + sw - 1, dy + sh - 1, sx, sy, mx, my, ppmp, ctmask); done: free(mask); free(maskfn); - freemask(ctmask); + if (!mbuf) + freemask(ctmask); free(ppmfn); freepixels(ppmp); } +static void +load_ppm_str_handler(char *str, size_t slen, char *fn, void *apcd) +{ + char *p; + char *ppmfn = NULL; + struct ciolib_pixels *ppmp = NULL; + unsigned long bufnum = 0; + unsigned long *val; + + for (p = str + 18; p && *p == ';'; p = strchr(p + 1, ';')) { + val = NULL; + switch (p[1]) { + case 'B': + val = &bufnum; + break; + } + if (val == NULL || p[2] != '=') + break; + *val = strtoul(p + 3, NULL, 10); + } + + if (bufnum >= sizeof(pixmap_buffer) / sizeof(pixmap_buffer[0])) + goto done; + + freepixels(pixmap_buffer[bufnum]); + pixmap_buffer[bufnum] = NULL; + + if (asprintf(&ppmfn, "%s%s", fn, p + 1) == -1) + goto done; + ppmp = read_pbm(ppmfn, false); + if (ppmp == NULL) + goto done; + pixmap_buffer[bufnum] = ppmp; + free(ppmfn); + return; + +done: + free(ppmfn); + freepixels(ppmp); +} + +static void +load_pbm_str_handler(char *str, size_t slen, char *fn, void *apcd) +{ + char *p; + char *maskfn = NULL; + + p = str + 18; + if (asprintf(&maskfn, "%s%s", fn, p + 1) == -1) + goto done; + freemask(mask_buffer); + mask_buffer = read_pbm(maskfn, true); + +done: + free(maskfn); +} + static void copy_pixmap(char *str, size_t slen, char *fn, void *apcd) { @@ -2963,6 +3036,7 @@ copy_pixmap(char *str, size_t slen, char *fn, void *apcd) unsigned long h = 0; // Source height unsigned long *val; char *p; + unsigned long bufnum = 0; for (p = str + 15; p && *p == ';'; p = strchr(p + 1, ';')) { val = NULL; @@ -2979,14 +3053,20 @@ copy_pixmap(char *str, size_t slen, char *fn, void *apcd) case 'H': val = &h; break; + case 'B': + val = &bufnum; + break; } if (val == NULL || p[2] != '=') return; *val = strtol(p + 3, NULL, 10); } - freepixels(pixmap_buffer); - pixmap_buffer = NULL; + if (bufnum >= sizeof(pixmap_buffer) / sizeof(pixmap_buffer[0])) + return; + + freepixels(pixmap_buffer[bufnum]); + pixmap_buffer[bufnum] = NULL; if (w == 0 || h == 0) { struct text_info ti; int vmode; @@ -2999,7 +3079,7 @@ copy_pixmap(char *str, size_t slen, char *fn, void *apcd) if (h == 0) h = vparams[vmode].yres - y; } - pixmap_buffer = getpixels(x, y, x + w - 1, y + h - 1, false); + pixmap_buffer[bufnum] = getpixels(x, y, x + w - 1, y + h - 1, false); } static void @@ -3015,6 +3095,7 @@ paste_pixmap(char *str, size_t slen, char *fn, void *apcd) unsigned long my = 0; // Destination Y unsigned long mw = 0; // Width of the mask unsigned long mh = 0; // Height of the mask + unsigned long bufnum = 0; unsigned long *val; void *mask = NULL; struct ciolib_mask *ctmask; @@ -3022,12 +3103,17 @@ paste_pixmap(char *str, size_t slen, char *fn, void *apcd) char *p; char *p2; size_t mlen = 0; + bool mbuf; + size_t poff; - if (pixmap_buffer == NULL) - return; for (p = str + 16; p && *p == ';'; p = strchr(p + 1, ';')) { val = NULL; + poff = 3; switch (p[1]) { + case 'B': + val = &bufnum; + poff = 2; + break; case 'S': switch (p[2]) { case 'X': @@ -3077,7 +3163,8 @@ paste_pixmap(char *str, size_t slen, char *fn, void *apcd) p2 = strchr(p + 6, 0); if (p2 == NULL) goto done; - freemask(ctmask); + if (!mbuf) + freemask(ctmask); ctmask = NULL; free(mask); mask = strndup(p + 7, p2 - p - 7); @@ -3090,7 +3177,8 @@ paste_pixmap(char *str, size_t slen, char *fn, void *apcd) if (p2 == NULL) goto done; FREE_AND_NULL(mask); - freemask(ctmask); + if (!mbuf) + freemask(ctmask); ctmask = alloc_ciolib_mask(0, 0); if (ctmask == NULL) goto done; @@ -3099,17 +3187,29 @@ paste_pixmap(char *str, size_t slen, char *fn, void *apcd) goto done; continue; // Avoid val check } + else if (strncmp(p + 2, "BUF", 3) == 0) { + freemask(ctmask); + ctmask = NULL; + mbuf = true; + continue; // Avoid val check + } break; } - if (val == NULL || p[3] != '=') - break; - *val = strtoul(p + 4, NULL, 10); + if (val == NULL || p[poff] != '=') + goto done; + *val = strtoul(p + poff + 1, NULL, 10); } + if (bufnum >= sizeof(pixmap_buffer) / sizeof(pixmap_buffer[0])) + return; + + if (pixmap_buffer[bufnum] == NULL) + return; + if (sw == 0) - sw = pixmap_buffer->width - sx; + sw = pixmap_buffer[bufnum]->width - sx; if (sh == 0) - sh = pixmap_buffer->height - sy; + sh = pixmap_buffer[bufnum]->height - sy; if (ctmask != NULL) { if (mlen < (sw * sh + 7) / 8) @@ -3136,10 +3236,14 @@ paste_pixmap(char *str, size_t slen, char *fn, void *apcd) goto done; } - setpixels(dx, dy, dx + sw - 1, dy + sh - 1, sx, sy, mx, my, pixmap_buffer, ctmask); + if (mbuf) + ctmask = mask_buffer; + + setpixels(dx, dy, dx + sw - 1, dy + sh - 1, sx, sy, mx, my, pixmap_buffer[bufnum], ctmask); done: free(mask); - freemask(ctmask); + if (!mbuf) + freemask(ctmask); } static void @@ -3193,6 +3297,14 @@ apc_handler(char *strbuf, size_t slen, void *apcd) free(buf); fclose(f); } + else if (strncmp(strbuf, "SyncTERM:C;LoadPPM", 18) == 0) { + // Load PPM into memory buffer + load_ppm_str_handler(strbuf, slen, fn, apcd); + } + else if (strncmp(strbuf, "SyncTERM:C;LoadPBM", 18) == 0) { + // Load PPM into memory buffer + load_pbm_str_handler(strbuf, slen, fn, apcd); + } else if (strncmp(strbuf, "SyncTERM:C;L", 12) == 0) { // Cache list if ((strbuf[12] != 0) && (strbuf[12] != ';')) @@ -3307,6 +3419,10 @@ apc_handler(char *strbuf, size_t slen, void *apcd) else if (strncmp(strbuf, "SyncTERM:P;Paste", 16) == 0) { paste_pixmap(strbuf, slen, fn, apcd); } + + // TODO: Copy PPM to memory + // TODO: Copy PBM mask to memory + // TODO: Multiple (at least two) memory buffers } void @@ -3511,8 +3627,12 @@ doterm(struct bbslist *bbs) struct mouse_state ms = {0}; int speedwatch = 0; - ciolib_freepixels(pixmap_buffer); - pixmap_buffer = NULL; + freepixels(pixmap_buffer[0]); + freepixels(pixmap_buffer[1]); + pixmap_buffer[0] = NULL; + pixmap_buffer[1] = NULL; + freemask(mask_buffer); + mask_buffer = NULL; gettextinfo(&txtinfo); if ((bbs->conn_type == CONN_TYPE_SERIAL) || (bbs->conn_type == CONN_TYPE_SERIAL_NORTS)) speed = 0;