Update with current status
[gnash.git] / gui / qt / kde.cpp
blob0a31f7c5213a943ee8fce4d8f13c05819dad986e
1 // kde.cpp: K Development Environment top level window, for Gnash.
2 //
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
4 // 2011 Free Software Foundation, Inc
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifdef HAVE_CONFIG_H
22 #include "gnashconfig.h"
23 #endif
26 #include <qwidget.h>
27 #include <qmessagebox.h>
28 #include <qcursor.h>
29 #ifdef HAVE_KDE3
30 #include <qxembed.h>
31 #endif
32 #include <qnamespace.h>
33 #include <qtimer.h>
34 #include <qcursor.h>
35 #if HAVE_QT3
36 #include <qeventloop.h>
37 #endif
38 #include "Range2d.h"
40 #include "movie_definition.h"
41 #include "log.h"
43 #include "gui.h"
44 #include "kdesup.h"
45 #include "klash3.moc"
46 #include "GnashNumeric.h" // for pixelsToTwips
47 #include "RunResources.h" // for pixelsToTwips
49 using namespace std;
51 namespace gnash
54 KdeGui::~KdeGui()
56 // GNASH_REPORT_FUNCTION;
60 KdeGui::KdeGui(unsigned long xid, float scale, bool loop, RunResources& r)
61 : Gui(xid, scale, loop, r)
65 bool
66 KdeGui::init(int argc, char **argv[])
68 // GNASH_REPORT_FUNCTION;
69 _qapp.reset(new QApplication(argc, *argv));
70 _qwidget.reset(new qwidget(this));
71 #ifdef HAVE_KDE3
72 if (_xid) {
73 QXEmbed::initialize();
74 QXEmbed::embedClientIntoWindow(_qwidget.get(), _xid);
76 #endif
77 _glue.init (argc, argv);
79 return true;
82 bool
83 KdeGui::createWindow(const char* windowtitle, int width, int height,
84 int xPosition, int yPosition)
86 // GNASH_REPORT_FUNCTION;
88 // Move the window to correct position if requested by user.
89 if (xPosition > 1) {
90 if (yPosition > 1) {
91 _qwidget->setGeometry(xPosition, yPosition, width, height);
93 else { // If only given X position by user
94 _qwidget->setGeometry(xPosition, 0, width, height);
97 else if (yPosition > 1) { // If only given Y position by user
98 _qwidget->setGeometry(0, yPosition, width, height);
100 _qwidget->setCaption(windowtitle);
102 _qapp->setMainWidget(_qwidget.get());
103 _qwidget->show();
105 _glue.prepDrawingArea(_qwidget.get());
106 _renderer.reset(_glue.createRenderHandler());
107 if (!_renderer.get())
109 // something went wrong
110 return false;
112 _glue.initBuffer(width, height);
114 _width = width;
115 _height = height;
116 _runResources.setRenderer(_renderer);
118 return true;
121 void
122 KdeGui::renderBuffer()
124 // GNASH_REPORT_FUNCTION;
125 _glue.render();
129 void
130 KdeGui::setInvalidatedRegions(const InvalidatedRanges& ranges)
132 _glue.setInvalidatedRegions(ranges);
135 void
136 KdeGui::setTimeout(unsigned int timeout)
138 // GNASH_REPORT_FUNCTION;
139 QTimer::singleShot(timeout, _qapp.get(), SLOT(quit()));
142 void
143 KdeGui::setInterval(unsigned int interval)
145 // GNASH_REPORT_FUNCTION;
146 _qwidget->setInterval(interval);
149 void
150 KdeGui::setCursor(gnash_cursor_type newcursor)
152 switch(newcursor) {
153 case CURSOR_HAND:
154 #if QT_VERSION > 2312
155 _qwidget->setCursor(Qt::PointingHandCursor);
156 #else
157 _qwidget->setCursor(PointingHandCursor);
158 #endif
159 break;
160 case CURSOR_INPUT:
161 #if QT_VERSION > 2312
162 _qwidget->setCursor(Qt::IbeamCursor);
163 #else
164 _qwidget->setCursor(IbeamCursor);
165 #endif
166 break;
167 default:
168 _qwidget->unsetCursor();
172 bool
173 KdeGui::run()
175 // GNASH_REPORT_FUNCTION;
176 _qapp->exec();
178 return true;
181 bool
182 KdeGui::createMenu()
184 // GNASH_REPORT_FUNCTION;
186 return true;
189 bool
190 KdeGui::setupEvents()
192 // GNASH_REPORT_FUNCTION;
194 return true;
197 gnash::key::code
198 KdeGui::qtToGnashKey(QKeyEvent *event)
201 // Gnash uses its own keycodes to map key events
202 // to the three sometimes weird and confusing values that flash movies
203 // can refer to. See GnashKey.h for the keycodes and map.
205 // Gnash's keycodes are gnash::key::code. They are mainly in ascii order.
206 // Standard ascii characters (32-127) have the same value. Extended ascii
207 // characters (160-254) are in ascii order but correspond to gnash::key::code
208 // 169-263. Non-character values must normally be mapped separately.
210 gnash::key::code c = gnash::key::INVALID;
211 int key = event->key();
213 // Qt seems to treat numbers on the keypad and main keyboard
214 // as the same key event, so needs this check:
215 if (key >= Qt::Key_0 && key <= Qt::Key_9) {
216 if (event->state() & Qt::Keypad)
217 c = (gnash::key::code) ((key - Qt::Key_0) + gnash::key::KP_0);
218 else
219 c = (gnash::key::code) ((key - Qt::Key_0) + gnash::key::_0);
222 // All other characters between ascii 32 and 126 are simple.
223 // From space (32) to slash (47):
224 else if (key >= Qt::Key_Space && key <= Qt::Key_Slash) {
225 c = (gnash::key::code) ((key - Qt::Key_Space) + gnash::key::SPACE);
228 // From colon (58) to tilde (126):
229 else if (key >= Qt::Key_Colon && key <= Qt::Key_AsciiTilde) {
230 c = (gnash::key::code) ((key - Qt::Key_Colon) + gnash::key::COLON);
233 // Function keys:
234 else if (key >= Qt::Key_F1 && key <= Qt::Key_F15) {
235 c = (gnash::key::code) ((key - Qt::Key_F1) + gnash::key::F1);
238 // Extended ascii from non-breaking (160) space to ΓΏ (264) is in the same
239 // order.
240 else if (key >= Qt::Key_nobreakspace && key <= Qt::Key_ydiaeresis) {
241 c = (gnash::key::code) ((key - Qt::Key_nobreakspace) + gnash::key::NOBREAKSPACE);
244 else {
245 // many keys don't correlate, so just use a look-up table.
246 struct {
247 int qt;
248 gnash::key::code gs;
249 } table[] = {
250 { Qt::Key_Backspace, gnash::key::BACKSPACE },
251 { Qt::Key_Tab, gnash::key::TAB },
252 #if QT_VERSION > 2312
253 { Qt::Key_Clear, gnash::key::CLEAR },
254 #endif
255 { Qt::Key_Return, gnash::key::ENTER },
256 { Qt::Key_Enter, gnash::key::ENTER },
258 { Qt::Key_Shift, gnash::key::SHIFT },
259 { Qt::Key_Control, gnash::key::CONTROL },
260 { Qt::Key_Alt, gnash::key::ALT },
261 { Qt::Key_CapsLock, gnash::key::CAPSLOCK },
263 { Qt::Key_Escape, gnash::key::ESCAPE },
264 //{ Qt::Key_Space, gnash::key::SPACE },
266 { Qt::Key_Next, gnash::key::PGDN },
267 { Qt::Key_Prior, gnash::key::PGUP },
268 { Qt::Key_Home, gnash::key::HOME },
269 { Qt::Key_End, gnash::key::END },
270 { Qt::Key_Left, gnash::key::LEFT },
271 { Qt::Key_Up, gnash::key::UP },
272 { Qt::Key_Right, gnash::key::RIGHT },
273 { Qt::Key_Down, gnash::key::DOWN },
274 { Qt::Key_Insert, gnash::key::INSERT },
275 { Qt::Key_Delete, gnash::key::DELETEKEY },
277 { Qt::Key_Help, gnash::key::HELP },
278 { Qt::Key_NumLock, gnash::key::NUM_LOCK },
279 //{ Qt::Key_Semicolon, gnash::key::SEMICOLON },
280 //{ Qt::Key_Equal, gnash::key::EQUALS },
281 //{ Qt::Key_Minus, gnash::key::MINUS },
282 //{ Qt::Key_Slash, gnash::key::SLASH },
283 //{ Qt::Key_BracketLeft, gnash::key::LEFT_BRACKET },
284 //{ Qt::Key_Backslash, gnash::key::BACKSLASH },
285 //{ Qt::Key_BracketRight, gnash::key::RIGHT_BRACKET },
286 //{ Qt::Key_QuoteDbl, gnash::key::DOUBLE_QUOTE },
287 { 0, gnash::key::INVALID }
290 for (int i = 0; table[i].qt != 0; i++) {
291 if (key == table[i].qt) {
292 c = table[i].gs;
293 break;
298 return c;
302 KdeGui::qtToGnashModifier(Qt::ButtonState state)
304 int modifier = gnash::key::GNASH_MOD_NONE;
306 if (state & Qt::ShiftButton) {
307 modifier = modifier | gnash::key::GNASH_MOD_SHIFT;
309 if (state & Qt::ControlButton) {
310 modifier = modifier | gnash::key::GNASH_MOD_CONTROL;
312 if (state & Qt::AltButton) {
313 modifier = modifier | gnash::key::GNASH_MOD_ALT;
316 return modifier;
319 void
320 KdeGui::handleKeyEvent(QKeyEvent *event, bool down)
322 gnash::key::code c = qtToGnashKey(event);
323 int mod = qtToGnashModifier(event->state());
324 notify_key_event(c, mod, down);
327 void
328 KdeGui::resize(int width, int height)
330 _glue.resize(width, height);
331 resize_view(width, height);
334 void
335 KdeGui::quitUI()
337 #if 1
338 _qapp->exit();
339 #else // dunno what this wanted to achive
340 #if QT_VERSION > 2312
341 _qapp->eventLoop()->exit();
342 #endif
343 #endif
347 /// \brief restart the movie from the beginning
348 void
349 qwidget::menuitem_restart_callback()
351 // GNASH_REPORT_FUNCTION;
352 _godfather->restart();
355 /// \brief force redraw of current frame
356 void
357 qwidget::menuitem_refresh_callback()
359 // GNASH_REPORT_FUNCTION;
360 _godfather->refreshView();
363 /// \brief quit complete, and close the application
364 void
365 qwidget::menuitem_quit_callback()
367 // GNASH_REPORT_FUNCTION;
368 _godfather->quit();
371 /// \brief Start the movie playing from the current frame.
372 void
373 qwidget::menuitem_play_callback()
375 // GNASH_REPORT_FUNCTION;
376 _godfather->play();
379 /// \brief toggle that's playing or paused.
380 void
381 qwidget::menuitem_pause_callback()
383 // GNASH_REPORT_FUNCTION;
384 _godfather->pause();
387 /// \brief stop the movie that's playing.
388 void
389 qwidget::menuitem_stop_callback()
391 // GNASH_REPORT_FUNCTION;
392 _godfather->stop();
396 // Event handlers
401 void
402 qwidget::mouseMoveEvent(QMouseEvent *event)
404 // GNASH_REPORT_FUNCTION;
405 assert(_godfather);
406 QPoint position = event->pos();
408 _godfather->notifyMouseMove(position.x(), position.y());
411 qwidget::qwidget(KdeGui* godfather)
413 _qmenu.insertItem(_("Play Movie"), this, SLOT(menuitem_play_callback()));
414 _qmenu.insertItem(_("Pause Movie"), this, SLOT(menuitem_pause_callback()));
415 _qmenu.insertItem(_("Stop Movie"), this, SLOT(menuitem_stop_callback()));
416 _qmenu.insertItem(_("Restart Movie"), this, SLOT(menuitem_restart_callback()));
417 #if 0 // Presently disabled
418 _qmenu.insertItem(_("Step Forward"), this, SLOT(menuitem_step_forward_callback()));
419 _qmenu.insertItem(_("Step Backward"), this, SLOT( menuitem_step_backward_callback()));
420 _qmenu.insertItem(_("Jump Forward"), this, SLOT(menuitem_jump_forward_callback()));
421 _qmenu.insertItem(_("Jump Backward"), this, SLOT(menuitem_jump_backward_callback()));
422 #endif
423 _qmenu.insertItem(_("Refresh"), this, SLOT(menuitem_refresh_callback()));
424 _qmenu.insertItem(_("Quit Gnash"), this, SLOT(menuitem_quit_callback()));
426 _godfather = godfather;
428 setMouseTracking(true);
429 setFocusPolicy(QWidget::StrongFocus);
432 void
433 qwidget::setInterval(unsigned int interval)
435 startTimer(interval);
439 void
440 qwidget::timerEvent(QTimerEvent *)
442 Gui::advance_movie(_godfather);
445 #if QT_VERSION > 2312
446 void
447 qwidget::contextMenuEvent(QContextMenuEvent*)
449 _qmenu.exec(QCursor::pos());
451 #endif
453 void
454 qwidget::mousePressEvent(QMouseEvent* event)
456 if(Qt::LeftButton & event->button())
457 _godfather->notifyMouseClick(true);
460 void
461 qwidget::mouseReleaseEvent(QMouseEvent* /* event */)
463 _godfather->notifyMouseClick(false);
466 void
467 qwidget::keyPressEvent(QKeyEvent *event)
469 _godfather->handleKeyEvent(event, true);
472 void
473 qwidget::keyReleaseEvent(QKeyEvent *event)
475 _godfather->handleKeyEvent(event, false);
478 void
479 qwidget::resizeEvent(QResizeEvent *event)
481 _godfather->resize(event->size().width(), event->size().height());
484 void
485 qwidget::paintEvent(QPaintEvent *event)
487 const QRegion& region = event->region();
488 QRect rect = region.boundingRect();
490 int xmin = static_cast<int> (pixelsToTwips(rect.x()-1)),
491 ymin = static_cast<int> (pixelsToTwips(rect.y()-1)),
492 xmax = static_cast<int> (pixelsToTwips(rect.right()+1)),
493 ymax = static_cast<int> (pixelsToTwips(rect.bottom()+1));
495 geometry::Range2d<int> range(xmin, ymin, xmax, ymax);
496 InvalidatedRanges ranges;
497 ranges.add(range);
500 _godfather->setInvalidatedRegions(ranges);
501 _godfather->renderBuffer();
504 // end of namespace gnash