~ubuntu-branches/ubuntu/karmic/iterm/karmic

« back to all changes in this revision

Viewing changes to unix/Xaw/lib/VT.c

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Fok
  • Date: 2004-02-27 04:13:16 UTC
  • Revision ID: james.westby@ubuntu.com-20040227041316-q0jn37sia8mt0t9u
Tags: upstream-0.5
ImportĀ upstreamĀ versionĀ 0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This software is subject to the terms of the Common Public License
 
2
   You must accept the terms of this license to use this software.
 
3
 
 
4
   Copyright (C) 2002, International Business Machines Corporation
 
5
   and others.  All Rights Reserved.
 
6
 
 
7
   Further information about Common Public License Version 0.5 is obtained
 
8
   from url http://oss.software.ibm.com/developer/opensource/license-cpl.html */
 
9
 
 
10
/* $TOG: Template.c /main/6 1998/02/06 12:50:51 kaleb $ */
 
11
 
 
12
/*
 
13
 
 
14
Copyright 1987, 1998  The Open Group
 
15
 
 
16
All Rights Reserved.
 
17
 
 
18
The above copyright notice and this permission notice shall be included in
 
19
all copies or substantial portions of the Software.
 
20
 
 
21
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
22
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
23
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
24
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
25
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
26
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
 
 
28
Except as contained in this notice, the name of The Open Group shall not be
 
29
used in advertising or otherwise to promote the sale, use or other dealings
 
30
in this Software without prior written authorization from The Open Group.
 
31
 
 
32
*/
 
33
/* $XFree86: xc/lib/Xaw/Template.c,v 1.6 1999/06/06 08:48:13 dawes Exp $ */
 
34
 
 
35
#include <X11/IntrinsicP.h>
 
36
#include <X11/Xaw/XawImP.h>
 
37
#include <X11/StringDefs.h>
 
38
#include <X11/Shell.h>
 
39
#include <X11/keysym.h>
 
40
 
 
41
#include "VTP.h"
 
42
#include "VTScreenView.h"
 
43
#include "xim.h"
 
44
#include "actions.h"
 
45
#include "scrollbar.h"
 
46
 
 
47
#include <stdio.h>
 
48
#include <stdlib.h>
 
49
 
 
50
#include <iterm/unix/ttyio.h>
 
51
#include <time.h>
 
52
 
 
53
 
 
54
#define DEFAULT_FONTSET "-misc-fixed-medium-r-normal--14-*,*"
 
55
 
 
56
#define DEFAULT_FONTSET_1 "-misc-fixed-medium-r-normal--10-*,*"
 
57
#define DEFAULT_FONTSET_2 "-misc-fixed-medium-r-normal--12-*,*"
 
58
#define DEFAULT_FONTSET_3 "-misc-fixed-medium-r-normal--14-*,*"
 
59
#define DEFAULT_FONTSET_4 "-misc-fixed-medium-r-normal--16-*,*"
 
60
#define DEFAULT_FONTSET_5 "-misc-fixed-medium-r-normal--20-*,*"
 
61
#define DEFAULT_FONTSET_6 "-misc-fixed-medium-r-normal--24-*,*"
 
62
 
 
63
/*
 
64
 * Class Methods
 
65
 */
 
66
static void VTInitialize(Widget, Widget, ArgList, Cardinal*);
 
67
static void VTRealize(Widget,XtValueMask*,XSetWindowAttributes *);
 
68
static void VTDestroy(Widget w);
 
69
static void VTExpose(Widget w, XEvent *event, Region region);
 
70
static void VTResize(Widget w);
 
71
 
 
72
/*
 
73
 * Event Handler
 
74
 */
 
75
static void HandleFocusChange(Widget w,XtPointer client_data, XEvent *event,
 
76
  Boolean *continue_dispatch);
 
77
static void HandleNonMaskableEvent(Widget w,XtPointer client_data,
 
78
                                   XEvent *event, Boolean *continue_dispatch);
 
79
/*
 
80
 * Initialization
 
81
 */
 
82
#define offset(field) XtOffsetOf(VTRec, vt.field)
 
