~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/hw/xfree86/XF86Setup/tclxkbui.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XConsortium: tclxkbui.c /main/2 1996/10/19 19:06:46 kaleb $ */
 
2
 
 
3
 
 
4
 
 
5
 
 
6
 
 
7
/* $XFree86: xc/programs/Xserver/hw/xfree86/XF86Setup/tclxkbui.c,v 3.2 1996/12/27 06:54:25 dawes Exp $ */
 
8
/* 
 
9
 * tkXkbUIWin.c --
 
10
 *
 
11
 *      This module implements "xkbview" widgets.
 
12
 *      A "xkbview" is a widget that uses the xkbui library to
 
13
 *      display a representation of the keyboard as described by
 
14
 *      the XKB geometry.
 
15
 *
 
16
 * Copyright 1996 Joseph Moss
 
17
 *
 
18
 * The file is derived from the sample widget code tkSquare.c, which is
 
19
 * Copyright (c) 1991-1994 The Regents of the University of California.
 
20
 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
 
21
 *
 
22
 * See the file "license.terms" for information on usage and redistribution
 
23
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 
24
 */
 
25
 
 
26
#include <Xos.h>
 
27
#include <Xfuncs.h>
 
28
#include <tk.h>
 
29
#include <X11/XKBlib.h>
 
30
#include <X11/extensions/XKBgeom.h>
 
31
#include <X11/extensions/XKBui.h>
 
32
 
 
33
#define DEF_XKBUI_HEIGHT "100"
 
34
#define DEF_XKBUI_WIDTH  "300"
 
35
 
 
36
extern char *   TkInitXkbUIWin _ANSI_ARGS_((Tcl_Interp *interp,
 
37
                        Tk_Window tkwin, int toplevel, int argc,
 
38
                        char *argv[]));
 
39
 
 
40
extern XkbDescPtr       GetXkbDescPtr _ANSI_ARGS_((Tcl_Interp *interp,
 
41
                                char *handle));
 
42
 
 
43
/*
 
44
 * A data structure of the following type is kept for each xkbview
 
45
 * widget managed by this file:
 
46
 */
 
47
 
 
48
typedef struct {
 
49
    Tk_Window tkwin;            /* Window that embodies the xkbview.  NULL
 
50
                                 * means window has been deleted but
 
51
                                 * widget record hasn't been cleaned up yet. */
 
52
    Display *display;           /* X's token for the window's display. */
 
53
    Tcl_Interp *interp;         /* Interpreter associated with widget. */
 
54
    Tcl_Command widgetCmd;      /* Token for xkbview's widget command. */
 
55
    int width, height;          /* Window height & width */
 
56
 
 
57
    /*
 
58
     * Information used when displaying widget:
 
59
     */
 
60
 
 
61
    int borderWidth;            /* Width of 3-D border around whole widget. */
 
62
    Tk_3DBorder bgBorder;       /* Used for drawing background. */
 
63
    int relief;                 /* Indicates whether window as a whole is
 
64
                                 * raised, sunken, or flat. */
 
65
    GC gc;                      /* Graphics context for copying from
 
66
                                 * off-screen pixmap onto screen. */
 
67
    int doubleBuffer;           /* Non-zero means double-buffer redisplay
 
68
                                 * with pixmap;  zero means draw straight
 
69
                                 * onto the display. */
 
70
    int updatePending;          /* Non-zero means a call to XkbUIWinDisplay
 
71
                                 * has already been scheduled. */
 
72
    char *xkbHandle;            /* Handle of XkbDescRec */
 
73
    XkbUI_ViewPtr view;         /* XkbUI view structure */
 
74
 
 
75
} XkbUIWin;
 
76
 
 
77
/*
 
78
 * Information used for argv parsing.
 
79
 */
 
