]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - mac/macctrls.c
bc745140cece88e3a3485b4194bf4daa5fbe8076
[PuTTY.git] / mac / macctrls.c
1 /* $Id: macctrls.c,v 1.3 2003/03/18 19:06:51 simon Exp $ */
2 /*
3  * Copyright (c) 2003 Ben Harris
4  * All rights reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use,
10  * copy, modify, merge, publish, distribute, sublicense, and/or
11  * sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following
13  * conditions:
14  * 
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  * 
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  */
27
28 #include <MacTypes.h>
29 #include <Appearance.h>
30 #include <Controls.h>
31 #include <ControlDefinitions.h>
32 #include <Resources.h>
33 #include <Sound.h>
34 #include <TextUtils.h>
35 #include <Windows.h>
36
37 #include "putty.h"
38 #include "mac.h"
39 #include "macresid.h"
40 #include "dialog.h"
41 #include "tree234.h"
42
43 union macctrl {
44     struct macctrl_generic {
45         enum {
46             MACCTRL_TEXT,
47             MACCTRL_RADIO,
48             MACCTRL_CHECKBOX,
49             MACCTRL_BUTTON
50         } type;
51         /* Template from which this was generated */
52         union control *ctrl;
53     } generic;
54     struct {
55         struct macctrl_generic generic;
56         ControlRef tbctrl;
57     } text;
58     struct {
59         struct macctrl_generic generic;
60         ControlRef *tbctrls;
61     } radio;
62     struct {
63         struct macctrl_generic generic;
64         ControlRef tbctrl;
65     } checkbox;
66     struct {
67         struct macctrl_generic generic;
68         ControlRef tbctrl;
69     } button;
70 };
71
72 struct mac_layoutstate {
73     Point pos;
74     unsigned int width;
75 };
76
77 #define ctrlevent(mcs, mc, event) do {                                  \
78     if ((mc)->generic.ctrl->generic.handler != NULL)                    \
79         (*(mc)->generic.ctrl->generic.handler)((mc)->generic.ctrl, (mc),\
80                                                (mcs)->data, (event));   \
81 } while (0)
82
83 static void macctrl_layoutset(struct mac_layoutstate *, struct controlset *, 
84                               WindowPtr, struct macctrls *);
85 static void macctrl_text(struct macctrls *, WindowPtr,
86                          struct mac_layoutstate *, union control *);
87 static void macctrl_radio(struct macctrls *, WindowPtr,
88                           struct mac_layoutstate *, union control *);
89 static void macctrl_checkbox(struct macctrls *, WindowPtr,
90                              struct mac_layoutstate *, union control *);
91 static void macctrl_button(struct macctrls *, WindowPtr,
92                            struct mac_layoutstate *, union control *);
93 #if !TARGET_API_MAC_CARBON
94 static pascal SInt32 macctrl_sys7_text_cdef(SInt16, ControlRef,
95                                             ControlDefProcMessage, SInt32);
96 #endif
97
98 #if !TARGET_API_MAC_CARBON
99 /*
100  * This trick enables us to keep all the CDEF code in the main
101  * application, which makes life easier.  For details, see
102  * <http://developer.apple.com/technotes/tn/tn2003.html#custom_code_base>.
103  */
104
105 #pragma options align=mac68k
106 typedef struct {
107     short               jmpabs; /* 4EF9 */
108     ControlDefUPP       theUPP;
109 } **PatchCDEF;
110 #pragma options align=reset
111 #endif
112
113 static void macctrl_init()
114 {
115 #if !TARGET_API_MAC_CARBON
116     static int inited = 0;
117     PatchCDEF cdef;
118
119     if (inited) return;
120     cdef = (PatchCDEF)GetResource(kControlDefProcResourceType, CDEF_Text);
121     (*cdef)->theUPP = NewControlDefProc(macctrl_sys7_text_cdef);
122     inited = 1;
123 #endif
124 }
125
126
127 static int macctrl_cmp_byctrl(void *av, void *bv)
128 {
129     union macctrl *a = (union macctrl *)av;
130     union macctrl *b = (union macctrl *)bv;
131
132     if (a->generic.ctrl < b->generic.ctrl)
133         return -1;
134     else if (a->generic.ctrl > b->generic.ctrl)
135         return +1;
136     else
137         return 0;
138 }
139
140 void macctrl_layoutbox(struct controlbox *cb, WindowPtr window,
141                        struct macctrls *mcs)
142 {
143     int i;
144     struct mac_layoutstate curstate;
145     ControlRef root;
146     Rect rect;
147
148     macctrl_init();
149 #if TARGET_API_MAC_CARBON
150     GetPortBounds(GetWindowPort(window), &rect);
151 #else
152     rect = window->portRect;
153 #endif
154     curstate.pos.h = rect.left + 13;
155     curstate.pos.v = rect.top + 13;
156     curstate.width = rect.right - rect.left - (13 * 2);
157     if (mac_gestalts.apprvers >= 0x100)
158         CreateRootControl(window, &root);
159     mcs->byctrl = newtree234(macctrl_cmp_byctrl);
160     for (i = 0; i < cb->nctrlsets; i++)
161         macctrl_layoutset(&curstate, cb->ctrlsets[i], window, mcs);
162 }
163
164 static void macctrl_layoutset(struct mac_layoutstate *curstate,
165                               struct controlset *s,
166                               WindowPtr window, struct macctrls *mcs)
167 {
168     unsigned int i;
169
170     fprintf(stderr, "--- begin set ---\n");
171     if (s->boxname && *s->boxname)
172         fprintf(stderr, "boxname = %s\n", s->boxname);
173     if (s->boxtitle)
174         fprintf(stderr, "boxtitle = %s\n", s->boxtitle);
175
176
177     for (i = 0; i < s->ncontrols; i++) {
178         union control *ctrl = s->ctrls[i];
179         char const *s;
180
181         switch (ctrl->generic.type) {
182           case CTRL_TEXT: s = "text"; break;
183           case CTRL_EDITBOX: s = "editbox"; break;
184           case CTRL_RADIO: s = "radio"; break;
185           case CTRL_CHECKBOX: s = "checkbox"; break;
186           case CTRL_BUTTON: s = "button"; break;
187           case CTRL_LISTBOX: s = "listbox"; break;
188           case CTRL_COLUMNS: s = "columns"; break;
189           case CTRL_FILESELECT: s = "fileselect"; break;
190           case CTRL_FONTSELECT: s = "fontselect"; break;
191           case CTRL_TABDELAY: s = "tabdelay"; break;
192           default: s = "unknown"; break;
193         }
194         fprintf(stderr, "  control: %s\n", s);
195         switch (ctrl->generic.type) {
196           case CTRL_TEXT:
197             macctrl_text(mcs, window, curstate, ctrl);
198             break;
199           case CTRL_RADIO:
200             macctrl_radio(mcs, window, curstate, ctrl);
201             break;
202           case CTRL_CHECKBOX:
203             macctrl_checkbox(mcs, window, curstate, ctrl);
204             break;
205           case CTRL_BUTTON:
206             macctrl_button(mcs, window, curstate, ctrl);
207             break;
208
209         }
210     }
211 }
212
213 static void macctrl_text(struct macctrls *mcs, WindowPtr window,
214                          struct mac_layoutstate *curstate,
215                          union control *ctrl)
216 {
217     union macctrl *mc = smalloc(sizeof *mc);
218     Rect bounds;
219
220     fprintf(stderr, "    label = %s\n", ctrl->text.label);
221     mc->generic.type = MACCTRL_TEXT;
222     mc->generic.ctrl = ctrl;
223     bounds.left = curstate->pos.h;
224     bounds.right = bounds.left + curstate->width;
225     bounds.top = curstate->pos.v;
226     bounds.bottom = bounds.top + 16;
227     if (mac_gestalts.apprvers >= 0x100) {
228         SInt16 height;
229         Size olen;
230
231         mc->text.tbctrl = NewControl(window, &bounds, NULL, TRUE, 0, 0, 0,
232                                      kControlStaticTextProc, (long)mc);
233         SetControlData(mc->text.tbctrl, kControlEntireControl,
234                        kControlStaticTextTextTag,
235                        strlen(ctrl->text.label), ctrl->text.label);
236         GetControlData(mc->text.tbctrl, kControlEntireControl,
237                        kControlStaticTextTextHeightTag,
238                        sizeof(height), &height, &olen);
239         fprintf(stderr, "    height = %d\n", height);
240         SizeControl(mc->text.tbctrl, curstate->width, height);
241         curstate->pos.v += height + 6;
242     } else {
243         Str255 title;
244
245         c2pstrcpy(title, ctrl->text.label);
246         mc->text.tbctrl = NewControl(window, &bounds, title, TRUE, 0, 0, 0,
247                                      SYS7_TEXT_PROC, (long)mc);
248     }
249     add234(mcs->byctrl, mc);
250 }
251
252 #if !TARGET_API_MAC_CARBON
253 static pascal SInt32 macctrl_sys7_text_cdef(SInt16 variant, ControlRef control,
254                                      ControlDefProcMessage msg, SInt32 param)
255 {
256     RgnHandle rgn;
257
258     switch (msg) {
259       case drawCntl:
260         if ((*control)->contrlVis)
261             TETextBox((*control)->contrlTitle + 1, (*control)->contrlTitle[0],
262                       &(*control)->contrlRect, teFlushDefault);
263         return 0;
264       case calcCRgns:
265         if (param & (1 << 31)) {
266             param &= ~(1 << 31);
267             goto calcthumbrgn;
268         }
269         /* FALLTHROUGH */
270       case calcCntlRgn:
271         rgn = (RgnHandle)param;
272         RectRgn(rgn, &(*control)->contrlRect);
273         return 0;
274       case calcThumbRgn:
275       calcthumbrgn:
276         rgn = (RgnHandle)param;
277         SetEmptyRgn(rgn);
278         return 0;
279     }
280
281     return 0;
282 }
283 #endif
284
285 static void macctrl_radio(struct macctrls *mcs, WindowPtr window,
286                           struct mac_layoutstate *curstate,
287                           union control *ctrl)
288 {
289     union macctrl *mc = smalloc(sizeof *mc);
290     Rect bounds;
291     Str255 title;
292     unsigned int i, colwidth;
293
294     fprintf(stderr, "    label = %s\n", ctrl->radio.label);
295     mc->generic.type = MACCTRL_RADIO;
296     mc->generic.ctrl = ctrl;
297     mc->radio.tbctrls =
298         smalloc(sizeof(*mc->radio.tbctrls) * ctrl->radio.nbuttons);
299     colwidth = (curstate->width + 13) / ctrl->radio.ncolumns;
300     for (i = 0; i < ctrl->radio.nbuttons; i++) {
301         fprintf(stderr, "    button = %s\n", ctrl->radio.buttons[i]);
302         bounds.top = curstate->pos.v;
303         bounds.bottom = bounds.top + 16;
304         bounds.left = curstate->pos.h + colwidth * (i % ctrl->radio.ncolumns);
305         if (i == ctrl->radio.nbuttons - 1 ||
306             i % ctrl->radio.ncolumns == ctrl->radio.ncolumns - 1) {
307             bounds.right = curstate->pos.h + curstate->width;
308             curstate->pos.v += 22;
309         } else
310             bounds.right = bounds.left + colwidth - 13;
311         c2pstrcpy(title, ctrl->radio.buttons[i]);
312         mc->radio.tbctrls[i] = NewControl(window, &bounds, title, TRUE,
313                                           0, 0, 1, radioButProc, (long)mc);
314     }
315     add234(mcs->byctrl, mc);
316     ctrlevent(mcs, mc, EVENT_REFRESH);
317 }
318
319 static void macctrl_checkbox(struct macctrls *mcs, WindowPtr window,
320                              struct mac_layoutstate *curstate,
321                              union control *ctrl)
322 {
323     union macctrl *mc = smalloc(sizeof *mc);
324     Rect bounds;
325     Str255 title;
326
327     fprintf(stderr, "    label = %s\n", ctrl->checkbox.label);
328     mc->generic.type = MACCTRL_CHECKBOX;
329     mc->generic.ctrl = ctrl;
330     bounds.left = curstate->pos.h;
331     bounds.right = bounds.left + curstate->width;
332     bounds.top = curstate->pos.v;
333     bounds.bottom = bounds.top + 16;
334     c2pstrcpy(title, ctrl->checkbox.label);
335     mc->checkbox.tbctrl = NewControl(window, &bounds, title, TRUE, 0, 0, 1,
336                                      checkBoxProc, (long)mc);
337     add234(mcs->byctrl, mc);
338     curstate->pos.v += 22;
339     ctrlevent(mcs, mc, EVENT_REFRESH);
340 }
341
342 static void macctrl_button(struct macctrls *mcs, WindowPtr window,
343                            struct mac_layoutstate *curstate,
344                            union control *ctrl)
345 {
346     union macctrl *mc = smalloc(sizeof *mc);
347     Rect bounds;
348     Str255 title;
349
350     fprintf(stderr, "    label = %s\n", ctrl->button.label);
351     if (ctrl->button.isdefault)
352         fprintf(stderr, "    is default\n");
353     mc->generic.type = MACCTRL_BUTTON;
354     mc->generic.ctrl = ctrl;
355     bounds.left = curstate->pos.h;
356     bounds.right = bounds.left + 100; /* XXX measure string */
357     bounds.top = curstate->pos.v;
358     bounds.bottom = bounds.top + 20;
359     c2pstrcpy(title, ctrl->button.label);
360     mc->button.tbctrl = NewControl(window, &bounds, title, TRUE, 0, 0, 1,
361                                    pushButProc, (long)mc);
362     if (mac_gestalts.apprvers >= 0x100) {
363         Boolean isdefault = ctrl->button.isdefault;
364
365         SetControlData(mc->button.tbctrl, kControlEntireControl,
366                        kControlPushButtonDefaultTag,
367                        sizeof(isdefault), &isdefault);
368     }
369     add234(mcs->byctrl, mc);
370     curstate->pos.v += 26;
371 }
372
373
374 void macctrl_activate(WindowPtr window, EventRecord *event)
375 {
376     Boolean active = (event->modifiers & activeFlag) != 0;
377     GrafPtr saveport;
378     ControlRef root;
379
380     GetPort(&saveport);
381     SetPort((GrafPtr)GetWindowPort(window));
382     if (mac_gestalts.apprvers >= 0x100) {
383         SetThemeWindowBackground(window, active ?
384                                  kThemeBrushModelessDialogBackgroundActive :
385                                  kThemeBrushModelessDialogBackgroundInactive,
386                                  TRUE);
387         GetRootControl(window, &root);
388         if (active)
389             ActivateControl(root);
390         else
391             DeactivateControl(root);
392     } else {
393         /* (De)activate controls one at a time */
394     }
395     SetPort(saveport);
396 }
397
398 void macctrl_click(WindowPtr window, EventRecord *event)
399 {
400     Point mouse;
401     ControlHandle control;
402     int part;
403     GrafPtr saveport;
404     union macctrl *mc;
405     struct macctrls *mcs = mac_winctrls(window);
406     int i;
407
408     GetPort(&saveport);
409     SetPort((GrafPtr)GetWindowPort(window));
410     mouse = event->where;
411     GlobalToLocal(&mouse);
412     part = FindControl(mouse, window, &control);
413     if (control != NULL)
414         if (TrackControl(control, mouse, NULL) != 0) {
415             mc = (union macctrl *)GetControlReference(control);
416             switch (mc->generic.type) {
417               case MACCTRL_RADIO:
418                 for (i = 0; i < mc->generic.ctrl->radio.nbuttons; i++) {
419                     if (mc->radio.tbctrls[i] == control)
420                         SetControlValue(mc->radio.tbctrls[i],
421                                         kControlRadioButtonCheckedValue);
422                     else
423                         SetControlValue(mc->radio.tbctrls[i],
424                                         kControlRadioButtonUncheckedValue);
425                 }
426                 ctrlevent(mcs, mc, EVENT_VALCHANGE);
427                 break;
428               case MACCTRL_CHECKBOX:
429                 SetControlValue(control, !GetControlValue(control));
430                 ctrlevent(mcs, mc, EVENT_VALCHANGE);
431                 break;
432               case MACCTRL_BUTTON:
433                 ctrlevent(mcs, mc, EVENT_ACTION);
434                 break;
435             }
436         }
437     SetPort(saveport);
438 }
439
440 void macctrl_update(WindowPtr window)
441 {
442 #if TARGET_API_MAC_CARBON
443     RgnHandle visrgn;
444 #endif
445     Rect rect;
446     GrafPtr saveport;
447
448     BeginUpdate(window);
449     GetPort(&saveport);
450     SetPort((GrafPtr)GetWindowPort(window));
451     if (mac_gestalts.apprvers >= 0x101) {
452 #if TARGET_API_MAC_CARBON
453         GetPortBounds(GetWindowPort(window), &rect);
454 #else
455         rect = window->portRect;
456 #endif
457         InsetRect(&rect, -1, -1);
458         DrawThemeModelessDialogFrame(&rect, mac_frontwindow() == window ?
459                                      kThemeStateActive : kThemeStateInactive);
460     }
461 #if TARGET_API_MAC_CARBON
462     visrgn = NewRgn();
463     GetPortVisibleRegion(GetWindowPort(window), visrgn);
464     UpdateControls(window, visrgn);
465     DisposeRgn(visrgn);
466 #else
467     UpdateControls(window, window->visRgn);
468 #endif
469     SetPort(saveport);
470     EndUpdate(window);
471 }
472
473 #if TARGET_API_MAC_CARBON
474 #define EnableItem EnableMenuItem
475 #define DisableItem DisableMenuItem
476 #endif
477 void macctrl_adjustmenus(WindowPtr window)
478 {
479     MenuHandle menu;
480
481     menu = GetMenuHandle(mFile);
482     DisableItem(menu, iSave); /* XXX enable if modified */
483     EnableItem(menu, iSaveAs);
484     EnableItem(menu, iDuplicate);
485
486     menu = GetMenuHandle(mEdit);
487     DisableItem(menu, 0);
488 }
489
490 void macctrl_close(WindowPtr window)
491 {
492     struct macctrls *mcs = mac_winctrls(window);
493     union macctrl *mc;
494
495     while ((mc = index234(mcs->byctrl, 0)) != NULL) {
496         del234(mcs->byctrl, mc);
497         sfree(mc);
498     }
499
500     freetree234(mcs->byctrl);
501     mcs->byctrl = NULL;
502
503 /* XXX
504     DisposeWindow(window);
505     if (s->window == NULL)
506         sfree(s);
507 */
508 }
509
510 void dlg_update_start(union control *ctrl, void *dlg)
511 {
512
513     /* No-op for now */
514 }
515
516 void dlg_update_done(union control *ctrl, void *dlg)
517 {
518
519     /* No-op for now */
520 }
521
522 void dlg_set_focus(union control *ctrl, void *dlg)
523 {
524
525     if (mac_gestalts.apprvers >= 0x100) {
526         /* Use SetKeyboardFocus() */
527     } else {
528         /* Do our own mucking around */
529     }
530 }
531
532 union control *dlg_last_focused(union control *ctrl, void *dlg)
533 {
534
535     return NULL;
536 }
537
538 void dlg_beep(void *dlg)
539 {
540
541     SysBeep(30);
542 }
543
544 void dlg_error_msg(void *dlg, char *msg)
545 {
546     Str255 pmsg;
547
548     c2pstrcpy(pmsg, msg);
549     ParamText(pmsg, NULL, NULL, NULL);
550     StopAlert(128, NULL);
551 }
552
553 void dlg_end(void *dlg, int value)
554 {
555
556 };
557
558 void dlg_refresh(union control *ctrl, void *dlg)
559 {
560
561 };
562
563 void *dlg_get_privdata(union control *ctrl, void *dlg)
564 {
565
566     return NULL;
567 }
568
569 void dlg_set_privdata(union control *ctrl, void *dlg, void *ptr)
570 {
571
572     fatalbox("dlg_set_privdata");
573 }
574
575 void *dlg_alloc_privdata(union control *ctrl, void *dlg, size_t size)
576 {
577
578     fatalbox("dlg_alloc_privdata");
579 }
580
581
582 /*
583  * Radio Button control
584  */
585
586 void dlg_radiobutton_set(union control *ctrl, void *dlg, int whichbutton)
587 {
588     union macctrl *mc = dlg;
589     int i;
590
591     for (i = 0; i < ctrl->radio.nbuttons; i++) {
592         if (i == whichbutton)
593             SetControlValue(mc->radio.tbctrls[i],
594                             kControlRadioButtonCheckedValue);
595         else
596             SetControlValue(mc->radio.tbctrls[i],
597                             kControlRadioButtonUncheckedValue);
598     }
599
600 };
601
602 int dlg_radiobutton_get(union control *ctrl, void *dlg)
603 {
604     union macctrl *mc = dlg;
605     int i;
606
607     for (i = 0; i < ctrl->radio.nbuttons; i++) {
608         if (GetControlValue(mc->radio.tbctrls[i])  ==
609             kControlRadioButtonCheckedValue)
610             return i;
611     }
612     return -1;
613 };
614
615
616 /*
617  * Check Box control
618  */
619
620 void dlg_checkbox_set(union control *ctrl, void *dlg, int checked)
621 {
622     union macctrl *mc = dlg;
623
624     SetControlValue(mc->checkbox.tbctrl,
625                     checked ? kControlCheckBoxCheckedValue :
626                               kControlCheckBoxUncheckedValue);
627 }
628
629 int dlg_checkbox_get(union control *ctrl, void *dlg)
630 {
631     union macctrl *mc = dlg;
632
633     return GetControlValue(mc->checkbox.tbctrl);
634 }
635
636
637 /*
638  * Edit Box control
639  */
640
641 void dlg_editbox_set(union control *ctrl, void *dlg, char const *text)
642 {
643
644 };
645
646 void dlg_editbox_get(union control *ctrl, void *dlg, char *buffer, int length)
647 {
648
649 };
650
651
652 /*
653  * List Box control
654  */
655
656 void dlg_listbox_clear(union control *ctrl, void *dlg)
657 {
658
659 };
660
661 void dlg_listbox_del(union control *ctrl, void *dlg, int index)
662 {
663
664 };
665
666 void dlg_listbox_add(union control *ctrl, void *dlg, char const *text)
667 {
668
669 };
670
671 void dlg_listbox_addwithindex(union control *ctrl, void *dlg,
672                               char const *text, int id)
673 {
674
675 };
676
677 int dlg_listbox_getid(union control *ctrl, void *dlg, int index)
678 {
679
680     return 0;
681 };
682
683 int dlg_listbox_index(union control *ctrl, void *dlg)
684 {
685
686     return 0;
687 };
688
689 int dlg_listbox_issel(union control *ctrl, void *dlg, int index)
690 {
691
692     return 0;
693 };
694
695 void dlg_listbox_select(union control *ctrl, void *dlg, int index)
696 {
697
698 };
699
700
701 /*
702  * Text control
703  */
704
705 void dlg_text_set(union control *ctrl, void *dlg, char const *text)
706 {
707     union macctrl *mc = dlg;
708
709     if (mac_gestalts.apprvers >= 0x100)
710         SetControlData(mc->text.tbctrl, kControlEntireControl,
711                        kControlStaticTextTextTag,
712                        strlen(ctrl->text.label), ctrl->text.label);
713 }
714
715
716 /*
717  * File Selector control
718  */
719
720 void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn)
721 {
722
723 }
724
725 void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn)
726 {
727
728 }
729
730
731 /*
732  * Font Selector control
733  */
734
735 void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec fn)
736 {
737
738 }
739
740 void dlg_fontsel_get(union control *ctrl, void *dlg, FontSpec *fn)
741 {
742
743 }
744
745
746 /*
747  * Printer enumeration
748  */
749
750 printer_enum *printer_start_enum(int *nprinters)
751 {
752
753     *nprinters = 0;
754     return NULL;
755 }
756
757 char *printer_get_name(printer_enum *pe, int thing)
758 {
759
760     return "<none>";
761 }
762
763 void printer_finish_enum(printer_enum *pe)
764 {
765
766 }
767
768
769 /*
770  * Colour selection stuff
771  */
772
773 void dlg_coloursel_start(union control *ctrl, void *dlg,
774                          int r, int g, int b)
775 {
776
777 }
778
779 int dlg_coloursel_results(union control *ctrl, void *dlg,
780                           int *r, int *g, int *b)
781 {
782
783     return 0;
784 }
785
786 /*
787  * Local Variables:
788  * c-file-style: "simon"
789  * End:
790  */