12to11/atoms.c
hujianwei 2979979633 Implement xdg-activation-v1
* 12to11-test.xml (test_surface): <activated>: New event.
* 12to11.c (XLMain): Initialize XDG activation.
* Imakefile (SRCS, OBJS): Add xdg_activation.c and
xdg_activation.o.
(xdg-activation-v1): New scanner target.
* atoms.c (names, XLInitAtoms): New atom `_NET_ACTIVE_WINDOW'.
Adjust accordingly.
* compositor.h (struct _RoleFuncs): New function `activate'.
(struct _XdgRoleImplementationFuncs): Likewise.
* seat.c (XLSeatCheckActivationSerial): New function.
* test.c (Activate): New function.
(GetTestSurface): Attach new hook.
* tests/Imakefile (OBJS13, SRCS13): Add xdg_activation_test.c/o.
(xdg-activation-v1): New scanner target.
(PROGRAMS): Add xdg_activation_test.
(xdg_activation_test): New program target.
* tests/run_tests.sh (standard_tests): Add xdg_activation_test.
* tests/svnignore.txt: Add xdg_activation_test.
* xdg_surface.c (Activate): New function.
(XLGetXdgSurface): Attach hook.
* xdg_toplevel.c (Activate): New function.
(XLGetXdgToplevel): Attach hook.
2022-11-14 06:05:23 +00:00

306 lines
8.7 KiB
C

