~ubuntu-branches/ubuntu/utopic/gettext/utopic

« back to all changes in this revision

Viewing changes to gettext-tools/gnulib-lib/term-ostream.c

  • Committer: Colin Watson
  • Date: 2010-08-01 21:36:08 UTC
  • mfrom: (2.1.10 sid)
  • Revision ID: cjwatson@canonical.com-20100801213608-yy7vkm8lpatep3ci
merge from Debian 0.18.1.1-1

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
#line 1 "term-ostream.oo.c"
4
4
/* Output stream for attributed text, producing ANSI escape sequences.
5
 
   Copyright (C) 2006-2007 Free Software Foundation, Inc.
 
5
   Copyright (C) 2006-2008 Free Software Foundation, Inc.
6
6
   Written by Bruno Haible <bruno@clisp.org>, 2006.
7
7
 
8
8
   This program is free software: you can redistribute it and/or modify
82
82
  if (r > g)
83
83
    {
84
84
      if (b > r)
85
 
        {
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;
90
 
        }
 
85
        {
 
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;
 
90
        }
91
91
      else if (b <= g)
92
 
        {
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;
97
 
        }
 
92
        {
 
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;
 
97
        }
98
98
      else
99
 
        {
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;
104
 
        }
 
99
        {
 
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;
 
104
        }
105
105
    }
106
106
  else
107
107
    {
108
108
      if (b > g)
109
 
        {
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;
114
 
        }
 
109
        {
 
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;
 
114
        }
115
115
      else if (b < r)
116
 
        {
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;
121
 
        }
 
116
        {
 
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;
 
121
        }
122
122
      else if (g > r)
123
 
        {
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;
128
 
        }
 
123
        {
 
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;
 
128
        }
129
129
      else
130
 
        {
131
 
          /* r = g = b.  A grey color.  */
132
 
          result->hue = 0; /* arbitrary */
133
 
          result->saturation = 0;
134
 
          result->brightness = (float) r / 255.0f;
135
 
        }
 
130
        {
 
131
          /* r = g = b.  A grey color.  */
 
132
          result->hue = 0; /* arbitrary */
 
133
          result->saturation = 0;
 
134
          result->brightness = (float) r / 255.0f;
 
135
        }
136
136
    }
137
137
}
138
138
 
146
146
  float angle1 = color1->hue * 1.04719755f; /* normalize to [0,2π] */
147
147
  float angle2 = color2->hue * 1.04719755f; /* normalize to [0,2π] */
148
148
  float delta_x = color1->saturation * cosf (angle1)
149
 
                  - color2->saturation * cosf (angle2);
 
149
                  - color2->saturation * cosf (angle2);
150
150
  float delta_y = color1->saturation * sinf (angle1)
151
 
                  - color2->saturation * sinf (angle2);
 
151
                  - color2->saturation * sinf (angle2);
152
152
  float delta_v = color1->brightness
153
 
                  - color2->brightness;
 
153
                  - color2->brightness;
154
154
 
155
155
  return delta_x * delta_x + delta_y * delta_y + delta_v * delta_v;
156
156
#else
159
159
  float delta_hue =
160
160
    (color1->hue >= color2->hue
161
161
     ? (color1->hue - color2->hue >= 3.0f
162
 
        ? 6.0f + color2->hue - color1->hue
163
 
        : color1->hue - color2->hue)
 
162
        ? 6.0f + color2->hue - color1->hue
 
163
        : color1->hue - color2->hue)
164
164
     : (color2->hue - color1->hue >= 3.0f
165
 
        ? 6.0f + color1->hue - color2->hue
166
 
        : color2->hue - color1->hue));
 
165
        ? 6.0f + color1->hue - color2->hue
 
166
        : color2->hue - color1->hue));
167
167
  float min_saturation =
168
168
    (color1->saturation < color2->saturation
169
169
     ? color1->saturation
172
172
  float delta_brightness = color1->brightness - color2->brightness;
173
173
 
174
174
  return delta_hue * delta_hue * min_saturation
175
 
         + delta_saturation * delta_saturation * 0.2f
176
 
         + delta_brightness * delta_brightness * 0.8f;
 
175
         + delta_saturation * delta_saturation * 0.2f
 
176
         + delta_brightness * delta_brightness * 0.8f;
177
177
#endif
178
178
}
179
179
 
201
201
 
202
202
      /* Avoid converting a color to grey, or fading out a color too much.  */
203
203
      if (i_hsv.saturation > given_hsv.saturation * 0.5f)
204
 
        {
205
 
          float distance = color_distance (&given_hsv, &i_hsv);
206
 
          if (distance < best_distance)
207
 
            {
208
 
              best_index = i;
209
 
              best_distance = distance;
210
 
            }
211
 
        }
 
204
        {
 
205
          float distance = color_distance (&given_hsv, &i_hsv);
 
206
          if (distance < best_distance)
 
207
            {
 
208
              best_index = i;
 
209
              best_distance = distance;
 
210
            }
 
211
        }
212
212
    }
213
213
 
214
214
#if 0 /* Debugging code */
242
242
/* The color model used by the terminal.  */
243
243
typedef enum
244
244
{
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.  */
 
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.  */
251
251
} colormodel_t;
252
252
 
253
253
/* ----------------------- cm_monochrome color model ----------------------- */
298
298
      /* Greyscale approximation.  */
299
299
      float luminance = color_luminance (r, g, b);
300
300
      if (luminance < 0.500f)
301
 
        return 0;
 
301
        return 0;
302
302
      else
303
 
        return 7;
 
303
        return 7;
304
304
    }
305
305
  else
