1 // Copyright (C)2009-2021 D. R. Commander
2 //
3 // This library is free software and may be redistributed and/or modified under
4 // the terms of the wxWindows Library License, Version 3.1 or (at your option)
5 // any later version. The full license is in the LICENSE.txt file included
6 // with this distribution.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // wxWindows Library License for more details.
12
13 #include <ctype.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #include <math.h>
17 #include "Error.h"
18 #include "Log.h"
19 #include "Mutex.h"
20 #include "fakerconfig.h"
21 #include <stdio.h>
22 #include <X11/keysym.h>
23 #if FCONFIG_USESHM == 1
24 #include <sys/shm.h>
25 #include <sys/ipc.h>
26 #include <sys/types.h>
27 #endif
28 #include "vglutil.h"
29 #include <X11/Xatom.h>
30 #ifdef USEXV
31 #include <X11/extensions/Xv.h>
32 #include <X11/extensions/Xvlib.h>
33 #endif
34 #ifdef USEHELGRIND
35 #include <valgrind/helgrind.h>
36 #endif
37
38 using namespace vglutil;
39
40
41 #define DEFQUAL 95
42
43 static FakerConfig fconfig_env;
44 static bool fconfig_envset = false;
45
46 #if FCONFIG_USESHM == 1
47 static int fconfig_shmid = -1;
fconfig_getshmid(void)48 int fconfig_getshmid(void) { return fconfig_shmid; }
49 #endif
50 static FakerConfig *fconfig_instance = NULL;
51
52
53 // This is a hack necessary to defer the initialization of the recursive mutex
54 // so MainWin will not interfere with it
55
56 class DeferredCS : CriticalSection
57 {
58 public:
DeferredCS()59 DeferredCS() : isInit(false) {}
60
init(void)61 DeferredCS *init(void)
62 {
63 if(!isInit)
64 {
65 isInit = true;
66 pthread_mutexattr_t ma;
67 pthread_mutexattr_init(&ma);
68 pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
69 pthread_mutex_init(&mutex, &ma);
70 pthread_mutexattr_destroy(&ma);
71 }
72 return this;
73 }
74
75 private:
76
77 bool isInit;
78 };
79
80 static DeferredCS fconfig_mutex;
81 #define fcmutex ((CriticalSection &)(*fconfig_mutex.init()))
82
83
84 static void fconfig_init(void);
85
86
fconfig_getinstance(void)87 FakerConfig *fconfig_getinstance(void)
88 {
89 if(fconfig_instance == NULL)
90 {
91 CriticalSection::SafeLock l(fcmutex);
92 if(fconfig_instance == NULL)
93 {
94 #if FCONFIG_USESHM == 1
95
96 void *addr = NULL;
97 if((fconfig_shmid = shmget(IPC_PRIVATE, sizeof(FakerConfig),
98 IPC_CREAT | 0600)) == -1)
99 THROW_UNIX();
100 if((addr = shmat(fconfig_shmid, 0, 0)) == (void *)-1) THROW_UNIX();
101 if(!addr)
102 THROW("Could not attach to config structure in shared memory");
103 #ifndef sun
104 shmctl(fconfig_shmid, IPC_RMID, 0);
105 #endif
106 char *env = NULL;
107 if((env = getenv("VGL_VERBOSE")) != NULL && strlen(env) > 0
108 && !strncmp(env, "1", 1))
109 vglout.println("[VGL] Shared memory segment ID for vglconfig: %d",
110 fconfig_shmid);
111 fconfig_instance = (FakerConfig *)addr;
112
113 #else
114
115 fconfig_instance = new FakerConfig;
116 if(!fconfig_instance) THROW("Could not allocate config structure");
117
118 #endif
119
120 fconfig_init();
121 }
122 }
123 return fconfig_instance;
124 }
125
126
fconfig_deleteinstance(CriticalSection * mutex)127 void fconfig_deleteinstance(CriticalSection *mutex)
128 {
129 if(fconfig_instance != NULL)
130 {
131 CriticalSection::SafeLock l(mutex ? *mutex : fcmutex, false);
132 if(fconfig_instance != NULL)
133 {
134 #if FCONFIG_USESHM == 1
135
136 shmdt((char *)fconfig_instance);
137 if(fconfig_shmid != -1)
138 {
139 int ret = shmctl(fconfig_shmid, IPC_RMID, 0);
140 char *env = NULL;
141 if((env = getenv("VGL_VERBOSE")) != NULL && strlen(env) > 0
142 && !strncmp(env, "1", 1) && ret != -1)
143 vglout.println("[VGL] Removed shared memory segment %d",
144 fconfig_shmid);
145 }
146
147 #else
148
149 delete fconfig_instance;
150
151 #endif
152
153 fconfig_instance = NULL;
154 }
155 }
156 }
157
158
fconfig_init(void)159 static void fconfig_init(void)
160 {
161 CriticalSection::SafeLock l(fcmutex);
162 memset(&fconfig, 0, sizeof(FakerConfig));
163 memset(&fconfig_env, 0, sizeof(FakerConfig));
164 fconfig.compress = -1;
165 strncpy(fconfig.config, VGLCONFIG_PATH, MAXSTR);
166 #ifdef sun
167 fconfig.dlsymloader = true;
168 #endif
169 #ifdef FAKEXCB
170 fconfig.fakeXCB = 1;
171 #endif
172 fconfig.forcealpha = 0;
173 fconfig_setgamma(fconfig, 1.0);
174 fconfig.glflushtrigger = 1;
175 fconfig.gui = 1;
176 fconfig.guikey = XK_F9;
177 fconfig.guimod = ShiftMask | ControlMask;
178 fconfig.interframe = 1;
179 strncpy(fconfig.localdpystring, ":0", MAXSTR);
180 fconfig.np = 1;
181 fconfig.port = -1;
182 fconfig.probeglx = 1;
183 fconfig.qual = DEFQUAL;
184 fconfig.readback = RRREAD_PBO;
185 fconfig.refreshrate = 60.0;
186 fconfig.samples = -1;
187 fconfig.spoil = 1;
188 fconfig.spoillast = 1;
189 fconfig.stereo = RRSTEREO_QUADBUF;
190 fconfig.subsamp = -1;
191 fconfig.tilesize = RR_DEFAULTTILESIZE;
192 fconfig.transpixel = -1;
193 fconfig_reloadenv();
194 #ifdef USEHELGRIND
195 ANNOTATE_BENIGN_RACE_SIZED(&fconfig.egl, sizeof(bool), );
196 ANNOTATE_BENIGN_RACE_SIZED(&fconfig.flushdelay, sizeof(double), );
197 #endif
198 }
199
200
fconfig_buildlut(FakerConfig & fc)201 static void fconfig_buildlut(FakerConfig &fc)
202 {
203 if(fc.gamma != 0.0 && fc.gamma != 1.0 && fc.gamma != -1.0)
204 {
205 double g = fc.gamma > 0.0 ? 1.0 / fc.gamma : -fc.gamma;
206 for(int i = 0; i < 256; i++)
207 fc.gamma_lut[i] = (unsigned char)(255. * pow((double)i / 255., g) + 0.5);
208 for(int i = 0; i < 1024; i++)
209 fc.gamma_lut10[i] =
210 (unsigned short)(1023. * pow((double)i / 1023., g) + 0.5);
211 for(int i = 0; i < 65536; i++)
212 {
213 fc.gamma_lut16[i] =
214 (unsigned short)(255. * pow((double)(i / 256) / 255., g) + 0.5) << 8;
215 fc.gamma_lut16[i] |=
216 (unsigned short)(255. * pow((double)(i % 256) / 255., g) + 0.5);
217 }
218 }
219 }
220
221
222 #define FETCHENV_STR(envvar, s) \
223 { \
224 if((env = getenv(envvar)) != NULL && strlen(env) > 0 \
225 && (!fconfig_envset || strncmp(env, fconfig_env.s, MAXSTR - 1))) \
226 { \
227 strncpy(fconfig.s, env, MAXSTR - 1); \
228 strncpy(fconfig_env.s, env, MAXSTR - 1); \
229 } \
230 }
231
232 #define FETCHENV_BOOL(envvar, b) \
233 { \
234 if((env = getenv(envvar)) != NULL && strlen(env) > 0) \
235 { \
236 if(!strncmp(env, "1", 1) && (!fconfig_envset || fconfig_env.b != 1)) \
237 fconfig.b = fconfig_env.b = 1; \
238 else if(!strncmp(env, "0", 1) && (!fconfig_envset || fconfig_env.b != 0)) \
239 fconfig.b = fconfig_env.b = 0; \
240 } \
241 }
242
243 #define FETCHENV_INT(envvar, i, min, max) \
244 { \
245 if((env = getenv(envvar)) != NULL && strlen(env) > 0) \
246 { \
247 char *t = NULL; int itemp = strtol(env, &t, 10); \
248 if(t && t != env && itemp >= min && itemp <= max \
249 && (!fconfig_envset || itemp != fconfig_env.i)) \
250 fconfig.i = fconfig_env.i = itemp; \
251 } \
252 }
253
254 #define FETCHENV_DBL(envvar, d, min, max) \
255 { \
256 char *temp = NULL; \
257 if((temp = getenv(envvar)) != NULL && strlen(temp) > 0) \
258 { \
259 char *t = NULL; double dtemp = strtod(temp, &t); \
260 if(t && t != temp && dtemp >= min && dtemp <= max \
261 && (!fconfig_envset || dtemp != fconfig_env.d)) \
262 fconfig.d = fconfig_env.d = dtemp; \
263 } \
264 }
265
266
fconfig_setgamma(FakerConfig & fc,double gamma)267 void fconfig_setgamma(FakerConfig &fc, double gamma)
268 {
269 fc.gamma = gamma;
270 fconfig_buildlut(fc);
271 }
272
273
fconfig_reloadenv(void)274 void fconfig_reloadenv(void)
275 {
276 char *env;
277
278 CriticalSection::SafeLock l(fcmutex);
279
280 FETCHENV_BOOL("VGL_ALLOWINDIRECT", allowindirect);
281 FETCHENV_BOOL("VGL_AMDGPUHACK", amdgpuHack);
282 FETCHENV_BOOL("VGL_AUTOTEST", autotest);
283 FETCHENV_STR("VGL_CLIENT", client);
284 if((env = getenv("VGL_SUBSAMP")) != NULL && strlen(env) > 0)
285 {
286 int subsamp = -1;
287 if(!strnicmp(env, "G", 1)) subsamp = 0;
288 else
289 {
290 char *t = NULL; int itemp = strtol(env, &t, 10);
291 if(t && t != env)
292 {
293 switch(itemp)
294 {
295 case 0: subsamp = 0; break;
296 case 444: case 11: case 1: subsamp = 1; break;
297 case 422: case 21: case 2: subsamp = 2; break;
298 case 411: case 420: case 22: case 4: subsamp = 4; break;
299 case 410: case 42: case 8: subsamp = 8; break;
300 case 44: case 16: subsamp = 16; break;
301 }
302 }
303 }
304 if(subsamp >= 0 && (!fconfig_envset || fconfig_env.subsamp != subsamp))
305 fconfig.subsamp = fconfig_env.subsamp = subsamp;
306 }
307 FETCHENV_STR("VGL_TRANSPORT", transport);
308 if((env = getenv("VGL_COMPRESS")) != NULL && strlen(env) > 0)
309 {
310 char *t = NULL; int itemp = strtol(env, &t, 10);
311 int compress = -1;
312 if(t && t != env && itemp >= 0
313 && (itemp < RR_COMPRESSOPT || strlen(fconfig.transport) > 0))
314 compress = itemp;
315 else if(!strnicmp(env, "p", 1)) compress = RRCOMP_PROXY;
316 else if(!strnicmp(env, "j", 1)) compress = RRCOMP_JPEG;
317 else if(!strnicmp(env, "r", 1)) compress = RRCOMP_RGB;
318 else if(!strnicmp(env, "x", 1)) compress = RRCOMP_XV;
319 else if(!strnicmp(env, "y", 1)) compress = RRCOMP_YUV;
320 if(compress >= 0 && (!fconfig_envset || fconfig_env.compress != compress))
321 {
322 fconfig_setcompress(fconfig, compress);
323 fconfig_env.compress = compress;
324 }
325 }
326 FETCHENV_STR("VGL_CONFIG", config);
327 FETCHENV_STR("VGL_DEFAULTFBCONFIG", defaultfbconfig);
328 if((env = getenv("VGL_DISPLAY")) != NULL && strlen(env) > 0)
329 {
330 if(!fconfig_envset || strncmp(env, fconfig_env.localdpystring, MAXSTR - 1))
331 {
332 strncpy(fconfig.localdpystring, env, MAXSTR - 1);
333 strncpy(fconfig_env.localdpystring, env, MAXSTR - 1);
334 }
335 if((env[0] == '/' || !strnicmp(env, "EGL", 3)))
336 fconfig.egl = true;
337 }
338 FETCHENV_BOOL("VGL_DLSYM", dlsymloader);
339 #ifdef EGLBACKEND
340 FETCHENV_STR("VGL_EGLLIB", egllib);
341 #endif
342 FETCHENV_STR("VGL_EXCLUDE", excludeddpys);
343 #ifdef FAKEXCB
344 FETCHENV_BOOL("VGL_FAKEXCB", fakeXCB);
345 #endif
346 FETCHENV_BOOL("VGL_FORCEALPHA", forcealpha);
347 FETCHENV_DBL("VGL_FPS", fps, 0.0, 1000000.0);
348 if((env = getenv("VGL_GAMMA")) != NULL && strlen(env) > 0)
349 {
350 if(!strcmp(env, "1"))
351 {
352 if(!fconfig_envset || fconfig_env.gamma != 2.22)
353 {
354 fconfig_env.gamma = 2.22;
355 fconfig_setgamma(fconfig, 2.22);
356 }
357 }
358 else if(!strcmp(env, "0"))
359 {
360 if(!fconfig_envset || fconfig_env.gamma != 1.0)
361 {
362 fconfig_env.gamma = 1.0;
363 fconfig_setgamma(fconfig, 1.0);
364 }
365 }
366 else
367 {
368 char *t = NULL; double dtemp = strtod(env, &t);
369 if(t && t != env
370 && (!fconfig_envset || fconfig_env.gamma != dtemp))
371 {
372 fconfig_env.gamma = dtemp;
373 fconfig_setgamma(fconfig, dtemp);
374 }
375 }
376 }
377 FETCHENV_BOOL("VGL_GLFLUSHTRIGGER", glflushtrigger);
378 FETCHENV_STR("VGL_GLLIB", gllib);
379 FETCHENV_STR("VGL_GLXVENDOR", glxvendor);
380 FETCHENV_STR("VGL_GUI", guikeyseq);
381 if(strlen(fconfig.guikeyseq) > 0)
382 {
383 if(!stricmp(fconfig.guikeyseq, "none")) fconfig.gui = false;
384 else
385 {
386 unsigned int mod = 0, key = 0;
387 for(unsigned int i = 0; i < strlen(fconfig.guikeyseq); i++)
388 fconfig.guikeyseq[i] = tolower(fconfig.guikeyseq[i]);
389 if(strstr(fconfig.guikeyseq, "ctrl")) mod |= ControlMask;
390 if(strstr(fconfig.guikeyseq, "alt")) mod |= Mod1Mask;
391 if(strstr(fconfig.guikeyseq, "shift")) mod |= ShiftMask;
392 if(strstr(fconfig.guikeyseq, "f10")) key = XK_F10;
393 else if(strstr(fconfig.guikeyseq, "f11")) key = XK_F11;
394 else if(strstr(fconfig.guikeyseq, "f12")) key = XK_F12;
395 else if(strstr(fconfig.guikeyseq, "f1")) key = XK_F1;
396 else if(strstr(fconfig.guikeyseq, "f2")) key = XK_F2;
397 else if(strstr(fconfig.guikeyseq, "f3")) key = XK_F3;
398 else if(strstr(fconfig.guikeyseq, "f4")) key = XK_F4;
399 else if(strstr(fconfig.guikeyseq, "f5")) key = XK_F5;
400 else if(strstr(fconfig.guikeyseq, "f6")) key = XK_F6;
401 else if(strstr(fconfig.guikeyseq, "f7")) key = XK_F7;
402 else if(strstr(fconfig.guikeyseq, "f8")) key = XK_F8;
403 else if(strstr(fconfig.guikeyseq, "f9")) key = XK_F9;
404 if(key) fconfig.guikey = key; fconfig.guimod = mod;
405 fconfig.gui = true;
406 }
407 }
408 FETCHENV_BOOL("VGL_INTERFRAME", interframe);
409 FETCHENV_STR("VGL_LOG", log);
410 FETCHENV_BOOL("VGL_LOGO", logo);
411 FETCHENV_INT("VGL_NPROCS", np, 1, min(NumProcs(), MAXPROCS));
412 #ifdef FAKEOPENCL
413 FETCHENV_STR("VGL_OCLLIB", ocllib);
414 #endif
415 FETCHENV_INT("VGL_PORT", port, 0, 65535);
416 FETCHENV_BOOL("VGL_PROBEGLX", probeglx);
417 FETCHENV_INT("VGL_QUAL", qual, 1, 100);
418 if((env = getenv("VGL_READBACK")) != NULL && strlen(env) > 0)
419 {
420 int readback = -1;
421 if(!strnicmp(env, "N", 1)) readback = RRREAD_NONE;
422 else if(!strnicmp(env, "P", 1)) readback = RRREAD_PBO;
423 else if(!strnicmp(env, "S", 1)) readback = RRREAD_SYNC;
424 else
425 {
426 char *t = NULL; int itemp = strtol(env, &t, 10);
427 if(t && t != env && itemp >= 0 && itemp < RR_READBACKOPT)
428 readback = itemp;
429 }
430 if(readback >= 0 && (!fconfig_envset || fconfig_env.readback != readback))
431 fconfig.readback = fconfig_env.readback = readback;
432 }
433 FETCHENV_DBL("VGL_REFRESHRATE", refreshrate, 0.0, 1000000.0);
434 FETCHENV_INT("VGL_SAMPLES", samples, 0, 64);
435 FETCHENV_BOOL("VGL_SPOIL", spoil);
436 FETCHENV_BOOL("VGL_SPOILLAST", spoillast);
437 FETCHENV_BOOL("VGL_SSL", ssl);
438 {
439 if((env = getenv("VGL_STEREO")) != NULL && strlen(env) > 0)
440 {
441 int stereo = -1;
442 if(!strnicmp(env, "L", 1)) stereo = RRSTEREO_LEYE;
443 else if(!strnicmp(env, "RC", 2)) stereo = RRSTEREO_REDCYAN;
444 else if(!strnicmp(env, "R", 1)) stereo = RRSTEREO_REYE;
445 else if(!strnicmp(env, "Q", 1)) stereo = RRSTEREO_QUADBUF;
446 else if(!strnicmp(env, "GM", 2)) stereo = RRSTEREO_GREENMAGENTA;
447 else if(!strnicmp(env, "BY", 2)) stereo = RRSTEREO_BLUEYELLOW;
448 else if(!strnicmp(env, "I", 2)) stereo = RRSTEREO_INTERLEAVED;
449 else if(!strnicmp(env, "TB", 2)) stereo = RRSTEREO_TOPBOTTOM;
450 else if(!strnicmp(env, "SS", 2)) stereo = RRSTEREO_SIDEBYSIDE;
451 else
452 {
453 char *t = NULL; int itemp = strtol(env, &t, 10);
454 if(t && t != env && itemp >= 0 && itemp < RR_STEREOOPT) stereo = itemp;
455 }
456 if(stereo >= 0 && (!fconfig_envset || fconfig_env.stereo != stereo))
457 fconfig.stereo = fconfig_env.stereo = stereo;
458 }
459 }
460 FETCHENV_BOOL("VGL_SYNC", sync);
461 FETCHENV_INT("VGL_TILESIZE", tilesize, 8, 1024);
462 FETCHENV_BOOL("VGL_TRACE", trace);
463 FETCHENV_INT("VGL_TRANSPIXEL", transpixel, 0, 255);
464 FETCHENV_BOOL("VGL_TRAPX11", trapx11);
465 FETCHENV_STR("VGL_XVENDOR", vendor);
466 FETCHENV_BOOL("VGL_VERBOSE", verbose);
467 FETCHENV_BOOL("VGL_WM", wm);
468 FETCHENV_STR("VGL_X11LIB", x11lib);
469 #ifdef FAKEXCB
470 FETCHENV_STR("VGL_XCBLIB", xcblib);
471 FETCHENV_STR("VGL_XCBGLXLIB", xcbglxlib);
472 FETCHENV_STR("VGL_XCBKEYSYMSLIB", xcbkeysymslib);
473 FETCHENV_STR("VGL_XCBX11LIB", xcbkeysymslib);
474 #endif
475
476 if(strlen(fconfig.transport) > 0)
477 {
478 if(fconfig.compress < 0) fconfig.compress = 0;
479 if(fconfig.subsamp < 0) fconfig.subsamp = 1;
480 }
481
482 fconfig_envset = true;
483 }
484
485
fconfig_setdefaultsfromdpy(Display * dpy)486 void fconfig_setdefaultsfromdpy(Display *dpy)
487 {
488 CriticalSection::SafeLock l(fcmutex);
489
490 if(fconfig.compress < 0)
491 {
492 bool useSunRay = false;
493 Atom atom = None;
494 if((atom = XInternAtom(dpy, "_SUN_SUNRAY_SESSION", True)) != None)
495 useSunRay = true;
496 const char *dstr = DisplayString(dpy);
497 if((strlen(dstr) && dstr[0] == ':') || (strlen(dstr) > 5
498 && !strnicmp(dstr, "unix", 4)))
499 {
500 if(useSunRay) fconfig_setcompress(fconfig, RRCOMP_XV);
501 else fconfig_setcompress(fconfig, RRCOMP_PROXY);
502 }
503 else
504 {
505 if(useSunRay) fconfig_setcompress(fconfig, RRCOMP_YUV);
506 else fconfig_setcompress(fconfig, RRCOMP_JPEG);
507 }
508 }
509
510 if(fconfig.port < 0)
511 {
512 #ifdef USESSL
513 fconfig.port = fconfig.ssl ? RR_DEFAULTSSLPORT : RR_DEFAULTPORT;
514 #else
515 fconfig.port = RR_DEFAULTPORT;
516 #endif
517 Atom atom = None; unsigned long n = 0, bytesLeft = 0;
518 int actualFormat = 0; Atom actualType = None;
519 unsigned char *prop = NULL;
520 if((atom = XInternAtom(dpy,
521 fconfig.ssl ? "_VGLCLIENT_SSLPORT" : "_VGLCLIENT_PORT", True)) != None)
522 {
523 if(XGetWindowProperty(dpy, RootWindow(dpy, DefaultScreen(dpy)), atom, 0,
524 1, False, XA_INTEGER, &actualType, &actualFormat, &n, &bytesLeft,
525 &prop) == Success && n >= 1 && actualFormat == 16
526 && actualType == XA_INTEGER && prop)
527 fconfig.port = *(unsigned short *)prop;
528 if(prop) XFree(prop);
529 }
530 }
531
532 #ifdef USEXV
533
534 int k, port, nformats, dummy1, dummy2, dummy3;
535 unsigned int i, j, nadaptors = 0;
536 XvAdaptorInfo *ai = NULL;
537 XvImageFormatValues *ifv = NULL;
538
539 if(XQueryExtension(dpy, "XVideo", &dummy1, &dummy2, &dummy3)
540 && XvQueryAdaptors(dpy, DefaultRootWindow(dpy), &nadaptors,
541 &ai) == Success && nadaptors >= 1 && ai)
542 {
543 port = -1;
544 for(i = 0; i < nadaptors; i++)
545 {
546 for(j = ai[i].base_id; j < ai[i].base_id + ai[i].num_ports; j++)
547 {
548 nformats = 0;
549 ifv = XvListImageFormats(dpy, j, &nformats);
550 if(ifv && nformats > 0)
551 {
552 for(k = 0; k < nformats; k++)
553 {
554 if(ifv[k].id == 0x30323449)
555 {
556 XFree(ifv); port = j;
557 goto found;
558 }
559 }
560 }
561 XFree(ifv);
562 }
563 }
564 found:
565 XvFreeAdaptorInfo(ai); ai = NULL;
566 if(port != -1) fconfig.transvalid[RRTRANS_XV] = 1;
567 }
568
569 #endif
570 }
571
572
fconfig_setcompress(FakerConfig & fc,int i)573 void fconfig_setcompress(FakerConfig &fc, int i)
574 {
575 if(i < 0 || (i >= RR_COMPRESSOPT && strlen(fc.transport) == 0)) return;
576 CriticalSection::SafeLock l(fcmutex);
577
578 bool is = (fc.compress >= 0);
579 fc.compress = i;
580 if(strlen(fc.transport) > 0) return;
581 if(!is) fc.transvalid[_Trans[fc.compress]] = fc.transvalid[RRTRANS_X11] = 1;
582 if(fc.subsamp < 0) fc.subsamp = _Defsubsamp[fc.compress];
583 if(strlen(fc.transport) == 0 && _Minsubsamp[fc.compress] >= 0
584 && _Maxsubsamp[fc.compress] >= 0)
585 {
586 if(fc.subsamp < _Minsubsamp[fc.compress]
587 || fc.subsamp > _Maxsubsamp[fc.compress])
588 fc.subsamp = _Defsubsamp[fc.compress];
589 }
590 }
591
592
593 #define PRCONF_INT(i) vglout.println(#i " = %d", fc.i)
594 #define PRCONF_STR(s) \
595 vglout.println(#s " = \"%s\"", strlen(fc.s) > 0 ? fc.s : "{Empty}")
596 #define PRCONF_DBL(d) vglout.println(#d " = %f", fc.d)
597
fconfig_print(FakerConfig & fc)598 void fconfig_print(FakerConfig &fc)
599 {
600 PRCONF_INT(allowindirect);
601 PRCONF_INT(amdgpuHack);
602 PRCONF_STR(client);
603 PRCONF_INT(compress);
604 PRCONF_STR(config);
605 PRCONF_STR(defaultfbconfig);
606 PRCONF_INT(dlsymloader);
607 #ifdef EGLBACKEND
608 PRCONF_INT(egl);
609 PRCONF_STR(egllib);
610 #endif
611 PRCONF_STR(excludeddpys);
612 PRCONF_DBL(fps);
613 PRCONF_DBL(flushdelay);
614 PRCONF_INT(forcealpha);
615 PRCONF_DBL(gamma);
616 PRCONF_INT(glflushtrigger);
617 PRCONF_STR(gllib);
618 PRCONF_STR(glxvendor);
619 PRCONF_INT(gui);
620 PRCONF_INT(guikey);
621 PRCONF_STR(guikeyseq);
622 PRCONF_INT(guimod);
623 PRCONF_INT(interframe);
624 PRCONF_STR(localdpystring);
625 PRCONF_STR(log);
626 PRCONF_INT(logo);
627 PRCONF_INT(np);
628 #ifdef FAKEOPENCL
629 PRCONF_STR(ocllib);
630 #endif
631 PRCONF_INT(port);
632 PRCONF_INT(qual);
633 PRCONF_INT(readback);
634 PRCONF_INT(samples);
635 PRCONF_INT(spoil);
636 PRCONF_INT(spoillast);
637 PRCONF_INT(ssl);
638 PRCONF_INT(stereo);
639 PRCONF_INT(subsamp);
640 PRCONF_INT(sync);
641 PRCONF_INT(tilesize);
642 PRCONF_INT(trace);
643 PRCONF_INT(transpixel);
644 PRCONF_INT(transvalid[RRTRANS_X11]);
645 PRCONF_INT(transvalid[RRTRANS_VGL]);
646 PRCONF_INT(transvalid[RRTRANS_XV]);
647 PRCONF_INT(trapx11);
648 PRCONF_STR(vendor);
649 PRCONF_INT(verbose);
650 PRCONF_INT(wm);
651 PRCONF_STR(x11lib);
652 #ifdef FAKEXCB
653 PRCONF_STR(xcblib);
654 PRCONF_STR(xcbglxlib);
655 PRCONF_STR(xcbkeysymslib);
656 PRCONF_STR(xcbx11lib);
657 #endif
658 }
659