83
static XtResource resources[] = {
 
84
/*{
 
85
    name,
 
86
    class,
 
87
    type,
 
88
    size,
 
89
    offset,
 
90
    default_type,
 
91
    default_addr
 
92
  },*/
 
93
/*  {XtNvtResource, XtCVTResource, XtRVTResource, sizeof(char*),
 
94
    offset(resource), XtRString, (XtPointer)"default" }, */
 
95
  {XtNfontSet,XtCFontSet, XtRString,sizeof(char *),
 
96
   offset(fontset_string),XtRString, DEFAULT_FONTSET },
 
97
  {XtNboldFontSet,XtCBoldFontSet, XtRString,sizeof(char *),
 
98
   offset(bold_fontset_string),XtRString, NULL },
 
99
  {XtNfontSet1, XtCFontSet1, XtRString, sizeof(char *),
 
100
   offset(fontsets[0]),XtRString, DEFAULT_FONTSET_1},
 
101
  {XtNfontSet2, XtCFontSet2, XtRString, sizeof(char *),
 
102
   offset(fontsets[1]),XtRString, DEFAULT_FONTSET_2},
 
103
  {XtNfontSet3, XtCFontSet3, XtRString, sizeof(char *),
 
104
   offset(fontsets[2]),XtRString, DEFAULT_FONTSET_3},
 
105
  {XtNfontSet4, XtCFontSet4, XtRString, sizeof(char *),
 
106
   offset(fontsets[3]),XtRString, DEFAULT_FONTSET_4},
 
107
  {XtNfontSet5, XtCFontSet5, XtRString, sizeof(char *),
 
108
   offset(fontsets[4]),XtRString, DEFAULT_FONTSET_5},
 
109
  {XtNfontSet6, XtCFontSet6, XtRString, sizeof(char *),
 
110
   offset(fontsets[5]),XtRString, DEFAULT_FONTSET_6},
 
111
  {XtNtextColor0, XtCTextColor0, XtRPixel, sizeof(Pixel),
 
112
   offset(textcolor[0]),XtRString, "black"},
 
113
  {XtNtextColor1, XtCTextColor1, XtRPixel, sizeof(Pixel),
 
114
   offset(textcolor[1]),XtRString, "red3"},
 
115
  {XtNtextColor2, XtCTextColor2, XtRPixel, sizeof(Pixel),
 
116
   offset(textcolor[2]),XtRString, "green3"},
 
117
  {XtNtextColor3, XtCTextColor3, XtRPixel, sizeof(Pixel),
 
118
   offset(textcolor[3]),XtRString, "yellow3"},
 
119
  {XtNtextColor4, XtCTextColor4, XtRPixel, sizeof(Pixel),
 
120
   offset(textcolor[4]),XtRString, "blue3"},
 
121
  {XtNtextColor5, XtCTextColor5, XtRPixel, sizeof(Pixel),
 
122
   offset(textcolor[5]),XtRString, "magenta3"},
 
123
  {XtNtextColor6, XtCTextColor6, XtRPixel, sizeof(Pixel),
 
124
   offset(textcolor[6]),XtRString, "cyan3"},
 
125
  {XtNtextColor7, XtCTextColor7, XtRPixel, sizeof(Pixel),
 
126
   offset(textcolor[7]),XtRString, "gray90"},
 
127
  {XtNtextColor8, XtCTextColor8, XtRPixel, sizeof(Pixel), 
 
128
  offset(textcolor[8]),XtRString, "gray30"},
 
129
  {XtNtextColor9, XtCTextColor9, XtRPixel, sizeof(Pixel),
 
130
   offset(textcolor[9]),XtRString, "red"},
 
131
  {XtNtextColor10, XtCTextColor10, XtRPixel, sizeof(Pixel),
 
132
   offset(textcolor[10]),XtRString, "green"},
 
133
  {XtNtextColor11, XtCTextColor11, XtRPixel, sizeof(Pixel),
 
134
   offset(textcolor[11]),XtRString, "yellow"},
 
135
  {XtNtextColor12, XtCTextColor12, XtRPixel, sizeof(Pixel),
 
136
   offset(textcolor[12]),XtRString, "blue"},
 
137
  {XtNtextColor13, XtCTextColor13, XtRPixel, sizeof(Pixel),
 
138
   offset(textcolor[13]),XtRString, "magenta"},
 
139
  {XtNtextColor14, XtCTextColor14, XtRPixel, sizeof(Pixel),
 
140
   offset(textcolor[14]),XtRString, "cyan"},
 
141
  {XtNtextColor15, XtCTextColor15, XtRPixel, sizeof(Pixel),
 
142
   offset(textcolor[15]),XtRString, "white"},
 
143
  {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
 
144
   offset(foreground),XtRString,  "XtDefaultForeground"},
 
145
  {XtNcursorColor, XtCForeground, XtRPixel, sizeof(Pixel),
 
146
   offset(cursor_color),XtRString,  "XtDefaultForeground"},
 
147
  {XtNvisualBell, XtCVisualBell, XtRBoolean, sizeof(Boolean),
 
148
   offset(visual_bell_on), XtRString, (XtPointer) "false"},
 
149
  {XtNinputMethod,XtCInputMethod, XtRString,sizeof(char *),
 
150
   offset(input_method),XtRString, (XtPointer)NULL },
 
151
  {XtNscrollBar,XtCScrollBar, XtRBoolean,sizeof(Boolean),
 
152
   offset(scrollbar_on),XtRString, "true"},
 
153
  {XtNstatusLineChange,XtCCallback, XtRCallback,sizeof(XtCallbackList),
 
154
   offset(statusLineChanged),XtRCallback, NULL},
 
155
  {XtNrow, XtCRow, XtRInt, sizeof(Cardinal),
 
156
   offset(num_rows),XtRString,(XtPointer)"24"},
 
157
  {XtNcol, XtCCol, XtRInt, sizeof(Cardinal),
 
158
   offset(num_cols),XtRString,(XtPointer)"80"},
 
159
  {XtNloginShell, XtCLoginShell, XtRBoolean, sizeof(Boolean),
 
160
   offset(login_shell), XtRString, (XtPointer) "false"},
 
161
};
 
