Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
UppHub
Status & Roadmap
FAQ
Authors & License
Forums
Funding U++
Search on this site











SourceForge.net Logo

SourceForge.net Logo

GitHub Logo

Discord Logo

LinuxFb

 

 

 

 

Local.h

 

#ifdef PLATFORM_POSIX

 

void FBInit(const String& fbdevice);

void FBDeInit();

 

#define GUI_APP_MAIN \

void GuiMainFn_();\

\

int main(int argc, const char **argv, const char **envptr) { \

    UPP::AppInit__(argc, argv, envptr); \

    FBInit("/dev/fb0"); \

    GuiMainFn_(); \

    UPP::Ctrl::CloseTopCtrls(); \

    FBDeInit(); \

    return UPP::GetExitCode(); \

} \

\

void GuiMainFn_()

 

#endif

 

 

 

 

vgakeyboard.h

 

/* Keyboard interface for svgalib. */

/* Can be used independently. */

 

#ifndef VGAKEYBOARD_H

#define VGAKEYBOARD_H

 

#ifdef __cplusplus

extern "C"

{

#endif

 

#define SCANCODE_ESCAPE            1

 

#define SCANCODE_1            2

#define SCANCODE_2            3

#define SCANCODE_3            4

#define SCANCODE_4            5

#define SCANCODE_5            6

#define SCANCODE_6            7

#define SCANCODE_7            8

#define SCANCODE_8            9

#define SCANCODE_9            10

#define SCANCODE_0            11

 

#define SCANCODE_MINUS            12

#define SCANCODE_EQUAL            13

 

#define SCANCODE_BACKSPACE        14

#define SCANCODE_TAB            15

 

#define SCANCODE_Q            16

#define SCANCODE_W            17

#define SCANCODE_E            18

#define SCANCODE_R            19

#define SCANCODE_T            20

#define SCANCODE_Y            21

#define SCANCODE_U            22

#define SCANCODE_I            23

#define SCANCODE_O            24

#define SCANCODE_P            25

#define SCANCODE_BRACKET_LEFT        26

#define SCANCODE_BRACKET_RIGHT        27

 

#define SCANCODE_ENTER            28

 

#define SCANCODE_LEFTCONTROL        29

 

#define SCANCODE_A            30

#define SCANCODE_S            31

#define SCANCODE_D            32

#define SCANCODE_F            33

#define SCANCODE_G            34

#define SCANCODE_H            35

#define SCANCODE_J            36

#define SCANCODE_K            37

#define SCANCODE_L            38

#define SCANCODE_SEMICOLON        39

#define SCANCODE_APOSTROPHE        40

#define SCANCODE_GRAVE            41

 

#define SCANCODE_LEFTSHIFT        42

#define SCANCODE_BACKSLASH        43

 

#define SCANCODE_Z            44

#define SCANCODE_X            45

#define SCANCODE_C            46

#define SCANCODE_V            47

#define SCANCODE_B            48

#define SCANCODE_N            49

#define SCANCODE_M            50

#define SCANCODE_COMMA            51

#define SCANCODE_PERIOD            52

#define SCANCODE_SLASH            53

 

#define SCANCODE_RIGHTSHIFT        54

#define SCANCODE_KEYPADMULTIPLY        55

 

#define SCANCODE_LEFTALT        56

#define SCANCODE_SPACE            57

#define SCANCODE_CAPSLOCK        58

 

#define SCANCODE_F1            59

#define SCANCODE_F2            60

#define SCANCODE_F3            61

#define SCANCODE_F4            62

#define SCANCODE_F5            63

#define SCANCODE_F6            64

#define SCANCODE_F7            65

#define SCANCODE_F8            66

#define SCANCODE_F9            67

#define SCANCODE_F10            68

 

#define SCANCODE_NUMLOCK        69

#define SCANCODE_SCROLLLOCK        70

 

#define SCANCODE_KEYPAD7        71

#define SCANCODE_CURSORUPLEFT        71

#define SCANCODE_KEYPAD8        72

#define SCANCODE_CURSORUP        72

#define SCANCODE_KEYPAD9        73

#define SCANCODE_CURSORUPRIGHT        73

#define SCANCODE_KEYPADMINUS        74

#define SCANCODE_KEYPAD4        75

#define SCANCODE_CURSORLEFT        75

#define SCANCODE_KEYPAD5        76

#define SCANCODE_KEYPAD6        77

#define SCANCODE_CURSORRIGHT        77

#define SCANCODE_KEYPADPLUS        78

#define SCANCODE_KEYPAD1        79

#define SCANCODE_CURSORDOWNLEFT        79

#define SCANCODE_KEYPAD2        80

#define SCANCODE_CURSORDOWN        80

#define SCANCODE_KEYPAD3        81

#define SCANCODE_CURSORDOWNRIGHT    81

#define SCANCODE_KEYPAD0        82

#define SCANCODE_KEYPADPERIOD        83

 

#define SCANCODE_LESS            86

 

#define SCANCODE_F11            87

#define SCANCODE_F12            88

 

#define SCANCODE_KEYPADENTER        96

#define SCANCODE_RIGHTCONTROL        97

#define SCANCODE_CONTROL        97

#define SCANCODE_KEYPADDIVIDE        98

#define SCANCODE_PRINTSCREEN        99

#define SCANCODE_RIGHTALT        100

#define SCANCODE_BREAK            101    /* Beware: is 119     */

#define SCANCODE_BREAK_ALTERNATIVE    119    /* on some keyboards! */

 

#define SCANCODE_HOME            102

#define SCANCODE_CURSORBLOCKUP        103    /* Cursor key block */

#define SCANCODE_PAGEUP            104

#define SCANCODE_CURSORBLOCKLEFT    105    /* Cursor key block */

#define SCANCODE_CURSORBLOCKRIGHT    106    /* Cursor key block */

#define SCANCODE_END            107

#define SCANCODE_CURSORBLOCKDOWN    108    /* Cursor key block */

#define SCANCODE_PAGEDOWN        109

#define SCANCODE_INSERT            110

#define SCANCODE_REMOVE            111

 

#define SCANCODE_RIGHTWIN        126

#define SCANCODE_LEFTWIN        125

 

#define KEY_EVENTRELEASE 0

#define KEY_EVENTPRESS 1

 

#define MAX_KEYNAME_LEN 20

 

/* Initialize keyboard handler (brings keyboard into RAW mode). Returns */

/* 0 if succesful, -1 otherwise. */

   int keyboard_init(void);

/* Similar, but returns console fd if succesful. */

   int keyboard_init_return_fd(void);

/* Set event handler invoked by keyboard_update(). */

   typedef void (*__keyboard_handler) (int scancode, int press);

   void keyboard_seteventhandler(__keyboard_handler handler);

/* Return keyboard to normal state. */

   void keyboard_close(void);

/* Read raw keyboard device and handle events. Returns 0 if no event. */

   int keyboard_update(void);

/* Similar to keyboard_update, but wait for an event to happen. */

/* [This doesn't seem to work very well -- use select on fd] */

   void keyboard_waitforupdate(void);

 

/* keyboard_init sets default event handler that keeps track of complete */

/* keyboard state: */

 

/* Result of keypressed. */

#define KEY_NOTPRESSED 0

#define KEY_PRESSED 1

 

/* Modes for translatekeys. */

#define TRANSLATE_CURSORKEYS 1    /* Map cursor block to keypad cursor. */

#define TRANSLATE_DIAGONAL 2    /* Map keypad diagonal to keypad cursor. */

#define TRANSLATE_KEYPADENTER 4    /* Map keypad enter to main enter key. */

#define DONT_CATCH_CTRLC 8    /* Disable Crtl-C check. */

 

/* Revert to default handler. */

   void keyboard_setdefaulteventhandler(void);

/* Return pointer to buffer holding state of each key (scancode). */

/* Value 1 corresponds to key that is pressed, 0 means not pressed. */

   char *keyboard_getstate(void);

/* Force keyboard state to nothing pressed (all zeroes). */

   void keyboard_clearstate(void);

/* Let default handler translate cursor key block events to numeric keypad */

/* cursor key events and other translations. */

   void keyboard_translatekeys(int mask);

 

/* Return nonzero if key is depressed. */

   int keyboard_keypressed(int scancode);

 

#ifdef __cplusplus

}

 