306
306
    /* Color approximation.  */
356
356
      /* Greyscale approximation.  */
357
357
      float luminance = color_luminance (r, g, b);
358
358
      if (luminance < 0.500f)
359
 
        return 0;
 
359
        return 0;
360
360
      else
361
 
        return 7;
 
361
        return 7;
362
362
    }
363
363
  else
364
364
    /* Color approximation.  */
404
404
      /* Greyscale approximation.  */
405
405
      float luminance = color_luminance (r, g, b);
406
406
      if (luminance < 0.151f)
407
 
        return 0;
 
407
        return 0;
408
408
      else if (luminance < 0.600f)
409
 
        return 8;
 
409
        return 8;
410
410
      else if (luminance < 0.949f)
411
 
        return 7;
 
411
        return 7;
412
412
      else
413
 
        return 15;
 
413
        return 15;
414
414
    }
415
415
  else
416
416
    /* Color approximation.  */
530
530
      /* Greyscale approximation.  */
531
531
      float luminance = color_luminance (r, g, b);
532
532
      if (luminance < 0.090f)
533
 
        return 0;
 
533
        return 0;
534
534
      else if (luminance < 0.241f)
535
 
        return 80;
 
535
        return 80;
536
536
      else if (luminance < 0.331f)
537
 
        return 8;
 
537
        return 8;
538
538
      else if (luminance < 0.406f)
539
 
        return 81;
 
539
        return 81;
540
540
      else if (luminance < 0.498f)
541
 
        return 82;
 
541
        return 82;
542
542
      else if (luminance < 0.585f)
543
 
        return 37;
 
543
        return 37;
544
544
      else if (luminance < 0.680f)
545
 
        return 84;
 
545
        return 84;
546
546
      else if (luminance < 0.764f)
547
 
        return 85;
 
547
        return 85;
548
548
      else if (luminance < 0.810f)
549
 
        return 58;
 
549
        return 58;
550
550
      else if (luminance < 0.857f)
551
 
        return 86;
 
551
        return 86;
552
552
      else if (luminance < 0.902f)
553
 
        return 7;
 
553
        return 7;
554
554
      else if (luminance < 0.953f)
555
 
        return 87;
 
555
        return 87;
556
556
      else
557
 
        return 15;
 
557
        return 15;
558
558
    }
559
559
  else
560
560
    /* Color approximation.  */
842
842
      /* Greyscale approximation.  */
843
843
      float luminance = color_luminance (r, g, b);
844
844
      if (luminance < 0.015f)
845
 
        return 0;
 
845
        return 0;
846
846
      else if (luminance < 0.051f)
847
 
        return 232;
 
847
        return 232;
848
848
      else if (luminance < 0.090f)
849
 
        return 233;
 
849
        return 233;
850
850
      else if (luminance < 0.129f)
851
 
        return 234;
 
851
        return 234;
852
852
      else if (luminance < 0.157f)
853
 
        return 235;
 
853
        return 235;
854
854
      else if (luminance < 0.177f)
855
 
        return 59;
 
855
        return 59;
856
856
      else if (luminance < 0.207f)
857
 
        return 236;
 
857
        return 236;
858
858
      else if (luminance < 0.247f)
859
 
        return 237;
 
859
        return 237;
860
860
      else if (luminance < 0.284f)
861
 
        return 238;
 
861
        return 238;
862
862
      else if (luminance < 0.304f)
863
 
        return 8;
 
863
        return 8;
864
864
      else if (luminance < 0.319f)
865
 
        return 239;
 
865
        return 239;
866
866
      else if (luminance < 0.339f)
867
 
        return 102;
 
867
        return 102;
868
868
      else if (luminance < 0.364f)
869
 
        return 240;
 
869
        return 240;
870
870
      else if (luminance < 0.404f)
871
 
        return 241;
 
871
        return 241;
872
872
      else if (luminance < 0.443f)
873
 
        return 242;
 
873
        return 242;
874
874
      else if (luminance < 0.480f)
875
 
        return 243;
 
875
        return 243;
876
876
      else if (luminance < 0.500f)
877
 
        return 145;
 
877
        return 145;
878
878
      else if (luminance < 0.521f)
879
 
        return 244;
 
879
        return 244;
880
880
      else if (luminance < 0.560f)
881
 
        return 245;
 
881
        return 245;
882
882
      else if (luminance < 0.600f)
883
 
        return 246;
 
883
        return 246;
884
884
      else if (luminance < 0.639f)
885
 
        return 247;
 
885
        return 247;
886
886
      else if (luminance < 0.663f)
887
 
        return 248;
 
887
        return 248;
888
888
      else if (luminance < 0.682f)
889
 
        return 188;
 
889
        return 188;
890
890
      else if (luminance < 0.717f)
891
 
        return 249;
 
891
        return 249;
892
892
      else if (luminance < 0.756f)
893
 
        return 250;
 
893
        return 250;
894
894
      else if (luminance < 0.796f)
895
 
        return 251;
 
895
        return 251;
896
896
      else if (luminance < 0.823f)
897
 
        return 252;
 
897
        return 252;
898
898
      else if (luminance < 0.843f)
899
 
        return 231;
 
899
        return 231;
900
900
      else if (luminance < 0.874f)
901
 
        return 253;
 
901
        return 253;
902
902
      else if (luminance < 0.896f)
903
 
        return 254;
 
903
        return 254;
904
904
      else if (luminance < 0.915f)
905
 
        return 7;
 
905
        return 7;
906
906
      else if (luminance < 0.966f)
907
 
        return 255;
 
907
        return 255;
908
908
      else
