xref: /haiku/src/apps/terminal/TermWindow.cpp (revision 9ecf9d1c1d4888d341a6eac72112c72d1ae3a4cb)
1 /*
2  * Copyright (c) 2003-2004 Kian Duffy <myob@users.sourceforge.net>
3  * Copyright (C) 1998,99 Kazuho Okui and Takashi Murai.
4  * Copyright (c) 2004 Daniel Furrer <assimil8or@users.sourceforge.net>
5  *
6  * Distributed unter the terms of the MIT license.
7  */
8 #include <Alert.h>
9 #include <Application.h>
10 #include <Menu.h>
11 #include <MenuBar.h>
12 #include <MenuItem.h>
13 #include <Path.h>
14 #include <PrintJob.h>
15 #include <PropertyInfo.h>
16 #include <Roster.h>
17 #include <Screen.h>
18 #include <ScrollBar.h>
19 #include <TextControl.h>
20 #include <WindowScreen.h>
21 #include <float.h>
22 #include <stdio.h>
23 #include <string>
24 #include <sys/time.h>
25 #include <unistd.h>
26 
27 #include "CodeConv.h"
28 #include "ColorWindow.h"
29 #include "MenuUtil.h"
30 #include "FindDlg.h"
31 #include "PrefDlg.h"
32 #include "PrefView.h"
33 #include "PrefHandler.h"
34 #include "TermApp.h"
35 #include "TermBaseView.h"
36 #include "TermBuffer.h"
37 #include "TermParse.h"
38 #include "TermView.h"
39 #include "TermWindow.h"
40 #include "TermConst.h"
41 #include "spawn.h"
42 
43 
44 // Global Preference Handler
45 extern PrefHandler *gTermPref;
46 //
47 // help and GPL URL
48 //
49 //#define URL_PREFIX  "file:///boot/home/config/settings/MuTerminal/help/"
50 //#define INDEX_FILE  "/index.html"
51 //#define GPL_FILE  "/gpl.html"
52 //#define CHLP_FILE   "file:///boot/beos/documentation/Shell%20Tools/index.html"
53 
54 extern int gNowCoding;  /* defined TermParce.cpp */
55 
56 void SetCoding(int);
57 
58 
59 TermWindow::TermWindow(BRect frame, const char* title)
60 	: BWindow(frame, title, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE)
61 {
62 	InitWindow();
63 
64 	fPrintSettings = NULL;
65 	fPrefWindow = NULL;
66 	fFindPanel = NULL;
67 }
68 
69 
70 TermWindow::~TermWindow()
71 {
72 	delete fWindowUpdate;
73 }
74 
75 
76 //	#pragma mark - public methods
77 
78 
79 /** Initialize Window object. */
80 
81 void
82 TermWindow::InitWindow(void)
83 {
84 	// make menu bar
85 	SetupMenu();
86 
87 	// Setup font.
88 
89 	const char *family = gTermPref->getString(PREF_HALF_FONT_FAMILY);
90 
91 	BFont halfFont;
92 	halfFont.SetFamilyAndStyle(family, NULL);
93 	float size = gTermPref->getFloat(PREF_HALF_FONT_SIZE);
94 	if (size < 6.0f)
95 		size = 6.0f;
96 	halfFont.SetSize(size);
97 	halfFont.SetSpacing(B_FIXED_SPACING);
98 
99 	family = gTermPref->getString(PREF_FULL_FONT_FAMILY);
100 
101 	BFont fullFont;
102 	fullFont.SetFamilyAndStyle(family, NULL);
103 	size = gTermPref->getFloat(PREF_FULL_FONT_SIZE);
104 	if (size < 6.0f)
105 		size = 6.0f;
106 	fullFont.SetSize(size);
107 	fullFont.SetSpacing(B_FIXED_SPACING);
108 
109 	// Make Terminal text view.
110 
111 	BRect textframe = Bounds();
112 	textframe.top = fMenubar->Bounds().bottom + 1.0;
113 
114 	fCodeConv = new CodeConv();
115 	fTermView = new TermView(Bounds(), fCodeConv);
116 
117 	/*
118 	 * MuTerm has two views. BaseView is window base view.
119 	 * TermView is character Terminal view on BaseView. It has paste
120 	 * on BaseView shift as VIEW_OFFSET.
121 	 */
122 	fBaseView = new TermBaseView(textframe, fTermView);
123 
124 	// Initialize TermView. (font, size and color)
125 
126 	fTermView->SetTermFont(&halfFont, &fullFont);
127 
128 	BRect rect = fTermView->SetTermSize(gTermPref->getInt32(PREF_ROWS),
129 		gTermPref->getInt32(PREF_COLS), 1);
130 
131 	int width, height;
132 
133 	fTermView->GetFontSize(&width, &height);
134 	SetSizeLimits(MIN_COLS * width, MAX_COLS * width,
135 		MIN_COLS * height, MAX_COLS * height);
136 
137 	fTermView->SetTermColor();
138 	fBaseView->SetViewColor(gTermPref->getRGB(PREF_TEXT_BACK_COLOR));
139 
140 	// Add offset to baseview.
141 	rect.InsetBy(-VIEW_OFFSET, -VIEW_OFFSET);
142 
143 	// Resize Window
144 
145 	ResizeTo(rect.Width()+ B_V_SCROLL_BAR_WIDTH,
146 		rect.Height() + fMenubar->Bounds().Height());
147 
148 	fBaseView->ResizeTo(rect.Width(), rect.Height());
149 	fBaseView->AddChild(fTermView);
150 	fTermView->MoveBy(VIEW_OFFSET, VIEW_OFFSET);
151 
152 	// Make Scroll Bar.
153 
154 	BRect scrollRect(0, 0, B_V_SCROLL_BAR_WIDTH,
155 		rect.Height() - B_H_SCROLL_BAR_HEIGHT + 1);
156 
157 	scrollRect.OffsetBy(rect.Width() + 1, fMenubar->Bounds().Height());
158 
159 	BScrollBar *scrollBar = new BScrollBar(scrollRect, "scrollbar",
160 		fTermView, 0, 0, B_VERTICAL);
161 	fTermView->SetScrollBar(scrollBar);
162 
163 	AddChild(scrollBar);
164 	AddChild(fBaseView);
165 
166 	// Set fEditmenu's target to fTermView. (Oh!...)
167 	fEditmenu->SetTargetForItems(fTermView);
168 
169 	// Initialize TermParse
170 
171 	gNowCoding = longname2op(gTermPref->getString(PREF_TEXT_ENCODING));
172 	fTermParse = new TermParse();
173 	fTermParse->InitPtyReader(this);
174 	fTermParse->InitTermParse(fTermView, fCodeConv);
175 
176 	// Set Coding.
177 
178 	// Init find parameters
179 	fMatchCase = false;
180 	fMatchWord = false;
181 	fFindSelection = false;
182 	fForwardSearch = false;
183 
184 	// Initialize MessageRunner.
185 	fWindowUpdate = new BMessageRunner(BMessenger(this),
186 		new BMessage (MSGRUN_WINDOW), 500000);
187 }
188 
189 
190 void
191 TermWindow::MenusBeginning(void)
192 {
193 	// Syncronize Encode Menu Pop-up menu and Preference.
194 	(fEncodingmenu->FindItem(op2longname(gNowCoding)))->SetMarked(true);
195 	BWindow::MenusBeginning();
196 }
197 
198 
199 void
200 TermWindow::SetupMenu(void)
201 {
202 	PrefHandler menuText;
203 
204 	LoadLocaleFile (&menuText);
205 
206 	// Menu bar object.
207 	fMenubar = new BMenuBar(Bounds(), "mbar");
208 
209 	// Make File Menu.
210 	fFilemenu = new BMenu("Terminal");
211 	fFilemenu->AddItem(new BMenuItem("Switch Terminals", new BMessage(MENU_SWITCH_TERM),'G'));
212 	fFilemenu->AddItem(new BMenuItem("Start New Terminal", new BMessage(MENU_NEW_TERM), 'N'));
213 	fFilemenu->AddSeparatorItem();
214 	fFilemenu->AddItem(new BMenuItem("Page Setup...", new BMessage(MENU_PAGE_SETUP)));
215 	fFilemenu->AddItem(new BMenuItem("Print", new BMessage(MENU_PRINT),'P'));
216 	fFilemenu->AddSeparatorItem();
217 	fFilemenu->AddItem(new BMenuItem("About Terminal...", new BMessage(B_ABOUT_REQUESTED)));
218 	fFilemenu->AddSeparatorItem();
219 	fFilemenu->AddItem(new BMenuItem("Quit", new BMessage(MENU_FILE_QUIT), 'Q'));
220 	fMenubar->AddItem(fFilemenu);
221 
222 	// Make Edit Menu.
223 	fEditmenu = new BMenu ("Edit");
224 	fEditmenu->AddItem (new BMenuItem ("Copy", new BMessage (B_COPY),'C'));
225 	fEditmenu->AddItem (new BMenuItem ("Paste", new BMessage (B_PASTE),'V'));
226 	fEditmenu->AddSeparatorItem ();
227 	fEditmenu->AddItem (new BMenuItem ("Select All", new BMessage (B_SELECT_ALL), 'A'));
228 	fEditmenu->AddItem (new BMenuItem ("Clear All", new BMessage (MENU_CLEAR_ALL), 'L'));
229 	fEditmenu->AddSeparatorItem ();
230 	fEditmenu->AddItem (new BMenuItem ("Find", new BMessage (MENU_FIND_STRING),'F'));
231 	fFindBackwardMenuItem = new BMenuItem ("Find Backward", new BMessage (MENU_FIND_BACKWARD), '[');
232 	fEditmenu->AddItem (fFindBackwardMenuItem);
233 	fFindBackwardMenuItem->SetEnabled(false);
234 	fFindForwardMenuItem = new BMenuItem ("Find Forward", new BMessage (MENU_FIND_FORWARD), ']');
235 	fEditmenu->AddItem (fFindForwardMenuItem);
236 	fFindForwardMenuItem->SetEnabled(false);
237 
238 
239 	fMenubar->AddItem (fEditmenu);
240 
241 	// Make Help Menu.
242 	fHelpmenu = new BMenu("Settings");
243 	fWindowSizeMenu = new BMenu("Window Size");
244 	fWindowSizeMenu->AddItem(new BMenuItem("80x24", new BMessage(EIGHTYTWENTYFOUR)));
245 	fWindowSizeMenu->AddItem(new BMenuItem("80x25", new BMessage(EIGHTYTWENTYFIVE)));
246 	fWindowSizeMenu->AddItem(new BMenuItem("80x40", new BMessage(EIGHTYFORTY)));
247 	fWindowSizeMenu->AddItem(new BMenuItem("132x24", new BMessage(ONETHREETWOTWENTYFOUR)));
248 	fWindowSizeMenu->AddItem(new BMenuItem("132x25", new BMessage(ONETHREETWOTWENTYFIVE)));
249 	fWindowSizeMenu->AddItem(new BMenuItem("Fullscreen", new BMessage(FULLSCREEN), B_ENTER));
250 
251  	// Considering we have this in the preferences window, this menu is not
252  	// needed and should not be shown if we are to not confuse the user
253 /*  fNewFontMenu = new BMenu("Font");
254 	fNewFontMenu->SetRadioMode(true);
255 		int32 numFamilies1 = count_font_families();
256 		for ( int32 i = 0; i < numFamilies1; i++ ) {
257 			font_family family;
258 			uint32 flags;
259 			if ( get_font_family(i, &family, &flags) == B_OK ) {
260 				fNewFontMenu->AddItem(item = new BMenuItem(family, new BMessage(MSG_FONT_CHANGED)));
261 			//	if (0 ==i) item->SetMarked(true);
262 			}
263 		}
264   fNewFontMenu->FindItem (gTermPref->getString(PREF_HALF_FONT_FAMILY))->SetMarked(true);
265 */
266 
267 	fEncodingmenu = new BMenu("Font Encoding");
268 	fEncodingmenu->SetRadioMode(true);
269 	MakeEncodingMenu(fEncodingmenu, gNowCoding, true);
270 	fHelpmenu->AddItem(fWindowSizeMenu);
271 	fHelpmenu->AddItem(fEncodingmenu);
272 //  fHelpmenu->AddItem(fNewFontMenu);
273 	fHelpmenu->AddSeparatorItem();
274 	fHelpmenu->AddItem(new BMenuItem("Preferences", new BMessage(MENU_PREF_OPEN)));
275 	fHelpmenu->AddSeparatorItem();
276 	fHelpmenu->AddItem(new BMenuItem("Save as default", new BMessage(SAVE_AS_DEFAULT)));
277 	fMenubar->AddItem(fHelpmenu);
278 
279 	AddChild(fMenubar);
280 }
281 
282 
283 void
284 TermWindow::MessageReceived(BMessage *message)
285 {
286   int32 coding_id;
287   BRect r;
288   BFont halfFont;
289   BFont fullFont;
290   bool findresult;
291 
292 	switch (message->what) {
293 		case MENU_SWITCH_TERM: {
294 			be_app->PostMessage(MENU_SWITCH_TERM);
295 			break;
296 		}
297 		case MENU_NEW_TERM: {
298 			app_info info;
299 			be_app->GetAppInfo(&info);
300 
301 			// try launching two different ways to work around possible problems
302 			if (be_roster->Launch(&info.ref)!=B_OK)
303 			be_roster->Launch(TERM_SIGNATURE);
304 			break;
305 		}
306 		case MENU_PREF_OPEN: {
307 			if (!fPrefWindow)
308 				fPrefWindow = new PrefDlg(this);
309 			else
310 				fPrefWindow->Activate();
311 			break;
312 		}
313 		case MSG_PREF_CLOSED: {
314 			fPrefWindow = NULL;
315 			break;
316 		}
317 		case MENU_FIND_STRING: {
318 			if (!fFindPanel) {
319 				BRect r = Frame();
320 				r.left += 20;
321 				r.top += 20;
322 				r.right = r.left + 260;
323 				r.bottom = r.top + 190;
324 				fFindPanel = new FindDlg(r, this, fFindString, fFindSelection, fMatchWord, fMatchCase, fForwardSearch);
325 			}
326 			else
327 				fFindPanel->Activate();
328 			break;
329 		}
330 		case MSG_FIND: {
331 			fFindPanel->PostMessage(B_QUIT_REQUESTED);
332 			message->FindBool("findselection", &fFindSelection);
333 			if (!fFindSelection)
334 				message->FindString("findstring", &fFindString);
335 			else
336 				fTermView->GetSelection(fFindString);
337 
338 			if (fFindString.Length() == 0) {
339 				BAlert *alert = new BAlert("find failed", "No search string.", "Okay", NULL,
340 					NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
341 				alert->Go();
342 				fFindBackwardMenuItem->SetEnabled(false);
343 				fFindForwardMenuItem->SetEnabled(false);
344 				break;
345 			}
346 
347 			message->FindBool("forwardsearch", &fForwardSearch);
348 			message->FindBool("matchcase", &fMatchCase);
349 			message->FindBool("matchword", &fMatchWord);
350 			findresult = fTermView->Find(fFindString, fForwardSearch, fMatchCase, fMatchWord);
351 
352 			if (!findresult) {
353 				BAlert *alert = new BAlert("find failed", "Not Found.", "Okay", NULL,
354 					NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
355 				alert->Go();
356 				fFindBackwardMenuItem->SetEnabled(false);
357 				fFindForwardMenuItem->SetEnabled(false);
358 				break;
359 			}
360 
361 			//Enable the menu items Find Forward and Find Backward
362 			fFindBackwardMenuItem->SetEnabled(true);
363 			fFindForwardMenuItem->SetEnabled(true);
364 			break;
365 		}
366 		case MENU_FIND_FORWARD: {
367 			findresult = fTermView->Find(fFindString, true, fMatchCase, fMatchWord);
368 			if (!findresult) {
369 				BAlert *alert = new BAlert("find failed", "Not Found.", "Okay", NULL,
370 					NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
371 				alert->Go();
372 			}
373 			break;
374 		}
375 		case MENU_FIND_BACKWARD: {
376 			findresult = fTermView->Find(fFindString, false, fMatchCase, fMatchWord);
377 			if (!findresult) {
378 				BAlert *alert = new BAlert("find failed", "Not Found.", "Okay", NULL,
379 					NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
380 				alert->Go();
381 			}
382 			break;
383 		}
384 		case MSG_FIND_CLOSED: {
385 			fFindPanel = NULL;
386 			break;
387 		}
388 		case MENU_FILE_QUIT: {
389 			be_app->PostMessage(B_QUIT_REQUESTED);
390 			break;
391 		}
392 		case MENU_ENCODING: {
393 			message->FindInt32 ("op", &coding_id);
394 			gNowCoding = coding_id;
395 			SetCoding(coding_id);
396 			break;
397 		}
398 		// Extended B_SET_PROPERTY. Dispatch this message,
399 		// Set coding ID.
400 		case B_SET_PROPERTY: {
401 			int32 i;
402 			BMessage spe;
403 			message->GetCurrentSpecifier(&i, &spe);
404 			if (!strcmp("encode", spe.FindString("property", i))){
405 				message->FindInt32 ("data",  &coding_id);
406 				gNowCoding = coding_id;
407 				SetCoding (coding_id);
408 
409 				message->SendReply(B_REPLY);
410 			} else {
411 				BWindow::MessageReceived(message);
412 			}
413 			break;
414 		}
415 
416 		// Extended B_GET_PROPERTY. Dispatch this message, reply now coding ID.
417 		case B_GET_PROPERTY: {
418 			int32 i;
419 			BMessage spe;
420 			message->GetCurrentSpecifier(&i, &spe);
421 			if (!strcmp("encode", spe.FindString("property", i))){
422 				BMessage reply(B_REPLY);
423 				reply.AddInt32("result", gNowCoding);
424 				message->SendReply(&reply);
425 			}
426 			else if (!strcmp("tty", spe.FindString("property", i))) {
427 				BMessage reply(B_REPLY);
428 				reply.AddString("result", &tty_name[8]);
429 				message->SendReply(&reply);
430 			} else {
431 				BWindow::MessageReceived(message);
432 			}
433 			break;
434 		}
435 
436 		// Message from Preference panel.
437 		case MSG_ROWS_CHANGED:
438 		case MSG_COLS_CHANGED: {
439 			r = fTermView->SetTermSize (gTermPref->getInt32 (PREF_ROWS),
440 										gTermPref->getInt32 (PREF_COLS), 0);
441 
442 			ResizeTo (r.Width()+ B_V_SCROLL_BAR_WIDTH + VIEW_OFFSET * 2,
443 			r.Height()+fMenubar->Bounds().Height() + VIEW_OFFSET *2);
444 
445 			BPath path;
446 			if (PrefHandler::GetDefaultPath(path) == B_OK)
447 				gTermPref->SaveAsText(path.Path(), PREFFILE_MIMETYPE);
448 			break;
449 		}
450 		case MSG_HALF_FONT_CHANGED:
451 		case MSG_FULL_FONT_CHANGED:
452 		case MSG_HALF_SIZE_CHANGED:
453 		case MSG_FULL_SIZE_CHANGED: {
454 
455 			halfFont.SetFamilyAndStyle (gTermPref->getString(PREF_HALF_FONT_FAMILY),NULL);
456 			halfFont.SetSize (gTermPref->getFloat(PREF_HALF_FONT_SIZE));
457 			halfFont.SetSpacing (B_FIXED_SPACING);
458 
459 			fullFont.SetFamilyAndStyle (gTermPref->getString(PREF_FULL_FONT_FAMILY),NULL);
460 			fullFont.SetSize (gTermPref->getFloat(PREF_FULL_FONT_SIZE));
461 			fullFont.SetSpacing (B_FIXED_SPACING);
462 
463 			fTermView->SetTermFont (&halfFont, &fullFont);
464 			r = fTermView->SetTermSize (0, 0, 0);
465 
466 			int width, height;
467 
468 			fTermView->GetFontSize (&width, &height);
469 
470 			SetSizeLimits (MIN_COLS * width, MAX_COLS * width,
471 							MIN_COLS * height, MAX_COLS * height);
472 
473 			ResizeTo (r.Width()+ B_V_SCROLL_BAR_WIDTH + VIEW_OFFSET * 2,
474 			r.Height()+fMenubar->Bounds().Height() + VIEW_OFFSET * 2);
475 
476 			fTermView->Invalidate();
477 		    break;
478 		}
479 		case EIGHTYTWENTYFOUR: {
480 			gTermPref->setString(PREF_COLS, "80");
481 			gTermPref->setString(PREF_ROWS, "24");
482 		   	this->PostMessage (MSG_ROWS_CHANGED);
483 			this->PostMessage (MSG_COLS_CHANGED);
484 			break;
485 		}
486 		case EIGHTYTWENTYFIVE: {
487 			gTermPref->setString(PREF_COLS, "80");
488 			gTermPref->setString(PREF_ROWS, "25");
489 		   	this->PostMessage (MSG_ROWS_CHANGED);
490 		   	this->PostMessage (MSG_COLS_CHANGED);
491 			break;
492 		}
493 		case EIGHTYFORTY: {
494 			gTermPref->setString(PREF_COLS, "80");
495 			gTermPref->setString(PREF_ROWS, "40");
496 		   	this->PostMessage (MSG_ROWS_CHANGED);
497 		   	this->PostMessage (MSG_COLS_CHANGED);
498 			break;
499 		}
500 		case ONETHREETWOTWENTYFOUR: {
501 			gTermPref->setString(PREF_COLS, "132");
502 			gTermPref->setString(PREF_ROWS, "24");
503 		   	this->PostMessage (MSG_ROWS_CHANGED);
504 		   	this->PostMessage (MSG_COLS_CHANGED);
505 			break;
506 		}
507 		case ONETHREETWOTWENTYFIVE: {
508 			gTermPref->setString(PREF_COLS, "132");
509 			gTermPref->setString(PREF_ROWS, "25");
510 		   	this->PostMessage (MSG_ROWS_CHANGED);
511 		   	this->PostMessage (MSG_COLS_CHANGED);
512 			break;
513 		}
514 		case FULLSCREEN: {
515 			if (!fSavedFrame.IsValid()) { // go fullscreen
516 				float mbHeight = fMenubar->Bounds().Height() + 1;
517 				fSavedFrame = Frame();
518 				BScreen screen(this);
519 				fTermView->ScrollBar()->Hide();
520 				fMenubar->Hide();
521 				fBaseView->MoveTo(0,0);
522 				fBaseView->ResizeBy(B_V_SCROLL_BAR_WIDTH, mbHeight);
523 				fSavedLook = Look();
524 				// done before ResizeTo to work around a Dano bug (not erasing the decor)
525 				SetLook(B_NO_BORDER_WINDOW_LOOK);
526 				ResizeTo(screen.Frame().Width()+1, screen.Frame().Height()+1);
527 				MoveTo(screen.Frame().left, screen.Frame().top);
528 			} else { // exit fullscreen
529 				float mbHeight = fMenubar->Bounds().Height() + 1;
530 				fMenubar->Show();
531 				fTermView->ScrollBar()->Show();
532 				ResizeTo(fSavedFrame.Width(), fSavedFrame.Height());
533 				MoveTo(fSavedFrame.left, fSavedFrame.top);
534 				fBaseView->ResizeBy(-B_V_SCROLL_BAR_WIDTH, -mbHeight);
535 				fBaseView->MoveTo(0,mbHeight);
536 				SetLook(fSavedLook);
537 				fSavedFrame = BRect(0,0,-1,-1);
538 			}
539 			break;
540 		}
541 		case MSG_FONT_CHANGED: {
542 	    	gTermPref->setString (PREF_HALF_FONT_FAMILY, fNewFontMenu->FindMarked()->Label());
543 	    	this->PostMessage (MSG_HALF_FONT_CHANGED);
544 		    break;
545 		}
546 		case MSG_COLOR_CHANGED: {
547 			fBaseView->SetViewColor (gTermPref->getRGB (PREF_TEXT_BACK_COLOR));
548 			fTermView->SetTermColor ();
549 			fBaseView->Invalidate();
550 			fTermView->Invalidate();
551 			break;
552 		}
553 		case SAVE_AS_DEFAULT: {
554 			BPath path;
555 			if (PrefHandler::GetDefaultPath(path) == B_OK)
556 				gTermPref->SaveAsText(path.Path(), PREFFILE_MIMETYPE);
557 			break;
558 		}
559 		case MENU_PAGE_SETUP: {
560 			DoPageSetup ();
561 			break;
562 		}
563 		case MENU_PRINT: {
564 			DoPrint ();
565 			break;
566 		}
567 		case MSGRUN_WINDOW: {
568 			fTermView->UpdateSIGWINCH ();
569 			break;
570 		}
571 		case B_ABOUT_REQUESTED: {
572 			be_app->PostMessage(B_ABOUT_REQUESTED);
573 			break;
574 		}
575 		default: {
576 			BWindow::MessageReceived(message);
577 			break;
578 		}
579 	}
580 }
581 ////////////////////////////////////////////////////////////////////////////
582 // WindowActivated (bool)
583 //  Dispatch Mesasge.
584 ////////////////////////////////////////////////////////////////////////////
585 void
586 TermWindow::WindowActivated (bool )
587 {
588 
589 }
590 
591 ////////////////////////////////////////////////////////////////////////////
592 // Quit (void)
593 //  Quit Application.
594 ////////////////////////////////////////////////////////////////////////////
595 //void
596 //TermWindow::colRequested() {
597 //	colWindow *colW=new colWindow("Colours for Terminal");
598 //	colW->Show();
599 //	}
600 
601 
602 void
603 TermWindow::Quit(void)
604 {
605 	delete fTermParse;
606 	delete fCodeConv;
607 	if (fPrefWindow) fPrefWindow->PostMessage (B_QUIT_REQUESTED);
608 	if (fFindPanel) fFindPanel->PostMessage(B_QUIT_REQUESTED);
609 
610 	be_app->PostMessage (B_QUIT_REQUESTED, be_app);
611 	BWindow::Quit ();
612 }
613 
614 
615 bool
616 TermWindow::QuitRequested(void)
617 {
618 
619   return true;
620 }
621 ////////////////////////////////////////////////////////////////////////////
622 // int GetTimeZone (void)
623 //  Get Machine Timezone.
624 ////////////////////////////////////////////////////////////////////////////
625 int
626 TermWindow::GetTimeZone ()
627 {
628 	struct timeval tv;
629 	struct timezone tm;
630 
631 	gettimeofday (&tv, &tm);
632 
633 	return -tm.tz_minuteswest / 60;
634 }
635 
636 
637 void
638 TermWindow::TermWinActivate()
639 {
640 	Activate();
641 
642 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
643 	if (focus_follows_mouse()) {
644 		BPoint aMouseLoc = Frame().LeftTop();
645 		set_mouse_position(int32(aMouseLoc.x + 16), int32(aMouseLoc.y + 2));
646 		be_app->SetCursor(B_HAND_CURSOR);
647 	}
648 #endif
649 }
650 
651 
652 status_t
653 TermWindow::GetSupportedSuites(BMessage *msg)
654 {
655   static property_info prop_list[] = {
656      { "encode",
657        {B_GET_PROPERTY, 0},
658        {B_DIRECT_SPECIFIER, 0},
659        "get muterminal encode"},
660      { "encode",
661        {B_SET_PROPERTY, 0},
662        {B_DIRECT_SPECIFIER, 0},
663        "set muterminal encode"},
664      { "tty",
665        {B_GET_PROPERTY, 0},
666        {B_DIRECT_SPECIFIER, 0},
667        "get tty_name."},
668      { 0  }
669 
670   };
671   msg->AddString("suites", "suite/vnd.naan-termwindow");
672   BPropertyInfo prop_info(prop_list);
673   msg->AddFlat("messages", &prop_info);
674   return BWindow::GetSupportedSuites(msg);
675 }
676 ////////////////////////////////////////////////////////////////////////////
677 // ResolveSpecifier
678 //
679 ////////////////////////////////////////////////////////////////////////////
680 BHandler*
681 TermWindow::ResolveSpecifier(BMessage *msg, int32 index,
682            BMessage *specifier, int32 form,
683            const char *property)
684 {
685   if ( (strcmp(property, "encode") == 0)
686     && ((msg->what == B_SET_PROPERTY) || (msg->what == B_GET_PROPERTY) ))
687       return this;
688   else if ( (strcmp(property, "tty") == 0)
689     &&  (msg->what == B_GET_PROPERTY) )
690       return this;
691 
692   return BWindow::ResolveSpecifier(msg, index, specifier, form, property);
693 }
694 
695 ////////////////////////////////////////////////////////////////////////////
696 // SetCoding
697 //  Set coding utility functions.
698 ////////////////////////////////////////////////////////////////////////////
699 void SetCoding (int coding)
700 {
701   const etable *p = encoding_table;
702   p += coding;
703 
704   gNowCoding = coding;
705 
706   return;
707 }
708 ////////////////////////////////////////////////////////////////////////////
709 // DoPageSetUp ()
710 //
711 ////////////////////////////////////////////////////////////////////////////
712 status_t
713 TermWindow::DoPageSetup()
714 {
715   status_t rv;
716   BPrintJob job("PageSetup");
717 
718   /* display the page configure panel */
719   rv = job.ConfigPage();
720 
721   /* save a pointer to the settings */
722   fPrintSettings = job.Settings();
723 
724   return rv;
725 }
726 
727 ////////////////////////////////////////////////////////////////////////////
728 // DoPrint ()
729 //
730 ////////////////////////////////////////////////////////////////////////////
731 void
732 TermWindow::DoPrint()
733 {
734 //#if B_BEOS_VERSION < 0x0460
735   BPrintJob job("Print");
736 
737   if((! fPrintSettings) || (DoPageSetup() != B_NO_ERROR)) {
738     (new BAlert("Cancel", "Print cancelled.", "OK"))->Go();
739   return;
740   }
741 
742   job.SetSettings(new BMessage(*fPrintSettings));
743 
744   BRect pageRect = job.PrintableRect();
745   BRect curPageRect = pageRect;
746 
747   int pHeight = (int)pageRect.Height();
748   int pWidth = (int)pageRect.Width();
749   float w,h;
750   fTermView->GetFrameSize (&w, &h);
751   int xPages = (int)ceil(w / pWidth);
752   int yPages = (int)ceil(h / pHeight);
753 
754    /* engage the print server */
755   job.BeginJob();
756 
757   /* loop through and draw each page, and write to spool */
758   for(int x = 0; x < xPages; x++)
759     for(int y = 0; y < yPages; y++){
760       curPageRect.OffsetTo(x * pWidth, y * pHeight);
761       job.DrawView(fTermView, curPageRect, BPoint(0, 0));
762       job.SpoolPage();
763 
764       if(!job.CanContinue()){
765       	  // It is likely that the only way that the job was cancelled is
766       	  // because the user hit 'Cancel' in the page setup window, in which
767       	  // case, the user does *not* need to be told that it was cancelled.
768       	  // He/she will simply expect that it was done.
769 //        (new BAlert("Cancel", "Print job cancelled", "OK"))->Go();
770         return;
771       }
772   }
773 
774   /* commit the job, send the spool file */
775   job.CommitJob();
776 //#endif
777 }
778 
779 
780 
781