diff --git a/client/displayservers/X11/CMakeLists.txt b/client/displayservers/X11/CMakeLists.txt index f6f7ab68..bdb82492 100644 --- a/client/displayservers/X11/CMakeLists.txt +++ b/client/displayservers/X11/CMakeLists.txt @@ -12,6 +12,7 @@ pkg_check_modules(DISPLAYSERVER_X11_PKGCONFIG REQUIRED add_library(displayserver_X11 STATIC x11.c + atoms.c clipboard.c ) diff --git a/client/displayservers/X11/atoms.c b/client/displayservers/X11/atoms.c new file mode 100644 index 00000000..51cd0297 --- /dev/null +++ b/client/displayservers/X11/atoms.c @@ -0,0 +1,30 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017-2021 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "atoms.h" +#include "x11.h" + +struct X11DSAtoms x11atoms = { 0 }; + +void X11AtomsInit(void) +{ + #define DEF_ATOM(x) x11atoms.x = XInternAtom(x11.display, #x, True); + DEF_ATOMS() + #undef DEF_ATOM +} diff --git a/client/displayservers/X11/atoms.h b/client/displayservers/X11/atoms.h new file mode 100644 index 00000000..96c9ea36 --- /dev/null +++ b/client/displayservers/X11/atoms.h @@ -0,0 +1,50 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017-2021 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _H_X11DS_ATOMS_ +#define _H_X11DS_ATOMS_ + +#define DEF_ATOMS() \ + DEF_ATOM(_NET_REQUEST_FRAME_EXTENTS) \ + DEF_ATOM(_NET_FRAME_EXTENTS) \ + DEF_ATOM(_NET_WM_STATE) \ + DEF_ATOM(_NET_WM_STATE_FULLSCREEN) \ + DEF_ATOM(_NET_WM_WINDOW_TYPE) \ + DEF_ATOM(_NET_WM_WINDOW_TYPE_NORMAL) \ + DEF_ATOM(WM_DELETE_WINDOW) \ + \ + DEF_ATOM(CLIPBOARD) \ + DEF_ATOM(TARGETS) \ + DEF_ATOM(SEL_DATA) \ + DEF_ATOM(INCR) + +#include + +#define DEF_ATOM(x) Atom x; +struct X11DSAtoms +{ + DEF_ATOMS() +}; +#undef DEF_ATOM + +extern struct X11DSAtoms x11atoms; + +void X11AtomsInit(void); + +#endif diff --git a/client/displayservers/X11/clipboard.c b/client/displayservers/X11/clipboard.c index 19d5f350..8535638b 100644 --- a/client/displayservers/X11/clipboard.c +++ b/client/displayservers/X11/clipboard.c @@ -19,6 +19,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "clipboard.h" #include "x11.h" +#include "atoms.h" #include #include @@ -31,11 +32,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA struct X11ClipboardState { - Atom aSelection; Atom aCurSelection; - Atom aTargets; - Atom aSelData; - Atom aIncr; Atom aTypes[LG_CLIPBOARD_DATA_NONE]; LG_ClipboardData type; bool haveRequest; @@ -79,7 +76,7 @@ void x11CBEventThread(const XEvent xe) break; case PropertyNotify: - if (xe.xproperty.atom == x11cb.aSelData) + if (xe.xproperty.atom == x11atoms.SEL_DATA) { if (x11cb.lowerBound == 0) break; @@ -101,12 +98,7 @@ void x11CBEventThread(const XEvent xe) bool x11CBInit() { - x11cb.aSelection = XInternAtom(x11.display, "CLIPBOARD" , False); - x11cb.aTargets = XInternAtom(x11.display, "TARGETS" , False); - x11cb.aSelData = XInternAtom(x11.display, "SEL_DATA" , False); - x11cb.aIncr = XInternAtom(x11.display, "INCR" , False); x11cb.aCurSelection = BadValue; - for(int i = 0; i < LG_CLIPBOARD_DATA_NONE; ++i) { x11cb.aTypes[i] = XInternAtom(x11.display, atomTypes[i], False); @@ -127,7 +119,7 @@ bool x11CBInit() XFixesSelectSelectionInput(x11.display, x11.window, XA_PRIMARY, XFixesSetSelectionOwnerNotifyMask); XFixesSelectSelectionInput(x11.display, x11.window, - x11cb.aSelection, XFixesSetSelectionOwnerNotifyMask); + x11atoms.CLIPBOARD, XFixesSetSelectionOwnerNotifyMask); return true; } @@ -166,10 +158,10 @@ static void x11CBSelectionRequest(const XSelectionRequestEvent e) goto nodata; // target list requested - if (e.target == x11cb.aTargets) + if (e.target == x11atoms.TARGETS) { Atom targets[2]; - targets[0] = x11cb.aTargets; + targets[0] = x11atoms.TARGETS; targets[1] = x11cb.aTypes[x11cb.type]; XChangeProperty( @@ -206,7 +198,7 @@ send: static void x11CBSelectionClear(const XSelectionClearEvent e) { - if (e.selection != XA_PRIMARY && e.selection != x11cb.aSelection) + if (e.selection != XA_PRIMARY && e.selection != x11atoms.CLIPBOARD) return; x11cb.aCurSelection = BadValue; @@ -227,7 +219,7 @@ static void x11CBSelectionIncr(const XPropertyEvent e) e.atom, 0, ~0L, // start and length True, // delete the property - x11cb.aIncr, + x11atoms.INCR, &type, &format, &itemCount, @@ -292,7 +284,7 @@ out: static void x11CBXFixesSelectionNotify(const XFixesSelectionNotifyEvent e) { // check if the selection is valid and it isn't ourself - if ((e.selection != XA_PRIMARY && e.selection != x11cb.aSelection) || + if ((e.selection != XA_PRIMARY && e.selection != x11atoms.CLIPBOARD) || e.owner == x11.window || e.owner == 0) { return; @@ -303,8 +295,8 @@ static void x11CBXFixesSelectionNotify(const XFixesSelectionNotifyEvent e) XConvertSelection( x11.display, e.selection, - x11cb.aTargets, - x11cb.aTargets, + x11atoms.TARGETS, + x11atoms.TARGETS, x11.window, CurrentTime); @@ -338,7 +330,7 @@ static void x11CBSelectionNotify(const XSelectionEvent e) goto out; } - if (type == x11cb.aIncr) + if (type == x11atoms.INCR) { x11cb.incrStart = true; x11cb.lowerBound = *(unsigned int *)data; @@ -346,7 +338,7 @@ static void x11CBSelectionNotify(const XSelectionEvent e) } // the target list - if (e.property == x11cb.aTargets) + if (e.property == x11atoms.TARGETS) { // the format is 32-bit and we must have data // this is technically incorrect however as it's @@ -372,7 +364,7 @@ static void x11CBSelectionNotify(const XSelectionEvent e) goto out; } - if (e.property == x11cb.aSelData) + if (e.property == x11atoms.SEL_DATA) { LG_ClipboardData dataType; for(dataType = 0; dataType < LG_CLIPBOARD_DATA_NONE; ++dataType) @@ -399,16 +391,16 @@ void x11CBNotice(LG_ClipboardData type) { x11cb.haveRequest = true; x11cb.type = type; - XSetSelectionOwner(x11.display, XA_PRIMARY , x11.window, CurrentTime); - XSetSelectionOwner(x11.display, x11cb.aSelection, x11.window, CurrentTime); + XSetSelectionOwner(x11.display, XA_PRIMARY , x11.window, CurrentTime); + XSetSelectionOwner(x11.display, x11atoms.CLIPBOARD, x11.window, CurrentTime); XFlush(x11.display); } void x11CBRelease(void) { x11cb.haveRequest = false; - XSetSelectionOwner(x11.display, XA_PRIMARY , None, CurrentTime); - XSetSelectionOwner(x11.display, x11cb.aSelection, None, CurrentTime); + XSetSelectionOwner(x11.display, XA_PRIMARY , None, CurrentTime); + XSetSelectionOwner(x11.display, x11atoms.CLIPBOARD, None, CurrentTime); XFlush(x11.display); } @@ -421,7 +413,7 @@ void x11CBRequest(LG_ClipboardData type) x11.display, x11cb.aCurSelection, x11cb.aTypes[type], - x11cb.aSelData, + x11atoms.SEL_DATA, x11.window, CurrentTime); } diff --git a/client/displayservers/X11/x11.c b/client/displayservers/X11/x11.c index c03bf95a..64614ab6 100644 --- a/client/displayservers/X11/x11.c +++ b/client/displayservers/X11/x11.c @@ -20,6 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "interface/displayserver.h" #include "x11.h" +#include "atoms.h" #include "clipboard.h" #include @@ -145,31 +146,17 @@ static bool x11Init(const LG_DSInitParams params) free(hint.res_name); free(hint.res_class); - x11.aNetReqFrameExtents = - XInternAtom(x11.display, "_NET_REQUEST_FRAME_EXTENTS", True); - x11.aNetFrameExtents = - XInternAtom(x11.display, "_NET_FRAME_EXTENTS", True); - x11.aNetWMState = - XInternAtom(x11.display, "_NET_WM_STATE", True); - x11.aNetWMStateFullscreen = - XInternAtom(x11.display, "_NET_WM_STATE_FULLSCREEN", True); - x11.aNetWMWindowType = - XInternAtom(x11.display, "_NET_WM_WINDOW_TYPE", True); - x11.aNetWMWindowTypeNormal = - XInternAtom(x11.display, "_NET_WM_WINDOW_TYPE_NORMAL", True); - x11.aWMDeleteWindow = - XInternAtom(x11.display, "WM_DELETE_WINDOW", True); - - XSetWMProtocols(x11.display, x11.window, &x11.aWMDeleteWindow, 1); + X11AtomsInit(); + XSetWMProtocols(x11.display, x11.window, &x11atoms.WM_DELETE_WINDOW, 1); XChangeProperty( x11.display, x11.window, - x11.aNetWMWindowType, + x11atoms._NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, - (unsigned char *)&x11.aNetWMWindowTypeNormal, + (unsigned char *)&x11atoms._NET_WM_WINDOW_TYPE_NORMAL, 1 ); @@ -178,16 +165,16 @@ static bool x11Init(const LG_DSInitParams params) XChangeProperty( x11.display, x11.window, - x11.aNetWMState, + x11atoms._NET_WM_STATE, XA_ATOM, 32, PropModeReplace, - (unsigned char *)&x11.aNetWMStateFullscreen, + (unsigned char *)&x11atoms._NET_WM_STATE_FULLSCREEN, 1 ); } - if (x11.aNetReqFrameExtents) + if (x11atoms._NET_REQUEST_FRAME_EXTENTS) { XEvent reqevent = { @@ -196,7 +183,7 @@ static bool x11Init(const LG_DSInitParams params) .type = ClientMessage, .window = x11.window, .format = 32, - .message_type = x11.aNetReqFrameExtents + .message_type = x11atoms._NET_REQUEST_FRAME_EXTENTS } }; @@ -473,7 +460,7 @@ static int x11EventThread(void * unused) switch(xe.type) { case ClientMessage: - if (xe.xclient.data.l[0] == x11.aWMDeleteWindow) + if (xe.xclient.data.l[0] == x11atoms.WM_DELETE_WINDOW) app_handleCloseEvent(); break; @@ -526,7 +513,7 @@ static int x11EventThread(void * unused) xe.xproperty.state != PropertyNewValue) continue; - if (xe.xproperty.atom == x11.aNetWMState) + if (xe.xproperty.atom == x11atoms._NET_WM_STATE) { Atom type; int fmt; @@ -534,7 +521,7 @@ static int x11EventThread(void * unused) unsigned char *data; if (XGetWindowProperty(x11.display, x11.window, - x11.aNetWMState, 0, ~0L, False, AnyPropertyType, + x11atoms._NET_WM_STATE, 0, ~0L, False, AnyPropertyType, &type, &fmt, &num, &bytes, &data) != Success) break; @@ -542,7 +529,7 @@ static int x11EventThread(void * unused) for(int i = 0; i < num; ++i) { Atom prop = ((Atom *)data)[i]; - if (prop == x11.aNetWMStateFullscreen) + if (prop == x11atoms._NET_WM_STATE_FULLSCREEN) fullscreen = true; } @@ -551,7 +538,7 @@ static int x11EventThread(void * unused) break; } - if (xe.xproperty.atom == x11.aNetFrameExtents) + if (xe.xproperty.atom == x11atoms._NET_FRAME_EXTENTS) { Atom type; int fmt; @@ -559,7 +546,7 @@ static int x11EventThread(void * unused) unsigned char *data; if (XGetWindowProperty(x11.display, x11.window, - x11.aNetFrameExtents, 0, 4, False, AnyPropertyType, + x11atoms._NET_FRAME_EXTENTS, 0, 4, False, AnyPropertyType, &type, &fmt, &num, &bytes, &data) != Success) break; @@ -1052,12 +1039,12 @@ static void x11SetFullscreen(bool fs) .xclient = { .type = ClientMessage, .send_event = true, - .message_type = x11.aNetWMState, + .message_type = x11atoms._NET_WM_STATE, .format = 32, .window = x11.window, .data.l = { fs ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, - x11.aNetWMStateFullscreen, + x11atoms._NET_WM_STATE_FULLSCREEN, 0 } } diff --git a/client/displayservers/X11/x11.h b/client/displayservers/X11/x11.h index 9ab2df12..105050f3 100644 --- a/client/displayservers/X11/x11.h +++ b/client/displayservers/X11/x11.h @@ -22,6 +22,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #include +#include #include "common/thread.h" #include "common/types.h" @@ -50,14 +51,6 @@ struct X11DSState Cursor blankCursor; Cursor squareCursor; - Atom aNetReqFrameExtents; - Atom aNetFrameExtents; - Atom aNetWMState; - Atom aNetWMStateFullscreen; - Atom aNetWMWindowType; - Atom aNetWMWindowTypeNormal; - Atom aWMDeleteWindow; - // XFixes vars int eventBase; int errorBase;