162
#undef offset
 
163
 
 
164
static char translations[] =
 
165
"Shift <KeyPress> Prior:" "scroll-up(1,halfpage) \n"
 
166
"Shift <KeyPress> Next:" "scroll-down(1,halfpage) \n"
 
167
"Shift <Btn4Down>,<Btn4Up>:" "scroll-up(1,line) \n"
 
168
"Shift <Btn5Down>,<Btn5Up>:" "scroll-down(1,line) \n"
 
169
"Ctrl <Btn4Down>,<Btn4Up>:" "scroll-up(1,page) \n"
 
170
"Ctrl <Btn5Down>,<Btn5Up>:" "scroll-down(1,page) \n"
 
171
#ifdef BIDI
 
172
"Alt <Key>Return:" "switch-direction() \n"
 
173
#endif
 
174
"<Btn4Down>,<Btn4Up>:" "scroll-up(1,halfpage) \n"
 
175
"<Btn5Down>,<Btn5Up>:" "scroll-down(1,halfpage) \n"
 
176
"<Key>Delete:" "string(\033[3~) \n "
 
177
"<Key>BackSpace:" "string(\177) \n "
 
178
"~Ctrl ~Meta <Btn2Up>:" "insert-selection() \n "
 
179
"<Btn1Motion>:" "extend-selection() \n"
 
180
"<Btn1Up>:" "end-selection() \n"
 
181
"~Ctrl ~Meta <Btn3Down>:" "extend-selection() \n"
 
182
"~Meta <Btn3Motion>:" "extend-selection()\n"
 
183
"<Btn3Up>:" "end-selection() \n"
 
184
"<Btn1Down>:" "start-selection() \n"
 
185
"<BtnDown>:" "button-down() \n"
 
186
"<BtnUp>:" "button-up() \n"
 
187
"<KeyPress>:"   "insert-keys() ";
 
188
 
 
189
 
 
190
static XtActionsRec actions[] =
 
191
{
 
192
    {"scroll-up", HandleScrollUp},
 
193
    {"scroll-down", HandleScrollDown},
 
194
    {"insert-keys",     HandleKeys},
 
195
    {"string",  HandleString},
 
196
    {"insert-selection",HandleInsertSelection},
 
197
    {"start-selection",HandleStartSelection},
 
198
    {"extend-selection",HandleExtendSelection},
 
199
    {"end-selection",HandleEndSelection},
 
200
    {"button-down",HandleButtonDown},
 
201
    {"button-up",HandleButtonUp},
 
202
#ifdef BIDI
 
203
    {"switch-direction",HandleSwitchDirection},
 
204
#endif    
 
205
/*    {"clicked",   VTClicked},
 
206
      {"popup",  HandlePopup}, */
 
207
};
 
208
 
 
209
#define Superclass      (&widgetClassRec)
 