80
 
 
81
static Tk_ConfigSpec configSpecs[] = {
 
82
    {TK_CONFIG_BORDER, "-background", "background", "Background",
 
83
        "#cdb79e", Tk_Offset(XkbUIWin, bgBorder), TK_CONFIG_COLOR_ONLY},
 
84
    {TK_CONFIG_BORDER, "-background", "background", "Background",
 
85
        "white", Tk_Offset(XkbUIWin, bgBorder), TK_CONFIG_MONO_ONLY},
 
86
    {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
 
87
        (char *) NULL, 0, 0},
 
88
    {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
 
89
        (char *) NULL, 0, 0},
 
90
    {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
 
91
        "2", Tk_Offset(XkbUIWin, borderWidth), 0},
 
92
    {TK_CONFIG_INT, "-dbl", "doubleBuffer", "DoubleBuffer",
 
93
        "1", Tk_Offset(XkbUIWin, doubleBuffer), 0},
 
94
    {TK_CONFIG_PIXELS, "-height", "height", "Height",
 
95
        DEF_XKBUI_HEIGHT, Tk_Offset(XkbUIWin, height), 0},
 
96
    {TK_CONFIG_STRING, "-keyboard", "keyboard", (char *) NULL,
 
97
        "xkb1", Tk_Offset(XkbUIWin, xkbHandle), 0},
 
98
    {TK_CONFIG_SYNONYM, "-kbd", "keyboard", (char *) NULL,
 
99
        (char *) NULL, 0, 0},
 
100
    {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
 
101
        "raised", Tk_Offset(XkbUIWin, relief), 0},
 
102
    {TK_CONFIG_PIXELS, "-width", "width", "Width",
 
103
        DEF_XKBUI_WIDTH, Tk_Offset(XkbUIWin, width), 0},
 
104
    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
 
105
        (char *) NULL, 0, 0}
 
106
};
 
107
 
 
108
/*
 
109
 * Forward declarations for procedures defined later in this file:
 
110
 */
 
111
 
 
112
static void             XkbUIWinCmdDeletedProc _ANSI_ARGS_((
 
113
                            ClientData clientData));
 
114
static int              XkbUIWinConfigure _ANSI_ARGS_((Tcl_Interp *interp,
 
115
                            XkbUIWin *xkbui, int argc, char **argv,
 
116
                            int flags));
 
117
static void             XkbUIWinDestroy _ANSI_ARGS_((ClientData clientData));
 
118
static void             XkbUIWinDisplay _ANSI_ARGS_((ClientData clientData));
 
119
static void             XkbUIWinEventProc _ANSI_ARGS_((ClientData clientData,
 
120
                            XEvent *eventPtr));
 
121
static int              XkbUIWinWidgetCmd _ANSI_ARGS_((ClientData clientData,
 
122
                            Tcl_Interp *, int argc, char **argv));
 
123
 
 
124
/*
 
125
 *--------------------------------------------------------------
 
126
 *
 
127
 * XkbUIWinCmd --
 
128
 *
 
129
 *      This procedure is invoked to process the "xkbview" Tcl
 
130
 *      command.  It creates a new "xkbview" widget.
 
131
 *
 
132
 * Results:
 
133
 *      A standard Tcl result.
 
134
 *
 
135
 * Side effects:
 
136
 *      A new widget is created and configured.
 
137
 *
 
138
 *--------------------------------------------------------------
 
139
 */
 
140
 
 
141
int
 
142
XkbUIWinCmd(clientData, interp, argc, argv)
 
143
    ClientData clientData;      /* Main window associated with
 
144
                                 * interpreter. */
 
145
    Tcl_Interp *interp;         /* Current interpreter. */
 
146
    int argc;                   /* Number of arguments. */
 
147
    char **argv;                /* Argument strings. */
 
