1 /* $Id: macterm.c,v 1.1.2.8 1999/02/28 17:05:11 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 *);
62 /* Temporary hack till I get the terminal emulator supporting multiple sessions */
64 static struct mac_session *onlysession;
66 static void inbuf_putc(int c) {
67 inbuf[inbuf_head] = c;
68 inbuf_head = (inbuf_head+1) & INBUF_MASK;
71 static void inbuf_putstr(const char *c) {
76 static void display_resource(unsigned long type, short id) {
81 h = GetResource(type, id);
83 fatalbox("Can't get test resource");
84 SetResAttrs(h, GetResAttrs(h) | resLocked);
86 len = GetResourceSizeOnDisk(h);
87 for (i = 0; i < len; i++) {
91 SetResAttrs(h, GetResAttrs(h) & ~resLocked);
96 void mac_newsession(void) {
97 struct mac_session *s;
100 /* This should obviously be initialised by other means */
101 mac_loadconfig(&cfg);
102 s = smalloc(sizeof(*s));
105 /* XXX: Own storage management? */
106 if (mac_gestalts.qdvers == gestaltOriginalQD)
107 s->window = GetNewWindow(wTerminal, NULL, (WindowPtr)-1);
109 s->window = GetNewCWindow(wTerminal, NULL, (WindowPtr)-1);
110 SetWRefCon(s->window, (long)s);
111 s->scrollbar = GetNewControl(cVScroll, s->window);
113 term_size(24, 80, 100);
116 /* Set to FALSE to not get palette updates in the background. */
117 SetPalette(s->window, s->palette, TRUE);
118 ActivatePalette(s->window);
119 ShowWindow(s->window);
120 display_resource('pTST', 128);
123 static void mac_initfont(struct mac_session *s) {
128 macfont[0] = sprintf((char *)&macfont[1], "%s", cfg.font);
129 GetFNum(macfont, &s->fontnum);
130 TextFont(s->fontnum);
131 TextFace(cfg.fontisbold ? bold : 0);
132 TextSize(cfg.fontheight);
134 font_width = fi.widMax;
135 font_height = fi.ascent + fi.descent + fi.leading;
136 s->font_ascent = fi.ascent;
141 * To be called whenever the window size changes.
142 * rows and cols should be desired values.
143 * It's assumed the terminal emulator will be or has been informed.
145 static void mac_adjustsize(struct mac_session *s) {
146 int winwidth, winheight;
148 winwidth = cols * font_width + 15;
149 winheight = rows * font_height;
150 SizeWindow(s->window, winwidth, winheight, true);
151 HideControl(s->scrollbar);
152 MoveControl(s->scrollbar, winwidth - 15, -1);
153 SizeControl(s->scrollbar, 16, winheight - 13);
154 ShowControl(s->scrollbar);
157 static void mac_initpalette(struct mac_session *s) {
160 if (mac_gestalts.qdvers == gestaltOriginalQD)
162 s->palette = NewPalette((*cfg.colours)->pmEntries, NULL, pmCourteous, 0);
163 if (s->palette == NULL)
164 fatalbox("Unable to create palette");
165 CopyPalette(cfg.colours, s->palette, 0, 0, (*cfg.colours)->pmEntries);
169 * I don't think this is (a) safe or (b) a good way to do this.
171 static void mac_updatewinbg(struct mac_session *s) {
174 WCTabHandle cth = &ctp;
179 ct.ctTable[0].value = wContentColor;
180 ct.ctTable[0].rgb = (*s->palette)->pmInfo[16].ciRGB;
181 SetWinColor(s->window, cth);
184 void mac_activateterm(WindowPtr window, Boolean active) {
185 struct mac_session *s;
187 s = (struct mac_session *)GetWRefCon(window);
189 ShowControl(s->scrollbar);
191 HideControl(s->scrollbar);
194 void mac_updateterm(WindowPtr window) {
195 struct mac_session *s;
198 s = (struct mac_session *)GetWRefCon(window);
201 (*window->visRgn)->rgnBBox.left,
202 (*window->visRgn)->rgnBBox.top,
203 (*window->visRgn)->rgnBBox.right,
204 (*window->visRgn)->rgnBBox.bottom);
205 /* Restore default colours in case the Window Manager uses them */
208 if (FrontWindow() != window)
209 EraseRect(&(*s->scrollbar)->contrlRect);
210 UpdateControls(window, window->visRgn);
211 /* Stop DrawGrowIcon giving us space for a horizontal scrollbar */
212 clip.left = window->portRect.right - 15;
213 clip.right = SHRT_MAX;
215 clip.bottom = SHRT_MAX;
217 DrawGrowIcon(window);
218 clip.left = SHRT_MIN;
224 * Call from the terminal emulator to draw a bit of text
226 * x and y are text row and column (zero-based)
228 void do_text(struct mac_session *s, int x, int y, char *text, int len,
229 unsigned long attr) {
231 int bgcolour, fgcolour;
232 RGBColor rgbfore, rgbback;
237 /* First check this text is relevant */
238 textrect.top = y * font_height;
239 textrect.bottom = (y + 1) * font_height;
240 textrect.left = x * font_width;
241 textrect.right = (x + len) * font_width;
242 if (!RectInRgn(&textrect, s->window->visRgn))
245 TextFont(s->fontnum);
246 if (cfg.fontisbold || (attr & ATTR_BOLD) && !cfg.bold_colour)
248 if (attr & ATTR_UNDER)
251 TextSize(cfg.fontheight);
253 if (attr & ATTR_REVERSE) {
254 bgcolour = ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT) * 2;
255 fgcolour = ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT) * 2;
257 fgcolour = ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT) * 2;
258 bgcolour = ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT) * 2;
260 if ((attr & ATTR_BOLD) && cfg.bold_colour)
262 /* RGBForeColor(&s->palette[fgcolour]); */ /* XXX Non-Color-QD version */
263 /* RGBBackColor(&s->palette[bgcolour]); */
264 PmForeColor(fgcolour);
265 PmBackColor(bgcolour);
266 SetFractEnable(FALSE); /* We want characters on pixel boundaries */
267 MoveTo(textrect.left, textrect.top + s->font_ascent);
268 DrawText(text, 0, len);
270 /* Tell the window manager about it in case this isn't an update */
271 ValidRect(&textrect);
275 * Call from the terminal emulator to get its graphics context.
276 * I feel this should disappear entirely (and do_text should take
277 * a Session as an argument). Simon may disagree.
279 struct mac_session *get_ctx(void) {
285 * Presumably this does something in Windows
287 void free_ctx(struct mac_session *ctx) {
292 * Set the scroll bar position
294 * total is the line number of the bottom of the working screen
295 * start is the line number of the top of the display
296 * page is the length of the displayed page
298 void set_sbar(int total, int start, int page) {
299 struct mac_session *s = onlysession;
301 SetControlMinimum(s->scrollbar, 0);
302 SetControlMaximum(s->scrollbar, total - page);
303 SetControlValue(s->scrollbar, start);
305 /* XXX: This doesn't compile for me - bjh */
306 if (mac_gestalts.cntlattr & gestaltControlMgrPresent)
307 SetControlViewSize(s->scrollbar, page);
318 * XXX We should indicate the relevant window and/or use the
319 * Notification Manager
324 * Set icon string -- a no-op here (Windowshade?)
326 void set_icon(char *icon) {
331 * Set the window title
333 void set_title(char *title) {
335 struct mac_session *s = onlysession;
337 mactitle[0] = sprintf((char *)&mactitle[1], "%s", title);
338 SetWTitle(s->window, mactitle);
342 * Resize the window at the emulator's request
344 void request_resize(int w, int h) {
348 mac_initfont(onlysession);
352 * Set the logical palette
354 void palette_set(int n, int r, int g, int b) {
356 struct mac_session *s = onlysession;
357 static const int first[21] = {
358 0, 2, 4, 6, 8, 10, 12, 14,
359 1, 3, 5, 7, 9, 11, 13, 15,
363 col.red = r * 0x0101;
364 col.green = g * 0x0101;
365 col.blue = b * 0x0101;
366 SetEntryColor(s->palette, first[n], &col);
368 SetEntryColor(s->palette, first[n]+1, &col);
369 ActivatePalette(s->window);
373 * Reset to the default palette
375 void palette_reset(void) {
376 struct mac_session *s = onlysession;
378 if (mac_gestalts.qdvers == gestaltOriginalQD)
380 CopyPalette(cfg.colours, s->palette, 0, 0, (*cfg.colours)->pmEntries);
381 ActivatePalette(s->window);
382 /* Palette Manager will generate update events as required. */