mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-05-28 23:34:49 -05:00
Implement true-colour in write_clip for Windows
This allows text copied from PuTTY to a rich-text program to retain the true-colour attribute.
This commit is contained in:
parent
7bdfdabb5e
commit
891d909b3d
126
windows/window.c
126
windows/window.c
@ -24,6 +24,7 @@
|
||||
#include "storage.h"
|
||||
#include "win_res.h"
|
||||
#include "winsecur.h"
|
||||
#include "tree234.h"
|
||||
|
||||
#ifndef NO_MULTIMON
|
||||
#include <multimon.h>
|
||||
@ -4986,6 +4987,18 @@ void write_aclip(void *frontend, char *data, int len, int must_deselect)
|
||||
SendMessage(hwnd, WM_IGNORE_CLIP, FALSE, 0);
|
||||
}
|
||||
|
||||
typedef struct _rgbindex {
|
||||
int index;
|
||||
COLORREF ref;
|
||||
} rgbindex;
|
||||
|
||||
int cmpCOLORREF(void *va, void *vb)
|
||||
{
|
||||
COLORREF a = ((rgbindex *)va)->ref;
|
||||
COLORREF b = ((rgbindex *)vb)->ref;
|
||||
return (a < b) ? -1 : (a > b) ? +1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: unlike write_aclip() this will not append a nul.
|
||||
*/
|
||||
@ -5033,12 +5046,15 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour
|
||||
int rtfsize = 0;
|
||||
int multilen, blen, alen, totallen, i;
|
||||
char before[16], after[4];
|
||||
int fgcolour, lastfgcolour = 0;
|
||||
int bgcolour, lastbgcolour = 0;
|
||||
int fgcolour, lastfgcolour = -1;
|
||||
int bgcolour, lastbgcolour = -1;
|
||||
COLORREF fg, lastfg = -1;
|
||||
COLORREF bg, lastbg = -1;
|
||||
int attrBold, lastAttrBold = 0;
|
||||
int attrUnder, lastAttrUnder = 0;
|
||||
int palette[NALLCOLOURS];
|
||||
int numcolours;
|
||||
tree234 *rgbtree = NULL;
|
||||
FontSpec *font = conf_get_fontspec(conf, CONF_font);
|
||||
|
||||
get_unitab(CP_ACP, unitab, 0);
|
||||
@ -5076,7 +5092,7 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour
|
||||
fgcolour ++;
|
||||
}
|
||||
|
||||
if (attr[i] & ATTR_BLINK) {
|
||||
if ((attr[i] & ATTR_BLINK)) {
|
||||
if (bgcolour < 8) /* ANSI colours */
|
||||
bgcolour += 8;
|
||||
else if (bgcolour >= 256) /* Default colours */
|
||||
@ -5087,6 +5103,28 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour
|
||||
palette[bgcolour]++;
|
||||
}
|
||||
|
||||
if (truecolour) {
|
||||
rgbtree = newtree234(cmpCOLORREF);
|
||||
for (i = 0; i < (len-1); i++) {
|
||||
if (truecolour[i].fg.enabled) {
|
||||
rgbindex *rgbp = snew(rgbindex);
|
||||
rgbp->ref = RGB(truecolour[i].fg.r,
|
||||
truecolour[i].fg.g,
|
||||
truecolour[i].fg.b);
|
||||
if (add234(rgbtree, rgbp) != rgbp)
|
||||
sfree(rgbp);
|
||||
}
|
||||
if (truecolour[i].bg.enabled) {
|
||||
rgbindex *rgbp = snew(rgbindex);
|
||||
rgbp->ref = RGB(truecolour[i].bg.r,
|
||||
truecolour[i].bg.g,
|
||||
truecolour[i].bg.b);
|
||||
if (add234(rgbtree, rgbp) != rgbp)
|
||||
sfree(rgbp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Next - Create a reduced palette
|
||||
*/
|
||||
@ -5096,6 +5134,12 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour
|
||||
palette[i] = ++numcolours;
|
||||
}
|
||||
|
||||
if (rgbtree) {
|
||||
rgbindex *rgbp;
|
||||
for (i = 0; (rgbp = index234(rgbtree, i)) != NULL; i++)
|
||||
rgbp->index = ++numcolours;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally - Write the colour table
|
||||
*/
|
||||
@ -5108,6 +5152,12 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour
|
||||
rtflen += sprintf(&rtf[rtflen], "\\red%d\\green%d\\blue%d;", defpal[i].rgbtRed, defpal[i].rgbtGreen, defpal[i].rgbtBlue);
|
||||
}
|
||||
}
|
||||
if (rgbtree) {
|
||||
rgbindex *rgbp;
|
||||
for (i = 0; (rgbp = index234(rgbtree, i)) != NULL; i++)
|
||||
rtflen += sprintf(&rtf[rtflen], "\\red%d\\green%d\\blue%d;",
|
||||
GetRValue(rgbp->ref), GetGValue(rgbp->ref), GetBValue(rgbp->ref));
|
||||
}
|
||||
strcpy(&rtf[rtflen], "}");
|
||||
rtflen ++;
|
||||
}
|
||||
@ -5151,23 +5201,44 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour
|
||||
/*
|
||||
* Determine foreground and background colours
|
||||
*/
|
||||
fgcolour = ((attr[tindex] & ATTR_FGMASK) >> ATTR_FGSHIFT);
|
||||
bgcolour = ((attr[tindex] & ATTR_BGMASK) >> ATTR_BGSHIFT);
|
||||
if (truecolour && truecolour[tindex].fg.enabled) {
|
||||
fgcolour = -1;
|
||||
fg = RGB(truecolour[tindex].fg.r,
|
||||
truecolour[tindex].fg.g,
|
||||
truecolour[tindex].fg.b);
|
||||
} else {
|
||||
fgcolour = ((attr[tindex] & ATTR_FGMASK) >> ATTR_FGSHIFT);
|
||||
fg = -1;
|
||||
}
|
||||
|
||||
if (truecolour && truecolour[tindex].bg.enabled) {
|
||||
bgcolour = -1;
|
||||
bg = RGB(truecolour[tindex].bg.r,
|
||||
truecolour[tindex].bg.g,
|
||||
truecolour[tindex].bg.b);
|
||||
} else {
|
||||
bgcolour = ((attr[tindex] & ATTR_BGMASK) >> ATTR_BGSHIFT);
|
||||
bg = -1;
|
||||
}
|
||||
|
||||
if (attr[tindex] & ATTR_REVERSE) {
|
||||
int tmpcolour = fgcolour; /* Swap foreground and background */
|
||||
fgcolour = bgcolour;
|
||||
bgcolour = tmpcolour;
|
||||
|
||||
COLORREF tmpref = fg;
|
||||
fg = bg;
|
||||
bg = tmpref;
|
||||
}
|
||||
|
||||
if (bold_colours && (attr[tindex] & ATTR_BOLD)) {
|
||||
if (bold_colours && (attr[tindex] & ATTR_BOLD) && (fgcolour >= 0)) {
|
||||
if (fgcolour < 8) /* ANSI colours */
|
||||
fgcolour += 8;
|
||||
else if (fgcolour >= 256) /* Default colours */
|
||||
fgcolour ++;
|
||||
}
|
||||
|
||||
if (attr[tindex] & ATTR_BLINK) {
|
||||
if ((attr[tindex] & ATTR_BLINK) && (bgcolour >= 0)) {
|
||||
if (bgcolour < 8) /* ANSI colours */
|
||||
bgcolour += 8;
|
||||
else if (bgcolour >= 256) /* Default colours */
|
||||
@ -5206,15 +5277,33 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour
|
||||
/*
|
||||
* Write RTF text attributes
|
||||
*/
|
||||
if (lastfgcolour != fgcolour) {
|
||||
lastfgcolour = fgcolour;
|
||||
rtflen += sprintf(&rtf[rtflen], "\\cf%d ", (fgcolour >= 0) ? palette[fgcolour] : 0);
|
||||
}
|
||||
if ((lastfgcolour != fgcolour) || (lastfg != fg)) {
|
||||
lastfgcolour = fgcolour;
|
||||
lastfg = fg;
|
||||
if (fg == -1)
|
||||
rtflen += sprintf(&rtf[rtflen], "\\cf%d ",
|
||||
(fgcolour >= 0) ? palette[fgcolour] : 0);
|
||||
else {
|
||||
rgbindex rgb, *rgbp;
|
||||
rgb.ref = fg;
|
||||
if ((rgbp = find234(rgbtree, &rgb, NULL)) != NULL)
|
||||
rtflen += sprintf(&rtf[rtflen], "\\cf%d ", rgbp->index);
|
||||
}
|
||||
}
|
||||
|
||||
if (lastbgcolour != bgcolour) {
|
||||
lastbgcolour = bgcolour;
|
||||
rtflen += sprintf(&rtf[rtflen], "\\highlight%d ", (bgcolour >= 0) ? palette[bgcolour] : 0);
|
||||
}
|
||||
if ((lastbgcolour != bgcolour) || (lastbg != bg)) {
|
||||
lastbgcolour = bgcolour;
|
||||
lastbg = bg;
|
||||
if (bg == -1)
|
||||
rtflen += sprintf(&rtf[rtflen], "\\highlight%d ",
|
||||
(bgcolour >= 0) ? palette[bgcolour] : 0);
|
||||
else {
|
||||
rgbindex rgb, *rgbp;
|
||||
rgb.ref = bg;
|
||||
if ((rgbp = find234(rgbtree, &rgb, NULL)) != NULL)
|
||||
rtflen += sprintf(&rtf[rtflen], "\\highlight%d ", rgbp->index);
|
||||
}
|
||||
}
|
||||
|
||||
if (lastAttrBold != attrBold) {
|
||||
lastAttrBold = attrBold;
|
||||
@ -5295,6 +5384,13 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour
|
||||
GlobalUnlock(clipdata3);
|
||||
}
|
||||
sfree(rtf);
|
||||
|
||||
if (rgbtree) {
|
||||
rgbindex *rgbp;
|
||||
while ((rgbp = delpos234(rgbtree, 0)) != NULL)
|
||||
sfree(rgbp);
|
||||
freetree234(rgbtree);
|
||||
}
|
||||
} else
|
||||
clipdata3 = NULL;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user