99
1010#include <sys/socket.h>
1111
12+ #include "common/properties.h"
13+
1214#include "wayland.h"
1315#include "wlr-output-management-unstable-v1-client-protocol.h"
1416#include "kde-output-device-v2-client-protocol.h"
1517#include "kde-output-order-v1-client-protocol.h"
1618#include "xdg-output-unstable-v1-client-protocol.h"
1719
1820#ifndef __FreeBSD__
19- static void waylandDetectWM (int fd , FFDisplayServerResult * result )
21+ static bool waylandDetectWM (int fd , FFDisplayServerResult * result )
2022{
2123 struct ucred ucred ;
2224 socklen_t len = sizeof (struct ucred );
2325 if (getsockopt (fd , SOL_SOCKET , SO_PEERCRED , & ucred , & len ) == -1 )
24- return ;
26+ return false ;
2527
2628 FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreate ();
2729 ffStrbufAppendF (& procPath , "/proc/%d/cmdline" , ucred .pid ); //We check the cmdline for the process name, because it is not trimmed.
2830 ffReadFileBuffer (procPath .chars , & result -> wmProcessName );
2931 ffStrbufSubstrBeforeFirstC (& result -> wmProcessName , '\0' ); //Trim the arguments
3032 ffStrbufSubstrAfterLastC (& result -> wmProcessName , '/' ); //Trim the path
33+ puts (result -> wmProcessName .chars );
34+ return true;
3135}
3236#else
3337static void waylandDetectWM (int fd , FFDisplayServerResult * result )
3438{
3539 FF_UNUSED (fd , result );
40+ return false;
3641}
3742#endif
3843
@@ -112,6 +117,67 @@ bool detectWayland(FFDisplayServerResult* result)
112117 data .ffwl_proxy_destroy (registry );
113118 ffwl_display_disconnect (data .display );
114119
120+ if (data .primaryDisplayId == 0 && result -> wmProcessName .length > 0 )
121+ {
122+ const char * fileName = ffStrbufEqualS (& result -> wmProcessName , "gnome-shell" )
123+ ? "monitors.xml"
124+ : ffStrbufEqualS (& result -> wmProcessName , "cinnamon" )
125+ ? "cinnamon-monitors.xml"
126+ : NULL ;
127+ if (fileName )
128+ {
129+ FF_STRBUF_AUTO_DESTROY monitorsXml = ffStrbufCreate ();
130+ FF_LIST_FOR_EACH (FFstrbuf , basePath , instance .state .platform .configDirs )
131+ {
132+ char path [1024 ];
133+ snprintf (path , sizeof (path ) - 1 , "%s%s" , basePath -> chars , fileName );
134+ if (ffReadFileBuffer (path , & monitorsXml ))
135+ break ;
136+ }
137+ if (monitorsXml .length )
138+ {
139+ // <monitors version="2">
140+ // <configuration>
141+ // <logicalmonitor>
142+ // <x>0</x>
143+ // <y>0</y>
144+ // <scale>1.7489879131317139</scale>
145+ // <primary>yes</primary>
146+ // <monitor>
147+ // <monitorspec>
148+ // <connector>Virtual-1</connector>
149+ // <vendor>unknown</vendor>
150+ // <product>unknown</product>
151+ // <serial>unknown</serial>
152+ // </monitorspec>
153+ // <mode>
154+ // <width>3456</width>
155+ // <height>2160</height>
156+ // <rate>60.000068664550781</rate>
157+ // </mode>
158+ // </monitor>
159+ // </logicalmonitor>
160+ // </configuration>
161+ // </monitors>
162+ uint32_t start = ffStrbufFirstIndexS (& monitorsXml , "<primary>yes</primary>" );
163+ if (start < monitorsXml .length )
164+ {
165+ start = ffStrbufNextIndexS (& monitorsXml , start , "<connector>" );
166+ if (start < monitorsXml .length )
167+ {
168+ uint32_t end = ffStrbufNextIndexS (& monitorsXml , start , "</connector>" );
169+ if (end < monitorsXml .length )
170+ {
171+ ffStrbufSubstrBefore (& monitorsXml , end );
172+ const char * name = monitorsXml .chars + start + strlen ("<connector>" );
173+ data .primaryDisplayId = ffWaylandGenerateIdFromName (name );
174+ }
175+ }
176+ }
177+ }
178+ }
179+ }
180+
115181 if (data .primaryDisplayId )
116182 {
117183 FF_LIST_FOR_EACH (FFDisplayResult , d , data .result -> displays )
@@ -134,6 +200,8 @@ bool detectWayland(FFDisplayServerResult* result)
134200void ffWaylandOutputNameListener (void * data , FF_MAYBE_UNUSED void * output , const char * name )
135201{
136202 WaylandDisplay * display = data ;
203+ if (display -> id ) return ;
204+
137205 if (ffStrStartsWith (name , "eDP-" ))
138206 display -> type = FF_DISPLAY_TYPE_BUILTIN ;
139207 else if (ffStrStartsWith (name , "HDMI-" ))
@@ -147,6 +215,8 @@ void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const
147215void ffWaylandOutputDescriptionListener (void * data , FF_MAYBE_UNUSED void * output , const char * description )
148216{
149217 WaylandDisplay * display = data ;
218+ if (display -> description .length ) return ;
219+
150220 while (* description == ' ' ) ++ description ;
151221 if (!ffStrEquals (description , "Unknown Display" ) && !ffStrContains (description , "(null)" ))
152222 ffStrbufAppendS (& display -> description , description );
0 commit comments