148
{
 
149
    Tk_Window main = (Tk_Window) clientData;
 
150
    XkbUIWin *xkbuiPtr;
 
151
    Tk_Window tkwin;
 
152
 
 
153
    if (argc < 2) {
 
154
        Tcl_AppendResult(interp, "wrong # args:  should be \"",
 
155
                argv[0], " pathName ?options?\"", (char *) NULL);
 
156
        return TCL_ERROR;
 
157
    }
 
158
 
 
159
    tkwin = Tk_CreateWindowFromPath(interp, main, argv[1], (char *) NULL);
 
160
    if (tkwin == NULL) {
 
161
        return TCL_ERROR;
 
162
    }
 
163
    Tk_SetClass(tkwin, "Xkbui");
 
164
 
 
165
    /*
 
166
     * Allocate and initialize the widget record.
 
167
     */
 
168
 
 
169
    xkbuiPtr = (XkbUIWin *) ckalloc(sizeof(XkbUIWin));
 
170
    xkbuiPtr->tkwin = tkwin;
 
171
    xkbuiPtr->display = Tk_Display(tkwin);
 
172
    xkbuiPtr->interp = interp;
 
173
    xkbuiPtr->widgetCmd = Tcl_CreateCommand(interp,
 
174
            Tk_PathName(xkbuiPtr->tkwin), XkbUIWinWidgetCmd,
 
175
            (ClientData) xkbuiPtr, XkbUIWinCmdDeletedProc);
 
176
    xkbuiPtr->height = -1;
 
177
    xkbuiPtr->width = -1;
 
178
    xkbuiPtr->borderWidth = 0;
 
179
    xkbuiPtr->bgBorder = NULL;
 
180
    xkbuiPtr->relief = TK_RELIEF_FLAT;
 
181
    xkbuiPtr->gc = None;
 
182
    xkbuiPtr->doubleBuffer = 1;
 
183
    xkbuiPtr->updatePending = 0;
 
184
    xkbuiPtr->xkbHandle = NULL;
 
185
    xkbuiPtr->view = NULL;
 
186
 
 
187
    Tk_CreateEventHandler(xkbuiPtr->tkwin, ExposureMask|StructureNotifyMask,
 
188
            XkbUIWinEventProc, (ClientData) xkbuiPtr);
 
189
    if (XkbUIWinConfigure(interp, xkbuiPtr, argc-2, argv+2, 0) != TCL_OK) {
 
190
        Tk_DestroyWindow(xkbuiPtr->tkwin);
 
191
        return TCL_ERROR;
 
192
    }
 
193
 
 
194
    interp->result = Tk_PathName(xkbuiPtr->tkwin);
 
195
    return TCL_OK;
 
196
}
 
197
 
 
198
/*
 
199
 *--------------------------------------------------------------
 
200
 *
 
201
 * XkbUIWinWidgetCmd --
 
202
 *
 
203
 *      This procedure is invoked to process the Tcl command
 
204
 *      that corresponds to a widget managed by this module.
 
205
 *      See the user documentation for details on what it does.
 
206
 *
 
207
 * Results:
 
208
 *      A standard Tcl result.
 
209
 *
 
210
 * Side effects:
 
211
 *      See the user documentation.
 
212
 *
 
213
 *--------------------------------------------------------------
 
214
 */
 
215
 
 
216
static int
 
217
XkbUIWinWidgetCmd(clientData, interp, argc, argv)
 
218
    ClientData clientData;              /* Information about xkbview widget. */
 
219
    Tcl_Interp *interp;                 /* Current interpreter. */
 
220
    int argc;                           /* Number of arguments. */
 
221
    char **argv;                        /* Argument strings. */
 
222
{
 
223
    XkbUIWin *xkbuiPtr = (XkbUIWin *) clientData;
 
224
    int result = TCL_OK;
 
225
    size_t length;
 
226
    char c;
 
227
 
 
228
    if (argc < 2) {
 
229
        Tcl_AppendResult(interp, "wrong # args: should be \"",
 
230
                argv[0], " option ?arg arg ...?\"", (char *) NULL);
 
231
        return TCL_ERROR;
 
232
    }
 
233
    Tk_Preserve((ClientData) xkbuiPtr);
 
234
    c = argv[1][0];
 
235
    length = strlen(argv[1]);
 
236
    if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0)
 
237
            && (length >= 2)) {
 
238
        if (argc != 3) {
 
239
            Tcl_AppendResult(interp, "wrong # args: should be \"",
 
240
                    argv[0], " cget option\"",
 
241
                    (char *) NULL);
 
242
            goto error;
 
243
        }
 
244
        result = Tk_ConfigureValue(interp, xkbuiPtr->tkwin, configSpecs,
 
245
                (char *) xkbuiPtr, argv[2], 0);
 
246
    } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)
 
247
            && (length >= 2)) {
 
248
        if (argc == 2) {
 
249
            result = Tk_ConfigureInfo(interp, xkbuiPtr->tkwin, configSpecs,
 
250
                    (char *) xkbuiPtr, (char *) NULL, 0);
 
251
        } else if (argc == 3) {
 
252
            result = Tk_ConfigureInfo(interp, xkbuiPtr->tkwin, configSpecs,
 
253
                    (char *) xkbuiPtr, argv[2], 0);
 
254
        } else {
 
255
            result = XkbUIWinConfigure(interp, xkbuiPtr, argc-2, argv+2,
 
256
                    TK_CONFIG_ARGV_ONLY);
 
257
        }
 
258
    } else if ((c == 'r') && (strncmp(argv[1], "refresh", length) == 0)
 
259
            && (length >= 2)) {
 
260
        /* Nothing - The call to Tk_DoWhenIdle below takes care of this */
 
261
        ;
 
262
    } else {
 
263
        Tcl_AppendResult(interp, "bad option \"", argv[1],
 
264
                "\":  must be cget, configure, or refresh",
 
265
                (char *) NULL);
 
266
        goto error;
 
267
    }
 