909
 
        return 15;
 
909
        return 15;
910
910
    }
911
911
  else
912
912
    /* Color approximation.  */
962
962
      && stream->no_color_video > 0)
963
963
    {
964
964
      /* When colors and attributes can not be represented simultaneously,
965
 
         we give preference to the color.  */
 
965
         we give preference to the color.  */
966
966
      if (stream->no_color_video & 2)
967
 
        /* Colors conflict with underlining.  */
968
 
        attr.underline = UNDERLINE_OFF;
 
967
        /* Colors conflict with underlining.  */
 
968
        attr.underline = UNDERLINE_OFF;
969
969
      if (stream->no_color_video & 32)
970
 
        /* Colors conflict with bold weight.  */
971
 
        attr.weight = WEIGHT_NORMAL;
 
970
        /* Colors conflict with bold weight.  */
 
971
        attr.weight = WEIGHT_NORMAL;
972
972
    }
973
973
  if (!stream->supports_foreground)
974
974
    attr.color = COLOR_DEFAULT;
1017
1017
  if (out_fd >= 0)
1018
1018
    {
1019
1019
      if (restore_colors != NULL)
1020
 
        tputs (restore_colors, 1, out_char_unchecked);
 
1020
        tputs (restore_colors, 1, out_char_unchecked);
1021
1021
      if (restore_weight != NULL)
1022
 
        tputs (restore_weight, 1, out_char_unchecked);
 
1022
        tputs (restore_weight, 1, out_char_unchecked);
1023
1023
      if (restore_posture != NULL)
1024
 
        tputs (restore_posture, 1, out_char_unchecked);
 
1024
        tputs (restore_posture, 1, out_char_unchecked);
1025
1025
      if (restore_underline != NULL)
1026
 
        tputs (restore_underline, 1, out_char_unchecked);
 
1026
        tputs (restore_underline, 1, out_char_unchecked);
1027
1027
    }
1028
1028
}
1029
1029
 
1056
1056
 
1057
1057
      sigemptyset (&stopping_signal_set);
1058
1058
      for (i = 0; i < num_stopping_signals; i++)
1059
 
        sigaddset (&stopping_signal_set, stopping_signals[i]);
 
1059
        sigaddset (&stopping_signal_set, stopping_signals[i]);
1060
1060
 
1061
1061
      stopping_signal_set_initialized = true;
1062
1062
    }
1083
1083
equal_attributes (attributes_t attr1, attributes_t attr2)
1084
1084
{
1085
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);
 
1086
          && attr1.bgcolor == attr2.bgcolor
 
1087
          && attr1.weight == attr2.weight
 
1088
          && attr1.posture == attr2.posture
 
1089
          && attr1.underline == attr2.underline);
1090
1090
}
1091
1091
 
1092
1092
/* Signal error after full_write failed.  */
1114
1114
/* Output escape sequences to switch from OLD_ATTR to NEW_ATTR.  */
1115
1115
static void
1116
1116
out_attr_change (term_ostream_t stream,
1117
 
                 attributes_t old_attr, attributes_t new_attr)
 
1117
                 attributes_t old_attr, attributes_t new_attr)
1118
1118
{
1119
1119
  bool cleared_attributes;
1120
1120
 
1170
1170
  if ((old_attr.weight != WEIGHT_NORMAL
1171
1171
       && new_attr.weight == WEIGHT_NORMAL)
1172
1172
      || (old_attr.posture != POSTURE_NORMAL
1173
 
          && new_attr.posture == POSTURE_NORMAL
1174
 
          /* implies stream->exit_italics_mode == NULL */)
 
1173
          && new_attr.posture == POSTURE_NORMAL
 
1174
          /* implies stream->exit_italics_mode == NULL */)
1175
1175
      || (old_attr.underline != UNDERLINE_OFF
1176
 
          && new_attr.underline == UNDERLINE_OFF
1177
 
          /* implies stream->exit_underline_mode == NULL */))
 
1176
          && new_attr.underline == UNDERLINE_OFF
 
1177
          /* implies stream->exit_underline_mode == NULL */))
1178
1178
    {
1179
1179
      tputs (stream->exit_attribute_mode, 1, out_char);
1180
1180
      /* We don't know exactly what effects exit_attribute_mode has, but
1181
 
         this is the minimum effect:  */
 
1181
         this is the minimum effect:  */
1182
1182
      old_attr.weight = WEIGHT_NORMAL;
1183
1183
      if (stream->exit_italics_mode == NULL)
1184
 
        old_attr.posture = POSTURE_NORMAL;
 
1184
        old_attr.posture = POSTURE_NORMAL;
1185
1185
      if (stream->exit_underline_mode == NULL)
1186
 
        old_attr.underline = UNDERLINE_OFF;
 
1186
        old_attr.underline = UNDERLINE_OFF;
1187
1187
      cleared_attributes = true;
1188
1188
    }
1189
1189
 
1194
1194
      assert (stream->supports_foreground);
1195
1195
      assert (new_attr.color != COLOR_DEFAULT);
1196
1196
      switch (stream->colormodel)
1197
 
        {
1198
 
        case cm_common8:
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)),
1203
 
                   1, out_char);
1204
 
          else
1205
 
            tputs (tparm (stream->set_foreground, new_attr.color),
1206
 
                   1, out_char);
1207
 
          break;
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.  */
1210
 
        case cm_xterm8:
1211
 
          assert (new_attr.color >= 0 && new_attr.color < 8);
