26 static char *
find_modeline(
char *modeString,
char *pModeLines,
32 #define LOC QString("NVCtrl: ")
53 int sync = NV_CTRL_SYNC_TO_VBLANK_OFF;
62 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"OpenGL Sync to VBlank is disabled.");
63 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"For best results enable this in NVidia settings or try running:");
64 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"nvidia-settings -a \"SyncToVBlank=1\"");
67 if (!sync && getenv(
"__GL_SYNC_TO_VBLANK"))
69 LOG(VB_GENERAL, LOG_INFO,
LOC +
70 "OpenGL Sync to VBlank enabled via __GL_SYNC_TO_VBLANK.");
75 LOG(VB_GENERAL, LOG_WARNING,
LOC +
76 "Alternatively try setting the '__GL_SYNC_TO_VBLANK' environment variable.");
93 int screen, display_devices, mask, major, minor,
len, j;
97 char *pMetaModes, *pModeLines[8], *
tmp, *modeString;
98 char *modeLine, *modeName;
99 int MetaModeLen, ModeLineLen[8];
103 map<int, map<int,bool> > maprate;
105 memset(pModeLines, 0,
sizeof(pModeLines));
106 memset(ModeLineLen, 0,
sizeof(ModeLineLen));
118 LOG(VB_PLAYBACK, LOG_INFO,
119 QString(
"The NV-CONTROL X extension is not available on screen %1 "
121 .arg(screen) .arg(XDisplayName(NULL)));
129 LOG(VB_PLAYBACK, LOG_INFO,
130 QString(
"The NV-CONTROL X extension does not exist on '%1'.")
131 .arg(XDisplayName(NULL)));
140 LOG(VB_PLAYBACK, LOG_ERR,
141 "Failed to query if Dynamic Twinview is enabled");
147 LOG(VB_PLAYBACK, LOG_ERR,
"Dynamic Twinview not enabled, ignoring");
158 NV_CTRL_CONNECTED_DISPLAYS, &display_devices);
162 LOG(VB_PLAYBACK, LOG_ERR,
163 "Failed to query the enabled Display Devices.");
171 NV_CTRL_BINARY_DATA_METAMODES,
172 (
unsigned char **)&pMetaModes, &MetaModeLen);
175 LOG(VB_PLAYBACK, LOG_ERR,
176 "Failed to query the metamode on selected display device.");
188 for (mask = 1; mask < (1 << 24); mask <<= 1)
190 if (!(display_devices & mask))
continue;
193 NV_CTRL_BINARY_DATA_MODELINES,
194 (
unsigned char **)&str, &len);
197 LOG(VB_PLAYBACK, LOG_ERR,
198 "Unknown error. Failed to query the enabled Display Devices.");
200 for (j=0; j < nDisplayDevice; ++j)
208 pModeLines[nDisplayDevice] = str;
209 ModeLineLen[nDisplayDevice] =
len;
215 str = start = pMetaModes;
217 for (j = 0; j < MetaModeLen - 1; ++j)
224 if ((str[j] ==
'\0') && (str[j+1] !=
'\0'))
233 tmp = strstr(start,
"::");
245 char *strtok_state = NULL;
246 for (modeString = strtok_r(tmp,
",", &strtok_state);
248 modeString = strtok_r(NULL,
",", &strtok_state))
261 for (mask = 1; mask < (1 << 24); mask <<= 1)
263 if (!(display_devices & mask))
continue;
264 if (thisMask & mask)
break;
270 pModeLines[nDisplayDevice],
271 ModeLineLen[nDisplayDevice]);
275 int w, h, vfl, hfl, i, irate;
281 tmp = strchr(modeLine,
'"');
282 tmp = strchr(tmp+1,
'"') +1 ;
286 for (modeString = strtok_r(tmp,
" ", &strtok_state);
288 modeString = strtok_r(NULL,
" ", &strtok_state))
290 buf[i++] = modeString;
292 w = strtol(buf[1], NULL, 10);
293 h = strtol(buf[5], NULL, 10);
294 vfl = strtol(buf[8], NULL, 10);
295 hfl = strtol(buf[4], NULL, 10);
296 h = strtol(buf[5], NULL, 10);
297 istringstream istr(buf[0]);
298 istr.imbue(locale(
"C"));
300 r = (dcl * 1000000.0) / (vfl * hfl);
301 irate = (
int) round(r * 1000.0);
305 if (maprate.find(key2) == maprate.end())
308 maprate[key2] = map<int, bool>();
310 if ((maprate[key2].
find(irate) == maprate[key2].end()) &&
311 (screenmap.find(key) == screenmap.end()))
314 maprate[key2][irate] =
true;
325 for (j=0; j < nDisplayDevice; ++j)
332 #else // USING_XRANDR
345 if (strcmp(str,
"CRT-0") == 0)
return (1 << 0);
346 if (strcmp(str,
"CRT-1") == 0)
return (1 << 1);
347 if (strcmp(str,
"CRT-2") == 0)
return (1 << 2);
348 if (strcmp(str,
"CRT-3") == 0)
return (1 << 3);
349 if (strcmp(str,
"CRT-4") == 0)
return (1 << 4);
350 if (strcmp(str,
"CRT-5") == 0)
return (1 << 5);
351 if (strcmp(str,
"CRT-6") == 0)
return (1 << 6);
352 if (strcmp(str,
"CRT-7") == 0)
return (1 << 7);
354 if (strcmp(str,
"TV-0") == 0)
return (1 << 8);
355 if (strcmp(str,
"TV-1") == 0)
return (1 << 9);
356 if (strcmp(str,
"TV-2") == 0)
return (1 << 10);
357 if (strcmp(str,
"TV-3") == 0)
return (1 << 11);
358 if (strcmp(str,
"TV-4") == 0)
return (1 << 12);
359 if (strcmp(str,
"TV-5") == 0)
return (1 << 13);
360 if (strcmp(str,
"TV-6") == 0)
return (1 << 14);
361 if (strcmp(str,
"TV-7") == 0)
return (1 << 15);
363 if (strcmp(str,
"DFP-0") == 0)
return (1 << 16);
364 if (strcmp(str,
"DFP-1") == 0)
return (1 << 17);
365 if (strcmp(str,
"DFP-2") == 0)
return (1 << 18);
366 if (strcmp(str,
"DFP-3") == 0)
return (1 << 19);
367 if (strcmp(str,
"DFP-4") == 0)
return (1 << 20);
368 if (strcmp(str,
"DFP-5") == 0)
return (1 << 21);
369 if (strcmp(str,
"DFP-6") == 0)
return (1 << 22);
370 if (strcmp(str,
"DFP-7") == 0)
return (1 << 23);
385 char *colon, *s_end,
tmp;
388 while (*modeString ==
' ')
392 colon = strchr(modeString,
':');
399 modeString = colon + 1;
407 while (*modeString ==
' ')
416 s_end = strchr(modeString,
'\0');
418 for (
char *s = modeString; *s; s++)
420 if (*s ==
' ' && *(s+1) ==
'@')
426 *modeName = strdup(modeString);
437 static char *
find_modeline(
char *modeName,
char *pModeLines,
int ModeLineLen)
439 char *start, *beginQuote, *endQuote;
444 for (j = 0; j < ModeLineLen; j++)
446 if (pModeLines[j] ==
'\0')
454 beginQuote = strchr(start,
'"');
455 endQuote = beginQuote ? strchr(beginQuote+1,
'"') : NULL;
457 if (beginQuote && endQuote)
460 match = (strcmp(modeName, beginQuote+1) == 0);
470 char *
tmp = strstr(start,
"::");
482 start = &pModeLines[j+1];
498 begin = strstr(str,
"id=");
503 if (!(begin = end = strdup(begin + 3)))
507 while (isdigit(*end))
522 return (strstr(modeLine,
"Interlace") != NULL);