268
    if (!xkbuiPtr->updatePending) {
 
269
        Tk_DoWhenIdle(XkbUIWinDisplay, (ClientData) xkbuiPtr);
 
270
        xkbuiPtr->updatePending = 1;
 
271
    }
 
272
    Tk_Release((ClientData) xkbuiPtr);
 
273
    return result;
 
274
 
 
275
    error:
 
276
    Tk_Release((ClientData) xkbuiPtr);
 
277
    return TCL_ERROR;
 
278
}
 
279
 
 
280
/*
 
281
 *----------------------------------------------------------------------
 
282
 *
 
283
 * XkbUIWinConfigure --
 
284
 *
 
285
 *      This procedure is called to process an argv/argc list in
 
286
 *      conjunction with the Tk option database to configure (or
 
287
 *      reconfigure) a xkbview widget.
 
288
 *
 
289
 * Results:
 
290
 *      The return value is a standard Tcl result.  If TCL_ERROR is
 
291
 *      returned, then interp->result contains an error message.
 
292
 *
 
293
 * Side effects:
 
294
 *      Configuration information, such as colors, border width,
 
295
 *      etc. get set for xkbuiPtr;  old resources get freed,
 
296
 *      if there were any.
 
297
 *
 
298
 *----------------------------------------------------------------------
 
299
 */
 
300
 
 
301
static int
 
302
XkbUIWinConfigure(interp, xkbuiPtr, argc, argv, flags)
 
303
    Tcl_Interp *interp;                 /* Used for error reporting. */
 
304
    XkbUIWin *xkbuiPtr;                 /* Information about widget. */
 
305
    int argc;                           /* Number of valid entries in argv. */
 
306
    char **argv;                        /* Arguments. */
 
307
    int flags;                          /* Flags to pass to
 
308
                                         * Tk_ConfigureWidget. */
 
309
{
 
310
    if (Tk_ConfigureWidget(interp, xkbuiPtr->tkwin, configSpecs,
 
311
            argc, argv, (char *) xkbuiPtr, flags) != TCL_OK) {
 
312
        return TCL_ERROR;
 
313
    }
 
314
 
 
315
    /*
 
316
     * Set the background for the window and create a graphics context
 
317
     * for use during redisplay.
 
318
     */
 
319
 
 
320
    Tk_SetWindowBackground(xkbuiPtr->tkwin,
 
321
            Tk_3DBorderColor(xkbuiPtr->bgBorder)->pixel);
 
322
    if ((xkbuiPtr->gc == None) && (xkbuiPtr->doubleBuffer)) {
 
323
        XGCValues gcValues;
 
324
        gcValues.function = GXcopy;
 
325
        gcValues.graphics_exposures = False;
 
326
        xkbuiPtr->gc = Tk_GetGC(xkbuiPtr->tkwin,
 
327
                GCFunction|GCGraphicsExposures, &gcValues);
 
328
    }
 
329
 
 
330
    /*
 
331
     * Register the desired geometry for the window.  Then arrange for
 
332
     * the window to be redisplayed.
 
333
     */
 
334
 
 
335
    Tk_GeometryRequest(xkbuiPtr->tkwin, 200, 150);
 
336
    Tk_SetInternalBorder(xkbuiPtr->tkwin, xkbuiPtr->borderWidth);
 
337
    if (!xkbuiPtr->updatePending) {
 
338
        Tk_DoWhenIdle(XkbUIWinDisplay, (ClientData) xkbuiPtr);
 
339
        xkbuiPtr->updatePending = 1;
 
340
    }
 
341
    return TCL_OK;
 
342
}
 
343
 
 
344
/*
 
345
 *--------------------------------------------------------------
 
346
 *
 
347
 * XkbUIWinEventProc --
 
348
 *
 
349
 *      This procedure is invoked by the Tk dispatcher for various
 
350
 *      events on xkbviews.
 
351
 *
 
352
 * Results:
 
353
 *      None.
 
354
 *
 
355
 * Side effects:
 
356
 *      When the window gets deleted, internal structures get
 
357
 *      cleaned up.  When it gets exposed, it is redisplayed.
 
358
 *
 
359
 *--------------------------------------------------------------
 
360
 */
 