1212
 
          {
1213
 
            char bytes[5];
1214
 
            bytes[0] = 0x1B; bytes[1] = '[';
1215
 
            bytes[2] = '3'; bytes[3] = '0' + new_attr.color;
1216
 
            bytes[4] = 'm';
1217
 
            if (full_write (out_fd, bytes, 5) < 5)
1218
 
              out_error ();
1219
 
          }
1220
 
          break;
1221
 
        case cm_xterm16:
1222
 
          assert (new_attr.color >= 0 && new_attr.color < 16);
1223
 
          {
1224
 
            char bytes[5];
1225
 
            bytes[0] = 0x1B; bytes[1] = '[';
1226
 
            if (new_attr.color < 8)
1227
 
              {
1228
 
                bytes[2] = '3'; bytes[3] = '0' + new_attr.color;
1229
 
              }
1230
 
            else
1231
 
              {
1232
 
                bytes[2] = '9'; bytes[3] = '0' + (new_attr.color - 8);
1233
 
              }
1234
 
            bytes[4] = 'm';
1235
 
            if (full_write (out_fd, bytes, 5) < 5)
1236
 
              out_error ();
1237
 
          }
1238
 
          break;
1239
 
        case cm_xterm88:
1240
 
          assert (new_attr.color >= 0 && new_attr.color < 88);
1241
 
          {
1242
 
            char bytes[10];
1243
 
            char *p;
1244
 
            bytes[0] = 0x1B; bytes[1] = '[';
1245
 
            bytes[2] = '3'; bytes[3] = '8'; bytes[4] = ';';
1246
 
            bytes[5] = '5'; bytes[6] = ';';
1247
 
            p = bytes + 7;
1248
 
            if (new_attr.color >= 10)
1249
 
              *p++ = '0' + (new_attr.color / 10);
1250
 
            *p++ = '0' + (new_attr.color % 10);
1251
 
            *p++ = 'm';
1252
 
            if (full_write (out_fd, bytes, p - bytes) < p - bytes)
1253
 
              out_error ();
1254
 
          }
1255
 
          break;
1256
 
        case cm_xterm256:
1257
 
          assert (new_attr.color >= 0 && new_attr.color < 256);
1258
 
          {
1259
 
            char bytes[11];
1260
 
            char *p;
1261
 
            bytes[0] = 0x1B; bytes[1] = '[';
1262
 
            bytes[2] = '3'; bytes[3] = '8'; bytes[4] = ';';
1263
 
            bytes[5] = '5'; bytes[6] = ';';
1264
 
            p = bytes + 7;
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);
1270
 
            *p++ = 'm';
1271
 
            if (full_write (out_fd, bytes, p - bytes) < p - bytes)
1272
 
              out_error ();
1273
 
          }
1274
 
          break;
1275
 
        default:
1276
 
          abort ();
1277
 
        }
 
1197
        {
 
1198
        case cm_common8:
 
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)),
 
1203
                   1, out_char);
 
1204
          else
 
1205
            tputs (tparm (stream->set_foreground, new_attr.color),
 
1206
                   1, out_char);
 
1207
          break;
 
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.  */
 
1210
        case cm_xterm8:
 
1211
          assert (new_attr.color >= 0 && new_attr.color < 8);
 
1212
          {
 
1213
            char bytes[5];
 
1214
            bytes[0] = 0x1B; bytes[1] = '[';
 
1215
            bytes[2] = '3'; bytes[3] = '0' + new_attr.color;
 
1216
            bytes[4] = 'm';
 
1217
            if (full_write (out_fd, bytes, 5) < 5)
 
1218
              out_error ();
 
1219
          }
 
1220
          break;
 
1221
        case cm_xterm16:
 
1222
          assert (new_attr.color >= 0 && new_attr.color < 16);
 
1223
          {
 
1224
            char bytes[5];
 
1225
            bytes[0] = 0x1B; bytes[1] = '[';
 
1226
            if (new_attr.color < 8)
 
1227
              {
 
1228
                bytes[2] = '3'; bytes[3] = '0' + new_attr.color;
 
1229
              }
 
1230
            else
 
1231
              {
 
1232
                bytes[2] = '9'; bytes[3] = '0' + (new_attr.color - 8);
 
1233
              }
 
1234
            bytes[4] = 'm';
 
1235
            if (full_write (out_fd, bytes, 5) < 5)
 
1236
              out_error ();
 
1237
          }
 
1238
          break;
 
1239
        case cm_xterm88:
 
1240
          assert (new_attr.color >= 0 && new_attr.color < 88);
 
1241
          {
 
1242
            char bytes[10];
 
1243
            char *p;
 
1244
            bytes[0] = 0x1B; bytes[1] = '[';
 
1245
            bytes[2] = '3'; bytes[3] = '8'; bytes[4] = ';';
 
1246
            bytes[5] = '5'; bytes[6] = ';';
 
1247
            p = bytes + 7;
 
1248
            if (new_attr.color >= 10)
 
1249
              *p++ = '0' + (new_attr.color / 10);
 
1250
            *p++ = '0' + (new_attr.color % 10);
 
1251
            *p++ = 'm';
 
1252
            if (full_write (out_fd, bytes, p - bytes) < p - bytes)
 
1253
              out_error ();
 
1254
          }
 
1255
          break;
 
1256
        case cm_xterm256:
 
1257
          assert (new_attr.color >= 0 && new_attr.color < 256);
 
1258
          {
 
1259
            char bytes[11];
 
1260
            char *p;
 
1261
            bytes[0] = 0x1B; bytes[1] = '[';
 
1262
            bytes[2] = '3'; bytes[3] = '8'; bytes[4] = ';';
 
1263
            bytes[5] = '5'; bytes[6] = ';';
 
1264
            p = bytes + 7;
 
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);
 
