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