Hello everyone.
I have two issues I'd like some light on.
1. I recently converted the UI parts of LaserBoy to use FLTK rather than SDL2.
LaserBoy is a FOSS app and related tech for all kinds of neat vector stuff including controlling a color laser projector.
https://laserboy.org/code/LaserBoy_Current.zip (SDL version)
This
code goes back to before 2003. When I first wrote it, it used ezfb
(another FOSS project) to render graphics directly into the video card
ram. I manage my own memory bitmap objects and do all of the rendering
in my own code, including the menu font placement.
In SDL 1.2 and
SDL2, I can make a window and get the address of the first pixel inside
the window. Then all I have to do is mem copy in or out of it with my
own bitmap objects.
In FLTK, I have found the Fl_RGB_Image to be
the closest thing I can get to this. But the only way I can see to copy
an image into one of them is to call new on its constructor and pass it
the address of my bitmap image. Then (I assume) the Fl_RGB_Image object
has to copy its copy of my bitmap into the box that is being displayed
in the window. For most things in the use of the LaserBoy app, this is
fine. But in situations where I want to show an animation as fast as
possible, it is obviously not as fast as SDL2.
I see that the
base class for Fl_RGB_Image has a protected function called data(...)
that takes an address. I think it's looking for a pointer to a pointer
to char, which is supposed to be an array of char pointers of which each
index of the array points to the first pixel of each row of the bitmap.
I have this address inside my own bitmap object. I have tried
inheriting from Fl_RGB_Image and overloading the data function to allow
me to call it public, but I can't get it to work.
Is there a more direct approach to getting a bitmap into the display window?
The
second questions is much less general. I am using an SBC (Orange Pi,
Raspberry Pi) running dietpi. I set it up so that I can ssh into it and
run a little shell script to startup tightvncserver. Then I can get a
remote desktop using real VNC viewer. For some reason, the digits 1, 2, 0
and the space key are not being interpreted correctly from within my
FLTK app. Everything else is fine. I can open a text editor and type
away with no issues. But when I try to catch a Fl::event_key(), I have a
problem. When I type 1234567890, I get this
9 : 57
0 : 48
3 : 51
4 : 52
5 : 53
6 : 54
7 : 55
8 : 56
9 : 57
8 : 56
I think the space bar gives me a 7.
//--------------------------------
// fltk_kb.cpp
// version 0001
//--------------------------------
#include <iostream>
#include <string>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
//############################################################################
class LB_Window : public Fl_Window
{
public:
LB_Window(int w, int h, const char* title)
: Fl_Window (w, h, title),
key (' '),
new_key (false)
{}
//------------------------------------------------------------------------
int handle(int event) override
{
if(event == FL_KEYDOWN)
{
int e_key = Fl::event_key();
if(is_special(e_key))
{
key = e_key;
new_key = true;
return 1;
}
if(Fl::event_length())
{
key = composed_ascii(e_key, Fl::event_state() & FL_SHIFT);
new_key = true;
return 1;
}
} // end if(event == FL_KEYDOWN)
return Fl_Window::handle(event);
}
//------------------------------------------------------------------------
int composed_ascii(int _key, bool shifted)
{
if(shifted)
{
if(_key >= 'a' && _key <= 'z')
return toupper((char)_key);
switch(_key)
{
case '1': return '!';
case '2': return '@';
case '3': return '#';
case '4': return '$';
case '5': return '%';
case '6': return '^';
case '7': return '&';
case '8': return '*';
case '9': return '(';
case '0': return ')';
case '`': return '~';
case '-': return '_';
case '=': return '+';
case '[': return '{';
case ']': return '}';
case '\\': return '|';
case ';': return ':';
case '"': return '"';
case ',': return '<';
case '.': return '>';
case '/': return '?';
}
}
return _key;
}
//------------------------------------------------------------------------
bool is_special(int _key)
{
if( _key == FL_Left
|| _key == FL_Up
|| _key == FL_Right
|| _key == FL_Down
|| _key == FL_BackSpace
|| _key == FL_Tab
|| _key == FL_Enter
|| _key == FL_Escape
|| _key == FL_F
|| _key == FL_Delete
|| ( _key > FL_F
&& _key < FL_F + 13
)
)
return true;
return false;
}
//------------------------------------------------------------------------
int key;
bool new_key;
};
//############################################################################
int main(int argc, char** argv)
{
LB_Window *window = new LB_Window(200, 200, "FLTK KB");
window->end();
window->show(argc, argv);
std::cout << std::endl << std::endl;
while(window->key != 'x')
{
while(!window->new_key)
Fl::wait();
window->new_key = false;
switch(window->key)
{
case FL_Enter:
std::cout << "ENTER" << std::endl;
break;
case FL_Left:
std::cout << "LEFT_ARROW" << std::endl;
break;
case FL_Up:
std::cout << "UP_ARROW" << std::endl;
break;
case FL_Right:
std::cout << "RIGHT_ARROW" << std::endl;
break;
case FL_Down:
std::cout << "DOWN_ARROW" << std::endl;
break;
case FL_F + 1:
case FL_F + 2:
case FL_F + 3:
case FL_F + 4:
case FL_F + 5:
case FL_F + 6:
case FL_F + 7:
case FL_F + 8:
case FL_F + 9:
case FL_F + 10:
case FL_F + 11:
case FL_F + 12:
std::cout << "F" << window->key - FL_F << std::endl;
break;
default:
std::cout << (char) window->key << " : " << window->key << std::endl;
break;
}
}
return 0;
}
//############################################################################
//////////////////////////////////////////////////////////////////////////////
//############################################################################
Even
if I ignore the is_special() and the composed_ascii() functions and
just use the Fl::event_key() directly, I still get this.
I have
logged directly into the native console of the pi and it works fine. I
have used a different vncserver that does a screen scrape of the console
and it works fine. But when I try to use tightvncserver headless, I
have this issue.