From bab639e78a3c1ba0074b7ffe134df58ad51a3119 Mon Sep 17 00:00:00 2001 From: Alex Pasadyn Date: Thu, 16 Oct 2003 00:21:42 +0000 Subject: [PATCH] - Added support for XRandR extension. - Added new debugging channels for resolution changing. - Streamlined resolution changing and removed duplicated code. --- dlls/x11drv/Makefile.in | 2 + dlls/x11drv/desktop.c | 219 ++++---------------- dlls/x11drv/settings.c | 321 ++++++++++++++++++++++++++++ dlls/x11drv/x11ddraw.c | 8 +- dlls/x11drv/x11drv.h | 17 +- dlls/x11drv/x11drv_main.c | 12 +- dlls/x11drv/xrandr.c | 260 +++++++++++++++++++++++ dlls/x11drv/xrandr.h | 33 +++ dlls/x11drv/xvidmode.c | 425 +++++++------------------------------- dlls/x11drv/xvidmode.h | 6 - 10 files changed, 755 insertions(+), 548 deletions(-) create mode 100644 dlls/x11drv/settings.c create mode 100644 dlls/x11drv/xrandr.c create mode 100644 dlls/x11drv/xrandr.h diff --git a/dlls/x11drv/Makefile.in b/dlls/x11drv/Makefile.in index 14ac8d72405..a083dfe9233 100644 --- a/dlls/x11drv/Makefile.in +++ b/dlls/x11drv/Makefile.in @@ -29,11 +29,13 @@ C_SRCS = \ keyboard.c \ mouse.c \ scroll.c \ + settings.c \ ts_xlib.c \ window.c \ winpos.c \ x11ddraw.c \ x11drv_main.c \ + xrandr.c \ xrender.c \ xvidmode.c diff --git a/dlls/x11drv/desktop.c b/dlls/x11drv/desktop.c index ceb711e79d3..916d267a545 100644 --- a/dlls/x11drv/desktop.c +++ b/dlls/x11drv/desktop.c @@ -115,43 +115,22 @@ void X11DRV_create_desktop_thread(void) /* data for resolution changing */ static LPDDHALMODEINFO dd_modes; -static int nmodes; +static unsigned int dd_mode_count; static unsigned int max_width; static unsigned int max_height; static const unsigned int widths[] = {320, 512, 640, 800, 1024, 1152, 1280, 1600}; static const unsigned int heights[] = {200, 384, 480, 600, 768, 864, 1024, 1200}; -static const unsigned int depths[] = {8, 16, 32}; - -/* fill in DD mode info for one mode*/ -static void make_one_mode (LPDDHALMODEINFO info, unsigned int width, unsigned int height, unsigned int bpp) -{ - info->dwWidth = width; - info->dwHeight = height; - info->wRefreshRate = 0; - info->lPitch = 0; - info->dwBPP = bpp; - info->wFlags = 0; - info->dwRBitMask = 0; - info->dwGBitMask = 0; - info->dwBBitMask = 0; - info->dwAlphaBitMask = 0; - TRACE("initialized mode %d: %dx%dx%d\n", nmodes, width, height, bpp); -} +#define NUM_DESKTOP_MODES (8) /* create the mode structures */ static void make_modes(void) { - int i,j; - int max_modes = (3+1)*(8+2); - DWORD dwBpp = screen_depth; - if (dwBpp == 24) dwBpp = 32; - nmodes = 0; - dd_modes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DDHALMODEINFO) * max_modes); + int i; /* original specified desktop size */ - make_one_mode(&dd_modes[nmodes++], screen_width, screen_height, dwBpp); - for (i=0; i<8; i++) + X11DRV_Settings_AddOneMode(screen_width, screen_height, 0, 0); + for (i=0; idmDisplayFlags = 0; - devmode->dmDisplayFrequency = 85; - devmode->dmSize = sizeof(DEVMODEW); - if (n==(DWORD)-1) - { - devmode->dmBitsPerPel = dwBpp; - devmode->dmPelsHeight = screen_height; - devmode->dmPelsWidth = screen_width; - devmode->dmFields = (DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL); - TRACE("mode %ld (current) -- returning current %ldx%ldx%ldbpp\n", n, - devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel); - return TRUE; - } - else if (n==(DWORD)-2) - { - devmode->dmBitsPerPel = dwBpp; - devmode->dmPelsHeight = dd_modes[0].dwHeight; - devmode->dmPelsWidth = dd_modes[0].dwWidth; - devmode->dmFields = (DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL); - TRACE("mode %ld (registry) -- returning default %ldx%ldx%ldbpp\n", n, - devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel); - return TRUE; - } - else if (n < nmodes) - { - devmode->dmPelsWidth = dd_modes[n].dwWidth; - devmode->dmPelsHeight = dd_modes[n].dwHeight; - devmode->dmBitsPerPel = dd_modes[n].dwBPP; - devmode->dmFields = (DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL); - TRACE("mode %ld -- %ldx%ldx%ldbpp\n", n, - devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel); - return TRUE; - } - TRACE("mode %ld -- not present\n", n); - return FALSE; -} - -/* implementation of ChangeDisplaySettings for desktop */ -LONG X11DRV_desktop_ChangeDisplaySettingsExW( LPCWSTR devname, LPDEVMODEW devmode, - HWND hwnd, DWORD flags, LPVOID lpvoid ) -{ - DWORD i; - DWORD dwBpp = screen_depth; - if (dwBpp == 24) dwBpp = 32; - if (devmode==NULL) - { - X11DRV_desktop_SetCurrentMode(0); - return DISP_CHANGE_SUCCESSFUL; - } - - for (i = 0; i < nmodes; i++) - { - if (devmode->dmFields & DM_BITSPERPEL) - { - if (devmode->dmBitsPerPel != dd_modes[i].dwBPP) - continue; - } - if (devmode->dmFields & DM_PELSWIDTH) - { - if (devmode->dmPelsWidth != dd_modes[i].dwWidth) - continue; - } - if (devmode->dmFields & DM_PELSHEIGHT) - { - if (devmode->dmPelsHeight != dd_modes[i].dwHeight) - continue; - } - /* we have a valid mode */ - TRACE("Requested display settings match mode %ld\n", i); - X11DRV_desktop_SetCurrentMode(i); - return DISP_CHANGE_SUCCESSFUL; - } - - /* no valid modes found */ - ERR("No matching mode found!\n"); - return DISP_CHANGE_BADMODE; -} - -/* DirectDraw HAL stuff */ - -static DWORD PASCAL X11DRV_desktop_SetMode(LPDDHAL_SETMODEDATA data) -{ - TRACE("Mode %ld requested by DDHAL\n", data->dwModeIndex); - X11DRV_desktop_SetCurrentMode(data->dwModeIndex); - X11DRV_DDHAL_SwitchMode(data->dwModeIndex, NULL, NULL); - data->ddRVal = DD_OK; - return DDHAL_DRIVER_HANDLED; -} - -int X11DRV_desktop_CreateDriver(LPDDHALINFO info) -{ - if (!nmodes) return 0; /* no desktop */ - - TRACE("Setting up Desktop mode for DDRAW\n"); - info->dwNumModes = nmodes; - info->lpModeInfo = dd_modes; - X11DRV_DDHAL_SwitchMode(X11DRV_desktop_GetCurrentMode(), NULL, NULL); - info->lpDDCallbacks->SetMode = X11DRV_desktop_SetMode; - return TRUE; -} diff --git a/dlls/x11drv/settings.c b/dlls/x11drv/settings.c new file mode 100644 index 00000000000..6479aa451f7 --- /dev/null +++ b/dlls/x11drv/settings.c @@ -0,0 +1,321 @@ +/* + * Wine X11drv display settings functions + * + * Copyright 2003 Alexander James Pasadyn + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include +#include +#include "x11drv.h" +#include "x11ddraw.h" + +#include "windef.h" +#include "wingdi.h" +#include "ddrawi.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(x11settings); + +/* + * The DDHALMODEINFO type is used to hold all the mode information. + * This is done because the array of DDHALMODEINFO structures must be + * created for use by DirectDraw anyway. + */ +static LPDDHALMODEINFO dd_modes = NULL; +static unsigned int dd_mode_count = 0; +static unsigned int dd_max_modes = 0; +static int dd_mode_default = 0; +static const unsigned int depths[] = {8, 16, 32}; + +/* pointers to functions that actually do the hard stuff */ +static int (*pGetCurrentMode)(void); +static void (*pSetCurrentMode)(int mode); +static const char *handler_name; + +/* + * Set the handlers for resolution changing functions + * and initialize the master list of modes + */ +LPDDHALMODEINFO X11DRV_Settings_SetHandlers(const char *name, + int (*pNewGCM)(void), + void (*pNewSCM)(int), + unsigned int nmodes, + int reserve_depths) +{ + handler_name = name; + pGetCurrentMode = pNewGCM; + pSetCurrentMode = pNewSCM; + TRACE("Resolution settings now handled by: %s\n", name); + if (reserve_depths) + /* leave room for other depths */ + dd_max_modes = (3+1)*(nmodes); + else + dd_max_modes = nmodes; + + if (dd_modes) + { + TRACE("Destroying old display modes array\n"); + HeapFree(GetProcessHeap(), 0, dd_modes); + } + dd_modes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DDHALMODEINFO) * dd_max_modes); + dd_mode_count = 0; + TRACE("Initialized new display modes array\n"); + return dd_modes; +} + +/* Add one mode to the master list */ +void X11DRV_Settings_AddOneMode(unsigned int width, unsigned int height, unsigned int bpp, unsigned int freq) +{ + LPDDHALMODEINFO info = &(dd_modes[dd_mode_count]); + DWORD dwBpp = screen_depth; + if (dd_mode_count >= dd_max_modes) + { + ERR("Maximum modes (%d) exceeded\n", dd_max_modes); + return; + } + if (dwBpp == 24) dwBpp = 32; + if (bpp == 0) bpp = dwBpp; + info->dwWidth = width; + info->dwHeight = height; + info->wRefreshRate = freq; + info->lPitch = 0; + info->dwBPP = bpp; + info->wFlags = 0; + info->dwRBitMask = 0; + info->dwGBitMask = 0; + info->dwBBitMask = 0; + info->dwAlphaBitMask = 0; + TRACE("initialized mode %d: %dx%dx%d @%d Hz (%s)\n", + dd_mode_count, width, height, bpp, freq, handler_name); + dd_mode_count++; +} + +/* copy all the current modes using the other color depths */ +void X11DRV_Settings_AddDepthModes(void) +{ + int i, j; + int existing_modes = dd_mode_count; + DWORD dwBpp = screen_depth; + if (dwBpp == 24) dwBpp = 32; + for (j=0; j<3; j++) + { + if (depths[j] != dwBpp) + { + for (i=0; i < existing_modes; i++) + { + X11DRV_Settings_AddOneMode(dd_modes[i].dwWidth, dd_modes[i].dwHeight, + depths[j], dd_modes[i].wRefreshRate); + } + } + } +} + +/* set the default mode */ +void X11DRV_Settings_SetDefaultMode(int mode) +{ + dd_mode_default = mode; +} + +/* return the number of modes that are initialized */ +unsigned int X11DRV_Settings_GetModeCount(void) +{ + return dd_mode_count; +} + +/*********************************************************************** + * Default handlers if resolution switching is not enabled + * + */ +static int X11DRV_nores_GetCurrentMode(void) +{ + return 0; +} +static void X11DRV_nores_SetCurrentMode(int mode) +{ + TRACE("Ignoring mode change request\n"); +} +/* default handler only gets the current X desktop resolution */ +void X11DRV_Settings_Init(void) +{ + X11DRV_Settings_SetHandlers("NoRes", + X11DRV_nores_GetCurrentMode, + X11DRV_nores_SetCurrentMode, + 1, 0); + X11DRV_Settings_AddOneMode(screen_width, screen_height, 0, 0); +} + +/*********************************************************************** + * EnumDisplaySettingsExW (X11DRV.@) + * + */ +BOOL X11DRV_EnumDisplaySettingsExW( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DWORD flags) +{ + DWORD dwBpp = screen_depth; + if (dwBpp == 24) dwBpp = 32; + devmode->dmDisplayFlags = 0; + devmode->dmDisplayFrequency = 0; + devmode->dmSize = sizeof(DEVMODEW); + if (n == (DWORD)-1) + { + TRACE("mode %ld (current) -- getting current mode (%s)\n", n, handler_name); + n = pGetCurrentMode(); + } + if (n == (DWORD)-2) + { + TRACE("mode %ld (registry) -- getting default mode (%s)\n", n, handler_name); + n = dd_mode_default; + } + if (n < dd_mode_count) + { + devmode->dmPelsWidth = dd_modes[n].dwWidth; + devmode->dmPelsHeight = dd_modes[n].dwHeight; + devmode->dmBitsPerPel = dd_modes[n].dwBPP; + devmode->dmDisplayFrequency = dd_modes[n].wRefreshRate; + devmode->dmFields = (DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL); + if (devmode->dmDisplayFrequency) + { + devmode->dmFields |= DM_DISPLAYFREQUENCY; + TRACE("mode %ld -- %ldx%ldx%ldbpp @%ld Hz (%s)\n", n, + devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel, + devmode->dmDisplayFrequency, handler_name); + } + else + { + TRACE("mode %ld -- %ldx%ldx%ldbpp (%s)\n", n, + devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel, + handler_name); + } + return TRUE; + } + TRACE("mode %ld -- not present (%s)\n", n, handler_name); + return FALSE; +} + +#define _X_FIELD(prefix, bits) if ((fields) & prefix##_##bits) {p+=sprintf(p, "%s%s", first ? "" : ",", #bits); first=FALSE;} +static const char * _CDS_flags(DWORD fields) +{ + BOOL first = TRUE; + char buf[128]; + char *p = buf; + _X_FIELD(CDS,UPDATEREGISTRY);_X_FIELD(CDS,TEST);_X_FIELD(CDS,FULLSCREEN); + _X_FIELD(CDS,GLOBAL);_X_FIELD(CDS,SET_PRIMARY);_X_FIELD(CDS,RESET); + _X_FIELD(CDS,SETRECT);_X_FIELD(CDS,NORESET); + *p = 0; + return wine_dbg_sprintf("%s", buf); +} +static const char * _DM_fields(DWORD fields) +{ + BOOL first = TRUE; + char buf[128]; + char *p = buf; + _X_FIELD(DM,BITSPERPEL);_X_FIELD(DM,PELSWIDTH);_X_FIELD(DM,PELSHEIGHT); + _X_FIELD(DM,DISPLAYFLAGS);_X_FIELD(DM,DISPLAYFREQUENCY);_X_FIELD(DM,POSITION); + *p = 0; + return wine_dbg_sprintf("%s", buf); +} +#undef _X_FIELD + +/*********************************************************************** + * ChangeDisplaySettingsExW (X11DRV.@) + * + */ +LONG X11DRV_ChangeDisplaySettingsExW( LPCWSTR devname, LPDEVMODEW devmode, + HWND hwnd, DWORD flags, LPVOID lpvoid ) +{ + DWORD i; + DEVMODEW dm; + + TRACE("(%s,%p,%p,0x%08lx,%p)\n",debugstr_w(devname),devmode,hwnd,flags,lpvoid); + TRACE("flags=%s\n",_CDS_flags(flags)); + if (devmode) + { + TRACE("DM_fields=%s\n",_DM_fields(devmode->dmFields)); + TRACE("width=%ld height=%ld bpp=%ld freq=%ld (%s)\n", + devmode->dmPelsWidth,devmode->dmPelsHeight, + devmode->dmBitsPerPel,devmode->dmDisplayFrequency, handler_name); + } + else + { + TRACE("Return to original display mode (%s)\n", handler_name); + if (!X11DRV_EnumDisplaySettingsExW(devname, dd_mode_default, &dm, 0)) + { + ERR("Default mode not found!\n"); + return DISP_CHANGE_BADMODE; + } + devmode = &dm; + } + + for (i = 0; i < dd_mode_count; i++) + { + if (devmode->dmFields & DM_BITSPERPEL) + { + if (devmode->dmBitsPerPel != dd_modes[i].dwBPP) + continue; + } + if (devmode->dmFields & DM_PELSWIDTH) + { + if (devmode->dmPelsWidth != dd_modes[i].dwWidth) + continue; + } + if (devmode->dmFields & DM_PELSHEIGHT) + { + if (devmode->dmPelsHeight != dd_modes[i].dwHeight) + continue; + } + if (devmode->dmFields & DM_DISPLAYFREQUENCY) + { + if (devmode->dmDisplayFrequency != dd_modes[i].wRefreshRate) + continue; + } + /* we have a valid mode */ + TRACE("Requested display settings match mode %ld (%s)\n", i, handler_name); + pSetCurrentMode(i); + return DISP_CHANGE_SUCCESSFUL; + } + + /* no valid modes found */ + ERR("No matching mode found! (%s)\n", handler_name); + return DISP_CHANGE_BADMODE; +} + + + + +/*********************************************************************** + * DirectDraw HAL interface + * + */ +static DWORD PASCAL X11DRV_Settings_SetMode(LPDDHAL_SETMODEDATA data) +{ + TRACE("Mode %ld requested by DDHAL (%s)\n", data->dwModeIndex, handler_name); + pSetCurrentMode(data->dwModeIndex); + X11DRV_DDHAL_SwitchMode(data->dwModeIndex, NULL, NULL); + data->ddRVal = DD_OK; + return DDHAL_DRIVER_HANDLED; +} +int X11DRV_Settings_CreateDriver(LPDDHALINFO info) +{ + if (!dd_mode_count) return 0; /* no settings defined */ + + TRACE("Setting up display settings for DDRAW (%s)\n", handler_name); + info->dwNumModes = dd_mode_count; + info->lpModeInfo = dd_modes; + X11DRV_DDHAL_SwitchMode(pGetCurrentMode(), NULL, NULL); + info->lpDDCallbacks->SetMode = X11DRV_Settings_SetMode; + return TRUE; +} diff --git a/dlls/x11drv/x11ddraw.c b/dlls/x11drv/x11ddraw.c index 15981dd6a5d..996f4d5490d 100644 --- a/dlls/x11drv/x11ddraw.c +++ b/dlls/x11drv/x11ddraw.c @@ -28,6 +28,7 @@ #include "x11drv.h" #include "x11ddraw.h" #include "xvidmode.h" +#include "xrandr.h" #include "dga2.h" #include "windef.h" @@ -382,12 +383,7 @@ INT X11DRV_DCICommand(INT cbInput, const DCICMD *lpCmd, LPVOID lpOutData) if (!X11DRV_XF86DGA2_CreateDriver(&hal_info)) #endif { -#ifdef HAVE_LIBXXF86VM - if (!X11DRV_XF86VM_CreateDriver(&hal_info)) -#endif - { - X11DRV_desktop_CreateDriver(&hal_info); - } + X11DRV_Settings_CreateDriver(&hal_info); } #ifdef HAVE_OPENGL /*X11DRV_GLX_CreateDriver(&hal_info);*/ diff --git a/dlls/x11drv/x11drv.h b/dlls/x11drv/x11drv.h index f9354823431..62a129a84c8 100644 --- a/dlls/x11drv/x11drv.h +++ b/dlls/x11drv/x11drv.h @@ -491,13 +491,22 @@ extern void X11DRV_window_to_X_rect( WND *win, RECT *rect ); extern void X11DRV_X_to_window_rect( WND *win, RECT *rect ); extern void X11DRV_create_desktop_thread(void); extern Window X11DRV_create_desktop( XVisualInfo *desktop_vi, const char *geometry ); -extern int X11DRV_desktop_CreateDriver(LPDDHALINFO info); -extern BOOL X11DRV_desktop_EnumDisplaySettingsExW( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DWORD flags); -extern LONG X11DRV_desktop_ChangeDisplaySettingsExW( LPCWSTR devname, LPDEVMODEW devmode, - HWND hwnd, DWORD flags, LPVOID lpvoid ); extern void X11DRV_sync_window_style( Display *display, WND *win ); extern int X11DRV_sync_whole_window_position( Display *display, WND *win, int zorder ); extern int X11DRV_sync_client_window_position( Display *display, WND *win ); extern void X11DRV_set_wm_hints( Display *display, WND *win ); +extern void X11DRV_Settings_AddDepthModes(void); +extern void X11DRV_Settings_AddOneMode(unsigned int width, unsigned int height, unsigned int bpp, unsigned int freq); +extern int X11DRV_Settings_CreateDriver(LPDDHALINFO info); +extern LPDDHALMODEINFO X11DRV_Settings_CreateModes(unsigned int max_modes, int reserve_depths); +unsigned int X11DRV_Settings_GetModeCount(void); +void X11DRV_Settings_Init(void); +extern void X11DRV_Settings_SetDefaultMode(int mode); +LPDDHALMODEINFO X11DRV_Settings_SetHandlers(const char *name, + int (*pNewGCM)(void), + void (*pNewSCM)(int), + unsigned int nmodes, + int reserve_depths); + #endif /* __WINE_X11DRV_H */ diff --git a/dlls/x11drv/x11drv_main.c b/dlls/x11drv/x11drv_main.c index 8e4a980991a..8fba17dbed4 100644 --- a/dlls/x11drv/x11drv_main.c +++ b/dlls/x11drv/x11drv_main.c @@ -48,6 +48,7 @@ #include "win.h" #include "x11drv.h" #include "xvidmode.h" +#include "xrandr.h" #include "dga2.h" #include "wine/server.h" #include "wine/debug.h" @@ -70,7 +71,7 @@ unsigned int screen_height; unsigned int screen_depth; Window root_window; DWORD desktop_tid = 0; -int dxgrab, usedga, usexvidmode; +int dxgrab, usedga, usexvidmode, usexrandr; int use_xkb = 1; int use_take_focus = 1; int managed_mode = 1; @@ -261,6 +262,9 @@ static void setup_options(void) if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) )) usexvidmode = IS_OPTION_TRUE( buffer[0] ); + if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) )) + usexrandr = IS_OPTION_TRUE( buffer[0] ); + if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) )) use_take_focus = IS_OPTION_TRUE( buffer[0] ); @@ -361,6 +365,8 @@ static void process_attach(void) screen_width = WidthOfScreen( screen ); screen_height = HeightOfScreen( screen ); + X11DRV_Settings_Init(); + if (desktop_geometry) root_window = X11DRV_create_desktop( desktop_vi, desktop_geometry ); @@ -382,6 +388,10 @@ static void process_attach(void) /* initialize XVidMode */ X11DRV_XF86VM_Init(); #endif +#ifdef HAVE_LIBXRANDR + /* initialize XRandR */ + X11DRV_XRandR_Init(); +#endif #ifdef HAVE_LIBXXF86DGA2 /* initialize DGA2 */ X11DRV_XF86DGA2_Init(); diff --git a/dlls/x11drv/xrandr.c b/dlls/x11drv/xrandr.c new file mode 100644 index 00000000000..58b8dda33a4 --- /dev/null +++ b/dlls/x11drv/xrandr.c @@ -0,0 +1,260 @@ +/* + * Wine X11drv Xrandr interface + * + * Copyright 2003 Alexander James Pasadyn + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include +#include + +#ifdef HAVE_LIBXRANDR + +#include "ts_xlib.h" + +#include +#include "x11drv.h" + +#include "x11ddraw.h" +#include "xrandr.h" + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "ddrawi.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(xrandr); + +extern int usexrandr; + +static int xrandr_event, xrandr_error, xrandr_major, xrandr_minor; + +static LPDDHALMODEINFO dd_modes; +static unsigned int dd_mode_count; +static XRRScreenSize *real_xrandr_sizes; +static short **real_xrandr_rates; +static unsigned int real_xrandr_sizes_count; +static int *real_xrandr_rates_count; +static unsigned int real_xrandr_modes_count; + +static int XRandRErrorHandler(Display *dpy, XErrorEvent *event, void *arg) +{ + return 1; +} + +static Bool in_desktop_mode; +static const unsigned int depths[] = {8, 16, 32}; + +/* create the mode structures */ +static void make_modes(void) +{ + int i, j; + for (i=0; i0); + } + if (ok) + { + real_xrandr_rates = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(short *) * real_xrandr_sizes_count); + real_xrandr_rates_count = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(int) * real_xrandr_sizes_count); + for (i=0; i < real_xrandr_sizes_count; i++) + { + real_xrandr_rates[i] = XRRRates (gdi_display, DefaultScreen(gdi_display), i, &(real_xrandr_rates_count[i])); + if (real_xrandr_rates_count[i]) + { + nmodes += real_xrandr_rates_count[i]; + } + else + { + nmodes++; + } + } + } + wine_tsx11_unlock(); + if (!ok) return; + + real_xrandr_modes_count = nmodes; + TRACE("XRandR modes: count=%d\n", nmodes); + + dd_modes = X11DRV_Settings_SetHandlers("XRandR", + X11DRV_XRandR_GetCurrentMode, + X11DRV_XRandR_SetCurrentMode, + nmodes, 1); + make_modes(); + X11DRV_Settings_AddDepthModes(); + dd_mode_count = X11DRV_Settings_GetModeCount(); + X11DRV_Settings_SetDefaultMode(0); + + TRACE("Available DD modes: count=%d\n", dd_mode_count); + TRACE("Enabling XRandR\n"); +} + +void X11DRV_XRandR_Cleanup(void) +{ + if (real_xrandr_rates) + { + HeapFree(GetProcessHeap(), 0, real_xrandr_rates); + real_xrandr_rates = NULL; + } + if (real_xrandr_rates_count) + { + HeapFree(GetProcessHeap(), 0, real_xrandr_rates_count); + real_xrandr_rates_count = NULL; + } +} + +#endif /* HAVE_LIBXRANDR */ diff --git a/dlls/x11drv/xrandr.h b/dlls/x11drv/xrandr.h new file mode 100644 index 00000000000..562f3c57c7b --- /dev/null +++ b/dlls/x11drv/xrandr.h @@ -0,0 +1,33 @@ +/* + * Wine X11drv Xrandr interface + * + * Copyright 2003 Alexander James Pasadyn + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __WINE_XRANDR_H +#define __WINE_XRANDR_H + +#ifndef __WINE_CONFIG_H +# error You must include config.h to use this header +#endif + +#ifdef HAVE_LIBXRANDR + +void X11DRV_XRandR_Init(void); +void X11DRV_XRandR_Cleanup(void); + +#endif /* HAVE_LIBXRANDR */ +#endif /* __WINE_XRANDR_H */ diff --git a/dlls/x11drv/xvidmode.c b/dlls/x11drv/xvidmode.c index c8b7d3493d0..cefcf6729f7 100644 --- a/dlls/x11drv/xvidmode.c +++ b/dlls/x11drv/xvidmode.c @@ -28,7 +28,6 @@ #define XMD_H #include "basetsd.h" #include -#endif /* HAVE_LIBXXF86VM */ #include "x11drv.h" #include "x11ddraw.h" @@ -39,9 +38,7 @@ #include "ddrawi.h" #include "wine/debug.h" -WINE_DEFAULT_DEBUG_CHANNEL(x11drv); - -#ifdef HAVE_LIBXXF86VM +WINE_DEFAULT_DEBUG_CHANNEL(xvidmode); extern int usexvidmode; @@ -50,31 +47,22 @@ static int xf86vm_event, xf86vm_error, xf86vm_major, xf86vm_minor; #ifdef X_XF86VidModeSetGammaRamp static int xf86vm_gammaramp_size; static BOOL xf86vm_use_gammaramp; -#endif +#endif /* X_XF86VidModeSetGammaRamp */ static LPDDHALMODEINFO dd_modes; static unsigned int dd_mode_count; static XF86VidModeModeInfo** real_xf86vm_modes; static unsigned int real_xf86vm_mode_count; -static unsigned int xf86vm_initial_mode; +static unsigned int xf86vm_initial_mode = 0; -static void convert_modeinfo( const XF86VidModeModeInfo *mode, LPDDHALMODEINFO info, unsigned int bpp) +static void convert_modeinfo( const XF86VidModeModeInfo *mode) { - info->dwWidth = mode->hdisplay; - info->dwHeight = mode->vdisplay; + int rate; if (mode->htotal!=0 && mode->vtotal!=0) - info->wRefreshRate = mode->dotclock * 1000 / (mode->htotal * mode->vtotal); + rate = mode->dotclock * 1000 / (mode->htotal * mode->vtotal); else - info->wRefreshRate = 0; - TRACE(" width=%ld, height=%ld, refresh=%d\n", - info->dwWidth, info->dwHeight, info->wRefreshRate); - info->lPitch = 0; - info->dwBPP = bpp; - info->wFlags = 0; - info->dwRBitMask = 0; - info->dwGBitMask = 0; - info->dwBBitMask = 0; - info->dwAlphaBitMask = 0; + rate = 0; + X11DRV_Settings_AddOneMode(mode->hdisplay, mode->vdisplay, 0, rate); } static void convert_modeline(int dotclock, const XF86VidModeModeLine *mode, LPDDHALMODEINFO info, unsigned int bpp) @@ -102,13 +90,64 @@ static int XVidModeErrorHandler(Display *dpy, XErrorEvent *event, void *arg) } static Bool in_desktop_mode; -static const unsigned int depths[] = {8, 16, 32}; + +int X11DRV_XF86VM_GetCurrentMode(void) +{ + XF86VidModeModeLine line; + int dotclock, i; + DDHALMODEINFO cmode; + DWORD dwBpp = screen_depth; + if (dwBpp == 24) dwBpp = 32; + + TRACE("Querying XVidMode current mode\n"); + wine_tsx11_lock(); + XF86VidModeGetModeLine(gdi_display, DefaultScreen(gdi_display), &dotclock, &line); + wine_tsx11_unlock(); + convert_modeline(dotclock, &line, &cmode, dwBpp); + for (i=0; ihdisplay, real_xf86vm_modes[mode]->vdisplay); + XF86VidModeSwitchToMode(gdi_display, DefaultScreen(gdi_display), real_xf86vm_modes[mode]); +#if 0 /* FIXME */ + SYSMETRICS_Set( SM_CXSCREEN, real_xf86vm_modes[mode]->hdisplay ); + SYSMETRICS_Set( SM_CYSCREEN, real_xf86vm_modes[mode]->vdisplay ); +#else + FIXME("Need to update SYSMETRICS after resizing display (now %dx%d)\n", + real_xf86vm_modes[mode]->hdisplay, real_xf86vm_modes[mode]->vdisplay); +#endif +#if 0 /* it is said that SetViewPort causes problems with some X servers */ + XF86VidModeSetViewPort(gdi_display, DefaultScreen(gdi_display), 0, 0); +#else + XWarpPointer(gdi_display, None, DefaultRootWindow(gdi_display), 0, 0, 0, 0, 0, 0); +#endif + XSync(gdi_display, False); + wine_tsx11_unlock(); +} void X11DRV_XF86VM_Init(void) { Bool ok; - int nmodes, i, j; - int max_modes; + int nmodes, i; DWORD dwBpp = screen_depth; if (dwBpp == 24) dwBpp = 32; @@ -137,7 +176,7 @@ void X11DRV_XF86VM_Init(void) if (xf86vm_gammaramp_size == 256) xf86vm_use_gammaramp = TRUE; } -#endif +#endif /* X_XF86VidModeSetGammaRamp */ /* retrieve modes */ if (!in_desktop_mode) ok = XF86VidModeGetAllModeLines(gdi_display, DefaultScreen(gdi_display), &nmodes, &real_xf86vm_modes); @@ -151,32 +190,27 @@ void X11DRV_XF86VM_Init(void) TRACE("XVidMode modes: count=%d\n", nmodes); real_xf86vm_mode_count = nmodes; - max_modes = (3+1)*(nmodes); - dd_modes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DDHALMODEINFO) * max_modes); + dd_modes = X11DRV_Settings_SetHandlers("XF86VidMode", + X11DRV_XF86VM_GetCurrentMode, + X11DRV_XF86VM_SetCurrentMode, + nmodes, 1); /* convert modes to DDHALMODEINFO format */ for (i=0; ihdisplay, real_xf86vm_modes[mode]->vdisplay); - XF86VidModeSwitchToMode(gdi_display, DefaultScreen(gdi_display), real_xf86vm_modes[mode]); -#if 0 /* FIXME */ - SYSMETRICS_Set( SM_CXSCREEN, real_xf86vm_modes[mode]->hdisplay ); - SYSMETRICS_Set( SM_CYSCREEN, real_xf86vm_modes[mode]->vdisplay ); -#else - FIXME("Need to update SYSMETRICS after resizing display (now %dx%d)\n", - real_xf86vm_modes[mode]->hdisplay, real_xf86vm_modes[mode]->vdisplay); -#endif -#if 0 /* it is said that SetViewPort causes problems with some X servers */ - XF86VidModeSetViewPort(gdi_display, DefaultScreen(gdi_display), 0, 0); -#else - XWarpPointer(gdi_display, None, DefaultRootWindow(gdi_display), 0, 0, 0, 0, 0, 0); -#endif - XSync(gdi_display, False); - wine_tsx11_unlock(); -} - void X11DRV_XF86VM_SetExclusiveMode(int lock) { if (!dd_modes) return; /* no XVidMode */ @@ -245,30 +228,6 @@ void X11DRV_XF86VM_SetExclusiveMode(int lock) wine_tsx11_unlock(); } -/* actual DirectDraw HAL stuff */ - -static DWORD PASCAL X11DRV_XF86VM_SetMode(LPDDHAL_SETMODEDATA data) -{ - TRACE("Mode %ld requested by DDHAL\n", data->dwModeIndex); - X11DRV_XF86VM_SetCurrentMode(data->dwModeIndex); - X11DRV_DDHAL_SwitchMode(data->dwModeIndex, NULL, NULL); - data->ddRVal = DD_OK; - return DDHAL_DRIVER_HANDLED; -} - -int X11DRV_XF86VM_CreateDriver(LPDDHALINFO info) -{ - if (!dd_mode_count) return 0; /* no XVidMode */ - - TRACE("Setting up XF86VM mode for DDRAW\n"); - info->dwNumModes = dd_mode_count; - info->lpModeInfo = dd_modes; - X11DRV_DDHAL_SwitchMode(X11DRV_XF86VM_GetCurrentMode(), NULL, NULL); - info->lpDDCallbacks->SetMode = X11DRV_XF86VM_SetMode; - return TRUE; -} - - /***** GAMMA CONTROL *****/ /* (only available in XF86VidMode 2.x) */ @@ -453,243 +412,3 @@ BOOL X11DRV_SetDeviceGammaRamp(X11DRV_PDEVICE *physDev, LPVOID ramp) return FALSE; #endif } - -/* implementation of EnumDisplaySettings for XF86VM */ -BOOL X11DRV_XF86VM_EnumDisplaySettingsExW( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DWORD flags) -{ - DWORD dwBpp = screen_depth; - if (dwBpp == 24) dwBpp = 32; - devmode->dmDisplayFlags = 0; - devmode->dmDisplayFrequency = 85; - devmode->dmSize = sizeof(DEVMODEW); - if (n == (DWORD)-1) - { - TRACE("mode %ld (current) -- getting current mode\n", n); - n = X11DRV_XF86VM_GetCurrentMode(); - } - if (n == (DWORD)-2) - { - devmode->dmBitsPerPel = dwBpp; - devmode->dmPelsHeight = GetSystemMetrics(SM_CYSCREEN); - devmode->dmPelsWidth = GetSystemMetrics(SM_CXSCREEN); - devmode->dmFields = (DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL); - TRACE("mode %ld (registry) -- returning default %ldx%ldx%ldbpp\n", n, - devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel); - return TRUE; - } - if (n < dd_mode_count) - { - devmode->dmPelsWidth = dd_modes[n].dwWidth; - devmode->dmPelsHeight = dd_modes[n].dwHeight; - devmode->dmBitsPerPel = dd_modes[n].dwBPP; - devmode->dmDisplayFrequency = dd_modes[n].wRefreshRate; - devmode->dmFields = (DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL|DM_DISPLAYFREQUENCY); - TRACE("mode %ld -- %ldx%ldx%ldbpp %ld Hz\n", n, - devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel, - devmode->dmDisplayFrequency); - return TRUE; - } - TRACE("mode %ld -- not present\n", n); - return FALSE; -} - -/* implementation of ChangeDisplaySettings for XF86VM */ -LONG X11DRV_XF86VM_ChangeDisplaySettingsExW( LPCWSTR devname, LPDEVMODEW devmode, - HWND hwnd, DWORD flags, LPVOID lpvoid ) -{ - DWORD i; - DWORD dwBpp = screen_depth; - if (dwBpp == 24) dwBpp = 32; - if (devmode==NULL) - { -#ifdef HAVE_LIBXXF86VM - X11DRV_XF86VM_SetCurrentMode(xf86vm_initial_mode); -#endif - return DISP_CHANGE_SUCCESSFUL; - } - -#if 0 /* FIXME: only works if we update SYSMETRICS */ - if ((!(devmode->dmFields & DM_BITSPERPEL) || devmode->dmBitsPerPel == dwBpp) && - (!(devmode->dmFields & DM_PELSWIDTH) || devmode->dmPelsWidth == GetSystemMetrics(SM_CXSCREEN)) && - (!(devmode->dmFields & DM_PELSHEIGHT) || devmode->dmPelsHeight == GetSystemMetrics(SM_CYSCREEN))) - { - /* we have a valid mode */ - TRACE("Requested mode matches current mode -- no change!\n"); - return DISP_CHANGE_SUCCESSFUL; - } -#endif - -#ifdef HAVE_LIBXXF86VM - for (i = 0; i < dd_mode_count; i++) - { - if (devmode->dmFields & DM_BITSPERPEL) - { - if (devmode->dmBitsPerPel != dd_modes[i].dwBPP) - continue; - } - if (devmode->dmFields & DM_PELSWIDTH) - { - if (devmode->dmPelsWidth != dd_modes[i].dwWidth) - continue; - } - if (devmode->dmFields & DM_PELSHEIGHT) - { - if (devmode->dmPelsHeight != dd_modes[i].dwHeight) - continue; - } - if (devmode->dmFields & DM_DISPLAYFREQUENCY) - { - if (devmode->dmDisplayFrequency != dd_modes[i].wRefreshRate) - continue; - } - /* we have a valid mode */ - TRACE("Requested display settings match mode %ld\n", i); - X11DRV_XF86VM_SetCurrentMode(i); - if (dwBpp != dd_modes[i].dwBPP) - { - FIXME("Cannot change screen BPP from %ld to %ld\n", dwBpp, dd_modes[i].dwBPP); - } - return DISP_CHANGE_SUCCESSFUL; - } -#endif - - /* no valid modes found */ - ERR("No matching mode found!\n"); - return DISP_CHANGE_BADMODE; -} - -/* implementation of EnumDisplaySettings for nores */ -BOOL X11DRV_nores_EnumDisplaySettingsExW( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DWORD flags) -{ - DWORD dwBpp = screen_depth; - if (dwBpp == 24) dwBpp = 32; - devmode->dmDisplayFlags = 0; - devmode->dmDisplayFrequency = 85; - devmode->dmSize = sizeof(DEVMODEW); - if (n==0 || n == (DWORD)-1 || n == (DWORD)-2) - { - devmode->dmBitsPerPel = dwBpp; - devmode->dmPelsHeight = GetSystemMetrics(SM_CYSCREEN); - devmode->dmPelsWidth = GetSystemMetrics(SM_CXSCREEN); - devmode->dmFields = (DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL); - TRACE("mode %ld -- returning default %ldx%ldx%ldbpp\n", n, - devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel); - return TRUE; - } - TRACE("mode %ld -- not present\n", n); - return FALSE; -} - -/* implementation of ChangeDisplaySettings for nores */ -LONG X11DRV_nores_ChangeDisplaySettingsExW( LPCWSTR devname, LPDEVMODEW devmode, - HWND hwnd, DWORD flags, LPVOID lpvoid ) -{ - DWORD dwBpp = screen_depth; - if (dwBpp == 24) dwBpp = 32; - if (devmode==NULL) - { - return DISP_CHANGE_SUCCESSFUL; - } - - if ((!(devmode->dmFields & DM_BITSPERPEL) || devmode->dmBitsPerPel == dwBpp) && - (!(devmode->dmFields & DM_PELSWIDTH) || devmode->dmPelsWidth == GetSystemMetrics(SM_CXSCREEN)) && - (!(devmode->dmFields & DM_PELSHEIGHT) || devmode->dmPelsHeight == GetSystemMetrics(SM_CYSCREEN))) - { - /* we are in the desired mode */ - TRACE("Requested mode matches current mode -- no change!\n"); - return DISP_CHANGE_SUCCESSFUL; - } - - /* no valid modes found */ - ERR("No matching mode found!\n"); - return DISP_CHANGE_BADMODE; -} - -/*********************************************************************** - * EnumDisplaySettingsExW (X11DRV.@) - * - * FIXME: should move to somewhere appropriate - */ -BOOL X11DRV_EnumDisplaySettingsExW( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DWORD flags) -{ - if (dd_modes) - { - /* XVidMode */ - return X11DRV_XF86VM_EnumDisplaySettingsExW(name, n, devmode, flags); - } - else if (in_desktop_mode) - { - /* desktop */ - return X11DRV_desktop_EnumDisplaySettingsExW(name, n, devmode, flags); - } - else - { - /* no resolution changing */ - return X11DRV_nores_EnumDisplaySettingsExW(name, n, devmode, flags); - } -} - -#define _X_FIELD(prefix, bits) if ((fields) & prefix##_##bits) {p+=sprintf(p, "%s%s", first ? "" : ",", #bits); first=FALSE;} -static const char * _CDS_flags(DWORD fields) -{ - BOOL first = TRUE; - char buf[128]; - char *p = buf; - _X_FIELD(CDS,UPDATEREGISTRY);_X_FIELD(CDS,TEST);_X_FIELD(CDS,FULLSCREEN); - _X_FIELD(CDS,GLOBAL);_X_FIELD(CDS,SET_PRIMARY);_X_FIELD(CDS,RESET); - _X_FIELD(CDS,SETRECT);_X_FIELD(CDS,NORESET); - *p = 0; - return wine_dbg_sprintf("%s", buf); -} -static const char * _DM_fields(DWORD fields) -{ - BOOL first = TRUE; - char buf[128]; - char *p = buf; - _X_FIELD(DM,BITSPERPEL);_X_FIELD(DM,PELSWIDTH);_X_FIELD(DM,PELSHEIGHT); - _X_FIELD(DM,DISPLAYFLAGS);_X_FIELD(DM,DISPLAYFREQUENCY);_X_FIELD(DM,POSITION); - *p = 0; - return wine_dbg_sprintf("%s", buf); -} -#undef _X_FIELD - -/*********************************************************************** - * ChangeDisplaySettingsExW (X11DRV.@) - * - * FIXME: should move to somewhere appropriate - */ -LONG X11DRV_ChangeDisplaySettingsExW( LPCWSTR devname, LPDEVMODEW devmode, - HWND hwnd, DWORD flags, LPVOID lpvoid ) -{ - TRACE("(%s,%p,%p,0x%08lx,%p\n",debugstr_w(devname),devmode,hwnd,flags,lpvoid); - TRACE("flags=%s\n",_CDS_flags(flags)); - if (devmode) - { - TRACE("DM_fields=%s\n",_DM_fields(devmode->dmFields)); - TRACE("width=%ld height=%ld bpp=%ld freq=%ld\n", - devmode->dmPelsWidth,devmode->dmPelsHeight, - devmode->dmBitsPerPel,devmode->dmDisplayFrequency); - } - else - { - TRACE("Return to original display mode\n"); - } - if (dd_modes) - { - /* XVidMode */ - return X11DRV_XF86VM_ChangeDisplaySettingsExW( devname, devmode, - hwnd, flags, lpvoid ); - } - else if (in_desktop_mode) - { - /* no XVidMode */ - return X11DRV_desktop_ChangeDisplaySettingsExW( devname, devmode, - hwnd, flags, lpvoid ); - } - else - { - /* no resolution changing */ - return X11DRV_nores_ChangeDisplaySettingsExW( devname, devmode, - hwnd, flags, lpvoid ); - } -} diff --git a/dlls/x11drv/xvidmode.h b/dlls/x11drv/xvidmode.h index 2113cc4fd3c..03dd008184e 100644 --- a/dlls/x11drv/xvidmode.h +++ b/dlls/x11drv/xvidmode.h @@ -31,15 +31,9 @@ #include "wingdi.h" #include "ddrawi.h" -extern LPDDHALMODEINFO xf86vm_modes; -extern unsigned xf86vm_mode_count; - void X11DRV_XF86VM_Init(void); void X11DRV_XF86VM_Cleanup(void); -int X11DRV_XF86VM_GetCurrentMode(void); -void X11DRV_XF86VM_SetCurrentMode(int mode); void X11DRV_XF86VM_SetExclusiveMode(int lock); -int X11DRV_XF86VM_CreateDriver(LPDDHALINFO info); BOOL X11DRV_XF86VM_GetGammaRamp(LPDDGAMMARAMP ramp); BOOL X11DRV_XF86VM_SetGammaRamp(LPDDGAMMARAMP ramp);