2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "gnashconfig.h"
24 #include "RunResources.h"
26 #include <boost/format.hpp>
33 #include <interface/Font.h>
34 #include <Application.h>
42 #error Haiku gui requires AGG renderer
48 const int32 GNASH_PULSE
= 'GPLS';
49 const int32 GNASH_SEND_PULSE
= 'GSPL';
50 const int32 GNASH_QUITTING
= 'GQUI';
53 class BeWin
: public BWindow
56 BRect _unfullscreen_frame
;
59 BeWin(BRect frame
, const char *title
, HaikuGui
*gui
)
60 : BWindow(frame
, title
, B_TITLED_WINDOW
, 0), _gui(gui
),
67 be_app_messenger
.SendMessage(B_QUIT_REQUESTED
);
68 BWindow::QuitRequested();
72 void FrameResized(float width
, float height
)
74 BMessage
msg(GNASH_RESIZE
);
75 if (msg
.AddFloat("w", width
) != B_OK
76 || msg
.AddFloat("h", height
) != B_OK
)
79 be_app_messenger
.SendMessage(&msg
);
82 void setFullscreenEtc()
85 if (_fullscreen
== true)
91 _unfullscreen_frame
= Frame();
93 ResizeTo(r
.Width(), r
.Height());
96 void ScreenChanged(BRect frame
, color_space mode
)
101 if (_fullscreen
== false)
103 // XXX perform in beapp thread
105 ResizeTo(frame
.Width(), frame
.Height());
108 void unsetFullscreenEtc()
111 if (_fullscreen
== false)
114 MoveTo(_unfullscreen_frame
.left
, _unfullscreen_frame
.top
);
115 ResizeTo(_unfullscreen_frame
.Width(), _unfullscreen_frame
.Height());
121 class BeApp
: public BApplication
125 thread_id _pulse_tid
;
128 int32 _mouse_moves_this_pulse
;
129 int32 _mousemovedx
, _mousemovedy
;
132 : BApplication("application/gnash-player"),
133 _gui(gui
), _win(NULL
),
135 _start_t(time(NULL
)),
137 _mouse_moves_this_pulse(0),
138 _mousemovedx(0), _mousemovedy(0)
140 _pulse_tid
= spawn_thread(SendPulses
, "Pulses", B_NORMAL_PRIORITY
, this);
141 if (_pulse_tid
<= 0) {
142 throw runtime_error(_("spawn_thread failed"));
144 if (B_OK
!= resume_thread(_pulse_tid
)) {
145 throw runtime_error(_("resume_thread failed"));
151 SendPulses(void *data
)
154 static_cast<BeApp
*>(data
);
155 assert(that
!= NULL
);
156 int32 i
= that
->SendPulsesEtc();
158 boost::format
fmt(_("pulses thread returned %d"));
160 log_error(fmt
.str());
169 BMessage
m(GNASH_PULSE
);
175 if (B_OK
!= be_app_messenger
.SendMessage(&m
))
178 unsigned int interval
=
182 // interval in miliseconds, 1000 * interval in microseconds
183 usleep(1000 * interval
);
186 code
= receive_data(&sender
, NULL
, 0);
187 } while (code
== B_INTERRUPTED
);
190 case GNASH_SEND_PULSE
:
201 void setTimeout(time_t timeout
)
208 status_t st
, exit_value
;
210 st
= send_data(_pulse_tid
, GNASH_QUITTING
, NULL
, 0);
211 } while (st
== B_INTERRUPTED
);
213 wait_for_thread(_pulse_tid
, &exit_value
);
218 BApplication::QuitRequested();
224 return _timeout
&& time(NULL
) - _start_t
> _timeout
;
227 void setFullscreenEtc()
229 assert(_win
!= NULL
);
230 static_cast<BeWin
*>(_win
)->setFullscreenEtc();
233 void unsetFullscreenEtc()
235 assert(_win
!= NULL
);
236 static_cast<BeWin
*>(_win
)->unsetFullscreenEtc();
239 void MessageReceived(BMessage
*msg
)
244 if (_mouse_moves_this_pulse
> 3)
245 _gui
->notifyMouseMove(_mousemovedx
, _mousemovedy
);
246 _mouse_moves_this_pulse
= 0;
248 if (B_OK
!= send_data(_pulse_tid
, GNASH_SEND_PULSE
, NULL
, 0)) {
249 log_error(_("send_data failed"));
256 if (msg
->FindFloat("w", &width
) != B_OK
257 || msg
->FindFloat("h", &height
) != B_OK
)
260 _gui
->resize_view(width
+1, height
+1);
273 case GNASH_SET_FULLSCREEN
:
274 _gui
->setFullscreenEtc();
276 case GNASH_UNSET_FULLSCREEN
:
277 _gui
->unsetFullscreenEtc();
279 case GNASH_MOUSE_CLICKED
:
283 if (B_OK
!= msg
->FindBool("pressed", &pressed
)
284 || B_OK
!= msg
->FindInt32("mask", &mask
))
287 _gui
->notifyMouseClick(pressed
);
290 case GNASH_MOUSE_MOVED
:
292 ++ _mouse_moves_this_pulse
;
294 if (B_OK
!= msg
->FindInt32("x", &x
)
295 || B_OK
!= msg
->FindInt32("y", &y
))
299 if (_mouse_moves_this_pulse
> 3)
304 _gui
->notifyMouseMove(x
, y
);
308 case GNASH_KEY_EVENT
:
310 int32 key
, modifiers
;
312 if (B_OK
!= msg
->FindInt32("key", &key
)
313 || B_OK
!= msg
->FindInt32("modifiers", &modifiers
)
314 || B_OK
!= msg
->FindBool("pressed", &pressed
))
317 _gui
->notify_key_event(static_cast<gnash::key::code
>(key
), modifiers
, pressed
);
321 BApplication::MessageReceived(msg
);
331 CreateWindow(int width
, int height
, int xPosition
, int yPosition
,
334 assert(_win
== NULL
);
336 _win
= new BeWin(BRect(xPosition
, yPosition
, xPosition
+width
-1, yPosition
+height
-1),
350 HaikuGui::HaikuGui(unsigned long xid
, float scale
, bool loop
, RunResources
& r
)
351 : Gui(xid
, scale
, loop
, r
), _app(NULL
),
352 _glue(this, xid
), _timeout(0)
357 HaikuGui::~HaikuGui()
359 GNASH_REPORT_FUNCTION
;
365 HaikuGui::init(int argc
, char **argv
[])
368 GNASH_REPORT_FUNCTION
;
369 _app
= new BeApp(this);
372 // log_error (_("Ignoring request to display in X11 window"));
375 int origopterr
= opterr
;
380 while ((c
= getopt(argc
, *argv
, "D:")) != -1) {
382 // Terminate if no filename is given.
385 _("# FATAL: No filename given with -D argument.") << std::endl
;
388 _sharefilename
= optarg
;
395 _glue
.init(argc
, argv
, _app
->GetWinAddr(), _sharefilename
);
397 _renderer
.reset(_glue
.createRenderHandler(32));
398 if ( ! _renderer
) return false;
404 HaikuGui::createWindow(const char *title
, int width
, int height
,
405 int xPosition
, int yPosition
)
407 GNASH_REPORT_FUNCTION
;
408 if (xPosition
== -1 && yPosition
== -1)
420 bool b
= _app
->CreateWindow(width
, height
, xPosition
, yPosition
,
426 _glue
.prepDrawingArea(_width
, _height
, 0/*sdl_flags*/);
428 _runResources
.setRenderer(_renderer
);
436 GNASH_REPORT_FUNCTION
;
438 return ! _app
->Timedout();
442 HaikuGui::renderBuffer()
448 HaikuGui::setInterval(unsigned int interval
)
450 _interval
= interval
;
454 HaikuGui::setTimeout(unsigned int timeout
)
457 _app
->setTimeout((timeout
+999)/1000);
461 HaikuGui::error(const std::string
&msg
)
464 new BAlert("Error", msg
.c_str(), "Dismiss", NULL
, NULL
,
465 B_WIDTH_AS_USUAL
, B_OFFSET_SPACING
, B_STOP_ALERT
);
470 HaikuGui::yesno(const std::string
& question
)
473 new BAlert("yes/no", question
.c_str(), "Yes", "No", NULL
,
474 B_WIDTH_AS_USUAL
, B_EVEN_SPACING
, B_WARNING_ALERT
);
475 int32 answer
= alert
->Go();
480 HaikuGui::setInvalidatedRegions(const InvalidatedRanges
& ranges
)
482 _glue
.setInvalidatedRegions(ranges
);
486 HaikuGui::createMenu()
488 GNASH_REPORT_FUNCTION
;
493 HaikuGui::createMenuBar()
495 GNASH_REPORT_FUNCTION
;
500 HaikuGui::setupEvents()
502 GNASH_REPORT_FUNCTION
;
507 HaikuGui::setFullscreen()
509 BMessage
m(GNASH_SET_FULLSCREEN
);
510 be_app_messenger
.SendMessage(&m
);
514 HaikuGui::setFullscreenEtc()
516 //_glue.BlankScreen();
519 bool b
= _app
->CreateWindow(_width
, _height
, 0, 0,
525 //_glue.prepDrawingArea(_width+5, _height, 0/*sdl_flags*/);
526 //_glue.prepDrawingArea(_width, _height, 0/*sdl_flags*/);
529 _app
->setFullscreenEtc();
533 HaikuGui::unsetFullscreen()
535 BMessage
m(GNASH_UNSET_FULLSCREEN
);
536 be_app_messenger
.SendMessage(&m
);
540 HaikuGui::unsetFullscreenEtc()
542 //_glue.BlankScreen();
543 _app
->unsetFullscreenEtc();
546 (*_app
->GetWinAddr())->LockLooper();
547 (*_app
->GetWinAddr())->Quit();
548 (*_app
->GetWinAddr()) = NULL
;
551 //std::cerr << _width << " " << _height << std::endl;
552 //_glue.prepDrawingArea(_width, _height, 0/*sdl_flags*/);
555 void HaikuGui::GnashPulse()
557 if (_app
->Timedout())
563 Gui::advance_movie(this);
567 HaikuGui::getInterval()
573 HaikuGui::resize_view(int width
, int height
)
575 std::cerr
<< width
<< " " << height
<< std::endl
;
576 _glue
.prepDrawingArea(width
, height
, 0);
577 Gui::resize_view(width
, height
);