210
VTClassRec vtClassRec = {
 
211
  /* core */
 
212
  {
 
213
    (WidgetClass)Superclass,            /* superclass */
 
214
    "VT",                               /* class_name */
 
215
    sizeof(VTRec),                      /* widget_size */
 
216
    NULL,                               /* class_initialize */
 
217
    NULL,                               /* class_part_initialize */
 
218
    False,                              /* class_inited */
 
219
    VTInitialize,                       /* initialize */
 
220
    NULL,                               /* initialize_hook */
 
221
    VTRealize,                          /* realize */ 
 
222
    actions,                            /* actions */
 
223
    XtNumber(actions),                  /* num_actions */
 
224
    resources,                          /* resources */
 
225
    XtNumber(resources),                /* num_resources */
 
226
    NULLQUARK,                          /* xrm_class */
 
227
    True,                               /* compress_motion */
 
228
    False,                              /* compress_exposure */
 
229
    True,                               /* compress_enterleave */
 
230
    False,                              /* visible_interest */
 
231
    VTDestroy,                          /* destroy */
 
232
    VTResize,                           /* resize */
 
233
    VTExpose,                           /* expose */
 
234
    NULL,                               /* set_values */
 
235
    NULL,                               /* set_values_hook */
 
236
    XtInheritSetValuesAlmost,           /* set_values_almost */
 
237
    NULL,                               /* get_values_hook */
 
238
    NULL,                               /* accept_focus */
 
239
    XtVersion,                          /* version */
 
240
    NULL,                               /* callback_private */
 
241
    translations,                       /* tm_table */
 
242
    XtInheritQueryGeometry,             /* query_geometry */
 
243
    XtInheritDisplayAccelerator,        /* display_accelerator */
 
244
    NULL,                               /* extension */
 
245
  },
 
246
  /* vt */
 
247
  {
 
248
    NULL,                               /* extension */
 
249
  }
 
250
};
 
251
 
 
252
WidgetClass vtWidgetClass = (WidgetClass)&vtClassRec;
 
253
 
 
254
/* utility functions */
 
255
static void host_thread_dispatcher(XtPointer p, int *source, XtInputId *id)
 
256
{
 
257
  VTCore_dispatch((VTCore *)p);
 
258
}
 
259
 
 
260
static void reverse_video(VTWidget vt)
 
261
{
 
262
  Pixel tmp;
 
263
  XGCValues       xgcv;
 
264
  tmp = vt->vt.foreground;
 
265
  vt->vt.foreground = vt->core.background_pixel;
 
266
  vt->core.background_pixel = tmp;
 
267
 
 
268
  xgcv.foreground = vt->vt.foreground;
 
269
  xgcv.background = vt->core.background_pixel;
 
270
  XChangeGC(XtDisplay((Widget)vt),vt->vt.normal_gc,
 
271
                      GCForeground|GCBackground, &xgcv);
 
272
 
 
273
  xgcv.foreground = vt->core.background_pixel;
 
274
  xgcv.background = vt->vt.foreground;
 
275
  XChangeGC(XtDisplay((Widget)vt),vt->vt.reverse_gc,
 
276
                      GCForeground|GCBackground, &xgcv);
 
277
  XSetWindowBackground(XtDisplay((Widget)vt),
 
278
                       XtWindow((Widget)vt),
 
279
                       vt->core.background_pixel);
 
280
  
 
281
      /* swap foreground and background color, then redraw all screen */
 
282
  UpdateIMPreeditAttributes(vt);
 
283
  if(vt->vt.status_line)
 
284
      UpdateIMStatusAttributes(vt);
 
285
  XClearArea(XtDisplay((Widget)vt),XtWindow((Widget)vt),
 
286
             0,0,vt->core.width,vt->core.height,TRUE);
 
287
  XtVaSetValues((Widget)vt,XtNborderColor,vt->core.background_pixel,NULL);
 
288
  XFlush(XtDisplay((Widget)vt));
 
289
}
 
290
 
 
291
static TerminalIO *init_io(int cols, int rows, Boolean loginShell)
 
292
{
 
293
  char *defaultShell = "/bin/sh";
 
294
  char *shell;
 
295
  char *login_shell;
 
296
  char *program = defaultShell;
 
297
  char *argv[] = {program,NULL};
 
298
  putenv("TERM=xterm");
 
299
  shell = getenv("SHELL");
 
300
  if(shell != NULL && shell[0] != '\0')
 
301
  {
 
302
    program = shell;
 
303
    argv[0] = shell;
 
304
  }
 
305
  
 
306
  if(loginShell)
 
307
  {
 
308
    int length = strlen(program) + 1;
 
309
    login_shell = malloc(length) + 1;
 
310
    login_shell[0] = '-';
 
311
    memcpy(login_shell+1,program,length);
 
312
    argv[0] = login_shell;
 
313
  }
 
314
 
 
315
  return TtyTerminalIO_new(cols,rows,program,argv);
 
316
}
 
317
 
 
318
static int fontset_column_width_in_pixel(XFontSet fontset)
 
