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 | |
46 | union 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 | |
77 | struct 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 |
92 | static void macctrl_layoutset(struct mac_layoutstate *, struct controlset *, |
93 | WindowPtr, struct macctrls *); |
ee10bc56 |
94 | static void macctrl_switchtopanel(struct macctrls *, unsigned int); |
8a7e67ec |
95 | static void macctrl_text(struct macctrls *, WindowPtr, |
96 | struct mac_layoutstate *, union control *); |
97 | static void macctrl_radio(struct macctrls *, WindowPtr, |
98 | struct mac_layoutstate *, union control *); |
99 | static void macctrl_checkbox(struct macctrls *, WindowPtr, |
100 | struct mac_layoutstate *, union control *); |
101 | static void macctrl_button(struct macctrls *, WindowPtr, |
102 | struct mac_layoutstate *, union control *); |
fa4942e7 |
103 | #if !TARGET_API_MAC_CARBON |
104 | static pascal SInt32 macctrl_sys7_text_cdef(SInt16, ControlRef, |
105 | ControlDefProcMessage, SInt32); |
5537f572 |
106 | static 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 |
118 | typedef struct { |
119 | short jmpabs; /* 4EF9 */ |
120 | ControlDefUPP theUPP; |
121 | } **PatchCDEF; |
122 | #pragma options align=reset |
123 | #endif |
124 | |
125 | static 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 | |
141 | static 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 |
154 | static 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 |
167 | void 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 | |
207 | static 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 |
257 | static 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 |
295 | static 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 |
337 | static 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 |
369 | static 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 | |
405 | static 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 | |
430 | static 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 |
475 | static 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 | |
516 | void 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 | |
540 | void 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 | |
582 | void 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 |
619 | void 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 | |
632 | void 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 | |
648 | void dlg_update_start(union control *ctrl, void *dlg) |
649 | { |
650 | |
651 | /* No-op for now */ |
652 | } |
653 | |
654 | void dlg_update_done(union control *ctrl, void *dlg) |
655 | { |
656 | |
657 | /* No-op for now */ |
658 | } |
659 | |
660 | void 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 |
670 | union control *dlg_last_focused(union control *ctrl, void *dlg) |
8a7e67ec |
671 | { |
672 | |
673 | return NULL; |
674 | } |
675 | |
676 | void dlg_beep(void *dlg) |
677 | { |
678 | |
679 | SysBeep(30); |
680 | } |
681 | |
682 | void 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 | |
691 | void dlg_end(void *dlg, int value) |
692 | { |
693 | |
694 | }; |
695 | |
696 | void dlg_refresh(union control *ctrl, void *dlg) |
697 | { |
698 | |
699 | }; |
700 | |
701 | void *dlg_get_privdata(union control *ctrl, void *dlg) |
702 | { |
703 | |
704 | return NULL; |
705 | } |
706 | |
707 | void dlg_set_privdata(union control *ctrl, void *dlg, void *ptr) |
708 | { |
709 | |
710 | fatalbox("dlg_set_privdata"); |
711 | } |
712 | |
713 | void *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 | |
724 | void 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 | |
742 | int 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 | |
762 | void 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 | |
773 | int 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 | |
787 | void dlg_editbox_set(union control *ctrl, void *dlg, char const *text) |
788 | { |
789 | |
790 | }; |
791 | |
792 | void dlg_editbox_get(union control *ctrl, void *dlg, char *buffer, int length) |
793 | { |
794 | |
795 | }; |
796 | |
797 | |
798 | /* |
799 | * List Box control |
800 | */ |
801 | |
802 | void dlg_listbox_clear(union control *ctrl, void *dlg) |
803 | { |
804 | |
805 | }; |
806 | |
807 | void dlg_listbox_del(union control *ctrl, void *dlg, int index) |
808 | { |
809 | |
810 | }; |
811 | |
812 | void dlg_listbox_add(union control *ctrl, void *dlg, char const *text) |
813 | { |
814 | |
815 | }; |
816 | |
817 | void dlg_listbox_addwithindex(union control *ctrl, void *dlg, |
818 | char const *text, int id) |
819 | { |
820 | |
821 | }; |
822 | |
823 | int dlg_listbox_getid(union control *ctrl, void *dlg, int index) |
824 | { |
825 | |
826 | return 0; |
827 | }; |
828 | |
829 | int dlg_listbox_index(union control *ctrl, void *dlg) |
830 | { |
831 | |
832 | return 0; |
833 | }; |
834 | |
835 | int dlg_listbox_issel(union control *ctrl, void *dlg, int index) |
836 | { |
837 | |
838 | return 0; |
839 | }; |
840 | |
841 | void dlg_listbox_select(union control *ctrl, void *dlg, int index) |
842 | { |
843 | |
844 | }; |
845 | |
846 | |
847 | /* |
848 | * Text control |
849 | */ |
850 | |
851 | void 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 | |
873 | void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn) |
874 | { |
875 | |
876 | } |
877 | |
878 | void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn) |
879 | { |
880 | |
881 | } |
882 | |
883 | |
884 | /* |
885 | * Font Selector control |
886 | */ |
887 | |
888 | void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec fn) |
889 | { |
890 | |
891 | } |
892 | |
893 | void dlg_fontsel_get(union control *ctrl, void *dlg, FontSpec *fn) |
894 | { |
895 | |
896 | } |
897 | |
898 | |
899 | /* |
900 | * Printer enumeration |
901 | */ |
902 | |
903 | printer_enum *printer_start_enum(int *nprinters) |
904 | { |
905 | |
906 | *nprinters = 0; |
907 | return NULL; |
908 | } |
909 | |
910 | char *printer_get_name(printer_enum *pe, int thing) |
911 | { |
912 | |
913 | return "<none>"; |
914 | } |
915 | |
916 | void printer_finish_enum(printer_enum *pe) |
917 | { |
918 | |
919 | } |
920 | |
921 | |
922 | /* |
923 | * Colour selection stuff |
924 | */ |
925 | |
926 | void dlg_coloursel_start(union control *ctrl, void *dlg, |
927 | int r, int g, int b) |
928 | { |
929 | |
930 | } |
931 | |
932 | int 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 | */ |