Skip to content

Commit 5f1cb16

Browse files
committed
Display (Linux): support primary display detection for KDE
1 parent 013320b commit 5f1cb16

File tree

8 files changed

+220
-3
lines changed

8 files changed

+220
-3
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ if(LINUX)
433433
src/detection/displayserver/linux/wayland/kde-output.c
434434
src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c
435435
src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c
436+
src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c
436437
src/detection/displayserver/linux/wmde.c
437438
src/detection/displayserver/linux/xcb.c
438439
src/detection/displayserver/linux/xlib.c
@@ -568,6 +569,7 @@ elseif(BSD)
568569
src/detection/displayserver/linux/wayland/kde-output.c
569570
src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c
570571
src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c
572+
src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c
571573
src/detection/displayserver/linux/wmde.c
572574
src/detection/displayserver/linux/xcb.c
573575
src/detection/displayserver/linux/xlib.c
@@ -771,6 +773,7 @@ elseif(SunOS)
771773
src/detection/displayserver/linux/wayland/kde-output.c
772774
src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c
773775
src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c
776+
src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c
774777
src/detection/displayserver/linux/wmde.c
775778
src/detection/displayserver/linux/xcb.c
776779
src/detection/displayserver/linux/xlib.c

src/detection/displayserver/linux/wayland/global-output.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
124124
: &display.name,
125125
display.type,
126126
false,
127-
0
127+
display.id
128128
);
129129

