1/* $XConsortium: XKBui.c /main/2 1995/12/07 21:18:19 kaleb $ */
2/************************************************************
3 Copyright (c) 1996 by Silicon Graphics Computer Systems, Inc.
4
5 Permission to use, copy, modify, and distribute this
6 software and its documentation for any purpose and without
7 fee is hereby granted, provided that the above copyright
8 notice appear in all copies and that both that copyright
9 notice and this permission notice appear in supporting
10 documentation, and that the name of Silicon Graphics not be
11 used in advertising or publicity pertaining to distribution
12 of the software without specific prior written permission.
13 Silicon Graphics makes no representation about the suitability
14 of this software for any purpose. It is provided "as is"
15 without any express or implied warranty.
16
17 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
18 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
20 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
21 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
23 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
24 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25
26 ********************************************************/
27/* $XFree86: xc/lib/xkbui/XKBui.c,v 3.6 1999/06/20 07:14:08 dawes Exp $ */
28
29#include <X11/Xos.h>
30#include <stdio.h>
31#include <stdlib.h>
32
33#if defined(SVR4) && defined(i386) && !defined(_XOPEN_SOURCE)
34#  define _XOPEN_SOURCE
35#  include <math.h>
36#  undef _XOPEN_SOURCE
37#else
38#  include <math.h>
39#endif /* _XOPEN_SOURCE */
40
41#include <X11/Xfuncs.h>
42#include "XKBuiPriv.h"
43#include <X11/extensions/XKBfile.h>
44
45#ifndef M_PI
46#  define M_PI	3.141592653589793238462
47#endif
48
49static XkbUI_ViewOptsRec dfltOpts = {
50	XkbUI_AllViewOptsMask	/* present */,
51	1			/* fg */,
52	0			/* bg */,
53	XkbUI_KeyNames		/* label_mode */,
54	0 			/* color_mode */,
55	{
56		0	/* viewport.x */,
57		0	/* viewport.y */,
58		640	/* viewport.width */,
59		480	/* viewport.height */
60	},
61	10, 10,		/* margin_width, margin_height */
62	None
63};
64
65XkbUI_ViewPtr
66XkbUI_SimpleInit(Display *dpy,Window win,int width,int height)
67{
68XkbDescPtr	xkb;
69
70    if ((!dpy)||(win==None)||(width<1)||(height<1))
71	return NULL;
72    xkb= XkbGetKeyboard(dpy,XkbGBN_AllComponentsMask,XkbUseCoreKbd);
73    if (!xkb)
74	return NULL;
75    return XkbUI_Init(dpy,win,width,height,xkb,NULL);
76}
77
78static void
79_XkbUI_AllocateColors(XkbUI_ViewPtr view)
80{
81register int i;
82Display *	dpy;
83XColor		sdef,xdef;
84XkbDescPtr	xkb;
85
86    dpy= view->dpy;
87    xkb= view->xkb;
88    if (view->opts.cmap==None)
89	view->opts.cmap= DefaultColormap(dpy,DefaultScreen(dpy));
90    for (i=0;i<xkb->geom->num_colors;i++) {
91	char *spec;
92	Bool		found;
93
94	spec= xkb->geom->colors[i].spec;
95	found= False;
96	if (XAllocNamedColor(view->dpy,view->opts.cmap,spec,&sdef,&xdef)) {
97	    xkb->geom->colors[i].pixel= sdef.pixel;
98#ifdef DEBUG
99	    fprintf(stderr,"got pixel %lu for \"%s\"\n",sdef.pixel,spec);
100#endif
101	    found= True;
102	}
103	if ((!found)&&(XkbLookupCanonicalRGBColor(spec,&sdef))) {
104	    char buf[20];
105	    sprintf(buf,"#%02x%02x%02x",(sdef.red>>8)&0xff,
106						(sdef.green>>8)&0xff,
107						(sdef.blue>>8)&0xff);
108	    if (XAllocNamedColor(view->dpy,view->opts.cmap,buf,&sdef,&xdef)) {
109		xkb->geom->colors[i].pixel= sdef.pixel;
110#ifdef DEBUG
111		fprintf(stderr,"got pixel %lu for \"%s\"\n",sdef.pixel,spec);
112#endif
113		found= True;
114	    }
115	}
116	if (!found) {
117	    xkb->geom->colors[i].pixel= view->opts.fg;
118	    fprintf(stderr,"Couldn't allocate color \"%s\"\n",spec);
119	}
120    }
121    return;
122}
123
124XkbUI_ViewPtr
125XkbUI_Init(	Display *		dpy,
126		Window			win,
127		int			width,
128		int			height,
129		XkbDescPtr		xkb,
130		XkbUI_ViewOptsPtr	opts)
131{
132XGCValues	xgcv;
133XkbUI_ViewPtr	view;
134int		scrn;
135
136    if ((!dpy)||(!xkb)||(!xkb->geom)||(win==None)||(width<1)||(height<1))
137	return NULL;
138    view= _XkbTypedCalloc(1,XkbUI_ViewRec);
139    if (!view)
140	return NULL;
141    scrn= DefaultScreen(dpy);
142    view->dpy= 			dpy;
143    view->xkb= 			xkb;
144    view->win=			win;
145    view->opts= 		dfltOpts;
146    view->opts.fg=		WhitePixel(dpy,scrn);
147    view->opts.bg=		BlackPixel(dpy,scrn);
148    view->opts.viewport.x=	0;
149    view->opts.viewport.y=	0;
150    view->opts.viewport.width=	width;
151    view->opts.viewport.height=	height;
152    if ((opts)&&(opts->present)) {
153	if (opts->present&XkbUI_BackgroundMask)
154	    view->opts.bg=		opts->bg;
155	if (opts->present&XkbUI_ForegroundMask)
156	    view->opts.fg=		opts->fg;
157	if (opts->present&XkbUI_LabelModeMask)
158	    view->opts.label_mode=	opts->label_mode;
159	if (opts->present&XkbUI_ColorModeMask)
160	    view->opts.color_mode=	opts->color_mode;
161	if (opts->present&XkbUI_WidthMask)
162	    view->opts.viewport.width=	opts->viewport.width;
163	if (opts->present&XkbUI_HeightMask)
164	    view->opts.viewport.height=	opts->viewport.height;
165	if (opts->present&XkbUI_XOffsetMask)
166	    view->opts.viewport.x=	opts->viewport.x;
167	if (opts->present&XkbUI_YOffsetMask)
168	    view->opts.viewport.y=	opts->viewport.y;
169	if (opts->present&XkbUI_MarginWidthMask)
170	    view->opts.margin_width=	opts->margin_width;
171	if (opts->present&XkbUI_MarginHeightMask)
172	    view->opts.margin_height=	opts->margin_height;
173	if (opts->present&XkbUI_ColormapMask)
174	    view->opts.cmap=		opts->cmap;
175    }
176    view->canvas_width= width+(2*view->opts.margin_width);
177    view->canvas_height= height+(2*view->opts.margin_height);
178    if (view->opts.viewport.width>view->canvas_width) {
179	int tmp;
180	tmp= (view->opts.viewport.width-view->canvas_width)/2;
181	view->opts.margin_width+= tmp;
182    }
183    if (view->opts.viewport.height>view->canvas_height) {
184	int tmp;
185	tmp= (view->opts.viewport.height-view->canvas_height)/2;
186	view->opts.margin_height+= tmp;
187    }
188    bzero(view->state,XkbMaxLegalKeyCode+1);
189
190    xgcv.foreground= view->opts.fg;
191    xgcv.background= view->opts.bg;
192    view->gc= XCreateGC(view->dpy,view->win,GCForeground|GCBackground,&xgcv);
193    view->xscale= ((double)width)/((double)xkb->geom->width_mm);
194    view->yscale= ((double)height)/((double)xkb->geom->height_mm);
195
196    _XkbUI_AllocateColors(view);
197    return view;
198}
199
200Status
201XkbUI_SetViewOpts(XkbUI_ViewPtr	view,XkbUI_ViewOptsPtr opts)
202{
203    if ((!view)||(!opts))
204	return BadValue;
205    if (opts->present==0)
206	return Success;
207    if (opts->present&XkbUI_BackgroundMask)
208	view->opts.bg=			opts->bg;
209    if (opts->present&XkbUI_ForegroundMask)
210	view->opts.fg=			opts->fg;
211    if (opts->present&XkbUI_LabelModeMask)
212	view->opts.label_mode=		opts->label_mode;
213    if (opts->present&XkbUI_ColorModeMask)
214	view->opts.color_mode=		opts->color_mode;
215    if (opts->present&XkbUI_WidthMask)
216	view->opts.viewport.width=	opts->viewport.width;
217    if (opts->present&XkbUI_HeightMask)
218	view->opts.viewport.height=	opts->viewport.height;
219    if (opts->present&XkbUI_XOffsetMask)
220	view->opts.viewport.x=		opts->viewport.x;
221    if (opts->present&XkbUI_YOffsetMask)
222	view->opts.viewport.y=		opts->viewport.y;
223    if (opts->present&XkbUI_MarginWidthMask)
224	view->opts.margin_width=	opts->margin_width;
225    if (opts->present&XkbUI_MarginHeightMask)
226	view->opts.margin_height=	opts->margin_height;
227    if (opts->present&XkbUI_ColormapMask) {
228	view->opts.cmap=		opts->cmap;
229	_XkbUI_AllocateColors(view);
230    }
231    return Success;
232}
233
234Status
235XbUI_GetViewOpts(XkbUI_ViewPtr view,XkbUI_ViewOptsPtr opts_rtrn)
236{
237    if ((!view)||(!opts_rtrn))
238	return BadValue;
239    *opts_rtrn= view->opts;
240    return Success;
241}
242
243Status
244XkbUI_SetCanvasSize(XkbUI_ViewPtr view,int width,int height)
245{
246    if ((!view)||(!view->xkb)||(!view->xkb->geom))
247	return BadValue;
248    view->canvas_width= width;
249    view->canvas_height= height;
250    view->xscale= ((double)width)/((double)view->xkb->geom->width_mm);
251    view->yscale= ((double)height)/((double)view->xkb->geom->height_mm);
252    return Success;
253}
254
255Status
256XkbUI_GetCanvasSize(XkbUI_ViewPtr view,int *width_rtrn,int *height_rtrn)
257{
258    if (!view)
259	return BadValue;
260    if (width_rtrn)	*width_rtrn= view->canvas_width;
261    if (height_rtrn)	*height_rtrn= view->canvas_height;
262    return Success;
263}
264
265/***====================================================================***/
266
267static void
268_RotatePoints(	double		rangle,
269		int 		corner_x,
270		int		corner_y,
271		int		nPts,
272		XkbUI_PointPtr	pts)
273{
274register int	i;
275double		rr,rx,ry,rt;
276
277    for (i=0;i<nPts;i++,pts++) {
278	rx= pts->x-corner_x; ry= pts->y-corner_y; /* translate */
279	rr= hypot(rx,ry);
280	rt= atan2(ry,rx)+rangle;
281	rx= rr*cos(rt);
282	ry= rr*sin(rt);
283	pts->x= rx+corner_x; pts->y= ry+corner_y;
284    }
285    return;
286}
287
288static void
289_DrawPoints(XkbUI_ViewPtr view,int nPts,XkbUI_PointPtr pts,XPoint *xpts)
290{
291register int	i;
292
293    for (i=0;i<nPts;i++) {
294	if (pts[i].x>=0.0)	xpts[i].x=	pts[i].x*view->xscale+0.5;
295	else			xpts[i].x=	pts[i].x*view->xscale-0.5;
296	xpts[i].x+= view->opts.viewport.x;
297	if (pts[i].y>=0.0)	xpts[i].y=	pts[i].y*view->yscale+0.5;
298	else			xpts[i].x=	pts[i].y*view->yscale-0.5;
299	xpts[i].y+= 	view->opts.viewport.y;
300    }
301    if ((xpts[nPts-1].x!=xpts[0].x)||(xpts[nPts-1].y!=xpts[0].y))
302	xpts[nPts++]= xpts[0]; /* close the shape, if necessary */
303    XDrawLines(view->dpy,view->win,view->gc,xpts,nPts,CoordModeOrigin);
304XFlush(view->dpy);
305    return;
306}
307
308static void
309_DrawSolidPoints(XkbUI_ViewPtr view,int nPts,XkbUI_PointPtr pts,XPoint *xpts)
310{
311register int	i;
312
313    for (i=0;i<nPts;i++) {
314	if (pts[i].x>=0.0)	xpts[i].x=	pts[i].x*view->xscale+0.5;
315	else			xpts[i].x=	pts[i].x*view->xscale-0.5;
316	xpts[i].x+= view->opts.viewport.x;
317	if (pts[i].y>=0.0)	xpts[i].y=	pts[i].y*view->yscale+0.5;
318	else			xpts[i].x=	pts[i].y*view->yscale-0.5;
319	xpts[i].y+= 	view->opts.viewport.y;
320    }
321    if ((xpts[nPts-1].x!=xpts[0].x)||(xpts[nPts-1].y!=xpts[0].y))
322	xpts[nPts++]= xpts[0]; /* close the shape, if necessary */
323    XFillPolygon(view->dpy,view->win,view->gc,xpts,nPts,Nonconvex,
324							CoordModeOrigin);
325XFlush(view->dpy);
326    return;
327}
328
329static void
330_DrawShape(	XkbUI_ViewPtr	view,
331		double		rangle,
332		int		xoff,
333		int		yoff,
334		int		rotx,
335		int		roty,
336		XkbShapePtr	shape,
337		Bool		key)
338{
339XkbOutlinePtr	ol;
340register int	o;
341int		maxPts;
342XkbUI_PointPtr	uipts;
343XPoint *	xpts;
344
345    for (maxPts=4,o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) {
346	if ((shape->num_outlines>1)&&(ol==shape->approx))
347	    continue;
348	if (ol->num_points>maxPts)
349	    maxPts= ol->num_points;
350    }
351    uipts= _XkbTypedCalloc(maxPts,XkbUI_PointRec);
352    xpts= _XkbTypedCalloc(maxPts+1,XPoint);
353    XSetForeground(view->dpy,view->gc,view->xkb->geom->label_color->pixel);
354    for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) {
355	XkbPointPtr	gpts;
356	register int 	p;
357	if ((shape->num_outlines>1)&&(ol==shape->approx))
358	    continue;
359	gpts= ol->points;
360	if (ol->num_points==1) {
361	    uipts[0].x= xoff;		uipts[0].y= yoff;
362	    uipts[1].x= xoff+gpts[0].x;	uipts[1].y= yoff;
363	    uipts[2].x= xoff+gpts[0].x;	uipts[2].y= yoff+gpts[0].y;
364	    uipts[3].x= xoff;		uipts[3].y= yoff+gpts[0].y;
365	    p= 4;
366	}
367	else if (ol->num_points==2) {
368	    uipts[0].x= xoff+gpts[0].x;	uipts[0].y= yoff+gpts[0].y;
369	    uipts[1].x= xoff+gpts[1].x;	uipts[1].y= yoff+gpts[0].y;
370	    uipts[2].x= xoff+gpts[1].x;	uipts[2].y= yoff+gpts[1].y;
371	    uipts[3].x= xoff+gpts[0].x;	uipts[3].y= yoff+gpts[1].y;
372	    p= 4;
373	}
374	else {
375	    for (p=0;p<ol->num_points;p++) {
376		uipts[p].x= xoff+gpts[p].x;
377		uipts[p].y= yoff+gpts[p].y;
378	    }
379	    p= ol->num_points;
380	}
381	if (rangle!=0.0)
382	    _RotatePoints(rangle,rotx,roty,p,uipts);
383	if (key) {
384	    if (o==0) {
385		XSetForeground(view->dpy,view->gc,
386					view->xkb->geom->base_color->pixel);
387		_DrawSolidPoints(view,p,uipts,xpts);
388		XSetForeground(view->dpy,view->gc,
389					view->xkb->geom->label_color->pixel);
390	    }
391	    _DrawPoints(view,p,uipts,xpts);
392	}
393	else {
394	    _DrawPoints(view,p,uipts,xpts);
395	}
396    }
397    _XkbFree(uipts);
398    _XkbFree(xpts);
399    return;
400}
401
402static void
403_DrawRect(	XkbUI_ViewPtr	view,
404		double		rangle,
405		int		x1,
406		int		y1,
407		int		x2,
408		int		y2,
409		Bool		key)
410{
411XkbUI_PointRec	uipts[4];
412XPoint 		xpts[4];
413
414    XSetForeground(view->dpy,view->gc,view->xkb->geom->label_color->pixel);
415    uipts[0].x= x1; uipts[0].y= y1;
416    uipts[1].x= x2; uipts[1].y= y1;
417    uipts[2].x= x2; uipts[2].y= y2;
418    uipts[3].x= x1; uipts[3].y= y2;
419    if (rangle!=0.0)
420	_RotatePoints(rangle,0,0,4,uipts);
421    if (key) {
422	XSetForeground(view->dpy,view->gc,view->xkb->geom->base_color->pixel);
423	_DrawSolidPoints(view,4,uipts,xpts);
424	XSetForeground(view->dpy,view->gc,view->xkb->geom->label_color->pixel);
425	_DrawPoints(view,4,uipts,xpts);
426    }
427    else {
428	_DrawPoints(view,4,uipts,xpts);
429    }
430    return;
431}
432
433static void
434_DrawDoodad(	XkbUI_ViewPtr	view,
435		double		rangle,
436		int		xoff,
437		int		yoff,
438		XkbDoodadPtr	doodad)
439{
440int		x;
441int		y;
442XkbShapePtr	shape;
443Bool		solid;
444
445    x= 		doodad->any.left+xoff;
446    y= 		doodad->any.top+yoff;
447    shape=	NULL;
448    solid= 	False;
449    switch (doodad->any.type) {
450	case XkbOutlineDoodad:
451	    shape= XkbShapeDoodadShape(view->xkb->geom,(&doodad->shape));
452	    break;
453	case XkbSolidDoodad:
454	    shape= XkbShapeDoodadShape(view->xkb->geom,(&doodad->shape));
455	    solid= True;
456	    break;
457	case XkbTextDoodad:
458	    break;
459	case XkbIndicatorDoodad:
460	    shape= XkbIndicatorDoodadShape(view->xkb->geom,&doodad->indicator);
461	    solid= True;
462	    break;
463	case XkbLogoDoodad:
464	    shape= XkbLogoDoodadShape(view->xkb->geom,&doodad->logo);
465	    solid= True;
466	    break;
467    }
468    if (shape)
469	_DrawShape(view,rangle,x,y,x,y,shape,solid);
470    return;
471}
472
473static void
474_DrawRow(	XkbUI_ViewPtr	view,
475		double		rangle,
476		int		xoff,
477		int		yoff,
478		XkbRowPtr	row)
479{
480register int 	k,x,y;
481XkbKeyPtr	key;
482
483    x= xoff+row->left; y= yoff+row->top;
484    for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
485	XkbShapePtr	shape;
486	shape= XkbKeyShape(view->xkb->geom,key);
487	if (row->vertical) {
488	    y+= key->gap;
489	    _DrawShape(view,rangle,x,y,xoff,yoff,shape,True);
490	    y+= shape->bounds.y2;
491	}
492	else {
493	    x+= key->gap;
494	    _DrawShape(view,rangle,x,y,xoff,yoff,shape,True);
495	    x+= shape->bounds.x2;
496	}
497    }
498    return;
499}
500
501static void
502_DrawSection(XkbUI_ViewPtr view,XkbSectionPtr section)
503{
504double	rangle;
505
506    rangle= ((((double)(section->angle%3600))/3600.0)*(2.0*M_PI));
507    if (section->doodads) {
508	XkbDrawablePtr	first,draw;
509	first= XkbGetOrderedDrawables(NULL,section);
510	if (first) {
511	    for (draw=first;draw!=NULL;draw=draw->next) {
512		_DrawDoodad(view,rangle,section->left,section->top,draw->u.doodad);
513	    }
514	    XkbFreeOrderedDrawables(first);
515	}
516    }
517    if (section->rows) {
518	register int	r;
519	XkbRowPtr	row;
520	for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
521	    _DrawRow(view,rangle,section->left,section->top,row);
522	}
523    }
524    return;
525}
526
527static void
528_DrawAll(XkbUI_ViewPtr view)
529{
530XkbGeometryPtr	geom;
531XkbDrawablePtr	first,draw;
532Bool		dfltBorder;
533
534    geom= view->xkb->geom;
535    first= XkbGetOrderedDrawables(geom,NULL);
536    if (first) {
537	dfltBorder= True;
538	for (draw=first;draw!=NULL;draw=draw->next) {
539	    char *name;
540	    if ((draw->type!=XkbDW_Doodad)||
541		((draw->u.doodad->any.type!=XkbOutlineDoodad)&&
542		 (draw->u.doodad->any.type!=XkbSolidDoodad))) {
543		continue;
544	    }
545	    name= XkbAtomGetString(view->dpy,draw->u.doodad->any.name);
546	    if (name != NULL) {
547                if (strcmp(name, "edges") == 0) {
548                    _XkbFree(name);
549                    dfltBorder= False;
550                    break;
551                }
552                _XkbFree(name);
553	    }
554	}
555	if (dfltBorder)
556	    _DrawRect(view,0.0,0,0,geom->width_mm,geom->height_mm,True);
557	for (draw=first;draw!=NULL;draw=draw->next) {
558	    switch (draw->type) {
559		case XkbDW_Section:
560		    _DrawSection(view,draw->u.section);
561		    break;
562		case XkbDW_Doodad:
563		    _DrawDoodad(view,0.0,0,0,draw->u.doodad);
564		    break;
565	    }
566	}
567	XkbFreeOrderedDrawables(first);
568    }
569    XFlush(view->dpy);
570    return;
571}
572
573static void
574_RedrawKey(XkbUI_ViewPtr view,KeyCode kc)
575{
576/*    _DrawAll(view);*/
577    return;
578}
579
580/***====================================================================***/
581
582Bool
583XkbUI_SetKeyAppearance(XkbUI_ViewPtr view,KeyCode kc,unsigned int flags)
584{
585XkbDescPtr	xkb;
586unsigned	old;
587
588    if ((!view)||(!view->xkb))
589	return False;
590    xkb= view->xkb;
591    if ((kc<xkb->min_key_code)||(kc>xkb->max_key_code))
592	return False;
593    old= view->state[kc];
594    view->state[kc]= (flags&(~XkbUI_Obscured));
595    if (old&XkbUI_Obscured)
596	view->state[kc]|= XkbUI_Obscured;
597    else if (old!=view->state[kc])
598	_RedrawKey(view,kc);
599    return True;
600}
601
602Bool
603XkbUI_SetKeyAppearanceByName(	XkbUI_ViewPtr 	view,
604				XkbKeyNamePtr	name,
605				unsigned int	flags)
606{
607KeyCode	kc;
608
609    if ((!view)||(!view->xkb)||(!name))
610	return False;
611    kc= XkbFindKeycodeByName(view->xkb,name->name,True);
612    if (!kc)
613	return False;
614    return XkbUI_SetKeyAppearance(view,kc,flags);
615}
616
617Bool
618XkbUI_ResetKeyAppearance(	XkbUI_ViewPtr 	view,
619				unsigned int 	mask,
620				unsigned int 	values)
621{
622register int 	i;
623unsigned	new_val;
624
625    if ((!view)||(!view->xkb))
626	return False;
627    if (!mask)
628	return True;
629    for (i=view->xkb->min_key_code;i<=view->xkb->max_key_code;i++) {
630	new_val= (view->state[i]&(~mask));
631	new_val|= (mask&values);
632	XkbUI_SetKeyAppearance(view,i,new_val);
633    }
634    return True;
635}
636
637Bool
638XkbUI_DrawRegion(XkbUI_ViewPtr view,XRectangle *viewport)
639{
640    if (!view)
641	return False;
642    _DrawAll(view);
643    return True;
644}
645
646Bool
647XkbUI_DrawChanged(	XkbUI_ViewPtr	view,
648			XRectangle *	viewport,
649			XkbChangesPtr	changes,
650			int		num_keys,
651			XkbKeyNamePtr	keys)
652{
653    return False;
654}
655
656Bool
657XkbUI_Select(	XkbUI_ViewPtr	view,
658		XPoint *	coord,
659		unsigned int	which,
660		XkbSectionPtr	section)
661{
662    return False;
663}
664