4 #include <gtk/gtkmain.h>
5 #include <gtk/gtksignal.h>
6 #include "gtkviscreen.h"
11 #define INT9494(f,r,c) ((f) << 16) | ((r) << 8) | (c)
12 #define INTIS9494(c) !!(((c) >> 16) & 0x7F)
13 #define INTISUCS(c) ((c & ~0x7F) && !(((c) >> 16) & 0x7F))
15 #define INT9494F(c) ((c) >> 16) & 0x7F
16 #define INT9494R(c) ((c) >> 8) & 0x7F
17 #define INT9494C(c) (c) & 0x7F
18 #define INTILL(c) (1 << 23) | (c)
20 #define INTISWIDE(c) (!!(c >> 8))
21 #define CHAR_WIDTH(sp, ch) \
22 (INTISUCS(ch) && ucswidth(ch) > 0 ? ucswidth(ch) : INTISWIDE(ch) ? 2 : 1)
24 #define INTISWIDE(c) 0
25 #define CHAR_WIDTH(sp, ch) 1
28 void * v_strset
__P((CHAR_T
*s
, CHAR_T c
, size_t n
));
30 #define DEFAULT_VI_SCREEN_WIDTH_CHARS 80
31 #define DEFAULT_VI_SCREEN_HEIGHT_LINES 25
32 #define VI_SCREEN_BORDER_ROOM 1
44 static void gtk_vi_screen_class_init (GtkViScreenClass
*klass
);
45 static void gtk_vi_screen_set_arg (GtkObject
*object
,
48 static void gtk_vi_screen_get_arg (GtkObject
*object
,
51 static void gtk_vi_screen_init (GtkViScreen
*vi
);
52 static void gtk_vi_screen_destroy (GtkObject
*object
);
53 static void gtk_vi_screen_realize (GtkWidget
*widget
);
55 static void gtk_vi_screen_map (GtkWidget *widget);
56 static void gtk_vi_screen_unmap (GtkWidget *widget);
58 static void gtk_vi_screen_size_request (GtkWidget
*widget
,
59 GtkRequisition
*requisition
);
60 static void gtk_vi_screen_size_allocate (GtkWidget
*widget
,
61 GtkAllocation
*allocation
);
63 static void gtk_vi_screen_adjustment (GtkAdjustment *adjustment,
67 static void gtk_vi_screen_draw (GtkWidget
*widget
,
69 static gint
gtk_vi_screen_expose (GtkWidget
*widget
,
70 GdkEventExpose
*event
);
72 static void recompute_geometry (GtkViScreen
* vi
);
73 static void expose_text (GtkViScreen
* vi
, GdkRectangle
*area
, gboolean cursor
);
74 static void draw_lines(GtkViScreen
*vi
, gint y
, gint x
, gint ymax
, gint xmax
);
75 static void mark_lines(GtkViScreen
*vi
, gint ymin
, gint xmin
, gint ymax
, gint xmax
);
77 static GtkWidgetClass
*parent_class
= NULL
;
78 static guint vi_screen_signals
[LAST_SIGNAL
] = { 0 };
80 static GdkFont
*gb_font
;
84 #define CharAt(scr,y,x) scr->chars + (y) * scr->cols + x
85 #define FlagAt(scr,y,x) (scr->reverse + (y) * scr->cols + x)
86 #define ColAt(scr,y,x) (scr->endcol + (y) * scr->cols + x)
88 #define COLOR_STANDARD 0x00
89 #define COLOR_STANDOUT 0x01
92 enum { SA_ALTERNATE
, SA_INVERSE
};
95 gtk_vi_screen_attribute(GtkViScreen
*vi
, gint attribute
, gint on
)
99 vi
->color
= on
? COLOR_STANDOUT
: COLOR_STANDARD
;
104 /* col is screen column */
106 gtk_vi_screen_move(GtkViScreen
*vi
, gint row
, gint col
)
111 endcol
= vi
->endcol
+ row
*vi
->cols
;
112 for (x
= 0; col
> endcol
[x
]; ++x
);
118 cleartoel (GtkViScreen
*vi
, guint row
, guint col
)
122 if (MEMCMP(p
= CharAt(vi
,row
,col
), e
= CharAt(vi
,vi
->rows
,0),
124 MEMMOVE(p
, e
, vi
->cols
- col
);
125 memset(FlagAt(vi
,row
,col
), COLOR_STANDARD
, vi
->cols
- col
);
126 mark_lines(vi
, row
, col
, row
+1, vi
->cols
);
131 gtk_vi_screen_clrtoel (GtkViScreen
*vi
)
133 cleartoel(vi
, vi
->cury
, vi
->curx
);
137 gtk_vi_screen_addstr(GtkViScreen
*vi
, const char *str
, int len
)
145 line
= vi
->chars
+ vi
->cury
*vi
->cols
;
146 endcol
= vi
->endcol
+ vi
->cury
*vi
->cols
;
148 startcol
= x
? endcol
[x
-1] : -1;
149 for (p
= CharAt(vi
,vi
->cury
,vi
->curx
), end
= p
+ len
, col
= startcol
;
154 memset(FlagAt(vi
,vi
->cury
,vi
->curx
), vi
->color
, len
);
156 mark_lines(vi
, vi
->cury
, startcol
+1, vi
->cury
+1, endcol
[x
-1]+1);
158 if (endcol
[x
-1] >= vi
->cols
) {
159 if (++vi
->cury
>= vi
->rows
) {
160 vi
->cury
= vi
->rows
-1;
165 } else vi
->curx
+= len
;
166 if (x
< vi
->cols
) endcol
[x
] = vi
->cols
;
170 gtk_vi_screen_waddstr(GtkViScreen
*vi
, const CHAR_T
*str
, int len
)
178 MEMMOVE(CharAt(vi
,vi
->cury
,vi
->curx
),str
,len
);
179 memset(FlagAt(vi
,vi
->cury
,vi
->curx
), vi
->color
, len
);
181 line
= vi
->chars
+ vi
->cury
*vi
->cols
;
182 endcol
= vi
->endcol
+ vi
->cury
*vi
->cols
;
184 startcol
= x
? endcol
[x
-1] : -1;
185 for (col
= startcol
; x
< vi
->curx
+ len
; ++x
)
186 endcol
[x
] = col
+= CHAR_WIDTH(NULL
, *(line
+x
));
188 mark_lines(vi
, vi
->cury
, startcol
+1, vi
->cury
+1, endcol
[x
-1]+1);
190 if (endcol
[x
-1] >= vi
->cols
) {
191 if (++vi
->cury
>= vi
->rows
) {
192 vi
->cury
= vi
->rows
-1;
197 } else vi
->curx
+= len
;
198 if (x
< vi
->cols
) endcol
[x
] = vi
->cols
;
202 gtk_vi_screen_deleteln(GtkViScreen
*vi
)
205 gint rows
= vi
->rows
- (y
+1);
207 MEMMOVE(CharAt(vi
,y
,0), CharAt(vi
,y
+1,0), rows
* vi
->cols
);
208 cleartoel(vi
,vi
->rows
-1,0);
209 memmove(FlagAt(vi
,y
,0), FlagAt(vi
,y
+1,0), rows
* vi
->cols
);
210 memmove(ColAt(vi
,y
,0), ColAt(vi
,y
+1,0), rows
* vi
->cols
);
211 mark_lines(vi
, y
, 0, vi
->rows
-1, vi
->cols
);
215 gtk_vi_screen_insertln(GtkViScreen
*vi
)
218 gint rows
= vi
->rows
- (y
+1);
220 MEMMOVE(CharAt(vi
,y
+1,0), CharAt(vi
,y
,0), rows
* vi
->cols
);
222 memmove(FlagAt(vi
,y
+1,0), FlagAt(vi
,y
,0), rows
* vi
->cols
);
223 memmove(ColAt(vi
,y
+1,0), ColAt(vi
,y
,0), rows
* vi
->cols
);
224 mark_lines(vi
, y
+1, 0, vi
->rows
, vi
->cols
);
228 gtk_vi_screen_refresh(GtkViScreen
*vi
)
230 if (vi
->lastx
!= vi
->curx
|| vi
->lasty
!= vi
-> cury
) {
231 mark_lines(vi
, vi
->lasty
,
232 vi
->lastx
? *ColAt(vi
,vi
->lasty
,vi
->lastx
-1) + 1 : 0,
233 vi
->lasty
+1, *ColAt(vi
,vi
->lasty
,vi
->lastx
)+1);
234 mark_lines(vi
, vi
->cury
,
235 vi
->curx
? *ColAt(vi
,vi
->cury
,vi
->curx
-1) + 1 : 0,
236 vi
->cury
+1, *ColAt(vi
,vi
->cury
,vi
->curx
)+1);
238 if (vi
->marked_maxy
== 0)
240 draw_lines(vi
, vi
->marked_y
, vi
->marked_x
, vi
->marked_maxy
, vi
->marked_maxx
);
241 vi
->marked_x
= vi
->cols
;
242 vi
->marked_y
= vi
->rows
;
245 vi
->lastx
= vi
->curx
;
246 vi
->lasty
= vi
->cury
;
250 gtk_vi_screen_rewrite(GtkViScreen
*vi
, gint row
)
252 memset(FlagAt(vi
,row
,0), COLOR_STANDARD
, vi
->cols
);
253 mark_lines(vi
, row
, 0, row
+1, vi
->cols
);
257 gtk_vi_screen_get_type (void)
259 static GtkType vi_screen_type
= 0;
263 static const GtkTypeInfo vi_screen_info
=
266 sizeof (GtkViScreen
),
267 sizeof (GtkViScreenClass
),
268 (GtkClassInitFunc
) gtk_vi_screen_class_init
,
269 (GtkObjectInitFunc
) gtk_vi_screen_init
,
270 /* reserved_1 */ NULL
,
271 /* reserved_2 */ NULL
,
272 (GtkClassInitFunc
) NULL
,
275 vi_screen_type
= gtk_type_unique (GTK_TYPE_WIDGET
, &vi_screen_info
);
278 return vi_screen_type
;
282 gtk_vi_screen_class_init (GtkViScreenClass
*class)
284 GtkObjectClass
*object_class
;
285 GtkWidgetClass
*widget_class
;
287 object_class
= (GtkObjectClass
*) class;
288 widget_class
= (GtkWidgetClass
*) class;
289 parent_class
= gtk_type_class (GTK_TYPE_WIDGET
);
291 vi_screen_signals
[RESIZED
] =
292 gtk_signal_new ("resized",
295 GTK_SIGNAL_OFFSET (GtkViScreenClass
, resized
),
296 gtk_marshal_NONE__INT_INT
,
297 GTK_TYPE_NONE
, 2, GTK_TYPE_INT
, GTK_TYPE_INT
, 0);
299 gtk_object_class_add_signals(object_class
, vi_screen_signals
, LAST_SIGNAL
);
301 gtk_object_add_arg_type ("GtkViScreen::vadjustment",
303 GTK_ARG_READWRITE
| GTK_ARG_CONSTRUCT
,
306 object_class
->set_arg
= gtk_vi_screen_set_arg
;
307 object_class
->get_arg
= gtk_vi_screen_get_arg
;
308 object_class
->destroy
= gtk_vi_screen_destroy
;
310 widget_class
->realize
= gtk_vi_screen_realize
;
312 widget_class->map = gtk_vi_screen_map;
313 widget_class->unmap = gtk_vi_screen_unmap;
315 widget_class
->size_request
= gtk_vi_screen_size_request
;
316 widget_class
->size_allocate
= gtk_vi_screen_size_allocate
;
317 widget_class
->draw
= gtk_vi_screen_draw
;
318 widget_class
->expose_event
= gtk_vi_screen_expose
;
320 class->rename
= NULL
;
321 class->resized
= NULL
;
323 gb_font
= gdk_font_load ("-*-*-*-*-*-*-16-*-*-*-*-*-gb2312.1980-*");
325 tf = gdk_font_load ("-misc-fixed-*-*-*-*-16-*-*-*-*-*-iso10646-*");
327 tfn
= gdk_font_load ("-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646");
328 tfw
= gdk_font_load ("-Misc-Fixed-Medium-R-*-*-13-120-75-75-C-120-ISO10646-1");
332 gtk_vi_screen_set_arg (GtkObject
*object
,
336 GtkViScreen
*vi_screen
;
338 vi_screen
= GTK_VI_SCREEN (object
);
342 case ARG_VADJUSTMENT
:
343 gtk_vi_screen_set_adjustment (vi_screen
, GTK_VALUE_POINTER (*arg
));
351 gtk_vi_screen_get_arg (GtkObject
*object
,
355 GtkViScreen
*vi_screen
;
357 vi_screen
= GTK_VI_SCREEN (object
);
361 case ARG_VADJUSTMENT
:
362 GTK_VALUE_POINTER (*arg
) = vi_screen
->vadj
;
365 arg
->type
= GTK_TYPE_INVALID
;
371 gtk_vi_screen_init (GtkViScreen
*vi
)
375 GTK_WIDGET_SET_FLAGS (vi
, GTK_CAN_FOCUS
);
377 vi
->text_area
= NULL
;
381 vi
->color
= COLOR_STANDARD
;
387 style
= gtk_style_copy(GTK_WIDGET(vi
)->style
);
388 gdk_font_unref(style
->font
);
389 style
->font
= gdk_font_load("-*-fixed-*-*-*-*-16-*-*-*-*-*-iso8859-*");
390 GTK_WIDGET(vi
)->style
= style
;
394 gtk_vi_screen_destroy (GtkObject
*object
)
396 GtkViScreen
*vi_screen
;
398 g_return_if_fail (object
!= NULL
);
399 g_return_if_fail (GTK_IS_VI_SCREEN (object
));
401 vi_screen
= (GtkViScreen
*) object
;
404 gtk_signal_disconnect_by_data (GTK_OBJECT (vi_screen->vadj), vi_screen);
407 GTK_OBJECT_CLASS(parent_class
)->destroy (object
);
411 gtk_vi_screen_new (GtkAdjustment
*vadj
)
415 vi
= gtk_widget_new (GTK_TYPE_VI_SCREEN
,
424 gtk_vi_screen_set_adjustment (GtkViScreen
*vi_screen
,
427 g_return_if_fail (vi_screen
!= NULL
);
428 g_return_if_fail (GTK_IS_VI_SCREEN (vi_screen
));
430 g_return_if_fail (GTK_IS_ADJUSTMENT (vadj
));
432 vadj
= GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 1.0, 0.0, 1.0, 0.0, 0.0));
434 if (vi_screen
->vadj
&& (vi_screen
->vadj
!= vadj
))
436 gtk_signal_disconnect_by_data (GTK_OBJECT (vi_screen
->vadj
), vi_screen
);
437 gtk_object_unref (GTK_OBJECT (vi_screen
->vadj
));
440 if (vi_screen
->vadj
!= vadj
)
442 vi_screen
->vadj
= vadj
;
443 gtk_object_ref (GTK_OBJECT (vi_screen
->vadj
));
444 gtk_object_sink (GTK_OBJECT (vi_screen
->vadj
));
447 gtk_signal_connect (GTK_OBJECT (vi_screen->vadj), "changed",
448 (GtkSignalFunc) gtk_vi_screen_adjustment,
450 gtk_signal_connect (GTK_OBJECT (vi_screen->vadj), "value_changed",
451 (GtkSignalFunc) gtk_vi_screen_adjustment,
453 gtk_signal_connect (GTK_OBJECT (vi_screen->vadj), "disconnect",
454 (GtkSignalFunc) gtk_vi_screen_disconnect,
456 gtk_vi_screen_adjustment (vadj, vi_screen);
462 gtk_vi_screen_realize (GtkWidget
*widget
)
465 GdkWindowAttr attributes
;
466 gint attributes_mask
;
468 g_return_if_fail (widget
!= NULL
);
469 g_return_if_fail (GTK_IS_VI_SCREEN (widget
));
471 vi
= GTK_VI_SCREEN (widget
);
472 GTK_WIDGET_SET_FLAGS (vi
, GTK_REALIZED
);
474 attributes
.window_type
= GDK_WINDOW_CHILD
;
475 attributes
.x
= widget
->allocation
.x
;
476 attributes
.y
= widget
->allocation
.y
;
477 attributes
.width
= widget
->allocation
.width
;
478 attributes
.height
= widget
->allocation
.height
;
479 attributes
.wclass
= GDK_INPUT_OUTPUT
;
480 attributes
.visual
= gtk_widget_get_visual (widget
);
481 attributes
.colormap
= gtk_widget_get_colormap (widget
);
482 attributes
.event_mask
= gtk_widget_get_events (widget
);
483 attributes
.event_mask
|= (GDK_EXPOSURE_MASK
|
484 GDK_BUTTON_PRESS_MASK
|
485 GDK_BUTTON_RELEASE_MASK
|
486 GDK_BUTTON_MOTION_MASK
|
487 GDK_ENTER_NOTIFY_MASK
|
488 GDK_LEAVE_NOTIFY_MASK
|
490 attributes_mask
= GDK_WA_X
| GDK_WA_Y
| GDK_WA_VISUAL
| GDK_WA_COLORMAP
;
492 widget
->window
= gdk_window_new (gtk_widget_get_parent_window (widget
), &attributes
, attributes_mask
);
493 gdk_window_set_user_data (widget
->window
, vi
);
495 attributes
.x
= (widget
->style
->klass
->xthickness
+ VI_SCREEN_BORDER_ROOM
);
496 attributes
.y
= (widget
->style
->klass
->ythickness
+ VI_SCREEN_BORDER_ROOM
);
497 attributes
.width
= MAX (1, (gint
)widget
->allocation
.width
- (gint
)attributes
.x
* 2);
498 attributes
.height
= MAX (1, (gint
)widget
->allocation
.height
- (gint
)attributes
.y
* 2);
500 vi
->text_area
= gdk_window_new (widget
->window
, &attributes
, attributes_mask
);
501 gdk_window_set_user_data (vi
->text_area
, vi
);
503 widget
->style
= gtk_style_attach (widget
->style
, widget
->window
);
505 /* Can't call gtk_style_set_background here because it's handled specially */
506 gdk_window_set_background (widget
->window
, &widget
->style
->base
[GTK_STATE_NORMAL
]);
507 gdk_window_set_background (vi
->text_area
, &widget
->style
->base
[GTK_STATE_NORMAL
]);
509 vi
->gc
= gdk_gc_new (vi
->text_area
);
511 gdk_gc_set_exposures (vi
->gc
, TRUE
);
512 gdk_gc_set_foreground (vi
->gc
, &widget
->style
->text
[GTK_STATE_NORMAL
]);
514 vi
->reverse_gc
= gdk_gc_new (vi
->text_area
);
515 gdk_gc_set_foreground (vi
->reverse_gc
, &widget
->style
->base
[GTK_STATE_NORMAL
]);
517 gdk_window_show (vi
->text_area
);
519 recompute_geometry (vi
);
523 gtk_vi_screen_size_request (GtkWidget
*widget
,
524 GtkRequisition
*requisition
)
532 g_return_if_fail (widget
!= NULL
);
533 g_return_if_fail (GTK_IS_VI_SCREEN (widget
));
534 g_return_if_fail (requisition
!= NULL
);
536 vi
= GTK_VI_SCREEN (widget
);
538 xthickness
= widget
->style
->klass
->xthickness
+ VI_SCREEN_BORDER_ROOM
;
539 ythickness
= widget
->style
->klass
->ythickness
+ VI_SCREEN_BORDER_ROOM
;
541 vi
->ch_ascent
= widget
->style
->font
->ascent
;
542 vi
->ch_height
= (widget
->style
->font
->ascent
+ widget
->style
->font
->descent
) + 1;
543 vi
->ch_width
= gdk_text_width (widget
->style
->font
, "A", 1);
544 char_height
= DEFAULT_VI_SCREEN_HEIGHT_LINES
* vi
->ch_height
;
545 char_width
= DEFAULT_VI_SCREEN_WIDTH_CHARS
* vi
->ch_width
;
547 requisition
->width
= char_width
+ xthickness
* 2;
548 requisition
->height
= char_height
+ ythickness
* 2;
552 gtk_vi_screen_size_allocate (GtkWidget
*widget
,
553 GtkAllocation
*allocation
)
557 g_return_if_fail (widget
!= NULL
);
558 g_return_if_fail (GTK_IS_VI_SCREEN (widget
));
559 g_return_if_fail (allocation
!= NULL
);
561 vi
= GTK_VI_SCREEN (widget
);
563 widget
->allocation
= *allocation
;
564 if (GTK_WIDGET_REALIZED (widget
))
566 gdk_window_move_resize (widget
->window
,
567 allocation
->x
, allocation
->y
,
568 allocation
->width
, allocation
->height
);
570 gdk_window_move_resize (vi
->text_area
,
571 widget
->style
->klass
->xthickness
+ VI_SCREEN_BORDER_ROOM
,
572 widget
->style
->klass
->ythickness
+ VI_SCREEN_BORDER_ROOM
,
573 MAX (1, (gint
)widget
->allocation
.width
- (gint
)(widget
->style
->klass
->xthickness
+
574 (gint
)VI_SCREEN_BORDER_ROOM
) * 2),
575 MAX (1, (gint
)widget
->allocation
.height
- (gint
)(widget
->style
->klass
->ythickness
+
576 (gint
)VI_SCREEN_BORDER_ROOM
) * 2));
578 recompute_geometry (vi
);
584 gtk_vi_screen_adjustment (GtkAdjustment *adjustment,
585 GtkViScreen *vi_screen)
587 g_return_if_fail (adjustment != NULL);
588 g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
589 g_return_if_fail (vi_screen != NULL);
590 g_return_if_fail (GTK_IS_VI_SCREEN (vi_screen));
596 gtk_vi_screen_draw (GtkWidget
*widget
,
599 g_return_if_fail (widget
!= NULL
);
600 g_return_if_fail (GTK_IS_VI_SCREEN (widget
));
601 g_return_if_fail (area
!= NULL
);
603 if (GTK_WIDGET_DRAWABLE (widget
))
605 expose_text (GTK_VI_SCREEN (widget
), area
, TRUE
);
606 gtk_widget_draw_focus (widget
);
611 gtk_vi_screen_expose (GtkWidget
*widget
,
612 GdkEventExpose
*event
)
614 g_return_val_if_fail (widget
!= NULL
, FALSE
);
615 g_return_val_if_fail (GTK_IS_VI_SCREEN (widget
), FALSE
);
616 g_return_val_if_fail (event
!= NULL
, FALSE
);
618 if (event
->window
== GTK_VI_SCREEN (widget
)->text_area
)
620 expose_text (GTK_VI_SCREEN (widget
), &event
->area
, TRUE
);
622 else if (event
->count
== 0)
624 gtk_widget_draw_focus (widget
);
631 recompute_geometry (GtkViScreen
* vi
)
640 //xthickness = widget->style->klass->xthickness + VI_SCREEN_BORDER_ROOM;
641 //ythickness = widget->style->klass->ythickness + VI_SCREEN_BORDER_ROOM;
643 gdk_window_get_size (vi
->text_area
, &width
, &height
);
645 rows
= height
/ vi
->ch_height
;
646 cols
= width
/ vi
->ch_width
;
648 if (rows
== vi
->rows
&& cols
== vi
->cols
)
651 vi
->marked_x
= vi
->cols
= cols
;
652 vi
->marked_y
= vi
->rows
= rows
;
657 vi
->chars
= (CHAR_T
*)g_new(gchar
, (vi
->rows
+1)*vi
->cols
* sizeof(CHAR_T
));
658 STRSET(vi
->chars
, ' ', (vi
->rows
+1)*vi
->cols
);
660 vi
->endcol
= g_new(guchar
, vi
->rows
*vi
->cols
);
662 vi
->reverse
= g_new(guchar
, vi
->rows
*vi
->cols
);
663 memset(vi
->reverse
, 0, vi
->rows
*vi
->cols
);
665 gtk_signal_emit(GTK_OBJECT(vi
), vi_screen_signals
[RESIZED
], vi
->rows
, vi
->cols
);
669 expose_text (GtkViScreen
* vi
, GdkRectangle
*area
, gboolean cursor
)
674 gdk_window_clear_area (vi
->text_area
, area
->x
, area
->y
,
675 area
->width
, area
->height
);
676 ymax
= MIN((area
->y
+ area
->height
+ vi
->ch_height
- 1) / vi
->ch_height
,
678 xmin
= area
->x
/ vi
->ch_width
;
679 xmax
= MIN((area
->x
+ area
->width
+ vi
->ch_width
- 1) / vi
->ch_width
,
681 draw_lines(vi
, area
->y
/ vi
->ch_height
, xmin
, ymax
, xmax
);
684 #define Inverse(screen,y,x) \
685 ((*FlagAt(screen,y,x) == COLOR_STANDOUT) ^ \
686 (screen->cury == y && screen->curx == x))
689 draw_lines(GtkViScreen
*vi
, gint ymin
, gint xmin
, gint ymax
, gint xmax
)
691 gint y
, x
, len
, blen
, xpos
;
699 for (y
= ymin
, line
= vi
->chars
+ y
*vi
->cols
;
700 y
< ymax
; ++y
, line
+= vi
->cols
) {
701 for (x
= 0, xpos
= 0; xpos
<= xmin
; ++x
)
702 xpos
+= CHAR_WIDTH(NULL
, *(line
+x
));
704 xpos
-= CHAR_WIDTH(NULL
, *(line
+x
));
705 for (; xpos
< xmax
; x
+=len
, xpos
+= blen
) {
707 inverse
= Inverse(vi
,y
,x
);
709 if (sizeof(CHAR_T
) == sizeof(gchar
))
710 for (; x
+len
< xmax
&&
711 Inverse(vi
,y
,x
+len
) == inverse
; ++len
);
720 if (INTIS9494(*(line
+x
))) {
722 buf
[0] = INT9494R(*(line
+x
));
723 buf
[1] = INT9494C(*(line
+x
));
726 } else if (INTISUCS(*(line
+x
))) {
729 PangoFontDescription font_description
;
731 font_description
.family_name
= g_strdup ("monospace");
732 font_description
.style
= PANGO_STYLE_NORMAL
;
733 font_description
.variant
= PANGO_VARIANT_NORMAL
;
734 font_description
.weight
= 500;
735 font_description
.stretch
= PANGO_STRETCH_NORMAL
;
736 font_description
.size
= 15000;
738 vi
->conx
= pango_x_get_context (GDK_DISPLAY ());
739 pango_context_set_font_description (vi
->conx
,
741 vi
->alist
= pango_attr_list_new();
743 blen
= CHAR_WIDTH(NULL
, *(line
+x
));
749 buf
[0] = *(line
+x
) >> 8;
750 buf
[1] = (*(line
+x
)) & 0xFF;
755 font
= GTK_WIDGET(vi
)->style
->font
;
756 if (sizeof(CHAR_T
) == sizeof(gchar
))
764 gdk_draw_rectangle(vi
->text_area
, bg
, 1, xpos
* vi
->ch_width
,
765 y
* vi
->ch_height
, blen
* vi
->ch_width
,
767 /* hack to not display half a wide character that wasn't
771 gdk_draw_text (vi
->text_area
, font
, fg
,
773 y
* vi
->ch_height
+ vi
->ch_ascent
,
777 PangoGlyphString
*gs
;
783 len
= ucs2utf8(line
+x
, 1, buf
);
784 list
= pango_itemize(vi
->conx
, buf
, len
, vi
->alist
);
786 gs
= pango_glyph_string_new ();
787 pango_shape(buf
, len
, &item
->analysis
, gs
);
789 pango_x_render(GDK_DISPLAY (),
790 GDK_WINDOW_XWINDOW(vi
->text_area
), GDK_GC_XGC(fg
),
791 item
->analysis
.font
, gs
, xpos
* vi
->ch_width
,
792 y
* vi
->ch_height
+ vi
->ch_ascent
);
800 mark_lines(GtkViScreen
*vi
, gint ymin
, gint xmin
, gint ymax
, gint xmax
)
802 if (ymin
< vi
->marked_y
) vi
->marked_y
= ymin
;
803 if (xmin
< vi
->marked_x
) vi
->marked_x
= xmin
;
804 if (ymax
> vi
->marked_maxy
) vi
->marked_maxy
= ymax
;
805 if (xmax
> vi
->marked_maxx
) vi
->marked_maxx
= xmax
;