361
 
 
362
static void
 
363
XkbUIWinEventProc(clientData, eventPtr)
 
364
    ClientData clientData;      /* Information about window. */
 
365
    XEvent *eventPtr;           /* Information about event. */
 
366
{
 
367
    XkbUIWin *xkbuiPtr = (XkbUIWin *) clientData;
 
368
 
 
369
    if (eventPtr->type == Expose) {
 
370
        if (!xkbuiPtr->updatePending) {
 
371
            Tk_DoWhenIdle(XkbUIWinDisplay, (ClientData) xkbuiPtr);
 
372
            xkbuiPtr->updatePending = 1;
 
373
        }
 
374
    } else if (eventPtr->type == ConfigureNotify) {
 
375
        if (!xkbuiPtr->updatePending) {
 
376
            Tk_DoWhenIdle(XkbUIWinDisplay, (ClientData) xkbuiPtr);
 
377
            xkbuiPtr->updatePending = 1;
 
378
        }
 
379
    } else if (eventPtr->type == DestroyNotify) {
 
380
        if (xkbuiPtr->tkwin != NULL) {
 
381
            xkbuiPtr->tkwin = NULL;
 
382
            Tcl_DeleteCommand(xkbuiPtr->interp,
 
383
                    Tcl_GetCommandName(xkbuiPtr->interp,
 
384
                    xkbuiPtr->widgetCmd));
 
385
        }
 
386
        if (xkbuiPtr->updatePending) {
 
387
            Tk_CancelIdleCall(XkbUIWinDisplay, (ClientData) xkbuiPtr);
 
388
        }
 
389
        Tk_EventuallyFree((ClientData) xkbuiPtr,
 
390
                          (Tcl_FreeProc *)XkbUIWinDestroy);
 
391
    }
 
392
}
 
393
 
 
394
/*
 
395
 *----------------------------------------------------------------------
 
396
 *
 
397
 * XkbUIWinCmdDeletedProc --
 
398
 *
 
399
 *      This procedure is invoked when a widget command is deleted.  If
 
400
 *      the widget isn't already in the process of being destroyed,
 
401
 *      this command destroys it.
 
402
 *
 
403
 * Results:
 
404
 *      None.
 
405
 *
 
406
 * Side effects:
 
407
 *      The widget is destroyed.
 
408
 *
 
409
 *----------------------------------------------------------------------
 
410
 */
 
411
 
 
412
static void
 
413
XkbUIWinCmdDeletedProc(clientData)
 
414
    ClientData clientData;      /* Pointer to widget record for widget. */
 
415
{
 
416
    XkbUIWin *xkbuiPtr = (XkbUIWin *) clientData;
 
417
    Tk_Window tkwin = xkbuiPtr->tkwin;
 
418
 
 
419
    /*
 
420
     * This procedure could be invoked either because the window was
 
421
     * destroyed and the command was then deleted (in which case tkwin
 
422
     * is NULL) or because the command was deleted, and then this procedure
 
423
     * destroys the widget.
 
424
     */
 
425
 
 
426
    if (tkwin != NULL) {
 
427
        xkbuiPtr->tkwin = NULL;
 
428
        Tk_DestroyWindow(tkwin);
 
429
    }
 
430
}
 
431
 
 
432
/*
 
433
 *--------------------------------------------------------------
 
434
 *
 
435
 * XkbUIWinDisplay --
 
436
 *
 
437
 *      This procedure redraws the contents of a xkbview window.
 
438
 *      It is invoked as a do-when-idle handler, so it only runs
 
439
 *      when there's nothing else for the application to do.
 
440
 *
 
441
 * Results:
 
442
 *      None.
 
443
 *
 
444
 * Side effects:
 
445
 *      Information appears on the screen.
 
446
 *
 
447
 *--------------------------------------------------------------
 
448
 */
 
449
 
 
450
static void
 
451
XkbUIWinDisplay(clientData)
 
452
    ClientData clientData;      /* Information about window. */
 