#endif

#endif

 

 

 

LinuxFbLocal.h

 

#ifndef _LinuxFb_LinuxFbLocal_h

#define _LinuxFb_LinuxFbLocal_h

 

#include <CtrlCore/CtrlCore.h>

 

#include <unistd.h>

#include <stdio.h>

#include <fcntl.h>

#include <linux/fb.h>

#include <sys/mman.h>

#include <sys/ioctl.h>

 

#include <sys/types.h>

#include <termios.h>

 

#include <linux/vt.h>

#include <linux/kd.h>

//conflicts with upp

//#include <linux/keyboard.h>

 

NAMESPACE_UPP

 

//video

extern int fbfd;

extern struct fb_var_screeninfo vinfo;

extern struct fb_fix_screeninfo finfo;

extern long int screensize;

extern char *fbp;

 

//mouse

extern int mouse_fd;

extern bool mouse_imps2;

extern Point mousep;

extern dword mouseb;

 

//keyb

extern int keyb_fd;

extern int cvt;

extern dword modkeys;

 

int has_imps2(int fd);

int set_imps2(int fd, int b);

void dupkmap(int fd);

 

void handle_mouse();

void handle_keyboard();

void switchvt(int ii);

 

void SaveModKeys(dword keycode, dword pressed);

dword fbKEYtoK(dword keycode);

dword TranslateUnicode(dword keycode);

 

END_UPP_NAMESPACE

 

#endif

 

 

 

 

Keys.h

 

#ifndef _LinuxFb_Keys_h_

#define _LinuxFb_Keys_h_

 

//translation of linux keycodes from MEDIUMRAM to ultimate

//thanks goes to svgalib

 

K_BACK       = SCANCODE_BACKSPACE + K_DELTA,

K_BACKSPACE  = SCANCODE_BACKSPACE + K_DELTA,

 

//handled extra in fbKEYtoK

K_TAB        = 9, //SCANCODE_TAB

 

K_SPACE      = 32, //SCANCODE_SPACE

 

K_RETURN     = 13, //SCANCODE_ENTER

K_ENTER      = K_RETURN,

 

K_SHIFT_KEY  = SCANCODE_LEFTSHIFT + K_DELTA,

K_CTRL_KEY   = SCANCODE_LEFTCONTROL + K_DELTA,

K_ALT_KEY    = SCANCODE_LEFTALT + K_DELTA,

K_CAPSLOCK   = SCANCODE_CAPSLOCK + K_DELTA,

