[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
x11.c
atoms.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 "x11.h"
#include "atoms.h"
#include <string.h>
#include <unistd.h>
@ -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);
}

View File

@ -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 <string.h>
@ -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
}
}

View File

@ -22,6 +22,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#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;