/* Wayland compositor running on top of an X server.
Copyright (C) 2022 to various contributors.
This file is part of 12to11.
12to11 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 3 of the License, or (at your
option) any later version.
12to11 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 12to11. If not, see <https://www.gnu.org/licenses/>. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "compositor.h"
#define AtomTableSize 256
typedef struct _AtomTable AtomTable;
/* This is automatically generated by mime4.awk. */
Atom DirectTransferAtoms;
/* Simple hash table for atoms. */
struct _AtomTable
{
/* Atom array indexed by table size. */
Atom *atoms[AtomTableSize];
/* Atom name array indexed by table size. */
char **names[AtomTableSize];
/* Size of each array. */
ptrdiff_t atoms_length[AtomTableSize];
};
/* Array of all atom names. */
static const char *names[] =
{
"_NET_WM_OPAQUE_REGION",
"_XL_BUFFER_RELEASE",
"_NET_WM_SYNC_REQUEST_COUNTER",
"_NET_WM_FRAME_DRAWN",
"WM_DELETE_WINDOW",
"WM_PROTOCOLS",
"_NET_SUPPORTING_WM_CHECK",
"_NET_SUPPORTED",
"_NET_WM_SYNC_REQUEST",
"_MOTIF_WM_HINTS",
"_NET_WM_STATE_MAXIMIZED_VERT",
"_NET_WM_STATE_MAXIMIZED_HORZ",
"_NET_WM_STATE_FOCUSED",
"_NET_WM_STATE_FULLSCREEN",
"_NET_WM_STATE",
"_NET_WM_MOVERESIZE",
"_GTK_FRAME_EXTENTS",
"WM_TRANSIENT_FOR",
"_XL_DMA_BUF_CREATED",
"_GTK_SHOW_WINDOW_MENU",
"_NET_WM_ALLOWED_ACTIONS",
"_NET_WM_ACTION_FULLSCREEN",
"_NET_WM_ACTION_MAXIMIZE_HORZ",
"_NET_WM_ACTION_MAXIMIZE_VERT",
"_NET_WM_ACTION_MINIMIZE",
"INCR",
"CLIPBOARD",
"TARGETS",
"UTF8_STRING",
"_XL_SERVER_TIME_ATOM",
"MULTIPLE",
"TIMESTAMP",
"ATOM_PAIR",
"_NET_WM_NAME",
"WM_NAME",
"MANAGER",
"_XSETTINGS_SETTINGS",
"libinput Scroll Methods Available",
"XdndAware",
"XdndSelection",
"XdndTypeList",
"XdndActionCopy",
"XdndActionMove",
"XdndActionLink",
"XdndActionAsk",
"XdndActionPrivate",
"XdndActionList",
"XdndActionDescription",
"XdndProxy",
"XdndEnter",
"XdndPosition",
"XdndStatus",
"XdndLeave",
"XdndDrop",
"XdndFinished",
"_NET_WM_FRAME_TIMINGS",
"_NET_WM_BYPASS_COMPOSITOR",
"WM_STATE",
"_NET_WM_WINDOW_TYPE",
"_NET_WM_WINDOW_TYPE_MENU",
"_NET_WM_WINDOW_TYPE_DND",
"CONNECTOR_ID",
"_NET_WM_PID",
"_NET_WM_PING",
"libinput Scrolling Pixel Distance",
"_NET_ACTIVE_WINDOW",
/* These are automatically generated from mime.txt. */
DirectTransferAtomNames
};
Atom _NET_WM_OPAQUE_REGION, _XL_BUFFER_RELEASE, _NET_WM_SYNC_REQUEST_COUNTER,
_NET_WM_FRAME_DRAWN, WM_DELETE_WINDOW, WM_PROTOCOLS,
_NET_SUPPORTING_WM_CHECK, _NET_SUPPORTED, _NET_WM_SYNC_REQUEST,
_MOTIF_WM_HINTS, _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ,
_NET_WM_STATE_FOCUSED, _NET_WM_STATE_FULLSCREEN, _NET_WM_STATE,
_NET_WM_MOVERESIZE, _GTK_FRAME_EXTENTS, WM_TRANSIENT_FOR,
_XL_DMA_BUF_CREATED, _GTK_SHOW_WINDOW_MENU, _NET_WM_ALLOWED_ACTIONS,
_NET_WM_ACTION_FULLSCREEN, _NET_WM_ACTION_MAXIMIZE_HORZ,
_NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_MINIMIZE, INCR, CLIPBOARD,
TARGETS, UTF8_STRING, _XL_SERVER_TIME_ATOM, MULTIPLE, TIMESTAMP, ATOM_PAIR,
_NET_WM_NAME, WM_NAME, MANAGER, _XSETTINGS_SETTINGS,
libinput_Scroll_Methods_Available, XdndAware, XdndSelection, XdndTypeList,
XdndActionCopy, XdndActionMove, XdndActionLink, XdndActionAsk,
XdndActionPrivate, XdndActionList, XdndActionDescription, XdndProxy,
XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop, XdndFinished,
_NET_WM_FRAME_TIMINGS, _NET_WM_BYPASS_COMPOSITOR, WM_STATE,
_NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_MENU, _NET_WM_WINDOW_TYPE_DND,
CONNECTOR_ID, _NET_WM_PID, _NET_WM_PING, libinput_Scrolling_Pixel_Distance,
_NET_ACTIVE_WINDOW;
XrmQuark resource_quark, app_quark, QString;
/* Hash table containing atoms. */
static AtomTable atom_table;
static unsigned int
HashAtomString (const char *string)
{
unsigned int i;
i = 3323198485ul;
for (; *string; ++string)
{
i ^= *string;
i *= 0x5bd1e995;
i ^= i >> 15;
}
return i;
}
Atom
InternAtom (const char *name)
{
Atom atom;
unsigned int hash;
ptrdiff_t bucket_length, i;
hash = HashAtomString (name) % AtomTableSize;
bucket_length = atom_table.atoms_length[hash];
for (i = 0; i < bucket_length; ++i)
{
if (!strcmp (atom_table.names[hash][i], name))
return atom_table.atoms[hash][i];
}
atom = XInternAtom (compositor.display, name, False);
atom_table.atoms_length[hash] = ++bucket_length;
atom_table.names[hash]
= XLRealloc (atom_table.names[hash],
bucket_length * sizeof *atom_table.names);
atom_table.atoms[hash]
= XLRealloc (atom_table.atoms[hash],
bucket_length * sizeof *atom_table.atoms);
atom_table.names[hash][bucket_length - 1] = XLStrdup (name);
atom_table.atoms[hash][bucket_length - 1] = atom;
return atom;
}
void
ProvideAtom (const char *name, Atom atom)
{
unsigned int hash;
ptrdiff_t bucket_length, i;
hash = HashAtomString (name) % AtomTableSize;
bucket_length = atom_table.atoms_length[hash];
for (i = 0; i < bucket_length; ++i)
{
if (!strcmp (atom_table.names[hash][i], name))
/* The atom already exists; there is no need to update it. */
return;
}
atom_table.atoms_length[hash] = ++bucket_length;
atom_table.names[hash]
= XLRealloc (atom_table.names[hash],
bucket_length * sizeof *atom_table.names);
atom_table.atoms[hash]
= XLRealloc (atom_table.atoms[hash],
bucket_length * sizeof *atom_table.atoms);
atom_table.names[hash][bucket_length - 1] = XLStrdup (name);
atom_table.atoms[hash][bucket_length - 1] = atom;
}
void
XLInitAtoms (void)
{
Atom atoms[ArrayElements (names)];
if (!XInternAtoms (compositor.display, (char **) names,
ArrayElements (names), False,
atoms))
{
fprintf (stderr, "Failed to intern X atoms\n");
exit (1);
}
_NET_WM_OPAQUE_REGION = atoms[0];
_XL_BUFFER_RELEASE = atoms[1];
_NET_WM_SYNC_REQUEST_COUNTER = atoms[2];
_NET_WM_FRAME_DRAWN = atoms[3];
WM_DELETE_WINDOW = atoms[4];
WM_PROTOCOLS = atoms[5];
_NET_SUPPORTING_WM_CHECK = atoms[6];
_NET_SUPPORTED = atoms[7];
_NET_WM_SYNC_REQUEST = atoms[8];
_MOTIF_WM_HINTS = atoms[9];
_NET_WM_STATE_MAXIMIZED_VERT = atoms[10];
_NET_WM_STATE_MAXIMIZED_HORZ = atoms[11];
_NET_WM_STATE_FOCUSED = atoms[12];
_NET_WM_STATE_FULLSCREEN = atoms[13];
_NET_WM_STATE = atoms[14];
_NET_WM_MOVERESIZE = atoms[15];
_GTK_FRAME_EXTENTS = atoms[16];
WM_TRANSIENT_FOR = atoms[17];
_XL_DMA_BUF_CREATED = atoms[18];
_GTK_SHOW_WINDOW_MENU = atoms[19];
_NET_WM_ALLOWED_ACTIONS = atoms[20];
_NET_WM_ACTION_FULLSCREEN = atoms[21];
_NET_WM_ACTION_MAXIMIZE_HORZ = atoms[22];
_NET_WM_ACTION_MAXIMIZE_VERT = atoms[23];
_NET_WM_ACTION_MINIMIZE = atoms[24];
INCR = atoms[25];
CLIPBOARD = atoms[26];
TARGETS = atoms[27];
UTF8_STRING = atoms[28];
_XL_SERVER_TIME_ATOM = atoms[29];
MULTIPLE = atoms[30];
TIMESTAMP = atoms[31];
ATOM_PAIR = atoms[32];
_NET_WM_NAME = atoms[33];
WM_NAME = atoms[34];
MANAGER = atoms[35];
_XSETTINGS_SETTINGS = atoms[36];
libinput_Scroll_Methods_Available = atoms[37];
XdndAware = atoms[38];
XdndSelection = atoms[39];
XdndTypeList = atoms[40];
XdndActionCopy = atoms[41];
XdndActionMove = atoms[42];
XdndActionLink = atoms[43];
XdndActionAsk = atoms[44];
XdndActionPrivate = atoms[45];
XdndActionList = atoms[46];
XdndActionDescription = atoms[47];
XdndProxy = atoms[48];
XdndEnter = atoms[49];
XdndPosition = atoms[50];
XdndStatus = atoms[51];
XdndLeave = atoms[52];
XdndDrop = atoms[53];
XdndFinished = atoms[54];
_NET_WM_FRAME_TIMINGS = atoms[55];
_NET_WM_BYPASS_COMPOSITOR = atoms[56];
WM_STATE = atoms[57];
_NET_WM_WINDOW_TYPE = atoms[58];
_NET_WM_WINDOW_TYPE_MENU = atoms[59];
_NET_WM_WINDOW_TYPE_DND = atoms[60];
CONNECTOR_ID = atoms[61];
_NET_WM_PID = atoms[62];
_NET_WM_PING = atoms[63];
libinput_Scrolling_Pixel_Distance = atoms[64];
_NET_ACTIVE_WINDOW = atoms[65];
/* This is automatically generated. */
DirectTransferAtomInit (atoms, 66);
/* Now, initialize quarks. */
resource_quark = XrmPermStringToQuark (compositor.resource_name);
app_quark = XrmPermStringToQuark (compositor.app_name);
QString = XrmPermStringToQuark ("String");
}