1 /* Part of XPCE --- The SWI-Prolog GUI toolkit
2
3 Author: Jan Wielemaker and Anjo Anjewierden
4 E-mail: jan@swi.psy.uva.nl
5 WWW: http://www.swi.psy.uva.nl/projects/xpce/
6 Copyright (c) 1985-2002, University of Amsterdam
7 All rights reserved.
8
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 1. Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 2. Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in
18 the documentation and/or other materials provided with the
19 distribution.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #include <h/kernel.h>
36 #include <h/graphics.h>
37 /* generated from Makefile */
38
39 static status backgroundDisplay(DisplayObj, Colour);
40 static status foregroundDisplay(DisplayObj d, Colour c);
41 static void attach_font_families(Class class);
42
43
44 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
45 Create a display. The display is not yet opened.
46 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
47
48 static status
initialiseDisplay(DisplayObj d,Name address)49 initialiseDisplay(DisplayObj d, Name address)
50 { DisplayManager dm = TheDisplayManager();
51
52 assign(d, size, NIL);
53 assign(d, address, address);
54 assign(d, font_table, newObject(ClassHashTable, EAV));
55 assign(d, frames, newObject(ClassChain, EAV));
56 assign(d, inspect_handlers, newObject(ClassChain, EAV));
57 assign(d, cache, NIL);
58 assign(d, colour_map, DEFAULT);
59 assign(d, display_manager, dm);
60 assign(d, busy_locks, ZERO);
61
62 ws_init_display(d);
63 appendDisplayManager(dm, d);
64 protectObject(d);
65
66 succeed;
67 }
68
69
70 static DisplayObj
getConvertDisplay(Class class,Any obj)71 getConvertDisplay(Class class, Any obj)
72 { Name address;
73 DisplayObj d;
74
75 if ( (d = getMemberDisplayManager(TheDisplayManager(), obj)) )
76 answer(d);
77
78 if ( isDefault(obj) )
79 answer(CurrentDisplay(obj));
80
81 if ( instanceOfObject(obj, ClassVisual) )
82 answer(get(obj, NAME_display, EAV));
83
84 if ( (address = checkType(obj, TypeName, class)) &&
85 ws_legal_display_name(strName(address)) )
86 answer(answerObject(ClassDisplay, address, EAV));
87
88 fail;
89 }
90
91
92 static status
attachCacheDisplay(DisplayObj d)93 attachCacheDisplay(DisplayObj d)
94 { Size sz = getClassVariableValueObject(d, NAME_graphicsCache);
95
96 if ( isDefault(sz) )
97 sz = getSizeDisplay(d);
98
99 send(d, NAME_cache, newObject(ClassImage, DEFAULT, sz->w, sz->h,
100 NAME_pixmap, EAV), EAV);
101
102 succeed;
103 }
104
105
106 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
107 Open a display. If necessary, the X toolkit is initialised first and
108 a context for the application is created.
109
110 As PCE normally manages a collection of main windows an application
111 shell widget is created to serve as root for all the other (popup)
112 shells. This widget is never realised (page 35 of Xt manual).
113 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
114
115 status
openDisplay(DisplayObj d)116 openDisplay(DisplayObj d)
117 { if ( ws_opened_display(d) )
118 succeed;
119
120 DEBUG(NAME_display, Cprintf("Opening display %s\n", pp(d)));
121
122 ws_open_display(d); /* generate exception on failure */
123 obtainClassVariablesObject(d);
124 ws_foreground_display(d, d->foreground);
125 ws_background_display(d, d->background);
126 ws_init_graphics_display(d);
127 ws_init_monitors_display(d);
128
129 BLACK_COLOUR = newObject(ClassColour, NAME_black, EAV);
130 WHITE_COLOUR = newObject(ClassColour, NAME_white, EAV);
131
132 attachCacheDisplay(d);
133
134 succeed;
135 }
136
137
138 BoolObj
getOpenDisplay(Any d)139 getOpenDisplay(Any d)
140 { answer(ws_opened_display(d) ? ON : OFF);
141 }
142
143
144 static status
foregroundDisplay(DisplayObj d,Colour c)145 foregroundDisplay(DisplayObj d, Colour c)
146 { assign(d, foreground, c);
147 ws_foreground_display(d, c);
148
149 succeed;
150 }
151
152
153 static status
backgroundDisplay(DisplayObj d,Colour c)154 backgroundDisplay(DisplayObj d, Colour c)
155 { assign(d, background, c);
156 ws_background_display(d, c);
157
158 succeed;
159 }
160
161
162 static status
colourMapDisplay(DisplayObj d,ColourMap cm)163 colourMapDisplay(DisplayObj d, ColourMap cm)
164 { assign(d, colour_map, cm);
165
166 succeed;
167 }
168
169
170 status
drawInDisplay(DisplayObj d,Graphical gr,Point pos,BoolObj invert,BoolObj subtoo)171 drawInDisplay(DisplayObj d, Graphical gr, Point pos, BoolObj invert, BoolObj subtoo)
172 { Int oldx, oldy;
173 Device dev;
174
175 if ( isDefault(invert) )
176 invert = OFF;
177 if ( isDefault(subtoo) )
178 subtoo = OFF;
179
180 if ( notDefault(pos) )
181 { oldx = gr->area->x;
182 oldy = gr->area->y;
183 dev = gr->device;
184 gr->device = NIL;
185 setGraphical(gr, pos->x, pos->y, DEFAULT, DEFAULT);
186 } else
187 { oldx = oldy = (Int) DEFAULT;
188 dev = NIL; /* keep compiler happy */
189 }
190
191 ComputeGraphical(gr);
192 openDisplay(d);
193
194 ws_draw_in_display(d, gr, invert, subtoo);
195
196 if ( notDefault(oldx) )
197 { setGraphical(gr, oldx, oldy, DEFAULT, DEFAULT);
198 gr->device = dev;
199 }
200
201 succeed;
202 }
203
204
205 static Image
getImageDisplay(DisplayObj d,Area a)206 getImageDisplay(DisplayObj d, Area a)
207 { int x, y, w, h;
208
209 openDisplay(d);
210 if ( isDefault(a) )
211 { Size sz = getSizeDisplay(d);
212
213 x = y = 0;
214 w = valInt(sz->w);
215 h = valInt(sz->h);
216 } else
217 { x = valInt(a->x);
218 y = valInt(a->y);
219 w = valInt(a->w);
220 h = valInt(a->h);
221 }
222
223 return ws_grab_image_display(d, x, y, w, h);
224 }
225
226
227 status
grabServerDisplay(DisplayObj d,BoolObj val)228 grabServerDisplay(DisplayObj d, BoolObj val)
229 { if ( ws_opened_display(d) )
230 { if ( val == ON )
231 ws_grab_server(d);
232 else
233 ws_ungrab_server(d);
234 }
235
236 succeed;
237 }
238
239
240 static Int
getConnectionFdDisplay(DisplayObj d)241 getConnectionFdDisplay(DisplayObj d)
242 { if ( ws_opened_display(d) )
243 answer(ws_display_connection_number(d));
244
245 fail;
246 }
247
248
249 static status
eventQueuedDisplay(DisplayObj d)250 eventQueuedDisplay(DisplayObj d)
251 { if ( ws_opened_display(d) )
252 { RedrawDisplayManager(d->display_manager);
253
254 return ws_events_queued_display(d);
255 }
256
257 fail;
258 }
259
260
261 status
dispatchDisplay(DisplayObj d)262 dispatchDisplay(DisplayObj d)
263 { answer(dispatchDisplayManager(d->display_manager, DEFAULT, DEFAULT));
264 }
265
266
267 status
flushDisplay(DisplayObj d)268 flushDisplay(DisplayObj d)
269 { if ( ws_opened_display(d) )
270 { RedrawDisplayManager(d->display_manager);
271 ws_flush_display(d);
272 }
273
274 succeed;
275 }
276
277
278 status
synchroniseDisplay(DisplayObj d)279 synchroniseDisplay(DisplayObj d)
280 { if ( ws_opened_display(d) )
281 { RedrawDisplayManager(d->display_manager);
282
283 ws_synchronise_display(d);
284 }
285
286 succeed;
287 }
288
289
290 static status
screenSaverDisplay(DisplayObj d,BoolObj val)291 screenSaverDisplay(DisplayObj d, BoolObj val)
292 { openDisplay(d);
293
294 if ( val == ON )
295 ws_activate_screen_saver(d);
296 else
297 ws_deactivate_screen_saver(d);
298
299 succeed;
300 }
301
302
303 status
bellDisplay(DisplayObj d,Int vol)304 bellDisplay(DisplayObj d, Int vol)
305 { openDisplay(d);
306
307 if ( isDefault(vol) )
308 vol = (Int) getClassVariableValueObject(d, NAME_volume);
309
310 ws_bell_display(d, valInt(vol));
311
312 succeed;
313 }
314
315
316 Size
getSizeDisplay(DisplayObj d)317 getSizeDisplay(DisplayObj d)
318 { int w=0, h=0;
319
320 if ( notNil(d->size) )
321 answer(d->size);
322
323 openDisplay(d);
324 ws_get_size_display(d, &w, &h);
325 assign(d, size, newObject(ClassSize, toInt(w), toInt(h), EAV));
326
327 answer(d->size);
328 }
329
330
331 Int
getWidthDisplay(DisplayObj d)332 getWidthDisplay(DisplayObj d)
333 { answer(getSizeDisplay(d)->w);
334 }
335
336
337 Int
getHeightDisplay(DisplayObj d)338 getHeightDisplay(DisplayObj d)
339 { answer(getSizeDisplay(d)->h);
340 }
341
342
343 static Area
getBoundingBoxDisplay(DisplayObj d)344 getBoundingBoxDisplay(DisplayObj d)
345 { Size s = getSizeDisplay(d);
346
347 answer( answerObject(ClassArea, ZERO, ZERO, s->w, s->h, EAV) );
348 }
349
350
351 static Int
getDepthDisplay(DisplayObj d)352 getDepthDisplay(DisplayObj d)
353 { TRY(openDisplay(d));
354
355 answer(toInt(ws_depth_display(d)));
356 }
357
358 static Name
getVisualTypeDisplay(DisplayObj d)359 getVisualTypeDisplay(DisplayObj d)
360 { TRY(openDisplay(d));
361
362 answer(ws_get_visual_type_display(d));
363 }
364
365 static Size
getDotsPerInchDisplay(DisplayObj d)366 getDotsPerInchDisplay(DisplayObj d)
367 { int rx, ry;
368
369 if ( ws_resolution_display(d, &rx, &ry) )
370 answer(answerObject(ClassSize, toInt(rx), toInt(ry), EAV));
371
372 fail;
373 }
374
375 Point
getPointerLocationDisplay(DisplayObj d)376 getPointerLocationDisplay(DisplayObj d)
377 { int x, y;
378
379 TRY(openDisplay(d));
380 if ( ws_pointer_location_display(d, &x, &y) )
381 answer(answerObject(ClassPoint, toInt(x), toInt(y), EAV));
382
383 fail;
384 }
385
386
387
388 /*******************************
389 * MONITORS *
390 *******************************/
391
392 static Chain
getMonitorsDisplay(DisplayObj d)393 getMonitorsDisplay(DisplayObj d)
394 { openDisplay(d);
395
396 answer(d->monitors);
397 }
398
399
400 Monitor
getMonitorDisplay(DisplayObj d,Any obj)401 getMonitorDisplay(DisplayObj d, Any obj)
402 { Cell cell;
403
404 openDisplay(d);
405
406 if ( isDefault(obj) )
407 { if ( !(obj = getPointerLocationDisplay(d)) )
408 fail;
409 }
410
411 if ( instanceOfObject(obj, ClassPoint) )
412 { Point pt = obj;
413
414 for_cell(cell, d->monitors)
415 { Monitor mon = cell->value;
416
417 if ( pointInArea(mon->area, pt) )
418 return mon;
419 }
420 } else
421 { Area a = obj;
422 Monitor best = NULL;
423 Area tmp = tempObject(ClassArea, EAV);
424 int overlap = 0;
425
426 for_cell(cell, d->monitors)
427 { Monitor mon = cell->value;
428
429 copyArea(tmp, a);
430 if ( intersectionArea(tmp, mon->area) )
431 { int val = valInt(tmp->w)*valInt(tmp->h);
432
433 if ( val < 0 )
434 val = -val;
435 if ( val > overlap )
436 { best = mon;
437 overlap = val;
438 }
439 }
440 }
441
442 considerPreserveObject(tmp);
443 return best;
444 }
445
446 fail;
447 }
448
449
450 /********************************
451 * CUT BUFFERS *
452 ********************************/
453
454 static status
cutBufferDisplay(DisplayObj d,Int n,CharArray str)455 cutBufferDisplay(DisplayObj d, Int n, CharArray str)
456 { PceString s = &str->data;
457 TRY(openDisplay(d));
458
459 if ( isDefault(n) )
460 n = ZERO;
461
462 return ws_set_cutbuffer(d, valInt(n), s);
463 }
464
465
466 static StringObj
getCutBufferDisplay(DisplayObj d,Int n)467 getCutBufferDisplay(DisplayObj d, Int n)
468 { TRY(openDisplay(d));
469
470 if ( isDefault(n) )
471 n = ZERO;
472
473 return ws_get_cutbuffer(d, valInt(n));
474
475 }
476
477 /*******************************
478 * SELECTION INTERFACE *
479 *******************************/
480
481 static Real
getSelectionTimeoutDisplay(DisplayObj d)482 getSelectionTimeoutDisplay(DisplayObj d)
483 { unsigned long time = ws_get_selection_timeout();
484
485 answer(CtoReal((float)time/1000.0));
486 }
487
488
489 static status
selectionTimeoutDisplay(DisplayObj d,Real time)490 selectionTimeoutDisplay(DisplayObj d, Real time)
491 { ws_set_selection_timeout((unsigned long)(valReal(time) * 1000.0));
492
493 succeed;
494 }
495
496
497 static Any
getSelectionDisplay(DisplayObj d,Name which,Name target,Type type)498 getSelectionDisplay(DisplayObj d, Name which, Name target, Type type)
499 { Any sel;
500
501 TRY(openDisplay(d));
502
503 if ( isDefault(which) ) which = NAME_primary;
504 if ( isDefault(target) ) target = NAME_text;
505 if ( isDefault(type) ) type = nameToType(NAME_string);
506
507 if ( (sel = ws_get_selection(d, which, target)) )
508 answer(checkType(sel, type, NIL));
509
510 fail;
511 }
512
513
514 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
515 The owner of a selection is related using a hyper-object to the display.
516 This will inform the display if the selection onwner is deleted.
517 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
518
519 static Any
getSelectionOwnerDisplay(DisplayObj d,Name which)520 getSelectionOwnerDisplay(DisplayObj d, Name which)
521 { if ( isDefault(which) )
522 which = NAME_primary;
523
524 answer(getHyperedObject(d,
525 getAppendName(which, NAME_selectionOwner),
526 DEFAULT));
527 }
528
529
530 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
531 TBD: * multiple hypers for the various selection-types.
532 * proper call-back if the owner is unlinked.
533 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
534
535
536 status
looseSelectionDisplay(DisplayObj d,Name which)537 looseSelectionDisplay(DisplayObj d, Name which)
538 { Hyper h;
539 Code msg;
540 Name hypername = getAppendName(which, NAME_selectionOwner);
541
542 if ( (h = getFindHyperObject(d, hypername, DEFAULT)) &&
543 (msg = getAttributeObject(h, NAME_looseMessage)) &&
544 (msg = checkType(msg, TypeCode, NIL)) )
545 forwardReceiverCode(msg, h->to, which, EAV);
546
547 freeHypersObject(d, hypername, DEFAULT);
548
549 succeed;
550 }
551
552
553 static status
selectionOwnerDisplay(DisplayObj d,Any owner,Name selection,Function convert,Code loose,Name type)554 selectionOwnerDisplay(DisplayObj d, Any owner, Name selection,
555 Function convert, Code loose, Name type)
556 { TRY(openDisplay(d));
557
558 if ( isDefault(selection) )
559 selection = NAME_primary;
560 if ( isDefault(type) )
561 type = NAME_text;
562
563 if ( isNil(owner) )
564 { Any old = getSelectionOwnerDisplay(d, selection);
565
566 if ( old )
567 { looseSelectionDisplay(d, selection);
568 ws_disown_selection(d, selection);
569 }
570 } else
571 { Any old = getSelectionOwnerDisplay(d, selection);
572 Hyper h = NIL;
573 Name hypername = getAppendName(selection, NAME_selectionOwner);
574
575 if ( old && old != owner )
576 looseSelectionDisplay(d, selection);
577
578 if ( old != owner )
579 h = newObject(ClassHyper, d, owner, hypername, EAV);
580 else
581 h = getFindHyperObject(d, hypername, DEFAULT);
582
583 attributeObject(h, NAME_convertFunction,
584 newObject(ClassQuoteFunction, convert, EAV));
585 attributeObject(h, NAME_looseMessage, loose);
586 attributeObject(h, NAME_type, type);
587
588 #ifndef WIN32_GRAPHICS
589 if ( !old )
590 #endif
591 { if ( !ws_own_selection(d, selection, type) )
592 { freeHypersObject(d, hypername, DEFAULT);
593 return errorPce(owner, NAME_cannotBecomeSelectionOwner, selection);
594 }
595 }
596 }
597
598 succeed;
599 }
600
601 /*******************************
602 * SIMPLE SELECTION INTERFACE *
603 *******************************/
604
605 static status
selectionDisplay(DisplayObj d,Name which,StringObj data)606 selectionDisplay(DisplayObj d, Name which, StringObj data)
607 { StringObj s2 = get(data, NAME_copy, EAV);
608
609 if ( s2 )
610 { lockObject(s2, ON);
611
612 return selectionOwnerDisplay(d,
613 s2, which,
614 newObject(ClassObtain,
615 RECEIVER, NAME_self, EAV),
616 newObject(ClassMessage,
617 RECEIVER, NAME_free, EAV),
618 NAME_text);
619 }
620
621 fail;
622 }
623
624
625 static status
copyDisplay(DisplayObj d,StringObj data)626 copyDisplay(DisplayObj d, StringObj data)
627 { int rval = (send(d, NAME_cutBuffer, ZERO, data, EAV) |
628 send(d, NAME_selection, NAME_primary, data, EAV) |
629 send(d, NAME_selection, NAME_clipboard, data, EAV));
630
631
632 return rval ? SUCCEED : FAIL;
633 }
634
635
636 static StringObj
getPasteDisplay(DisplayObj d,Name which)637 getPasteDisplay(DisplayObj d, Name which)
638 { static Name formats[] = { NAME_utf8_string,
639 NAME_text,
640 NAME_string,
641 NULL
642 };
643 StringObj s = NULL;
644 Name *fmt;
645
646 if ( isDefault(which) )
647 which = NAME_clipboard;
648
649 catchErrorPce(PCE, NAME_getSelection);
650 for(fmt = formats; *fmt; fmt++)
651 { if ( (s=get(d, NAME_selection, which, *fmt, EAV)) )
652 break;
653 }
654 if ( ! (*fmt) )
655 s = get(d, NAME_cutBuffer, ZERO, EAV);
656
657 catchPopPce(PCE);
658
659 if ( s )
660 answer(s);
661
662 fail;
663 }
664
665
666 /********************************
667 * WINDOW_MANAGER/LOOK-AND-FEEL *
668 ********************************/
669
670 static Name
getWindowManagerDisplay(DisplayObj d)671 getWindowManagerDisplay(DisplayObj d)
672 { Name wm;
673
674 if ( notDefault(d->window_manager) )
675 answer(d->window_manager);
676
677 if ( (wm = getClassVariableValueObject(d, NAME_windowManager)) &&
678 notDefault(wm) )
679 { assign(d, window_manager, wm);
680 answer(d->window_manager);
681 }
682
683 if ( (wm = ws_window_manager(d)) )
684 assign(d, window_manager, wm);
685
686 answer(d->window_manager);
687 }
688
689
690 /********************************
691 * CONFIRM/INFORM *
692 ********************************/
693
694 static status
create_confirmer(DisplayObj d)695 create_confirmer(DisplayObj d)
696 { Any p, m, h;
697
698 if ( getAttributeObject(d, NAME_confirmer) )
699 succeed;
700
701 TRY( p = newObject(ClassWindow, DEFAULT, DEFAULT, d, EAV) );
702 TRY( m = newObject(ClassText, CtoName(""), NAME_center, EAV) );
703 TRY( h = newObject(ClassText, CtoName(""), NAME_center, EAV) );
704
705 send(m, NAME_font, getClassVariableValueObject(d, NAME_labelFont), EAV);
706 send(h, NAME_font, getClassVariableValueObject(d, NAME_valueFont), EAV);
707 send(p, NAME_display, m, EAV);
708 send(p, NAME_display, h, EAV);
709 send(p, NAME_kind, NAME_popup, EAV);
710 send(p, NAME_cursor, newObject(ClassCursor, NAME_mouse, EAV), EAV);
711 send(p, NAME_border, toInt(3), EAV);
712 send(p, NAME_pen, toInt(3), EAV);
713 send(p, NAME_create, EAV);
714 send(get(p, NAME_frame, EAV), NAME_border, ONE, EAV);
715
716 send(p, NAME_recogniser,
717 newObject(ClassHandler, NAME_button,
718 newObject(ClassMessage,
719 d, NAME_ConfirmPressed, Arg(1), EAV),
720 EAV),
721 EAV);
722
723 attributeObject(d, NAME_SeenDown, OFF);
724 attributeObject(d, NAME_confirmer, p);
725 attributeObject(p, NAME_helpText, h);
726 attributeObject(p, NAME_messageText, m);
727
728 succeed;
729 }
730
731
732 static status
ConfirmPressedDisplay(DisplayObj d,EventObj ev)733 ConfirmPressedDisplay(DisplayObj d, EventObj ev)
734 { if ( isDownEvent(ev) )
735 send(d, NAME_SeenDown, ON, EAV);
736 else if ( isUpEvent(ev) )
737 { if ( get(d, NAME_SeenDown, EAV) == ON )
738 { Name code = getButtonEvent(ev);
739
740 send(get(d, NAME_confirmer, EAV), NAME_return, code, EAV);
741 } else
742 { send(get(d, NAME_confirmer, EAV), NAME_grabPointer, OFF, EAV); /* HACK */
743 send(get(d, NAME_confirmer, EAV), NAME_grabPointer, ON, EAV);
744 }
745 }
746
747 succeed;
748 }
749
750
751 static Name
display_help(DisplayObj d,StringObj hlp,Name msg)752 display_help(DisplayObj d, StringObj hlp, Name msg)
753 { Any p;
754 TextObj hlp_text, msg_text;
755 int fx, fy, fw, fh, tx, ty;
756 Name rval;
757
758 create_confirmer(d);
759 TRY( p = getAttributeObject(d, NAME_confirmer) );
760 TRY( hlp_text = getAttributeObject(p, NAME_helpText));
761 TRY( msg_text = getAttributeObject(p, NAME_messageText));
762
763 send(hlp_text, NAME_string, hlp, EAV);
764 send(msg_text, NAME_string, msg, EAV);
765 send(p, NAME_compute, EAV);
766
767 fw = max(valInt(hlp_text->area->w), valInt(msg_text->area->w)) + 40;
768 fh = valInt(hlp_text->area->h) + valInt(msg_text->area->h) + 50;
769 getSizeDisplay(d); /* initialise size argument */
770 fx = (valInt(d->size->w) - fw) / 2;
771 fy = (valInt(d->size->h) - fh) / 2;
772
773 tx = (fw - 12 - valInt(hlp_text->area->w)) / 2;
774 send(hlp_text, NAME_set, toInt(tx), toInt(20), DEFAULT, DEFAULT, EAV);
775 tx = (fw - 12 - valInt(msg_text->area->w)) / 2;
776 ty = valInt(hlp_text->area->h) + 30;
777 send(msg_text, NAME_set, toInt(tx), toInt(ty), DEFAULT, DEFAULT, EAV);
778
779 send(get(p, NAME_frame, EAV), NAME_set, toInt(fx), toInt(fy),
780 toInt(fw), toInt(fh), EAV);
781
782 send(d, NAME_SeenDown, OFF, EAV);
783 send(p, NAME_show, ON, EAV);
784 send(p, NAME_grabPointer, ON, EAV);
785 rval = get(p, NAME_confirm, DEFAULT, ON, EAV);
786 send(p, NAME_grabPointer, OFF, EAV);
787 send(p, NAME_show, OFF, EAV);
788
789 return rval;
790 }
791
792
793 status
confirmDisplay(DisplayObj d,CharArray fmt,int argc,Any * argv)794 confirmDisplay(DisplayObj d, CharArray fmt, int argc, Any *argv)
795 { StringObj str;
796 ArgVector(av, argc+1);
797 int i;
798 Name button;
799
800 av[0] = (Any) fmt;
801 for(i=0; i<argc; i++)
802 av[i+1] = argv[i];
803
804 TRY(str = answerObjectv(ClassString, argc+1, av));
805
806 switch( ws_message_box(str, MBX_CONFIRM) )
807 { case MBX_OK:
808 succeed;
809 case MBX_CANCEL:
810 fail;
811 default:
812 { Name msg;
813
814 msg = CtoName("Press LEFT button to confirm, RIGHT button to cancel");
815 TRY(button = display_help(d, str, msg));
816 doneObject(str);
817
818 if ( button == NAME_left )
819 succeed;
820 }
821 }
822
823 fail;
824 }
825
826
827 status
informDisplay(DisplayObj d,CharArray fmt,int argc,Any * argv)828 informDisplay(DisplayObj d, CharArray fmt, int argc, Any *argv)
829 { StringObj str;
830 ArgVector(av, argc+1);
831 int i;
832 Name button;
833
834 av[0] = (Any) fmt;
835 for(i=0; i<argc; i++)
836 av[i+1] = argv[i];
837
838 TRY(str = answerObjectv(ClassString, argc+1, av));
839
840 switch( ws_message_box(str, MBX_INFORM) )
841 { case MBX_NOTHANDLED:
842 { Name msg;
843
844 msg = CtoName("Press any button to remove message");
845 TRY(button = display_help(d, str, msg));
846 doneObject(str);
847 }
848 }
849
850 succeed;
851 }
852
853
854 static status
reportDisplay(DisplayObj d,Name kind,CharArray fmt,int argc,Any * argv)855 reportDisplay(DisplayObj d, Name kind, CharArray fmt, int argc, Any *argv)
856 { if ( kind == NAME_error || kind == NAME_inform )
857 { ArgVector(av, argc+1);
858 StringObj str;
859
860 av[0] = isDefault(fmt) ? (CharArray) CtoName("") : fmt;
861 copyArgs(argc, argv, &av[1]);
862 TRY(str = answerObjectv(ClassString, argc+1, av));
863 if ( kind == NAME_error )
864 alertReporteeVisual(d);
865
866 switch( ws_message_box(str, MBX_ERROR) )
867 { case MBX_NOTHANDLED:
868 { Name msg, button;
869
870 msg = CtoName("Press any button to remove message");
871 TRY(button = display_help(d, str, msg));
872 doneObject(str);
873 }
874 }
875 } else if ( kind == NAME_warning )
876 alertReporteeVisual(d);
877
878 succeed;
879 }
880
881
882 /*******************************
883 * BUSY *
884 *******************************/
885
886 status
busyCursorDisplay(DisplayObj d,CursorObj c,BoolObj block_events)887 busyCursorDisplay(DisplayObj d, CursorObj c, BoolObj block_events)
888 { if ( !instanceOfObject(d, ClassDisplay) )
889 succeed;
890
891 if ( notNil(c) )
892 { assign(d, busy_locks, add(d->busy_locks, ONE));
893
894 if ( d->busy_locks == ONE )
895 { Cell cell;
896
897 for_cell(cell, d->frames)
898 busyCursorFrame(cell->value, c, block_events);
899 flushDisplay(d);
900 }
901 } else
902 { assign(d, busy_locks, sub(d->busy_locks, ONE));
903
904 if ( valInt(d->busy_locks) < 0 )
905 assign(d, busy_locks, ZERO);
906
907 if ( d->busy_locks == ZERO )
908 { Cell cell;
909
910 for_cell(cell, d->frames)
911 busyCursorFrame(cell->value, c, block_events);
912 }
913 }
914
915 succeed;
916 }
917
918
919 /********************************
920 * DEBUGGING *
921 ********************************/
922
923 static status
inspectHandlerDisplay(DisplayObj d,Handler h)924 inspectHandlerDisplay(DisplayObj d, Handler h)
925 { return addChain(d->inspect_handlers, h);
926 }
927
928
929 status
inspectDisplay(DisplayObj d,Graphical gr,EventObj ev)930 inspectDisplay(DisplayObj d, Graphical gr, EventObj ev)
931 { Handler h;
932
933 for_chain(d->inspect_handlers, h,
934 { if ( isAEvent(ev, h->event) &&
935 forwardReceiverCode(h->message, gr, gr, ev, EAV) )
936 { DEBUG(NAME_inspect, Cprintf("Inspect %s succeeded on %s\n",
937 pp(ev->id), pp(h)));
938 succeed;
939 }
940 })
941
942 fail;
943 }
944
945
946 static status
synchronousDisplay(DisplayObj d,BoolObj val)947 synchronousDisplay(DisplayObj d, BoolObj val)
948 { TRY(openDisplay(d));
949
950 if ( val == OFF )
951 ws_asynchronous(d);
952 else
953 ws_synchronous(d);
954
955 succeed;
956 }
957
958
959 static status
resetDisplay(DisplayObj d)960 resetDisplay(DisplayObj d)
961 { PceWindow sw;
962
963 grabServerDisplay(d, OFF);
964
965 if ( (sw = getAttributeObject(d, NAME_confirmer)) )
966 send(sw, NAME_show, OFF, EAV);
967
968 if ( d->busy_locks != ZERO )
969 { assign(d, busy_locks, ONE);
970 busyCursorDisplay(d, NIL, DEFAULT);
971 }
972
973 return resetVisual((VisualObj) d);
974 }
975
976
977 static status
quitDisplay(DisplayObj d)978 quitDisplay(DisplayObj d)
979 { ws_quit_display(d);
980
981 succeed;
982 }
983
984 /********************************
985 * FONT TABLES *
986 ********************************/
987
988 static status
loadFontFamilyDisplay(DisplayObj d,Name fam)989 loadFontFamilyDisplay(DisplayObj d, Name fam)
990 { Class class = classOfObject(d);
991
992 if ( !getClassVariableClass(class, fam) )
993 attach_class_variable(class, fam, "chain", "[]", "Font family set");
994
995 if ( !getClassVariableValueObject(d, fam) )
996 return errorPce(d, NAME_noFontsInFamily, fam);
997
998 succeed;
999 }
1000
1001
1002 static status
loadFontsDisplay(DisplayObj d)1003 loadFontsDisplay(DisplayObj d)
1004 { Chain fams;
1005 static int done = FALSE;
1006
1007 if ( done )
1008 succeed;
1009 done = TRUE;
1010
1011 if ( (fams = getClassVariableValueObject(d, NAME_fontFamilies)) )
1012 { Cell cell;
1013
1014 for_cell(cell, fams)
1015 send(d, NAME_loadFontFamily, cell->value, EAV);
1016 }
1017
1018 succeed;
1019 }
1020
1021
1022 static status
loadFontAliasesDisplay(DisplayObj d,Name res)1023 loadFontAliasesDisplay(DisplayObj d, Name res)
1024 { Chain ch = getClassVariableValueObject(d, res);
1025
1026 if ( ch )
1027 { Cell cell;
1028 Type type_font = nameToType(NAME_font);
1029
1030 for_cell(cell, ch)
1031 { Name name;
1032 FontObj font;
1033 Any n, f;
1034
1035 if ( instanceOfObject(cell->value, ClassBinding) )
1036 { Binding b = cell->value;
1037 n = b->name;
1038 f = b->value;
1039 } else if ( instanceOfObject(cell->value, ClassTuple) )
1040 { Tuple t = cell->value;
1041 n = t->first;
1042 f = t->second;
1043 } else if ( instanceOfObject(cell->value, ClassAttribute) )
1044 { Attribute a = cell->value;
1045 n = a->name;
1046 f = a->value;
1047 } else
1048 { errorPce(cell->value, NAME_unexpectedType,
1049 CtoType(":=|tuple|attribute"));
1050 continue;
1051 }
1052
1053 if ( !(name = checkType(n, TypeName, d)) ||
1054 !(font = checkType(f, type_font, d)) )
1055 errorPce(d, NAME_badFontAlias, n, f);
1056 else
1057 send(d, NAME_fontAlias, name, font, EAV);
1058 }
1059
1060 succeed;
1061 }
1062
1063 fail;
1064 }
1065
1066
1067 static status
fontAliasDisplay(DisplayObj d,Name name,FontObj font,BoolObj force)1068 fontAliasDisplay(DisplayObj d, Name name, FontObj font, BoolObj force)
1069 { if ( force == ON || !getMemberHashTable(d->font_table, name) )
1070 appendHashTable(d->font_table, name, font);
1071
1072 succeed;
1073 }
1074
1075
1076 static FontObj
getFontAliasDisplay(DisplayObj d,Name name)1077 getFontAliasDisplay(DisplayObj d, Name name)
1078 { FontObj f;
1079
1080 if ( (f = getMemberHashTable(d->font_table, name)) )
1081 answer(f);
1082
1083 makeBuiltinFonts();
1084
1085 answer(getMemberHashTable(d->font_table, name));
1086 }
1087
1088
1089 /********************************
1090 * VISUAL *
1091 ********************************/
1092
1093 static Chain
getContainsDisplay(DisplayObj d)1094 getContainsDisplay(DisplayObj d)
1095 { answer(d->frames);
1096 }
1097
1098
1099 static Any
getContainedInDisplay(DisplayObj d)1100 getContainedInDisplay(DisplayObj d)
1101 { answer(d->display_manager);
1102 }
1103
1104 /*******************************
1105 * CLASS DECLARATION *
1106 *******************************/
1107
1108 /* Type declarations */
1109
1110 static char *T_cutBuffer[] =
1111 { "buffer=[0..7]", "value=string" };
1112 static char *T_busyCursor[] =
1113 { "cursor=[cursor]*", "block_input=[bool]" };
1114 static char *T_drawIn[] =
1115 { "graphical", "at=[point]", "invert=[bool]", "subwindow=[bool]" };
1116 static char *T_postscript[] =
1117 { "landscape=[bool]", "max_area=[area]" };
1118 static char *T_fontAlias[] =
1119 { "name=name", "font=font", "force=[bool]" };
1120 static char *T_name_any_XXX[] =
1121 { "name", "any ..." };
1122 static char *T_selectionOwner[] =
1123 { "owner=object*", "which=[name]", "convert=[function]",
1124 "loose=[code]",
1125 #ifdef WIN32_GRAPHICS
1126 "type=[{text,emf,wmf}]" /* metafile types */
1127 #else
1128 "type=[{text}]"
1129 #endif
1130 };
1131 static char *T_getSelection[] =
1132 { "which=[name]", "target=[name]", "type=[type]" };
1133 static char *T_selection[] =
1134 { "which=[name]", "value=char_array" };
1135 #ifdef WIN32_GRAPHICS
1136 extern Name getWinFileNameDisplay(DisplayObj obj,
1137 Name mode,
1138 Chain filters,
1139 CharArray title,
1140 CharArray file,
1141 Directory dir,
1142 Any owner,
1143 Chain flags);
1144 static char *T_win_file_name[] =
1145 { "mode={open,save}",
1146 "filters=[chain]",
1147 "title=[char_array]",
1148 "default=[char_array]",
1149 "directory=[directory]",
1150 "owner=[frame|int]",
1151 "options=[chain]"
1152 };
1153 extern Name getWinDirectoryDisplay(DisplayObj d,
1154 CharArray title,
1155 Directory dir,
1156 Any owner);
1157 static char *T_win_directory[] =
1158 { "title=[char_array]",
1159 "directory=[directory]",
1160 "owner=[frame|int]"
1161 };
1162 #endif
1163
1164 /* Instance Variables */
1165
1166 static vardecl var_display[] =
1167 { IV(NAME_size, "size*", IV_NONE,
1168 NAME_dimension, "Size (width, height) of display"),
1169 IV(NAME_address, "[name]", IV_BOTH,
1170 NAME_address, "Host/screen on which display resides"),
1171 IV(NAME_fontTable, "hash_table", IV_BOTH,
1172 NAME_font, "Mapping for logical font-names to fonts"),
1173 IV(NAME_frames, "chain", IV_GET,
1174 NAME_organisation, "Frames displayed on this display"),
1175 IV(NAME_monitors, "chain", IV_NONE,
1176 NAME_organisation, "Physical monitors attached"),
1177 IV(NAME_inspectHandlers, "chain", IV_GET,
1178 NAME_event, "Chain of handlers to support inspector tools"),
1179 SV(NAME_foreground, "colour", IV_GET|IV_STORE, foregroundDisplay,
1180 NAME_appearance, "Windows default foreground colour"),
1181 SV(NAME_background, "colour", IV_GET|IV_STORE, backgroundDisplay,
1182 NAME_appearance, "Windows default background colour"),
1183 SV(NAME_colourMap, "[colour_map]*", IV_GET|IV_STORE, colourMapDisplay,
1184 NAME_appearance, "Default for `frame ->colour_map'"),
1185 IV(NAME_quickAndDirty, "bool", IV_BOTH,
1186 NAME_cache, "Painting quick or correct?"),
1187 IV(NAME_cache, "image*", IV_BOTH,
1188 NAME_cache, "Scratch image to avoid flickering"),
1189 IV(NAME_windowManager, "[{twm,olwm,mwm}|name]", IV_SEND,
1190 NAME_windowManager, "Window manager running on this display"),
1191 IV(NAME_displayManager, "display_manager", IV_GET,
1192 NAME_organisation, "The global display manager (@display_manager)"),
1193 IV(NAME_busyLocks, "0..", IV_NONE,
1194 NAME_event, "Lock count for ->busy_cursor"),
1195 IV(NAME_wsRef, "alien:WsRef", IV_NONE,
1196 NAME_windowSystem, "Window-System reference")
1197 };
1198
1199 /* Send Methods */
1200
1201 static senddecl send_display[] =
1202 { SM(NAME_initialise, 1, "address=[name]", initialiseDisplay,
1203 DEFAULT, "Create at given address (<host>:<screen>)"),
1204 SM(NAME_reset, 0, NULL, resetDisplay,
1205 NAME_abort, "Closedown informer/confirmer"),
1206 SM(NAME_flush, 0, NULL, flushDisplay,
1207 NAME_animate, "Flush pending commands to X-server"),
1208 SM(NAME_grabServer, 1, "grab=bool", grabServerDisplay,
1209 NAME_animate, "Freeze all other applications"),
1210 SM(NAME_synchronise, 0, NULL, synchroniseDisplay,
1211 NAME_animate, "->flush and process pending events"),
1212 SM(NAME_synchronous, 1, "[bool]", synchronousDisplay,
1213 NAME_debugging, "Make communication to X-server synchronous"),
1214 SM(NAME_busyCursor, 2, T_busyCursor, busyCursorDisplay,
1215 NAME_event, "Define (temporary) cursor for all frames on the display"),
1216 SM(NAME_dispatch, 0, NULL, dispatchDisplay,
1217 NAME_event, "Dispatch events for 1/4th second"),
1218 SM(NAME_eventQueued, 0, NULL, eventQueuedDisplay,
1219 NAME_event, "Test if there are X-events waiting"),
1220 SM(NAME_inspectHandler, 1, "handler", inspectHandlerDisplay,
1221 NAME_event, "Register handler for inspect tool"),
1222 SM(NAME_fontAlias, 3, T_fontAlias, fontAliasDisplay,
1223 NAME_font, "Define a logical name for a font"),
1224 SM(NAME_loadFontAliases, 1, "set=name", loadFontAliasesDisplay,
1225 NAME_font, "Load font aliases from named class-variable"),
1226 SM(NAME_loadFontFamily, 1, "family=name", loadFontFamilyDisplay,
1227 NAME_font, "Create predefined fonts from family"),
1228 SM(NAME_loadFonts, 0, NULL, loadFontsDisplay,
1229 NAME_font, "Create predefined font set from defaults"),
1230 SM(NAME_ConfirmPressed, 1, "event", ConfirmPressedDisplay,
1231 NAME_internal, "Handle confirmer events"),
1232 SM(NAME_open, 0, NULL, openDisplay,
1233 NAME_open, "Open connection to X-server and initialise"),
1234 SM(NAME_Postscript, 1, "{head,body}", postscriptDisplay,
1235 NAME_postscript, "Create PostScript"),
1236 SM(NAME_quit, 0, NULL, quitDisplay,
1237 NAME_quit, "Destroy all window-system references"),
1238 SM(NAME_bell, 1, "volume=[int]", bellDisplay,
1239 NAME_report, "Ring the bell at volume"),
1240 SM(NAME_confirm, 2, T_name_any_XXX, confirmDisplay,
1241 NAME_report, "Test if the user confirms string"),
1242 SM(NAME_inform, 2, T_name_any_XXX, informDisplay,
1243 NAME_report, "Inform the user of something"),
1244 SM(NAME_report, 3, T_report, reportDisplay,
1245 NAME_report, "Report message using ->inform"),
1246 SM(NAME_drawIn, 4, T_drawIn, drawInDisplay,
1247 NAME_root, "Draw graphical in root window"),
1248 SM(NAME_cutBuffer, 2, T_cutBuffer, cutBufferDisplay,
1249 NAME_selection, "Set value of numbered X-cut buffer"),
1250 SM(NAME_selectionOwner, 5, T_selectionOwner, selectionOwnerDisplay,
1251 NAME_selection, "Define the owner of the X11 selection"),
1252 SM(NAME_selectionTimeout, 1, "real", selectionTimeoutDisplay,
1253 NAME_selection, "Set the timeout-time for getting the selection value"),
1254 SM(NAME_selection, 2, T_selection, selectionDisplay,
1255 NAME_selection, "Set the (textual) selection"),
1256 SM(NAME_copy, 1, "char_array", copyDisplay,
1257 NAME_selection, "Copy to selection and cut_buffer"),
1258 #ifndef WIN32_GRAPHICS
1259 SM(NAME_metaModifier, 1, "name", metaModifierDisplay,
1260 NAME_x, "Set the X modifier that is associated with META-"),
1261 SM(NAME_x11Threads, 1, "bool", X11ThreadsDisplay,
1262 NAME_x, "Setup X11 of multi-threading?"),
1263 #endif
1264 SM(NAME_screenSaver, 1, "bool", screenSaverDisplay,
1265 NAME_x, "Activate (@on) or deactivate (@off) screensaver")
1266 };
1267
1268 /* Get Methods */
1269
1270 static getdecl get_display[] =
1271 { GM(NAME_containedIn, 0, "display_manager", NULL, getContainedInDisplay,
1272 DEFAULT, "Display manager"),
1273 GM(NAME_contains, 0, "chain", NULL, getContainsDisplay,
1274 DEFAULT, "Chain with frames contained"),
1275 GM(NAME_convert, 1, "display", "any", getConvertDisplay,
1276 DEFAULT, "Convert graphical or `host:display[.screen]'"),
1277 GM(NAME_depth, 0, "bits_per_pixel=int", NULL, getDepthDisplay,
1278 NAME_colour, "Number of bits/pixel"),
1279 GM(NAME_open, 0, "bool", NULL, getOpenDisplay,
1280 NAME_open, "Query connected status of the display"),
1281 GM(NAME_visualType, 0,
1282 "{monochrome,static_grey,grey_scale,static_colour,pseudo_colour,true_colour,direct_colour}",
1283 NULL, getVisualTypeDisplay,
1284 NAME_colour, "Type of display attached"),
1285 GM(NAME_height, 0, "int", NULL, getHeightDisplay,
1286 NAME_dimension, "Height of the display in pixels"),
1287 GM(NAME_size, 0, "size", NULL, getSizeDisplay,
1288 NAME_dimension, "Size of the display"),
1289 GM(NAME_width, 0, "int", NULL, getWidthDisplay,
1290 NAME_dimension, "Width of the display in pixels"),
1291 GM(NAME_dotsPerInch, 0, "size", NULL, getDotsPerInchDisplay,
1292 NAME_dimension, "Resolution in dots per inch"),
1293 GM(NAME_pointerLocation, 0, "point", NULL, getPointerLocationDisplay,
1294 NAME_event, "Current location of the pointer"),
1295 GM(NAME_monitors, 0, "chain*", NULL, getMonitorsDisplay,
1296 NAME_monitor, "Physical monitors attached"),
1297 GM(NAME_monitor, 1, "monitor", "[point|area]", getMonitorDisplay,
1298 NAME_monitor, "Find monitor at position"),
1299 GM(NAME_fontAlias, 1, "font", "name=name", getFontAliasDisplay,
1300 NAME_font, "Lookup logical name"),
1301 GM(NAME_connectionFd, 0, "int", NULL, getConnectionFdDisplay,
1302 NAME_host, "Unix file descriptor for X-display connection"),
1303 GM(NAME_boundingBox, 0, "area", NULL, getBoundingBoxDisplay,
1304 NAME_postscript, "PostScript bounding box for the display"),
1305 GM(NAME_postscript, 2, "string", T_postscript, getPostscriptObject,
1306 NAME_postscript, "Get PostScript or (area of) display"),
1307 GM(NAME_image, 1, "image", "[area]", getImageDisplay,
1308 NAME_conversion, "Image with the pixels of a region from the display"),
1309 GM(NAME_cutBuffer, 1, "string", "buffer=[0..7]", getCutBufferDisplay,
1310 NAME_selection, "New string with value of cut-buffer"),
1311 GM(NAME_selection, 3, "any", T_getSelection, getSelectionDisplay,
1312 NAME_selection, "Query value of the X-window selection"),
1313 GM(NAME_selectionOwner, 1, "object", "which=[name]", getSelectionOwnerDisplay,
1314 NAME_selection, "Current object owning the X11 selection"),
1315 GM(NAME_selectionTimeout, 0, "real", NULL, getSelectionTimeoutDisplay,
1316 NAME_selection, "Get the current selection timeout time (seconds)"),
1317 GM(NAME_paste, 1, "string", "which=[{primary,clipboard}]", getPasteDisplay,
1318 NAME_selection, "Simple interface to get clipboard value"),
1319 #ifdef WIN32_GRAPHICS
1320 GM(NAME_winFileName, 7, "name", T_win_file_name, getWinFileNameDisplay,
1321 NAME_prompt, "Ask for a filename using Windows standard dialog"),
1322 GM(NAME_winDirectory, 3, "name", T_win_directory, getWinDirectoryDisplay,
1323 NAME_prompt, "Ask for a directory (folder) using Windows standard dialog"),
1324 #endif
1325 GM(NAME_windowManager, 0, "[{twm,olwm,mwm,fvwm}|name]", NULL,
1326 getWindowManagerDisplay,
1327 NAME_windowManager, "Window manager running on this display")
1328 };
1329
1330 /* Resources */
1331
1332 static classvardecl rc_display[] =
1333 { RC(NAME_background, "colour", "white",
1334 "Default background for windows"),
1335 RC(NAME_foreground, "colour", "black",
1336 "Default foreground for windows"),
1337 RC(NAME_graphicsCache, "[size]", "@default",
1338 "Size of cache image to avoid flickering"),
1339 RC(NAME_labelFont, "font", "bold",
1340 "Label font for confirm/inform"),
1341 RC(NAME_systemFonts, "chain",
1342 "[ normal := font(helvetica, roman, 12),\n"
1343 " bold := font(helvetica, bold, 12),\n"
1344 " italic := font(helvetica, oblique, 12),\n"
1345 " small := font(helvetica, roman, 10),\n"
1346 " large := font(helvetica, roman, 14),\n"
1347 " boldlarge := font(helvetica, bold, 14),\n"
1348 " huge := font(helvetica, roman, 18),\n"
1349 " boldhuge := font(helvetica, bold, 18),\n"
1350 " fixed := font(courier, roman, 12),\n"
1351 " tt := font(courier, roman, 12),\n"
1352 " boldtt := font(courier, bold, 12)\n"
1353 "]",
1354 "Predefined font-aliases"),
1355 RC(NAME_noFont, "font", "normal",
1356 "Replacement for undefined fonts"),
1357 RC(NAME_quickAndDirty, "bool", "@on",
1358 "Draw quick or correct"),
1359 RC(NAME_valueFont, "font", "normal",
1360 "Text font for confirm/inform"),
1361 RC(NAME_volume, "int", "0",
1362 "Default volume of ->bell"),
1363 RC(NAME_windowManager, "[name]", "@default",
1364 "Window manager running on this display")
1365 };
1366
1367 /* Class Declaration */
1368
1369 static Name display_termnames[] = { NAME_address };
1370
1371 ClassDecl(display_decls,
1372 var_display, send_display, get_display, rc_display,
1373 1, display_termnames,
1374 "$Rev$");
1375
1376
1377
1378 status
makeClassDisplay(Class class)1379 makeClassDisplay(Class class)
1380 { DisplayObj TheDisplay;
1381
1382 declareClass(class, &display_decls);
1383 saveStyleClass(class, NAME_external);
1384 cloneStyleClass(class, NAME_none);
1385
1386 TheDisplay = globalObject(NAME_display, ClassDisplay, EAV);
1387 globalObject(NAME_colourDisplay, ClassGreater,
1388 newObject(ClassObtain, TheDisplay, NAME_depth, EAV),
1389 ONE, EAV);
1390
1391 attach_font_families(class);
1392
1393 succeed;
1394 }
1395
1396
1397 #define PFONT(n, p, x) { n, p, XNAME(x) }
1398 #define ENDFONTLIST { NULL, 0, NULL }
1399
1400 typedef struct
1401 { Name style;
1402 int points;
1403 char *xname;
1404 } fontdef, *FontDef;
1405
1406 #if defined(WIN32_GRAPHICS) || defined(USE_XFT)
1407 #define XNAME(x) NULL
1408 #else
1409 #define XNAME(x) x
1410 #endif
1411
1412 #ifndef FIXED_FAMILY
1413 #define FIXED_FAMILY "*"
1414 #endif
1415
1416 static fontdef screen_fonts[] =
1417 { PFONT(NAME_roman, 10,
1418 "-" FIXED_FAMILY "-fixed-medium-r-normal--10-*-*-*-*-*-iso10646-*"),
1419 PFONT(NAME_roman, 12,
1420 "-" FIXED_FAMILY "-fixed-medium-r-normal--12-*-*-*-*-*-iso10646-*"),
1421 PFONT(NAME_roman, 14,
1422 "-" FIXED_FAMILY "-fixed-medium-r-normal--14-*-*-*-*-*-iso10646-*"),
1423 PFONT(NAME_roman, 16,
1424 "-" FIXED_FAMILY "-fixed-medium-r-normal--16-*-*-*-*-*-iso10646-*"),
1425 PFONT(NAME_bold, 10,
1426 "-" FIXED_FAMILY "-fixed-bold-r-normal--10-*-*-*-*-*-iso10646-*"),
1427 PFONT(NAME_bold, 12,
1428 "-" FIXED_FAMILY "-fixed-bold-r-normal--12-*-*-*-*-*-iso10646-*"),
1429 PFONT(NAME_bold, 14,
1430 "-" FIXED_FAMILY "-fixed-bold-r-normal--14-*-*-*-*-*-iso10646-*"),
1431 PFONT(NAME_bold, 16,
1432 "-" FIXED_FAMILY "-fixed-bold-r-normal--16-*-*-*-*-*-iso10646-*"),
1433 ENDFONTLIST
1434 };
1435
1436 #undef XNAME
1437 #if defined(WIN32_GRAPHICS) || defined(USE_XFT)
1438 #define XNAME(x) NULL
1439 #else
1440 #define XNAME(x) x
1441 #endif
1442
1443 static fontdef courier_fonts[] =
1444 { PFONT(NAME_roman, 10,
1445 "-*-courier new-medium-r-normal--10-*-*-*-*-*-*-*"),
1446 PFONT(NAME_roman, 12,
1447 "-*-courier new-medium-r-normal--12-*-*-*-*-*-*-*"),
1448 PFONT(NAME_roman, 14,
1449 "-*-courier new-medium-r-normal--14-*-*-*-*-*-*-*"),
1450 PFONT(NAME_roman, 18,
1451 "-*-courier new-medium-r-normal--18-*-*-*-*-*-*-*"),
1452 PFONT(NAME_roman, 24,
1453 "-*-courier new-medium-r-normal--24-*-*-*-*-*-*-*"),
1454 PFONT(NAME_bold, 10,
1455 "-*-courier new-bold-r-normal--10-*-*-*-*-*-*-*"),
1456 PFONT(NAME_bold, 12,
1457 "-*-courier new-bold-r-normal--12-*-*-*-*-*-*-*"),
1458 PFONT(NAME_bold, 14,
1459 "-*-courier new-bold-r-normal--14-*-*-*-*-*-*-*"),
1460 PFONT(NAME_bold, 18,
1461 "-*-courier new-bold-r-normal--18-*-*-*-*-*-*-*"),
1462 PFONT(NAME_bold, 24,
1463 "-*-courier new-bold-r-normal--24-*-*-*-*-*-*-*"),
1464 PFONT(NAME_oblique, 10,
1465 "-*-courier new-medium-o-normal--10-*-*-*-*-*-*-*"),
1466 PFONT(NAME_oblique, 12,
1467 "-*-courier new-medium-o-normal--12-*-*-*-*-*-*-*"),
1468 PFONT(NAME_oblique, 14,
1469 "-*-courier new-medium-o-normal--14-*-*-*-*-*-*-*"),
1470 PFONT(NAME_oblique, 18,
1471 "-*-courier new-medium-o-normal--18-*-*-*-*-*-*-*"),
1472 PFONT(NAME_oblique, 24,
1473 "-*-courier new-medium-o-normal--24-*-*-*-*-*-*-*"),
1474 ENDFONTLIST
1475 };
1476
1477
1478 static fontdef helvetica_fonts[] =
1479 { PFONT(NAME_bold, 10,
1480 "-*-helvetica-bold-r-normal--10-*-*-*-*-*-*-*"),
1481 PFONT(NAME_bold, 12,
1482 "-*-helvetica-bold-r-normal--12-*-*-*-*-*-*-*"),
1483 PFONT(NAME_bold, 14,
1484 "-*-helvetica-bold-r-normal--14-*-*-*-*-*-*-*"),
1485 PFONT(NAME_bold, 18,
1486 "-*-helvetica-bold-r-normal--18-*-*-*-*-*-*-*"),
1487 PFONT(NAME_bold, 24,
1488 "-*-helvetica-bold-r-normal--24-*-*-*-*-*-*-*"),
1489 PFONT(NAME_roman, 10,
1490 "-*-helvetica-medium-r-normal--10-*-*-*-*-*-*-*"),
1491 PFONT(NAME_roman, 12,
1492 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*"),
1493 PFONT(NAME_roman, 14,
1494 "-*-helvetica-medium-r-normal--14-*-*-*-*-*-*-*"),
1495 PFONT(NAME_roman, 18,
1496 "-*-helvetica-medium-r-normal--18-*-*-*-*-*-*-*"),
1497 PFONT(NAME_roman, 24,
1498 "-*-helvetica-medium-r-normal--24-*-*-*-*-*-*-*"),
1499 PFONT(NAME_oblique, 10,
1500 "-*-helvetica-medium-o-normal--10-*-*-*-*-*-*-*"),
1501 PFONT(NAME_oblique, 12,
1502 "-*-helvetica-medium-o-normal--12-*-*-*-*-*-*-*"),
1503 PFONT(NAME_oblique, 14,
1504 "-*-helvetica-medium-o-normal--14-*-*-*-*-*-*-*"),
1505 PFONT(NAME_oblique, 18,
1506 "-*-helvetica-medium-o-normal--18-*-*-*-*-*-*-*"),
1507 PFONT(NAME_oblique, 24,
1508 "-*-helvetica-medium-o-normal--24-*-*-*-*-*-*-*"),
1509 ENDFONTLIST
1510 };
1511
1512
1513 static fontdef times_fonts[] =
1514 { PFONT(NAME_roman, 10,
1515 "-*-times-medium-r-normal--10-*-*-*-*-*-*-*"),
1516 PFONT(NAME_roman, 12,
1517 "-*-times-medium-r-normal--12-*-*-*-*-*-*-*"),
1518 PFONT(NAME_roman, 14,
1519 "-*-times-medium-r-normal--14-*-*-*-*-*-*-*"),
1520 PFONT(NAME_roman, 18,
1521 "-*-times-medium-r-normal--18-*-*-*-*-*-*-*"),
1522 PFONT(NAME_roman, 24,
1523 "-*-times-medium-r-normal--24-*-*-*-*-*-*-*"),
1524 PFONT(NAME_bold, 10,
1525 "-*-times-bold-r-normal--10-*-*-*-*-*-*-*"),
1526 PFONT(NAME_bold, 12,
1527 "-*-times-bold-r-normal--12-*-*-*-*-*-*-*"),
1528 PFONT(NAME_bold, 14,
1529 "-*-times-bold-r-normal--14-*-*-*-*-*-*-*"),
1530 PFONT(NAME_bold, 18,
1531 "-*-times-bold-r-normal--18-*-*-*-*-*-*-*"),
1532 PFONT(NAME_bold, 24,
1533 "-*-times-bold-r-normal--24-*-*-*-*-*-*-*"),
1534 PFONT(NAME_italic, 10,
1535 "-*-times-medium-i-normal--10-*-*-*-*-*-*-*"),
1536 PFONT(NAME_italic, 12,
1537 "-*-times-medium-i-normal--12-*-*-*-*-*-*-*"),
1538 PFONT(NAME_italic, 14,
1539 "-*-times-medium-i-normal--14-*-*-*-*-*-*-*"),
1540 PFONT(NAME_italic, 18,
1541 "-*-times-medium-i-normal--18-*-*-*-*-*-*-*"),
1542 PFONT(NAME_italic, 24,
1543 "-*-times-medium-i-normal--24-*-*-*-*-*-*-*"),
1544 ENDFONTLIST
1545 };
1546
1547
1548 static char *
default_font_list(Name fam,FontDef defs)1549 default_font_list(Name fam, FontDef defs)
1550 { char buf[10240];
1551 char *s = buf;
1552
1553 *s++ = '[';
1554
1555 while(defs->style)
1556 {
1557 if ( defs->xname )
1558 { sprintf(s, "font(%s, %s, %d, \"%s\")",
1559 strName(fam),
1560 strName(defs->style),
1561 defs->points,
1562 defs->xname);
1563 } else
1564 { sprintf(s, "font(%s, %s, %d)",
1565 strName(fam),
1566 strName(defs->style),
1567 defs->points);
1568 }
1569 s += strlen(s);
1570 defs++;
1571 if ( defs->style )
1572 strcpy(s, ",\n");
1573 s += strlen(s);
1574 }
1575
1576 *s++ = ']';
1577 *s = EOS;
1578
1579 return save_string(buf);
1580 }
1581
1582
1583 static void
attach_fonts(Class class,char * res,Name fam,FontDef defs)1584 attach_fonts(Class class, char *res, Name fam, FontDef defs)
1585 { attach_class_variable(class, CtoName(res), "chain",
1586 default_font_list(fam, defs),
1587 "Font family set");
1588 }
1589
1590
1591 static void
attach_font_families(Class class)1592 attach_font_families(Class class)
1593 { attach_class_variable(class, NAME_fontFamilies, "chain",
1594 "[screen_fonts,courier_fonts,"
1595 "helvetica_fonts,times_fonts]",
1596 "Predefined font families");
1597
1598 attach_fonts(class, "courier_fonts", NAME_courier, courier_fonts);
1599 attach_fonts(class, "helvetica_fonts", NAME_helvetica, helvetica_fonts);
1600 attach_fonts(class, "times_fonts", NAME_times, times_fonts);
1601 attach_fonts(class, "screen_fonts", NAME_screen, screen_fonts);
1602 }
1603