Display device handler will be used to initialize the registry. Different handlers can be implemented according to the interface, for example, via Xinerama or XRandR. With those registry data, EnumDisplayDevices, EnumDisplayMonitors and GetMonitorInfo can be built on top of it.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- v2: Supersede 162308~162314, fix xinerama primary adapter reporting, fix registry data reinit failure. v3: Rebase
dlls/winex11.drv/Makefile.in | 1 + dlls/winex11.drv/display.c | 37 ++++++++++++++++++ dlls/winex11.drv/x11drv.h | 76 ++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 dlls/winex11.drv/display.c
diff --git a/dlls/winex11.drv/Makefile.in b/dlls/winex11.drv/Makefile.in index 747f509b44..9ca2fc6efe 100644 --- a/dlls/winex11.drv/Makefile.in +++ b/dlls/winex11.drv/Makefile.in @@ -9,6 +9,7 @@ C_SRCS = \ brush.c \ clipboard.c \ desktop.c \ + display.c \ event.c \ graphics.c \ ime.c \ diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c new file mode 100644 index 0000000000..9b9009c255 --- /dev/null +++ b/dlls/winex11.drv/display.c @@ -0,0 +1,37 @@ +/* + * X11DRV display device functions + * + * Copyright 2019 Zhiyi Zhang for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include "wine/debug.h" +#include "x11drv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(x11drv); + +static struct x11drv_display_device_handler handler; + +void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *new_handler) +{ + if (new_handler->priority > handler.priority) + { + handler = *new_handler; + TRACE("Display device functions are now handled by: %s\n", handler.name); + } +} \ No newline at end of file diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index c633102a38..6aaea54fab 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -665,6 +665,82 @@ struct x11drv_mode_info *X11DRV_Settings_SetHandlers(const char *name, void X11DRV_XF86VM_Init(void) DECLSPEC_HIDDEN; void X11DRV_XRandR_Init(void) DECLSPEC_HIDDEN;
+/* X11 display device driver */ + +/* Represent a physical GPU in the PCI slots */ +struct x11drv_gpu +{ + /* ID to uniquely identify a GPU in handler */ + ULONG_PTR id; + /* Name */ + WCHAR name[128]; + /* PCI ID */ + UINT vendor_id; + UINT device_id; + UINT subsys_id; + UINT revision_id; +}; + +/* Represent an adapter in EnumDisplayDevices context */ +struct x11drv_adapter +{ + /* ID to uniquely identify an adapter in handler */ + ULONG_PTR id; + /* as StateFlags in DISPLAY_DEVICE struct */ + DWORD state_flags; +}; + +/* Represent a monitor in EnumDisplayDevices context */ +struct x11drv_monitor +{ + /* Name */ + WCHAR name[128]; + /* as RcMonitor in MONITORINFO struct */ + RECT rc_monitor; + /* as RcWork in MONITORINFO struct */ + RECT rc_work; + /* StateFlags in DISPLAY_DEVICE struct */ + DWORD state_flags; +}; + +/* Required functions for display device registry initialization */ +struct x11drv_display_device_handler +{ + /* A name to tell what host driver is used */ + CHAR name[MAX_PATH]; + + /* Higher priority can override handlers with lower proprity */ + INT priority; + + /* pGetGpus will be called to get a list of GPUs. First GPU has to be where the primary adapter is. + * + * Return FALSE on failure with parameters unchanged */ + BOOL (*pGetGpus)(struct x11drv_gpu **gpus, int *count); + + /* pGetAdapters will be called to get a list of adapters in EnumDisplayDevices context under a GPU. + * The first adapter has to be primary if GPU is primary. + * + * Return FALSE on failure with parameters unchanged */ + BOOL (*pGetAdapters)(ULONG_PTR gpu_id, struct x11drv_adapter **adapters, int *count); + + /* pGetMonitors will be called to get a list of monitors in EnumDisplayDevices context under an adapter. + * The first monitor has to be primary if adapter is primary. + * + * Return FALSE on failure with parameters unchanged */ + BOOL (*pGetMonitors)(ULONG_PTR adapter_id, struct x11drv_monitor **monitors, int *count); + + /* pFreeGpus will be called to free a GPU list from pGetGpus */ + void (*pFreeGpus)(struct x11drv_gpu *gpus); + + /* pFreeAdapters will be called to free an adapter list from pGetAdapters */ + void (*pFreeAdapters)(struct x11drv_adapter *adapters); + + /* pFreeMonitors will be called to free a monitor list from pGetMonitors */ + void (*pFreeMonitors)(struct x11drv_monitor *monitors); +}; + +extern void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *handler) DECLSPEC_HIDDEN; + /* XIM support */ extern BOOL X11DRV_InitXIM( const char *input_style ) DECLSPEC_HIDDEN; extern XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data) DECLSPEC_HIDDEN;
On Tue, May 14, 2019 at 05:48:12PM +0800, Zhiyi Zhang wrote:
Display device handler will be used to initialize the registry. Different handlers can be implemented according to the interface, for example, via Xinerama or XRandR. With those registry data, EnumDisplayDevices, EnumDisplayMonitors and GetMonitorInfo can be built on top of it.
Patches 1 and 2 contain mostly dead code; basically nothing happens until patch 3. What you want is for the first patch to do something useful (like write a bit of information to the registry) and build up from there. This may mean that the first patch is larger than ideal, but it should be possible to do it in a way that its not too big.
A more general point: I see that you have patches for Xrandr 1.4 in your tree. Do we actually care about Xinerama if we can get everything we need from Xrandr? Xrandr 1.4 is more than five years old right?
Huw.
On 5/16/19 5:33 PM, Huw Davies wrote:
On Tue, May 14, 2019 at 05:48:12PM +0800, Zhiyi Zhang wrote:
Display device handler will be used to initialize the registry. Different handlers can be implemented according to the interface, for example, via Xinerama or XRandR. With those registry data, EnumDisplayDevices, EnumDisplayMonitors and GetMonitorInfo can be built on top of it.
Patches 1 and 2 contain mostly dead code; basically nothing happens until patch 3. What you want is for the first patch to do something useful (like write a bit of information to the registry) and build up from there. This may mean that the first patch is larger than ideal, but it should be possible to do it in a way that its not too big.
Sure. I will merge it.
A more general point: I see that you have patches for Xrandr 1.4 in your tree. Do we actually care about Xinerama if we can get everything we need from Xrandr? Xrandr 1.4 is more than five years old right?
The reason why I also do it for Xinerama is in case XRandR is unavailable. Also Xinerama is currently used over XRandR when in desktop mode, I don't think we want to report multiple adapters or monitors when in desktop mode. We could only support XRandR but that would mean migrate some desktop mode code to XRandR as well and risks XRandR being unavailable.
Yes, XRandR 1.4 is more than fives years old.
Thanks, Zhiyi
Huw.