K_ESCAPE     = SCANCODE_ESCAPE + K_DELTA,

K_PRIOR      = SCANCODE_PAGEUP + K_DELTA,

K_PAGEUP     = SCANCODE_PAGEUP + K_DELTA,

K_NEXT       = SCANCODE_PAGEDOWN + K_DELTA,

K_PAGEDOWN   = SCANCODE_PAGEDOWN + K_DELTA,

K_END        = SCANCODE_END + K_DELTA,

K_HOME       = SCANCODE_HOME + K_DELTA,

K_LEFT       = SCANCODE_CURSORBLOCKLEFT + K_DELTA,

K_UP         = SCANCODE_CURSORBLOCKUP + K_DELTA,

K_RIGHT      = SCANCODE_CURSORBLOCKRIGHT + K_DELTA,

K_DOWN       = SCANCODE_CURSORBLOCKDOWN + K_DELTA,

K_INSERT     = SCANCODE_INSERT + K_DELTA,

K_DELETE     = SCANCODE_REMOVE + K_DELTA,

 

K_NUMPAD0    = SCANCODE_KEYPAD0 + K_DELTA,

K_NUMPAD1    = SCANCODE_KEYPAD1 + K_DELTA,

K_NUMPAD2    = SCANCODE_KEYPAD2 + K_DELTA,

K_NUMPAD3    = SCANCODE_KEYPAD3 + K_DELTA,

K_NUMPAD4    = SCANCODE_KEYPAD4 + K_DELTA,

K_NUMPAD5    = SCANCODE_KEYPAD5 + K_DELTA,

K_NUMPAD6    = SCANCODE_KEYPAD6 + K_DELTA,

K_NUMPAD7    = SCANCODE_KEYPAD7 + K_DELTA,

K_NUMPAD8    = SCANCODE_KEYPAD8 + K_DELTA,

K_NUMPAD9    = SCANCODE_KEYPAD9 + K_DELTA,

K_MULTIPLY   = SCANCODE_KEYPADMULTIPLY + K_DELTA,

K_ADD        = SCANCODE_KEYPADPLUS + K_DELTA,

K_SEPARATOR  = SCANCODE_KEYPADPERIOD + K_DELTA,

K_SUBTRACT   = SCANCODE_KEYPADMINUS + K_DELTA,

K_DECIMAL    = SCANCODE_KEYPADPERIOD + K_DELTA,

K_DIVIDE     = SCANCODE_KEYPADDIVIDE + K_DELTA,

K_SCROLL     = SCANCODE_SCROLLLOCK + K_DELTA,

 

K_F1         = SCANCODE_F1 + K_DELTA,

K_F2         = SCANCODE_F2 + K_DELTA,

K_F3         = SCANCODE_F3 + K_DELTA,

K_F4         = SCANCODE_F4 + K_DELTA,

K_F5         = SCANCODE_F5 + K_DELTA,

K_F6         = SCANCODE_F6 + K_DELTA,

K_F7         = SCANCODE_F7 + K_DELTA,

K_F8         = SCANCODE_F8 + K_DELTA,

K_F9         = SCANCODE_F9 + K_DELTA,

K_F10        = SCANCODE_F10 + K_DELTA,

K_F11        = SCANCODE_F11 + K_DELTA,

K_F12        = SCANCODE_F12 + K_DELTA,

 

K_A          = SCANCODE_A + K_DELTA,

K_B          = SCANCODE_B + K_DELTA,

K_C          = SCANCODE_C + K_DELTA,

K_D          = SCANCODE_D + K_DELTA,

K_E          = SCANCODE_E + K_DELTA,

K_F          = SCANCODE_F + K_DELTA,

K_G          = SCANCODE_G + K_DELTA,

K_H          = SCANCODE_H + K_DELTA,

K_I          = SCANCODE_I + K_DELTA,

K_J          = SCANCODE_J + K_DELTA,

K_K          = SCANCODE_K + K_DELTA,

K_L          = SCANCODE_L + K_DELTA,

K_M          = SCANCODE_M + K_DELTA,

K_N          = SCANCODE_N + K_DELTA,

K_O          = SCANCODE_O + K_DELTA,

K_P          = SCANCODE_P + K_DELTA,

K_Q          = SCANCODE_Q + K_DELTA,

K_R          = SCANCODE_R + K_DELTA,

K_S          = SCANCODE_S + K_DELTA,

K_T          = SCANCODE_T + K_DELTA,

K_U          = SCANCODE_U + K_DELTA,

K_V          = SCANCODE_V + K_DELTA,

K_W          = SCANCODE_W + K_DELTA,

K_X          = SCANCODE_X + K_DELTA,

K_Y          = SCANCODE_Y + K_DELTA,

K_Z          = SCANCODE_Z + K_DELTA,

K_0          = SCANCODE_0 + K_DELTA,

K_1          = SCANCODE_1 + K_DELTA,

K_2          = SCANCODE_2 + K_DELTA,

K_3          = SCANCODE_3 + K_DELTA,

K_4          = SCANCODE_4 + K_DELTA,

K_5          = SCANCODE_5 + K_DELTA,

K_6          = SCANCODE_6 + K_DELTA,

K_7          = SCANCODE_7 + K_DELTA,

K_8          = SCANCODE_8 + K_DELTA,

K_9          = SCANCODE_9 + K_DELTA,

 

K_CTRL_LBRACKET  = K_CTRL|219|K_DELTA,

K_CTRL_RBRACKET  = K_CTRL|221|K_DELTA,

