vfs: check userland buffers before reading them.
[haiku.git] / src / preferences / screen / MonitorView.cpp
blobb390d418065e5bd0a03bebade3df4f460a0c80cd
1 /*
2 * Copyright 2001-2009, Haiku.
3 * Copyright 2002, Thomas Kurschel.
4 * Distributed under the terms of the MIT License.
6 * Authors:
7 * Rafael Romo
8 * Thomas Kurschel
9 * Axel Dörfler, axeld@pinc-software.de
13 #include "MonitorView.h"
15 #include <stdio.h>
17 #include <Catalog.h>
18 #include <Locale.h>
19 #include <Roster.h>
20 #include <Screen.h>
22 #include "Constants.h"
24 #undef B_TRANSLATION_CONTEXT
25 #define B_TRANSLATION_CONTEXT "Monitor View"
28 MonitorView::MonitorView(BRect rect, const char *name, int32 width, int32 height)
29 : BView(rect, name, B_FOLLOW_ALL, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
30 fMaxWidth(1920),
31 fMaxHeight(1200),
32 fWidth(width),
33 fHeight(height),
34 fDPI(0)
36 BScreen screen(B_MAIN_SCREEN_ID);
37 fDesktopColor = screen.DesktopColor(current_workspace());
41 MonitorView::~MonitorView()
46 void
47 MonitorView::AttachedToWindow()
49 SetViewColor(B_TRANSPARENT_COLOR);
50 fBackgroundColor = ui_color(B_PANEL_BACKGROUND_COLOR);
52 _UpdateDPI();
56 void
57 MonitorView::MouseDown(BPoint point)
59 be_roster->Launch(kBackgroundsSignature);
63 void
64 MonitorView::Draw(BRect updateRect)
66 rgb_color darkColor = {160, 160, 160, 255};
67 rgb_color blackColor = {0, 0, 0, 255};
68 rgb_color redColor = {228, 0, 0, 255};
69 rgb_color whiteColor = {255, 255, 255, 255};
70 BRect outerRect = _MonitorBounds();
72 SetHighColor(fBackgroundColor);
73 FillRect(updateRect);
75 SetDrawingMode(B_OP_OVER);
77 // frame & background
79 SetHighColor(darkColor);
80 FillRoundRect(outerRect, 3.0, 3.0);
82 SetHighColor(blackColor);
83 StrokeRoundRect(outerRect, 3.0, 3.0);
85 SetHighColor(fDesktopColor);
87 BRect innerRect(outerRect.InsetByCopy(4, 4));
88 FillRoundRect(innerRect, 2.0, 2.0);
90 SetHighColor(blackColor);
91 StrokeRoundRect(innerRect, 2.0, 2.0);
93 SetDrawingMode(B_OP_COPY);
95 // power light
97 SetHighColor(redColor);
98 BPoint powerPos(outerRect.left + 5, outerRect.bottom - 2);
99 StrokeLine(powerPos, BPoint(powerPos.x + 2, powerPos.y));
101 // DPI
103 if (fDPI == 0)
104 return;
106 font_height fontHeight;
107 GetFontHeight(&fontHeight);
108 float height = ceilf(fontHeight.ascent + fontHeight.descent);
110 char text[64];
111 snprintf(text, sizeof(text), B_TRANSLATE("%ld dpi"), fDPI);
113 float width = StringWidth(text);
114 if (width > innerRect.Width() || height > innerRect.Height())
115 return;
117 SetLowColor(fDesktopColor);
118 SetHighColor(whiteColor);
120 DrawString(text, BPoint(innerRect.left + (innerRect.Width() - width) / 2,
121 innerRect.top + fontHeight.ascent + (innerRect.Height() - height) / 2));
125 void
126 MonitorView::SetResolution(int32 width, int32 height)
128 if (fWidth == width && fHeight == height)
129 return;
131 fWidth = width;
132 fHeight = height;
134 _UpdateDPI();
135 Invalidate();
139 void
140 MonitorView::SetMaxResolution(int32 width, int32 height)
142 if (fMaxWidth == width && fMaxHeight == height)
143 return;
145 fMaxWidth = width;
146 fMaxHeight = height;
148 Invalidate();
152 void
153 MonitorView::MessageReceived(BMessage* message)
155 switch (message->what) {
156 case B_COLORS_UPDATED:
158 message->FindColor(ui_color_name(B_PANEL_BACKGROUND_COLOR),
159 &fBackgroundColor);
160 break;
162 case UPDATE_DESKTOP_MSG:
164 int32 width, height;
165 if (message->FindInt32("width", &width) == B_OK
166 && message->FindInt32("height", &height) == B_OK)
167 SetResolution(width, height);
168 break;
171 case UPDATE_DESKTOP_COLOR_MSG:
173 BScreen screen(Window());
174 rgb_color color = screen.DesktopColor(current_workspace());
175 if (color != fDesktopColor) {
176 fDesktopColor = color;
177 Invalidate();
179 break;
182 default:
183 BView::MessageReceived(message);
184 break;
189 BRect
190 MonitorView::_MonitorBounds()
192 float maxWidth = Bounds().Width();
193 float maxHeight = Bounds().Height();
194 if (maxWidth / maxHeight > (float)fMaxWidth / fMaxHeight)
195 maxWidth = maxHeight / fMaxHeight * fMaxWidth;
196 else
197 maxHeight = maxWidth / fMaxWidth * fMaxHeight;
199 float factorX = (float)fWidth / fMaxWidth;
200 float factorY = (float)fHeight / fMaxHeight;
202 if (factorX > factorY && factorX > 1) {
203 factorY /= factorX;
204 factorX = 1;
205 } else if (factorY > factorX && factorY > 1) {
206 factorX /= factorY;
207 factorY = 1;
210 float width = maxWidth * factorX;
211 float height = maxHeight * factorY;
213 BSize size = Bounds().Size();
214 return BRect((size.width - width) / 2, (size.height - height) / 2,
215 (size.width + width) / 2, (size.height + height) / 2);
219 void
220 MonitorView::_UpdateDPI()
222 fDPI = 0;
224 BScreen screen(Window());
225 monitor_info info;
226 if (screen.GetMonitorInfo(&info) != B_OK)
227 return;
229 double x = info.width / 2.54;
230 double y = info.height / 2.54;
232 fDPI = (int32)round((fWidth / x + fHeight / y) / 2);