319
{
 
320
    XFontStruct **font_struct = NULL;
 
321
    char **font_name = NULL;
 
322
    int number_of_fonts = 0;
 
323
    int minimum = 0;
 
324
    int i;
 
325
 
 
326
    number_of_fonts = XFontsOfFontSet(fontset,&font_struct,&font_name);
 
327
 
 
328
    minimum = font_struct[0]->max_bounds.width;
 
329
 
 
330
    if(number_of_fonts == 1)
 
331
    {
 
332
          /*
 
333
            ad-hoc hack for bi-width fonts
 
334
            asume that min_bounds.width represents single column char width
 
335
            and man_bounds.width represents double columns char width
 
336
           */
 
337
      int min = font_struct[0]->min_bounds.width;
 
338
      if(min == (minimum/2))
 
339
          minimum = min;
 
340
    }
 
341
    else
 
342
    {
 
343
      for(i=1;i<number_of_fonts;i++)
 
344
      {
 
345
        if(font_struct[i]->max_bounds.width <  minimum)
 
346
            minimum = font_struct[i]->max_bounds.width;
 
347
      }
 
348
    }
 
349
    return minimum;
 
350
}
 
351
 
 
352
static int fontset_load(Display *d,char *fontset_string, XFontSet *fontset)
 
353
{
 
354
  XFontSet set = NULL;
 
355
 
 
356
  char **missingfonts;
 
357
  int count,i;
 
358
  char *defonts;
 
359
  
 
360
  if(!strlen(fontset_string))
 
361
      return 1;
 
362
 
 
363
  set = XCreateFontSet(d,fontset_string, &missingfonts,&count,&defonts);
 
364
 
 
365
  if(set)
 
366
  {
 
367
    if(*fontset)
 
368
        XFreeFontSet(d,*fontset);
 
369
    *fontset = XCreateFontSet(d,fontset_string,
 
370
                              &missingfonts,&count,&defonts);
 
371
    XFreeFontSet(d,set);
 
372
  }
 
373
  else
 
374
    return 1;
 
375
  
 
376
  for(i=0;i<count;i++)
 
377
  {
 
378
      printf("missing: %s for Window\n",&*missingfonts[i]);
 
379
  }
 
380
  return 0;
 
381
}
 
382
 
 
383
static int load_fontset(VTWidget w, char *normal_font, char *bold_font)
 
384
{
 
385
  XFontSetExtents *extents;
 
386
 
 
387
  if(fontset_load(XtDisplay(w),normal_font,&w->vt.fontset))
 
388
  {
 
389
    fprintf(stderr,"can't load fontset: %s\n",normal_font);
 
390
    w->vt.fontset_string = DEFAULT_FONTSET;
 
391
    fprintf(stderr,"switch to open default fontset: %s\n",DEFAULT_FONTSET);
 
392
    if(fontset_load(XtDisplay(w),w->vt.fontset_string,&w->vt.fontset))
 
393
    {
 
394
      fprintf(stderr,"can't load fontset: %s\n",normal_font);
 
395
      fprintf(stderr,"aborting\n");
 
396
      exit(1);
 
397
    }
 
398
  }
 
399
  else
 
400
  {
 
401
    if(bold_font)
 
402
        fontset_load(XtDisplay(w),bold_font,&w->vt.bold_fontset);
 
403
  }
 
404
 
 
405
  extents = XExtentsOfFontSet(w->vt.fontset);
 
406
 
 
407
  w->vt.cell_height_pixel= extents->max_logical_extent.height;
 
408
  w->vt.fontset_ascent = -extents->max_logical_extent.y;
 
409
  w->vt.cell_width_pixel = fontset_column_width_in_pixel(w->vt.fontset);
 
410
  
 
411
  return 0;
 
412
}
 
413
 
 
414
static void VTReshape(VTWidget w)
 
415
{
 
416
  w->vt.full_width =  w->vt.cell_width_pixel * w->vt.num_cols;
 
417
  w->vt.full_height = w->vt.cell_height_pixel * w->vt.num_rows;
 
418
 
 
419
  XtMakeResizeRequest((Widget)w,
 
420
                      w->vt.full_width + w->core.border_width*2,
 
421
                      w->vt.full_height + w->core.border_width*2+
 
422
                      VTGetStatusLineHeight((Widget)w),
 
423
                      NULL,NULL);
 
424
  UpdateIMPreeditAttributes(w);
 
425
  if(w->vt.status_line)
 
426
      UpdateIMStatusAttributes(w);
 
427
}
 
