xref: /netbsd-src/external/bsd/nvi/dist/gtk/gtkviscreen.c (revision dbd550ed1a6686d6600f748306f9cc03d8cd4c94)
1*dbd550edSchristos #include <stdio.h>
2*dbd550edSchristos #include <string.h>
3*dbd550edSchristos 
4*dbd550edSchristos #include <gtk/gtkmain.h>
5*dbd550edSchristos #include <gtk/gtksignal.h>
6*dbd550edSchristos #include "gtkviscreen.h"
7*dbd550edSchristos #include <gdk/gdkx.h>
8*dbd550edSchristos 
9*dbd550edSchristos #define INTISUCS(c)	((c & ~0x7F) && !(((c) >> 16) & 0x7F))
10*dbd550edSchristos #define INTUCS(c)	(c)
11*dbd550edSchristos #ifdef USE_WIDECHAR
12*dbd550edSchristos #define CHAR_WIDTH(sp, ch)  wcwidth(ch)
13*dbd550edSchristos #else
14*dbd550edSchristos #define CHAR_WIDTH(sp, ch)  1
15*dbd550edSchristos #endif
16*dbd550edSchristos 
17*dbd550edSchristos void * v_strset __P((CHAR_T *s, CHAR_T c, size_t n));
18*dbd550edSchristos 
19*dbd550edSchristos #define DEFAULT_VI_SCREEN_WIDTH_CHARS     80
20*dbd550edSchristos #define DEFAULT_VI_SCREEN_HEIGHT_LINES    25
21*dbd550edSchristos #define VI_SCREEN_BORDER_ROOM         1
22*dbd550edSchristos 
23*dbd550edSchristos enum {
24*dbd550edSchristos   ARG_0,
25*dbd550edSchristos   ARG_VADJUSTMENT,
26*dbd550edSchristos };
27*dbd550edSchristos 
28*dbd550edSchristos enum {
29*dbd550edSchristos     RESIZED,
30*dbd550edSchristos     LAST_SIGNAL
31*dbd550edSchristos };
32*dbd550edSchristos 
33*dbd550edSchristos static void gtk_vi_screen_class_init     (GtkViScreenClass   *klass);
34*dbd550edSchristos static void gtk_vi_screen_set_arg        (GtkObject      *object,
35*dbd550edSchristos 					  GtkArg         *arg,
36*dbd550edSchristos 					  guint           arg_id);
37*dbd550edSchristos static void gtk_vi_screen_get_arg        (GtkObject      *object,
38*dbd550edSchristos 					  GtkArg         *arg,
39*dbd550edSchristos 					  guint           arg_id);
40*dbd550edSchristos static void gtk_vi_screen_init           (GtkViScreen        *vi);
41*dbd550edSchristos static void gtk_vi_screen_destroy        (GtkObject      *object);
42*dbd550edSchristos static void gtk_vi_screen_realize        (GtkWidget      *widget);
43*dbd550edSchristos /*
44*dbd550edSchristos static void gtk_vi_screen_map (GtkWidget *widget);
45*dbd550edSchristos static void gtk_vi_screen_unmap (GtkWidget *widget);
46*dbd550edSchristos */
47*dbd550edSchristos static void gtk_vi_screen_size_request   (GtkWidget      *widget,
48*dbd550edSchristos 				      GtkRequisition *requisition);
49*dbd550edSchristos static void gtk_vi_screen_size_allocate  (GtkWidget      *widget,
50*dbd550edSchristos 				      GtkAllocation  *allocation);
51*dbd550edSchristos /*
52*dbd550edSchristos static void gtk_vi_screen_adjustment     (GtkAdjustment  *adjustment,
53*dbd550edSchristos 				      GtkViScreen        *text);
54*dbd550edSchristos */
55*dbd550edSchristos 
56*dbd550edSchristos static gint gtk_vi_screen_expose            (GtkWidget         *widget,
57*dbd550edSchristos 					 GdkEventExpose    *event);
58*dbd550edSchristos 
59*dbd550edSchristos static void recompute_geometry (GtkViScreen* vi);
60*dbd550edSchristos static void expose_text (GtkViScreen* vi, GdkRectangle *area, gboolean cursor);
61*dbd550edSchristos static void draw_lines(GtkViScreen *vi, gint y, gint x, gint ymax, gint xmax);
62*dbd550edSchristos static void mark_lines(GtkViScreen *vi, gint ymin, gint xmin, gint ymax, gint xmax);
63*dbd550edSchristos 
64*dbd550edSchristos static GtkWidgetClass *parent_class = NULL;
65*dbd550edSchristos static guint vi_screen_signals[LAST_SIGNAL] = { 0 };
66*dbd550edSchristos 
67*dbd550edSchristos static GdkFont *gb_font;
68*dbd550edSchristos static GdkFont *tfn;
69*dbd550edSchristos static GdkFont *tfw;
70*dbd550edSchristos 
71*dbd550edSchristos #define CharAt(scr,y,x)	scr->chars + (y) * scr->cols + x
72*dbd550edSchristos #define FlagAt(scr,y,x)	(scr->reverse + (y) * scr->cols + x)
73*dbd550edSchristos #define ColAt(scr,y,x)	(scr->endcol + (y) * scr->cols + x)
74*dbd550edSchristos 
75*dbd550edSchristos #define COLOR_STANDARD	    0x00
76*dbd550edSchristos #define COLOR_STANDOUT	    0x01
77*dbd550edSchristos 
78*dbd550edSchristos /* XXX */
79*dbd550edSchristos enum { SA_ALTERNATE, SA_INVERSE };
80*dbd550edSchristos 
81*dbd550edSchristos void
gtk_vi_screen_attribute(GtkViScreen * vi,gint attribute,gint on)82*dbd550edSchristos gtk_vi_screen_attribute(GtkViScreen *vi, gint attribute, gint on)
83*dbd550edSchristos {
84*dbd550edSchristos     switch (attribute) {
85*dbd550edSchristos     case SA_INVERSE:
86*dbd550edSchristos 	vi->color = on ? COLOR_STANDOUT : COLOR_STANDARD;
87*dbd550edSchristos 	break;
88*dbd550edSchristos     }
89*dbd550edSchristos }
90*dbd550edSchristos 
91*dbd550edSchristos /* col is screen column */
92*dbd550edSchristos void
gtk_vi_screen_move(GtkViScreen * vi,gint row,gint col)93*dbd550edSchristos gtk_vi_screen_move(GtkViScreen *vi, gint row, gint col)
94*dbd550edSchristos {
95*dbd550edSchristos     gint x;
96*dbd550edSchristos     guchar *endcol;
97*dbd550edSchristos 
98*dbd550edSchristos     endcol = vi->endcol + row*vi->cols;
99*dbd550edSchristos     for (x = 0; col > endcol[x]; ++x);
100*dbd550edSchristos     vi->curx = x;
101*dbd550edSchristos     vi->cury = row;
102*dbd550edSchristos }
103*dbd550edSchristos 
104*dbd550edSchristos static void
cleartoel(GtkViScreen * vi,guint row,guint col)105*dbd550edSchristos cleartoel (GtkViScreen *vi, guint row, guint col)
106*dbd550edSchristos {
107*dbd550edSchristos     CHAR_T *p, *e;
108*dbd550edSchristos 
109*dbd550edSchristos     if (MEMCMP(p = CharAt(vi,row,col), e = CharAt(vi,vi->rows,0),
110*dbd550edSchristos 		vi->cols - col)) {
111*dbd550edSchristos 	MEMMOVE(p, e, vi->cols - col);
112*dbd550edSchristos 	memset(FlagAt(vi,row,col), COLOR_STANDARD, vi->cols - col);
113*dbd550edSchristos 	mark_lines(vi, row, col, row+1, vi->cols);
114*dbd550edSchristos     }
115*dbd550edSchristos }
116*dbd550edSchristos 
117*dbd550edSchristos void
gtk_vi_screen_clrtoel(GtkViScreen * vi)118*dbd550edSchristos gtk_vi_screen_clrtoel (GtkViScreen *vi)
119*dbd550edSchristos {
120*dbd550edSchristos     cleartoel(vi, vi->cury, vi->curx);
121*dbd550edSchristos }
122*dbd550edSchristos 
123*dbd550edSchristos void
gtk_vi_screen_addstr(GtkViScreen * vi,const char * str,int len)124*dbd550edSchristos gtk_vi_screen_addstr(GtkViScreen *vi, const char *str, int len)
125*dbd550edSchristos {
126*dbd550edSchristos     CHAR_T *p, *end;
127*dbd550edSchristos     CHAR_T *line;
128*dbd550edSchristos     guchar *endcol;
129*dbd550edSchristos     gint col, startcol;
130*dbd550edSchristos     gint x;
131*dbd550edSchristos 
132*dbd550edSchristos     line = vi->chars + vi->cury*vi->cols;
133*dbd550edSchristos     endcol = vi->endcol + vi->cury*vi->cols;
134*dbd550edSchristos     x = vi->curx;
135*dbd550edSchristos     startcol = x ? endcol[x-1] : -1;
136*dbd550edSchristos     for (p = CharAt(vi,vi->cury,vi->curx), end = p + len, col = startcol;
137*dbd550edSchristos 		 p < end; ++x) {
138*dbd550edSchristos 	*p++ = *str++;
139*dbd550edSchristos 	endcol[x] = ++col;
140*dbd550edSchristos     }
141*dbd550edSchristos     memset(FlagAt(vi,vi->cury,vi->curx), vi->color, len);
142*dbd550edSchristos 
143*dbd550edSchristos     mark_lines(vi, vi->cury, startcol+1, vi->cury+1, endcol[x-1]+1);
144*dbd550edSchristos 
145*dbd550edSchristos     if (endcol[x-1] >= vi->cols) {
146*dbd550edSchristos 	if (++vi->cury >= vi->rows) {
147*dbd550edSchristos 	    vi->cury = vi->rows-1;
148*dbd550edSchristos 	    vi->curx = x-1;
149*dbd550edSchristos 	} else {
150*dbd550edSchristos 	    vi->curx = 0;
151*dbd550edSchristos 	}
152*dbd550edSchristos     } else vi->curx += len;
153*dbd550edSchristos     if (x < vi->cols) endcol[x] = vi->cols;
154*dbd550edSchristos }
155*dbd550edSchristos 
156*dbd550edSchristos void
gtk_vi_screen_waddstr(GtkViScreen * vi,const CHAR_T * str,int len)157*dbd550edSchristos gtk_vi_screen_waddstr(GtkViScreen *vi, const CHAR_T *str, int len)
158*dbd550edSchristos {
159*dbd550edSchristos     CHAR_T *p, *end;
160*dbd550edSchristos     CHAR_T *line;
161*dbd550edSchristos     guchar *endcol;
162*dbd550edSchristos     gint col, startcol;
163*dbd550edSchristos     gint x;
164*dbd550edSchristos 
165*dbd550edSchristos     MEMMOVE(CharAt(vi,vi->cury,vi->curx),str,len);
166*dbd550edSchristos     memset(FlagAt(vi,vi->cury,vi->curx), vi->color, len);
167*dbd550edSchristos 
168*dbd550edSchristos     line = vi->chars + vi->cury*vi->cols;
169*dbd550edSchristos     endcol = vi->endcol + vi->cury*vi->cols;
170*dbd550edSchristos     x = vi->curx;
171*dbd550edSchristos     startcol = x ? endcol[x-1] : -1;
172*dbd550edSchristos     for (col = startcol; x < vi->curx + len; ++x)
173*dbd550edSchristos 	endcol[x] = col += CHAR_WIDTH(NULL, *(line+x));
174*dbd550edSchristos 
175*dbd550edSchristos     mark_lines(vi, vi->cury, startcol+1, vi->cury+1, endcol[x-1]+1);
176*dbd550edSchristos 
177*dbd550edSchristos     if (endcol[x-1] >= vi->cols) {
178*dbd550edSchristos 	if (++vi->cury >= vi->rows) {
179*dbd550edSchristos 	    vi->cury = vi->rows-1;
180*dbd550edSchristos 	    vi->curx = x-1;
181*dbd550edSchristos 	} else {
182*dbd550edSchristos 	    vi->curx = 0;
183*dbd550edSchristos 	}
184*dbd550edSchristos     } else vi->curx += len;
185*dbd550edSchristos     if (x < vi->cols) endcol[x] = vi->cols;
186*dbd550edSchristos }
187*dbd550edSchristos 
188*dbd550edSchristos void
gtk_vi_screen_deleteln(GtkViScreen * vi)189*dbd550edSchristos gtk_vi_screen_deleteln(GtkViScreen *vi)
190*dbd550edSchristos {
191*dbd550edSchristos     gint y = vi->cury;
192*dbd550edSchristos     gint rows = vi->rows - (y+1);
193*dbd550edSchristos 
194*dbd550edSchristos     MEMMOVE(CharAt(vi,y,0), CharAt(vi,y+1,0), rows * vi->cols);
195*dbd550edSchristos     cleartoel(vi,vi->rows-1,0);
196*dbd550edSchristos     memmove(FlagAt(vi,y,0), FlagAt(vi,y+1,0), rows * vi->cols);
197*dbd550edSchristos     memmove(ColAt(vi,y,0), ColAt(vi,y+1,0), rows * vi->cols);
198*dbd550edSchristos     mark_lines(vi, y, 0, vi->rows-1, vi->cols);
199*dbd550edSchristos }
200*dbd550edSchristos 
201*dbd550edSchristos void
gtk_vi_screen_insertln(GtkViScreen * vi)202*dbd550edSchristos gtk_vi_screen_insertln(GtkViScreen *vi)
203*dbd550edSchristos {
204*dbd550edSchristos     gint y = vi->cury;
205*dbd550edSchristos     gint rows = vi->rows - (y+1);
206*dbd550edSchristos 
207*dbd550edSchristos     MEMMOVE(CharAt(vi,y+1,0), CharAt(vi,y,0), rows * vi->cols);
208*dbd550edSchristos     cleartoel(vi,y,0);
209*dbd550edSchristos     memmove(FlagAt(vi,y+1,0), FlagAt(vi,y,0), rows * vi->cols);
210*dbd550edSchristos     memmove(ColAt(vi,y+1,0), ColAt(vi,y,0), rows * vi->cols);
211*dbd550edSchristos     mark_lines(vi, y+1, 0, vi->rows, vi->cols);
212*dbd550edSchristos }
213*dbd550edSchristos 
214*dbd550edSchristos void
gtk_vi_screen_refresh(GtkViScreen * vi)215*dbd550edSchristos gtk_vi_screen_refresh(GtkViScreen *vi)
216*dbd550edSchristos {
217*dbd550edSchristos     if (vi->lastx != vi->curx || vi->lasty != vi-> cury) {
218*dbd550edSchristos 	mark_lines(vi, vi->lasty,
219*dbd550edSchristos 		vi->lastx ? *ColAt(vi,vi->lasty,vi->lastx-1) + 1 : 0,
220*dbd550edSchristos 		vi->lasty+1, *ColAt(vi,vi->lasty,vi->lastx)+1);
221*dbd550edSchristos 	mark_lines(vi, vi->cury,
222*dbd550edSchristos 		vi->curx ? *ColAt(vi,vi->cury,vi->curx-1) + 1 : 0,
223*dbd550edSchristos 		vi->cury+1, *ColAt(vi,vi->cury,vi->curx)+1);
224*dbd550edSchristos     }
225*dbd550edSchristos     if (vi->marked_maxy == 0)
226*dbd550edSchristos 	return;
227*dbd550edSchristos     draw_lines(vi, vi->marked_y, vi->marked_x, vi->marked_maxy, vi->marked_maxx);
228*dbd550edSchristos     vi->marked_x = vi->cols;
229*dbd550edSchristos     vi->marked_y = vi->rows;
230*dbd550edSchristos     vi->marked_maxx = 0;
231*dbd550edSchristos     vi->marked_maxy = 0;
232*dbd550edSchristos     vi->lastx = vi->curx;
233*dbd550edSchristos     vi->lasty = vi->cury;
234*dbd550edSchristos }
235*dbd550edSchristos 
236*dbd550edSchristos void
gtk_vi_screen_rewrite(GtkViScreen * vi,gint row)237*dbd550edSchristos gtk_vi_screen_rewrite(GtkViScreen *vi, gint row)
238*dbd550edSchristos {
239*dbd550edSchristos     memset(FlagAt(vi,row,0), COLOR_STANDARD, vi->cols);
240*dbd550edSchristos     mark_lines(vi, row, 0, row+1, vi->cols);
241*dbd550edSchristos }
242*dbd550edSchristos 
243*dbd550edSchristos GtkType
gtk_vi_screen_get_type(void)244*dbd550edSchristos gtk_vi_screen_get_type (void)
245*dbd550edSchristos {
246*dbd550edSchristos   static GtkType vi_screen_type = 0;
247*dbd550edSchristos 
248*dbd550edSchristos   if (!vi_screen_type)
249*dbd550edSchristos     {
250*dbd550edSchristos       static const GtkTypeInfo vi_screen_info =
251*dbd550edSchristos       {
252*dbd550edSchristos 	"GtkViScreen",
253*dbd550edSchristos 	sizeof (GtkViScreen),
254*dbd550edSchristos 	sizeof (GtkViScreenClass),
255*dbd550edSchristos 	(GtkClassInitFunc) gtk_vi_screen_class_init,
256*dbd550edSchristos 	(GtkObjectInitFunc) gtk_vi_screen_init,
257*dbd550edSchristos 	/* reserved_1 */ NULL,
258*dbd550edSchristos         /* reserved_2 */ NULL,
259*dbd550edSchristos         (GtkClassInitFunc) NULL,
260*dbd550edSchristos       };
261*dbd550edSchristos 
262*dbd550edSchristos       vi_screen_type = gtk_type_unique (GTK_TYPE_WIDGET, &vi_screen_info);
263*dbd550edSchristos     }
264*dbd550edSchristos 
265*dbd550edSchristos   return vi_screen_type;
266*dbd550edSchristos }
267*dbd550edSchristos 
268*dbd550edSchristos static void
gtk_vi_screen_class_init(GtkViScreenClass * class)269*dbd550edSchristos gtk_vi_screen_class_init (GtkViScreenClass *class)
270*dbd550edSchristos {
271*dbd550edSchristos   GtkObjectClass *object_class;
272*dbd550edSchristos   GtkWidgetClass *widget_class;
273*dbd550edSchristos 
274*dbd550edSchristos   object_class = (GtkObjectClass*) class;
275*dbd550edSchristos   widget_class = (GtkWidgetClass*) class;
276*dbd550edSchristos   parent_class = gtk_type_class (GTK_TYPE_WIDGET);
277*dbd550edSchristos 
278*dbd550edSchristos   vi_screen_signals[RESIZED] =
279*dbd550edSchristos     gtk_signal_new ("resized",
280*dbd550edSchristos 		    GTK_RUN_FIRST,
281*dbd550edSchristos 		    GTK_CLASS_TYPE(object_class),
282*dbd550edSchristos 		    GTK_SIGNAL_OFFSET (GtkViScreenClass, resized),
283*dbd550edSchristos 		    gtk_marshal_NONE__INT_INT,
284*dbd550edSchristos 		    GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT, 0);
285*dbd550edSchristos 
286*dbd550edSchristos #ifndef HAVE_PANGO
287*dbd550edSchristos   gtk_object_class_add_signals(object_class, vi_screen_signals, LAST_SIGNAL);
288*dbd550edSchristos #endif
289*dbd550edSchristos 
290*dbd550edSchristos   gtk_object_add_arg_type ("GtkViScreen::vadjustment",
291*dbd550edSchristos 			   GTK_TYPE_ADJUSTMENT,
292*dbd550edSchristos 			   GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT,
293*dbd550edSchristos 			   ARG_VADJUSTMENT);
294*dbd550edSchristos 
295*dbd550edSchristos   object_class->set_arg = gtk_vi_screen_set_arg;
296*dbd550edSchristos   object_class->get_arg = gtk_vi_screen_get_arg;
297*dbd550edSchristos   object_class->destroy = gtk_vi_screen_destroy;
298*dbd550edSchristos 
299*dbd550edSchristos   widget_class->realize = gtk_vi_screen_realize;
300*dbd550edSchristos   /*
301*dbd550edSchristos   widget_class->map = gtk_vi_screen_map;
302*dbd550edSchristos   widget_class->unmap = gtk_vi_screen_unmap;
303*dbd550edSchristos   */
304*dbd550edSchristos   widget_class->size_request = gtk_vi_screen_size_request;
305*dbd550edSchristos   widget_class->size_allocate = gtk_vi_screen_size_allocate;
306*dbd550edSchristos   widget_class->expose_event = gtk_vi_screen_expose;
307*dbd550edSchristos 
308*dbd550edSchristos   class->rename = NULL;
309*dbd550edSchristos   class->resized = NULL;
310*dbd550edSchristos 
311*dbd550edSchristos   gb_font = gdk_font_load ("-*-*-*-*-*-*-16-*-*-*-*-*-gb2312.1980-*");
312*dbd550edSchristos   /*
313*dbd550edSchristos   tf = gdk_font_load ("-misc-fixed-*-*-*-*-16-*-*-*-*-*-iso10646-*");
314*dbd550edSchristos   */
315*dbd550edSchristos   tfn = gdk_font_load ("-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646");
316*dbd550edSchristos   tfw = gdk_font_load ("-Misc-Fixed-Medium-R-*-*-13-120-75-75-C-120-ISO10646-1");
317*dbd550edSchristos }
318*dbd550edSchristos 
319*dbd550edSchristos static void
gtk_vi_screen_set_arg(GtkObject * object,GtkArg * arg,guint arg_id)320*dbd550edSchristos gtk_vi_screen_set_arg (GtkObject        *object,
321*dbd550edSchristos 		      GtkArg           *arg,
322*dbd550edSchristos 		      guint             arg_id)
323*dbd550edSchristos {
324*dbd550edSchristos   GtkViScreen *vi_screen;
325*dbd550edSchristos 
326*dbd550edSchristos   vi_screen = GTK_VI_SCREEN (object);
327*dbd550edSchristos 
328*dbd550edSchristos   switch (arg_id)
329*dbd550edSchristos     {
330*dbd550edSchristos     case ARG_VADJUSTMENT:
331*dbd550edSchristos       gtk_vi_screen_set_adjustment (vi_screen, GTK_VALUE_POINTER (*arg));
332*dbd550edSchristos       break;
333*dbd550edSchristos     default:
334*dbd550edSchristos       break;
335*dbd550edSchristos     }
336*dbd550edSchristos }
337*dbd550edSchristos 
338*dbd550edSchristos static void
gtk_vi_screen_get_arg(GtkObject * object,GtkArg * arg,guint arg_id)339*dbd550edSchristos gtk_vi_screen_get_arg (GtkObject        *object,
340*dbd550edSchristos 		      GtkArg           *arg,
341*dbd550edSchristos 		      guint             arg_id)
342*dbd550edSchristos {
343*dbd550edSchristos   GtkViScreen *vi_screen;
344*dbd550edSchristos 
345*dbd550edSchristos   vi_screen = GTK_VI_SCREEN (object);
346*dbd550edSchristos 
347*dbd550edSchristos   switch (arg_id)
348*dbd550edSchristos     {
349*dbd550edSchristos     case ARG_VADJUSTMENT:
350*dbd550edSchristos       GTK_VALUE_POINTER (*arg) = vi_screen->vadj;
351*dbd550edSchristos       break;
352*dbd550edSchristos     default:
353*dbd550edSchristos       arg->type = GTK_TYPE_INVALID;
354*dbd550edSchristos       break;
355*dbd550edSchristos     }
356*dbd550edSchristos }
357*dbd550edSchristos 
358*dbd550edSchristos static void
gtk_vi_screen_init(GtkViScreen * vi)359*dbd550edSchristos gtk_vi_screen_init (GtkViScreen *vi)
360*dbd550edSchristos {
361*dbd550edSchristos   GtkStyle *style;
362*dbd550edSchristos 
363*dbd550edSchristos   GTK_WIDGET_SET_FLAGS (vi, GTK_CAN_FOCUS);
364*dbd550edSchristos 
365*dbd550edSchristos   vi->text_area = NULL;
366*dbd550edSchristos   vi->chars = 0;
367*dbd550edSchristos   vi->reverse = 0;
368*dbd550edSchristos   vi->cols = 0;
369*dbd550edSchristos   vi->color = COLOR_STANDARD;
370*dbd550edSchristos   vi->cols = 0;
371*dbd550edSchristos   vi->rows = 0;
372*dbd550edSchristos 
373*dbd550edSchristos #ifdef HAVE_PANGO
374*dbd550edSchristos   vi->conx = NULL;
375*dbd550edSchristos #endif
376*dbd550edSchristos 
377*dbd550edSchristos   style = gtk_style_copy(GTK_WIDGET(vi)->style);
378*dbd550edSchristos   gdk_font_unref(style->font);
379*dbd550edSchristos   style->font = gdk_font_load("-*-fixed-*-*-*-*-16-*-*-*-*-*-iso8859-*");
380*dbd550edSchristos   GTK_WIDGET(vi)->style = style;
381*dbd550edSchristos }
382*dbd550edSchristos 
383*dbd550edSchristos static void
gtk_vi_screen_destroy(GtkObject * object)384*dbd550edSchristos gtk_vi_screen_destroy (GtkObject *object)
385*dbd550edSchristos {
386*dbd550edSchristos   GtkViScreen *vi_screen;
387*dbd550edSchristos 
388*dbd550edSchristos   g_return_if_fail (object != NULL);
389*dbd550edSchristos   g_return_if_fail (GTK_IS_VI_SCREEN (object));
390*dbd550edSchristos 
391*dbd550edSchristos   vi_screen = (GtkViScreen*) object;
392*dbd550edSchristos 
393*dbd550edSchristos   /*
394*dbd550edSchristos   gtk_signal_disconnect_by_data (GTK_OBJECT (vi_screen->vadj), vi_screen);
395*dbd550edSchristos   */
396*dbd550edSchristos 
397*dbd550edSchristos   GTK_OBJECT_CLASS(parent_class)->destroy (object);
398*dbd550edSchristos }
399*dbd550edSchristos 
400*dbd550edSchristos GtkWidget*
gtk_vi_screen_new(GtkAdjustment * vadj)401*dbd550edSchristos gtk_vi_screen_new (GtkAdjustment *vadj)
402*dbd550edSchristos {
403*dbd550edSchristos   GtkWidget *vi;
404*dbd550edSchristos 
405*dbd550edSchristos   vi = gtk_widget_new (GTK_TYPE_VI_SCREEN,
406*dbd550edSchristos 			 "vadjustment", vadj,
407*dbd550edSchristos 			 NULL);
408*dbd550edSchristos 
409*dbd550edSchristos 
410*dbd550edSchristos   return vi;
411*dbd550edSchristos }
412*dbd550edSchristos 
413*dbd550edSchristos void
gtk_vi_screen_set_adjustment(GtkViScreen * vi_screen,GtkAdjustment * vadj)414*dbd550edSchristos gtk_vi_screen_set_adjustment (GtkViScreen       *vi_screen,
415*dbd550edSchristos 			  GtkAdjustment *vadj)
416*dbd550edSchristos {
417*dbd550edSchristos   g_return_if_fail (vi_screen != NULL);
418*dbd550edSchristos   g_return_if_fail (GTK_IS_VI_SCREEN (vi_screen));
419*dbd550edSchristos   if (vadj)
420*dbd550edSchristos     g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
421*dbd550edSchristos   else
422*dbd550edSchristos     vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 1.0, 0.0, 1.0, 0.0, 0.0));
423*dbd550edSchristos 
424*dbd550edSchristos   if (vi_screen->vadj && (vi_screen->vadj != vadj))
425*dbd550edSchristos     {
426*dbd550edSchristos       gtk_signal_disconnect_by_data (GTK_OBJECT (vi_screen->vadj), vi_screen);
427*dbd550edSchristos       gtk_object_unref (GTK_OBJECT (vi_screen->vadj));
428*dbd550edSchristos     }
429*dbd550edSchristos 
430*dbd550edSchristos   if (vi_screen->vadj != vadj)
431*dbd550edSchristos     {
432*dbd550edSchristos       vi_screen->vadj = vadj;
433*dbd550edSchristos       gtk_object_ref (GTK_OBJECT (vi_screen->vadj));
434*dbd550edSchristos       gtk_object_sink (GTK_OBJECT (vi_screen->vadj));
435*dbd550edSchristos 
436*dbd550edSchristos       /*
437*dbd550edSchristos       gtk_signal_connect (GTK_OBJECT (vi_screen->vadj), "changed",
438*dbd550edSchristos 			  (GtkSignalFunc) gtk_vi_screen_adjustment,
439*dbd550edSchristos 			  vi_screen);
440*dbd550edSchristos       gtk_signal_connect (GTK_OBJECT (vi_screen->vadj), "value_changed",
441*dbd550edSchristos 			  (GtkSignalFunc) gtk_vi_screen_adjustment,
442*dbd550edSchristos 			  vi_screen);
443*dbd550edSchristos       gtk_signal_connect (GTK_OBJECT (vi_screen->vadj), "disconnect",
444*dbd550edSchristos 			  (GtkSignalFunc) gtk_vi_screen_disconnect,
445*dbd550edSchristos 			  vi_screen);
446*dbd550edSchristos       gtk_vi_screen_adjustment (vadj, vi_screen);
447*dbd550edSchristos       */
448*dbd550edSchristos     }
449*dbd550edSchristos }
450*dbd550edSchristos 
451*dbd550edSchristos static void
gtk_vi_screen_realize(GtkWidget * widget)452*dbd550edSchristos gtk_vi_screen_realize (GtkWidget *widget)
453*dbd550edSchristos {
454*dbd550edSchristos   GtkViScreen *vi;
455*dbd550edSchristos   GdkWindowAttr attributes;
456*dbd550edSchristos   gint attributes_mask;
457*dbd550edSchristos 
458*dbd550edSchristos   g_return_if_fail (widget != NULL);
459*dbd550edSchristos   g_return_if_fail (GTK_IS_VI_SCREEN (widget));
460*dbd550edSchristos 
461*dbd550edSchristos   vi = GTK_VI_SCREEN (widget);
462*dbd550edSchristos   GTK_WIDGET_SET_FLAGS (vi, GTK_REALIZED);
463*dbd550edSchristos 
464*dbd550edSchristos   attributes.window_type = GDK_WINDOW_CHILD;
465*dbd550edSchristos   attributes.x = widget->allocation.x;
466*dbd550edSchristos   attributes.y = widget->allocation.y;
467*dbd550edSchristos   attributes.width = widget->allocation.width;
468*dbd550edSchristos   attributes.height = widget->allocation.height;
469*dbd550edSchristos   attributes.wclass = GDK_INPUT_OUTPUT;
470*dbd550edSchristos   attributes.visual = gtk_widget_get_visual (widget);
471*dbd550edSchristos   attributes.colormap = gtk_widget_get_colormap (widget);
472*dbd550edSchristos   attributes.event_mask = gtk_widget_get_events (widget);
473*dbd550edSchristos   attributes.event_mask |= (GDK_EXPOSURE_MASK |
474*dbd550edSchristos 			    GDK_BUTTON_PRESS_MASK |
475*dbd550edSchristos 			    GDK_BUTTON_RELEASE_MASK |
476*dbd550edSchristos 			    GDK_BUTTON_MOTION_MASK |
477*dbd550edSchristos 			    GDK_ENTER_NOTIFY_MASK |
478*dbd550edSchristos 			    GDK_LEAVE_NOTIFY_MASK |
479*dbd550edSchristos 			    GDK_KEY_PRESS_MASK);
480*dbd550edSchristos   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
481*dbd550edSchristos 
482*dbd550edSchristos   widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
483*dbd550edSchristos   gdk_window_set_user_data (widget->window, vi);
484*dbd550edSchristos 
485*dbd550edSchristos   attributes.x = (widget->style->xthickness + VI_SCREEN_BORDER_ROOM);
486*dbd550edSchristos   attributes.y = (widget->style->ythickness + VI_SCREEN_BORDER_ROOM);
487*dbd550edSchristos   attributes.width = MAX (1, (gint)widget->allocation.width - (gint)attributes.x * 2);
488*dbd550edSchristos   attributes.height = MAX (1, (gint)widget->allocation.height - (gint)attributes.y * 2);
489*dbd550edSchristos 
490*dbd550edSchristos   vi->text_area = gdk_window_new (widget->window, &attributes, attributes_mask);
491*dbd550edSchristos   gdk_window_set_user_data (vi->text_area, vi);
492*dbd550edSchristos 
493*dbd550edSchristos   widget->style = gtk_style_attach (widget->style, widget->window);
494*dbd550edSchristos 
495*dbd550edSchristos   /* Can't call gtk_style_set_background here because it's handled specially */
496*dbd550edSchristos   gdk_window_set_background (widget->window, &widget->style->base[GTK_STATE_NORMAL]);
497*dbd550edSchristos   gdk_window_set_background (vi->text_area, &widget->style->base[GTK_STATE_NORMAL]);
498*dbd550edSchristos 
499*dbd550edSchristos   vi->gc = gdk_gc_new (vi->text_area);
500*dbd550edSchristos   /* What's this ? */
501*dbd550edSchristos   gdk_gc_set_exposures (vi->gc, TRUE);
502*dbd550edSchristos   gdk_gc_set_foreground (vi->gc, &widget->style->text[GTK_STATE_NORMAL]);
503*dbd550edSchristos 
504*dbd550edSchristos   vi->reverse_gc = gdk_gc_new (vi->text_area);
505*dbd550edSchristos   gdk_gc_set_foreground (vi->reverse_gc, &widget->style->base[GTK_STATE_NORMAL]);
506*dbd550edSchristos 
507*dbd550edSchristos   gdk_window_show (vi->text_area);
508*dbd550edSchristos 
509*dbd550edSchristos   recompute_geometry (vi);
510*dbd550edSchristos }
511*dbd550edSchristos 
512*dbd550edSchristos static void
gtk_vi_screen_size_request(GtkWidget * widget,GtkRequisition * requisition)513*dbd550edSchristos gtk_vi_screen_size_request (GtkWidget      *widget,
514*dbd550edSchristos 		       GtkRequisition *requisition)
515*dbd550edSchristos {
516*dbd550edSchristos   gint xthick;
517*dbd550edSchristos   gint ythick;
518*dbd550edSchristos   gint char_height;
519*dbd550edSchristos   gint char_width;
520*dbd550edSchristos   GtkViScreen *vi;
521*dbd550edSchristos 
522*dbd550edSchristos   g_return_if_fail (widget != NULL);
523*dbd550edSchristos   g_return_if_fail (GTK_IS_VI_SCREEN (widget));
524*dbd550edSchristos   g_return_if_fail (requisition != NULL);
525*dbd550edSchristos 
526*dbd550edSchristos   vi = GTK_VI_SCREEN (widget);
527*dbd550edSchristos 
528*dbd550edSchristos   xthick = widget->style->xthickness + VI_SCREEN_BORDER_ROOM;
529*dbd550edSchristos   ythick = widget->style->ythickness + VI_SCREEN_BORDER_ROOM;
530*dbd550edSchristos 
531*dbd550edSchristos   vi->ch_ascent = widget->style->font->ascent;
532*dbd550edSchristos   vi->ch_height = (widget->style->font->ascent + widget->style->font->descent) + 1;
533*dbd550edSchristos   vi->ch_width = gdk_text_width (widget->style->font, "A", 1);
534*dbd550edSchristos   char_height = DEFAULT_VI_SCREEN_HEIGHT_LINES * vi->ch_height;
535*dbd550edSchristos   char_width = DEFAULT_VI_SCREEN_WIDTH_CHARS * vi->ch_width;
536*dbd550edSchristos 
537*dbd550edSchristos   requisition->width  = char_width  + xthick * 2;
538*dbd550edSchristos   requisition->height = char_height + ythick * 2;
539*dbd550edSchristos }
540*dbd550edSchristos 
541*dbd550edSchristos static void
gtk_vi_screen_size_allocate(GtkWidget * widget,GtkAllocation * allocation)542*dbd550edSchristos gtk_vi_screen_size_allocate (GtkWidget     *widget,
543*dbd550edSchristos 			GtkAllocation *allocation)
544*dbd550edSchristos {
545*dbd550edSchristos   GtkViScreen *vi;
546*dbd550edSchristos 
547*dbd550edSchristos   g_return_if_fail (widget != NULL);
548*dbd550edSchristos   g_return_if_fail (GTK_IS_VI_SCREEN (widget));
549*dbd550edSchristos   g_return_if_fail (allocation != NULL);
550*dbd550edSchristos 
551*dbd550edSchristos   vi = GTK_VI_SCREEN (widget);
552*dbd550edSchristos 
553*dbd550edSchristos   widget->allocation = *allocation;
554*dbd550edSchristos   if (GTK_WIDGET_REALIZED (widget))
555*dbd550edSchristos     {
556*dbd550edSchristos       gdk_window_move_resize (widget->window,
557*dbd550edSchristos 			      allocation->x, allocation->y,
558*dbd550edSchristos 			      allocation->width, allocation->height);
559*dbd550edSchristos 
560*dbd550edSchristos       gdk_window_move_resize (vi->text_area,
561*dbd550edSchristos 			      widget->style->xthickness + VI_SCREEN_BORDER_ROOM,
562*dbd550edSchristos 			      widget->style->ythickness + VI_SCREEN_BORDER_ROOM,
563*dbd550edSchristos 			      MAX (1, (gint)widget->allocation.width - (gint)(widget->style->xthickness +
564*dbd550edSchristos 							  (gint)VI_SCREEN_BORDER_ROOM) * 2),
565*dbd550edSchristos 			      MAX (1, (gint)widget->allocation.height - (gint)(widget->style->ythickness +
566*dbd550edSchristos 							   (gint)VI_SCREEN_BORDER_ROOM) * 2));
567*dbd550edSchristos 
568*dbd550edSchristos       recompute_geometry (vi);
569*dbd550edSchristos     }
570*dbd550edSchristos }
571*dbd550edSchristos 
572*dbd550edSchristos /*
573*dbd550edSchristos static void
574*dbd550edSchristos gtk_vi_screen_adjustment (GtkAdjustment *adjustment,
575*dbd550edSchristos 			 GtkViScreen       *vi_screen)
576*dbd550edSchristos {
577*dbd550edSchristos   g_return_if_fail (adjustment != NULL);
578*dbd550edSchristos   g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
579*dbd550edSchristos   g_return_if_fail (vi_screen != NULL);
580*dbd550edSchristos   g_return_if_fail (GTK_IS_VI_SCREEN (vi_screen));
581*dbd550edSchristos 
582*dbd550edSchristos }
583*dbd550edSchristos */
584*dbd550edSchristos 
585*dbd550edSchristos static gint
gtk_vi_screen_expose(GtkWidget * widget,GdkEventExpose * event)586*dbd550edSchristos gtk_vi_screen_expose (GtkWidget      *widget,
587*dbd550edSchristos 		 GdkEventExpose *event)
588*dbd550edSchristos {
589*dbd550edSchristos   g_return_val_if_fail (widget != NULL, FALSE);
590*dbd550edSchristos   g_return_val_if_fail (GTK_IS_VI_SCREEN (widget), FALSE);
591*dbd550edSchristos   g_return_val_if_fail (event != NULL, FALSE);
592*dbd550edSchristos 
593*dbd550edSchristos   if (event->window == GTK_VI_SCREEN (widget)->text_area)
594*dbd550edSchristos     {
595*dbd550edSchristos       expose_text (GTK_VI_SCREEN (widget), &event->area, TRUE);
596*dbd550edSchristos     }
597*dbd550edSchristos 
598*dbd550edSchristos   return FALSE;
599*dbd550edSchristos }
600*dbd550edSchristos 
601*dbd550edSchristos static void
recompute_geometry(GtkViScreen * vi)602*dbd550edSchristos recompute_geometry (GtkViScreen* vi)
603*dbd550edSchristos {
604*dbd550edSchristos     //gint xthickness;
605*dbd550edSchristos     //gint ythickness;
606*dbd550edSchristos     gint height;
607*dbd550edSchristos     gint width;
608*dbd550edSchristos     gint rows, cols;
609*dbd550edSchristos     gint i;
610*dbd550edSchristos 
611*dbd550edSchristos     //xthickness = widget->style->xthickness + VI_SCREEN_BORDER_ROOM;
612*dbd550edSchristos     //ythickness = widget->style->ythickness + VI_SCREEN_BORDER_ROOM;
613*dbd550edSchristos 
614*dbd550edSchristos     gdk_window_get_size (vi->text_area, &width, &height);
615*dbd550edSchristos 
616*dbd550edSchristos     rows = height / vi->ch_height;
617*dbd550edSchristos     cols = width / vi->ch_width;
618*dbd550edSchristos 
619*dbd550edSchristos     if (rows == vi->rows && cols == vi->cols)
620*dbd550edSchristos 	return;
621*dbd550edSchristos 
622*dbd550edSchristos     vi->marked_x = vi->cols = cols;
623*dbd550edSchristos     vi->marked_y = vi->rows = rows;
624*dbd550edSchristos     vi->marked_maxx = 0;
625*dbd550edSchristos     vi->marked_maxy = 0;
626*dbd550edSchristos 
627*dbd550edSchristos     g_free(vi->chars);
628*dbd550edSchristos     vi->chars = (CHAR_T*)g_new(gchar, (vi->rows+1)*vi->cols * sizeof(CHAR_T));
629*dbd550edSchristos     STRSET(vi->chars, L(' '), (vi->rows+1)*vi->cols);
630*dbd550edSchristos     g_free(vi->endcol);
631*dbd550edSchristos     vi->endcol = g_new(guchar, vi->rows*vi->cols);
632*dbd550edSchristos     g_free(vi->reverse);
633*dbd550edSchristos     vi->reverse = g_new(guchar, vi->rows*vi->cols);
634*dbd550edSchristos     memset(vi->reverse, 0, vi->rows*vi->cols);
635*dbd550edSchristos 
636*dbd550edSchristos     gtk_signal_emit(GTK_OBJECT(vi), vi_screen_signals[RESIZED], vi->rows, vi->cols);
637*dbd550edSchristos }
638*dbd550edSchristos 
639*dbd550edSchristos static void
expose_text(GtkViScreen * vi,GdkRectangle * area,gboolean cursor)640*dbd550edSchristos expose_text (GtkViScreen* vi, GdkRectangle *area, gboolean cursor)
641*dbd550edSchristos {
642*dbd550edSchristos     gint ymax;
643*dbd550edSchristos     gint xmax, xmin;
644*dbd550edSchristos 
645*dbd550edSchristos     gdk_window_clear_area (vi->text_area, area->x, area->y,
646*dbd550edSchristos 			    area->width, area->height);
647*dbd550edSchristos     ymax = MIN((area->y + area->height + vi->ch_height - 1) / vi->ch_height,
648*dbd550edSchristos 		vi->rows);
649*dbd550edSchristos     xmin = area->x / vi->ch_width;
650*dbd550edSchristos     xmax = MIN((area->x + area->width + vi->ch_width - 1) / vi->ch_width,
651*dbd550edSchristos 		vi->cols);
652*dbd550edSchristos     draw_lines(vi, area->y / vi->ch_height, xmin, ymax, xmax);
653*dbd550edSchristos }
654*dbd550edSchristos 
655*dbd550edSchristos #define Inverse(screen,y,x) \
656*dbd550edSchristos     ((*FlagAt(screen,y,x) == COLOR_STANDOUT) ^ \
657*dbd550edSchristos 	(screen->cury == y && screen->curx == x))
658*dbd550edSchristos 
659*dbd550edSchristos static void
draw_lines(GtkViScreen * vi,gint ymin,gint xmin,gint ymax,gint xmax)660*dbd550edSchristos draw_lines(GtkViScreen *vi, gint ymin, gint xmin, gint ymax, gint xmax)
661*dbd550edSchristos {
662*dbd550edSchristos     gint y, x, len, blen, xpos;
663*dbd550edSchristos     CHAR_T *line;
664*dbd550edSchristos     GdkGC *fg, *bg;
665*dbd550edSchristos     GdkFont *font;
666*dbd550edSchristos     gchar buf[2];
667*dbd550edSchristos     gchar *p;
668*dbd550edSchristos     gboolean pango;
669*dbd550edSchristos 
670*dbd550edSchristos     for (y = ymin, line = vi->chars + y*vi->cols;
671*dbd550edSchristos 			     y < ymax; ++y, line += vi->cols) {
672*dbd550edSchristos 	for (x = 0, xpos = 0; xpos <= xmin; ++x)
673*dbd550edSchristos 	    xpos += CHAR_WIDTH(NULL, *(line+x));
674*dbd550edSchristos 	--x;
675*dbd550edSchristos 	xpos -= CHAR_WIDTH(NULL, *(line+x));
676*dbd550edSchristos 	for (; xpos < xmax; x+=len, xpos+= blen) {
677*dbd550edSchristos 	    gchar inverse;
678*dbd550edSchristos 	    inverse = Inverse(vi,y,x);
679*dbd550edSchristos 	    len = 1;
680*dbd550edSchristos 	    if (sizeof(CHAR_T) == sizeof(gchar))
681*dbd550edSchristos 		for (; x+len < xmax &&
682*dbd550edSchristos 		       Inverse(vi,y,x+len) == inverse; ++len);
683*dbd550edSchristos 	    if (inverse) {
684*dbd550edSchristos 		fg = vi->reverse_gc;
685*dbd550edSchristos 		bg = vi->gc;
686*dbd550edSchristos 	    } else {
687*dbd550edSchristos 		bg = vi->reverse_gc;
688*dbd550edSchristos 		fg = vi->gc;
689*dbd550edSchristos 	    }
690*dbd550edSchristos 	    pango = 0;
691*dbd550edSchristos #ifdef HAVE_PANGO
692*dbd550edSchristos 	    if (INTISUCS(*(line+x))) {
693*dbd550edSchristos 		if (!vi->conx) {
694*dbd550edSchristos 		    PangoFontDescription font_description;
695*dbd550edSchristos 
696*dbd550edSchristos 		    font_description.family_name = g_strdup ("monospace");
697*dbd550edSchristos 		    font_description.style = PANGO_STYLE_NORMAL;
698*dbd550edSchristos 		    font_description.variant = PANGO_VARIANT_NORMAL;
699*dbd550edSchristos 		    font_description.weight = 500;
700*dbd550edSchristos 		    font_description.stretch = PANGO_STRETCH_NORMAL;
701*dbd550edSchristos 		    font_description.size = 15000;
702*dbd550edSchristos 
703*dbd550edSchristos 		    vi->conx = gdk_pango_context_get();
704*dbd550edSchristos 		    pango_context_set_font_description (vi->conx,
705*dbd550edSchristos 			&font_description);
706*dbd550edSchristos 		    pango_context_set_lang(vi->conx, "en_US");
707*dbd550edSchristos 		    vi->alist = pango_attr_list_new();
708*dbd550edSchristos 		}
709*dbd550edSchristos 		blen = CHAR_WIDTH(NULL, *(line+x));
710*dbd550edSchristos 		pango = 1;
711*dbd550edSchristos 	    } else
712*dbd550edSchristos #endif
713*dbd550edSchristos 	    {
714*dbd550edSchristos 		font = GTK_WIDGET(vi)->style->font;
715*dbd550edSchristos 		if (sizeof(CHAR_T) == sizeof(gchar))
716*dbd550edSchristos 		    p = (gchar*)line+x;
717*dbd550edSchristos 		else {
718*dbd550edSchristos 		    buf[0] = *(line+x);
719*dbd550edSchristos 		    p = buf;
720*dbd550edSchristos 		}
721*dbd550edSchristos 		blen = len;
722*dbd550edSchristos 	    }
723*dbd550edSchristos 	    gdk_draw_rectangle(vi->text_area, bg, 1, xpos * vi->ch_width,
724*dbd550edSchristos 				y * vi->ch_height, blen * vi->ch_width,
725*dbd550edSchristos 				vi->ch_height);
726*dbd550edSchristos 	    /* hack to not display half a wide character that wasn't
727*dbd550edSchristos 	     * removed.
728*dbd550edSchristos 	     */
729*dbd550edSchristos 	    if (!pango)
730*dbd550edSchristos 		gdk_draw_text (vi->text_area, font, fg,
731*dbd550edSchristos 				xpos * vi->ch_width,
732*dbd550edSchristos 				y * vi->ch_height + vi->ch_ascent,
733*dbd550edSchristos 				p, blen);
734*dbd550edSchristos #ifdef HAVE_PANGO
735*dbd550edSchristos 	    else {
736*dbd550edSchristos 		PangoGlyphString *gs;
737*dbd550edSchristos 		GList *list;
738*dbd550edSchristos 		PangoItem *item;
739*dbd550edSchristos 		char buf[3];
740*dbd550edSchristos 		int len;
741*dbd550edSchristos 
742*dbd550edSchristos 		len = ucs2utf8(line+x, 1, buf);
743*dbd550edSchristos 		list = pango_itemize(vi->conx, buf, 0, len, vi->alist, NULL);
744*dbd550edSchristos 		item = list->data;
745*dbd550edSchristos 		gs = pango_glyph_string_new ();
746*dbd550edSchristos 		pango_shape(buf, len, &item->analysis, gs);
747*dbd550edSchristos 
748*dbd550edSchristos 		gdk_draw_glyphs (vi->text_area, fg, item->analysis.font,
749*dbd550edSchristos 				xpos * vi->ch_width,
750*dbd550edSchristos 				y * vi->ch_height + vi->ch_ascent, gs);
751*dbd550edSchristos 	    }
752*dbd550edSchristos #endif
753*dbd550edSchristos 	}
754*dbd550edSchristos     }
755*dbd550edSchristos }
756*dbd550edSchristos 
757*dbd550edSchristos static void
mark_lines(GtkViScreen * vi,gint ymin,gint xmin,gint ymax,gint xmax)758*dbd550edSchristos mark_lines(GtkViScreen *vi, gint ymin, gint xmin, gint ymax, gint xmax)
759*dbd550edSchristos {
760*dbd550edSchristos     if (ymin < vi->marked_y) vi->marked_y = ymin;
761*dbd550edSchristos     if (xmin < vi->marked_x) vi->marked_x = xmin;
762*dbd550edSchristos     if (ymax > vi->marked_maxy) vi->marked_maxy = ymax;
763*dbd550edSchristos     if (xmax > vi->marked_maxx) vi->marked_maxx = xmax;
764*dbd550edSchristos }
765