2
// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
3
// 2011 Free Software Foundation, Inc
2
// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
5
5
// This program is free software; you can redistribute it and/or modify
6
6
// it under the terms of the GNU General Public License as published by
27
27
/// Since there can be multiple input devices in /dev/input/ you have to
28
28
/// specify which device to use using the
29
/// POINTING_DEVICE environment variable for the mouse and
29
// POINTING_DEVICE environment variable for the mouse and
30
30
/// KEYBOARD_DEVICE environment variable for the keyboard
32
32
/// \page fb_calibration FB GUI Touchscreen Calibration
160
161
// GNASH_REPORT_FUNCTION;
162
163
// initializing to zero helps with debugging and prevents weird bugs
163
164
// memset(mouse_buf, 0, 256);
164
memset(&_var_screeninfo, 0, sizeof(fb_var_screeninfo));
165
memset(&_fix_screeninfo, 0, sizeof(fb_fix_screeninfo));
167
165
signal(SIGINT, terminate_signal);
168
166
signal(SIGTERM, terminate_signal);
176
174
enable_terminal();
177
log_debug(_("Closing framebuffer device"));
175
// log_debug("Closing framebuffer device");
181
#ifdef ENABLE_DOUBLE_BUFFERING
183
log_debug(_("Freeing offscreen buffer"));
190
181
FBGui::init(int argc, char *** argv)
192
GNASH_REPORT_FUNCTION;
183
// GNASH_REPORT_FUNCTION;
194
185
// the current renderer as set on the command line or gnashrc file
195
186
std::string renderer = _runResources.getRenderBackend();
232
223
_height = agg->height();
233
224
log_debug("Width:%d, Height:%d", _width, _height);
234
225
_renderer.reset(agg->createRenderHandler());
235
// Renderer_agg_base *rend = reinterpret_cast<Renderer_agg_base *>(_renderer.get());
236
// rend->init(_width, _height);
239
228
if ((renderer != "openvg") && (renderer != "agg")) {
240
log_error("No renderer! %s not supported.", renderer);
229
log_error(_("No renderer! %s not supported."), renderer);
243
232
disable_terminal();
234
// Look for the User Mode Input (Uinput) device, which is used to
235
// control the movement and coordinates of the mouse cursor.
236
if (_uinput.scanForDevice()) {
238
_uinput.moveTo(0, 0);
240
log_error(_("Found no accessible User mode input event device"));
245
243
// Initialize all the input devices
247
245
// Look for Mice that use the PS/2 mouse protocol
248
246
std::vector<boost::shared_ptr<InputDevice> > possibles
249
247
= InputDevice::scanForDevices();
250
248
if (possibles.empty()) {
251
log_error("Found no accessible input event devices");
249
log_error(_("Found no accessible input event devices"));
253
251
log_debug("Found %d input event devices.", possibles.size());
256
254
std::vector<boost::shared_ptr<InputDevice> >::iterator it;
257
255
for (it=possibles.begin(); it!=possibles.end(); ++it) {
256
// Set the screen size, which is used for calculating absolute
257
// mouse locations from relative ones.
258
(*it)->setScreenSize(_width, _height);
260
#if defined(USE_MOUSE_PS2) || defined(USE_MOUSE_ETT)
259
261
if ((*it)->getType() == InputDevice::MOUSE) {
260
log_debug("WARNING: Mouse support disabled as it conflicts with the input event support.");
262
log_debug(_("WARNING: Mouse support may conflict with the input event support."));
261
263
// For now we only want keyboard input events, as the mouse
262
264
// interface default of /dev/input/mice supports hotpluging devices,
263
265
// unlike the regular events.
264
// _inputs.push_back(*it);
266
_inputs.push_back(*it);
266
269
if ((*it)->getType() == InputDevice::KEYBOARD) {
267
270
_inputs.push_back(*it);
270
273
// use that instead of handling the events directly. The
271
274
// Babbage is configured as a tablet when using input events.
272
275
if ((*it)->getType() == InputDevice::TOUCHSCREEN) {
273
log_debug("Enabling Touchscreen support.");
276
log_debug(_("Enabling Touchscreen support."));
274
277
_inputs.push_back(*it);
276
279
if ((*it)->getType() == InputDevice::TABLET) {
278
log_debug("WARNING: Babbage Tablet support disabled as it conflicts with TSlib");
281
log_debug(_("WARNING: Babbage Tablet support disabled as it conflicts with TSlib"));
280
log_debug("Enabling Babbage Touchscreen support");
283
log_debug(_("Enabling Babbage Touchscreen support"));
281
284
_inputs.push_back(*it);
284
287
if ((*it)->getType() == InputDevice::POWERBUTTON) {
288
log_debug(_("Enabling Power Button support"));
285
289
_inputs.push_back(*it);
290
293
// Let -j -k override "window" size
291
294
optind = 0; opterr = 0; char c;
292
295
while ((c = getopt (argc, *argv, "j:k:X:Y:")) != -1) {
321
323
log_debug("X:%d, Y:%d", _xpos, _ypos);
324
326
_validbounds.setTo(0, 0, _width - 1, _height - 1);
332
FBGui::resize_view(int width, int height)
334
GNASH_REPORT_FUNCTION;
336
// _glue.prepDrawingArea(width, height, 0);
337
Gui::resize_view(width, height);
332
GNASH_REPORT_FUNCTION;
345
// GNASH_REPORT_FUNCTION;
335
348
int ts_loop_count;
338
351
VirtualClock& timer = getClock();
340
354
// let the GUI recompute the x/y scale factors to best fit the whole screen
341
355
resize_view(_validbounds.width(), _validbounds.height());
357
float fps = getFPS();
359
// FIXME: this value is arbitrary, and will make any movie with
360
// less than 12 frames eat up more of the cpu. It should probably
361
// be a much lower value, like 2.
363
delay = static_cast<int>(100000/fps);
365
// 10ms per heart beat
368
log_debug(_("Movie Frame Rate is %d, adjusting delay to %dms"), fps,
343
371
// This loops endlessly at the frame rate
344
372
while (!terminate_request) {
345
// wait the "heartbeat" inteval
346
gnashSleep(_interval * 1000);
373
// wait the "heartbeat" inteval. _interval is in milliseconds,
374
// but gnashSleep() wants nanoseconds, so adjust by 1000.
375
gnashSleep(_interval * 1000);
347
376
// TODO: Do we need to check the real time slept or is it OK when we woke
348
377
// up early because of some Linux signal sent to our process (and thus
349
378
// "advance" faster than the "heartbeat" interval)? - Udo
371
400
FBGui::renderBuffer()
373
// GNASH_REPORT_FUNCTION;
375
// if ( _drawbounds.size() == 0 ) return; // nothing to do..
377
#ifdef ENABLE_DOUBLE_BUFFERING
379
// Size of a pixel in bytes
380
// NOTE: +7 to support 15 bpp
381
const unsigned int pixel_size = (var_screeninfo.bits_per_pixel+7)/8;
383
for (unsigned int bno=0; bno < _drawbounds.size(); bno++) {
384
geometry::Range2d<int>& bounds = _drawbounds[bno];
385
assert ( ! bounds.isWorld() );
387
// Size, in bytes, of a row that has to be copied
388
const unsigned int row_size = (bounds.width()+1) * pixel_size;
391
const int minx = bounds.getMinX();
392
const int maxy = bounds.getMaxY();
394
const int minx1 = minx+_xpos;
395
for (int y=bounds.getMinY(), y1=y+_ypos; y<=maxy; ++y, ++y1) {
396
const unsigned int pix_idx_in = y*m_rowsize + minx*pixel_size;
397
const unsigned int pix_idx_out = y1*m_rowsize + minx1*pixel_size;
398
memcpy(&(fbmem[pix_idx_out]), &buffer[pix_idx_in], row_size);
402
// GNASH_REPORT_FUNCTION;
408
408
FBGui::createWindow(const char* /*title*/, int /*width*/, int /*height*/,
409
409
int /*xPosition*/, int /*yPosition*/)
411
GNASH_REPORT_FUNCTION;
411
// GNASH_REPORT_FUNCTION;
413
413
_runResources.setRenderer(_renderer);
417
_glue->prepDrawingArea(0);
449
441
_timeout = timeout;
453
// FBGui::setFullscreen()
455
// // FB GUI always runs fullscreen; ignore...
444
// The Framebuffer GUI usually always runs fullscreen, which is
445
// the default, but occasionally users want to run the SWF movie
446
// it's actual size, or in different locations.
448
FBGui::setFullscreen()
459
// FBGui::unsetFullscreen()
461
// // FB GUI always runs fullscreen; ignore...
454
FBGui::unsetFullscreen()
465
460
FBGui::showMenu(bool /*show*/)
480
FBGui::setInvalidatedRegion(const SWFRect& /* bounds */)
475
FBGui::setInvalidatedRegion(const SWFRect& bounds)
482
// GNASH_REPORT_FUNCTION;
485
FBAggGlue *fbag = reinterpret_cast
486
<FBAggGlue *>(_glue.get());
488
fbag->setInvalidatedRegion(bounds);
477
// GNASH_REPORT_FUNCTION;
479
setInvalidatedRegion(bounds);
493
483
FBGui::setInvalidatedRegions(const InvalidatedRanges& ranges)
495
// GNASH_REPORT_FUNCTION;
485
// GNASH_REPORT_FUNCTION;
498
FBAggGlue *fbag = reinterpret_cast<FBAggGlue *>(_glue.get());
499
fbag->setInvalidatedRegions(ranges);
501
_glue->setInvalidatedRegions(ranges);
487
_glue->setInvalidatedRegions(ranges);
555
log_debug(_("WARNING: Could not detect controlling TTY"));
539
log_error(_("Could not detect controlling TTY"));
560
543
// Detect the currently active virtual terminal (so we can switch back to
563
546
fd = open(tty, O_RDWR);
565
log_debug(_("WARNING: Could not open %s"), tty);
548
log_error(_("Could not open %s"), tty);
569
553
if (ioctl(fd, VT_GETSTATE, &vts) == -1) {
570
log_debug(_("WARNING: Could not get current VT state"));
554
log_error(_("Could not get current VT state"));
575
559
_original_vt = vts.v_active;
576
log_debug(_("Original TTY NO = %d"), _original_vt);
560
// log_debug("Original TTY NO = %d", _original_vt);
578
562
#ifdef REQUEST_NEW_VT
579
563
// Request a new VT number
580
564
if (ioctl(fd, VT_OPENQRY, &_own_vt) == -1) {
581
log_debug(_("WARNING: Could not request a new VT"));
565
log_error(_("Could not request a new VT"));
586
log_debug(_("Own TTY NO = %d"), _own_vt);
570
// log_debug("Own TTY NO = %d", _own_vt);
592
576
// Activate our new VT
593
577
tty = find_accessible_tty(_own_vt);
595
log_debug(_("WARNING: Could not find device for VT number %d"), _own_vt);
579
log_error(_("Could not find device for VT number %d"), _own_vt);
599
583
_fd = open(tty, O_RDWR);
601
log_debug(_("WARNING: Could not open %s"), tty);
585
log_error(_("Could not open %s"), tty);
605
589
if (ioctl(fd, VT_ACTIVATE, _own_vt) == -1) {
606
log_debug(_("WARNING: Could not activate VT number %d"), _own_vt);
590
log_error(_("Could not activate VT number %d"), _own_vt);
611
595
if (ioctl(fd, VT_WAITACTIVE, _own_vt) == -1) {
612
log_debug(_("WARNING: Error waiting for VT %d becoming active"),
596
log_error(_("Error waiting for VT %d becoming active"),
615
599
//return false; don't abort
626
610
// Activate our new VT
627
611
tty = find_accessible_tty(_own_vt);
629
log_debug(_("WARNING: Could not find device for VT number %d"),
613
log_error(_("Could not find device for VT number %d"), _own_vt);
634
617
fd = open(tty, O_RDWR);
636
log_debug(_("WARNING: Could not open %s"), tty);
619
log_error(_("Could not open %s"), tty);
641
624
// Become session leader and attach to terminal
643
626
if (ioctl(fd, TIOCSCTTY, 0) == -1) {
644
log_debug(_("WARNING: Could not attach controlling terminal (%s)"), tty);
627
log_error(_("Could not attach controlling terminal (%s)"), tty);
647
630
#endif // end of if REQUEST_NEW_VT
649
632
// Disable keyboard cursor
651
634
if (ioctl(fd, KDGETMODE, &_original_kd) == -1) {
652
log_debug(_("WARNING: Could not query current keyboard mode on VT"));
635
log_error(_("Could not query current keyboard mode on VT"));
655
638
if (ioctl(fd, KDSETMODE, KD_GRAPHICS) == -1) {
656
log_debug(_("WARNING: Could not switch to graphics mode on new VT"));
639
log_error(_("Could not switch to graphics mode on new VT"));
663
log_debug(_("VT %d ready"), _own_vt);
646
// log_debug("VT %d ready", _own_vt);
665
648
// NOTE: We could also implement virtual console switching by using
666
649
// VT_GETMODE / VT_SETMODE ioctl calls and handling their signals, but
675
658
// GNASH_REPORT_FUNCTION;
677
log_debug(_("Restoring terminal..."));
660
// log_debug("Restoring terminal...");
679
662
char* tty = find_accessible_tty(_own_vt);
681
log_debug(_("WARNING: Could not find device for VT number %d"), _own_vt);
664
log_error(_("Could not find device for VT number %d"), _own_vt);
685
668
int fd = open(tty, O_RDWR);
687
log_debug(_("WARNING: Could not open %s"), tty);
670
log_error(_("Could not open %s"), tty);
691
674
if (ioctl(fd, VT_ACTIVATE, _original_vt)) {
692
log_debug(_("WARNING: Could not activate VT number %d"), _original_vt);
675
log_error(_("Could not activate VT number %d"), _original_vt);
697
680
if (ioctl(fd, VT_WAITACTIVE, _original_vt)) {
698
log_debug(_("WARNING: Error waiting for VT %d becoming active"),
681
log_error(_("Error waiting for VT %d becoming active"),
701
684
//return false; don't abort
724
707
for (it=_inputs.begin(); it!=_inputs.end(); ++it) {
726
709
boost::shared_ptr<InputDevice::input_data_t> ie = (*it)->popData();
711
// notifyMouseMove(ie->x, ie->y);
729
713
std::cerr << "Got data: " << ((ie->pressed) ? "true" : "false");
730
714
std::cerr << ", " << ie->key << ", " << ie->modifier;
731
715
std::cerr << ", " << ie->x << ", " << ie->y << std::endl;
732
716
// cerr << "X = " << coords[0] << endl;
733
717
// cerr << "Y = " << coords[1] << endl;
736
719
// Range check and convert the position from relative to
738
721
boost::shared_array<int> coords =
739
MouseDevice::convertCoordinates(ie->x, ie->y,
740
getStage()->getStageWidth(),
741
getStage()->getStageHeight());
722
InputDevice::convertAbsCoords(ie->x, ie->y,
723
getStage()->getStageWidth(),
724
getStage()->getStageHeight());
742
725
// The mouse was moved
726
_uinput.moveTo(coords[0], coords[1]);
744
728
notifyMouseMove(coords[0], coords[1]);
747
731
// See if a mouse button was clicked
748
732
if (ie->pressed) {
749
733
notifyMouseClick(true);
751
735
double x = 0.655 * ie->x;
752
736
double y = 0.46875 * ie->y;
753
log_debug("Mouse clicked at: %g:%g", x, y);
737
// log_debug("Mouse clicked at: %g:%g", x, y);
754
738
notifyMouseMove(int(x), int(y));
756
740
notifyMouseMove(ie->x, ie->y);