428
/*
 
429
 * Implementation
 
430
 */
 
431
/*
 
432
 * Function:
 
433
 *      TemplateInitialize
 
434
 *
 
435
 * Parameters:
 
436
 *      request - requested widget
 
437
 *      w       - the widget
 
438
 *      args    - arguments
 
439
 *      num_args - number of arguments
 
440
 *
 
441
 * Description:
 
442
 *      Initializes widget instance.
 
443
 */
 
444
/*ARGSUSED*/
 
445
static void
 
446
VTInitialize(Widget request, Widget w, ArgList args, Cardinal *num_args)
 
447
{
 
448
  XGCValues gcvalues;
 
449
  XtGCMask valueMask;
 
450
  VTWidget new = (VTWidget)w;
 
451
  VTWidget req = (VTWidget)request;
 
452
 
 
453
  new->vt.fontset = NULL;
 
454
  new->vt.cell_width_pixel = 0;
 
455
  new->vt.cell_height_pixel = 0;
 
456
  new->vt.fontset_ascent = 0;
 
457
 
 
458
  new->vt.pixmap_buffer = 0;
 
459
  new->vt.current_gc = NULL;
 
460
  new->vt.normal_gc = NULL;
 
461
  new->vt.reverse_gc = NULL;
 
462
 
 
463
  memmove(new->vt.textcolor,req->vt.textcolor,sizeof(Pixel)*MAX_NUM_COLOR);
 
464
  new->vt.foreground = req->vt.foreground;
 
465
  new->vt.fontset_string = req->vt.fontset_string ;
 
466
  new->vt.bold_fontset_string = req->vt.bold_fontset_string ;
 
467
  new->vt.bold_fontset = NULL;
 
468
  new->vt.fontset = NULL;
 
469
  load_fontset(new,new->vt.fontset_string,new->vt.bold_fontset_string);
 
470
 
 
471
      /* dummy size */
 
472
  new->core.width = 10 ;
 
473
  new->core.height = 10 ;
 
474
 
 
475
  valueMask = GCForeground | GCBackground;
 
476
  gcvalues.background = new->core.background_pixel;
 
477
  gcvalues.foreground = new->vt.foreground;
 
478
  new->vt.current_gc = new->vt.normal_gc = XtGetGC(w,valueMask,&gcvalues);
 
479
 
 
480
  gcvalues.foreground = new->vt.cursor_color;
 
481
  new->vt.cursor_gc = XtGetGC(w,valueMask,&gcvalues);
 
482
  
 
483
  
 
484
  gcvalues.background = new->vt.foreground;
 
485
  gcvalues.foreground = new->core.background_pixel;
 
486
  new->vt.reverse_gc = XtGetGC(w,valueMask,&gcvalues);
 
487
 
 
488
  new->vt.scrollbar = NULL;
 
489
  
 
490
  new->vt.im = NULL;
 
491
  new->vt.ic = NULL;
 
492
  new->vt.ex_cursor_position.x = -1;
 
493
  new->vt.ex_cursor_position.y = -1;
 
494
}
 
495
 
 
496
/* Realize function */
 
497
static void VTRealize(Widget w,
 
498
                      XtValueMask *value_mask,
 
499
                      XSetWindowAttributes *attributes)
 
