[client] x11: split out atoms into a seperate structure

This commit is contained in:
Geoffrey McRae 2021-03-27 10:05:57 +11:00
parent 2f14d64289
commit 84d4c18c48
6 changed files with 117 additions and 64 deletions

View File

@ -12,6 +12,7 @@ pkg_check_modules(DISPLAYSERVER_X11_PKGCONFIG REQUIRED
add_library(displayserver_X11 STATIC add_library(displayserver_X11 STATIC
x11.c x11.c
atoms.c
clipboard.c clipboard.c
) )

View File

@ -0,0 +1,30 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2021 Geoffrey McRae <geoff@hostfission.com>
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
}

View File

@ -0,0 +1,50 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2021 Geoffrey McRae <geoff@hostfission.com>
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 <X11/Xlib.h>
#define DEF_ATOM(x) Atom x;
struct X11DSAtoms
{
DEF_ATOMS()
};
#undef DEF_ATOM
extern struct X11DSAtoms x11atoms;
void X11AtomsInit(void);
#endif

View File

@ -19,6 +19,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "clipboard.h" #include "clipboard.h"
#include "x11.h" #include "x11.h"
#include "atoms.h"
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -31,11 +32,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
struct X11ClipboardState struct X11ClipboardState
{ {
Atom aSelection;
Atom aCurSelection; Atom aCurSelection;
Atom aTargets;
Atom aSelData;
Atom aIncr;
Atom aTypes[LG_CLIPBOARD_DATA_NONE]; Atom aTypes[LG_CLIPBOARD_DATA_NONE];
LG_ClipboardData type; LG_ClipboardData type;
bool haveRequest; bool haveRequest;
@ -79,7 +76,7 @@ void x11CBEventThread(const XEvent xe)
break; break;
case PropertyNotify: case PropertyNotify:
if (xe.xproperty.atom == x11cb.aSelData) if (xe.xproperty.atom == x11atoms.SEL_DATA)
{ {
if (x11cb.lowerBound == 0) if (x11cb.lowerBound == 0)
break; break;
@ -101,12 +98,7 @@ void x11CBEventThread(const XEvent xe)
bool x11CBInit() 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; x11cb.aCurSelection = BadValue;
for(int i = 0; i < LG_CLIPBOARD_DATA_NONE; ++i) for(int i = 0; i < LG_CLIPBOARD_DATA_NONE; ++i)
{ {
x11cb.aTypes[i] = XInternAtom(x11.display, atomTypes[i], False); x11cb.aTypes[i] = XInternAtom(x11.display, atomTypes[i], False);
@ -127,7 +119,7 @@ bool x11CBInit()
XFixesSelectSelectionInput(x11.display, x11.window, XFixesSelectSelectionInput(x11.display, x11.window,
XA_PRIMARY, XFixesSetSelectionOwnerNotifyMask); XA_PRIMARY, XFixesSetSelectionOwnerNotifyMask);
XFixesSelectSelectionInput(x11.display, x11.window, XFixesSelectSelectionInput(x11.display, x11.window,
x11cb.aSelection, XFixesSetSelectionOwnerNotifyMask); x11atoms.CLIPBOARD, XFixesSetSelectionOwnerNotifyMask);
return true; return true;
} }
@ -166,10 +158,10 @@ static void x11CBSelectionRequest(const XSelectionRequestEvent e)
goto nodata; goto nodata;
// target list requested // target list requested
if (e.target == x11cb.aTargets) if (e.target == x11atoms.TARGETS)
{ {
Atom targets[2]; Atom targets[2];
targets[0] = x11cb.aTargets; targets[0] = x11atoms.TARGETS;
targets[1] = x11cb.aTypes[x11cb.type]; targets[1] = x11cb.aTypes[x11cb.type];
XChangeProperty( XChangeProperty(
@ -206,7 +198,7 @@ send:
static void x11CBSelectionClear(const XSelectionClearEvent e) 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; return;
x11cb.aCurSelection = BadValue; x11cb.aCurSelection = BadValue;
@ -227,7 +219,7 @@ static void x11CBSelectionIncr(const XPropertyEvent e)
e.atom, e.atom,
0, ~0L, // start and length 0, ~0L, // start and length
True, // delete the property True, // delete the property
x11cb.aIncr, x11atoms.INCR,
&type, &type,
&format, &format,
&itemCount, &itemCount,
@ -292,7 +284,7 @@ out:
static void x11CBXFixesSelectionNotify(const XFixesSelectionNotifyEvent e) static void x11CBXFixesSelectionNotify(const XFixesSelectionNotifyEvent e)
{ {
// check if the selection is valid and it isn't ourself // 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) e.owner == x11.window || e.owner == 0)
{ {
return; return;
@ -303,8 +295,8 @@ static void x11CBXFixesSelectionNotify(const XFixesSelectionNotifyEvent e)
XConvertSelection( XConvertSelection(
x11.display, x11.display,
e.selection, e.selection,
x11cb.aTargets, x11atoms.TARGETS,
x11cb.aTargets, x11atoms.TARGETS,
x11.window, x11.window,
CurrentTime); CurrentTime);
@ -338,7 +330,7 @@ static void x11CBSelectionNotify(const XSelectionEvent e)
goto out; goto out;
} }
if (type == x11cb.aIncr) if (type == x11atoms.INCR)
{ {
x11cb.incrStart = true; x11cb.incrStart = true;
x11cb.lowerBound = *(unsigned int *)data; x11cb.lowerBound = *(unsigned int *)data;
@ -346,7 +338,7 @@ static void x11CBSelectionNotify(const XSelectionEvent e)
} }
// the target list // the target list
if (e.property == x11cb.aTargets) if (e.property == x11atoms.TARGETS)
{ {
// the format is 32-bit and we must have data // the format is 32-bit and we must have data
// this is technically incorrect however as it's // this is technically incorrect however as it's
@ -372,7 +364,7 @@ static void x11CBSelectionNotify(const XSelectionEvent e)
goto out; goto out;
} }
if (e.property == x11cb.aSelData) if (e.property == x11atoms.SEL_DATA)
{ {
LG_ClipboardData dataType; LG_ClipboardData dataType;
for(dataType = 0; dataType < LG_CLIPBOARD_DATA_NONE; ++dataType) for(dataType = 0; dataType < LG_CLIPBOARD_DATA_NONE; ++dataType)
@ -400,7 +392,7 @@ void x11CBNotice(LG_ClipboardData type)
x11cb.haveRequest = true; x11cb.haveRequest = true;
x11cb.type = type; x11cb.type = type;
XSetSelectionOwner(x11.display, XA_PRIMARY , x11.window, CurrentTime); XSetSelectionOwner(x11.display, XA_PRIMARY , x11.window, CurrentTime);
XSetSelectionOwner(x11.display, x11cb.aSelection, x11.window, CurrentTime); XSetSelectionOwner(x11.display, x11atoms.CLIPBOARD, x11.window, CurrentTime);
XFlush(x11.display); XFlush(x11.display);
} }
@ -408,7 +400,7 @@ void x11CBRelease(void)
{ {
x11cb.haveRequest = false; x11cb.haveRequest = false;
XSetSelectionOwner(x11.display, XA_PRIMARY , None, CurrentTime); XSetSelectionOwner(x11.display, XA_PRIMARY , None, CurrentTime);
XSetSelectionOwner(x11.display, x11cb.aSelection, None, CurrentTime); XSetSelectionOwner(x11.display, x11atoms.CLIPBOARD, None, CurrentTime);
XFlush(x11.display); XFlush(x11.display);
} }
@ -421,7 +413,7 @@ void x11CBRequest(LG_ClipboardData type)
x11.display, x11.display,
x11cb.aCurSelection, x11cb.aCurSelection,
x11cb.aTypes[type], x11cb.aTypes[type],
x11cb.aSelData, x11atoms.SEL_DATA,
x11.window, x11.window,
CurrentTime); CurrentTime);
} }

View File

@ -20,6 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "interface/displayserver.h" #include "interface/displayserver.h"
#include "x11.h" #include "x11.h"
#include "atoms.h"
#include "clipboard.h" #include "clipboard.h"
#include <string.h> #include <string.h>
@ -145,31 +146,17 @@ static bool x11Init(const LG_DSInitParams params)
free(hint.res_name); free(hint.res_name);
free(hint.res_class); free(hint.res_class);
x11.aNetReqFrameExtents = X11AtomsInit();
XInternAtom(x11.display, "_NET_REQUEST_FRAME_EXTENTS", True); XSetWMProtocols(x11.display, x11.window, &x11atoms.WM_DELETE_WINDOW, 1);
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);
XChangeProperty( XChangeProperty(
x11.display, x11.display,
x11.window, x11.window,
x11.aNetWMWindowType, x11atoms._NET_WM_WINDOW_TYPE,
XA_ATOM, XA_ATOM,
32, 32,
PropModeReplace, PropModeReplace,
(unsigned char *)&x11.aNetWMWindowTypeNormal, (unsigned char *)&x11atoms._NET_WM_WINDOW_TYPE_NORMAL,
1 1
); );
@ -178,16 +165,16 @@ static bool x11Init(const LG_DSInitParams params)
XChangeProperty( XChangeProperty(
x11.display, x11.display,
x11.window, x11.window,
x11.aNetWMState, x11atoms._NET_WM_STATE,
XA_ATOM, XA_ATOM,
32, 32,
PropModeReplace, PropModeReplace,
(unsigned char *)&x11.aNetWMStateFullscreen, (unsigned char *)&x11atoms._NET_WM_STATE_FULLSCREEN,
1 1
); );
} }
if (x11.aNetReqFrameExtents) if (x11atoms._NET_REQUEST_FRAME_EXTENTS)
{ {
XEvent reqevent = XEvent reqevent =
{ {
@ -196,7 +183,7 @@ static bool x11Init(const LG_DSInitParams params)
.type = ClientMessage, .type = ClientMessage,
.window = x11.window, .window = x11.window,
.format = 32, .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) switch(xe.type)
{ {
case ClientMessage: case ClientMessage:
if (xe.xclient.data.l[0] == x11.aWMDeleteWindow) if (xe.xclient.data.l[0] == x11atoms.WM_DELETE_WINDOW)
app_handleCloseEvent(); app_handleCloseEvent();
break; break;
@ -526,7 +513,7 @@ static int x11EventThread(void * unused)
xe.xproperty.state != PropertyNewValue) xe.xproperty.state != PropertyNewValue)
continue; continue;
if (xe.xproperty.atom == x11.aNetWMState) if (xe.xproperty.atom == x11atoms._NET_WM_STATE)
{ {
Atom type; Atom type;
int fmt; int fmt;
@ -534,7 +521,7 @@ static int x11EventThread(void * unused)
unsigned char *data; unsigned char *data;
if (XGetWindowProperty(x11.display, x11.window, 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) &type, &fmt, &num, &bytes, &data) != Success)
break; break;
@ -542,7 +529,7 @@ static int x11EventThread(void * unused)
for(int i = 0; i < num; ++i) for(int i = 0; i < num; ++i)
{ {
Atom prop = ((Atom *)data)[i]; Atom prop = ((Atom *)data)[i];
if (prop == x11.aNetWMStateFullscreen) if (prop == x11atoms._NET_WM_STATE_FULLSCREEN)
fullscreen = true; fullscreen = true;
} }
@ -551,7 +538,7 @@ static int x11EventThread(void * unused)
break; break;
} }
if (xe.xproperty.atom == x11.aNetFrameExtents) if (xe.xproperty.atom == x11atoms._NET_FRAME_EXTENTS)
{ {
Atom type; Atom type;
int fmt; int fmt;
@ -559,7 +546,7 @@ static int x11EventThread(void * unused)
unsigned char *data; unsigned char *data;
if (XGetWindowProperty(x11.display, x11.window, 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) &type, &fmt, &num, &bytes, &data) != Success)
break; break;
@ -1052,12 +1039,12 @@ static void x11SetFullscreen(bool fs)
.xclient = { .xclient = {
.type = ClientMessage, .type = ClientMessage,
.send_event = true, .send_event = true,
.message_type = x11.aNetWMState, .message_type = x11atoms._NET_WM_STATE,
.format = 32, .format = 32,
.window = x11.window, .window = x11.window,
.data.l = { .data.l = {
fs ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, fs ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE,
x11.aNetWMStateFullscreen, x11atoms._NET_WM_STATE_FULLSCREEN,
0 0
} }
} }

View File

@ -22,6 +22,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/Xutil.h>
#include "common/thread.h" #include "common/thread.h"
#include "common/types.h" #include "common/types.h"
@ -50,14 +51,6 @@ struct X11DSState
Cursor blankCursor; Cursor blankCursor;
Cursor squareCursor; Cursor squareCursor;
Atom aNetReqFrameExtents;
Atom aNetFrameExtents;
Atom aNetWMState;
Atom aNetWMStateFullscreen;
Atom aNetWMWindowType;
Atom aNetWMWindowTypeNormal;
Atom aWMDeleteWindow;
// XFixes vars // XFixes vars
int eventBase; int eventBase;
int errorBase; int errorBase;