<html><body><div style="font-family: times new roman, new york, times, serif; font-size: 12pt; color: #000000"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Aug 18, 2016 at 6:48 PM, Frediano Ziglio <span dir="ltr"><<a href="mailto:fziglio@redhat.com" target="_blank">fziglio@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">><br>
> The Direct3D 9 API operates on either the Windows XP display driver<br>
> model (XPDM) or the Windows Vista display driver model (WDDM), depending<br>
> on the operating system installed.<br>
><br>
> This patch implements the WDDM interface while using the CCD API to do<br>
> so. Moreover it introduces multiple monitors support and arbitrary<br>
> resolution for Windows 10 while preserving backward compatiblity with<br>
> previous versions of Windows.<br>
><br>
> Based on a patch by Sandy Stutsman <sstutsma at <a href="http://redhat.com" rel="noreferrer" target="_blank">redhat.com</a>><br>
><br>
> Signed-off-by: Dmitry Fleytman <dfleytma at <a href="http://redhat.com" rel="noreferrer" target="_blank">redhat.com</a>><br>
> Signed-off-by: Sameeh Jubran <<a href="mailto:sameeh@daynix.com" target="_blank">sameeh@daynix.com</a>><br>
> ---<br>
>  vdagent/display_configuration.cpp | 346<br>
>  +++++++++++++++++++++++++++++++++++++-<br>
>  vdagent/display_configuration.h   |  47 ++++++<br>
>  2 files changed, 392 insertions(+), 1 deletion(-)<br>
><br>
<br>
</span>Missing changes however looking at the code I understood that<br>
now the ABI is as was before and you are using some malloc/free.<br>
So the protocol change is not needed.<br>
I prefer the version before you decided to introduce the protocol<br>
change.<br></blockquote><div><br></div><div>Can you please provide me the patch number that you preferred?</div><div>Beside the malloc/free, what's wrong with this version?</div></div></div></div></blockquote><div><br></div><div><div>I personally like v7 version, I would just add this patch</div><div><br></div><div><br></div><div>diff --git a/vdagent/display_configuration.cpp b/vdagent/display_configuration.cpp<br>index 1504a60..9cc39ae 100644<br>--- a/vdagent/display_configuration.cpp<br>+++ b/vdagent/display_configuration.cpp<br>@@ -17,6 +17,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.<br> <br> #include "display_configuration.h"<br> #include <winternl.h><br>+#include <spice/macros.h><br> <br> /* The following definitions and structures are taken<br> from the wine project repository and can be found<br>@@ -631,7 +632,7 @@ D3D_HANDLE WDDMInterface::handle_from_GDI_name(LPCTSTR adapter_name)<br>     NTSTATUS status;<br> <br>     ZeroMemory(&gdi_display_name, sizeof(gdi_display_name));<br>-    wcsncpy(gdi_display_name.DeviceName, adapter_name, sizeof(TCHAR)* CCHDEVICENAME);<br>+    wcsncpy(gdi_display_name.DeviceName, adapter_name, SPICE_N_ELEMENTS(gdi_display_name.DeviceName));<br> <br>     if (NT_SUCCESS(status = _pfnOpen_adapter_gdi_name(&gdi_display_name))) {<br>         return  gdi_display_name.hAdapter;<br><br></div><div>which fixes a potential buffer overflow (wcsncpy require number of characters, not bytes)</div><div><br></div><div><br></div><div>Other versions rely on QXL_ESCAPE which was removed or v10 which is the latest.<br></div><div>I don't like malloc/free as they does not fit with the current style, are not exception safe and</div><div>are heavy for small static structure allocations.<br></div><div><br></div>Frediano</div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="HOEnZb"><span style="color: #888888;" data-mce-style="color: #888888;" color="#888888"><br>
Frediano<br>
</span></span><div class="HOEnZb"><div class="h5"><br>
> diff --git a/vdagent/display_configuration.cpp<br>
> b/vdagent/display_configuration.cpp<br>
> index 01fdbb0..bab4c95 100644<br>
> --- a/vdagent/display_configuration.cpp<br>
> +++ b/vdagent/display_configuration.cpp<br>
> @@ -153,6 +153,56 @@ struct DISPLAYCONFIG_PATH_INFO {<br>
>      UINT32 flags;<br>
>  };<br>
><br>
> +/* The following definitions and structures are taken<br>
> + * from here<br>
> <a href="https://github.com/notr1ch/DWMCapture/blob/master/DWMCaptureSource.cpp" rel="noreferrer" target="_blank">https://github.com/notr1ch/DWMCapture/blob/master/DWMCaptureSource.cpp</a> */<br>
> +<br>
> +enum D3DKMT_ESCAPETYPE {<br>
> +    D3DKMT_ESCAPE_DRIVERPRIVATE = 0<br>
> +};<br>
> +<br>
> +struct D3DDDI_ESCAPEFLAGS {<br>
> +    union {<br>
> +        struct {<br>
> +            UINT    Reserved : 31;<br>
> +        };<br>
> +        UINT        Value;<br>
> +    };<br>
> +};<br>
> +<br>
> +struct D3DKMT_ESCAPE {<br>
> +    D3D_HANDLE hAdapter;<br>
> +    D3D_HANDLE hDevice;<br>
> +    D3DKMT_ESCAPETYPE Type;<br>
> +    D3DDDI_ESCAPEFLAGS Flags;<br>
> +    VOID* pPrivateDriverData;<br>
> +    UINT PrivateDriverDataSize;<br>
> +    D3D_HANDLE hContext;<br>
> +};<br>
> +<br>
> +struct D3DKMT_OPENADAPTERFROMHDC {<br>
> +    HDC hDc;<br>
> +    D3D_HANDLE hAdapter;<br>
> +    LUID AdapterLuid;<br>
> +    UINT VidPnSourceId;<br>
> +};<br>
> +<br>
> +struct D3DKMT_CLOSEADAPTER {<br>
> +    D3D_HANDLE hAdapter;<br>
> +};<br>
> +<br>
> +struct D3DKMT_OPENADAPTERFROMDEVICENAME {<br>
> +    const WCHAR *pDeviceName;<br>
> +    D3D_HANDLE hAdapter;<br>
> +    LUID AdapterLuid;<br>
> +};<br>
> +<br>
> +struct D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME {<br>
> +    WCHAR DeviceName[32];<br>
> +    D3D_HANDLE hAdapter;<br>
> +    LUID AdapterLuid;<br>
> +    UINT VidPnSourceId;<br>
> +};<br>
> +<br>
>  struct QXLMonitorEscape {<br>
>      QXLMonitorEscape(DEVMODE* dev_mode)<br>
>      {<br>
> @@ -178,7 +228,14 @@ struct QxlCustomEscapeObj : public<br>
> QXLEscapeSetCustomDisplay {<br>
>  DisplayConfig* DisplayConfig::create_config()<br>
>  {<br>
>      DisplayConfig* new_interface;<br>
> -    new_interface = new XPDMInterface();<br>
> +    /* Try to open a WDDM adapter.<br>
> +    If that failed, assume we have an XPDM driver */<br>
> +    try {<br>
> +        new_interface = new  WDDMInterface();<br>
> +    }<br>
> +    catch (std::exception& e) {<br>
> +        new_interface = new XPDMInterface();<br>
> +    }<br>
>      return new_interface;<br>
>  }<br>
><br>
> @@ -328,6 +385,293 @@ bool XPDMInterface::find_best_mode(LPCTSTR Device,<br>
> DEVMODE* dev_mode)<br>
>      return NT_SUCCESS(status);<br>
>  }<br>
><br>
> +WDDMInterface::WDDMInterface()<br>
> +    : _pfnOpen_adapter_hdc(NULL)<br>
> +    , _pfnClose_adapter(NULL)<br>
> +    , _pfnEscape(NULL)<br>
> +    , _pfnOpen_adapter_device_name(NULL)<br>
> +    , _pfnOpen_adapter_gdi_name(NULL)<br>
> +{<br>
> +    LONG error(0);<br>
> +    //Can we find the D3D calls we need?<br>
> +    if (!init_d3d_api()) {<br>
> +        throw std::exception();<br>
> +    }<br>
> +<br>
> +    //Initialize  CCD path stuff<br>
> +    if (!_ccd.query_display_config()) {<br>
> +        throw std::exception();<br>
> +    }<br>
> +<br>
> +    if (!_ccd.set_display_config(error)) {<br>
> +        throw std::exception();<br>
> +    }<br>
> +}<br>
> +<br>
> +bool WDDMInterface::is_attached(DISPLAY_DEVICE* dev_info)<br>
> +{<br>
> +    return _ccd.is_attached(dev_info->DeviceName);<br>
> +}<br>
> +<br>
> +bool WDDMInterface::set_monitor_state(LPCTSTR device_name, DEVMODE*<br>
> dev_mode, MONITOR_STATE state)<br>
> +{<br>
> +   return  _ccd.set_path_state(device_name, state);<br>
> +}<br>
> +<br>
> +bool WDDMInterface::custom_display_escape(LPCTSTR device_name, DEVMODE*<br>
> dev_mode)<br>
> +{<br>
> +    DISPLAYCONFIG_MODE_INFO* mode = _ccd.get_active_mode(device_name,<br>
> false);<br>
> +    if (!mode) {<br>
> +        return false;<br>
> +    }<br>
> +<br>
> +    //Don't bother if we are already set to the new resolution<br>
> +    if (mode->sourceMode.width == dev_mode->dmPelsWidth &&<br>
> +        mode->sourceMode.height == dev_mode->dmPelsHeight) {<br>
> +        return true;<br>
> +    }<br>
> +<br>
> +    vd_printf("%s: updating %S resolution\n", __FUNCTION__, device_name);<br>
> +<br>
> +    size_t data_size = sizeof(QXLEscape) +<br>
> sizeof(QXLEscapeSetCustomDisplay);<br>
> +    QXLEscape * qxl_escape = (QXLEscape *) malloc(data_size);<br>
> +    qxl_escape->ioctl = QXL_ESCAPE_SET_CUSTOM_DISPLAY;<br>
> +    QXLEscapeSetCustomDisplay * wddm_escape = (QXLEscapeSetCustomDisplay<br>
> *)qxl_escape->data;<br>
> +    wddm_escape->bpp = dev_mode->dmBitsPerPel;<br>
> +    wddm_escape->xres = dev_mode->dmPelsWidth;<br>
> +    wddm_escape->yres = dev_mode->dmPelsHeight;<br>
> +    bool escape_result = escape(device_name, qxl_escape, data_size);<br>
> +    free(qxl_escape);<br>
> +    if (escape_result) {<br>
> +        return _ccd.update_mode_size(device_name, dev_mode);<br>
> +    }<br>
> +<br>
> +    vd_printf("%s: (%dx%d)", __FUNCTION__, mode->sourceMode.width,<br>
> mode->sourceMode.height);<br>
> +    return false;<br>
> +}<br>
> +<br>
> +bool WDDMInterface::update_monitor_config(LPCTSTR device_name, DisplayMode*<br>
> display_mode,<br>
> +                                           DEVMODE* dev_mode)<br>
> +{<br>
> +    if (!display_mode || !display_mode->get_attached()) {<br>
> +        return false;<br>
> +    }<br>
> +    DISPLAYCONFIG_MODE_INFO* mode = _ccd.get_active_mode(device_name,<br>
> false);<br>
> +    if (!mode || !_send_monitors_config)<br>
> +        return false;<br>
> +<br>
> +    size_t data_size = sizeof(QXLEscape) + sizeof(QXLHead);<br>
> +    QXLEscape * qxl_escape = (QXLEscape *) malloc(data_size);<br>
> +    qxl_escape->ioctl = QXL_ESCAPE_MONITOR_CONFIG;<br>
> +    QXLHead * wddm_escape = (QXLHead *) qxl_escape->data;<br>
> +    wddm_escape->id = wddm_escape->surface_id = 0;<br>
> +    wddm_escape->x = display_mode->get_pos_x();<br>
> +    wddm_escape->y = display_mode->get_pos_y();<br>
> +    wddm_escape->width = display_mode->get_width();<br>
> +    wddm_escape->height = display_mode->get_height();<br>
> +    bool escape_result = escape(device_name, qxl_escape, data_size);<br>
> +    free(qxl_escape);<br>
> +    if (escape_result) {<br>
> +        //Update the path position<br>
> +        return _ccd.update_mode_position(device_name, dev_mode);<br>
> +    }<br>
> +<br>
> +    vd_printf("%s: %S failed", __FUNCTION__, device_name);<br>
> +    return false;<br>
> +<br>
> +}<br>
> +<br>
> +LONG WDDMInterface::update_display_settings()<br>
> +{<br>
> +    LONG error(0);<br>
> +    //If we removed the primary monitor since the last call, we need to<br>
> +    //reorder the other monitors, making the leftmost one the primary<br>
> +    _ccd.verify_primary_position();<br>
> +    _ccd.set_display_config(error);<br>
> +    return error;<br>
> +}<br>
> +<br>
> +void WDDMInterface::update_config_path()<br>
> +{<br>
> +    _ccd.query_display_config();<br>
> +}<br>
> +<br>
> +bool WDDMInterface::update_dev_mode_position(LPCTSTR device_name, DEVMODE*<br>
> dev_mode,<br>
> +                                             LONG x, LONG y)<br>
> +{<br>
> +    dev_mode->dmPosition.x = x;<br>
> +    dev_mode->dmPosition.y = y;<br>
> +    return _ccd.update_mode_position(device_name, dev_mode);<br>
> +}<br>
> +<br>
> +bool WDDMInterface::init_d3d_api()<br>
> +{<br>
> +    HMODULE hModule = GetModuleHandle(L"gdi32.dll");<br>
> +<br>
> +    //Look for the gdi32 functions we need to perform driver escapes<br>
> +    if (!hModule) {<br>
> +        vd_printf("%s something wildly wrong as we can't open gdi32.dll",<br>
> __FUNCTION__);<br>
> +        return false;<br>
> +    }<br>
> +<br>
> +    do {<br>
> +        _pfnClose_adapter = (PFND3DKMT_CLOSEADAPTER)<br>
> +            GetProcAddress(hModule, "D3DKMTCloseAdapter");<br>
> +        if (!_pfnClose_adapter) {<br>
> +            break;<br>
> +        }<br>
> +<br>
> +        _pfnEscape = (PFND3DKMT_ESCAPE) GetProcAddress(hModule,<br>
> "D3DKMTEscape");<br>
> +        if (!_pfnEscape) {<br>
> +            break;<br>
> +        }<br>
> +<br>
> +        _pfnOpen_adapter_hdc = (PFND3DKMT_OPENADAPTERFROMHDC)<br>
> +            GetProcAddress(hModule, "D3DKMTOpenAdapterFromHdc");<br>
> +        if (!_pfnOpen_adapter_hdc) {<br>
> +            break;<br>
> +        }<br>
> +<br>
> +        _pfnOpen_adapter_device_name = (PFND3DKMT_OPENADAPTERFROMDEVICENAME)<br>
> +            GetProcAddress(hModule, "D3DKMTOpenAdapterFromDeviceName");<br>
> +        if (!_pfnOpen_adapter_device_name) {<br>
> +            break;<br>
> +        }<br>
> +<br>
> +        _pfnOpen_adapter_gdi_name =<br>
> (PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME)<br>
> +            GetProcAddress(hModule, "D3DKMTOpenAdapterFromGdiDisplayName");<br>
> +        if (!_pfnOpen_adapter_gdi_name) {<br>
> +            break;<br>
> +        }<br>
> +<br>
> +    }<br>
> +    while(0);<br>
> +<br>
> +    //Did we get them ?<br>
> +    if (!_pfnClose_adapter || !_pfnOpen_adapter_hdc || !_pfnEscape)  {<br>
> +        return false;<br>
> +    }<br>
> +    return true;<br>
> +}<br>
> +<br>
> +D3D_HANDLE WDDMInterface::adapter_handle(LPCTSTR device_name)<br>
> +{<br>
> +    D3D_HANDLE hAdapter(0);<br>
> +<br>
> +    //For some reason, this call will occasionally fail.<br>
> +    if ((hAdapter = handle_from_DC(device_name))) {<br>
> +        return hAdapter;<br>
> +    }<br>
> +        //So try other available methods.<br>
> +    if (_pfnOpen_adapter_device_name && (hAdapter =<br>
> handle_from_device_name(device_name))) {<br>
> +        return hAdapter;<br>
> +    }<br>
> +    //One last chance to open this guy<br>
> +    if (_pfnOpen_adapter_gdi_name) {<br>
> +        hAdapter = handle_from_GDI_name(device_name);<br>
> +    }<br>
> +<br>
> +    if (!hAdapter) {<br>
> +        vd_printf("%s: failed to open adapter %S", __FUNCTION__,<br>
> device_name);<br>
> +    }<br>
> +<br>
> +    return hAdapter;<br>
> +}<br>
> +<br>
> +D3D_HANDLE WDDMInterface::handle_from_DC(LPCTSTR adapter_name)<br>
> +{<br>
> +    NTSTATUS status;<br>
> +    D3DKMT_OPENADAPTERFROMHDC open_data;<br>
> +    HDC hDc(CreateDC(adapter_name, NULL, NULL, NULL));<br>
> +<br>
> +    if (!hDc) {<br>
> +        vd_printf("%s: %S CreateDC failed with %lu", __FUNCTION__,<br>
> adapter_name, GetLastError());<br>
> +        return 0;<br>
> +    }<br>
> +<br>
> +    ZeroMemory(&open_data, sizeof(D3DKMT_OPENADAPTERFROMHDC));<br>
> +    open_data.hDc = hDc;<br>
> +<br>
> +    if (!NT_SUCCESS(status = _pfnOpen_adapter_hdc(&open_data))) {<br>
> +        vd_printf("%s: %S open adapter from hdc failed with %lu",<br>
> __FUNCTION__, adapter_name,<br>
> +            status);<br>
> +        open_data.hAdapter = 0;<br>
> +    }<br>
> +<br>
> +    DeleteDC(hDc);<br>
> +    return open_data.hAdapter;<br>
> +}<br>
> +<br>
> +D3D_HANDLE WDDMInterface::handle_from_device_name(LPCTSTR adapter_name)<br>
> +{<br>
> +    D3DKMT_OPENADAPTERFROMDEVICENAME display_name_data;<br>
> +    NTSTATUS  status;<br>
> +<br>
> +    ZeroMemory(&display_name_data, sizeof(display_name_data));<br>
> +    display_name_data.pDeviceName = adapter_name;<br>
> +<br>
> +    if (NT_SUCCESS(status =<br>
> _pfnOpen_adapter_device_name(&display_name_data))) {<br>
> +        return display_name_data.hAdapter;<br>
> +    }<br>
> +<br>
> +    vd_printf("%s %S failed with 0x%lx", __FUNCTION__, adapter_name,<br>
> status);<br>
> +    return 0;<br>
> +}<br>
> +<br>
> +D3D_HANDLE WDDMInterface::handle_from_GDI_name(LPCTSTR adapter_name)<br>
> +{<br>
> +    D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME gdi_display_name;<br>
> +    NTSTATUS status;<br>
> +<br>
> +    ZeroMemory(&gdi_display_name, sizeof(gdi_display_name));<br>
> +    wcsncpy(gdi_display_name.DeviceName, adapter_name, sizeof(TCHAR)*<br>
> CCHDEVICENAME);<br>
> +<br>
> +    if (NT_SUCCESS(status = _pfnOpen_adapter_gdi_name(&gdi_display_name))) {<br>
> +        return  gdi_display_name.hAdapter;<br>
> +    }<br>
> +<br>
> +    vd_printf("%s: %S aurrrgghh nothing works..error  is 0x%lx",<br>
> __FUNCTION__, adapter_name,<br>
> +            status);<br>
> +    return 0;<br>
> +}<br>
> +<br>
> +void WDDMInterface::close_adapter(D3D_HANDLE handle)<br>
> +{<br>
> +    D3DKMT_CLOSEADAPTER closeData;<br>
> +    if (handle) {<br>
> +        closeData.hAdapter = handle;<br>
> +        _pfnClose_adapter(&closeData);<br>
> +    }<br>
> +}<br>
> +<br>
> +bool WDDMInterface::escape(LPCTSTR device_name, void* data, UINT size_data)<br>
> +{<br>
> +    D3DKMT_ESCAPE   escapeData;<br>
> +    NTSTATUS        status;<br>
> +    D3D_HANDLE   hAdapter(0);<br>
> +<br>
> +    if (!(hAdapter = adapter_handle(device_name)))<br>
> +        return false;<br>
> +<br>
> +    escapeData.hAdapter = hAdapter;<br>
> +    escapeData.hDevice = 0;<br>
> +    escapeData.hContext = 0;<br>
> +    escapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;<br>
> +    escapeData.Flags.Value = 0;<br>
> +    escapeData.pPrivateDriverData = data;<br>
> +    escapeData.PrivateDriverDataSize = size_data;<br>
> +<br>
> +    status = _pfnEscape(&escapeData);<br>
> +<br>
> +    if (!NT_SUCCESS(status)) {<br>
> +        vd_printf("%s: this should never happen. Status is 0x%lx",<br>
> __FUNCTION__, status);<br>
> +    }<br>
> +<br>
> +    //Close the handle to this device<br>
> +    close_adapter(hAdapter);<br>
> +    return NT_SUCCESS(status);<br>
> +}<br>
> +<br>
>  CCD::CCD()<br>
>      :_numPathElements(0)<br>
>      ,_numModeElements(0)<br>
> diff --git a/vdagent/display_configuration.h<br>
> b/vdagent/display_configuration.h<br>
> index 388ac9d..7abf526 100644<br>
> --- a/vdagent/display_configuration.h<br>
> +++ b/vdagent/display_configuration.h<br>
> @@ -125,4 +125,51 @@ private:<br>
>      bool find_best_mode(LPCTSTR Device, DEVMODE* dev_mode);<br>
>  };<br>
><br>
> +//DisplayConfig implementation for guest with WDDM graphics drivers<br>
> +typedef UINT D3D_HANDLE;<br>
> +<br>
> +struct D3DKMT_ESCAPE;<br>
> +struct D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME;<br>
> +struct D3DKMT_OPENADAPTERFROMDEVICENAME;<br>
> +struct D3DKMT_CLOSEADAPTER;<br>
> +struct D3DKMT_OPENADAPTERFROMHDC;<br>
> +<br>
> +typedef NTSTATUS(APIENTRY* PFND3DKMT_ESCAPE)(CONST D3DKMT_ESCAPE*);<br>
> +typedef NTSTATUS(APIENTRY*<br>
> PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME)(D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME*);<br>
> +typedef NTSTATUS(APIENTRY*<br>
> PFND3DKMT_OPENADAPTERFROMDEVICENAME)(D3DKMT_OPENADAPTERFROMDEVICENAME*);<br>
> +typedef NTSTATUS(APIENTRY* PFND3DKMT_CLOSEADAPTER)(D3DKMT_CLOSEADAPTER*);<br>
> +typedef NTSTATUS(APIENTRY*<br>
> PFND3DKMT_OPENADAPTERFROMHDC)(D3DKMT_OPENADAPTERFROMHDC*);<br>
> +<br>
> +class WDDMInterface : public DisplayConfig {<br>
> +public:<br>
> +    WDDMInterface();<br>
> +    bool is_attached(DISPLAY_DEVICE* dev_info);<br>
> +    bool set_monitor_state(LPCTSTR device_name, DEVMODE* dev_mode,<br>
> MONITOR_STATE state);<br>
> +    LONG update_display_settings();<br>
> +    bool custom_display_escape(LPCTSTR device_name, DEVMODE* dev_mode);<br>
> +    bool update_monitor_config(LPCTSTR device_name, DisplayMode* mode,<br>
> DEVMODE* dev_mode);<br>
> +    bool update_dev_mode_position(LPCTSTR device_name, DEVMODE * dev_mode,<br>
> LONG x, LONG y);<br>
> +    void update_config_path();<br>
> +<br>
> +private:<br>
> +    bool init_d3d_api();<br>
> +    D3D_HANDLE adapter_handle(LPCTSTR device_name);<br>
> +    D3D_HANDLE handle_from_DC(LPCTSTR adapter_name);<br>
> +    D3D_HANDLE handle_from_device_name(LPCTSTR adapter_name);<br>
> +    D3D_HANDLE handle_from_GDI_name(LPCTSTR adapter_name);<br>
> +<br>
> +    void close_adapter(D3D_HANDLE handle);<br>
> +    bool escape(LPCTSTR device_name, void* data, UINT sizeData);<br>
> +<br>
> +    //GDI Function pointers<br>
> +    PFND3DKMT_OPENADAPTERFROMHDC _pfnOpen_adapter_hdc;<br>
> +    PFND3DKMT_CLOSEADAPTER  _pfnClose_adapter;<br>
> +    PFND3DKMT_ESCAPE _pfnEscape;<br>
> +    PFND3DKMT_OPENADAPTERFROMDEVICENAME _pfnOpen_adapter_device_name;<br>
> +    PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME _pfnOpen_adapter_gdi_name;<br>
> +<br>
> +    //object handles the CCD API<br>
> +    CCD _ccd;<br>
> +};<br>
> +<br>
>  #endif<br>
> \ No newline at end of file<br></div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><span style="color: #0b5394; font-family: times new roman,serif; font-size: large;" data-mce-style="color: #0b5394; font-family: times new roman,serif; font-size: large;" color="#0b5394" face="times new roman, serif" size="4">Respectfully,<br></span><div style="font-size:12.8px;color:rgb(136,136,136)"><span style="color: #0b5394; font-family: times new roman,serif; font-size: large;" data-mce-style="color: #0b5394; font-family: times new roman,serif; font-size: large;" color="#0b5394" face="times new roman, serif" size="4"><b><i>Sameeh Jubran</i></b></span></div><div style="font-size:12.8px;color:rgb(136,136,136)"><i style="color:rgb(7,55,99);font-family:"times new roman",serif;font-size:large"><span style="line-height:15px"><a href="https://il.linkedin.com/pub/sameeh-jubran/87/747/a8a" title="View public profile" name="UNIQUE_ID_SafeHtmlFilter_UNIQUE_ID_SafeHtmlFilter_UNIQUE_ID_SafeHtmlFilter_UNIQUE_ID_SafeHtmlFilter_14e2c1de96f8c195_UNIQUE_ID_SafeHtmlFilter_SafeHtmlFilter_SafeHtmlFilter_webProfileURL" style="color:rgb(17,85,204);margin:0px;padding:0px;border-width:0px;outline:none;vertical-align:baseline;text-decoration:none" target="_blank">Linkedin</a></span></i><br></div><div style="font-size:12.8px;color:rgb(136,136,136)"><span style="color: #073763; font-family: times new roman,serif; font-size: large;" data-mce-style="color: #073763; font-family: times new roman,serif; font-size: large;" color="#073763" face="times new roman, serif" size="4"><i>Junior Software Engineer @ <a href="http://www.daynix.com" target="_blank">Daynix</a>.</i></span></div></div></div></div></div></div></div></div></div></blockquote><div><br></div></div></body></html>