K_CTRL_MINUS     = K_CTRL|0xbd|K_DELTA,

K_CTRL_GRAVE     = K_CTRL|0xc0|K_DELTA,

K_CTRL_SLASH     = K_CTRL|0xbf|K_DELTA,

K_CTRL_BACKSLASH = K_CTRL|0xdc|K_DELTA,

K_CTRL_COMMA     = K_CTRL|0xbc|K_DELTA,

K_CTRL_PERIOD    = K_CTRL|0xbe|K_DELTA,

K_CTRL_SEMICOLON = K_CTRL|0xbe|K_DELTA,

K_CTRL_EQUAL     = K_CTRL|0xbb|K_DELTA,

K_CTRL_APOSTROPHE= K_CTRL|0xde|K_DELTA,

 

K_BREAK      = SCANCODE_BREAK + K_DELTA, //SCANCODE_BREAK_ALTERNATIVE

 

#endif

 

 

 

LinuxFb.h

 

#ifndef _LinuxFb_LinuxFb_h_

#define _LinuxFb_LinuxFb_h_

 

#include <Framebuffer/Framebuffer.h>

 

#include <CtrlCore/stdids.h>

 

//used with thanks from svgalib

#include "vgakeyboard.h"

 

#endif

 

 

 

 

Proc.cpp

 

#include "LinuxFbLocal.h"

 

NAMESPACE_UPP

 

#define LLOG(x)       //LOG(x)

 

bool GetMouseLeft()   { return mouseb & (1<<0); }

bool GetMouseRight()  { return mouseb & (1<<1); }

bool GetMouseMiddle() { return mouseb & (1<<2); }

 

void purgefd(int fd)

{

    fd_set fdset;

    struct timeval tv;

    char temp[64];

 

    FD_ZERO(&fdset);

    FD_SET(fd, &fdset);

    tv.tv_sec = 0;

    tv.tv_usec = 0;

    while(select(fd+1, &fdset, 0, 0, &tv) > 0)

        read(fd, temp, sizeof(temp));

}

 

int set_imps2(int fd, int b)

{

    uint8 set[] = {0xf3, 200, 0xf3, 100, 0xf3, 80};

    uint8 reset[] = {0xff};

    int retval = 0;

 

    if(b && write(fd, &set, sizeof(set)) != sizeof(set))

        return 0;

    //SDL says not to reset, some mice wont work with it

    if(!b && write(fd, &reset, sizeof (reset)) != sizeof(reset))

        return 0;

 

    purgefd(fd);

    return 1;

}

 

int has_imps2(int fd)

{

    uint8 query = 0xF2;

    purgefd(fd);

    if(write(fd, &query, sizeof (query)) != sizeof(query))

        return 0;

 

    uint8 ch = 0;

    fd_set fdset;

    struct timeval tv;

    while(1) {

        FD_ZERO(&fdset);

        FD_SET(fd, &fdset);

        tv.tv_sec = 1;

        tv.tv_usec = 0;

        if(select(fd+1, &fdset, 0, 0, &tv) < 1) break;

        if(read(fd, &ch, sizeof(ch)) != sizeof(ch)) break;

        switch(ch) {

            case 0xFA:

            case 0xAA: continue;

            case 3:

            case 4: return 1;

            default: return 0;            

        }

    }

    return 0;

}

 

dword lastbdowntime[8] = {0};

dword isdblclick[8] = {0};

 

void handle_button(dword ct, dword mouseb, dword bm, int i,

    dword df, dword rf, dword dbf, dword uf)

{

    dword m = (1<<i);

    if(bm & m)

    {

        if(mouseb & m) //down

        {

            if(isdblclick[i] && (abs(int(ct) - int(lastbdowntime[i])) < 400))

            {

                Ctrl::DoMouseFB(dbf, mousep);

                isdblclick[i] = 0; //reset, to go ahead sending repeats

            }

            else if(!isdblclick[i])

            {

                //Ctrl::DoMouseFB(rf, mousep);

            }

            else

            {

                lastbdowntime[i] = ct;

                isdblclick[i] = 0; //prepare for repeat

                Ctrl::DoMouseFB(df, mousep);

            }

        }

        else //up

        {

            isdblclick[i] = 1; //indicate maybe a dblclick

            Ctrl::DoMouseFB(uf, mousep);

        }

    }

}

 

void handle_mouse()