130130
ffStrbufDestroy(&display.description);
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/* Generated by wayland-scanner 1.22.0 */
2+
3+
#ifndef KDE_OUTPUT_ORDER_V1_CLIENT_PROTOCOL_H
4+
#define KDE_OUTPUT_ORDER_V1_CLIENT_PROTOCOL_H
5+
6+
#include <stdint.h>
7+
#include <stddef.h>
8+
#include "wayland-client.h"
9+
10+
#ifdef __cplusplus
11+
extern "C" {
12+
#endif
13+
14+
/**
15+
* @page page_kde_output_order_v1 The kde_output_order_v1 protocol
16+
* @section page_ifaces_kde_output_order_v1 Interfaces
17+
* - @subpage page_iface_kde_output_order_v1 - announce order of outputs
18+
* @section page_copyright_kde_output_order_v1 Copyright
19+
* <pre>
20+
*
21+
* SPDX-FileCopyrightText: 2022 Xaver Hugl <[email protected]>
22+
*
23+
* SPDX-License-Identifier: MIT-CMU
24+
* </pre>
25+
*/
26+
struct kde_output_order_v1;
27+
28+
#ifndef KDE_OUTPUT_ORDER_V1_INTERFACE
29+
#define KDE_OUTPUT_ORDER_V1_INTERFACE
30+
/**
31+
* @page page_iface_kde_output_order_v1 kde_output_order_v1
32+
* @section page_iface_kde_output_order_v1_desc Description
33+
*
34+
* Announce the order in which desktop environment components should be placed on outputs.
35+
* The compositor will send the list of outputs when the global is bound and whenever there is a change.
36+
* @section page_iface_kde_output_order_v1_api API
37+
* See @ref iface_kde_output_order_v1.
38+
*/
39+
/**
40+
* @defgroup iface_kde_output_order_v1 The kde_output_order_v1 interface
41+
*
42+
* Announce the order in which desktop environment components should be placed on outputs.
43+
* The compositor will send the list of outputs when the global is bound and whenever there is a change.
44+
*/
45+
extern const struct wl_interface kde_output_order_v1_interface;
46+
#endif
47+
48+
/**
49+
* @ingroup iface_kde_output_order_v1
50+
* @struct kde_output_order_v1_listener
51+
*/
52+
struct kde_output_order_v1_listener {
53+
/**
54+
* output name
55+
*
56+
* Specifies the output identified by their wl_output.name.
57+
* @param output_name the name of the output
58+
*/
59+
void (*output)(void *data,
60+
struct kde_output_order_v1 *kde_output_order_v1,
61+
const char *output_name);
62+
/**
63+
* done
64+
*
65+
* Specifies that the output list is complete. On the next output
66+
* event, a new list begins.
67+
*/
68+
void (*done)(void *data,
69+
struct kde_output_order_v1 *kde_output_order_v1);
70+
};
71+
72+
/**
73+
* @ingroup iface_kde_output_order_v1
74+
*/
75+
static inline int
76+
kde_output_order_v1_add_listener(struct kde_output_order_v1 *kde_output_order_v1,
77+
const struct kde_output_order_v1_listener *listener, void *data)
78+
{
79+
return wl_proxy_add_listener((struct wl_proxy *) kde_output_order_v1,
80+
(void (**)(void)) listener, data);
81+
}
82+
83+
#define KDE_OUTPUT_ORDER_V1_DESTROY 0
84+
85+
/**
86+
* @ingroup iface_kde_output_order_v1
87+
*/
88+
#define KDE_OUTPUT_ORDER_V1_OUTPUT_SINCE_VERSION 1
89+
/**
90+
* @ingroup iface_kde_output_order_v1
91+
*/
92+
#define KDE_OUTPUT_ORDER_V1_DONE_SINCE_VERSION 1
93+
94+
/**
95+
* @ingroup iface_kde_output_order_v1
96+
*/
97+
#define KDE_OUTPUT_ORDER_V1_DESTROY_SINCE_VERSION 1
98+
99+
/** @ingroup iface_kde_output_order_v1 */
100+
static inline void
101+
kde_output_order_v1_set_user_data(struct kde_output_order_v1 *kde_output_order_v1, void *user_data)
102+
{
103+
wl_proxy_set_user_data((struct wl_proxy *) kde_output_order_v1, user_data);
104+
}
105+
106+
/** @ingroup iface_kde_output_order_v1 */
107+
static inline void *
108+
kde_output_order_v1_get_user_data(struct kde_output_order_v1 *kde_output_order_v1)
109+
{
110+
return wl_proxy_get_user_data((struct wl_proxy *) kde_output_order_v1);
111+
}
112+
113+
static inline uint32_t
114+
kde_output_order_v1_get_version(struct kde_output_order_v1 *kde_output_order_v1)
115+
{
116+
return wl_proxy_get_version((struct wl_proxy *) kde_output_order_v1);
117+
}
118+
119+
/**
120+
* @ingroup iface_kde_output_order_v1
121+
*/
122+
static inline void
123+
kde_output_order_v1_destroy(struct kde_output_order_v1 *kde_output_order_v1)
124+
{
125+
wl_proxy_marshal_flags((struct wl_proxy *) kde_output_order_v1,
126+
KDE_OUTPUT_ORDER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) kde_output_order_v1), WL_MARSHAL_FLAG_DESTROY);
127+
}
128+
129+
#ifdef __cplusplus
130+
}
131+
#endif
132+
133+
#endif
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#ifdef FF_HAVE_WAYLAND
2+
3+
/* Generated by wayland-scanner 1.22.0 */
4+
5+
/*
6+
* SPDX-FileCopyrightText: 2022 Xaver Hugl <[email protected]>
7+
*
8+
* SPDX-License-Identifier: MIT-CMU
9+
*/
10+
11+
#include <stdlib.h>
12+
#include <stdint.h>
13+
#include "wayland-util.h"
14+
15+
16+
static const struct wl_interface *kde_output_order_v1_types[] = {
17+
NULL,
18+
};
19+
20+
static const struct wl_message kde_output_order_v1_requests[] = {
21+
{ "destroy", "", kde_output_order_v1_types + 0 },
22+
};
23+
24+
static const struct wl_message kde_output_order_v1_events[] = {
25+
{ "output", "s", kde_output_order_v1_types + 0 },
26+
{ "done", "", kde_output_order_v1_types + 0 },
27+
};
28+
29+
WL_EXPORT const struct wl_interface kde_output_order_v1_interface = {
30+
"kde_output_order_v1", 1,
31+
1, kde_output_order_v1_requests,
32+
2, kde_output_order_v1_events,
33+
};
34+
35+
#endif

src/detection/displayserver/linux/wayland/kde-output.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "wayland.h"
44
#include "kde-output-device-v2-client-protocol.h"
5+
#include "kde-output-order-v1-client-protocol.h"
56
#include "util/edidHelper.h"
67
#include "util/base64.h"
78

