source: trunk/examples/qws/svgalib/svgalibscreen.cpp@ 561

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 10.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "svgalibscreen.h"
43#include "svgalibsurface.h"
44
45#include <QVector>
46#include <QApplication>
47#include <QColor>
48#include <QWidget>
49
50#include <math.h>
51
52static int getModeDepth(vga_modeinfo *mode)
53{
54 const int bits = int(log2(mode->colors));
55 if (bits == 24 && mode->bytesperpixel == 4)
56 return 32;
57 return bits;
58}
59
60//! [0]
61bool SvgalibScreen::connect(const QString &displaySpec)
62{
63 int mode = vga_getdefaultmode();
64 if (mode <= 0) {
65 qCritical("SvgalibScreen::connect(): invalid vga mode");
66 return false;
67 }
68
69 vga_modeinfo *modeinfo = vga_getmodeinfo(mode);
70
71 QScreen::lstep = modeinfo->linewidth;
72 QScreen::dw = QScreen::w = modeinfo->width;
73 QScreen::dh = QScreen::h = modeinfo->height;
74 QScreen::d = getModeDepth(modeinfo);
75 QScreen::size = QScreen::lstep * dh;
76 QScreen::data = 0;
77
78 switch (depth()) {
79 case 32:
80 setPixelFormat(QImage::Format_ARGB32_Premultiplied);
81 break;
82 case 24:
83 setPixelFormat(QImage::Format_RGB888);
84 break;
85 case 16:
86 setPixelFormat(QImage::Format_RGB16);
87 break;
88 case 15:
89 setPixelFormat(QImage::Format_RGB555);
90 break;
91 default:
92 break;
93 }
94
95 const int dpi = 72;
96 QScreen::physWidth = qRound(QScreen::dw * 25.4 / dpi);
97 QScreen::physHeight = qRound(QScreen::dh * 25.4 / dpi);
98
99 const QStringList args = displaySpec.split(QLatin1Char(':'),
100 QString::SkipEmptyParts);
101 grayscale = args.contains(QLatin1String("grayscale"), Qt::CaseInsensitive);
102
103 return true;
104}
105//! [0]
106
107void SvgalibScreen::initColorMap()
108{
109 const int numColors = vga_getcolors();
110 if (numColors == 2 || numColors > 256) {
111 screencols = 0;
112 return; // not a palette based mode
113 }
114
115 if (numColors == 16) {
116 if (grayscale) {
117 for (int i = 0; i < 256; ++i) {
118 const int c = i * 16 / 256;
119 vga_setpalette(i, c, c, c);
120 }
121 screencols = 256; // XXX: takes advantage of optimization in alloc()
122 } else { // read in EGA palette
123 int r, g, b;
124 for (int i = 0; i < 16; ++i) {
125 vga_getpalette(i, &r, &g, &b);
126 screenclut[i] = qRgb(r, g, b);
127 }
128 screencols = 16;
129 }
130
131 return;
132 }
133
134 Q_ASSERT(numColors == 256);
135
136 if (grayscale) {
137 for (int i = 0; i < 256; ++i) {
138 const int c = i * 64 / 256;
139 vga_setpalette(i, c, c, c);
140 }
141 } else {
142 int i = 0;
143
144#if 0
145 // read in EGA palette
146 while (i < 16) {
147 int r, g, b;
148 vga_getpalette(i, &r, &g, &b);
149 screenclut[i] = qRgb(r, g, b);
150 ++i;
151 }
152 screencols = 16;
153#endif
154
155 // 6 * 6 * 6 color cube
156 for (int r = 0; r < 6; ++r) {
157 for (int g = 0; g < 6; ++g) {
158 for (int b = 0; b < 6; ++b) {
159 vga_setpalette(i, r * 64/6, g * 64/6, b * 64/6);
160 screenclut[i] = qRgb(r * 256/6, g * 256/6, b * 256/6);
161 ++i;
162 }
163 }
164 }
165 screencols = i;
166
167 while (i < 256) {
168 screenclut[i] = qRgb(0, 0, 0);
169 ++i;
170 }
171 }
172}
173
174//! [1]
175bool SvgalibScreen::initDevice()
176{
177 if (vga_init() != 0) {
178 qCritical("SvgalibScreen::initDevice(): unable to initialize svgalib");
179 return false;
180 }
181
182 int mode = vga_getdefaultmode();
183 if (vga_setmode(mode) == -1) {
184 qCritical("SvgalibScreen::initialize(): unable to set graphics mode");
185 return false;
186 }
187
188 if (gl_setcontextvga(mode) != 0) {
189 qCritical("SvgalibScreen::initDevice(): unable to set vga context");
190 return false;
191 }
192 context = gl_allocatecontext();
193 gl_getcontext(context);
194
195 vga_modeinfo *modeinfo = vga_getmodeinfo(mode);
196 if (modeinfo->flags & IS_LINEAR)
197 QScreen::data = vga_getgraphmem();
198
199 initColorMap();
200
201 QScreenCursor::initSoftwareCursor();
202 return true;
203}
204//! [1]
205
206//! [2]
207void SvgalibScreen::shutdownDevice()
208{
209 gl_freecontext(context);
210 vga_setmode(TEXT);
211}
212//! [2]
213
214//! [3]
215void SvgalibScreen::disconnect()
216{
217}
218//! [3]
219
220//! [4]
221void SvgalibScreen::solidFill(const QColor &color, const QRegion &reg)
222{
223 int c;
224 if (depth() == 4 || depth() == 8)
225 c = alloc(color.red(), color.green(), color.blue());
226 else
227 c = gl_rgbcolor(color.red(), color.green(), color.blue());
228
229 const QVector<QRect> rects = (reg & region()).rects();
230 for (int i = 0; i < rects.size(); ++i) {
231 const QRect r = rects.at(i);
232 gl_fillbox(r.left(), r.top(), r.width(), r.height(), c);
233 }
234}
235//! [4]
236
237void SvgalibScreen::blit16To8(const QImage &image,
238 const QPoint &topLeft, const QRegion &region)
239{
240 const int imageStride = image.bytesPerLine() / 2;
241 const QVector<QRect> rects = region.rects();
242
243 for (int i = 0; i < rects.size(); ++i) {
244 const QRect r = rects.at(i).translated(-topLeft);
245 int y = r.y();
246 const quint16 *s = reinterpret_cast<const quint16*>(image.scanLine(y));
247
248 while (y <= r.bottom()) {
249 int x1 = r.x();
250 while (x1 <= r.right()) {
251 const quint16 c = s[x1];
252 int x2 = x1;
253 // find span length
254 while ((x2+1 < r.right()) && (s[x2+1] == c))
255 ++x2;
256 gl_hline(x1 + topLeft.x(), y + topLeft.y(), x2 + topLeft.x(),
257 qt_colorConvert<quint8, quint16>(c, 0));
258 x1 = x2 + 1;
259 }
260 s += imageStride;
261 ++y;
262 }
263 }
264}
265
266void SvgalibScreen::blit32To8(const QImage &image,
267 const QPoint &topLeft, const QRegion &region)
268{
269 const int imageStride = image.bytesPerLine() / 4;
270 const QVector<QRect> rects = region.rects();
271
272 for (int i = 0; i < rects.size(); ++i) {
273 const QRect r = rects.at(i).translated(-topLeft);
274 int y = r.y();
275 const quint32 *s = reinterpret_cast<const quint32*>(image.scanLine(y));
276
277 while (y <= r.bottom()) {
278 int x1 = r.x();
279 while (x1 <= r.right()) {
280 const quint32 c = s[x1];
281 int x2 = x1;
282 // find span length
283 while ((x2+1 < r.right()) && (s[x2+1] == c))
284 ++x2;
285 gl_hline(x1 + topLeft.x(), y + topLeft.y(), x2 + topLeft.x(),
286 qt_colorConvert<quint8, quint32>(c, 0));
287 x1 = x2 + 1;
288 }
289 s += imageStride;
290 ++y;
291 }
292 }
293}
294
295//! [5]
296void SvgalibScreen::blit(const QImage &img, const QPoint &topLeft,
297 const QRegion &reg)
298{
299 if (depth() == 8) {
300 switch (img.format()) {
301 case QImage::Format_RGB16:
302 blit16To8(img, topLeft, reg);
303 return;
304 case QImage::Format_RGB32:
305 case QImage::Format_ARGB32:
306 case QImage::Format_ARGB32_Premultiplied:
307 blit32To8(img, topLeft, reg);
308 return;
309 default:
310 break;
311 }
312 }
313
314 if (img.format() != pixelFormat()) {
315 if (base())
316 QScreen::blit(img, topLeft, reg);
317 return;
318 }
319
320 const QVector<QRect> rects = (reg & region()).rects();
321
322 for (int i = 0; i < rects.size(); ++i) {
323 const QRect r = rects.at(i);
324 gl_putboxpart(r.x(), r.y(), r.width(), r.height(),
325 img.width(), img.height(),
326 static_cast<void*>(const_cast<uchar*>(img.bits())),
327 r.x() - topLeft.x(), r.y() - topLeft.y());
328 }
329}
330//! [5]
331
332//! [7]
333QWSWindowSurface* SvgalibScreen::createSurface(QWidget *widget) const
334{
335 if (base()) {
336 static int onScreenPaint = -1;
337 if (onScreenPaint == -1)
338 onScreenPaint = qgetenv("QT_ONSCREEN_PAINT").toInt();
339
340 if (onScreenPaint > 0 || widget->testAttribute(Qt::WA_PaintOnScreen))
341 return new SvgalibSurface(widget);
342 }
343 return QScreen::createSurface(widget);
344}
345//! [7]
346
347//! [8]
348QWSWindowSurface* SvgalibScreen::createSurface(const QString &key) const
349{
350 if (key == QLatin1String("svgalib"))
351 return new SvgalibSurface;
352 return QScreen::createSurface(key);
353}
354//! [8]
Note: See TracBrowser for help on using the repository browser.