comparison lib/AuxPanel.c @ 0:92745d501b9a

initial import from kinput2-v3.1
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 08 Mar 2010 04:44:30 +0900
parents
children 89750191b165
comparison
equal deleted inserted replaced
-1:000000000000 0:92745d501b9a
1 #ifndef lint
2 static char *rcsid = "$Id: AuxPanel.c,v 1.23 1994/09/01 06:33:41 ishisone Exp $";
3 #endif
4 /*
5 * Copyright (c) 1990 Software Research Associates, Inc.
6 *
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation for any purpose and without fee is hereby granted, provided
9 * that the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of Software Research Associates not be
12 * used in advertising or publicity pertaining to distribution of the
13 * software without specific, written prior permission. Software Research
14 * Associates makes no representations about the suitability of this software
15 * for any purpose. It is provided "as is" without express or implied
16 * warranty.
17 *
18 * Author: Makoto Ishisone, Software Research Associates, Inc., Japan
19 */
20
21 /* Copyright 1991 NEC Corporation, Tokyo, Japan.
22 *
23 * Permission to use, copy, modify, and distribute this software and its
24 * documentation for any purpose and without fee is hereby granted,
25 * provided that the above copyright notice appear in all copies and that
26 * both that copyright notice and this permission notice appear in
27 * supporting documentation, and that the name of NEC Corporation
28 * not be used in advertising or publicity pertaining to distribution
29 * of the software without specific, written prior permission. NEC
30 * Corporation makes no representations about the suitability of this
31 * software for any purpose. It is provided "as is" without express
32 * or implied warranty.
33 *
34 * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
35 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
36 * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
37 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
38 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
39 * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
40 * PERFORMANCE OF THIS SOFTWARE.
41 *
42 * Author: Akira Kon, NEC Corporation. (kon@d1.bs2.mt.nec.co.jp)
43 */
44
45 /*
46 $BLdBjE@(B
47 $B!&J8;zIA2h$,A4It=q$-D>$7=hM}$K$J$C$F$$$k!#(B
48 $B!&$@$l$b(B Destroy $B$r8F$s$G$/$l$J$$$N$G$A$g$C$H$4$_$,;D$k!#(B
49 */
50
51 #include <X11/IntrinsicP.h>
52 #include <X11/StringDefs.h>
53 #if XtSpecificationRelease > 4
54 #include <X11/Xfuncs.h>
55 #endif
56 #include "AuxPanelP.h"
57 #include "ConvDisp.h"
58 #include "WStr.h"
59
60 #define DEBUG_VAR debug_AuxPanel
61 #include "DebugPrint.h"
62
63 static XtResource resources[] = {
64 #define offset(field) XtOffset(AuxPanelWidget, cpanel.field)
65 { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
66 offset(foreground), XtRString, XtDefaultForeground },
67 { XtNhorizontalSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
68 offset(hspace), XtRString, "6" },
69 { XtNverticalSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
70 offset(vspace), XtRString, "4" },
71 { XtNdefaultWidth, XtCDefaultWidth, XtRDimension, sizeof(Dimension),
72 offset(defaultwidth), XtRString, "400" },
73 { XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
74 offset(cursor), XtRImmediate, (XtPointer)None },
75 { XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
76 offset(callback), XtRCallback, NULL },
77 #undef offset
78 };
79
80 static void Initialize(), Destroy();
81 static void Realize();
82 static void Redisplay();
83 static void Resize();
84 static Boolean SetValues();
85 static XtGeometryResult QueryGeometry();
86 static void InsertChild();
87
88 static void GetInvGC();
89 static void ComputeSize();
90 static void Layout();
91
92 static void freeDisplaySegments();
93 static void UpdateAuxDisplay();
94
95 static CompositeClassExtensionRec CompositeExtension = {
96 /* next_extension */ NULL,
97 /* record_type */ NULLQUARK,
98 /* version */ XtCompositeExtensionVersion,
99 /* record_size */ sizeof(CompositeClassExtensionRec),
100 /* accept_objects */ True,
101 };
102
103 AuxPanelClassRec auxPanelClassRec = {
104 { /* core fields */
105 /* superclass */ (WidgetClass) &compositeClassRec,
106 /* class_name */ "AuxPanel",
107 /* widget_size */ sizeof(AuxPanelRec),
108 /* class_initialize */ NULL,
109 /* class_part_initialize */ NULL,
110 /* class_inited */ FALSE,
111 /* initialize */ Initialize,
112 /* initialize_hook */ NULL,
113 /* realize */ Realize,
114 /* actions */ NULL,
115 /* num_actions */ 0,
116 /* resources */ resources,
117 /* num_resources */ XtNumber(resources),
118 /* xrm_class */ NULLQUARK,
119 /* compress_motion */ TRUE,
120 /* compress_exposure */ TRUE,
121 /* compress_enterleave */ TRUE,
122 /* visible_interest */ FALSE,
123 /* destroy */ Destroy,
124 /* resize */ Resize,
125 /* expose */ Redisplay,
126 /* set_values */ SetValues,
127 /* set_values_hook */ NULL,
128 /* set_values_almost */ XtInheritSetValuesAlmost,
129 /* get_values_hook */ NULL,
130 /* accept_focus */ NULL,
131 /* version */ XtVersion,
132 /* callback_private */ NULL,
133 /* tm_table */ NULL,
134 /* query_geometry */ QueryGeometry,
135 /* display_accelerator */ XtInheritDisplayAccelerator,
136 /* extension */ NULL
137 },
138 { /* composite fields */
139 /* geometry_manager */ NULL,
140 /* change_managed */ NULL,
141 /* insert_child */ InsertChild,
142 /* delete_child */ XtInheritDeleteChild,
143 /* extension */ (XtPointer)&CompositeExtension,
144 },
145 { /* auxpanel fields */
146 /* empty */ 0
147 }
148 };
149
150 WidgetClass auxPanelWidgetClass = (WidgetClass)&auxPanelClassRec;
151
152 /* ARGSUSED */
153 static void
154 Initialize(req, new, args, num_args)
155 Widget req;
156 Widget new;
157 ArgList args;
158 Cardinal *num_args;
159 {
160 AuxPanelWidget cpw = (AuxPanelWidget)new;
161
162 TRACE(("AuxPanel:Initialize()\n"));
163
164 cpw->cpanel.displayobj = NULL;
165 cpw->cpanel.dispauxsegments = NULL;
166 cpw->cpanel.dispauxsegmentsize = 0;
167 cpw->cpanel.numauxsegments = 0;
168 GetInvGC(cpw);
169 }
170
171 static void
172 Destroy(w)
173 Widget w;
174 {
175 AuxPanelWidget cpw = (AuxPanelWidget)w;
176
177 TRACE(("AuxPanel:Destroy()\n"));
178
179 freeDisplaySegments(cpw);
180 if (cpw->cpanel.invgc != NULL) XtReleaseGC(w, cpw->cpanel.invgc);
181 }
182
183 static void
184 Realize(w, mask, value)
185 Widget w;
186 XtValueMask *mask;
187 XSetWindowAttributes *value;
188 {
189 AuxPanelWidget cpw = (AuxPanelWidget)w;
190 CompositeWidgetClass super = (CompositeWidgetClass)XtClass(w)->core_class.superclass;
191 String params[1];
192 Cardinal num_params;
193
194 TRACE(("AuxPanel:Realize()\n"));
195
196 if (cpw->cpanel.displayobj == NULL) {
197 params[0] = XtClass(w)->core_class.class_name;
198 num_params = 1;
199 XtAppErrorMsg(XtWidgetToApplicationContext(w),
200 "childError", "number", "WidgetError",
201 "%s: has no child (ConvDisplayObject)",
202 params, &num_params);
203 }
204
205 if (cpw->cpanel.cursor != None) {
206 *mask |= CWCursor;
207 value->cursor = cpw->cpanel.cursor;
208 }
209
210 (*super->core_class.realize)(w, mask, value);
211 }
212
213 /* ARGSUSED */
214 static void
215 Redisplay(w, ev, region)
216 Widget w;
217 XEvent *ev;
218 Region region;
219 {
220 AuxPanelWidget cpw = (AuxPanelWidget)w;
221 XExposeEvent *event = (XExposeEvent *)ev;
222 DisplaySegment *dseg;
223 int cheight, hspace, vspace;
224 int x, i;
225
226 TRACE(("AuxPanel:Redisplay()\n"));
227
228 cheight = cpw->cpanel.fontheight;
229 hspace = cpw->cpanel.hspace;
230 vspace = cpw->cpanel.vspace;
231
232 if (event->y + event->height < vspace / 2
233 || cheight + vspace / 2 < event->y)
234 return;
235
236 for (i = 0, x = hspace / 2, dseg = cpw->cpanel.dispauxsegments;
237 i < cpw->cpanel.numauxsegments ; i++, dseg++) {
238 if (x < event->x + event->width && event->x < x + dseg->width) {
239 dseg->redrawpos = 0;
240 }
241 else {
242 dseg->redrawpos = -1; /* $B=q$-D>$9I,MW$,$J$$(B */
243 }
244 x += dseg->width;
245 }
246
247 UpdateAuxDisplay(cpw);
248 }
249
250 static void
251 Resize(w)
252 Widget w;
253 {
254 AuxPanelWidget cpw = (AuxPanelWidget)w;
255
256 TRACE(("AuxPanel:Resize()\n"));
257
258 Layout(cpw, True, True);
259 }
260
261 /* ARGSUSED */
262 static Boolean
263 SetValues(cur, req, wid, args, num_args)
264 Widget cur;
265 Widget req;
266 Widget wid;
267 ArgList args;
268 Cardinal *num_args;
269 {
270 AuxPanelWidget old = (AuxPanelWidget)cur;
271 AuxPanelWidget new = (AuxPanelWidget)wid;
272 Boolean redisplay = False;
273
274 TRACE(("AuxPanel:SetValues()\n"));
275
276 if (new->cpanel.displayobj == NULL) return False;
277
278 if (new->cpanel.foreground != old->cpanel.foreground ||
279 new->core.background_pixel != old->core.background_pixel) {
280 XtVaSetValues(new->cpanel.displayobj,
281 XtNforeground, new->cpanel.foreground,
282 XtNbackground, new->core.background_pixel,
283 NULL);
284 redisplay = True;
285 }
286
287 if (new->cpanel.numauxsegments > 0 ||
288 new->cpanel.hspace != old->cpanel.hspace ||
289 new->cpanel.vspace != old->cpanel.vspace ||
290 new->cpanel.defaultwidth != old->cpanel.defaultwidth) {
291 Layout(new, True, True);
292 redisplay = True;
293 }
294
295 if (new->cpanel.cursor != old->cpanel.cursor && XtIsRealized(wid)) {
296 XDefineCursor(XtDisplay(wid), XtWindow(wid), new->cpanel.cursor);
297 }
298
299 return redisplay;
300 }
301
302 static XtGeometryResult
303 QueryGeometry(w, req, ret)
304 Widget w;
305 XtWidgetGeometry *req;
306 XtWidgetGeometry *ret;
307 {
308 Dimension width, height;
309 Dimension owidth, oheight;
310
311 TRACE(("AuxPanel:QueryGeometry()\n"));
312
313 ret->request_mode = 0;
314
315 if ((req->request_mode & (CWWidth | CWHeight)) == 0) return XtGeometryYes;
316
317 width = (req->request_mode & CWWidth) ? req->width : w->core.width;
318 height = (req->request_mode & CWHeight) ? req->height : w->core.height;
319
320 owidth = width;
321 oheight = height;
322 ComputeSize((AuxPanelWidget)w,
323 (req->request_mode & CWWidth) != 0,
324 (req->request_mode & CWHeight) != 0,
325 &width, &height);
326 ret->request_mode = CWWidth | CWHeight;
327 ret->width = width;
328 ret->height = height;
329
330 if (width != owidth || height != oheight) return XtGeometryAlmost;
331
332 return XtGeometryYes;
333 }
334
335 static void
336 InsertChild(w)
337 Widget w;
338 {
339 AuxPanelWidget cpw = (AuxPanelWidget)XtParent(w);
340 CompositeWidgetClass super = (CompositeWidgetClass)XtClass(cpw)->core_class.superclass;
341 String params[1];
342 Cardinal num_params;
343
344 TRACE(("AuxPanel:InsertChild()\n"));
345
346 if (!XtIsSubclass(w, convDisplayObjectClass)) {
347 params[0] = XtClass(cpw)->core_class.class_name;
348 num_params = 1;
349 XtAppErrorMsg(XtWidgetToApplicationContext(w),
350 "childError", "class", "WidgetError",
351 "%s: child must be subclass of ConvDisplayObject",
352 params, &num_params);
353 }
354 if (cpw->composite.num_children != 0) {
355 params[0] = XtClass(cpw)->core_class.class_name;
356 num_params = 1;
357 XtAppErrorMsg(XtWidgetToApplicationContext(w),
358 "childError", "number", "WidgetError",
359 "%s: can only take one child",
360 params, &num_params);
361 }
362
363 (*super->composite_class.insert_child)(w);
364
365 cpw->cpanel.displayobj = w;
366 cpw->cpanel.fontheight = CDLineHeight(w, (Position *)NULL);
367
368 #ifdef notdef
369 {
370 Pixel fg, bg;
371 XtVaGetValues(w, XtNforeground, &fg, XtNbackground, &bg, NULL);
372 GetInvGC(cpw, fg, bg);
373 }
374 #endif
375
376 if (cpw->cpanel.numauxsegments > 0) {
377 Layout(cpw, cpw->core.width == 0, cpw->core.height == 0);
378 }
379 }
380
381 static void
382 GetInvGC(cpw)
383 AuxPanelWidget cpw;
384 {
385 XGCValues values;
386
387 TRACE(("AuxPanel:GetInvGC()\n"));
388
389 values.function = GXinvert;
390 values.plane_mask = cpw->cpanel.foreground ^ cpw->core.background_pixel;
391 cpw->cpanel.invgc = XtGetGC((Widget)cpw, GCFunction|GCPlaneMask, &values);
392 }
393
394 /* ARGSUSED */
395 static void
396 ComputeSize(cpw, resizex, resizey, width_inout, height_inout)
397 AuxPanelWidget cpw;
398 int resizex;
399 int resizey;
400 Dimension *width_inout;
401 Dimension *height_inout;
402 {
403 int width, height;
404 int i, minwidth = 0;
405 DisplaySegment *dseg = cpw->cpanel.dispauxsegments;
406
407
408 TRACE(("AuxPanel:ComputeSize()\n"));
409
410 if (cpw->cpanel.displayobj == NULL) return;
411
412 width = *width_inout;
413 height = *height_inout;
414
415 for (i = 0 ; i < cpw->cpanel.numauxsegments ; i++, dseg++) {
416 minwidth += CDStringWidth(cpw->cpanel.displayobj, &dseg->seg, 0, -1);
417 }
418 minwidth += cpw->cpanel.hspace * 2;
419 if (resizex) {
420 width = minwidth;
421 } else {
422 width = (cpw->core.width < minwidth) ? minwidth : cpw->core.width;
423 }
424 height = cpw->cpanel.fontheight + cpw->cpanel.vspace;
425 *width_inout = width;
426 *height_inout = height;
427 }
428
429 static void
430 Layout(cpw, resizex, resizey)
431 AuxPanelWidget cpw;
432 int resizex;
433 int resizey;
434 {
435 Dimension width, height;
436 Dimension owidth, oheight;
437 XtGeometryResult re;
438
439 TRACE(("AuxPanel:Layout()\n"));
440
441 if (cpw->cpanel.displayobj == NULL) return;
442
443 width = cpw->core.width;
444 height = cpw->core.height;
445 ComputeSize(cpw, resizex, resizey, &width, &height);
446 if (width != cpw->core.width || height != cpw->core.height) {
447 owidth = width;
448 oheight = height;
449 re = XtMakeResizeRequest((Widget)cpw, owidth, oheight,
450 &width, &height);
451 switch (re) {
452 case XtGeometryYes:
453 /* no problem */
454 break;
455 }
456 }
457 }
458
459 /*- allocDisplaySegments: prepare specified number of display segments -*/
460 static void
461 allocDisplaySegments(cpw, n)
462 AuxPanelWidget cpw;
463 Cardinal n;
464 {
465 if (cpw->cpanel.dispauxsegmentsize > n) return;
466 n = ((n + 3) / 4) * 4 ;
467 if (cpw->cpanel.dispauxsegments == NULL) {
468 cpw->cpanel.dispauxsegments =
469 (DisplaySegment *)XtCalloc(n, sizeof(DisplaySegment));
470 } else {
471 cpw->cpanel.dispauxsegments =
472 (DisplaySegment *)XtRealloc((char *)cpw->cpanel.dispauxsegments,
473 n * sizeof(DisplaySegment));
474 bzero((char *)(cpw->cpanel.dispauxsegments + cpw->cpanel.numauxsegments),
475 (n - cpw->cpanel.numauxsegments) * sizeof(DisplaySegment));
476 }
477 cpw->cpanel.dispauxsegmentsize = n;
478 }
479
480 /*- freeDisplaySegments: free display segments -*/
481 static void
482 freeDisplaySegments(cpw)
483 AuxPanelWidget cpw;
484 {
485 Cardinal i;
486 DisplaySegment *dseg = cpw->cpanel.dispauxsegments;
487
488 for (i = 0 ; i < cpw->cpanel.dispauxsegmentsize ; i++, dseg++) {
489 if (dseg->seg.data != NULL) XtFree(dseg->seg.data);
490 }
491 XtFree((char *)cpw->cpanel.dispauxsegments);
492 cpw->cpanel.dispauxsegments = (DisplaySegment *)0;
493 cpw->cpanel.dispauxsegmentsize = 0;
494 }
495
496 /*- copyString: copy ICString -*/
497 static void
498 copyString(from, to)
499 ICString *from;
500 ICString *to;
501 {
502 if (to->data != NULL) XtFree(to->data);
503 *to = *from;
504 to->data = XtMalloc(to->nbytes);
505 (void)bcopy(from->data, to->data, to->nbytes);
506 }
507
508 static void
509 UpdateAuxDisplay(cpw)
510 AuxPanelWidget cpw;
511 {
512 Widget dispobj = cpw->cpanel.displayobj;
513 DisplaySegment *dseg;
514 int hspace, vspace;
515 int x, y;
516 Cardinal i;
517
518 if (dispobj == NULL) return;
519
520 hspace = cpw->cpanel.hspace;
521 vspace = cpw->cpanel.vspace;
522
523 x = hspace / 2;
524 y = vspace / 2;
525
526 for (i = 0, dseg = cpw->cpanel.dispauxsegments;
527 i < cpw->cpanel.numauxsegments ; i++, dseg++) {
528 if (dseg->redrawpos >= 0) {
529 int offset = 0;
530 int idx = dseg->redrawpos;
531
532 if (dseg->width == 0) {
533 dseg->width = CDStringWidth(dispobj, &dseg->seg, 0, -1);
534 }
535 if (idx > 0) {
536 offset = CDStringWidth(dispobj, &dseg->seg, 0, idx);
537 }
538 CDDrawString(dispobj, (Widget)cpw, &dseg->seg, 0, -1, x + offset, y);
539 }
540 x += dseg->width;
541 }
542 return;
543 }
544
545 /*
546 * Public Functions
547 */
548
549 /* ARGSUSED */
550 void
551 APanelStart(w, segments, nseg, curseg, cursorpos)
552 Widget w;
553 ICString *segments;
554 Cardinal nseg, curseg, cursorpos;
555 {
556 AuxPanelWidget cpw = (AuxPanelWidget)w;
557 Cardinal i;
558 DisplaySegment *dseg;
559
560 cpw->cpanel.numauxsegments = nseg;
561 allocDisplaySegments(cpw, nseg);
562 for (i = 0, dseg = cpw->cpanel.dispauxsegments ; i < nseg ; i++, dseg++) {
563 copyString(segments +i, &dseg->seg);
564 dseg->redrawpos = 0;
565 dseg->width = 0;
566 }
567 Layout(cpw, True, True);
568 if (XtIsRealized(w)) XClearWindow(XtDisplay(w), XtWindow(w));
569 return;
570 }
571
572 void
573 APanelEnd(w)
574 Widget w;
575 {
576 AuxPanelWidget cpw = (AuxPanelWidget)w;
577
578 cpw->cpanel.numauxsegments = 0;
579 return;
580 }
581
582 /* ARGSUSED */
583 void
584 APanelChange(w, segments, nseg, curseg, cursorpos)
585 Widget w;
586 ICString *segments;
587 Cardinal nseg, curseg, cursorpos;
588 {
589 AuxPanelWidget cpw = (AuxPanelWidget)w;
590 Cardinal i;
591 DisplaySegment *dseg;
592
593 cpw->cpanel.numauxsegments = nseg;
594 allocDisplaySegments(cpw, nseg);
595 for (i = 0, dseg = cpw->cpanel.dispauxsegments ; i < nseg ; i++, dseg++) {
596 /* $BA4=q$-49$($K$J$C$F$7$^$&!#(BICCompareSegment $B$,;H$($k$J$i(B
597 $B;H$$$?$$$N$@$,!#(B */
598 copyString(segments +i, &dseg->seg);
599 dseg->redrawpos = 0;
600 dseg->width = 0;
601 }
602 Layout(cpw, False, False);
603 if (XtIsRealized(w)) XClearWindow(XtDisplay(w), XtWindow(w));
604 UpdateAuxDisplay(cpw);
605 return;
606 }