1270
            *p++ = 'm';
 
1271
            if (full_write (out_fd, bytes, p - bytes) < p - bytes)
 
1272
              out_error ();
 
1273
          }
 
1274
          break;
 
1275
        default:
 
1276
          abort ();
 
1277
        }
1278
1278
    }
1279
1279
  if (new_attr.bgcolor != old_attr.bgcolor
1280
1280
      || (cleared_attributes && new_attr.bgcolor != COLOR_DEFAULT))
1282
1282
      assert (stream->supports_background);
1283
1283
      assert (new_attr.bgcolor != COLOR_DEFAULT);
1284
1284
      switch (stream->colormodel)
1285
 
        {
1286
 
        case cm_common8:
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)),
1291
 
                   1, out_char);
1292
 
          else
1293
 
            tputs (tparm (stream->set_background, new_attr.bgcolor),
1294
 
                   1, out_char);
1295
 
          break;
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.  */
1298
 
        case cm_xterm8:
1299
 
          assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 8);
1300
 
          {
1301
 
            char bytes[5];
1302
 
            bytes[0] = 0x1B; bytes[1] = '[';
1303
 
            bytes[2] = '4'; bytes[3] = '0' + new_attr.bgcolor;
1304
 
            bytes[4] = 'm';
1305
 
            if (full_write (out_fd, bytes, 5) < 5)
1306
 
              out_error ();
1307
 
          }
1308
 
          break;
1309
 
        case cm_xterm16:
1310
 
          assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 16);
1311
 
          {
1312
 
            char bytes[6];
1313
 
            bytes[0] = 0x1B; bytes[1] = '[';
1314
 
            if (new_attr.bgcolor < 8)
1315
 
              {
1316
 
                bytes[2] = '4'; bytes[3] = '0' + new_attr.bgcolor;
1317
 
                bytes[4] = 'm';
1318
 
                if (full_write (out_fd, bytes, 5) < 5)
1319
 
                  out_error ();
1320
 
              }
1321
 
            else
1322
 
              {
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)
1326
 
                  out_error ();
1327
 
              }
1328
 
          }
1329
 
          break;
1330
 
        case cm_xterm88:
1331
 
          assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 88);
1332
 
          {
1333
 
            char bytes[10];
1334
 
            char *p;
1335
 
            bytes[0] = 0x1B; bytes[1] = '[';
1336
 
            bytes[2] = '4'; bytes[3] = '8'; bytes[4] = ';';
1337
 
            bytes[5] = '5'; bytes[6] = ';';
1338
 
            p = bytes + 7;
1339
 
            if (new_attr.bgcolor >= 10)
1340
 
              *p++ = '0' + (new_attr.bgcolor / 10);
1341
 
            *p++ = '0' + (new_attr.bgcolor % 10);
1342
 
            *p++ = 'm';
1343
 
            if (full_write (out_fd, bytes, p - bytes) < p - bytes)
1344
 
              out_error ();
1345
 
          }
1346
 
          break;
1347
 
        case cm_xterm256:
1348
 
          assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 256);
1349
 
          {
1350
 
            char bytes[11];
1351
 
            char *p;
1352
 
            bytes[0] = 0x1B; bytes[1] = '[';
1353
 
            bytes[2] = '4'; bytes[3] = '8'; bytes[4] = ';';
1354
 
            bytes[5] = '5'; bytes[6] = ';';
1355
 
            p = bytes + 7;
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);
1361
 
            *p++ = 'm';
1362
 
            if (full_write (out_fd, bytes, p - bytes) < p - bytes)
1363
 
              out_error ();
1364
 
          }
1365
 
          break;
1366
 
        default:
1367
 
          abort ();
1368
 
        }
 
1285
        {
 
1286
        case cm_common8:
 
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)),
 
1291
                   1, out_char);
 
1292
          else
 
1293
            tputs (tparm (stream->set_background, new_attr.bgcolor),
 
1294
                   1, out_char);
 
1295
          break;
 
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.  */
 
1298
        case cm_xterm8:
 
1299
          assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 8);
 
1300
          {
 
1301
            char bytes[5];
 
1302
            bytes[0] = 0x1B; bytes[1] = '[';
 
1303
            bytes[2] = '4'; bytes[3] = '0' + new_attr.bgcolor;
 
1304
            bytes[4] = 'm';
 
1305
            if (full_write (out_fd, bytes, 5) < 5)
 
1306
              out_error ();
 
1307
          }
 
1308
          break;
 
1309
        case cm_xterm16:
 
1310
          assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 16);
 
1311
          {
 
1312
            char bytes[6];
 
1313
            bytes[0] = 0x1B; bytes[1] = '[';
 
1314
            if (new_attr.bgcolor < 8)
 
1315
              {
 
1316
                bytes[2] = '4'; bytes[3] = '0' + new_attr.bgcolor;
 
1317
                bytes[4] = 'm';
 
1318
                if (full_write (out_fd, bytes, 5) < 5)
 
1319
                  out_error ();
 
1320
              }
 
1321
            else
 
1322
              {
 
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)
 
1326
                  out_error ();
 
1327
              }
 
1328
          }
 
1329
          break;
 
1330
        case cm_xterm88:
 
1331
          assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 88);
 