453
{
 
454
    XkbUIWin *xkbuiPtr = (XkbUIWin *) clientData;
 
455
    Tk_Window tkwin = xkbuiPtr->tkwin;
 
456
    Pixmap pm = None;
 
457
    Drawable d;
 
458
    XkbDescPtr xkb;
 
459
    XkbUI_ViewOptsRec opts;
 
460
    int width, height, bd;
 
461
 
 
462
    xkbuiPtr->updatePending = 0;
 
463
    if (!Tk_IsMapped(tkwin)) {
 
464
        return;
 
465
    }
 
466
 
 
467
    /*
 
468
     * Create a pixmap for double-buffering, if necessary.
 
469
     */
 
470
 
 
471
    if (xkbuiPtr->doubleBuffer) {
 
472
        pm = XCreatePixmap(Tk_Display(tkwin), Tk_WindowId(tkwin),
 
473
                (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin),
 
474
                (unsigned) DefaultDepthOfScreen(Tk_Screen(tkwin)));
 
475
        d = pm;
 
476
    } else {
 
477
        d = Tk_WindowId(tkwin);
 
478
    }
 
479
 
 
480
    /*
 
481
     * Redraw the widget's background and border.
 
482
     */
 
483
 
 
484
    Tk_Fill3DRectangle(tkwin, d, xkbuiPtr->bgBorder, 0, 0, Tk_Width(tkwin),
 
485
            Tk_Height(tkwin), xkbuiPtr->borderWidth, xkbuiPtr->relief);
 
486
 
 
487
    /*
 
488
     * Display the keyboard.
 
489
     */
 
490
 
 
491
    bzero((char *)&opts, sizeof(opts));
 
492
    bd = 0;
 
493
    if (xkbuiPtr->relief != TK_RELIEF_FLAT)
 
494
        bd = xkbuiPtr->borderWidth;
 
495
    opts.present = XkbUI_SizeMask|XkbUI_ColormapMask
 
496
                        |XkbUI_MarginMask|XkbUI_OffsetMask;
 
497
    opts.margin_width = opts.margin_height = 0;
 
498
    opts.viewport.x   = opts.viewport.y    = bd;
 
499
    width  = opts.viewport.width  = Tk_Width(tkwin) - 2*bd;
 
500
    height = opts.viewport.height = Tk_Height(tkwin) - 2*bd;
 
501
    opts.cmap = Tk_Colormap(tkwin);
 
502
    xkb = GetXkbDescPtr(xkbuiPtr->interp, xkbuiPtr->xkbHandle);
 
503
    if (xkb != NULL) {
 
504
        if (xkbuiPtr->view)
 
505
            ckfree(xkbuiPtr->view);
 
506
        xkbuiPtr->view= XkbUI_Init(xkbuiPtr->display, d,
 
507
                                        width, height, xkb, &opts);
 
508
        if (xkbuiPtr->view)
 
509
            XkbUI_DrawRegion(xkbuiPtr->view,NULL);
 
510
    }
 
511
 
 
512
    /*
 
513
     * If double-buffered, copy to the screen and release the pixmap.
 
514
     */
 
515
 
 
516
    if (xkbuiPtr->doubleBuffer) {
 
517
        XCopyArea(Tk_Display(tkwin), pm, Tk_WindowId(tkwin), xkbuiPtr->gc,
 
518
                0, 0, (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin),
 
519
                0, 0);
 
520
        XFreePixmap(Tk_Display(tkwin), pm);
 
521
    }
 
522
}
 
523
 
 
524
/*
 
525
 *----------------------------------------------------------------------
 
526
 *
 
527
 * XkbUIWinDestroy --
 
528
 *
 
529
 *      This procedure is invoked by Tk_EventuallyFree or Tk_Release
 
530
 *      to clean up the internal structure of a xkbview at a safe time
 
531
 *      (when no-one is using it anymore).
 
532
 *
 
533
 * Results:
 
534
 *      None.
 
535
 *
 
536
 * Side effects:
 
537
 *      Everything associated with the xkbview is freed up.
 
538
 *
 
539
 *----------------------------------------------------------------------
 
540
 */
 
541
 
 
542
static void
 
543
XkbUIWinDestroy(clientData)
 
544
    ClientData clientData;      /* Info about xkbview widget. */
 
545
{
 
546
    XkbUIWin *xkbuiPtr = (XkbUIWin *) clientData;
 
547
 
 
548
    Tk_FreeOptions(configSpecs, (char *) xkbuiPtr, xkbuiPtr->display, 0);
 
549
    if (xkbuiPtr->gc != None) {
 
550
        Tk_FreeGC(xkbuiPtr->display, xkbuiPtr->gc);
 
551
    }
 
552
    if (xkbuiPtr->view != NULL) {
 
553
        ckfree(xkbuiPtr->view);
 
554
    }
 
555
    ckfree((char *) xkbuiPtr);
 
556
}
 
557