{

    static int offs = 0;

    static unsigned char buf[BUFSIZ];

    static int rel = 1;

 

    int i, n;

    int b = 0;

    int dx = 0, dy = 0, dz = 0;

    int rdsize = (!mouse_imps2)?(3):(4);

    

    n = read(mouse_fd, &buf[offs], BUFSIZ-offs);

    if(n < 0) return;

    n += offs;

 

    for(i=0; i<(n-(rdsize-1)); i += rdsize) {

        if((buf[i] & 0xC0) != 0) {

            i -= (rdsize-1);

            continue;

        }

        if(!mouse_imps2)

        {

            b = (buf[i] & 0x07); /*MRL*/

            dx = (buf[i] & 0x10) ? buf[i+1] - 256 : buf[i+1];

            dy = (buf[i] & 0x20) ? -(buf[i+2] - 256) : -buf[i+2];

        }

        else

        {

            b = (buf[i] & 0xC7); /*54...MRL*/

            dx = (buf[i] & 0x10) ? buf[i+1] - 256 : buf[i+1];

            dy = (buf[i] & 0x20) ? -(buf[i+2] - 256) : -buf[i+2];

            dz = (char)buf[i+3];

        }

 

        if(dx || dy)

        {

            mousep.x += dx;

            mousep.y += dy;

            mousep.x = minmax(mousep.x, 0, int(vinfo.xres));

            mousep.y = minmax(mousep.y, 0, int(vinfo.yres));

            Ctrl::DoMouseFB(Ctrl::MOUSEMOVE, mousep);

        }

 

 

        dword bm = b ^ mouseb;

        mouseb = b; //for GetMouse*

        dword ct = GetTickCount();

 

        handle_button(ct, mouseb, bm, 0, Ctrl::LEFTDOWN, Ctrl::LEFTREPEAT, Ctrl::LEFTDOUBLE, Ctrl::LEFTUP);

        handle_button(ct, mouseb, bm, 1, Ctrl::RIGHTDOWN, Ctrl::RIGHTREPEAT, Ctrl::RIGHTDOUBLE, Ctrl::RIGHTUP);

        handle_button(ct, mouseb, bm, 2, Ctrl::MIDDLEDOWN, Ctrl::MIDDLEREPEAT, Ctrl::MIDDLEDOUBLE, Ctrl::MIDDLEUP);

 

        if(dz) Ctrl::DoMouseFB(Ctrl::MOUSEWHEEL, mousep, dz*120);

    }

    if(i < n) {

        memcpy(buf, &buf[i], (n-i));

        offs = (n-i);

    } else

        offs = 0;

}

 

void handle_keyboard()

{

    unsigned char buf[BUFSIZ];

    int n;

    int keyup;

    int keycode;

 

    n = read(keyb_fd, buf, BUFSIZ);

    for(int i=0; i<n; ++i) {

        keycode = buf[i] & 0x7F;

        keyup = (buf[i] & 0x80)?(K_KEYUP):(0);

        bool b;

 

        SaveModKeys(keycode, !keyup);

 

        //we dont support both sides, fall back to left

        switch(keycode)

        {

            case SCANCODE_RIGHTALT: keycode = SCANCODE_LEFTALT; break;    

            case SCANCODE_RIGHTSHIFT: keycode = SCANCODE_LEFTSHIFT; break;    

            case SCANCODE_RIGHTCONTROL: keycode = SCANCODE_LEFTCONTROL; break;    

        }

 

        dword uppcode = fbKEYtoK(keycode) | keyup;

 

        if(!keyup && uppcode == K_SPACE)

            uppcode = 0; //prevent double send with unicode

 

        //vtswitch

        int vtck = uppcode & (K_DELTA | 0xFFFF);

        switch(vtck) {

            case K_F11:

            case K_F12:

                vtck -= 18; //dirty hack: after F10 doesnt come F11, see vgakeyboard.h

            case K_F1:

            case K_F2:

            case K_F3:

            case K_F4:

            case K_F5:

            case K_F6:

            case K_F7:

            case K_F8:

            case K_F9:

            case K_F10:

            if(GetCtrl() && GetAlt()) {

                int ii = vtck - K_F1 + 1;

                if(!keyup)

                    switchvt(ii);

                return;

            }

        }

 

        //first, the upp keycode

        if(uppcode)

            b = Ctrl::DoKeyFB(uppcode, 1);

 

        //second, the unicode translation for a keypress

        if(!keyup)

        {

            dword unicode = TranslateUnicode(keycode);

            if(unicode >= 32 && unicode != 127)

                b = Ctrl::DoKeyFB(unicode, 1);

        }

 

        //helper quit

        if(uppcode == (K_SHIFT_CTRL | K_ESCAPE))

            Ctrl::EndSession();

    }

}

 

END_UPP_NAMESPACE

 

 

 

keymap.cpp

 

#include "LinuxFbLocal.h"

 

#define LLOG(x)       //LOG(x)

 

NAMESPACE_UPP

 

dword modkeys = 0;

 

enum KMOD {

    KMOD_NONE  = 0x00,

 

    KMOD_LSHIFT= 0x01,

    KMOD_RSHIFT= 0x02,

    KMOD_LCTRL = 0x04,

    KMOD_RCTRL = 0x08,

    KMOD_LALT  = 0x10,

    KMOD_RALT  = 0x20,

 

    KMOD_CAPS  = 0x40,

    KMOD_NUM   = 0x80,

    

    KMOD_CTRL = KMOD_LCTRL | KMOD_RCTRL,

    KMOD_SHIFT = KMOD_LSHIFT | KMOD_RSHIFT,

    KMOD_ALT = KMOD_LALT | KMOD_RALT,

};

 

#define CHFLAG(w, m, b) if(b) w |= m; else w &= ~m;

void SaveModKeys(dword keycode, dword pressed)

{

    switch(keycode)

    {

        case SCANCODE_LEFTSHIFT: CHFLAG(modkeys, KMOD_LSHIFT, pressed) break;

        case SCANCODE_RIGHTSHIFT: CHFLAG(modkeys, KMOD_RSHIFT, pressed) break;

        case SCANCODE_LEFTCONTROL: CHFLAG(modkeys, KMOD_LCTRL, pressed) break;

        case SCANCODE_RIGHTCONTROL: CHFLAG(modkeys, KMOD_RCTRL, pressed) break;

        case SCANCODE_LEFTALT: CHFLAG(modkeys, KMOD_LALT, pressed) break;

        case SCANCODE_RIGHTALT: CHFLAG(modkeys, KMOD_RALT, pressed) break;

        case SCANCODE_CAPSLOCK: CHFLAG(modkeys, KMOD_CAPS, pressed) break;

        case SCANCODE_NUMLOCK: CHFLAG(modkeys, KMOD_NUM, pressed) break;

    }

}

 