500
{
 
501
  VTWidget new = (VTWidget)w;
 
502
  char *app_name;
 
503
  char *app_class;
 
504
 
 
505
  XtCreateWindow(w,InputOutput,CopyFromParent, *value_mask,attributes);
 
506
 
 
507
/*  XSetWindowBorderWidth(XtDisplay(w),XtWindow(w),new->vt.border_width); */
 
508
  XtVaSetValues(w,XtNborderColor,new->core.background_pixel,NULL);
 
509
  if(new->vt.input_method)
 
510
  {
 
511
    char modifier[256];
 
512
    strcpy(modifier,"@im=");
 
513
    strcat(modifier,new->vt.input_method);
 
514
    XSetLocaleModifiers(modifier);
 
515
  }
 
516
  else
 
517
      XSetLocaleModifiers(NULL);
 
518
 
 
519
      /* try to initialize IM */
 
520
  new->vt.im = NULL;
 
521
  IMCallback(XtDisplay(w),(XtPointer)new,NULL);
 
522
      /*
 
523
        Now We register callback for IM initialization
 
524
        even already opned IM, for re-run IM server 
 
525
      */
 
526
  XtGetApplicationNameAndClass(XtDisplay(w),&app_name,&app_class);
 
527
  XRegisterIMInstantiateCallback(
 
528
    XtDisplay(w),NULL,app_name,app_class,IMCallback,(XPointer)new); 
 
529
 
 
530
      { /*
 
531
          set window id, I need to extend to store DISPLAY as well
 
532
          this is just quick hack
 
533
         */
 
534
        char string[32];
 
535
        sprintf(string,"WINDOWID=%ld",XtWindow(new));
 
536
        putenv(string);
 
537
      }
 
538
  new->vt.io = init_io(new->vt.num_cols,new->vt.num_rows,new->vt.login_shell);
 
539
  new->vt.vtcore = VTCore_new(new->vt.io,
 
540
                              new->vt.num_cols,new->vt.num_rows,500);
 
541
 
 
542
 
 
543
      /* may need to add another event handler to change
 
544
         cursor, mouse pointer and so on so on..
 
545
  XtAddEventHandler(w, EnterWindowMask, FALSE,
 
546
                    HandleFocusChange, (Opaque)NULL);
 
547
  XtAddEventHandler(w, LeaveWindowMask, FALSE,
 
548
                    HandleFocusChange, (Opaque)NULL);
 
549
  XtAddEventHandler((Widget)new, PropertyChangeMask, FALSE,
 
550
                    PropertyChangeHandler, (Opaque)NULL);
 
551
      */
 
552
      /* Need for SetICFocus */
 
553
  XtAddEventHandler(w, FocusChangeMask, FALSE,
 
554
                    HandleFocusChange, (Opaque)NULL);
 
555
  XtAddEventHandler(w, 0L, True,
 
556
                    HandleNonMaskableEvent, (Opaque)NULL);
 
557
  new->vt.id = XtAppAddInput(XtWidgetToApplicationContext(new),
 
558
                             TtyTerminalIO_get_associated_fd(new->vt.io),
 
559
                             (XtPointer)XtInputReadMask,host_thread_dispatcher,
 
560
                             new->vt.vtcore);
 
561
  
 
562
  VTReshape(new);
 
563
}
 
564
 
 
565
/* Destroy function  */
 
566
static void VTDestroy(Widget w)
 
567
{
 
568
  VTWidget vt = (VTWidget)w;
 
569
 
 
570
  XtRemoveInput(vt->vt.id);
 
571
  XFreeGC(XtDisplay(w),vt->vt.normal_gc);
 
572
  XFreeGC(XtDisplay(w),vt->vt.reverse_gc);
 
573
/*  if(vt->vt.cursor_gc)
 
574
    XFreeGC(XtDisplay(w),vt->vt.cursor_gc);  */
 
575
  XFreeFontSet(XtDisplay(w),vt->vt.fontset);
 
576
  if(vt->vt.bold_fontset)
 
577
      XFreeFontSet(XtDisplay(w),vt->vt.bold_fontset);
 
578
  VTCore_destroy(vt->vt.vtcore);
 
579
  TtyTerminalIO_destroy(vt->vt.io);
 
580
}
 
581
/* Exposure function */
 
582
static void VTExpose(Widget w, XEvent *event, Region region)
 
583
{
 
584
  VTWidget new = (VTWidget)w;
 
585
  if(event->type == Expose || event->type == GraphicsExpose)
 
586
  {
 
587
    XExposeEvent *ev = (XExposeEvent *)event;
 
588
    int scol,srow;
 
589
    int ecol,erow;
 
590
 
 
591
        /* find top left cell's col */
 
592
    scol = ev->x / new->vt.cell_width_pixel;
 
593
        /* find bottom right cell's col */
 
594
    ecol = ((ev->x + ev->width) / new->vt.cell_width_pixel) + 1;
 
595
        /* find top left cell's row */
 
596
    srow = ev->y / new->vt.cell_height_pixel;
 
597
        /* find bottom right cell's row */
 
598
    erow = ((ev->y + ev->height) / new->vt.cell_height_pixel) + 1;
 
599
 
 
600
    VTCore_redraw(new->vt.vtcore,scol,srow,ecol,erow);
 
601
  }
 
602
  DrawStatusLine(new);
 
603
}
 
604
 
 
605
static void ScreenResized(VTWidget vt, int width, int height)
 
