Various cosmetic fixes to the GTK config box: vertical alignment of
[u/mdw/putty] / mac / macctrls.c
CommitLineData
ee10bc56 1/* $Id: macctrls.c,v 1.8 2003/03/21 00:24:17 ben Exp $ */
8a7e67ec 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>
fa4942e7 32#include <Resources.h>
8a7e67ec 33#include <Sound.h>
34#include <TextUtils.h>
35#include <Windows.h>
36
93ba25f8 37#include <assert.h>
ee10bc56 38#include <string.h>
93ba25f8 39
8a7e67ec 40#include "putty.h"
41#include "mac.h"
42#include "macresid.h"
43#include "dialog.h"
44#include "tree234.h"
45
46union macctrl {
47 struct macctrl_generic {
48 enum {
49 MACCTRL_TEXT,
50 MACCTRL_RADIO,
51 MACCTRL_CHECKBOX,
52 MACCTRL_BUTTON
53 } type;
54 /* Template from which this was generated */
55 union control *ctrl;
ee10bc56 56 /* Next control in this panel */
57 union macctrl *next;
8a7e67ec 58 } generic;
59 struct {
60 struct macctrl_generic generic;
61 ControlRef tbctrl;
62 } text;
63 struct {
64 struct macctrl_generic generic;
65 ControlRef *tbctrls;
66 } radio;
67 struct {
68 struct macctrl_generic generic;
69 ControlRef tbctrl;
70 } checkbox;
71 struct {
72 struct macctrl_generic generic;
73 ControlRef tbctrl;
74 } button;
75};
76
77struct mac_layoutstate {
78 Point pos;
79 unsigned int width;
ee10bc56 80 unsigned int panelnum;
8a7e67ec 81};
82
83#define ctrlevent(mcs, mc, event) do { \
84 if ((mc)->generic.ctrl->generic.handler != NULL) \
93ba25f8 85 (*(mc)->generic.ctrl->generic.handler)((mc)->generic.ctrl, (mcs),\
8a7e67ec 86 (mcs)->data, (event)); \
87} while (0)
88
93ba25f8 89#define findbyctrl(mcs, ctrl) \
90 find234((mcs)->byctrl, (ctrl), macctrl_cmp_byctrl_find)
91
8a7e67ec 92static void macctrl_layoutset(struct mac_layoutstate *, struct controlset *,
93 WindowPtr, struct macctrls *);
ee10bc56 94static void macctrl_switchtopanel(struct macctrls *, unsigned int);
8a7e67ec 95static void macctrl_text(struct macctrls *, WindowPtr,
96 struct mac_layoutstate *, union control *);
97static void macctrl_radio(struct macctrls *, WindowPtr,
98 struct mac_layoutstate *, union control *);
99static void macctrl_checkbox(struct macctrls *, WindowPtr,
100 struct mac_layoutstate *, union control *);
101static void macctrl_button(struct macctrls *, WindowPtr,
102 struct mac_layoutstate *, union control *);
fa4942e7 103#if !TARGET_API_MAC_CARBON
104static pascal SInt32 macctrl_sys7_text_cdef(SInt16, ControlRef,
105 ControlDefProcMessage, SInt32);
5537f572 106static pascal SInt32 macctrl_sys7_default_cdef(SInt16, ControlRef,
107 ControlDefProcMessage, SInt32);
fa4942e7 108#endif
109
110#if !TARGET_API_MAC_CARBON
111/*
112 * This trick enables us to keep all the CDEF code in the main
113 * application, which makes life easier. For details, see
114 * <http://developer.apple.com/technotes/tn/tn2003.html#custom_code_base>.
115 */
116
117#pragma options align=mac68k
118typedef struct {
119 short jmpabs; /* 4EF9 */
120 ControlDefUPP theUPP;
121} **PatchCDEF;
122#pragma options align=reset
123#endif
124
125static void macctrl_init()
126{
127#if !TARGET_API_MAC_CARBON
128 static int inited = 0;
129 PatchCDEF cdef;
130
131 if (inited) return;
132 cdef = (PatchCDEF)GetResource(kControlDefProcResourceType, CDEF_Text);
133 (*cdef)->theUPP = NewControlDefProc(macctrl_sys7_text_cdef);
5537f572 134 cdef = (PatchCDEF)GetResource(kControlDefProcResourceType, CDEF_Default);
135 (*cdef)->theUPP = NewControlDefProc(macctrl_sys7_default_cdef);
fa4942e7 136 inited = 1;
137#endif
138}
139
8a7e67ec 140
141static int macctrl_cmp_byctrl(void *av, void *bv)
142{
143 union macctrl *a = (union macctrl *)av;
144 union macctrl *b = (union macctrl *)bv;
145
146 if (a->generic.ctrl < b->generic.ctrl)
147 return -1;
148 else if (a->generic.ctrl > b->generic.ctrl)
149 return +1;
150 else
151 return 0;
152}
153
93ba25f8 154static int macctrl_cmp_byctrl_find(void *av, void *bv)
155{
156 union control *a = (union control *)av;
157 union macctrl *b = (union macctrl *)bv;
158
159 if (a < b->generic.ctrl)
160 return -1;
161 else if (a > b->generic.ctrl)
162 return +1;
163 else
164 return 0;
165}
166
8a7e67ec 167void macctrl_layoutbox(struct controlbox *cb, WindowPtr window,
168 struct macctrls *mcs)
169{
170 int i;
171 struct mac_layoutstate curstate;
172 ControlRef root;
173 Rect rect;
fa4942e7 174
175 macctrl_init();
8a7e67ec 176#if TARGET_API_MAC_CARBON
177 GetPortBounds(GetWindowPort(window), &rect);
178#else
179 rect = window->portRect;
180#endif
181 curstate.pos.h = rect.left + 13;
ee10bc56 182 curstate.pos.v = rect.bottom - 59;
8a7e67ec 183 curstate.width = rect.right - rect.left - (13 * 2);
184 if (mac_gestalts.apprvers >= 0x100)
185 CreateRootControl(window, &root);
186 mcs->byctrl = newtree234(macctrl_cmp_byctrl);
ee10bc56 187 /* Count the number of panels */
188 mcs->npanels = 1;
189 for (i = 1; i < cb->nctrlsets; i++)
190 if (strcmp(cb->ctrlsets[i]->pathname, cb->ctrlsets[i-1]->pathname))
191 mcs->npanels++;
192 mcs->panels = smalloc(sizeof(*mcs->panels) * mcs->npanels);
193 memset(mcs->panels, 0, sizeof(*mcs->panels) * mcs->npanels);
194 curstate.panelnum = 0;
195 for (i = 0; i < cb->nctrlsets; i++) {
196 if (i > 0 && strcmp(cb->ctrlsets[i]->pathname,
197 cb->ctrlsets[i-1]->pathname)) {
198 curstate.pos.v = rect.top + 13;
199 curstate.panelnum++;
200 assert(curstate.panelnum < mcs->npanels);
201 }
8a7e67ec 202 macctrl_layoutset(&curstate, cb->ctrlsets[i], window, mcs);
ee10bc56 203 }
204 macctrl_switchtopanel(mcs, 1);
8a7e67ec 205}
206
207static void macctrl_layoutset(struct mac_layoutstate *curstate,
208 struct controlset *s,
209 WindowPtr window, struct macctrls *mcs)
210{
211 unsigned int i;
212
213 fprintf(stderr, "--- begin set ---\n");
93ba25f8 214 fprintf(stderr, "pathname = %s\n", s->pathname);
8a7e67ec 215 if (s->boxname && *s->boxname)
216 fprintf(stderr, "boxname = %s\n", s->boxname);
217 if (s->boxtitle)
218 fprintf(stderr, "boxtitle = %s\n", s->boxtitle);
219
220
221 for (i = 0; i < s->ncontrols; i++) {
222 union control *ctrl = s->ctrls[i];
223 char const *s;
224
225 switch (ctrl->generic.type) {
226 case CTRL_TEXT: s = "text"; break;
227 case CTRL_EDITBOX: s = "editbox"; break;
228 case CTRL_RADIO: s = "radio"; break;
229 case CTRL_CHECKBOX: s = "checkbox"; break;
230 case CTRL_BUTTON: s = "button"; break;
231 case CTRL_LISTBOX: s = "listbox"; break;
232 case CTRL_COLUMNS: s = "columns"; break;
233 case CTRL_FILESELECT: s = "fileselect"; break;
234 case CTRL_FONTSELECT: s = "fontselect"; break;
235 case CTRL_TABDELAY: s = "tabdelay"; break;
236 default: s = "unknown"; break;
237 }
238 fprintf(stderr, " control: %s\n", s);
239 switch (ctrl->generic.type) {
240 case CTRL_TEXT:
241 macctrl_text(mcs, window, curstate, ctrl);
242 break;
243 case CTRL_RADIO:
244 macctrl_radio(mcs, window, curstate, ctrl);
245 break;
246 case CTRL_CHECKBOX:
247 macctrl_checkbox(mcs, window, curstate, ctrl);
248 break;
249 case CTRL_BUTTON:
250 macctrl_button(mcs, window, curstate, ctrl);
251 break;
252
253 }
254 }
255}
256
ee10bc56 257static void macctrl_switchtopanel(struct macctrls *mcs, unsigned int which)
258{
259 unsigned int i, j;
260 union macctrl *mc;
261
262 /* Panel 0 is special and always visible. */
263 for (i = 1; i < mcs->npanels; i++)
264 for (mc = mcs->panels[i]; mc != NULL; mc = mc->generic.next)
265 switch (mc->generic.type) {
266 case MACCTRL_TEXT:
267 if (i == which)
268 ShowControl(mc->text.tbctrl);
269 else
270 HideControl(mc->text.tbctrl);
271 break;
272 case MACCTRL_RADIO:
273 for (j = 0; j < mc->generic.ctrl->radio.nbuttons; j++)
274 if (i == which)
275 ShowControl(mc->radio.tbctrls[j]);
276 else
277 HideControl(mc->radio.tbctrls[j]);
278 break;
279 case MACCTRL_CHECKBOX:
280 if (i == which)
281 ShowControl(mc->checkbox.tbctrl);
282 else
283 HideControl(mc->checkbox.tbctrl);
284 break;
285 case MACCTRL_BUTTON:
286 if (i == which)
287 ShowControl(mc->button.tbctrl);
288 else
289 HideControl(mc->button.tbctrl);
290 break;
291
292 }
293}
294
8a7e67ec 295static void macctrl_text(struct macctrls *mcs, WindowPtr window,
296 struct mac_layoutstate *curstate,
297 union control *ctrl)
298{
299 union macctrl *mc = smalloc(sizeof *mc);
300 Rect bounds;
301
302 fprintf(stderr, " label = %s\n", ctrl->text.label);
303 mc->generic.type = MACCTRL_TEXT;
304 mc->generic.ctrl = ctrl;
305 bounds.left = curstate->pos.h;
306 bounds.right = bounds.left + curstate->width;
307 bounds.top = curstate->pos.v;
308 bounds.bottom = bounds.top + 16;
309 if (mac_gestalts.apprvers >= 0x100) {
310 SInt16 height;
311 Size olen;
312
313 mc->text.tbctrl = NewControl(window, &bounds, NULL, TRUE, 0, 0, 0,
314 kControlStaticTextProc, (long)mc);
315 SetControlData(mc->text.tbctrl, kControlEntireControl,
316 kControlStaticTextTextTag,
317 strlen(ctrl->text.label), ctrl->text.label);
318 GetControlData(mc->text.tbctrl, kControlEntireControl,
319 kControlStaticTextTextHeightTag,
320 sizeof(height), &height, &olen);
321 fprintf(stderr, " height = %d\n", height);
322 SizeControl(mc->text.tbctrl, curstate->width, height);
323 curstate->pos.v += height + 6;
324 } else {
fa4942e7 325 Str255 title;
326
327 c2pstrcpy(title, ctrl->text.label);
328 mc->text.tbctrl = NewControl(window, &bounds, title, TRUE, 0, 0, 0,
329 SYS7_TEXT_PROC, (long)mc);
8a7e67ec 330 }
331 add234(mcs->byctrl, mc);
ee10bc56 332 mc->generic.next = mcs->panels[curstate->panelnum];
333 mcs->panels[curstate->panelnum] = mc;
8a7e67ec 334}
335
fa4942e7 336#if !TARGET_API_MAC_CARBON
337static pascal SInt32 macctrl_sys7_text_cdef(SInt16 variant, ControlRef control,
338 ControlDefProcMessage msg, SInt32 param)
339{
340 RgnHandle rgn;
341
342 switch (msg) {
343 case drawCntl:
344 if ((*control)->contrlVis)
345 TETextBox((*control)->contrlTitle + 1, (*control)->contrlTitle[0],
346 &(*control)->contrlRect, teFlushDefault);
347 return 0;
348 case calcCRgns:
349 if (param & (1 << 31)) {
350 param &= ~(1 << 31);
351 goto calcthumbrgn;
352 }
353 /* FALLTHROUGH */
354 case calcCntlRgn:
355 rgn = (RgnHandle)param;
356 RectRgn(rgn, &(*control)->contrlRect);
357 return 0;
358 case calcThumbRgn:
359 calcthumbrgn:
360 rgn = (RgnHandle)param;
361 SetEmptyRgn(rgn);
362 return 0;
363 }
364
365 return 0;
366}
367#endif
368
8a7e67ec 369static void macctrl_radio(struct macctrls *mcs, WindowPtr window,
370 struct mac_layoutstate *curstate,
371 union control *ctrl)
372{
373 union macctrl *mc = smalloc(sizeof *mc);
374 Rect bounds;
375 Str255 title;
376 unsigned int i, colwidth;
377
378 fprintf(stderr, " label = %s\n", ctrl->radio.label);
379 mc->generic.type = MACCTRL_RADIO;
380 mc->generic.ctrl = ctrl;
381 mc->radio.tbctrls =
382 smalloc(sizeof(*mc->radio.tbctrls) * ctrl->radio.nbuttons);
383 colwidth = (curstate->width + 13) / ctrl->radio.ncolumns;
384 for (i = 0; i < ctrl->radio.nbuttons; i++) {
385 fprintf(stderr, " button = %s\n", ctrl->radio.buttons[i]);
386 bounds.top = curstate->pos.v;
387 bounds.bottom = bounds.top + 16;
388 bounds.left = curstate->pos.h + colwidth * (i % ctrl->radio.ncolumns);
389 if (i == ctrl->radio.nbuttons - 1 ||
390 i % ctrl->radio.ncolumns == ctrl->radio.ncolumns - 1) {
391 bounds.right = curstate->pos.h + curstate->width;
392 curstate->pos.v += 22;
393 } else
394 bounds.right = bounds.left + colwidth - 13;
395 c2pstrcpy(title, ctrl->radio.buttons[i]);
396 mc->radio.tbctrls[i] = NewControl(window, &bounds, title, TRUE,
397 0, 0, 1, radioButProc, (long)mc);
398 }
399 add234(mcs->byctrl, mc);
ee10bc56 400 mc->generic.next = mcs->panels[curstate->panelnum];
401 mcs->panels[curstate->panelnum] = mc;
8a7e67ec 402 ctrlevent(mcs, mc, EVENT_REFRESH);
403}
404
405static void macctrl_checkbox(struct macctrls *mcs, WindowPtr window,
406 struct mac_layoutstate *curstate,
407 union control *ctrl)
408{
409 union macctrl *mc = smalloc(sizeof *mc);
410 Rect bounds;
411 Str255 title;
412
413 fprintf(stderr, " label = %s\n", ctrl->checkbox.label);
414 mc->generic.type = MACCTRL_CHECKBOX;
415 mc->generic.ctrl = ctrl;
416 bounds.left = curstate->pos.h;
417 bounds.right = bounds.left + curstate->width;
418 bounds.top = curstate->pos.v;
419 bounds.bottom = bounds.top + 16;
420 c2pstrcpy(title, ctrl->checkbox.label);
421 mc->checkbox.tbctrl = NewControl(window, &bounds, title, TRUE, 0, 0, 1,
422 checkBoxProc, (long)mc);
423 add234(mcs->byctrl, mc);
424 curstate->pos.v += 22;
ee10bc56 425 mc->generic.next = mcs->panels[curstate->panelnum];
426 mcs->panels[curstate->panelnum] = mc;
8a7e67ec 427 ctrlevent(mcs, mc, EVENT_REFRESH);
428}
429
430static void macctrl_button(struct macctrls *mcs, WindowPtr window,
431 struct mac_layoutstate *curstate,
432 union control *ctrl)
433{
434 union macctrl *mc = smalloc(sizeof *mc);
435 Rect bounds;
436 Str255 title;
437
438 fprintf(stderr, " label = %s\n", ctrl->button.label);
439 if (ctrl->button.isdefault)
440 fprintf(stderr, " is default\n");
441 mc->generic.type = MACCTRL_BUTTON;
442 mc->generic.ctrl = ctrl;
443 bounds.left = curstate->pos.h;
444 bounds.right = bounds.left + 100; /* XXX measure string */
445 bounds.top = curstate->pos.v;
446 bounds.bottom = bounds.top + 20;
447 c2pstrcpy(title, ctrl->button.label);
448 mc->button.tbctrl = NewControl(window, &bounds, title, TRUE, 0, 0, 1,
449 pushButProc, (long)mc);
450 if (mac_gestalts.apprvers >= 0x100) {
451 Boolean isdefault = ctrl->button.isdefault;
452
453 SetControlData(mc->button.tbctrl, kControlEntireControl,
454 kControlPushButtonDefaultTag,
455 sizeof(isdefault), &isdefault);
5537f572 456 } else if (ctrl->button.isdefault) {
457 InsetRect(&bounds, -4, -4);
458 NewControl(window, &bounds, title, TRUE, 0, 0, 1,
459 SYS7_DEFAULT_PROC, (long)mc);
8a7e67ec 460 }
855d05c4 461 if (mac_gestalts.apprvers >= 0x110) {
462 Boolean iscancel = ctrl->button.iscancel;
463
464 SetControlData(mc->button.tbctrl, kControlEntireControl,
465 kControlPushButtonCancelTag,
466 sizeof(iscancel), &iscancel);
467 }
8a7e67ec 468 add234(mcs->byctrl, mc);
ee10bc56 469 mc->generic.next = mcs->panels[curstate->panelnum];
470 mcs->panels[curstate->panelnum] = mc;
8a7e67ec 471 curstate->pos.v += 26;
472}
473
5537f572 474#if !TARGET_API_MAC_CARBON
475static pascal SInt32 macctrl_sys7_default_cdef(SInt16 variant,
476 ControlRef control,
477 ControlDefProcMessage msg,
478 SInt32 param)
479{
480 RgnHandle rgn;
481 Rect rect;
482 int oval;
483
484 switch (msg) {
485 case drawCntl:
486 if ((*control)->contrlVis) {
487 rect = (*control)->contrlRect;
488 PenNormal();
489 PenSize(3, 3);
490 oval = (rect.bottom - rect.top) / 2 + 2;
491 FrameRoundRect(&rect, oval, oval);
492 }
493 return 0;
494 case calcCRgns:
495 if (param & (1 << 31)) {
496 param &= ~(1 << 31);
497 goto calcthumbrgn;
498 }
499 /* FALLTHROUGH */
500 case calcCntlRgn:
501 rgn = (RgnHandle)param;
502 RectRgn(rgn, &(*control)->contrlRect);
503 return 0;
504 case calcThumbRgn:
505 calcthumbrgn:
506 rgn = (RgnHandle)param;
507 SetEmptyRgn(rgn);
508 return 0;
509 }
510
511 return 0;
512}
513#endif
514
8a7e67ec 515
516void macctrl_activate(WindowPtr window, EventRecord *event)
517{
518 Boolean active = (event->modifiers & activeFlag) != 0;
519 GrafPtr saveport;
520 ControlRef root;
521
522 GetPort(&saveport);
523 SetPort((GrafPtr)GetWindowPort(window));
524 if (mac_gestalts.apprvers >= 0x100) {
525 SetThemeWindowBackground(window, active ?
526 kThemeBrushModelessDialogBackgroundActive :
527 kThemeBrushModelessDialogBackgroundInactive,
528 TRUE);
529 GetRootControl(window, &root);
530 if (active)
531 ActivateControl(root);
532 else
533 DeactivateControl(root);
534 } else {
535 /* (De)activate controls one at a time */
536 }
537 SetPort(saveport);
538}
539
540void macctrl_click(WindowPtr window, EventRecord *event)
541{
542 Point mouse;
543 ControlHandle control;
544 int part;
545 GrafPtr saveport;
546 union macctrl *mc;
547 struct macctrls *mcs = mac_winctrls(window);
548 int i;
549
550 GetPort(&saveport);
551 SetPort((GrafPtr)GetWindowPort(window));
552 mouse = event->where;
553 GlobalToLocal(&mouse);
554 part = FindControl(mouse, window, &control);
555 if (control != NULL)
556 if (TrackControl(control, mouse, NULL) != 0) {
557 mc = (union macctrl *)GetControlReference(control);
558 switch (mc->generic.type) {
559 case MACCTRL_RADIO:
560 for (i = 0; i < mc->generic.ctrl->radio.nbuttons; i++) {
561 if (mc->radio.tbctrls[i] == control)
562 SetControlValue(mc->radio.tbctrls[i],
563 kControlRadioButtonCheckedValue);
564 else
565 SetControlValue(mc->radio.tbctrls[i],
566 kControlRadioButtonUncheckedValue);
567 }
568 ctrlevent(mcs, mc, EVENT_VALCHANGE);
569 break;
570 case MACCTRL_CHECKBOX:
571 SetControlValue(control, !GetControlValue(control));
572 ctrlevent(mcs, mc, EVENT_VALCHANGE);
573 break;
574 case MACCTRL_BUTTON:
575 ctrlevent(mcs, mc, EVENT_ACTION);
576 break;
577 }
578 }
579 SetPort(saveport);
580}
581
582void macctrl_update(WindowPtr window)
583{
584#if TARGET_API_MAC_CARBON
585 RgnHandle visrgn;
586#endif
587 Rect rect;
588 GrafPtr saveport;
589
590 BeginUpdate(window);
591 GetPort(&saveport);
592 SetPort((GrafPtr)GetWindowPort(window));
593 if (mac_gestalts.apprvers >= 0x101) {
594#if TARGET_API_MAC_CARBON
595 GetPortBounds(GetWindowPort(window), &rect);
596#else
597 rect = window->portRect;
598#endif
599 InsetRect(&rect, -1, -1);
600 DrawThemeModelessDialogFrame(&rect, mac_frontwindow() == window ?
601 kThemeStateActive : kThemeStateInactive);
602 }
603#if TARGET_API_MAC_CARBON
604 visrgn = NewRgn();
605 GetPortVisibleRegion(GetWindowPort(window), visrgn);
606 UpdateControls(window, visrgn);
607 DisposeRgn(visrgn);
608#else
609 UpdateControls(window, window->visRgn);
610#endif
611 SetPort(saveport);
612 EndUpdate(window);
613}
614
615#if TARGET_API_MAC_CARBON
616#define EnableItem EnableMenuItem
617#define DisableItem DisableMenuItem
618#endif
619void macctrl_adjustmenus(WindowPtr window)
620{
621 MenuHandle menu;
622
623 menu = GetMenuHandle(mFile);
624 DisableItem(menu, iSave); /* XXX enable if modified */
625 EnableItem(menu, iSaveAs);
626 EnableItem(menu, iDuplicate);
627
628 menu = GetMenuHandle(mEdit);
629 DisableItem(menu, 0);
630}
631
632void macctrl_close(WindowPtr window)
633{
634 struct macctrls *mcs = mac_winctrls(window);
635 union macctrl *mc;
636
637 while ((mc = index234(mcs->byctrl, 0)) != NULL) {
638 del234(mcs->byctrl, mc);
639 sfree(mc);
640 }
641
642 freetree234(mcs->byctrl);
643 mcs->byctrl = NULL;
ee10bc56 644 sfree(mcs->panels);
645 mcs->panels = NULL;
8a7e67ec 646}
647
648void dlg_update_start(union control *ctrl, void *dlg)
649{
650
651 /* No-op for now */
652}
653
654void dlg_update_done(union control *ctrl, void *dlg)
655{
656
657 /* No-op for now */
658}
659
660void dlg_set_focus(union control *ctrl, void *dlg)
661{
662
663 if (mac_gestalts.apprvers >= 0x100) {
664 /* Use SetKeyboardFocus() */
665 } else {
666 /* Do our own mucking around */
667 }
668}
669
0bd8d76d 670union control *dlg_last_focused(union control *ctrl, void *dlg)
8a7e67ec 671{
672
673 return NULL;
674}
675
676void dlg_beep(void *dlg)
677{
678
679 SysBeep(30);
680}
681
682void dlg_error_msg(void *dlg, char *msg)
683{
684 Str255 pmsg;
685
686 c2pstrcpy(pmsg, msg);
687 ParamText(pmsg, NULL, NULL, NULL);
688 StopAlert(128, NULL);
689}
690
691void dlg_end(void *dlg, int value)
692{
693
694};
695
696void dlg_refresh(union control *ctrl, void *dlg)
697{
698
699};
700
701void *dlg_get_privdata(union control *ctrl, void *dlg)
702{
703
704 return NULL;
705}
706
707void dlg_set_privdata(union control *ctrl, void *dlg, void *ptr)
708{
709
710 fatalbox("dlg_set_privdata");
711}
712
713void *dlg_alloc_privdata(union control *ctrl, void *dlg, size_t size)
714{
715
716 fatalbox("dlg_alloc_privdata");
717}
718
719
720/*
721 * Radio Button control
722 */
723
724void dlg_radiobutton_set(union control *ctrl, void *dlg, int whichbutton)
725{
93ba25f8 726 struct macctrls *mcs = dlg;
727 union macctrl *mc = findbyctrl(mcs, ctrl);
8a7e67ec 728 int i;
729
93ba25f8 730 assert(mc != NULL);
8a7e67ec 731 for (i = 0; i < ctrl->radio.nbuttons; i++) {
732 if (i == whichbutton)
733 SetControlValue(mc->radio.tbctrls[i],
734 kControlRadioButtonCheckedValue);
735 else
736 SetControlValue(mc->radio.tbctrls[i],
737 kControlRadioButtonUncheckedValue);
738 }
739
740};
741
742int dlg_radiobutton_get(union control *ctrl, void *dlg)
743{
93ba25f8 744 struct macctrls *mcs = dlg;
745 union macctrl *mc = findbyctrl(mcs, ctrl);
8a7e67ec 746 int i;
747
93ba25f8 748 assert(mc != NULL);
8a7e67ec 749 for (i = 0; i < ctrl->radio.nbuttons; i++) {
750 if (GetControlValue(mc->radio.tbctrls[i]) ==
751 kControlRadioButtonCheckedValue)
752 return i;
753 }
754 return -1;
755};
756
757
758/*
759 * Check Box control
760 */
761
762void dlg_checkbox_set(union control *ctrl, void *dlg, int checked)
763{
93ba25f8 764 struct macctrls *mcs = dlg;
765 union macctrl *mc = findbyctrl(mcs, ctrl);
8a7e67ec 766
93ba25f8 767 assert(mc != NULL);
8a7e67ec 768 SetControlValue(mc->checkbox.tbctrl,
769 checked ? kControlCheckBoxCheckedValue :
770 kControlCheckBoxUncheckedValue);
771}
772
773int dlg_checkbox_get(union control *ctrl, void *dlg)
774{
93ba25f8 775 struct macctrls *mcs = dlg;
776 union macctrl *mc = findbyctrl(mcs, ctrl);
8a7e67ec 777
93ba25f8 778 assert(mc != NULL);
8a7e67ec 779 return GetControlValue(mc->checkbox.tbctrl);
780}
781
782
783/*
784 * Edit Box control
785 */
786
787void dlg_editbox_set(union control *ctrl, void *dlg, char const *text)
788{
789
790};
791
792void dlg_editbox_get(union control *ctrl, void *dlg, char *buffer, int length)
793{
794
795};
796
797
798/*
799 * List Box control
800 */
801
802void dlg_listbox_clear(union control *ctrl, void *dlg)
803{
804
805};
806
807void dlg_listbox_del(union control *ctrl, void *dlg, int index)
808{
809
810};
811
812void dlg_listbox_add(union control *ctrl, void *dlg, char const *text)
813{
814
815};
816
817void dlg_listbox_addwithindex(union control *ctrl, void *dlg,
818 char const *text, int id)
819{
820
821};
822
823int dlg_listbox_getid(union control *ctrl, void *dlg, int index)
824{
825
826 return 0;
827};
828
829int dlg_listbox_index(union control *ctrl, void *dlg)
830{
831
832 return 0;
833};
834
835int dlg_listbox_issel(union control *ctrl, void *dlg, int index)
836{
837
838 return 0;
839};
840
841void dlg_listbox_select(union control *ctrl, void *dlg, int index)
842{
843
844};
845
846
847/*
848 * Text control
849 */
850
851void dlg_text_set(union control *ctrl, void *dlg, char const *text)
852{
93ba25f8 853 struct macctrls *mcs = dlg;
854 union macctrl *mc = findbyctrl(mcs, ctrl);
f32ce408 855 Str255 title;
8a7e67ec 856
93ba25f8 857 assert(mc != NULL);
8a7e67ec 858 if (mac_gestalts.apprvers >= 0x100)
859 SetControlData(mc->text.tbctrl, kControlEntireControl,
860 kControlStaticTextTextTag,
861 strlen(ctrl->text.label), ctrl->text.label);
f32ce408 862 else {
863 c2pstrcpy(title, text);
864 SetControlTitle(mc->text.tbctrl, title);
865 }
8a7e67ec 866}
867
868
869/*
870 * File Selector control
871 */
872
873void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn)
874{
875
876}
877
878void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn)
879{
880
881}
882
883
884/*
885 * Font Selector control
886 */
887
888void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec fn)
889{
890
891}
892
893void dlg_fontsel_get(union control *ctrl, void *dlg, FontSpec *fn)
894{
895
896}
897
898
899/*
900 * Printer enumeration
901 */
902
903printer_enum *printer_start_enum(int *nprinters)
904{
905
906 *nprinters = 0;
907 return NULL;
908}
909
910char *printer_get_name(printer_enum *pe, int thing)
911{
912
913 return "<none>";
914}
915
916void printer_finish_enum(printer_enum *pe)
917{
918
919}
920
921
922/*
923 * Colour selection stuff
924 */
925
926void dlg_coloursel_start(union control *ctrl, void *dlg,
927 int r, int g, int b)
928{
929
930}
931
932int dlg_coloursel_results(union control *ctrl, void *dlg,
933 int *r, int *g, int *b)
934{
935
936 return 0;
937}
938
939/*
940 * Local Variables:
941 * c-file-style: "simon"
942 * End:
943 */