1 /* $Id: macterm.c,v 1.1.2.9 1999/03/01 22:26:50 ben Exp $ */
3 * Copyright (c) 1999 Ben Harris
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
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
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
29 * macterm.c -- Macintosh terminal front-end
36 #include <MacWindows.h>
38 #include <Quickdraw.h>
39 #include <QuickdrawText.h>
40 #include <Resources.h>
54 PaletteHandle palette;
55 ControlHandle scrollbar;
58 static void mac_initfont(struct mac_session *);
59 static void mac_initpalette(struct mac_session *);
60 static void mac_adjustsize(struct mac_session *);
61 static pascal void mac_scrolltracker(ControlHandle, short);
64 * Temporary hack till I get the terminal emulator supporting multiple
68 static struct mac_session *onlysession;
70 static void inbuf_putc(int c) {
71 inbuf[inbuf_head] = c;
72 inbuf_head = (inbuf_head+1) & INBUF_MASK;
75 static void inbuf_putstr(const char *c) {
80 static void display_resource(unsigned long type, short id) {
85 h = GetResource(type, id);
87 fatalbox("Can't get test resource");
88 SetResAttrs(h, GetResAttrs(h) | resLocked);
90 len = GetResourceSizeOnDisk(h);
91 for (i = 0; i < len; i++) {
95 SetResAttrs(h, GetResAttrs(h) & ~resLocked);
100 void mac_newsession(void) {
101 struct mac_session *s;
104 /* This should obviously be initialised by other means */
105 mac_loadconfig(&cfg);
106 s = smalloc(sizeof(*s));
109 /* XXX: Own storage management? */
110 if (mac_gestalts.qdvers == gestaltOriginalQD)
111 s->window = GetNewWindow(wTerminal, NULL, (WindowPtr)-1);
113 s->window = GetNewCWindow(wTerminal, NULL, (WindowPtr)-1);
114 SetWRefCon(s->window, (long)s);
115 s->scrollbar = GetNewControl(cVScroll, s->window);
117 term_size(cfg.height, cfg.width, cfg.savelines);
120 /* Set to FALSE to not get palette updates in the background. */
121 SetPalette(s->window, s->palette, TRUE);
122 ActivatePalette(s->window);
123 ShowWindow(s->window);
124 display_resource('pTST', 128);
127 static void mac_initfont(struct mac_session *s) {
132 macfont[0] = sprintf((char *)&macfont[1], "%s", cfg.font);
133 GetFNum(macfont, &s->fontnum);
134 TextFont(s->fontnum);
135 TextFace(cfg.fontisbold ? bold : 0);
136 TextSize(cfg.fontheight);
138 font_width = fi.widMax;
139 font_height = fi.ascent + fi.descent + fi.leading;
140 s->font_ascent = fi.ascent;
145 * To be called whenever the window size changes.
146 * rows and cols should be desired values.
147 * It's assumed the terminal emulator will be or has been informed.
149 static void mac_adjustsize(struct mac_session *s) {
150 int winwidth, winheight;
152 winwidth = cols * font_width + 15;
153 winheight = rows * font_height;
154 SizeWindow(s->window, winwidth, winheight, true);
155 HideControl(s->scrollbar);
156 MoveControl(s->scrollbar, winwidth - 15, -1);
157 SizeControl(s->scrollbar, 16, winheight - 13);
158 ShowControl(s->scrollbar);
161 static void mac_initpalette(struct mac_session *s) {
164 if (mac_gestalts.qdvers == gestaltOriginalQD)
166 s->palette = NewPalette((*cfg.colours)->pmEntries, NULL, pmCourteous, 0);
167 if (s->palette == NULL)
168 fatalbox("Unable to create palette");
169 CopyPalette(cfg.colours, s->palette, 0, 0, (*cfg.colours)->pmEntries);
173 * I don't think this is (a) safe or (b) a good way to do this.
175 static void mac_updatewinbg(struct mac_session *s) {
178 WCTabHandle cth = &ctp;
183 ct.ctTable[0].value = wContentColor;
184 ct.ctTable[0].rgb = (*s->palette)->pmInfo[16].ciRGB;
185 SetWinColor(s->window, cth);
188 void mac_clickterm(WindowPtr window, EventRecord *event) {
189 struct mac_session *s;
191 ControlHandle control;
194 s = (struct mac_session *)GetWRefCon(window);
196 mouse = event->where;
197 GlobalToLocal(&mouse);
198 part = FindControl(mouse, window, &control);
199 if (control == s->scrollbar) {
201 case kControlIndicatorPart:
202 if (TrackControl(control, mouse, NULL) == kControlIndicatorPart)
203 term_scroll(+1, GetControlValue(control));
205 case kControlUpButtonPart:
206 case kControlDownButtonPart:
207 case kControlPageUpPart:
208 case kControlPageDownPart:
209 TrackControl(control, mouse, mac_scrolltracker);
215 static pascal void mac_scrolltracker(ControlHandle control, short part) {
216 struct mac_session *s;
218 s = (struct mac_session *)GetWRefCon((*control)->contrlOwner);
220 case kControlUpButtonPart:
223 case kControlDownButtonPart:
226 case kControlPageUpPart:
227 term_scroll(0, -(rows - 1));
229 case kControlPageDownPart:
230 term_scroll(0, +(rows - 1));
235 void mac_activateterm(WindowPtr window, Boolean active) {
236 struct mac_session *s;
238 s = (struct mac_session *)GetWRefCon(window);
240 ShowControl(s->scrollbar);
242 HideControl(s->scrollbar);
245 void mac_updateterm(WindowPtr window) {
246 struct mac_session *s;
249 s = (struct mac_session *)GetWRefCon(window);
252 (*window->visRgn)->rgnBBox.left,
253 (*window->visRgn)->rgnBBox.top,
254 (*window->visRgn)->rgnBBox.right,
255 (*window->visRgn)->rgnBBox.bottom);
256 /* Restore default colours in case the Window Manager uses them */
259 if (FrontWindow() != window)
260 EraseRect(&(*s->scrollbar)->contrlRect);
261 UpdateControls(window, window->visRgn);
262 /* Stop DrawGrowIcon giving us space for a horizontal scrollbar */
263 clip.left = window->portRect.right - 15;
264 clip.right = SHRT_MAX;
266 clip.bottom = SHRT_MAX;
268 DrawGrowIcon(window);
269 clip.left = SHRT_MIN;
275 * Call from the terminal emulator to draw a bit of text
277 * x and y are text row and column (zero-based)
279 void do_text(struct mac_session *s, int x, int y, char *text, int len,
280 unsigned long attr) {
282 int bgcolour, fgcolour;
283 RGBColor rgbfore, rgbback;
288 /* First check this text is relevant */
289 textrect.top = y * font_height;
290 textrect.bottom = (y + 1) * font_height;
291 textrect.left = x * font_width;
292 textrect.right = (x + len) * font_width;
293 if (!RectInRgn(&textrect, s->window->visRgn))
296 TextFont(s->fontnum);
297 if (cfg.fontisbold || (attr & ATTR_BOLD) && !cfg.bold_colour)
299 if (attr & ATTR_UNDER)
302 TextSize(cfg.fontheight);
304 if (attr & ATTR_REVERSE) {
305 bgcolour = ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT) * 2;
306 fgcolour = ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT) * 2;
308 fgcolour = ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT) * 2;
309 bgcolour = ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT) * 2;
311 if ((attr & ATTR_BOLD) && cfg.bold_colour)
313 /* RGBForeColor(&s->palette[fgcolour]); */ /* XXX Non-Color-QD version */
314 /* RGBBackColor(&s->palette[bgcolour]); */
315 PmForeColor(fgcolour);
316 PmBackColor(bgcolour);
317 SetFractEnable(FALSE); /* We want characters on pixel boundaries */
318 MoveTo(textrect.left, textrect.top + s->font_ascent);
319 DrawText(text, 0, len);
321 /* Tell the window manager about it in case this isn't an update */
322 ValidRect(&textrect);
326 * Call from the terminal emulator to get its graphics context.
328 struct mac_session *get_ctx(void) {
334 * Presumably this does something in Windows
336 void free_ctx(struct mac_session *ctx) {
341 * Set the scroll bar position
343 * total is the line number of the bottom of the working screen
344 * start is the line number of the top of the display
345 * page is the length of the displayed page
347 void set_sbar(int total, int start, int page) {
348 struct mac_session *s = onlysession;
350 SetControlMinimum(s->scrollbar, 0);
351 SetControlMaximum(s->scrollbar, total - page);
352 SetControlValue(s->scrollbar, start);
354 /* XXX: This doesn't compile for me - bjh */
355 if (mac_gestalts.cntlattr & gestaltControlMgrPresent)
356 SetControlViewSize(s->scrollbar, page);
367 * XXX We should indicate the relevant window and/or use the
368 * Notification Manager
373 * Set icon string -- a no-op here (Windowshade?)
375 void set_icon(char *icon) {
380 * Set the window title
382 void set_title(char *title) {
384 struct mac_session *s = onlysession;
386 mactitle[0] = sprintf((char *)&mactitle[1], "%s", title);
387 SetWTitle(s->window, mactitle);
391 * Resize the window at the emulator's request
393 void request_resize(int w, int h) {
397 mac_initfont(onlysession);
401 * Set the logical palette
403 void palette_set(int n, int r, int g, int b) {
405 struct mac_session *s = onlysession;
406 static const int first[21] = {
407 0, 2, 4, 6, 8, 10, 12, 14,
408 1, 3, 5, 7, 9, 11, 13, 15,
412 if (mac_gestalts.qdvers == gestaltOriginalQD)
414 col.red = r * 0x0101;
415 col.green = g * 0x0101;
416 col.blue = b * 0x0101;
417 SetEntryColor(s->palette, first[n], &col);
419 SetEntryColor(s->palette, first[n]+1, &col);
420 ActivatePalette(s->window);
424 * Reset to the default palette
426 void palette_reset(void) {
427 struct mac_session *s = onlysession;
429 if (mac_gestalts.qdvers == gestaltOriginalQD)
431 CopyPalette(cfg.colours, s->palette, 0, 0, (*cfg.colours)->pmEntries);
432 ActivatePalette(s->window);
433 /* Palette Manager will generate update events as required. */
437 * Move `lines' lines from position `from' to position `to' in the
439 * Note that this is currently broken if "from" and "to" are more
440 * than "lines" lines apart.
442 void optimised_move(int to, int from, int lines) {
445 struct mac_session *s = onlysession;
450 min = (to < from ? to : from);
451 max = to + from - min;
455 r.left = 0; r.right = cols * font_width;
456 r.top = min * font_height; r.bottom = (max+lines) * font_height;
457 ScrollRect(&r, 0, (to - from) * font_height, update);
458 InvalRgn(update); /* XXX: necessary? probably harmless anyway */