1332
          {
 
1333
            char bytes[10];
 
1334
            char *p;
 
1335
            bytes[0] = 0x1B; bytes[1] = '[';
 
1336
            bytes[2] = '4'; bytes[3] = '8'; bytes[4] = ';';
 
1337
            bytes[5] = '5'; bytes[6] = ';';
 
1338
            p = bytes + 7;
 
1339
            if (new_attr.bgcolor >= 10)
 
1340
              *p++ = '0' + (new_attr.bgcolor / 10);
 
1341
            *p++ = '0' + (new_attr.bgcolor % 10);
 
1342
            *p++ = 'm';
 
1343
            if (full_write (out_fd, bytes, p - bytes) < p - bytes)
 
1344
              out_error ();
 
1345
          }
 
1346
          break;
 
1347
        case cm_xterm256:
 
1348
          assert (new_attr.bgcolor >= 0 && new_attr.bgcolor < 256);
 
1349
          {
 
1350
            char bytes[11];
 
1351
            char *p;
 
1352
            bytes[0] = 0x1B; bytes[1] = '[';
 
1353
            bytes[2] = '4'; bytes[3] = '8'; bytes[4] = ';';
 
1354
            bytes[5] = '5'; bytes[6] = ';';
 
1355
            p = bytes + 7;
 
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);
 
1361
            *p++ = 'm';
 
1362
            if (full_write (out_fd, bytes, p - bytes) < p - bytes)
 
1363
              out_error ();
 
1364
          }
 
1365
          break;
 
1366
        default:
 
1367
          abort ();
 
1368
        }
1369
1369
    }
1370
1370
 
1371
1371
  if (new_attr.weight != old_attr.weight
1429
1429
  if (n > 0)
1430
1430
    {
1431
1431
      if (full_write (stream->fd, cp, n) < n)
1432
 
        error (EXIT_FAILURE, errno, _("error writing to %s"), stream->filename);
 
1432
        error (EXIT_FAILURE, errno, _("error writing to %s"), stream->filename);
1433
1433
      cp += n;
1434
1434
      ap += n;
1435
1435
      len -= n;
1437
1437
  if (len > 0)
1438
1438
    {
1439
1439
      /* Block fatal signals, so that a SIGINT or similar doesn't interrupt
1440
 
         us without the possibility of restoring the terminal's state.  */
 
1440
         us without the possibility of restoring the terminal's state.  */
1441
1441
      block_fatal_signals ();
1442
1442
      /* Likewise for SIGTSTP etc.  */
1443
1443
      block_stopping_signals ();
1444
1444
 
1445
1445
      /* Enable the exit handler for restoring the terminal's state.  */
1446
1446
      restore_colors =
1447
 
        (stream->supports_foreground || stream->supports_background
1448
 
         ? stream->orig_pair
1449
 
         : NULL);
 
1447
        (stream->supports_foreground || stream->supports_background
 
1448
         ? stream->orig_pair
 
1449
         : NULL);
1450
1450
      restore_weight =
1451
 
        (stream->supports_weight ? stream->exit_attribute_mode : NULL);
 
1451
        (stream->supports_weight ? stream->exit_attribute_mode : NULL);
1452
1452
      restore_posture =
1453
 
        (stream->supports_posture
1454
 
         ? (stream->exit_italics_mode != NULL
1455
 
            ? stream->exit_italics_mode
1456
 
            : stream->exit_attribute_mode)
1457
 
         : NULL);
 
1453
        (stream->supports_posture
 
1454
         ? (stream->exit_italics_mode != NULL
 
1455
            ? stream->exit_italics_mode
 
1456
            : stream->exit_attribute_mode)
 
1457
         : NULL);
1458
1458
      restore_underline =
1459
 
        (stream->supports_underline
1460
 
         ? (stream->exit_underline_mode != NULL
1461
 
            ? stream->exit_underline_mode
1462
 
            : stream->exit_attribute_mode)
1463
 
         : NULL);
 
1459
        (stream->supports_underline
 
1460
         ? (stream->exit_underline_mode != NULL
 
1461
            ? stream->exit_underline_mode
 
1462
            : stream->exit_attribute_mode)
 
1463
         : NULL);
1464
1464
      out_fd = stream->fd;
1465
1465
      out_filename = stream->filename;
1466
1466
 
1467
1467
      while (len > 0)
1468
 
        {
1469
 
          /* Activate the attributes in *ap.  */
1470
 
          out_attr_change (stream, attr, *ap);
1471
 
          attr = *ap;
1472
 
          /* See how many characters we can output without further attribute
1473
 
             changes.  */
1474
 
          for (n = 1; n < len && equal_attributes (ap[n], attr); n++)
1475
 
            ;
1476
 
          if (full_write (stream->fd, cp, n) < n)
1477
 
            error (EXIT_FAILURE, errno, _("error writing to %s"),
1478
 
                   stream->filename);
1479
 
          cp += n;
1480
 
          ap += n;
1481
 
          len -= n;
1482
 
        }
 
1468
        {
 
1469
          /* Activate the attributes in *ap.  */
 
1470
          out_attr_change (stream, attr, *ap);
 
1471
          attr = *ap;
 
1472
          /* See how many characters we can output without further attribute
 
1473
             changes.  */
 
1474
          for (n = 1; n < len && equal_attributes (ap[n], attr); n++)
 
1475
            ;
 
1476
          if (full_write (stream->fd, cp, n) < n)
 
1477
            error (EXIT_FAILURE, errno, _("error writing to %s"),
 
1478
                   stream->filename);
 
1479
          cp += n;
 
1480
          ap += n;
 
1481
          len -= n;
 
1482
        }
1483
1483
 
1484
1484
      /* Switch back to the default attributes.  */
1485
1485
      out_attr_change (stream, attr, default_attr);
1531
1531
 
1532
1532
      /* Copy n bytes into the buffer.  */
1533
1533
      if (n > stream->allocated - stream->buflen)
1534
 
        {
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"),
1541
 
                   "term_ostream");
1542
 
          stream->buffer = (char *) xrealloc (stream->buffer, new_allocated);
1543
 
          stream->attrbuffer =
1544
 
            (attributes_t *)
1545
 
            xrealloc (stream->attrbuffer,
1546
 
                      new_allocated * sizeof (attributes_t));
1547
 
          stream->allocated = new_allocated;
1548
 
        }
 
1534
        {
 
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"),
 
1541
                   "term_ostream");
 
1542
          stream->buffer = (char *) xrealloc (stream->buffer, new_allocated);
 
1543
          stream->attrbuffer =
 
1544
            (attributes_t *)
 
1545
            xrealloc (stream->attrbuffer,
 
1546
                      new_allocated * sizeof (attributes_t));
 
1547
          stream->allocated = new_allocated;
 
1548
        }
1549
1549
      memcpy (stream->buffer + stream->buflen, cp, n);
1550
1550
      {
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++)
1555
 
          *ap = attr;
 
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++)
 