@@ -214,12 +215,36 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry,
214215
: &display.name,
215216
display.type,
216217
false,
217-
0
218+
display.id
218219
);
219220

220221
ffStrbufDestroy(&display.description);
221222
ffStrbufDestroy(&display.name);
222223
ffStrbufDestroy(&display.edidName);
223224
}
224225

226+
227+
static void waylandKdeOutputOrderListener(void *data, FF_MAYBE_UNUSED struct kde_output_order_v1 *_, const char *output_name)
228+
{
229+
uint64_t* id = (uint64_t*) data;
230+
if (*id == 0)
231+
strncpy((char*) id, output_name, sizeof(*id));
232+
}
233+
234+
void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
235+
{
236+
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &kde_output_order_v1_interface, version, name, kde_output_order_v1_interface.name, version, NULL);
237+
if(output == NULL)
238+
return;
239+
240+
struct kde_output_order_v1_listener orderListener = {
241+
.output = waylandKdeOutputOrderListener,
242+
.done = (void*) stubListener,
243+
};
244+
245+
wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &orderListener, &wldata->primaryDisplayId);
246+
wldata->ffwl_display_roundtrip(wldata->display);
247+
wldata->ffwl_proxy_destroy(output);
248+
}
249+
225250
#endif

src/detection/displayserver/linux/wayland/wayland.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "wayland.h"
1313
#include "wlr-output-management-unstable-v1-client-protocol.h"
1414
#include "kde-output-device-v2-client-protocol.h"
15+
#include "kde-output-order-v1-client-protocol.h"
1516

1617
#ifndef __FreeBSD__
1718
static void waylandDetectWM(int fd, FFDisplayServerResult* result)
@@ -53,6 +54,10 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u
5354
wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_KDE;
5455
ffWaylandHandleKdeOutput(wldata, registry, name, version);
5556
}
57+
else if(ffStrEquals(interface, kde_output_order_v1_interface.name))
58+
{
59+
ffWaylandHandleKdeOutputOrder(wldata, registry, name, version);
60+
}
5661
}
5762

5863
bool detectWayland(FFDisplayServerResult* result)
@@ -99,6 +104,18 @@ bool detectWayland(FFDisplayServerResult* result)
99104
data.ffwl_proxy_destroy(registry);
100105
ffwl_display_disconnect(data.display);
101106

107+
if(data.primaryDisplayId)
108+
{
109+
FF_LIST_FOR_EACH(FFDisplayResult, d, data.result->displays)
110+
{
111+
if(d->id == data.primaryDisplayId)
112+
{
113+
d->primary = true;
114+
break;
115+
}
116+
}
117+
}
118+
102119
//We successfully connected to wayland and detected the display.
103120
//So we can set set the session type to wayland.
104121
//This is used as an indicator that we are running wayland by the x11 backends.
@@ -115,6 +132,7 @@ void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const
115132
display->type = FF_DISPLAY_TYPE_EXTERNAL;
116133
if (!display->edidName.length)
117134
ffdsMatchDrmConnector(name, &display->edidName);
135+
strncpy((char*) &display->id, name, sizeof(display->id));
118136
ffStrbufAppendS(&display->name, name);
119137
}
120138

src/detection/displayserver/linux/wayland/wayland.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ typedef struct WaylandData
2727
struct wl_display* display;
2828
const struct wl_interface* ffwl_output_interface;
2929
WaylandProtocolType protocolType;
30+
uint64_t primaryDisplayId;
3031
} WaylandData;
3132

3233
typedef struct WaylandDisplay
@@ -41,6 +42,7 @@ typedef struct WaylandDisplay
4142
FFstrbuf name;
4243
FFstrbuf description;
4344
FFstrbuf edidName;
45+
uint64_t id;
4446
void* internal;
4547
} WaylandDisplay;
4648

@@ -55,5 +57,6 @@ void ffWaylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED void* output
5557
void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
5658
void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
5759
void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
60+
void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
5861

5962
#endif

src/detection/displayserver/linux/wayland/zwlr-output.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output
160160
: &display.name,
161161
display.type,
162162
false,
163-
0
163+
display.id
164164
);
165165

166166
ffStrbufDestroy(&display.description);

0 commit comments

Comments
 (0)