bool GetShift()       { return modkeys & KMOD_SHIFT; }

bool GetCtrl()        { return modkeys & KMOD_CTRL; }

bool GetAlt()         { return modkeys & KMOD_ALT; }

bool GetCapsLock()    { return modkeys & KMOD_CAPS; }

 

dword fbKEYtoK(dword chr) {

 

    if(chr == SCANCODE_TAB)

        chr = K_TAB;

    else

    if(chr == SCANCODE_SPACE)

        chr = K_SPACE;

    else

    if(chr == SCANCODE_ENTER)

        chr = K_RETURN;

    else

        chr = chr + K_DELTA;

 

    //if the mod keys themselves, no need to have CTRL+ xxx behaviour indicator

    if(chr == K_ALT_KEY || chr == K_CTRL_KEY || chr == K_SHIFT_KEY)

        return chr;

 

    if(GetCtrl()) chr |= K_CTRL;

    if(GetAlt()) chr |= K_ALT;

    if(GetShift()) chr |= K_SHIFT;

 

    return chr;

}

 

END_UPP_NAMESPACE

 

//kernel defines conflict with some upp K_ enums, like K_SHIFT, K_ALT, K_CTRL

//so we separate as much as possible

#include <linux/keyboard.h>

 

NAMESPACE_UPP

 

//The kernel copy of translation tables

//from a console keycode in MEDIUMRAW to unicode

static uint16 kmap[MAX_NR_KEYMAPS][NR_KEYS];

 

void dupkmap(int fd)

{

    struct kbentry entry;

 

    if(fd < 0) return;

 

    for(int m=0; m<MAX_NR_KEYMAPS; ++m) {

        memset(kmap[m], 0, NR_KEYS*sizeof(uint16));

        for(int i=0; i<NR_KEYS; ++i) {

            entry.kb_table = m; entry.kb_index = i;

            if(ioctl(fd, KDGKBENT, &entry) < 0)

            {

                fprintf(stderr, "Error: reading keymap\n");

                return;

            }

 

            if(entry.kb_value == K_ENTER ) entry.kb_value = K(KT_ASCII,13);

 

            //correct numpad

            if(KTYP(entry.kb_value) == KT_PAD) {

                switch(entry.kb_value) {

                    case K_P0:

                    case K_P1:

                    case K_P2:

                    case K_P3:

                    case K_P4:

                    case K_P5:

                    case K_P6:

                    case K_P7:

                    case K_P8:

                    case K_P9:

                        kmap[m][i]=entry.kb_value;

                        kmap[m][i]+= '0';

                        break;

                    case K_PPLUS:  kmap[m][i]=K(KT_ASCII,'+'); break;

                    case K_PMINUS: kmap[m][i]=K(KT_ASCII,'-'); break;

                    case K_PSTAR:  kmap[m][i]=K(KT_ASCII,'*'); break;

                    case K_PSLASH: kmap[m][i]=K(KT_ASCII,'/'); break;

                    case K_PENTER: kmap[m][i]=K(KT_ASCII,'\r'); break;

                    case K_PCOMMA: kmap[m][i]=K(KT_ASCII,','); break;

                    case K_PDOT:   kmap[m][i]=K(KT_ASCII,'.'); break;

                    default: break;

                }

            }

 

            if((KTYP(entry.kb_value) == KT_LATIN)

                || (KTYP(entry.kb_value) == KT_ASCII)

                || (KTYP(entry.kb_value) == KT_LETTER)

            )

                kmap[m][i] = entry.kb_value;

        }

    }

}

 

dword TranslateUnicode(dword keycode)

{

    int m = 0;

 

    if(modkeys & KMOD_SHIFT) m |= (1<<KG_SHIFT);

    if(modkeys & KMOD_CTRL) m |= (1<<KG_CTRL);

    if(modkeys & KMOD_LALT) m |= (1<<KG_ALT);

    if(modkeys & KMOD_RALT) m |= (1<<KG_ALTGR);

 

    //CAPS changes shift meaning in both directions

    if((modkeys & KMOD_CAPS)

        && KTYP(kmap[m][keycode]) == KT_LETTER

    )

        m ^= (1<<KG_SHIFT);

 

    //num pad handling stays same so far

    if((modkeys & KMOD_NUM)

        && KTYP(kmap[m][keycode]) == KT_PAD

    )

        return KVAL(kmap[m][keycode]);

    else

        return KVAL(kmap[m][keycode]);

}

 

END_UPP_NAMESPACE

 

 

 

Win.cpp

 

#include "LinuxFbLocal.h"

 

#define LLOG(x)       //LOG(x)

 

NAMESPACE_UPP

 

//video

int fbfd = -1;

struct fb_var_screeninfo vinfo;

struct fb_fix_screeninfo finfo;

long int screensize = 0;

char *fbp = 0;

 

//mouse

int mouse_fd = -1;

bool mouse_imps2 = false;

Point mousep;

dword mouseb = 0;

 

//keyb

int keyb_fd = -1;

int cvt = -1;

 

//

 

int oldvt;

struct termios oldtermios;

int oldmode;

 

