/* create the mode structures */ static void make_modes(void) { RECT primary_rect = get_primary_monitor_rect(); unsigned int i; unsigned int screen_width = primary_rect.right - primary_rect.left; unsigned int screen_height = primary_rect.bottom - primary_rect.top; /* original specified desktop size */ X11DRV_Settings_AddOneMode(screen_width, screen_height, 0, 60); for (i=0; i<NUM_DESKTOP_MODES; i++) { if ( (widths[i] <= max_width) && (heights[i] <= max_height) ) { if ( ( (widths[i] != max_width) || (heights[i] != max_height) ) && ( (widths[i] != screen_width) || (heights[i] != screen_height) ) ) { /* only add them if they are smaller than the root window and unique */ X11DRV_Settings_AddOneMode(widths[i], heights[i], 0, 60); } } } if ((max_width != screen_width) && (max_height != screen_height)) { /* root window size (if different from desktop window) */ X11DRV_Settings_AddOneMode(max_width, max_height, 0, 60); } }
/* 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, 60); }
static void convert_modeinfo( const XF86VidModeModeInfo *mode) { int rate; if (mode->htotal!=0 && mode->vtotal!=0) rate = mode->dotclock * 1000 / (mode->htotal * mode->vtotal); else rate = 0; X11DRV_Settings_AddOneMode(mode->hdisplay, mode->vdisplay, 0, rate); }
/* create the mode structures */ static void make_modes(void) { int i, j; for (i=0; i<real_xrandr_sizes_count; i++) { if (real_xrandr_rates_count[i]) { for (j=0; j < real_xrandr_rates_count[i]; j++) { X11DRV_Settings_AddOneMode(real_xrandr_sizes[i].width, real_xrandr_sizes[i].height, 0, real_xrandr_rates[i][j]); } } else { X11DRV_Settings_AddOneMode(real_xrandr_sizes[i].width, real_xrandr_sizes[i].height, 0, 0); } } }
/* 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_bpp; const DWORD *depths = screen_bpp == 32 ? depths_32 : depths_24; 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); } } } }
static int xrandr12_init_modes(void) { unsigned int only_one_resolution = 1, mode_count; XRRScreenResources *resources; XRROutputInfo *output_info; XRRCrtcInfo *crtc_info; int ret = -1; int i, j; if (!(resources = pXRRGetScreenResourcesCurrent( gdi_display, root_window ))) { ERR("Failed to get screen resources.\n"); return ret; } if (!resources->ncrtc) { pXRRFreeScreenResources( resources ); if (!(resources = pXRRGetScreenResources( gdi_display, root_window ))) { ERR("Failed to get screen resources.\n"); return ret; } } if (!(crtc_info = xrandr12_get_primary_crtc_info( resources, &primary_crtc ))) { pXRRFreeScreenResources( resources ); ERR("Failed to get primary CRTC info.\n"); return ret; } TRACE("CRTC %d: mode %#lx, %ux%u+%d+%d.\n", primary_crtc, crtc_info->mode, crtc_info->width, crtc_info->height, crtc_info->x, crtc_info->y); if (!crtc_info->noutput || !(output_info = pXRRGetOutputInfo( gdi_display, resources, crtc_info->outputs[0] ))) { pXRRFreeCrtcInfo( crtc_info ); pXRRFreeScreenResources( resources ); ERR("Failed to get output info.\n"); return ret; } TRACE("OUTPUT 0: name %s.\n", debugstr_a(output_info->name)); if (!output_info->nmode) { ERR("Output has no modes.\n"); goto done; } if (!(xrandr12_modes = HeapAlloc( GetProcessHeap(), 0, sizeof(*xrandr12_modes) * output_info->nmode ))) { ERR("Failed to allocate xrandr mode info array.\n"); goto done; } dd_modes = X11DRV_Settings_SetHandlers( "XRandR 1.2", xrandr12_get_current_mode, xrandr12_set_current_mode, output_info->nmode, 1 ); xrandr_mode_count = 0; for (i = 0; i < output_info->nmode; ++i) { for (j = 0; j < resources->nmode; ++j) { XRRModeInfo *mode = &resources->modes[j]; if (mode->id == output_info->modes[i]) { unsigned int dots = mode->hTotal * mode->vTotal; unsigned int refresh = dots ? (mode->dotClock + dots / 2) / dots : 0; TRACE("Adding mode %#lx: %ux%u@%u.\n", mode->id, mode->width, mode->height, refresh); X11DRV_Settings_AddOneMode( mode->width, mode->height, 0, refresh ); xrandr12_modes[xrandr_mode_count++] = mode->id; break; } } } mode_count = X11DRV_Settings_GetModeCount(); for (i = 1; i < mode_count; ++i) { if (dd_modes[i].width != dd_modes[0].width || dd_modes[i].height != dd_modes[0].height) { only_one_resolution = 0; break; } } /* Recent (304.64, possibly earlier) versions of the nvidia driver only * report a DFP's native mode through RandR 1.2 / 1.3. Standard DMT modes * are only listed through RandR 1.0 / 1.1. This is completely useless, * but NVIDIA considers this a feature, so it's unlikely to change. The * best we can do is to fall back to RandR 1.0 and encourage users to * consider more cooperative driver vendors when we detect such a * configuration. */ if (only_one_resolution && XQueryExtension( gdi_display, "NV-CONTROL", &i, &j, &ret )) { ERR_(winediag)("Broken NVIDIA RandR detected, falling back to RandR 1.0. " "Please consider using the Nouveau driver instead.\n"); ret = -1; HeapFree( GetProcessHeap(), 0, xrandr12_modes ); goto done; } X11DRV_Settings_AddDepthModes(); ret = 0; done: pXRRFreeOutputInfo( output_info ); pXRRFreeCrtcInfo( crtc_info ); pXRRFreeScreenResources( resources ); return ret; }
static void xrandr10_init_modes(void) { XRRScreenSize *sizes; int sizes_count; int i, j, nmodes = 0; sizes = pXRRSizes( gdi_display, DefaultScreen(gdi_display), &sizes_count ); if (sizes_count <= 0) return; TRACE("XRandR: found %d sizes.\n", sizes_count); for (i = 0; i < sizes_count; ++i) { int rates_count; short *rates; rates = pXRRRates( gdi_display, DefaultScreen(gdi_display), i, &rates_count ); TRACE("- at %d: %dx%d (%d rates):", i, sizes[i].width, sizes[i].height, rates_count); if (rates_count) { nmodes += rates_count; for (j = 0; j < rates_count; ++j) { if (j > 0) TRACE(","); TRACE(" %d", rates[j]); } } else { ++nmodes; TRACE(" <default>"); } TRACE(" Hz\n"); } TRACE("XRandR modes: count=%d\n", nmodes); if (!(xrandr10_modes = HeapAlloc( GetProcessHeap(), 0, sizeof(*xrandr10_modes) * nmodes ))) { ERR("Failed to allocate xrandr mode info array.\n"); return; } dd_modes = X11DRV_Settings_SetHandlers( "XRandR 1.0", xrandr10_get_current_mode, xrandr10_set_current_mode, nmodes, 1 ); xrandr_mode_count = 0; for (i = 0; i < sizes_count; ++i) { int rates_count; short *rates; rates = pXRRRates( gdi_display, DefaultScreen(gdi_display), i, &rates_count ); if (rates_count) { for (j = 0; j < rates_count; ++j) { X11DRV_Settings_AddOneMode( sizes[i].width, sizes[i].height, 0, rates[j] ); xrandr10_modes[xrandr_mode_count++] = i; } } else { X11DRV_Settings_AddOneMode( sizes[i].width, sizes[i].height, 0, 0 ); xrandr10_modes[xrandr_mode_count++] = i; } } X11DRV_Settings_AddDepthModes(); nmodes = X11DRV_Settings_GetModeCount(); TRACE("Available DD modes: count=%d\n", nmodes); TRACE("Enabling XRandR\n"); }