Move the Mac port over to using snew/snewn/sresize.
[u/mdw/putty] / mac / macevlog.c
1 /* $Id: macevlog.c,v 1.6 2003/03/29 23:07:55 ben 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 <Lists.h>
30 #include <MacWindows.h>
31 #include <Quickdraw.h>
32 #include <Script.h>
33 #include <ToolUtils.h>
34
35 #include <limits.h>
36 #include <string.h>
37
38 #include "putty.h"
39 #include "mac.h"
40 #include "macresid.h"
41 #include "terminal.h"
42
43 static void mac_draweventloggrowicon(Session *s);
44 static void mac_adjusteventlogscrollbar(Session *s);
45 static void mac_clickeventlog(WindowPtr, EventRecord *);
46 static void mac_activateeventlog(WindowPtr, EventRecord *);
47 static void mac_groweventlog(WindowPtr, EventRecord *);
48 static void mac_updateeventlog(WindowPtr);
49 static void mac_closeeventlog(WindowPtr);
50
51 static void mac_createeventlog(Session *s)
52 {
53 Rect view;
54 ListBounds bounds = { 0, 0, 0, 1 }; /* 1 column, 0 rows */
55 Point csize = { 0, 0 };
56 GrafPtr saveport;
57 long fondsize;
58 WinInfo *wi;
59
60 s->eventlog_window = GetNewWindow(wEventLog, NULL, (WindowPtr)-1);
61 wi = snew(WinInfo);
62 memset(wi, 0, sizeof(*wi));
63 wi->s = s;
64 wi->wtype = wEventLog;
65 wi->click = &mac_clickeventlog;
66 wi->activate = &mac_activateeventlog;
67 wi->grow = &mac_groweventlog;
68 wi->update = &mac_updateeventlog;
69 wi->close = &mac_closeeventlog;
70 SetWRefCon(s->eventlog_window, (long)wi);
71 GetPort(&saveport);
72 SetPort((GrafPtr)GetWindowPort(s->eventlog_window));
73 fondsize = GetScriptVariable(smRoman, smScriptSmallFondSize);
74 TextFont(HiWord(fondsize));
75 TextSize(LoWord(fondsize));
76 SetPort(saveport);
77 #if TARGET_API_MAC_CARBON
78 GetPortBounds(GetWindowPort(s->eventlog_window), &view);
79 #else
80 view = s->eventlog_window->portRect;
81 #endif
82 view.right -= 15; /* Scrollbar */
83 s->eventlog = LNew(&view, &bounds, csize, 0, s->eventlog_window,
84 TRUE, TRUE, FALSE, TRUE);
85 mac_adjusteventlogscrollbar(s);
86 #if TARGET_API_MAC_CARBON
87 SetListSelectionFlags(s->eventlog, lExtendDrag | lNoDisjoint | lNoExtend);
88 #else
89 (*s->eventlog)->selFlags = lExtendDrag | lNoDisjoint | lNoExtend;
90 #endif
91 }
92
93 void mac_freeeventlog(Session *s)
94 {
95
96 if (s->eventlog != NULL)
97 LDispose(s->eventlog);
98 if (s->eventlog_window != NULL) {
99 sfree((WinInfo *)GetWRefCon(s->eventlog_window));
100 DisposeWindow(s->eventlog_window);
101 }
102 }
103
104 /*
105 * FIXME: logevent() should be passed a frontend handle, but backends have to
106 * have a terminal handle instead, because they pass it to from_backend(),
107 * so we accept a terminal handle here as well, and hope no-one tries to call
108 * us with sensible arguments.
109 */
110 void logevent(void *frontend, char *str)
111 {
112 Terminal *term = frontend;
113 Session *s = term->frontend;
114 ListBounds bounds, visible;
115 Cell cell = { 0, 0 };
116
117 if (s->eventlog == NULL)
118 mac_createeventlog(s);
119 if (s->eventlog == NULL)
120 return;
121
122 #if TARGET_API_MAC_CARBON
123 GetListDataBounds(s->eventlog, &bounds);
124 GetListVisibleCells(s->eventlog, &visible);
125 #else
126 bounds = (*s->eventlog)->dataBounds;
127 visible = (*s->eventlog)->visible;
128 #endif
129
130 cell.v = bounds.bottom;
131 LAddRow(1, cell.v, s->eventlog);
132 LSetCell(str, strlen(str), cell, s->eventlog);
133 /* ">=" and "2" because there can be a blank cell below the last one. */
134 if (visible.bottom >= bounds.bottom)
135 LScroll(0, 2, s->eventlog);
136 }
137
138 static void mac_draweventloggrowicon(Session *s)
139 {
140 Rect clip;
141 RgnHandle savergn;
142
143 SetPort((GrafPtr)GetWindowPort(s->eventlog_window));
144 /*
145 * Stop DrawGrowIcon giving us space for a horizontal scrollbar
146 * See Tech Note TB575 for details.
147 */
148 #if TARGET_API_MAC_CARBON
149 GetPortBounds(GetWindowPort(s->eventlog_window), &clip);
150 #else
151 clip = s->eventlog_window->portRect;
152 #endif
153 clip.left = clip.right - 15;
154 savergn = NewRgn();
155 GetClip(savergn);
156 ClipRect(&clip);
157 DrawGrowIcon(s->eventlog_window);
158 SetClip(savergn);
159 DisposeRgn(savergn);
160 }
161
162 /*
163 * For some reason, LNew doesn't seem to respect the hasGrow
164 * parameter, so we hammer the scrollbar into shape ourselves.
165 */
166 static void mac_adjusteventlogscrollbar(Session *s)
167 {
168 #if TARGET_API_MAC_CARBON
169 Rect winrect;
170
171 GetPortBounds(GetWindowPort(s->eventlog_window), &winrect);
172 SizeControl(GetListVerticalScrollBar(s->eventlog),
173 16, winrect.bottom - 13);
174 #else
175 SizeControl((*s->eventlog)->vScroll,
176 16, s->eventlog_window->portRect.bottom - 13);
177 #endif
178 }
179
180 void mac_clickeventlog(WindowPtr window, EventRecord *event)
181 {
182 Session *s = mac_windowsession(window);
183 Point mouse;
184 GrafPtr saveport;
185
186 GetPort(&saveport);
187 SetPort((GrafPtr)GetWindowPort(window));
188 mouse = event->where;
189 GlobalToLocal(&mouse);
190 LClick(mouse, event->modifiers, s->eventlog);
191 SetPort(saveport);
192 }
193
194 static void mac_groweventlog(WindowPtr window, EventRecord *event)
195 {
196 Session *s = mac_windowsession(window);
197 Rect limits;
198 long grow_result;
199 #if TARGET_API_MAC_CARBON
200 Rect rect;
201 Point cellsize;
202 #else
203 GrafPtr saveport;
204 #endif
205
206 SetRect(&limits, 15, 0, SHRT_MAX, SHRT_MAX);
207 grow_result = GrowWindow(window, event->where, &limits);
208 if (grow_result == 0) return;
209 SizeWindow(window, LoWord(grow_result), HiWord(grow_result), TRUE);
210 LSize(LoWord(grow_result) - 15, HiWord(grow_result), s->eventlog);
211 mac_adjusteventlogscrollbar(s);
212 /* We would use SetListCellSize in Carbon, but it's missing. */
213 (*s->eventlog)->cellSize.h = LoWord(grow_result) - 15;
214 #if TARGET_API_MAC_CARBON
215 cellsize.h = LoWord(grow_result) - 15;
216 GetListViewBounds(s->eventlog, &rect);
217 InvalWindowRect(window, &rect);
218 #else
219 GetPort(&saveport);
220 SetPort(window);
221 InvalRect(&(*s->eventlog)->rView);
222 SetPort(saveport);
223 #endif
224 }
225
226 static void mac_activateeventlog(WindowPtr window, EventRecord *event)
227 {
228 Session *s = mac_windowsession(window);
229 int active = (event->modifiers & activeFlag) != 0;
230
231 LActivate(active, s->eventlog);
232 mac_draweventloggrowicon(s);
233 }
234
235 static void mac_updateeventlog(WindowPtr window)
236 {
237 Session *s = mac_windowsession(window);
238 #if TARGET_API_MAC_CARBON
239 RgnHandle visrgn;
240 #endif
241
242 SetPort((GrafPtr)GetWindowPort(window));
243 BeginUpdate(window);
244 #if TARGET_API_MAC_CARBON
245 visrgn = NewRgn();
246 GetPortVisibleRegion(GetWindowPort(window), visrgn);
247 LUpdate(visrgn, s->eventlog);
248 DisposeRgn(visrgn);
249 #else
250 LUpdate(window->visRgn, s->eventlog);
251 #endif
252 mac_draweventloggrowicon(s);
253 EndUpdate(window);
254 }
255
256 static void mac_closeeventlog(WindowPtr window)
257 {
258
259 HideWindow(window);
260 }
261
262 void mac_showeventlog(Session *s)
263 {
264
265 SelectWindow(s->eventlog_window);
266 ShowWindow(s->eventlog_window);
267 }
268
269 /*
270 * Local Variables:
271 * c-file-style: "simon"
272 * End:
273 */