int entervt()

{

    struct termios kt;

 

    if(cvt > 0) {

        struct vt_stat vtst;

        if(ioctl(keyb_fd, VT_GETSTATE, &vtst) == 0)

            oldvt = vtst.v_active;

        if(ioctl(keyb_fd, VT_ACTIVATE, cvt) == 0)

            ioctl(keyb_fd, VT_WAITACTIVE, cvt);

    }

 

    if(tcgetattr(keyb_fd, &oldtermios) < 0) {

        fprintf(stderr, "Error: saving terminal attributes");

        return -1;

    }

 

    if(ioctl(keyb_fd, KDGKBMODE, &oldmode) < 0) {

        fprintf(stderr, "Error: saving keyboard mode");

        return -1;

    }

 

    kt = oldtermios;

    kt.c_lflag &= ~(ICANON | ECHO | ISIG);

    kt.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);

    kt.c_cc[VMIN] = 0;

    kt.c_cc[VTIME] = 0;

 

    if(tcsetattr(keyb_fd, TCSAFLUSH, &kt) < 0) {

        fprintf(stderr, "Error: setting new terminal attributes");

        return -1;

    }

 

    if(ioctl(keyb_fd, KDSKBMODE, K_MEDIUMRAW) < 0) {

        fprintf(stderr, "Error: setting keyboard in mediumraw mode");

        return -1;

    }

 

    if(ioctl(keyb_fd, KDSETMODE, KD_GRAPHICS) < 0) {

        fprintf(stderr, "Error: setting keyboard in graphics mode");

        return -1;

    }

 

    ioctl(keyb_fd, VT_LOCKSWITCH, 1);

    

    return 0;

}

 

void switchvt_pre()

{

    ioctl(keyb_fd, KDSETMODE, KD_TEXT);

    ioctl(keyb_fd, VT_UNLOCKSWITCH, 1);

}

 

void switchvt_post()

{

    ioctl(keyb_fd, VT_LOCKSWITCH, 1);

    ioctl(keyb_fd, KDSETMODE, KD_GRAPHICS);

}

 

int switched_away = 0;

 

void switchvt(int ii)

{

    struct vt_stat vtst;

 

    /* Figure out whether or not we're switching to a new console */

    if(ioctl(keyb_fd, VT_GETSTATE, &vtst) < 0)

    {

        fprintf(stderr, "Error: could not read tty state");

        return;    

    }

    if(ii == vtst.v_active)

        return;

 

    LLOG("trying to switch to VT " << ii);

 

    GuiLock __;

 

    switchvt_pre();

 

    if(ioctl(keyb_fd, VT_ACTIVATE, ii) == 0) {

        ioctl(keyb_fd, VT_WAITACTIVE, ii);

        switched_away = 1;

        return;

    }

 

    switchvt_post();

}

 

void leavevt()

{

    if(oldmode < 0) return;

 

    if(ioctl(keyb_fd, KDSETMODE, KD_TEXT) < 0)

        fprintf(stderr, "Error: setting keyboard in text mode");

        

    if(ioctl(keyb_fd, KDSKBMODE, oldmode) < 0)

        fprintf(stderr, "Error: restoring keyboard mode");

 

    if(tcsetattr(keyb_fd, TCSAFLUSH, &oldtermios) < 0)

        fprintf(stderr, "Error: setting new terminal attributes");

 

    oldmode = -1;

 

    ioctl(keyb_fd, VT_UNLOCKSWITCH, 1);

 

    if(oldvt > 0)

        ioctl(keyb_fd, VT_ACTIVATE, oldvt);

}

 

int pend = 0;

 

//returns 0 if timeout, 1 for mouse, 2 for keyboard

//common for waitforevents and sleep

int readevents(int ms)

{

    fd_set fdset;

    int max_fd;

    static struct timeval to;

    to.tv_sec = ms / 1000;

    to.tv_usec = ms % 1000 * 1000;

 

    if(switched_away) {

        struct vt_stat vtst;

        GuiLock __;

        if((ioctl(keyb_fd, VT_GETSTATE, &vtst) == 0) &&

             vtst.v_active == cvt) {

            switched_away = 0;

            switchvt_post();

        }

    }

 

    FD_ZERO(&fdset);

    max_fd = 0;

    if(mouse_fd >= 0) {

        FD_SET(mouse_fd, &fdset);

        if(max_fd < mouse_fd) max_fd = mouse_fd;

    }

    if(keyb_fd >= 0) {

        FD_SET(keyb_fd, &fdset);

        if(max_fd < keyb_fd) max_fd = keyb_fd;

    }

    if(select(max_fd+1, &fdset, NULL, NULL, &to) > 0) {

        if(mouse_fd >= 0) {

            if(FD_ISSET(mouse_fd, &fdset)) return 1;

        }

        if(keyb_fd >= 0) {

            if(FD_ISSET(keyb_fd, &fdset)) return 2;

        }

    }

    return 0;

}

 

//

 

void FBQuitSession()

{

    Ctrl::EndSession();

}

 

bool FBIsWaitingEvent()

{

    pend = readevents(0);

    return pend > 0;

}

 

bool FBProcessEvent(bool *quit)

{

    if(pend)

    {

        if(pend & 1) handle_mouse();

        if(pend & 2) handle_keyboard();

        pend = 0; //need to reset, since with repeated call is not updated here, would stuck

        return true;

    }

    return false;

}

 

void FBSleep(int ms)

