[DEV] implement fullscreen in X11 interface with grab keyboard events

This commit is contained in:
Edouard DUPIN 2016-10-13 00:39:37 +02:00
parent aed53ea524
commit 0d6277a651
2 changed files with 118 additions and 44 deletions

View File

@ -253,11 +253,16 @@ namespace gale {
*/
virtual void forceOrientation(enum gale::orientation _orientation) { };
/**
* @brief get all the event from the X system
* @param[in] _isGrabbed "true" if all the event will be get, false if we want only ours.
* @brief get all Keyboard event from the X system (like many time use of META)
* @param[in] _status "true" if all the event will be get, false if we want only ours.
*/
virtual void grabKeyboardEvents(bool _status) {}
/**
* @brief get all Mouse/Touch events from the X system
* @param[in] _status "true" if all the event will be get, false if we want only ours.
* @param[in] _forcedPosition the position where the mouse might be reset at every events ...
*/
virtual void grabPointerEvents(bool _isGrabbed, const vec2& _forcedPosition) { };
virtual void grabPointerEvents(bool _status, const vec2& _forcedPosition) { };
/**
* @brief set the cursor display type.
* @param[in] _newCursor selected new cursor.
@ -268,11 +273,17 @@ namespace gale {
* @param[in] _inputFile new filename icon of the curent program.
*/
virtual void setIcon(const std::string& _inputFile) { };
/**
* @brief Enable or Disable the decoration on the Windows (availlable only on Desktop)
* @param[in] _status "true" to enable decoration / false otherwise
*/
virtual void setWindowsDecoration(bool _status) {};
/**
* @brief get the curent time in micro-second
* @note : must be implemented in all system OS implementation
* @return The curent time of the process
*/
// TODO : REMOVE this ... deprecated since c++11
static int64_t getTime();
private:
// TODO : set user argument here ....

View File

@ -11,6 +11,7 @@
#include <etk/types.hpp>
#include <etk/os/FSNode.hpp>
#include <etk/tool.hpp>
#include <gale/debug.hpp>
#include <gale/gale.hpp>
@ -127,13 +128,14 @@ class X11Interface : public gale::Context {
bool m_clipBoardOwnerPrimary; //!< we are the owner of the current selection
bool m_clipBoardOwnerStd; //!< we are the owner of the current copy buffer
// Atom access...
Atom XAtomeSelection;
Atom XAtomeClipBoard;
Atom XAtomeTargetString;
Atom XAtomeTargetStringUTF8;
Atom XAtomeTargetTarget;
Atom XAtomeGALE;
Atom XAtomeDeleteWindows;
Atom XAtomSelection;
Atom XAtomClipBoard;
Atom XAtomTargetString;
Atom XAtomTargetStringUTF8;
Atom XAtomTargetTarget;
Atom XAtomGALE;
Atom XAtomDeleteWindows;
std::string m_uniqueWindowsName;
enum gale::context::cursor m_currentCursor; //!< select the current cursor to display :
char32_t m_lastKeyPressed; //!< The last element key presed...
public:
@ -156,13 +158,13 @@ class X11Interface : public gale::Context {
m_clipBoardRequestPrimary(false),
m_clipBoardOwnerPrimary(false),
m_clipBoardOwnerStd(false),
XAtomeSelection(0),
XAtomeClipBoard(0),
XAtomeTargetString(0),
XAtomeTargetStringUTF8(0),
XAtomeTargetTarget(0),
XAtomeGALE(0),
XAtomeDeleteWindows(0),
XAtomSelection(0),
XAtomClipBoard(0),
XAtomTargetString(0),
XAtomTargetStringUTF8(0),
XAtomTargetTarget(0),
XAtomGALE(0),
XAtomDeleteWindows(0),
m_currentCursor(gale::context::cursor::arrow),
m_lastKeyPressed(0) {
X11_INFO("X11:INIT");
@ -176,13 +178,14 @@ class X11Interface : public gale::Context {
createX11Context();
createOGlContext();
// reset the Atom properties ...
XAtomeSelection = XInternAtom(m_display, "PRIMARY", 0);
XAtomeClipBoard = XInternAtom(m_display, "CLIPBOARD", 0);
XAtomeTargetString = XInternAtom(m_display, "STRING", 0);
XAtomeTargetStringUTF8 = XInternAtom(m_display, "UTF8_STRING", 0);
XAtomeTargetTarget = XInternAtom(m_display, "TARGETS", 0);
XAtomeGALE = XInternAtom(m_display, "GALE", 0);
XAtomeDeleteWindows = XInternAtom(m_display, "WM_DELETE_WINDOW", 0);
XAtomSelection = XInternAtom(m_display, "PRIMARY", 0);
XAtomClipBoard = XInternAtom(m_display, "CLIPBOARD", 0);
XAtomTargetString = XInternAtom(m_display, "STRING", 0);
XAtomTargetStringUTF8 = XInternAtom(m_display, "UTF8_STRING", 0);
XAtomTargetTarget = XInternAtom(m_display, "TARGETS", 0);
m_uniqueWindowsName = "GALE_" + etk::to_string(etk::tool::irand(0, 1999999999));
XAtomGALE = XInternAtom(m_display, m_uniqueWindowsName.c_str(), 0);
XAtomDeleteWindows = XInternAtom(m_display, "WM_DELETE_WINDOW", 0);
m_run = true;
}
@ -203,7 +206,7 @@ class X11Interface : public gale::Context {
switch (event.type) {
case ClientMessage: {
X11_INFO("Receive : ClientMessage");
if(XAtomeDeleteWindows == (uint64_t)event.xclient.data.l[0]) {
if(XAtomDeleteWindows == (uint64_t)event.xclient.data.l[0]) {
GALE_INFO(" == > Kill Requested ...");
OS_Stop();
// We do not close here but in the application only:
@ -312,21 +315,21 @@ class X11Interface : public gale::Context {
#endif
std::string tmpData = "";
if (req->selection == XAtomeSelection) {
if (req->selection == XAtomSelection) {
tmpData = gale::context::clipBoard::get(gale::context::clipBoard::clipboardSelection);
} else if (req->selection == XAtomeClipBoard) {
} else if (req->selection == XAtomClipBoard) {
tmpData = gale::context::clipBoard::get(gale::context::clipBoard::clipboardStd);
}
const char * magatTextToSend = tmpData.c_str();
Atom listOfAtom[4];
if(strlen(magatTextToSend) == 0 ) {
respond.xselection.property= None;
} else if(XAtomeTargetTarget == req->target) {
} else if(XAtomTargetTarget == req->target) {
// We need to generate the list of the possibles target element of atom
int32_t nbAtomSupported = 0;
listOfAtom[nbAtomSupported++] = XAtomeTargetTarget;
listOfAtom[nbAtomSupported++] = XAtomeTargetString;
listOfAtom[nbAtomSupported++] = XAtomeTargetStringUTF8;
listOfAtom[nbAtomSupported++] = XAtomTargetTarget;
listOfAtom[nbAtomSupported++] = XAtomTargetString;
listOfAtom[nbAtomSupported++] = XAtomTargetStringUTF8;
listOfAtom[nbAtomSupported++] = None;
XChangeProperty( m_display,
req->requestor,
@ -338,7 +341,7 @@ class X11Interface : public gale::Context {
nbAtomSupported );
respond.xselection.property=req->property;
GALE_INFO(" == > Respond ... (test)");
} else if(XAtomeTargetString == req->target) {
} else if(XAtomTargetString == req->target) {
XChangeProperty( m_display,
req->requestor,
req->property,
@ -349,7 +352,7 @@ class X11Interface : public gale::Context {
strlen(magatTextToSend));
respond.xselection.property=req->property;
GALE_INFO(" == > Respond ...");
} else if (XAtomeTargetStringUTF8 == req->target) {
} else if (XAtomTargetStringUTF8 == req->target) {
XChangeProperty( m_display,
req->requestor,
req->property,
@ -799,9 +802,69 @@ class X11Interface : public gale::Context {
XResizeWindow(m_display, m_WindowHandle, _size.x(), _size.y());
}
/****************************************************************************************/
void gale::Context::setFullScreen(bool _status) {
void setFullScreen(bool _status) {
X11_INFO("X11-API: changeFullscreen=" << _status);
XEvent event;
event.xclient.type = ClientMessage;
event.xclient.serial = 0;
event.xclient.send_event = True;
event.xclient.display = m_display;
event.xclient.window = m_WindowHandle;
event.xclient.message_type = XInternAtom(m_display, "_NET_WM_STATE", False);
event.xclient.format = 32;
if (_status == true) {
event.xclient.data.l[0] = 1;//XInternAtom(m_display, "_NET_WM_STATE_REMOVE", False);
} else {
event.xclient.data.l[0] = 0;//XInternAtom(m_display, "_NET_WM_STATE_ADD", False);
}
event.xclient.data.l[1] = XInternAtom(m_display, "_NET_WM_STATE_FULLSCREEN", False);
event.xclient.data.l[2] = 0;
event.xclient.data.l[3] = 0;
event.xclient.data.l[4] = 0;
//long mask = SubstructureNotifyMask;
//long mask = StructureNotifyMask | ResizeRedirectMask;
//long mask = SubstructureRedirectMask;
long mask = PropertyChangeMask;
XSendEvent(m_display,
RootWindow(m_display, DefaultScreen(m_display)),
False,
mask,
&event);
// associate the keyboard grabing (99% associated case)
grabKeyboardEvents(_status);
}
/****************************************************************************************/
virtual void grabKeyboardEvents(bool _status) {
if (_status == true) {
X11_INFO("X11-API: Grab Keyboard Events");
XGrabKeyboard(m_display, m_WindowHandle,
False,
GrabModeAsync,
GrabModeAsync,
CurrentTime);
} else {
X11_INFO("X11-API: Un-Grab Keyboard Events");
XUngrabKeyboard(m_display, CurrentTime);
}
}
/****************************************************************************************/
virtual void setWindowsDecoration(bool _status) {
X11_INFO("X11-API: setWindows Decoration :" << _status);
// Remove/set decoration
Hints hints;
hints.flags = 2;
if (_status == true) {
hints.decorations = 1;
} else {
hints.decorations = 0;
}
XChangeProperty(m_display, m_WindowHandle,
XInternAtom(m_display, "_MOTIF_WM_HINTS", False),
XInternAtom(m_display, "_MOTIF_WM_HINTS", False),
32, PropModeReplace,
(unsigned char *)&hints,5);
};
/****************************************************************************************/
virtual void setPos(const vec2& _pos) {
@ -912,8 +975,8 @@ class X11Interface : public gale::Context {
}
}
/****************************************************************************************/
void grabPointerEvents(bool _isGrabbed, const vec2& _forcedPosition) {
if (_isGrabbed == true) {
void grabPointerEvents(bool _status, const vec2& _forcedPosition) {
if (_status == true) {
X11_DEBUG("X11-API: Grab Events");
int32_t test = XGrabPointer(m_display,RootWindow(m_display, DefaultScreen(m_display)), True,
ButtonPressMask |
@ -1319,9 +1382,9 @@ class X11Interface : public gale::Context {
m_clipBoardRequestPrimary = true;
// generate a request on X11
XConvertSelection(m_display,
XAtomeSelection,
XAtomeTargetStringUTF8,
XAtomeGALE,
XAtomSelection,
XAtomTargetStringUTF8,
XAtomGALE,
m_WindowHandle,
CurrentTime);
} else {
@ -1334,9 +1397,9 @@ class X11Interface : public gale::Context {
m_clipBoardRequestPrimary = false;
// generate a request on X11
XConvertSelection(m_display,
XAtomeClipBoard,
XAtomeTargetStringUTF8,
XAtomeGALE,
XAtomClipBoard,
XAtomTargetStringUTF8,
XAtomGALE,
m_WindowHandle,
CurrentTime);
} else {
@ -1355,14 +1418,14 @@ class X11Interface : public gale::Context {
case gale::context::clipBoard::clipboardSelection:
// Request the selection :
if (m_clipBoardOwnerPrimary == false) {
XSetSelectionOwner(m_display, XAtomeSelection, m_WindowHandle, CurrentTime);
XSetSelectionOwner(m_display, XAtomSelection, m_WindowHandle, CurrentTime);
m_clipBoardOwnerPrimary = true;
}
break;
case gale::context::clipBoard::clipboardStd:
// Request the clipBoard :
if (m_clipBoardOwnerStd == false) {
XSetSelectionOwner(m_display, XAtomeClipBoard, m_WindowHandle, CurrentTime);
XSetSelectionOwner(m_display, XAtomClipBoard, m_WindowHandle, CurrentTime);
m_clipBoardOwnerStd = true;
}
break;