1555
          *ap = attr;
1556
1556
      }
1557
1557
      stream->buflen += n;
1558
1558
 
1559
1559
      if (newline != NULL)
1560
 
        {
1561
 
          output_buffer (stream);
1562
 
          if (full_write (stream->fd, "\n", 1) < 1)
1563
 
            error (EXIT_FAILURE, errno, _("error writing to %s"),
1564
 
                   stream->filename);
1565
 
          cp += n + 1; /* cp = newline + 1; */
1566
 
          len -= n + 1;
1567
 
        }
 
1560
        {
 
1561
          output_buffer (stream);
 
1562
          if (full_write (stream->fd, "\n", 1) < 1)
 
1563
            error (EXIT_FAILURE, errno, _("error writing to %s"),
 
1564
                   stream->filename);
 
1565
          cp += n + 1; /* cp = newline + 1; */
 
1566
          len -= n + 1;
 
1567
        }
1568
1568
      else
1569
 
        break;
 
1569
        break;
1570
1570
    }
1571
1571
}
1572
1572
 
1609
1609
 
1610
1610
/* Implementation of term_ostream_t methods.  */
1611
1611
 
1612
 
term_color_t
 
1612
static term_color_t
1613
1613
term_ostream__get_color (term_ostream_t stream)
1614
1614
{
1615
1615
  return stream->curr_attr.color;
1616
1616
}
1617
1617
 
1618
 
void
 
1618
static void
1619
1619
term_ostream__set_color (term_ostream_t stream, term_color_t color)
1620
1620
{
1621
1621
  stream->curr_attr.color = color;
1622
1622
  stream->simp_attr = simplify_attributes (stream, stream->curr_attr);
1623
1623
}
1624
1624
 
1625
 
term_color_t
 
1625
static term_color_t
1626
1626
term_ostream__get_bgcolor (term_ostream_t stream)
1627
1627
{
1628
1628
  return stream->curr_attr.bgcolor;
1629
1629
}
1630
1630
 
1631
 
void
 
1631
static void
1632
1632
term_ostream__set_bgcolor (term_ostream_t stream, term_color_t color)
1633
1633
{
1634
1634
  stream->curr_attr.bgcolor = color;
1635
1635
  stream->simp_attr = simplify_attributes (stream, stream->curr_attr);
1636
1636
}
1637
1637
 
1638
 
term_weight_t
 
1638
static term_weight_t
1639
1639
term_ostream__get_weight (term_ostream_t stream)
1640
1640
{
1641
1641
  return stream->curr_attr.weight;
1642
1642
}
1643
1643
 
1644
 
void
 
1644
static void
1645
1645
term_ostream__set_weight (term_ostream_t stream, term_weight_t weight)
1646
1646
{
1647
1647
  stream->curr_attr.weight = weight;
1648
1648
  stream->simp_attr = simplify_attributes (stream, stream->curr_attr);
1649
1649
}
1650
1650
 
1651
 
term_posture_t
 
1651
static term_posture_t
1652
1652
term_ostream__get_posture (term_ostream_t stream)
1653
1653
{
1654
1654
  return stream->curr_attr.posture;
1655
1655
}
1656
1656
 
1657
 
void
 
1657
static void
1658
1658
term_ostream__set_posture (term_ostream_t stream, term_posture_t posture)
1659
1659
{
1660
1660
  stream->curr_attr.posture = posture;
1661
1661
  stream->simp_attr = simplify_attributes (stream, stream->curr_attr);
1662
1662
}
1663
1663
 
1664
 
term_underline_t
 
1664
static term_underline_t
1665
1665
term_ostream__get_underline (term_ostream_t stream)
1666
1666
{
1667
1667
  return stream->curr_attr.underline;
1668
1668
}
1669
1669
 
1670
 
void
 
1670
static void
1671
1671
term_ostream__set_underline (term_ostream_t stream, term_underline_t underline)
1672
1672
{
1673
1673
  stream->curr_attr.underline = underline;
1718
1718
  if (term != NULL && term[0] != '\0')
1719
1719
    {
1720
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.  */
 
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.  */
1726
1726
#if HAVE_TERMINFO
1727
1727
      int err = 1;
1728
1728
 
1729
1729
      if (setupterm (term, fd, &err) || err == 1)
1730
 
        {
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"));
1745
 
        }
 
1730
        {
 
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"));
 
1745
        }
1746
1746
#elif HAVE_TERMCAP
1747
1747
      struct { char buf[1024]; char canary[4]; } termcapbuf;
1748
1748
      int retval;
1751
1751
      memcpy (termcapbuf.canary, "CnRy", 4);
1752
1752
      retval = tgetent (termcapbuf.buf, term);
1753
1753
      if (memcmp (termcapbuf.canary, "CnRy", 4) != 0)
1754
 
        /* Buffer overflow!  */
1755
 
        abort ();
 
1754
        /* Buffer overflow!  */
 
1755
        abort ();
1756
1756
 
1757
1757
      if (retval > 0)
1758
 
        {
1759
 
          struct { char buf[1024]; char canary[4]; } termentrybuf;
1760
 
          char *termentryptr;
1761
 
 
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)
1767
 
 
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));
 