606
{
 
607
  int n_cols = width / vt->vt.cell_width_pixel;
 
608
  int n_rows = height / vt->vt.cell_height_pixel;
 
609
  if(vt->vt.status_line)
 
610
      n_rows--;
 
611
  vt->vt.num_cols = n_cols;
 
612
  vt->vt.num_rows = n_rows;
 
613
  vt->vt.full_width =  n_cols * vt->vt.cell_width_pixel;
 
614
  vt->vt.full_height = n_rows * vt->vt.cell_height_pixel;
 
615
 
 
616
  UpdateIMPreeditAttributes(vt);
 
617
  if(vt->vt.status_line)
 
618
      UpdateIMStatusAttributes(vt);
 
619
  DrawStatusLine(vt);
 
620
  VTCore_set_screen_size(vt->vt.vtcore,n_cols,n_rows);
 
621
}
 
622
 
 
623
 
 
624
/* Resize function */
 
625
static void VTResize(Widget widget)
 
626
{
 
627
  VTWidget w = (VTWidget)widget;
 
628
  ScreenResized(w,
 
629
                w->core.width-w->core.border_width*2,
 
630
                w->core.height-w->core.border_width*2);
 
631
}
 
632
 
 
633
/* Event Handler */
 
634
 
 
635
static
 
636
void HandleFocusChange(Widget w,XtPointer client_data, XEvent *event,
 
637
                       Boolean *continue_dispatch)
 
638
{
 
639
  VTWidget vt = (VTWidget)w;
 
640
 
 
641
  if(event->type == FocusIn )
 
642
  {
 
643
    if (vt->vt.ic)
 
644
        XSetICFocus(vt->vt.ic); 
 
645
  
 
646
    *continue_dispatch = False;
 
647
  }
 
648
  else if (event->type == FocusOut )
 
649
  {
 
650
    if (vt->vt.ic)
 
651
        XUnsetICFocus(vt->vt.ic);
 
652
    *continue_dispatch = False;
 
653
  }
 
654
  else
 
655
  {
 
656
        /*printf("event->type == %d\n",event->type); */
 
657
  }
 
658
}
 
659
 
 
660
static void HandleNonMaskableEvent(Widget w,XtPointer client_data,
 
661
                                   XEvent *event, Boolean *continue_dispatch)
 
662
{
 
663
  VTWidget vt = (VTWidget)w;
 
664
  XExposeEvent *e = (XExposeEvent *)event;
 
665
 
 
666
  switch(event->type)
 
667
  {
 
668
    case GraphicsExpose:
 
669
        VTExpose(w,event,(Region)NULL);
 
670
        break;
 
671
    default:
 
672
        /* do nothing */;
 
673
  }
 
674
}
 
675
 
 
676
/* Utility Methods */
 
677
int VTGetCellWidth(Widget w)
 
678
{
 
679
  VTWidget vt = (VTWidget)w;
 
680
  return vt->vt.cell_width_pixel;
 
681
}
 
682
 
 
683
int VTGetCellHeight(Widget w)
 
684
{
 
685
  VTWidget vt = (VTWidget)w;
 
686
  return vt->vt.cell_height_pixel;
 
687
}
 
688
 
 
689
int VTGetStatusLineHeight(Widget w)
 
690
{
 
691
  VTWidget vt = (VTWidget)w;
 
692
  return vt->vt.status_line ? vt->vt.cell_height_pixel : 0;
 
693
}
 
694
 
 
695
void VTSelectFont(Widget w, int font_num)
 
696
{
 
697
  VTWidget vt = (VTWidget)w;
 
698
 
 
699
  if(font_num < 1 || NUM_FONTSETS < font_num )
 
700
      load_fontset(vt,vt->vt.fontset_string,vt->vt.bold_fontset_string);
 
701
  else
 
702
      load_fontset(vt,vt->vt.fontsets[font_num-1],NULL);
 
703
  vt->vt.ex_cursor_position.x = -1;
 
704
  vt->vt.ex_cursor_position.y = -1;
 
705
  UpdateFontset(vt);
 
706
  VTReshape(vt);
 
707
}
 
708
 
 
709
void VTSwapVideo(Widget w)
 
710
{
 
711
  reverse_video((VTWidget)w);
 
712
}
 
713
 
 
714
void VTSetConnectionClosedCallback(Widget w, void (*proc)())
 
715
{
 
716
  VTWidget vt = (VTWidget)w;
 
717
  VTCore_set_exit_callback(vt->vt.vtcore, proc);
 
718
}
 
719
 
 
720
void  VTSetVisualBell(Widget w, Boolean on)
 
721
{
 
722
  VTWidget vt = (VTWidget)w;
 
723
  vt->vt.visual_bell_on = on;
 
724
}
 
725
 
 
726
Boolean VTIsVisualBell(Widget w)
 
727
{
 
728
  VTWidget vt = (VTWidget)w;
 
729
  return vt->vt.visual_bell_on;
 
730
}
 
731