xref: /haiku/src/apps/serialconnect/TermView.cpp (revision 7a74a5df454197933bc6e80a542102362ee98703)
1 /*
2  * Copyright 2012, Adrien Destugues, pulkomandy@gmail.com
3  * Distributed under the terms of the MIT licence.
4  */
5 
6 
7 #include "TermView.h"
8 
9 #include <stdio.h>
10 
11 #include <Layout.h>
12 
13 #include "SerialApp.h"
14 
15 
16 TermView::TermView()
17 	:
18 	BView("TermView", B_WILL_DRAW)
19 {
20 	font_height height;
21 	GetFontHeight(&height);
22 	fFontHeight = height.ascent + height.descent + height.leading;
23 	fFontWidth = be_fixed_font->StringWidth("X");
24 	fTerm = vterm_new(kDefaultHeight, kDefaultWidth);
25 
26 	vterm_parser_set_utf8(fTerm, 1);
27 
28 	fTermScreen = vterm_obtain_screen(fTerm);
29 	vterm_screen_set_callbacks(fTermScreen, &sScreenCallbacks, this);
30 	vterm_screen_reset(fTermScreen, 1);
31 
32 	SetFont(be_fixed_font);
33 }
34 
35 
36 TermView::~TermView()
37 {
38 	vterm_free(fTerm);
39 }
40 
41 
42 void TermView::AttachedToWindow()
43 {
44 	MakeFocus();
45 }
46 
47 
48 void TermView::Draw(BRect updateRect)
49 {
50 	VTermRect updatedChars = PixelsToGlyphs(updateRect);
51 
52 	VTermPos pos;
53 	font_height height;
54 	GetFontHeight(&height);
55 	for (pos.row = updatedChars.start_row; pos.row <= updatedChars.end_row;
56 			pos.row++) {
57 		float x = updatedChars.start_col * fFontWidth + kBorderSpacing;
58 		float y = pos.row * fFontHeight + height.ascent + kBorderSpacing;
59 		MovePenTo(x, y);
60 
61 		for (pos.col = updatedChars.start_col;
62 				pos.col <= updatedChars.end_col;) {
63 			if (pos.col < 0 || pos.row < 0 || pos.col >= kDefaultWidth
64 					|| pos.row >= kDefaultHeight) {
65 				DrawString(" ");
66 				pos.col ++;
67 			} else {
68 				VTermScreenCell cell;
69 				vterm_screen_get_cell(fTermScreen, pos, &cell);
70 
71 				if (cell.chars[0] == 0) {
72 					DrawString(" ");
73 					pos.col ++;
74 				} else {
75 					char buffer[VTERM_MAX_CHARS_PER_CELL];
76 					wcstombs(buffer, (wchar_t*)cell.chars,
77 						VTERM_MAX_CHARS_PER_CELL);
78 
79 					DrawString(buffer);
80 					pos.col += cell.width;
81 				}
82 			}
83 		}
84 	}
85 }
86 
87 
88 void TermView::GetPreferredSize(float* width, float* height)
89 {
90 	if (width != NULL)
91 		*width = kDefaultWidth * fFontWidth + 2 * kBorderSpacing;
92 	if (height != NULL)
93 		*height = kDefaultHeight * fFontHeight + 2 * kBorderSpacing;
94 }
95 
96 
97 void TermView::KeyDown(const char* bytes, int32 numBytes)
98 {
99 	BMessage* keyEvent = new BMessage(kMsgDataWrite);
100 	keyEvent->AddData("data", B_RAW_TYPE, bytes, numBytes);
101 	be_app_messenger.SendMessage(keyEvent);
102 }
103 
104 
105 void TermView::PushBytes(const char* bytes, size_t length)
106 {
107 	vterm_push_bytes(fTerm, bytes, length);
108 }
109 
110 
111 VTermRect TermView::PixelsToGlyphs(BRect pixels) const
112 {
113 	pixels.OffsetBy(-kBorderSpacing, -kBorderSpacing);
114 
115 	VTermRect rect;
116 	rect.start_col = (int)floor(pixels.left / fFontWidth);
117 	rect.end_col = (int)ceil(pixels.right / fFontWidth);
118 	rect.start_row = (int)floor(pixels.top / fFontHeight);
119 	rect.end_row = (int)ceil(pixels.bottom / fFontHeight);
120 /*
121 	printf(
122 		"TOP %d ch < %f px\n"
123 		"BTM %d ch < %f px\n"
124 		"LFT %d ch < %f px\n"
125 		"RGH %d ch < %f px\n",
126 		rect.start_row, pixels.top,
127 		rect.end_row, pixels.bottom,
128 		rect.start_col, pixels.left,
129 		rect.end_col, pixels.right
130 	);
131 */
132 	return rect;
133 }
134 
135 
136 BRect TermView::GlyphsToPixels(const VTermRect& glyphs) const
137 {
138 	BRect rect;
139 	rect.top = glyphs.start_row * fFontHeight;
140 	rect.bottom = glyphs.end_row * fFontHeight;
141 	rect.left = glyphs.start_col * fFontWidth;
142 	rect.right = glyphs.end_col * fFontWidth;
143 
144 	rect.OffsetBy(kBorderSpacing, kBorderSpacing);
145 /*
146 	printf(
147 		"TOP %d ch > %f px (%f)\n"
148 		"BTM %d ch > %f px\n"
149 		"LFT %d ch > %f px (%f)\n"
150 		"RGH %d ch > %f px\n",
151 		glyphs.start_row, rect.top, fFontHeight,
152 		glyphs.end_row, rect.bottom,
153 		glyphs.start_col, rect.left, fFontWidth,
154 		glyphs.end_col, rect.right
155 	);
156 */
157 	return rect;
158 }
159 
160 
161 BRect TermView::GlyphsToPixels(const int width, const int height) const
162 {
163 	VTermRect rect;
164 	rect.start_row = 0;
165 	rect.start_col = 0;
166 	rect.end_row = height;
167 	rect.end_col = width;
168 	return GlyphsToPixels(rect);
169 }
170 
171 
172 void TermView::Damage(VTermRect rect)
173 {
174 	Invalidate();
175 //	Invalidate(GlyphsToPixels(rect));
176 }
177 
178 
179 /* static */
180 int TermView::Damage(VTermRect rect, void* user)
181 {
182 	TermView* view = (TermView*)user;
183 	view->Damage(rect);
184 
185 	return 0;
186 }
187 
188 
189 const VTermScreenCallbacks TermView::sScreenCallbacks = {
190 	&TermView::Damage,
191 	/*.moverect =*/ NULL,
192 	/*.movecursor =*/ NULL,
193 	/*.settermprop =*/ NULL,
194 	/*.setmousefunc =*/ NULL,
195 	/*.bell =*/ NULL,
196 	/*.resize =*/ NULL,
197 };
198