{

    pend = readevents(ms); //interruptable sleep

 

    //keep queue busy, see SDLFb/Win.cpp for why

    //this indicates that some stuff is pending, returning true in FBProcessEvent

    //while nothing is actually processed

    pend |= 4;

}

 

void FBInitUpdate()

{

 

}

 

void FBUpdate(const Rect& inv)

{

    if(switched_away) return; //backdraw

    //FIXME accelerate

    const ImageBuffer& framebuffer = Ctrl::GetFrameBuffer();

    memcpy(fbp, ~framebuffer, framebuffer.GetLength() * sizeof(RGBA));

}

 

void FBFlush()

{

 

}

 

void FBInit(const String& fbdevice)

{

    Ctrl::InitFB();

 

    fbfd = open(fbdevice, O_RDWR);

    if (!fbfd) {

        fprintf(stderr, "Error: cannot open framebuffer device.\n");

        exit(-1);

    }

    LLOG("The framebuffer device was opened successfully.\n");

 

    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {

        fprintf(stderr, "Error reading fixed information.\n");

        exit(-2);

    }

 

    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {

        fprintf(stderr, "Error reading variable information.\n");

        exit(-3);

    }

    RLOG("Framebuffer opened: " << fbdevice << ": " << vinfo.xres << "x" << vinfo.yres << " @ " << vinfo.bits_per_pixel);

 

    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; //bytes

 

    fbp = (char*)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);

    if((intptr_t)fbp == -1) {

        fprintf(stderr, "Error: failed to map framebuffer device to memory.\n");

        exit(-4);

    }

    LLOG("The framebuffer device was mapped to memory successfully.\n");

 

    Size fbsz(vinfo.xres, vinfo.yres);

    Ctrl::SetFramebufferSize(fbsz);

 

    //mouse

 

    //mousep = fbsz / 2;

    mousep.Clear();    

 

    static const char *mice[] = {

        "/dev/input/mice"

        , "/dev/usbmouse"

        , "/dev/psaux"

        , NULL

    };

 

    for(int i=0; (mouse_fd < 0) && mice[i]; ++i) {

        mouse_fd = open(mice[i], O_RDWR, 0);

        if(mouse_fd < 0) mouse_fd = open(mice[i], O_RDONLY, 0);

        if(mouse_fd >= 0) {

            set_imps2(mouse_fd, 1);

            if(mouse_imps2 = has_imps2(mouse_fd)) {

                LLOG("IMPS2 mouse enabled: " << mice[i]);

            }

            else

                RLOG("no IMPS2 mouse present");

        }

        else

            fprintf(stderr, "Error: failed to open %s.\n", mice[i]);

    }

 

    //keyb

 

    static const char* const tty0[] = {

        "/dev/tty0"

        , "/dev/vc/0"

        , NULL

    };

    static const char* const vcs[] = {

        "/dev/vc/"

        , "/dev/tty"

        , NULL

    };

 

    int tfd = -1;

    for(int i=0; tty0[i] && (tfd < 0); ++i)

        tfd = open(tty0[i], O_WRONLY, 0);

    if(tfd < 0)

        tfd = dup(0);

    ASSERT(tfd>=0);

 

    ioctl(tfd, VT_OPENQRY, &cvt);

    close(tfd);

    LLOG("probable new VT: " << cvt);

 

    if(geteuid() != 0)

    {

        fprintf(stderr, "Error: not running as ROOT, mouse handling pobably unavailable\n");

    }

    else if(cvt > 0) {

        LLOG("try to open the NEW assigned VT: " << cvt);

        for(int i=0; vcs[i] && (keyb_fd < 0); ++i) {

            char path[32];

            snprintf(path, 32, "%s%d", vcs[i], cvt);

            keyb_fd = open(path, O_RDWR, 0);

 

            if(keyb_fd < 0)

                continue;    

            

            LLOG("TTY path opened: " << path);

            tfd = open("/dev/tty", O_RDWR, 0);

            if(tfd >= 0) {

                LLOG("detaching from local stdin/out/err");

                ioctl(tfd, TIOCNOTTY, 0);

                close(tfd);

            }

            else

                fprintf(stderr, "Error: detaching from local stdin/out/err\n");

        }

    }

 

    if(keyb_fd < 0) {

        LLOG("Using already assigned VT, must not detach");

        struct vt_stat vtst;

 

        keyb_fd = open("/dev/tty", O_RDWR);

 

        if(ioctl(keyb_fd, VT_GETSTATE, &vtst) < 0) {

            cvt = 0;

        } else {

            cvt = vtst.v_active;

        }

    }

 

    if(cvt>0)

        fprintf(stdout, "started on VT %d\n", cvt);

 

    ASSERT(keyb_fd>=0);

    oldmode = -1;

 

    {

        int d;

        if(ioctl(keyb_fd, KDGKBMODE, &d) < 0) {

            close(keyb_fd);

            keyb_fd = -1;

            fprintf(stderr, "Error: opening a console terminal");

            exit(5);

        }

    }

 

    LLOG("tty opened: " << keyb_fd);

 

    dupkmap(keyb_fd);

 

    entervt();

    

    pend = 4; //fake video expose event to cause first paint

}

 

void FBDeInit()

{

    Ctrl::ExitFB();

    munmap(fbp, screensize);

    close(fbfd);

    

    leavevt();

    close(mouse_fd);

}

 

END_UPP_NAMESPACE

 

 

 

 

Do you want to contribute?