1758
        {
 
1759
          struct { char buf[1024]; char canary[4]; } termentrybuf;
 
1760
          char *termentryptr;
 
1761
 
 
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)
 
1767
 
 
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));
1782
1782
 
1783
1783
# ifdef __BEOS__
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)
1789
 
            {
1790
 
              free (stream->set_a_foreground);
1791
 
              stream->set_a_foreground = xstrdup ("\033[3%dm");
1792
 
            }
1793
 
          if (stream->set_a_background != NULL
1794
 
              && strcmp (stream->set_a_background, "\033[4%p1%dm") == 0)
1795
 
            {
1796
 
              free (stream->set_a_background);
1797
 
              stream->set_a_background = xstrdup ("\033[4%dm");
1798
 
            }
 
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)
 
1789
            {
 
1790
              free (stream->set_a_foreground);
 
1791
              stream->set_a_foreground = xstrdup ("\033[3%dm");
 
1792
            }
 
1793
          if (stream->set_a_background != NULL
 
1794
              && strcmp (stream->set_a_background, "\033[4%p1%dm") == 0)
 
1795
            {
 
1796
              free (stream->set_a_background);
 
1797
              stream->set_a_background = xstrdup ("\033[4%dm");
 
1798
            }
1799
1799
# endif
1800
1800
 
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;
 
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;
1805
1805
 
1806
 
          /* Done with tgetstr.  Detect possible buffer overflow.  */
1807
 
          #undef TEBP
1808
 
          if (memcmp (termentrybuf.canary, "CnRz", 4) != 0)
1809
 
            /* Buffer overflow!  */
1810
 
            abort ();
1811
 
        }
 
1806
          /* Done with tgetstr.  Detect possible buffer overflow.  */
 
1807
          #undef TEBP
 
1808
          if (memcmp (termentrybuf.canary, "CnRz", 4) != 0)
 
1809
            /* Buffer overflow!  */
 
1810
            abort ();
 
1811
        }
1812
1812
#else
1813
1813
    /* Fallback code for platforms with neither the terminfo nor the termcap
1814
1814
       functions, such as mingw.
1826
1826
#endif
1827
1827
 
1828
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.  */
 
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
1832
      if (stream->max_colors <= 1
1833
 
          && (strcmp (term, "xterm") == 0 || strcmp (term, "xterms") == 0))
1834
 
        {
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");
1839
 
        }
 
1833
          && (strcmp (term, "xterm") == 0 || strcmp (term, "xterms") == 0))
 
1834
        {
 
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");
 
1839
        }
1840
1840
    }
1841
1841
 
1842
1842
  /* Infer the capabilities.  */
1851
1851
  stream->colormodel =
1852
1852
    (stream->supports_foreground || stream->supports_background
1853
1853
     ? (term != NULL
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 :
1863
 
           cm_xterm8)
1864
 
        : cm_common8)
 
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 :
 
1863
           cm_xterm8)
 
1864
        : cm_common8)
1865
1865
     : cm_monochrome);
1866
1866
  stream->supports_weight =
1867
1867
    (stream->enter_bold_mode != NULL && stream->exit_attribute_mode != NULL);
1868
1868
  stream->supports_posture =
1869
1869
    (stream->enter_italics_mode != NULL
1870
1870
     && (stream->exit_italics_mode != NULL
1871
 
         || stream->exit_attribute_mode != NULL));
 
1871
         || stream->exit_attribute_mode != NULL));
1872
1872
  stream->supports_underline =
1873
1873
    (stream->enter_underline_mode != NULL
1874
1874
     && (stream->exit_underline_mode != NULL
1875
 
         || stream->exit_attribute_mode != NULL));
 
1875
         || stream->exit_attribute_mode != NULL));
1876
1876
 
1877
1877
  /* Initialize the buffer.  */
1878
1878
  stream->allocated = 120;
1893
1893
    static bool registered = false;
1894
1894
    if (!registered)
1895
1895
      {
1896
 
        atexit (restore);
1897
 
        registered = true;
 
1896
        atexit (restore);
 
1897
        registered = true;
1898
1898
      }
1899
1899
  }
1900
1900
 
1953
1953
}
1954
1954
 
1955
1955
term_color_t
1956
 
term_ostream_rgb_to_color (term_ostream_t first_arg,                         int red, int green, int blue)
 
1956
term_ostream_rgb_to_color (term_ostream_t first_arg,                              int red, int green, int blue)
1957
1957
{
1958
1958
  const struct term_ostream_implementation *vtable =
1959
1959
    ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;
2033
2033
}
2034
2034
 
2035
2035
void
2036
 
term_ostream_set_underline (term_ostream_t first_arg,                             term_underline_t underline)
 
2036
term_ostream_set_underline (term_ostream_t first_arg,                                   term_underline_t underline)
2037
2037
{
2038
2038
  const struct term_ostream_implementation *vtable =
2039
2039
    ((struct term_ostream_representation_header *) (struct term_ostream_representation *) first_arg)->vtable;