1 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 #line 1 "term-ostream.oo.c"
4 /* Output stream for attributed text, producing ANSI escape sequences.
5 Copyright (C) 2006-2008 Free Software Foundation, Inc.
6 Written by Bruno Haible <bruno@clisp.org>, 2006.
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "term-ostream.h"
34 #include "fatal-signal.h"
35 #include "full-write.h"
41 #define _(str) gettext (str)
44 /* GNU termcap's tparam() function requires a buffer argument. Make it so
45 large that there is no risk that tparam() needs to call malloc(). */
46 static char tparambuf[100];
47 /* Define tparm in terms of tparam. In the scope of this file, it is called
48 with at most one argument after the string. */
49 # define tparm(str, arg1) \
50 tparam (str, tparambuf, sizeof (tparambuf), arg1)
53 #define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
56 /* =========================== Color primitives =========================== */
58 /* A color in RGB format. */
61 unsigned int red : 8; /* range 0..255 */
62 unsigned int green : 8; /* range 0..255 */
63 unsigned int blue : 8; /* range 0..255 */
66 /* A color in HSV (a.k.a. HSB) format. */
69 float hue; /* normalized to interval [0,6) */
70 float saturation; /* normalized to interval [0,1] */
71 float brightness; /* a.k.a. value, normalized to interval [0,1] */
74 /* Conversion of a color in RGB to HSV format. */
76 rgb_to_hsv (rgb_t c, hsv_t *result)
78 unsigned int r = c.red;
79 unsigned int g = c.green;
80 unsigned int b = c.blue;
86 /* b > r > g, so max = b, min = g */
87 result->hue = 4.0f + (float) (r - g) / (float) (b - g);
88 result->saturation = 1.0f - (float) g / (float) b;
89 result->brightness = (float) b / 255.0f;
93 /* r > g >= b, so max = r, min = b */
94 result->hue = 0.0f + (float) (g - b) / (float) (r - b);
95 result->saturation = 1.0f - (float) b / (float) r;
96 result->brightness = (float) r / 255.0f;
100 /* r >= b > g, so max = r, min = g */
101 result->hue = 6.0f - (float) (b - g) / (float) (r - g);
102 result->saturation = 1.0f - (float) g / (float) r;
103 result->brightness = (float) r / 255.0f;
110 /* b > g >= r, so max = b, min = r */
111 result->hue = 4.0f - (float) (g - r) / (float) (b - r);
112 result->saturation = 1.0f - (float) r / (float) b;
113 result->brightness = (float) b / 255.0f;
117 /* g >= r > b, so max = g, min = b */
118 result->hue = 2.0f - (float) (r - b) / (float) (g - b);
119 result->saturation = 1.0f - (float) b / (float) g;
120 result->brightness = (float) g / 255.0f;
124 /* g >= b >= r, g > r, so max = g, min = r */
125 result->hue = 2.0f + (float) (b - r) / (float) (g - r);
126 result->saturation = 1.0f - (float) r / (float) g;
127 result->brightness = (float) g / 255.0f;
131 /* r = g = b. A grey color. */
132 result->hue = 0; /* arbitrary */
133 result->saturation = 0;
134 result->brightness = (float) r / 255.0f;
139 /* Square of distance of two colors. */
141 color_distance (const hsv_t *color1, const hsv_t *color2)
144 /* Formula taken from "John Smith: Color Similarity",
145 http://www.ctr.columbia.edu/~jrsmith/html/pubs/acmmm96/node8.html. */
146 float angle1 = color1->hue * 1.04719755f; /* normalize to [0,2π] */
147 float angle2 = color2->hue * 1.04719755f; /* normalize to [0,2π] */
148 float delta_x = color1->saturation * cosf (angle1)
149 - color2->saturation * cosf (angle2);
150 float delta_y = color1->saturation * sinf (angle1)
151 - color2->saturation * sinf (angle2);
152 float delta_v = color1->brightness
153 - color2->brightness;
155 return delta_x * delta_x + delta_y * delta_y + delta_v * delta_v;
157 /* Formula that considers hue differences with more weight than saturation
158 or brightness differences, like the human eye does. */
160 (color1->hue >= color2->hue
161 ? (color1->hue - color2->hue >= 3.0f
162 ? 6.0f + color2->hue - color1->hue
163 : color1->hue - color2->hue)
164 : (color2->hue - color1->hue >= 3.0f
165 ? 6.0f + color1->hue - color2->hue
166 : color2->hue - color1->hue));
167 float min_saturation =
168 (color1->saturation < color2->saturation
170 : color2->saturation);
171 float delta_saturation = color1->saturation - color2->saturation;
172 float delta_brightness = color1->brightness - color2->brightness;
174 return delta_hue * delta_hue * min_saturation
175 + delta_saturation * delta_saturation * 0.2f
176 + delta_brightness * delta_brightness * 0.8f;
180 /* Return the index of the color in a color table that is nearest to a given
183 nearest_color (rgb_t given, const rgb_t *table, unsigned int table_size)
186 unsigned int best_index;
190 assert (table_size > 0);
192 rgb_to_hsv (given, &given_hsv);
195 best_distance = 1000000.0f;
196 for (i = 0; i < table_size; i++)
200 rgb_to_hsv (table[i], &i_hsv);
202 /* Avoid converting a color to grey, or fading out a color too much. */
203 if (i_hsv.saturation > given_hsv.saturation * 0.5f)
205 float distance = color_distance (&given_hsv, &i_hsv);
206 if (distance < best_distance)
209 best_distance = distance;
214 #if 0 /* Debugging code */
216 rgb_to_hsv (table[best_index], &best_hsv);
217 fprintf (stderr, "nearest: (%d,%d,%d) = (%f,%f,%f)\n -> (%f,%f,%f) = (%d,%d,%d)\n",
218 given.red, given.green, given.blue,
219 (double)given_hsv.hue, (double)given_hsv.saturation, (double)given_hsv.brightness,
220 (double)best_hsv.hue, (double)best_hsv.saturation, (double)best_hsv.brightness,
221 table[best_index].red, table[best_index].green, table[best_index].blue);
227 /* The luminance of a color. This is the brightness of the color, as it
228 appears to the human eye. This must be used in color to grey conversion. */
230 color_luminance (int r, int g, int b)
232 /* Use the luminance model used by NTSC and JPEG.
233 Taken from http://www.fho-emden.de/~hoffmann/gray10012001.pdf .
234 No need to care about rounding errors leading to luminance > 1;
235 this cannot happen. */
236 return (0.299f * r + 0.587f * g + 0.114f * b) / 255.0f;
240 /* ============================= Color models ============================= */
242 /* The color model used by the terminal. */
245 cm_monochrome, /* No colors. */
246 cm_common8, /* Usual terminal with at least 8 colors. */
247 cm_xterm8, /* TERM=xterm, with 8 colors. */
248 cm_xterm16, /* TERM=xterm-16color, with 16 colors. */
249 cm_xterm88, /* TERM=xterm-88color, with 88 colors. */
250 cm_xterm256 /* TERM=xterm-256color, with 256 colors. */
253 /* ----------------------- cm_monochrome color model ----------------------- */
255 /* A non-default color index doesn't exist in this color model. */
256 static inline term_color_t
257 rgb_to_color_monochrome ()
259 return COLOR_DEFAULT;
262 /* ------------------------ cm_common8 color model ------------------------ */
264 /* A non-default color index is in the range 0..7.
274 static const rgb_t colors_of_common8[8] =
276 /* R G B grey index */
277 { 0, 0, 0 }, /* 0.000 0 */
284 { 255, 255, 255 } /* 1.000 7 */
287 static inline term_color_t
288 rgb_to_color_common8 (int r, int g, int b)
293 color.red = r; color.green = g; color.blue = b;
294 rgb_to_hsv (color, &hsv);
296 if (hsv.saturation < 0.065f)
298 /* Greyscale approximation. */
299 float luminance = color_luminance (r, g, b);
300 if (luminance < 0.500f)
306 /* Color approximation. */
307 return nearest_color (color, colors_of_common8, 8);
310 /* Convert a cm_common8 color in RGB encoding to BGR encoding.
311 See the ncurses terminfo(5) manual page, section "Color Handling", for an
312 explanation why this is needed. */
314 color_bgr (term_color_t color)
316 return ((color & 4) >> 2) | (color & 2) | ((color & 1) << 2);
319 /* ------------------------- cm_xterm8 color model ------------------------- */
321 /* A non-default color index is in the range 0..7.
331 static const rgb_t colors_of_xterm8[8] =
333 /* The real xterm's colors are dimmed; assume full-brightness instead. */
334 /* R G B grey index */
335 { 0, 0, 0 }, /* 0.000 0 */
342 { 255, 255, 255 } /* 1.000 7 */
345 static inline term_color_t
346 rgb_to_color_xterm8 (int r, int g, int b)
351 color.red = r; color.green = g; color.blue = b;
352 rgb_to_hsv (color, &hsv);
354 if (hsv.saturation < 0.065f)
356 /* Greyscale approximation. */
357 float luminance = color_luminance (r, g, b);
358 if (luminance < 0.500f)
364 /* Color approximation. */
365 return nearest_color (color, colors_of_xterm8, 8);
368 /* ------------------------ cm_xterm16 color model ------------------------ */
370 /* A non-default color index is in the range 0..15.
371 The RGB values come from xterm's XTerm-col.ad. */
372 static const rgb_t colors_of_xterm16[16] =
374 /* R G B grey index */
375 { 0, 0, 0 }, /* 0.000 0 */
382 { 229, 229, 229 }, /* 0.898 7 */
383 { 77, 77, 77 }, /* 0.302 8 */
390 { 255, 255, 255 } /* 1.000 15 */
393 static inline term_color_t
394 rgb_to_color_xterm16 (int r, int g, int b)
399 color.red = r; color.green = g; color.blue = b;
400 rgb_to_hsv (color, &hsv);
402 if (hsv.saturation < 0.065f)
404 /* Greyscale approximation. */
405 float luminance = color_luminance (r, g, b);
406 if (luminance < 0.151f)
408 else if (luminance < 0.600f)
410 else if (luminance < 0.949f)
416 /* Color approximation. */
417 return nearest_color (color, colors_of_xterm16, 16);
420 /* ------------------------ cm_xterm88 color model ------------------------ */
422 /* A non-default color index is in the range 0..87.
423 Colors 0..15 are the same as in the cm_xterm16 color model.
424 Colors 16..87 are defined in xterm's 88colres.h. */
426 static const rgb_t colors_of_xterm88[88] =
428 /* R G B grey index */
429 { 0, 0, 0 }, /* 0.000 0 */
436 { 229, 229, 229 }, /* 0.898 7 */
437 { 77, 77, 77 }, /* 0.302 8 */
444 { 255, 255, 255 }, /* 1.000 15 */
445 { 0, 0, 0 }, /* 0.000 16 */
466 { 139, 139, 139 }, /* 0.545 37 */
487 { 205, 205, 205 }, /* 0.804 58 */
508 { 255, 255, 255 }, /* 1.000 79 */
509 { 46, 46, 46 }, /* 0.180 80 */
510 { 92, 92, 92 }, /* 0.361 81 */
511 { 115, 115, 115 }, /* 0.451 82 */
512 { 139, 139, 139 }, /* 0.545 83 */
513 { 162, 162, 162 }, /* 0.635 84 */
514 { 185, 185, 185 }, /* 0.725 85 */
515 { 208, 208, 208 }, /* 0.816 86 */
516 { 231, 231, 231 } /* 0.906 87 */
519 static inline term_color_t
520 rgb_to_color_xterm88 (int r, int g, int b)
525 color.red = r; color.green = g; color.blue = b;
526 rgb_to_hsv (color, &hsv);
528 if (hsv.saturation < 0.065f)
530 /* Greyscale approximation. */
531 float luminance = color_luminance (r, g, b);
532 if (luminance < 0.090f)
534 else if (luminance < 0.241f)
536 else if (luminance < 0.331f)
538 else if (luminance < 0.406f)
540 else if (luminance < 0.498f)
542 else if (luminance < 0.585f)
544 else if (luminance < 0.680f)
546 else if (luminance < 0.764f)
548 else if (luminance < 0.810f)
550 else if (luminance < 0.857f)
552 else if (luminance < 0.902f)
554 else if (luminance < 0.953f)
560 /* Color approximation. */
561 return nearest_color (color, colors_of_xterm88, 88);
564 /* ------------------------ cm_xterm256 color model ------------------------ */
566 /* A non-default color index is in the range 0..255.
567 Colors 0..15 are the same as in the cm_xterm16 color model.
568 Colors 16..255 are defined in xterm's 256colres.h. */
570 static const rgb_t colors_of_xterm256[256] =
572 /* R G B grey index */
573 { 0, 0, 0 }, /* 0.000 0 */
580 { 229, 229, 229 }, /* 0.898 7 */
581 { 77, 77, 77 }, /* 0.302 8 */
588 { 255, 255, 255 }, /* 1.000 15 */
589 { 0, 0, 0 }, /* 0.000 16 */
632 { 42, 42, 42 }, /* 0.165 59 */
675 { 85, 85, 85 }, /* 0.333 102 */
718 { 127, 127, 127 }, /* 0.498 145 */
761 { 170, 170, 170 }, /* 0.667 188 */
804 { 212, 212, 212 }, /* 0.831 231 */
805 { 8, 8, 8 }, /* 0.031 232 */
806 { 18, 18, 18 }, /* 0.071 233 */
807 { 28, 28, 28 }, /* 0.110 234 */
808 { 38, 38, 38 }, /* 0.149 235 */
809 { 48, 48, 48 }, /* 0.188 236 */
810 { 58, 58, 58 }, /* 0.227 237 */
811 { 68, 68, 68 }, /* 0.267 238 */
812 { 78, 78, 78 }, /* 0.306 239 */
813 { 88, 88, 88 }, /* 0.345 240 */
814 { 98, 98, 98 }, /* 0.384 241 */
815 { 108, 108, 108 }, /* 0.424 242 */
816 { 118, 118, 118 }, /* 0.463 243 */
817 { 128, 128, 128 }, /* 0.502 244 */
818 { 138, 138, 138 }, /* 0.541 245 */
819 { 148, 148, 148 }, /* 0.580 246 */
820 { 158, 158, 158 }, /* 0.620 247 */
821 { 168, 168, 168 }, /* 0.659 248 */
822 { 178, 178, 178 }, /* 0.698 249 */
823 { 188, 188, 188 }, /* 0.737 250 */
824 { 198, 198, 198 }, /* 0.776 251 */
825 { 208, 208, 208 }, /* 0.816 252 */
826 { 218, 218, 218 }, /* 0.855 253 */
827 { 228, 228, 228 }, /* 0.894 254 */
828 { 238, 238, 238 } /* 0.933 255 */
831 static inline term_color_t
832 rgb_to_color_xterm256 (int r, int g, int b)
837 color.red = r; color.green = g; color.blue = b;
838 rgb_to_hsv (color, &hsv);
840 if (hsv.saturation < 0.065f)
842 /* Greyscale approximation. */
843 float luminance = color_luminance (r, g, b);
844 if (luminance < 0.015f)
846 else if (luminance < 0.051f)
848 else if (luminance < 0.090f)
850 else if (luminance < 0.129f)
852 else if (luminance < 0.157f)
854 else if (luminance < 0.177f)
856 else if (luminance < 0.207f)
858 else if (luminance < 0.247f)
860 else if (luminance < 0.284f)
862 else if (luminance < 0.304f)
864 else if (luminance < 0.319f)
866 else if (luminance < 0.339f)
868 else if (luminance < 0.364f)
870 else if (luminance < 0.404f)
872 else if (luminance < 0.443f)
874 else if (luminance < 0.480f)
876 else if (luminance < 0.500f)
878 else if (luminance < 0.521f)
880 else if (luminance < 0.560f)
882 else if (luminance < 0.600f)
884 else if (luminance < 0.639f)
886 else if (luminance < 0.663f)
888 else if (luminance < 0.682f)
890 else if (luminance < 0.717f)
892 else if (luminance < 0.756f)
894 else if (luminance < 0.796f)
896 else if (luminance < 0.823f)
898 else if (luminance < 0.843f)
900 else if (luminance < 0.874f)
902 else if (luminance < 0.896f)
904 else if (luminance < 0.915f)
906 else if (luminance < 0.966f)
912 /* Color approximation. */
913 return nearest_color (color, colors_of_xterm256, 256);
917 /* ============================= attributes_t ============================= */
919 /* ANSI C and ISO C99 6.7.2.1.(4) forbid use of bit fields for types other
920 than 'int' or 'unsigned int'.
921 On the other hand, C++ forbids conversion between enum types and integer
922 types without an explicit cast. */
924 # define BITFIELD_TYPE(orig_type,integer_type) orig_type
926 # define BITFIELD_TYPE(orig_type,integer_type) integer_type
929 /* Attributes that can be set on a character. */
932 BITFIELD_TYPE(term_color_t, signed int) color : 9;
933 BITFIELD_TYPE(term_color_t, signed int) bgcolor : 9;
934 BITFIELD_TYPE(term_weight_t, unsigned int) weight : 1;
935 BITFIELD_TYPE(term_posture_t, unsigned int) posture : 1;
936 BITFIELD_TYPE(term_underline_t, unsigned int) underline : 1;
940 /* ============================ term_ostream_t ============================ */
942 #line 943 "term-ostream.c"
944 #define term_ostream_representation any_ostream_representation
946 #include "term_ostream.priv.h"
948 const typeinfo_t term_ostream_typeinfo = { "term_ostream" };
950 static const typeinfo_t * const term_ostream_superclasses[] =
951 { term_ostream_SUPERCLASSES };
953 #define super ostream_vtable
955 #line 979 "term-ostream.oo.c"
957 /* Simplify attributes, according to the terminal's capabilities. */
959 simplify_attributes (term_ostream_t stream, attributes_t attr)
961 if ((attr.color != COLOR_DEFAULT || attr.bgcolor != COLOR_DEFAULT)
962 && stream->no_color_video > 0)
964 /* When colors and attributes can not be represented simultaneously,
965 we give preference to the color. */
966 if (stream->no_color_video & 2)
967 /* Colors conflict with underlining. */
968 attr.underline = UNDERLINE_OFF;
969 if (stream->no_color_video & 32)
970 /* Colors conflict with bold weight. */
971 attr.weight = WEIGHT_NORMAL;
973 if (!stream->supports_foreground)
974 attr.color = COLOR_DEFAULT;
975 if (!stream->supports_background)
976 attr.bgcolor = COLOR_DEFAULT;
977 if (!stream->supports_weight)
978 attr.weight = WEIGHT_DEFAULT;
979 if (!stream->supports_posture)
980 attr.posture = POSTURE_DEFAULT;
981 if (!stream->supports_underline)
982 attr.underline = UNDERLINE_DEFAULT;
986 /* While a line is being output, we need to be careful to restore the
987 terminal's settings in case of a fatal signal or an exit() call. */
989 /* File descriptor to which out_char shall output escape sequences. */
990 static int out_fd = -1;
992 /* Filename of out_fd. */
993 static const char *out_filename;
995 /* Output a single char to out_fd. Ignore errors. */
997 out_char_unchecked (int c)
1002 full_write (out_fd, bytes, 1);
1006 /* State that informs the exit handler what to do. */
1007 static const char *restore_colors;
1008 static const char *restore_weight;
1009 static const char *restore_posture;
1010 static const char *restore_underline;
1012 /* The exit handler. */
1016 /* Only do something while some output was interrupted. */
1019 if (restore_colors != NULL)
1020 tputs (restore_colors, 1, out_char_unchecked);
1021 if (restore_weight != NULL)
1022 tputs (restore_weight, 1, out_char_unchecked);
1023 if (restore_posture != NULL)
1024 tputs (restore_posture, 1, out_char_unchecked);
1025 if (restore_underline != NULL)
1026 tputs (restore_underline, 1, out_char_unchecked);
1030 /* The list of signals whose default behaviour is to stop the program. */
1031 static int stopping_signals[] =
1045 #define num_stopping_signals (SIZEOF (stopping_signals) - 1)
1047 static sigset_t stopping_signal_set;
1050 init_stopping_signal_set ()
1052 static bool stopping_signal_set_initialized = false;
1053 if (!stopping_signal_set_initialized)
1057 sigemptyset (&stopping_signal_set);
1058 for (i = 0; i < num_stopping_signals; i++)
1059 sigaddset (&stopping_signal_set, stopping_signals[i]);
1061 stopping_signal_set_initialized = true;
1065 /* Temporarily delay the stopping signals. */
1067 block_stopping_signals ()
1069 init_stopping_signal_set ();
1070 sigprocmask (SIG_BLOCK, &stopping_signal_set, NULL);
1073 /* Stop delaying the stopping signals. */
1075 unblock_stopping_signals ()
1077 init_stopping_signal_set ();
1078 sigprocmask (SIG_UNBLOCK, &stopping_signal_set, NULL);
1081 /* Compare two sets of attributes for equality. */
1083 equal_attributes (attributes_t attr1, attributes_t attr2)
1085 return (attr1.color == attr2.color
1086 && attr1.bgcolor == attr2.bgcolor
1087 && attr1.weight == attr2.weight
1088 && attr1.posture == attr2.posture
1089 && attr1.underline == attr2.underline);
1092 /* Signal error after full_write failed. */
1096 error (EXIT_FAILURE, errno, _("error writing to %s"), out_filename);
1099 /* Output a single char to out_fd. */
1106 /* We have to write directly to the file descriptor, not to a buffer with
1107 the same destination, because of the padding and sleeping that tputs()
1109 if (full_write (out_fd, bytes, 1) < 1)
1114 /* Output escape sequences to switch from OLD_ATTR to NEW_ATTR. */
1116 out_attr_change (term_ostream_t stream,
1117 attributes_t old_attr, attributes_t new_attr)
1119 bool cleared_attributes;
1121 /* We don't know the default colors of the terminal. The only way to switch
1122 back to a default color is to use stream->orig_pair. */
1123 if ((new_attr.color == COLOR_DEFAULT && old_attr.color != COLOR_DEFAULT)
1124 || (new_attr.bgcolor == COLOR_DEFAULT && old_attr.bgcolor != COLOR_DEFAULT))
1126 assert (stream->supports_foreground || stream->supports_background);
1127 tputs (stream->orig_pair, 1, out_char);
1128 old_attr.color = COLOR_DEFAULT;
1129 old_attr.bgcolor = COLOR_DEFAULT;
1132 /* To turn off WEIGHT_BOLD, the only way is to output the exit_attribute_mode
1133 sequence. (With xterm, you can also do it with "Esc [ 0 m", but this
1134 escape sequence is not contained in the terminfo description.) It may
1135 also clear the colors; this is the case e.g. when TERM="xterm" or
1137 To turn off UNDERLINE_ON, we can use the exit_underline_mode or the
1138 exit_attribute_mode sequence. In the latter case, it will not only
1139 turn off UNDERLINE_ON, but also the other attributes, and possibly also
1141 To turn off POSTURE_ITALIC, we can use the exit_italics_mode or the
1142 exit_attribute_mode sequence. Again, in the latter case, it will not
1143 only turn off POSTURE_ITALIC, but also the other attributes, and possibly
1145 There is no point in setting an attribute just before emitting an
1146 escape sequence that may again turn off the attribute. Therefore we
1147 proceed in two steps: First, clear the attributes that need to be
1148 cleared; then - taking into account that this may have cleared all
1149 attributes and all colors - set the colors and the attributes.
1150 The variable 'cleared_attributes' tells whether an escape sequence
1151 has been output that may have cleared all attributes and all color
1153 cleared_attributes = false;
1154 if (old_attr.posture != POSTURE_NORMAL
1155 && new_attr.posture == POSTURE_NORMAL
1156 && stream->exit_italics_mode != NULL)
1158 tputs (stream->exit_italics_mode, 1, out_char);
1159 old_attr.posture = POSTURE_NORMAL;
1160 cleared_attributes = true;
1162 if (old_attr.underline != UNDERLINE_OFF
1163 && new_attr.underline == UNDERLINE_OFF
1164 && stream->exit_underline_mode != NULL)
1166 tputs (stream->exit_underline_mode, 1, out_char);
1167 old_attr.underline = UNDERLINE_OFF;
1168 cleared_attributes = true;
1170 if ((old_attr.weight != WEIGHT_NORMAL
1171 && new_attr.weight == WEIGHT_NORMAL)
1172 || (old_attr.posture != POSTURE_NORMAL
1173 && new_attr.posture == POSTURE_NORMAL
1174 /* implies stream->exit_italics_mode == NULL */)
1175 || (old_attr.underline != UNDERLINE_OFF
1176 && new_attr.underline == UNDERLINE_OFF
1177 /* implies stream->exit_underline_mode == NULL */))
1179 tputs (stream->exit_attribute_mode, 1, out_char);
1180 /* We don't know exactly what effects exit_attribute_mode has, but
1181 this is the minimum effect: */
1182 old_attr.weight = WEIGHT_NORMAL;
1183 if (stream->exit_italics_mode == NULL)
1184 old_attr.posture = POSTURE_NORMAL;
1185 if (stream->exit_underline_mode == NULL)
1186 old_attr.underline = UNDERLINE_OFF;
1187 cleared_attributes = true;
1190 /* Turn on the colors. */
1191 if (new_attr.color != old_attr.color
1192 || (cleared_attributes && new_attr.color != COLOR_DEFAULT))
1194 assert (stream->supports_foreground);
1195 assert (new_attr.color != COLOR_DEFAULT);
1196 switch (stream->colormodel)
1199 assert (new_attr.color >= 0 && new_attr.color < 8);
1200 if (stream->set_a_foreground != NULL)
1201 tputs (tparm (stream->set_a_foreground,
1202 color_bgr (new_attr.color)),
1205 tputs (tparm (stream->set_foreground, new_attr.color),
1208 /* When we are dealing with an xterm, there is no need to go through
1209 tputs() because we know there is no padding and sleeping. */
1211 assert (new_attr.color >= 0 && new_attr.color < 8);
1214 bytes[0] = 0x1B; bytes[1] = '[';
1215 bytes[2] = '3'; bytes[3] = '0' + new_attr.color;
1217 if (full_write (out_fd, bytes, 5) < 5)
1222 assert (new_attr.color >= 0 && new_attr.color < 16);
1225 bytes[0] = 0x1B; bytes[1] = '[';
1226 if (new_attr.color < 8)
1228 bytes[2] = '3'; bytes[3] = '0' + new_attr.color;
1232 bytes[2] = '9'; bytes[3] = '0' + (new_attr.color - 8);
1235 if (full_write (out_fd, bytes, 5) < 5)
1240 assert (new_attr.color >= 0 && new_attr.color < 88);
1244 bytes[0] = 0x1B; bytes[1] = '[';
1245 bytes[2] = '3'; bytes[3] = '8'; bytes[4] = ';';
1246 bytes[5] = '5'; bytes[6] = ';';
1248 if (new_attr.color >= 10)
1249 *p++ = '0' + (new_attr.color / 10);
1250 *p++ = '0' + (new_attr.color % 10);
1252 if (full_write (out_fd, bytes, p - bytes) < p - bytes)
1257 assert (new_attr.color >= 0 && new_attr.color < 256);
1261 bytes[0] = 0x1B; bytes[1] = '[';
1262 bytes[2] = '3'; bytes[3] = '8'; bytes[4] = ';';
1263 bytes[5] = '5'; bytes[6] = ';';
1265 if (new_attr.color >= 100)
1266 *p++ = '0' + (new_attr.color / 100);
1267 if (new_attr.color >= 10)
1268 *p++ = '0' + ((new_attr.color % 100) / 10);
1269 *p++ = '0' + (new_attr.color % 10);
1271 if (full_write (out_fd, bytes, p - bytes) < p - bytes)
1279 if (new_attr.bgcolor != old_attr.bgcolor
1280 || (cleared_attributes && new_attr.bgcolor != COLOR_DEFAULT))
1282 assert (stream->supports_background);
1283 assert (new_attr.bgcolor != COLOR_DEFAULT);
1284 switch (stream->colormodel)
1287 assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 8);
1288 if (stream->set_a_background != NULL)
1289 tputs (tparm (stream->set_a_background,
1290 color_bgr (new_attr.bgcolor)),
1293 tputs (tparm (stream->set_background, new_attr.bgcolor),
1296 /* When we are dealing with an xterm, there is no need to go through
1297 tputs() because we know there is no padding and sleeping. */
1299 assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 8);
1302 bytes[0] = 0x1B; bytes[1] = '[';
1303 bytes[2] = '4'; bytes[3] = '0' + new_attr.bgcolor;
1305 if (full_write (out_fd, bytes, 5) < 5)
1310 assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 16);
1313 bytes[0] = 0x1B; bytes[1] = '[';
1314 if (new_attr.bgcolor < 8)
1316 bytes[2] = '4'; bytes[3] = '0' + new_attr.bgcolor;
1318 if (full_write (out_fd, bytes, 5) < 5)
1323 bytes[2] = '1'; bytes[3] = '0';
1324 bytes[4] = '0' + (new_attr.bgcolor - 8); bytes[5] = 'm';
1325 if (full_write (out_fd, bytes, 6) < 6)
1331 assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 88);
1335 bytes[0] = 0x1B; bytes[1] = '[';
1336 bytes[2] = '4'; bytes[3] = '8'; bytes[4] = ';';
1337 bytes[5] = '5'; bytes[6] = ';';
1339 if (new_attr.bgcolor >= 10)
1340 *p++ = '0' + (new_attr.bgcolor / 10);
1341 *p++ = '0' + (new_attr.bgcolor % 10);
1343 if (full_write (out_fd, bytes, p - bytes) < p - bytes)
1348 assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 256);
1352 bytes[0] = 0x1B; bytes[1] = '[';
1353 bytes[2] = '4'; bytes[3] = '8'; bytes[4] = ';';
1354 bytes[5] = '5'; bytes[6] = ';';
1356 if (new_attr.bgcolor >= 100)
1357 *p++ = '0' + (new_attr.bgcolor / 100);
1358 if (new_attr.bgcolor >= 10)
1359 *p++ = '0' + ((new_attr.bgcolor % 100) / 10);
1360 *p++ = '0' + (new_attr.bgcolor % 10);
1362 if (full_write (out_fd, bytes, p - bytes) < p - bytes)
1371 if (new_attr.weight != old_attr.weight
1372 || (cleared_attributes && new_attr.weight != WEIGHT_DEFAULT))
1374 assert (stream->supports_weight);
1375 assert (new_attr.weight != WEIGHT_DEFAULT);
1377 assert (new_attr.weight == WEIGHT_BOLD);
1378 tputs (stream->enter_bold_mode, 1, out_char);
1380 if (new_attr.posture != old_attr.posture
1381 || (cleared_attributes && new_attr.posture != POSTURE_DEFAULT))
1383 assert (stream->supports_posture);
1384 assert (new_attr.posture != POSTURE_DEFAULT);
1386 assert (new_attr.posture == POSTURE_ITALIC);
1387 tputs (stream->enter_italics_mode, 1, out_char);
1389 if (new_attr.underline != old_attr.underline
1390 || (cleared_attributes && new_attr.underline != UNDERLINE_DEFAULT))
1392 assert (stream->supports_underline);
1393 assert (new_attr.underline != UNDERLINE_DEFAULT);
1395 assert (new_attr.underline == UNDERLINE_ON);
1396 tputs (stream->enter_underline_mode, 1, out_char);
1400 /* Output the buffered line atomically.
1401 The terminal is assumed to have the default state (regarding colors and
1402 attributes) before this call. It is left in default state after this
1403 call (regardless of stream->curr_attr). */
1405 output_buffer (term_ostream_t stream)
1407 attributes_t default_attr;
1410 const attributes_t *ap;
1414 default_attr.color = COLOR_DEFAULT;
1415 default_attr.bgcolor = COLOR_DEFAULT;
1416 default_attr.weight = WEIGHT_DEFAULT;
1417 default_attr.posture = POSTURE_DEFAULT;
1418 default_attr.underline = UNDERLINE_DEFAULT;
1420 attr = default_attr;
1422 cp = stream->buffer;
1423 ap = stream->attrbuffer;
1424 len = stream->buflen;
1426 /* See how much we can output without blocking signals. */
1427 for (n = 0; n < len && equal_attributes (ap[n], attr); n++)
1431 if (full_write (stream->fd, cp, n) < n)
1432 error (EXIT_FAILURE, errno, _("error writing to %s"), stream->filename);
1439 /* Block fatal signals, so that a SIGINT or similar doesn't interrupt
1440 us without the possibility of restoring the terminal's state. */
1441 block_fatal_signals ();
1442 /* Likewise for SIGTSTP etc. */
1443 block_stopping_signals ();
1445 /* Enable the exit handler for restoring the terminal's state. */
1447 (stream->supports_foreground || stream->supports_background
1451 (stream->supports_weight ? stream->exit_attribute_mode : NULL);
1453 (stream->supports_posture
1454 ? (stream->exit_italics_mode != NULL
1455 ? stream->exit_italics_mode
1456 : stream->exit_attribute_mode)
1459 (stream->supports_underline
1460 ? (stream->exit_underline_mode != NULL
1461 ? stream->exit_underline_mode
1462 : stream->exit_attribute_mode)
1464 out_fd = stream->fd;
1465 out_filename = stream->filename;
1469 /* Activate the attributes in *ap. */
1470 out_attr_change (stream, attr, *ap);
1472 /* See how many characters we can output without further attribute
1474 for (n = 1; n < len && equal_attributes (ap[n], attr); n++)
1476 if (full_write (stream->fd, cp, n) < n)
1477 error (EXIT_FAILURE, errno, _("error writing to %s"),
1484 /* Switch back to the default attributes. */
1485 out_attr_change (stream, attr, default_attr);
1487 /* Disable the exit handler. */
1489 out_filename = NULL;
1491 /* Unblock fatal and stopping signals. */
1492 unblock_stopping_signals ();
1493 unblock_fatal_signals ();
1498 /* Implementation of ostream_t methods. */
1501 term_ostream__rgb_to_color (term_ostream_t stream, int red, int green, int blue)
1503 switch (stream->colormodel)
1506 return rgb_to_color_monochrome ();
1508 return rgb_to_color_common8 (red, green, blue);
1510 return rgb_to_color_xterm8 (red, green, blue);
1512 return rgb_to_color_xterm16 (red, green, blue);
1514 return rgb_to_color_xterm88 (red, green, blue);
1516 return rgb_to_color_xterm256 (red, green, blue);
1523 term_ostream__write_mem (term_ostream_t stream, const void *data, size_t len)
1525 const char *cp = (const char *) data;
1528 /* Look for the next newline. */
1529 const char *newline = (const char *) memchr (cp, '\n', len);
1530 size_t n = (newline != NULL ? newline - cp : len);
1532 /* Copy n bytes into the buffer. */
1533 if (n > stream->allocated - stream->buflen)
1535 size_t new_allocated =
1536 xmax (xsum (stream->buflen, n),
1537 xsum (stream->allocated, stream->allocated));
1538 if (size_overflow_p (new_allocated))
1539 error (EXIT_FAILURE, 0,
1540 _("%s: too much output, buffer size overflow"),
1542 stream->buffer = (char *) xrealloc (stream->buffer, new_allocated);
1543 stream->attrbuffer =
1545 xrealloc (stream->attrbuffer,
1546 new_allocated * sizeof (attributes_t));
1547 stream->allocated = new_allocated;
1549 memcpy (stream->buffer + stream->buflen, cp, n);
1551 attributes_t attr = stream->simp_attr;
1552 attributes_t *ap = stream->attrbuffer + stream->buflen;
1553 attributes_t *ap_end = ap + n;
1554 for (; ap < ap_end; ap++)
1557 stream->buflen += n;
1559 if (newline != NULL)
1561 output_buffer (stream);
1562 if (full_write (stream->fd, "\n", 1) < 1)
1563 error (EXIT_FAILURE, errno, _("error writing to %s"),
1565 cp += n + 1; /* cp = newline + 1; */
1574 term_ostream__flush (term_ostream_t stream)
1576 output_buffer (stream);
1580 term_ostream__free (term_ostream_t stream)
1582 term_ostream_flush (stream);
1583 free (stream->filename);
1584 if (stream->set_a_foreground != NULL)
1585 free (stream->set_a_foreground);
1586 if (stream->set_foreground != NULL)
1587 free (stream->set_foreground);
1588 if (stream->set_a_background != NULL)
1589 free (stream->set_a_background);
1590 if (stream->set_background != NULL)
1591 free (stream->set_background);
1592 if (stream->orig_pair != NULL)
1593 free (stream->orig_pair);
1594 if (stream->enter_bold_mode != NULL)
1595 free (stream->enter_bold_mode);
1596 if (stream->enter_italics_mode != NULL)
1597 free (stream->enter_italics_mode);
1598 if (stream->exit_italics_mode != NULL)
1599 free (stream->exit_italics_mode);
1600 if (stream->enter_underline_mode != NULL)
1601 free (stream->enter_underline_mode);
1602 if (stream->exit_underline_mode != NULL)
1603 free (stream->exit_underline_mode);
1604 if (stream->exit_attribute_mode != NULL)
1605 free (stream->exit_attribute_mode);
1606 free (stream->buffer);
1610 /* Implementation of term_ostream_t methods. */
1613 term_ostream__get_color (term_ostream_t stream)
1615 return stream->curr_attr.color;
1619 term_ostream__set_color (term_ostream_t stream, term_color_t color)
1621 stream->curr_attr.color = color;
1622 stream->simp_attr = simplify_attributes (stream, stream->curr_attr);
1626 term_ostream__get_bgcolor (term_ostream_t stream)
1628 return stream->curr_attr.bgcolor;
1632 term_ostream__set_bgcolor (term_ostream_t stream, term_color_t color)
1634 stream->curr_attr.bgcolor = color;
1635 stream->simp_attr = simplify_attributes (stream, stream->curr_attr);
1638 static term_weight_t
1639 term_ostream__get_weight (term_ostream_t stream)
1641 return stream->curr_attr.weight;
1645 term_ostream__set_weight (term_ostream_t stream, term_weight_t weight)
1647 stream->curr_attr.weight = weight;
1648 stream->simp_attr = simplify_attributes (stream, stream->curr_attr);
1651 static term_posture_t
1652 term_ostream__get_posture (term_ostream_t stream)
1654 return stream->curr_attr.posture;
1658 term_ostream__set_posture (term_ostream_t stream, term_posture_t posture)
1660 stream->curr_attr.posture = posture;
1661 stream->simp_attr = simplify_attributes (stream, stream->curr_attr);
1664 static term_underline_t
1665 term_ostream__get_underline (term_ostream_t stream)
1667 return stream->curr_attr.underline;
1671 term_ostream__set_underline (term_ostream_t stream, term_underline_t underline)
1673 stream->curr_attr.underline = underline;
1674 stream->simp_attr = simplify_attributes (stream, stream->curr_attr);
1679 static inline char *
1680 xstrdup0 (const char *str)
1685 if (str == (const char *)(-1))
1688 return xstrdup (str);
1692 term_ostream_create (int fd, const char *filename)
1694 term_ostream_t stream = XMALLOC (struct term_ostream_representation);
1697 stream->base.vtable = &term_ostream_vtable;
1699 stream->filename = xstrdup (filename);
1702 stream->max_colors = -1;
1703 stream->no_color_video = -1;
1704 stream->set_a_foreground = NULL;
1705 stream->set_foreground = NULL;
1706 stream->set_a_background = NULL;
1707 stream->set_background = NULL;
1708 stream->orig_pair = NULL;
1709 stream->enter_bold_mode = NULL;
1710 stream->enter_italics_mode = NULL;
1711 stream->exit_italics_mode = NULL;
1712 stream->enter_underline_mode = NULL;
1713 stream->exit_underline_mode = NULL;
1714 stream->exit_attribute_mode = NULL;
1716 /* Retrieve the terminal type. */
1717 term = getenv ("TERM");
1718 if (term != NULL && term[0] != '\0')
1720 /* When the terminfo function are available, we prefer them over the
1721 termcap functions because
1722 1. they don't risk a buffer overflow,
1723 2. on OSF/1, for TERM=xterm, the tiget* functions provide access
1724 to the number of colors and the color escape sequences, whereas
1725 the tget* functions don't provide them. */
1729 if (setupterm (term, fd, &err) || err == 1)
1731 /* Retrieve particular values depending on the terminal type. */
1732 stream->max_colors = tigetnum ("colors");
1733 stream->no_color_video = tigetnum ("ncv");
1734 stream->set_a_foreground = xstrdup0 (tigetstr ("setaf"));
1735 stream->set_foreground = xstrdup0 (tigetstr ("setf"));
1736 stream->set_a_background = xstrdup0 (tigetstr ("setab"));
1737 stream->set_background = xstrdup0 (tigetstr ("setb"));
1738 stream->orig_pair = xstrdup0 (tigetstr ("op"));
1739 stream->enter_bold_mode = xstrdup0 (tigetstr ("bold"));
1740 stream->enter_italics_mode = xstrdup0 (tigetstr ("sitm"));
1741 stream->exit_italics_mode = xstrdup0 (tigetstr ("ritm"));
1742 stream->enter_underline_mode = xstrdup0 (tigetstr ("smul"));
1743 stream->exit_underline_mode = xstrdup0 (tigetstr ("rmul"));
1744 stream->exit_attribute_mode = xstrdup0 (tigetstr ("sgr0"));
1747 struct { char buf[1024]; char canary[4]; } termcapbuf;
1750 /* Call tgetent, being defensive against buffer overflow. */
1751 memcpy (termcapbuf.canary, "CnRy", 4);
1752 retval = tgetent (termcapbuf.buf, term);
1753 if (memcmp (termcapbuf.canary, "CnRy", 4) != 0)
1754 /* Buffer overflow! */
1759 struct { char buf[1024]; char canary[4]; } termentrybuf;
1762 /* Prepare for calling tgetstr, being defensive against buffer
1763 overflow. ncurses' tgetstr() supports a second argument NULL,
1764 but NetBSD's tgetstr() doesn't. */
1765 memcpy (termentrybuf.canary, "CnRz", 4);
1766 #define TEBP ((termentryptr = termentrybuf.buf), &termentryptr)
1768 /* Retrieve particular values depending on the terminal type. */
1769 stream->max_colors = tgetnum ("Co");
1770 stream->no_color_video = tgetnum ("NC");
1771 stream->set_a_foreground = xstrdup0 (tgetstr ("AF", TEBP));
1772 stream->set_foreground = xstrdup0 (tgetstr ("Sf", TEBP));
1773 stream->set_a_background = xstrdup0 (tgetstr ("AB", TEBP));
1774 stream->set_background = xstrdup0 (tgetstr ("Sb", TEBP));
1775 stream->orig_pair = xstrdup0 (tgetstr ("op", TEBP));
1776 stream->enter_bold_mode = xstrdup0 (tgetstr ("md", TEBP));
1777 stream->enter_italics_mode = xstrdup0 (tgetstr ("ZH", TEBP));
1778 stream->exit_italics_mode = xstrdup0 (tgetstr ("ZR", TEBP));
1779 stream->enter_underline_mode = xstrdup0 (tgetstr ("us", TEBP));
1780 stream->exit_underline_mode = xstrdup0 (tgetstr ("ue", TEBP));
1781 stream->exit_attribute_mode = xstrdup0 (tgetstr ("me", TEBP));
1784 /* The BeOS termcap entry for "beterm" is broken: For "AF" and "AB"
1785 it contains balues in terminfo syntax but the system's tparam()
1786 function understands only the termcap syntax. */
1787 if (stream->set_a_foreground != NULL
1788 && strcmp (stream->set_a_foreground, "\033[3%p1%dm") == 0)
1790 free (stream->set_a_foreground);
1791 stream->set_a_foreground = xstrdup ("\033[3%dm");
1793 if (stream->set_a_background != NULL
1794 && strcmp (stream->set_a_background, "\033[4%p1%dm") == 0)
1796 free (stream->set_a_background);
1797 stream->set_a_background = xstrdup ("\033[4%dm");
1801 /* The termcap entry for cygwin is broken: It has no "ncv" value,
1802 but bold and underline are actually rendered through colors. */
1803 if (strcmp (term, "cygwin") == 0)
1804 stream->no_color_video |= 2 | 32;
1806 /* Done with tgetstr. Detect possible buffer overflow. */
1808 if (memcmp (termentrybuf.canary, "CnRz", 4) != 0)
1809 /* Buffer overflow! */
1813 /* Fallback code for platforms with neither the terminfo nor the termcap
1814 functions, such as mingw.
1815 Assume the ANSI escape sequences. Extracted through
1816 "TERM=ansi infocmp", replacing \E with \033. */
1817 stream->max_colors = 8;
1818 stream->no_color_video = 3;
1819 stream->set_a_foreground = xstrdup ("\033[3%p1%dm");
1820 stream->set_a_background = xstrdup ("\033[4%p1%dm");
1821 stream->orig_pair = xstrdup ("\033[39;49m");
1822 stream->enter_bold_mode = xstrdup ("\033[1m");
1823 stream->enter_underline_mode = xstrdup ("\033[4m");
1824 stream->exit_underline_mode = xstrdup ("\033[m");
1825 stream->exit_attribute_mode = xstrdup ("\033[0;10m");
1828 /* AIX 4.3.2, IRIX 6.5, HP-UX 11, Solaris 7..10 all lack the
1829 description of color capabilities of "xterm" and "xterms"
1830 in their terminfo database. But it is important to have
1831 color in xterm. So we provide the color capabilities here. */
1832 if (stream->max_colors <= 1
1833 && (strcmp (term, "xterm") == 0 || strcmp (term, "xterms") == 0))
1835 stream->max_colors = 8;
1836 stream->set_a_foreground = xstrdup ("\033[3%p1%dm");
1837 stream->set_a_background = xstrdup ("\033[4%p1%dm");
1838 stream->orig_pair = xstrdup ("\033[39;49m");
1842 /* Infer the capabilities. */
1843 stream->supports_foreground =
1844 (stream->max_colors >= 8
1845 && (stream->set_a_foreground != NULL || stream->set_foreground != NULL)
1846 && stream->orig_pair != NULL);
1847 stream->supports_background =
1848 (stream->max_colors >= 8
1849 && (stream->set_a_background != NULL || stream->set_background != NULL)
1850 && stream->orig_pair != NULL);
1851 stream->colormodel =
1852 (stream->supports_foreground || stream->supports_background
1854 && (/* Recognize xterm-16color, xterm-88color, xterm-256color. */
1855 (strlen (term) >= 5 && memcmp (term, "xterm", 5) == 0)
1856 || /* Recognize rxvt-16color. */
1857 (strlen (term) >= 4 && memcmp (term, "rxvt", 7) == 0)
1858 || /* Recognize konsole-16color. */
1859 (strlen (term) >= 7 && memcmp (term, "konsole", 7) == 0))
1860 ? (stream->max_colors == 256 ? cm_xterm256 :
1861 stream->max_colors == 88 ? cm_xterm88 :
1862 stream->max_colors == 16 ? cm_xterm16 :
1866 stream->supports_weight =
1867 (stream->enter_bold_mode != NULL && stream->exit_attribute_mode != NULL);
1868 stream->supports_posture =
1869 (stream->enter_italics_mode != NULL
1870 && (stream->exit_italics_mode != NULL
1871 || stream->exit_attribute_mode != NULL));
1872 stream->supports_underline =
1873 (stream->enter_underline_mode != NULL
1874 && (stream->exit_underline_mode != NULL
1875 || stream->exit_attribute_mode != NULL));
1877 /* Initialize the buffer. */
1878 stream->allocated = 120;
1879 stream->buffer = XNMALLOC (stream->allocated, char);
1880 stream->attrbuffer = XNMALLOC (stream->allocated, attributes_t);
1883 /* Initialize the current attributes. */
1884 stream->curr_attr.color = COLOR_DEFAULT;
1885 stream->curr_attr.bgcolor = COLOR_DEFAULT;
1886 stream->curr_attr.weight = WEIGHT_DEFAULT;
1887 stream->curr_attr.posture = POSTURE_DEFAULT;
1888 stream->curr_attr.underline = UNDERLINE_DEFAULT;
1889 stream->simp_attr = simplify_attributes (stream, stream->curr_attr);
1891 /* Register an exit handler. */
1893 static bool registered = false;
1904 #line 1905 "term-ostream.c"
1906 const struct term_ostream_implementation term_ostream_vtable =
1908 term_ostream_superclasses,
1909 sizeof (term_ostream_superclasses) / sizeof (term_ostream_superclasses[0]),
1910 sizeof (struct term_ostream_representation),
1911 term_ostream__write_mem,
1912 term_ostream__flush,
1914 term_ostream__rgb_to_color,
1915 term_ostream__get_color,
1916 term_ostream__set_color,
1917 term_ostream__get_bgcolor,
1918 term_ostream__set_bgcolor,
1919 term_ostream__get_weight,
1920 term_ostream__set_weight,
1921 term_ostream__get_posture,
1922 term_ostream__set_posture,
1923 term_ostream__get_underline,
1924 term_ostream__set_underline,
1929 /* Define the functions that invoke the methods. */
1932 term_ostream_write_mem (term_ostream_t first_arg, const void *data, size_t len)
1934 const struct term_ostream_implementation *vtable =
1935 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
1936 vtable->write_mem (first_arg,data,len);
1940 term_ostream_flush (term_ostream_t first_arg)
1942 const struct term_ostream_implementation *vtable =
1943 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
1944 vtable->flush (first_arg);
1948 term_ostream_free (term_ostream_t first_arg)
1950 const struct term_ostream_implementation *vtable =
1951 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
1952 vtable->free (first_arg);
1956 term_ostream_rgb_to_color (term_ostream_t first_arg, int red, int green, int blue)
1958 const struct term_ostream_implementation *vtable =
1959 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
1960 return vtable->rgb_to_color (first_arg,red,green,blue);
1964 term_ostream_get_color (term_ostream_t first_arg)
1966 const struct term_ostream_implementation *vtable =
1967 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
1968 return vtable->get_color (first_arg);
1972 term_ostream_set_color (term_ostream_t first_arg, term_color_t color)
1974 const struct term_ostream_implementation *vtable =
1975 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
1976 vtable->set_color (first_arg,color);
1980 term_ostream_get_bgcolor (term_ostream_t first_arg)
1982 const struct term_ostream_implementation *vtable =
1983 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
1984 return vtable->get_bgcolor (first_arg);
1988 term_ostream_set_bgcolor (term_ostream_t first_arg, term_color_t color)
1990 const struct term_ostream_implementation *vtable =
1991 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
1992 vtable->set_bgcolor (first_arg,color);
1996 term_ostream_get_weight (term_ostream_t first_arg)
1998 const struct term_ostream_implementation *vtable =
1999 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
2000 return vtable->get_weight (first_arg);
2004 term_ostream_set_weight (term_ostream_t first_arg, term_weight_t weight)
2006 const struct term_ostream_implementation *vtable =
2007 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
2008 vtable->set_weight (first_arg,weight);
2012 term_ostream_get_posture (term_ostream_t first_arg)
2014 const struct term_ostream_implementation *vtable =
2015 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
2016 return vtable->get_posture (first_arg);
2020 term_ostream_set_posture (term_ostream_t first_arg, term_posture_t posture)
2022 const struct term_ostream_implementation *vtable =
2023 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
2024 vtable->set_posture (first_arg,posture);
2028 term_ostream_get_underline (term_ostream_t first_arg)
2030 const struct term_ostream_implementation *vtable =
2031 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
2032 return vtable->get_underline (first_arg);
2036 term_ostream_set_underline (term_ostream_t first_arg, term_underline_t underline)
2038 const struct term_ostream_implementation *vtable =
2039 ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
2040 vtable->set_underline (first_arg,underline);