diff options
Diffstat (limited to 'nx-X11/programs/Xserver/hw/nxagent/Args.c')
-rw-r--r-- | nx-X11/programs/Xserver/hw/nxagent/Args.c | 2357 |
1 files changed, 2357 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c new file mode 100644 index 000000000..07526de56 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c @@ -0,0 +1,2357 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */ +/* */ +/* NXAGENT, NX protocol compression and NX extensions to this software */ +/* are copyright of NoMachine. Redistribution and use of the present */ +/* software is allowed according to terms specified in the file LICENSE */ +/* which comes in the source distribution. */ +/* */ +/* Check http://www.nomachine.com/licensing.html for applicability. */ +/* */ +/* NX and NoMachine are trademarks of NoMachine S.r.l. */ +/* */ +/* All rights reserved. */ +/* */ +/**************************************************************************/ + +/* + +Copyright 1993 by Davor Matic + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation. Davor Matic makes no representations about +the suitability of this software for any purpose. It is provided "as +is" without express or implied warranty. + +*/ + +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#ifdef __sun +#include <strings.h> +#endif + +#include "X.h" +#include "Xproto.h" +#include "screenint.h" +#include "input.h" +#include "misc.h" +#include "scrnintstr.h" +#include "dixstruct.h" +#include "servermd.h" +#include "opaque.h" + +#include "Agent.h" +#include "Display.h" +#include "Args.h" +#include "Options.h" +#include "Binder.h" +#include "Trap.h" +#include "Screen.h" +#include "Image.h" +#ifdef RENDER +#include "Render.h" +#endif +#include "Handlers.h" +#include "Error.h" + +/* + * NX includes and definitions. + */ + +#include "NXlib.h" +#include "NXpack.h" + +/* + * Set here the required log level. + */ + +#define PANIC +#define WARNING +#undef TEST +#undef DEBUG +#undef WATCH + +#ifdef WATCH + +#include "unistd.h" + +#endif + +/* + * Define this to force the dispatcher + * to always use the dumb scheduler. + */ + +#undef DISABLE_SMART_SCHEDULE + +int nxagentUserDefinedFontPath = 0; + +/* + * From X11/ImUtil.c. + */ + +extern int _XGetBitsPerPixel(Display *dpy, int depth); + +extern char dispatchExceptionAtReset; + +char nxagentDisplayName[1024]; + +char nxagentShadowDisplayName[1024] = {0}; + +char nxagentWindowName[256]; +char nxagentDialogName[256]; +char nxagentSessionId[256] = {0}; +char *nxagentOptionFile; + +Bool nxagentFullGeneration = False; +int nxagentDefaultClass = TrueColor; +Bool nxagentUserDefaultClass = False; +int nxagentDefaultDepth; +Bool nxagentUserDefaultDepth = False; +struct UserGeometry nxagentUserGeometry = {0, 0, 0, 0, 0}; +Bool nxagentUserBorderWidth = False; +int nxagentNumScreens = 0; +Bool nxagentDoDirectColormaps = False; +Window nxagentParentWindow = 0; +Bool nxagentIpaq = False; + +int nxagentLockDeferLevel = 0; + +Bool nxagentResizeDesktopAtStartup = False; + +Bool nxagentUseNXTrans = False; +Bool nxagentForceNXTrans = False; + +int nxagentMaxAllowedResets = 0; + +char *nxagentKeyboard = NULL; + +Bool nxagentOnce = True; + +static void nxagentParseOptionString(char*); + +/* + * Get the caption to be used for helper dialogs + * from agent's window name passed as parameter. + */ + +static int nxagentGetDialogName(void); + +char nxagentVerbose = 0; + +int ddxProcessArgument(int argc, char *argv[], int i) +{ + /* + * Ensure that the options are set to their defaults. + */ + + static Bool resetOptions = True; + + if (resetOptions == True) + { + char *envOptions = NULL; + char *envDisplay = NULL; + int j; + + nxagentInitOptions(); + + resetOptions = False; + + /* + * Ensure the correct order of options evaluation: + * the environment first, then those included in + * the options file and, last, the command line + * options. + */ + + envDisplay = getenv("DISPLAY"); + + if (envDisplay != NULL && strlen(envDisplay) == 0) + { + envDisplay = NULL; + } + + for (j = 0; j < argc; j++) + { + if ((!strcmp(argv[j], "-display")) && (j + 1 < argc)) + { + envOptions = malloc(strlen(argv[j + 1]) + 1); + + if (envOptions != NULL) + { + envOptions = strcpy(envOptions, argv[j + 1]); + } + #ifdef WARNING + else + { + fprintf(stderr, "ddxProcessArgument: WARNING! failed string allocation.\n"); + } + #endif + + break; + } + } + + if ((envOptions == NULL) && (envDisplay != NULL)) + { + envOptions = malloc(strlen(envDisplay) + 1); + + if (envOptions != NULL) + { + envOptions = strcpy(envOptions, envDisplay); + } + #ifdef WARNING + else + { + fprintf(stderr, "ddxProcessArgument: WARNING! failed string allocation.\n"); + } + #endif + } + + if (envOptions != NULL) + { + nxagentParseOptionString(envOptions); + + free(envOptions); + } + + for (j = 0; j < argc; j++) + { + if ((!strcmp(argv[j], "-options") || !strcmp(argv[j], "-option")) && j + 1 < argc) + { + if (nxagentOptionFile) + { + nxagentOptionFile = (char *) realloc(nxagentOptionFile, strlen(argv[j + 1]) + 1); + } + else + { + nxagentOptionFile = (char *) malloc(strlen(argv[j + 1]) +1); + } + + if (nxagentOptionFile != NULL) + { + nxagentOptionFile = strcpy(nxagentOptionFile, argv[j + 1]); + } + #ifdef WARNING + else + { + fprintf(stderr, "ddxProcessArgument: WARNING! failed string allocation.\n"); + } + #endif + + break; + } + } + + if (nxagentOptionFile) + { + nxagentProcessOptionsFile(); + } + } + + if (!strcmp(argv[i], "-B")) + { + #ifdef TEST + fprintf(stderr, "ddxProcessArgument: Checking the NX binder option.\n"); + #endif + + if (nxagentCheckBinder(argc, argv, i) > 0) + { + /* + * We are going to run the agent with the + * 'binder' option. Go straight to the + * proxy loop. + */ + + #ifdef TEST + fprintf(stderr, "ddxProcessArgument: Entering the NX proxy binder loop.\n"); + #endif + + nxagentBinderLoop(); + + /* + * This will make an exit. + */ + + nxagentBinderExit(0); + } + else + { + /* + * Exit with an error. + */ + + nxagentBinderExit(1); + } + } + + if (!strcmp(argv[i], "-display")) + { + if (++i < argc) + { + strncpy(nxagentDisplayName, argv[i], 1023); + + nxagentDisplayName[1023] = '\0'; + + return 2; + } + + return 0; + } + + if (!strcmp(argv[i], "-id")) + { + if (++i < argc) + { + strncpy(nxagentSessionId, argv[i], 255); + + *(nxagentSessionId + 255) = '\0'; + + return 2; + } + + return 0; + } + + /* + * This had to be '-options' since the beginning + * but was '-option' by mistake. Now we have to + * handle the backward compatibility. + */ + + if (!strcmp(argv[i], "-options") || !strcmp(argv[i], "-option")) + { + if (++i < argc) + { + int size; + + if (nxagentOptionFile != NULL) + { + xfree(nxagentOptionFile); + + nxagentOptionFile = NULL; + } + + if ((size = strlen(argv[i])) < 1024) + { + if ((nxagentOptionFile = xalloc(size + 1)) == NULL) + { + FatalError("malloc failed"); + } + + strncpy(nxagentOptionFile, argv[i], size); + + nxagentOptionFile[size] = '\0'; + } + else + { + /* + * It is useless to store the file name + * that has just been truncated. + */ + + #ifdef WARNING + fprintf(stderr, "ddxProcessArgument: WARNING! Option file name " + "too long. It will be ignored.\n"); + #endif + } + + return 2; + } + + return 0; + } + + if (!strcmp(argv[i], "-full")) { + nxagentFullGeneration = True; + return 1; + } + + if (!strcmp(argv[i], "-class")) { + if (++i < argc) { + if (!strcmp(argv[i], "StaticGray")) { + nxagentDefaultClass = StaticGray; + nxagentUserDefaultClass = True; + return 2; + } + else if (!strcmp(argv[i], "GrayScale")) { + nxagentDefaultClass = GrayScale; + nxagentUserDefaultClass = True; + return 2; + } + else if (!strcmp(argv[i], "StaticColor")) { + nxagentDefaultClass = StaticColor; + nxagentUserDefaultClass = True; + return 2; + } + else if (!strcmp(argv[i], "PseudoColor")) { + nxagentDefaultClass = PseudoColor; + nxagentUserDefaultClass = True; + return 2; + } + else if (!strcmp(argv[i], "TrueColor")) { + nxagentDefaultClass = TrueColor; + nxagentUserDefaultClass = True; + return 2; + } + else if (!strcmp(argv[i], "DirectColor")) { + nxagentDefaultClass = DirectColor; + nxagentUserDefaultClass = True; + return 2; + } + } + return 0; + } + + if (!strcmp(argv[i], "-cc")) { + if (++i < argc && sscanf(argv[i], "%i", &nxagentDefaultClass) == 1) { + if (nxagentDefaultClass >= 0 && nxagentDefaultClass <= 5) { + nxagentUserDefaultClass = True; + /* lex the OS layer process it as well, so return 0 */ + } + } + return 0; + } + + if (!strcmp(argv[i], "-depth")) { + if (++i < argc && sscanf(argv[i], "%i", &nxagentDefaultDepth) == 1) { + if (nxagentDefaultDepth > 0) { + nxagentUserDefaultDepth = True; + return 2; + } + } + return 0; + } + + /* + * These options are now useless and are + * parsed only for compatibility with + * older versions. + */ + + if (!strcmp(argv[i], "-fast") || + !strcmp(argv[i], "-slow") || + !strcmp(argv[i], "-hint") || + !strcmp(argv[i], "-sss")) + { + fprintf(stderr, "Warning: Ignoring deprecated command line option '%s'.\n", + argv[i]); + + return 1; + } + + if (!strcmp(argv[i], "-backingstore")) + { + if (++i < argc) + { + if (!strcmp(argv[i], "0")) + { + nxagentChangeOption(BackingStore, BackingStoreNever); + } + else + { + nxagentChangeOption(BackingStore, BackingStoreForce); + } + + return 2; + } + + return 0; + } + + if (!strcmp(argv[i], "-streaming")) + { + if (++i < argc) + { + if (!strcmp(argv[i], "0")) + { + nxagentChangeOption(Streaming, 0); + } + else + { + nxagentChangeOption(Streaming, 1); + } + + return 2; + } + + return 0; + } + + if (!strcmp(argv[i], "-defer")) + { + int level; + + if (++i < argc && + sscanf(argv[i], "%i", &level) == 1 && + level >= 0 && level <= 2) + { + if (nxagentOption(Shadow) == 0) + { + nxagentChangeOption(DeferLevel, level); + + /* + * The defer level set with the command + * line is not changed when the session + * is resumed. + */ + + nxagentLockDeferLevel = 1; + } + + return 2; + } + + return 0; + } + + if (!strcmp(argv[i], "-tile")) + { + int width; + int height; + + if (++i < argc && + sscanf(argv[i], "%ix%i", &width, &height) == 2 && + width >= 32 && height >= 32) + { + nxagentChangeOption(TileWidth, width); + nxagentChangeOption(TileHeight, height); + + return 2; + } + + return 0; + } + + if (strcmp(argv[i], "-fp") == 0) + { + if(++i < argc) + { + + #ifdef sgi + + userdefinedfontpath = 1; + + #endif + + #ifdef TEST + fprintf(stderr, "ddxProcessArgument: User defined font path [%s].\n", argv[i]); + #endif + + nxagentUserDefinedFontPath = 1; + + defaultFontPath = argv[i]; + } + else + { + UseMsg(); + } + } + + if (!strcmp(argv[i], "-geometry")) + { + if (++i < argc) + { + if (!strcmp(argv[i],"fullscreen")) + { + nxagentChangeOption(Fullscreen, True); + } + else if (!strcmp(argv[i],"ipaq")) + { + nxagentChangeOption(Fullscreen, True); + + nxagentIpaq = True; + } + else + { + if (nxagentUserGeometry.flag == 0) + { + nxagentUserGeometry.flag = XParseGeometry(argv[i], + &nxagentUserGeometry.X, + &nxagentUserGeometry.Y, + &nxagentUserGeometry.Width, + &nxagentUserGeometry.Height); + } + } + + if (nxagentUserGeometry.flag || (nxagentOption(Fullscreen) == 1)) return 2; + } + + return 0; + } + + if (!strcmp(argv[i], "-bw")) + { + int BorderWidth; + + if (++i < argc && sscanf(argv[i], "%i", &BorderWidth) == 1) + { + nxagentChangeOption(BorderWidth, BorderWidth); + + if (nxagentOption(BorderWidth) >= 0) + { + nxagentUserBorderWidth = True; + + return 2; + } + } + + return 0; + } + + if (!strcmp(argv[i], "-name")) + { + if (++i < argc) + { + strncpy(nxagentWindowName, argv[i], 255); + + *(nxagentWindowName + 255) = '\0'; + + return 2; + } + + return 0; + } + + if (!strcmp(argv[i], "-scrns")) { + if (++i < argc && sscanf(argv[i], "%i", &nxagentNumScreens) == 1) { + if (nxagentNumScreens > 0) { + if (nxagentNumScreens > MAXSCREENS) { + ErrorF("Maximum number of screens is %d.\n", MAXSCREENS); + nxagentNumScreens = MAXSCREENS; + } + return 2; + } + } + return 0; + } + + if (!strcmp(argv[i], "-install")) { + nxagentDoDirectColormaps = True; + return 1; + } + + if (!strcmp(argv[i], "-parent")) { + if (++i < argc) { + nxagentParentWindow = (XID) strtol (argv[i], (char**)NULL, 0); + return 2; + } + } + + if (!strcmp(argv[i], "-forcenx")) { + nxagentForceNXTrans = True; + return 1; + } + + if (!strcmp(argv[i], "-noonce")) + { + nxagentOnce = False; + return 1; + } + + if (!strcmp(argv[i], "-kbtype") || + !strcmp(argv[i], "-keyboard")) + { + if (++i < argc) + { + int size; + + if (nxagentKeyboard != NULL) + { + xfree(nxagentKeyboard); + + nxagentKeyboard = NULL; + } + + if ((size = strlen(argv[i])) < 256) + { + if ((nxagentKeyboard = xalloc(size + 1)) == NULL) + { + FatalError("malloc failed"); + } + + strncpy(nxagentKeyboard, argv[i], size); + + nxagentKeyboard[size] = '\0'; + } + #ifdef WARNING + else + { + /* + * it is useless to remember a kbtype + * option that has just been truncated. + */ + + fprintf(stderr, "ddxProcessArgument: WARNING! Option [%s] too long. " + "It will be ignored.\n", argv[i]); + } + #endif + + return 2; + } + + return 0; + } + + if (!strcmp(argv[i], "-extensions")) + { + return 1; + } + + #ifdef RENDER + if (!strcmp(argv[i], "-norender")) + { + nxagentRenderEnable = False; + + return 1; + } + #endif + + if (!strcmp(argv[i], "-nocomposite")) + { + nxagentChangeOption(Composite, 0); + + return 1; + } + + if (!strcmp(argv[i], "-nodamage")) + { + nxagentChangeOption(UseDamage, 0); + + return 1; + } + + /* + * The original -noreset option, disabling + * dispatchExceptionAtReset, is the default. + * Use this option to restore the original + * behaviour. + */ + + if (!strcmp(argv[i], "-reset")) + { + nxagentChangeOption(Reset, True); + + return 1; + } + + if (!strcmp(argv[i], "-persistent")) + { + nxagentChangeOption(Persistent, True); + + return 1; + } + + if (!strcmp(argv[i], "-nopersistent")) + { + nxagentChangeOption(Persistent, False); + + return 1; + } + + if (!strcmp(argv[i], "-noshmem")) + { + nxagentChangeOption(SharedMemory, False); + + return 1; + } + + if (!strcmp(argv[i], "-shmem")) + { + nxagentChangeOption(SharedMemory, True); + + return 1; + } + + if (!strcmp(argv[i], "-noignore")) + { + nxagentChangeOption(DeviceControl, True); + + return 1; + } + + if (!strcmp(argv[i], "-nokbreset")) + { + nxagentChangeOption(ResetKeyboardAtResume, False); + + return 1; + } + + if (!strcmp(argv[i], "-noxkblock")) + { + nxagentChangeOption(InhibitXkb, 0); + + return 1; + } + + /* + * Enable pseudo-rootless mode. + */ + + if (!strcmp(argv[i], "-R")) + { + if (nxagentOption(Binder) == UNDEFINED || + nxagentOption(Desktop) == UNDEFINED || + nxagentOption(Rootless) == UNDEFINED) + { + nxagentChangeOption(Binder, False); + nxagentChangeOption(Desktop, False); + nxagentChangeOption(Rootless, True); + } + return 1; + } + + /* + * Enable the "desktop" mode. This is + * the default. + */ + + if (!strcmp(argv[i], "-D")) + { + nxagentChangeOption(Binder, False); + nxagentChangeOption(Rootless, False); + nxagentChangeOption(Desktop, True); + + return 1; + } + + /* + * Enable the "shadow" mode. + */ + + if (!strcmp(argv[i], "-S")) + { + nxagentChangeOption(Shadow, 1); + nxagentChangeOption(DeferLevel, 0); + nxagentChangeOption(Persistent, 0); + + return 1; + } + + if (!strcmp(argv[i], "-shadow")) + { + if (++i < argc) + { + strncpy(nxagentShadowDisplayName, argv[i], 1023); + + if (strcmp(nxagentShadowDisplayName, "") == 0) + { + FatalError("Invalid shadow display option"); + } + + *(nxagentShadowDisplayName + 1023) = '\0'; + + return 2; + } + + return 0; + } + + + if (!strcmp(argv[i], "-shadowmode")) + { + if (++i < argc) + { + if (!strcmp(argv[i], "0")) + { + nxagentChangeOption(ViewOnly, 1); + } + else + { + nxagentChangeOption(ViewOnly, 0); + } + + return 2; + } + + return 0; + } + + /* + * Enable the auto-disconnect timeout. + */ + + if (!strcmp(argv[i], "-timeout")) + { + int seconds; + + if (++i < argc && sscanf(argv[i], "%i", &seconds) == 1) + { + if (seconds >= 0) + { + if (seconds > 0 && seconds < 60) + { + seconds = 60; + } + + nxagentChangeOption(Timeout, seconds); + + return 2; + } + } + + return 0; + } + + /* + * The return value for -query, -broadcast and + * -indirect must be 0 to let the dix layer pro- + * cess these options. + */ + + if (!strcmp(argv[i], "-query")) + + { + nxagentChangeOption(Desktop, True); + nxagentChangeOption(Xdmcp, True); + + nxagentMaxAllowedResets = 0; + + return 0; + } + + if (!strcmp(argv[i], "-broadcast")) + + { + nxagentChangeOption(Desktop, True); + nxagentChangeOption(Xdmcp, True); + + nxagentMaxAllowedResets = 0; + + return 0; + } + + if (!strcmp(argv[i], "-indirect")) + { + nxagentChangeOption(Desktop, True); + nxagentChangeOption(Xdmcp, True); + + nxagentMaxAllowedResets = 1; + + return 0; + } + + if (!strcmp(argv[i], "-noshpix")) + { + nxagentChangeOption(SharedPixmaps, False); + + return 1; + } + + if (!strcmp(argv[i], "-shpix")) + { + nxagentChangeOption(SharedPixmaps, True); + + return 1; + } + + if (!strcmp(argv[i], "-clipboard")) + { + if (!strcmp(argv[i+1], "both")) + { + nxagentChangeOption(Clipboard, ClipboardBoth); + } + else if (!strcmp(argv[i+1], "client")) + { + nxagentChangeOption(Clipboard, ClipboardClient); + } + else if (!strcmp(argv[i+1], "server")) + { + nxagentChangeOption(Clipboard, ClipboardServer); + } + else if (!strcmp(argv[i+1], "none")) + { + nxagentChangeOption(Clipboard, ClipboardNone); + } + else + { + nxagentChangeOption(Clipboard, ClipboardBoth); + } + + return 2; + } + + if (!strcmp(argv[i], "-bs")) + { + nxagentChangeOption(BackingStore, BackingStoreNever); + return 1; + } + + if (!strcmp(argv[i], "-verbose")) + { + nxagentVerbose = 1; + + return 1; + } + + return 0; +} + +static void nxagentParseOptions(char *name, char *value) +{ + int size, argc; + + char *argv[2] = { NULL, NULL }; + + #ifdef TEST + fprintf(stderr, "nxagentParseOptions: Processing option '%s' = '%s'.\n", + validateString(name), validateString(value)); + #endif + + if (!strcmp(name, "kbtype") || + !strcmp(name, "keyboard") || + !strcmp(name, "id") || + !strcmp(name, "display") || + !strcmp(name, "clipboard") || + !strcmp(name, "geometry") || + !strcmp(name, "option") || + !strcmp(name, "options") || + !strcmp(name, "shadow") || + !strcmp(name, "shadowmode") || + !strcmp(name, "streaming") || + !strcmp(name, "defer") || + !strcmp(name, "tile")) + { + argv[1] = value; + + argc = 2; + } + else if (!strcmp(name, "R") && !strcmp(value, "1")) + { + argc = 1; + } + else if (!strcmp(name, "fast") || !strcmp(name, "slow")) + { + fprintf(stderr, "Warning: Ignoring deprecated option '%s'.\n", name); + + return; + } + else if (!strcmp(name, "render")) + { + if (nxagentReconnectTrap == True) + { + #ifdef DEBUG + fprintf(stderr, "nxagentParseOptions: Ignoring option 'render' at reconnection.\n"); + #endif + } + else if (nxagentRenderEnable == UNDEFINED) + { + if (!strcmp(value, "1")) + { + nxagentRenderEnable = True; + } + else if (!strcmp(value, "0")) + { + nxagentRenderEnable = False; + } + else + { + fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'render'.\n", + validateString(value)); + } + } + + return; + } + else if (!strcmp(name, "fullscreen")) + { + if (nxagentReconnectTrap == True) + { + #ifdef DEBUG + fprintf(stderr, "nxagentParseOptions: Ignoring option 'fullscreen' at reconnection.\n"); + #endif + } + else if (!strcmp(value, "1")) + { + nxagentChangeOption(Fullscreen, True); + } + else if (!strcmp(value, "0")) + { + nxagentChangeOption(Fullscreen, False); + } + else + { + fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'fullscreen'.\n", + validateString(value)); + } + + return; + } + else if (!strcmp(name, "shpix")) + { + if (!strcmp(value, "1")) + { + nxagentChangeOption(SharedPixmaps, True); + } + else if (!strcmp(value, "0")) + { + nxagentChangeOption(SharedPixmaps, False); + } + else + { + fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'shpix'.\n", + validateString(value)); + } + + return; + } + else if (!strcmp(name, "shmem")) + { + if (!strcmp(value, "1")) + { + nxagentChangeOption(SharedMemory, True); + } + else if (!strcmp(value, "0")) + { + nxagentChangeOption(SharedMemory, False); + } + else + { + fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'shmem'.\n", + validateString(value)); + } + + return; + } + else if (!strcmp(name, "composite")) + { + if (!strcmp(value, "1")) + { + nxagentChangeOption(Composite, 1); + } + else if (!strcmp(value, "0")) + { + nxagentChangeOption(Composite, 0); + } + else + { + fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'composite'.\n", + validateString(value)); + } + + return; + } + else if (!strcmp(name, "resize")) + { + if (!strcmp(value, "1")) + { + nxagentResizeDesktopAtStartup = True; + } + else if (!strcmp(value, "0")) + { + nxagentResizeDesktopAtStartup = False; + } + else + { + fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'resize'.\n", + validateString(value)); + } + + return; + } + else if (!strcmp(name, "backingstore")) + { + if (!strcmp(value, "0")) + { + nxagentChangeOption(BackingStore, BackingStoreNever); + } + else + { + nxagentChangeOption(BackingStore, BackingStoreForce); + } + + return; + } + else if (!strcmp(name, "menu")) + { + if (!strcmp(value, "0")) + { + nxagentChangeOption(Menu, 0); + } + else + { + nxagentChangeOption(Menu, 1); + } + + return; + } + else if (strcmp(name, "shadowuid") == 0) + { + nxagentShadowUid = atoi(value); + + return; + } + else if (strcmp(name, "clients") == 0) + { + strcpy(nxagentClientsLogName, value); + + return; + } + else if (strcmp(name, "client") == 0) + { + if (strcmp(value, "winnt") == 0 || strcmp(value, "windows") == 0) + { + nxagentChangeOption(ClientOs, ClientOsWinnt); + } + else if (strcmp(value, "linux") == 0) + { + nxagentChangeOption(ClientOs, ClientOsLinux); + } + else if (strcmp(value, "solaris") == 0) + { + nxagentChangeOption(ClientOs, ClientOsSolaris); + } + else if (strcmp(value, "mac") == 0) + { + nxagentChangeOption(ClientOs, ClientOsMac); + } + + return; + } + else + { + #ifdef DEBUG + fprintf(stderr, "nxagentParseOptions: Ignored option [%s] with value [%s].\n", + validateString(name), validateString(value)); + #endif + + return; + } + + /* + * Before passing the not yet evaluated options + * to ddxProcessArgument(), we have to add a dash + * as prefix. + */ + + if ((size = strlen(name) + 1) > 1) + { + if ((argv[0] = malloc(size + 1)) == NULL) + { + fprintf(stderr, "Warning: Ignoring option '%s' due to lack of memory.\n", + name); + + return; + } + + *argv[0] = '-'; + + memcpy(argv[0] + 1, name, size); + } + + ddxProcessArgument(argc, argv, 0); + + free(argv[0]); +} + +static void nxagentParseOptionString(char *string) +{ + char *value = NULL; + char *option = NULL; + char *delimiter = NULL; + + /* + * Remove the port specification. + */ + + delimiter = rindex(string, ':'); + + if (delimiter) + { + *delimiter = 0; + } + else + { + fprintf(stderr, "Warning: Option file doesn't contain a port specification.\n"); + } + + while ((option = strtok(option ? NULL : string, ","))) + { + delimiter = rindex(option, '='); + + if (delimiter) + { + *delimiter = 0; + value = delimiter + 1; + } + else + { + value = NULL; + } + + nxagentParseOptions(option, value); + } +} + +void nxagentProcessOptionsFile() +{ + FILE *file; + char *data; + + int offset; + int size; + + int sizeOfFile; + int maxFileSize = 1024; + + #ifdef DEBUG + fprintf(stderr, "nxagentProcessOptionsFile: Going to process option the file [%s].\n", + validateString(nxagentOptionFile)); + #endif + + if (nxagentOptionFile == NULL) + { + return; + } + + if ((file = fopen(nxagentOptionFile, "r")) == NULL) + { + fprintf(stderr, "Warning: Couldn't open option file '%s'. Error is '%s'.\n", + validateString(nxagentOptionFile), strerror(errno)); + + goto nxagentProcessOptionsFileExit; + } + + if (fseek(file, 0, SEEK_END) != 0) + { + fprintf(stderr, "Warning: Couldn't position inside option file '%s'. Error is '%s'.\n", + validateString(nxagentOptionFile), strerror(errno)); + + goto nxagentProcessOptionsFileClose; + } + + if ((sizeOfFile = ftell(file)) == -1) + { + fprintf(stderr, "Warning: Couldn't get the size of option file '%s'. Error is '%s'.\n", + validateString(nxagentOptionFile), strerror(errno)); + + goto nxagentProcessOptionsFileClose; + } + + #ifdef DEBUG + fprintf(stderr, "nxagentProcessOptionsFile: Processing option file [%s].\n", + validateString(nxagentOptionFile)); + #endif + + rewind(file); + + if (sizeOfFile > maxFileSize) + { + fprintf(stderr, "Warning: Maximum file size exceeded for options '%s'.\n", + validateString(nxagentOptionFile)); + + goto nxagentProcessOptionsFileClose; + } + + if ((data = xalloc(sizeOfFile + 1)) == NULL) + { + fprintf(stderr, "Warning: Memory allocation failed processing file '%s'.\n", + validateString(nxagentOptionFile)); + + goto nxagentProcessOptionsFileClose; + } + + offset = 0; + size = 0; + + for (;;) + { + size_t result = fread(data + offset, 1, sizeOfFile, file); + + if (ferror(file) != 0) + { + fprintf(stderr, "Warning: Error reading the option file '%s'.\n", + validateString(nxagentOptionFile)); + + goto nxagentProcessOptionsFileFree; + } + + size += result; + offset += result; + + if (feof(file) != 0 || (size == sizeOfFile)) + { + break; + } + } + + if (size != sizeOfFile) + { + fprintf(stderr, "Warning: Premature end of option file '%s' while reading.\n", + validateString(nxagentOptionFile)); + + goto nxagentProcessOptionsFileFree; + } + + /* + * Truncate the buffer to the first line. + */ + + for (offset = 0; (offset < sizeOfFile) && (data[offset] != '\n'); offset++); + + data[offset] = 0; + + nxagentParseOptionString(data); + +nxagentProcessOptionsFileFree: + + if (data != NULL) + { + Xfree(data); + } + +nxagentProcessOptionsFileClose: + + if (fclose(file) != 0) + { + fprintf(stderr, "Warning: Couldn't close option file '%s'. Error is '%s'.\n", + validateString(nxagentOptionFile), strerror(errno)); + } + +nxagentProcessOptionsFileExit: + + return; +} + +/* + * FIXME: Transport initialization, shouldn't depend upon + * argv[], because we call it at every reconnection. + */ + +Bool nxagentPostProcessArgs(char* name, Display* dpy, Screen* scr) +{ + Bool useNXTrans = False; + + #ifdef WATCH + + fprintf(stderr, "nxagentPostProcessArgs: Watchpoint 2.\n"); + +/* +Reply Total Cached Bits In Bits Out Bits/Reply Ratio +------- ----- ------ ------- -------- ---------- ----- +N/A +*/ + + sleep(30); + + #endif + + if ((nxagentOption(Rootless) == 1) && nxagentOption(Fullscreen) == 1) + { + #ifdef TEST + fprintf(stderr, "WARNING: Ignoring fullscreen option for rootless session.\n"); + #endif + + nxagentChangeOption(Fullscreen, False); + } + + /* + * Ensure we have a valid name for children dialogs. + */ + + nxagentGetDialogName(); + + /* + * Ensure we have a valid name for window name. + */ + + if (*nxagentWindowName == '\0') + { + strncpy(nxagentWindowName, "NX", 255); + + *(nxagentWindowName + 255) = '\0'; + } + + /* + * Note that use of NX packed images as well as + * render extension could be later disabled due + * to the fact that session is running nested + * in a nxagent server. + */ + + if (nxagentForceNXTrans) + { + useNXTrans = True; + } + else if ((strncasecmp(name, "nx/", 3) == 0) || + (strncasecmp(name, "nx:", 3) == 0) || + (strncasecmp(name, "nx,", 3) == 0) || + (strcasecmp(name, "nx") == 0)) + { + useNXTrans = True; + } + + if (useNXTrans == True) + { + unsigned int linkType = LINK_TYPE_NONE; + + unsigned int localMajor = 0; + unsigned int localMinor = 0; + unsigned int localPatch = 0; + + unsigned int remoteMajor = 0; + unsigned int remoteMinor = 0; + unsigned int remotePatch = 0; + + int splitTimeout = 0; + int motionTimeout = 0; + + int splitMode = 0; + int splitSize = 0; + + unsigned int packMethod = PACK_NONE; + unsigned int packQuality = 9; + + int dataLevel = 0; + int streamLevel = 0; + int deltaLevel = 0; + + unsigned int loadCache = 0; + unsigned int saveCache = 0; + unsigned int startupCache = 0; + + unsigned int enableClient = 0; + unsigned int enableServer = 0; + + unsigned int clientSegment = 0; + unsigned int serverSegment = 0; + + unsigned int clientSize = 0; + unsigned int serverSize = 0; + + if (NXGetControlParameters(dpy, &linkType, &localMajor, &localMinor, + &localPatch, &remoteMajor, &remoteMinor, &remotePatch, + &splitTimeout, &motionTimeout, &splitMode, &splitSize, + &packMethod, &packQuality, &dataLevel, &streamLevel, + &deltaLevel, &loadCache, &saveCache, &startupCache) == 0) + { + fprintf(stderr, "Warning: Failed to get the control parameters.\n"); + } + + nxagentChangeOption(LinkType, linkType); + + #ifdef TEST + fprintf(stderr, "nxagentPostProcessArgs: Got local version [%d.%d.%d] remote version [%d.%d.%d].\n", + localMajor, localMinor, localPatch, remoteMajor, remoteMinor, remotePatch); + + fprintf(stderr, "nxagentPostProcessArgs: Got split timeout [%d] motion timeout [%d].\n", + splitTimeout, motionTimeout); + + fprintf(stderr, "nxagentPostProcessArgs: Got split mode [%d] split size [%d].\n", + splitMode, splitSize); + + fprintf(stderr, "nxagentPostProcessArgs: Got preferred pack method [%d] and quality [%d].\n", + packMethod, packQuality); + #endif + + if (remoteMajor < 2) + { + #ifdef TEST + fprintf(stderr, "nxagentPostProcessArgs: WARNING! Using backward compatible alpha encoding.\n"); + #endif + + nxagentAlphaCompat = 1; + } + else + { + nxagentAlphaCompat = 0; + } + + if (nxagentPackMethod == -1) + { + nxagentPackMethod = packMethod; + } + + if (nxagentPackQuality == -1) + { + nxagentPackQuality = packQuality; + } + + /* + * Set the minimum size of images being + * streamed. + */ + + if (nxagentSplitThreshold == -1) + { + nxagentSplitThreshold = splitSize; + } + + /* + * Let the remote proxy use the shared memory + * extension, if supported by the X server. + * The client part is not useful and not impl- + * emented. The size of the segment is chosen + * by the user. The only purpose of the message + * is to reserve the XID that will be used by + * the remote. + */ + + enableClient = 0; + enableServer = 1; + + if (NXGetShmemParameters(dpy, &enableClient, &enableServer, &clientSegment, + &serverSegment, &clientSize, &serverSize) == 0) + { + fprintf(stderr, "Warning: Failed to get the shared memory parameters.\n"); + } + + if (enableServer == 1) + { + fprintf(stderr, "Info: Using shared memory parameters %d/%d/%d/%dK.\n", + nxagentOption(SharedMemory), nxagentOption(SharedPixmaps), + enableServer, serverSize / 1024); + } + else + { + fprintf(stderr, "Info: Using shared memory parameters %d/%d/0/0K.\n", + nxagentOption(SharedMemory), nxagentOption(SharedPixmaps)); + } + + /* + * We don't need the NoExpose events. Block + * them at the proxy side. + */ + + NXSetExposeParameters(nxagentDisplay, 1, 1, 0); + } + else + { + /* + * We don't have a proxy on the remote side. + */ + + nxagentChangeOption(LinkType, LINK_TYPE_NONE); + } + + /* + * Set the lossless and lossy pack methods + * based on the user's preferences and the + * selected link type. + */ + + nxagentSetPackMethod(); + + /* + * If not set, set the defer level and the + * synchronization timeout based on the link + * type. + */ + + nxagentSetDeferLevel(); + + /* + * Also set the display output buffer size. + */ + + nxagentSetBufferSize(); + + /* + * Select the preferred scheduler. + */ + + nxagentSetScheduler(); + + /* + * Select the buffer coalescence timeout. + */ + + nxagentSetCoalescence(); + + /* + * Set the other defaults. + */ + + if (nxagentOption(Fullscreen) == UNDEFINED) + { + nxagentChangeOption(Fullscreen, False); + } + + if (nxagentOption(Binder) == UNDEFINED) + { + nxagentChangeOption(Binder, False); + } + + if (nxagentOption(Rootless) == UNDEFINED) + { + nxagentChangeOption(Rootless, False); + } + + if (nxagentOption(Desktop) == UNDEFINED) + { + nxagentChangeOption(Desktop, True); + } + + /* + * The enableBackingStore flag is defined + * in window.c in the dix. + */ +/* +FIXME: In rootless mode the backing-store support is not functional yet. +*/ + if (nxagentOption(Rootless)) + { + enableBackingStore = 0; + } + else if (nxagentOption(BackingStore) == BackingStoreUndefined || + nxagentOption(BackingStore) == BackingStoreForce) + { + enableBackingStore = 1; + } + else if (nxagentOption(BackingStore) == BackingStoreNever) + { + enableBackingStore = 0; + } + + /* + * need to check if this was set on the + * command line as this has the priority + * over the option file. + */ + + if (nxagentRenderEnable == UNDEFINED) + { + nxagentRenderEnable = True; + } + + if (nxagentRenderEnable == True) + { + nxagentAlphaEnabled = True; + } + else + { + nxagentAlphaEnabled = False; + } + + if ((nxagentOption(Rootless) == 1) && nxagentOption(Xdmcp)) + { + FatalError("PANIC! Cannot start a XDMCP session in rootless mode.\n"); + } + + /* + * We enable server reset only for indirect + * XDMCP sessions. + */ + + if (nxagentOption(Reset) == True && nxagentMaxAllowedResets == 0) + { + #ifdef WARNING + fprintf(stderr, "nxagentPostProcessArgs: Disabling the server reset.\n"); + #endif + + nxagentChangeOption(Reset, False); + + dispatchExceptionAtReset = 0; + } + + /* + * We skip server reset by default. This should + * be equivalent to passing the -noreset option + * to a standard XFree86 server. + */ + + if (nxagentOption(Reset) == False) + { + #ifdef TEST + fprintf(stderr, "nxagentPostProcessArgs: Disabling dispatch of exception at server reset.\n"); + #endif + + dispatchExceptionAtReset = 0; + } + + /* + * Check if the user activated the auto-disconect + * feature. + */ + + if (nxagentOption(Timeout) > 0) + { + fprintf(stderr, "Info: Using auto-disconnect timeout of %d seconds.\n", + nxagentOption(Timeout)); + + nxagentAutoDisconnectTimeout = nxagentOption(Timeout) * MILLI_PER_SECOND; + } + + #ifdef WATCH + + fprintf(stderr, "nxagentPostProcessArgs: Watchpoint 3.\n"); + +/* +Reply Total Cached Bits In Bits Out Bits/Reply Ratio +------- ----- ------ ------- -------- ---------- ----- +#16 1 256 bits (0 KB) -> 12 bits (0 KB) -> 256/1 -> 12/1 = 21.333:1 +#233 A 1 256 bits (0 KB) -> 131 bits (0 KB) -> 256/1 -> 131/1 = 1.954:1 +#245 A 2 512 bits (0 KB) -> 19 bits (0 KB) -> 256/1 -> 10/1 = 26.947:1 +*/ + + sleep(30); + + #endif + + return useNXTrans; +} + +void ddxUseMsg() +{ + ErrorF("-display string display name of the real server\n"); + ErrorF("-sync synchronize with the real server\n"); + ErrorF("-full utilize full regeneration\n"); + ErrorF("-class string default visual class\n"); + ErrorF("-depth int default depth\n"); + ErrorF("-geometry WxH+X+Y window size and position\n"); + ErrorF("-bw int window border width\n"); + ErrorF("-name string window name\n"); + ErrorF("-scrns int number of screens to generate\n"); + ErrorF("-install install colormaps directly\n"); + + ErrorF("The NX system adds the following arguments:\n"); + ErrorF("-forcenx force use of NX protocol messages assuming communication through nxproxy\n"); + ErrorF("-timeout int auto-disconnect timeout in seconds (minimum allowed: 60)\n"); +#ifdef RENDER + ErrorF("-norender disable the use of the render extension\n"); + ErrorF("-nocomposite disable the use of the composite extension\n"); +#endif + ErrorF("-nopersistent disable disconnection/reconnection to the X display on SIGHUP\n"); + ErrorF("-noshmem disable use of shared memory extension\n"); + ErrorF("-shmem enable use of shared memory extension\n"); + ErrorF("-noshpix disable use of shared pixmaps\n"); + ErrorF("-shpix enable use of shared pixmaps\n"); + ErrorF("-noignore don't ignore pointer and keyboard configuration changes mandated by clients\n"); + ErrorF("-nokbreset don't reset keyboard device if the session is resumed\n"); + ErrorF("-noxkblock always allow applications to change layout through XKEYBOARD\n"); + ErrorF("-tile WxH size of image tiles (minimum allowed: 32x32)\n"); + ErrorF("-D enable desktop mode\n"); + ErrorF("-R enable rootless mode\n"); + ErrorF("-S enable shadow mode\n"); + ErrorF("-B enable proxy binding mode\n"); +} + +static int nxagentGetDialogName() +{ + strcpy(nxagentDialogName, "NX"); + + *(nxagentDialogName + 255) = '\0'; + + if (*nxagentSessionId != '\0') + { + int length = strlen(nxagentSessionId); + + strcpy(nxagentDialogName, "NX - "); + + if (length > (MD5_LENGTH * 2 + 1) && + *(nxagentSessionId + (length - (MD5_LENGTH * 2 + 1))) == '-') + { + strncat(nxagentDialogName, nxagentSessionId, length - (MD5_LENGTH * 2 + 1)); + } + else + { + strncat(nxagentDialogName, nxagentSessionId, 250); + } + + *(nxagentSessionId + 255) = '\0'; + + return 1; + } + + return 0; +} + +void nxagentSetPackMethod(void) +{ + unsigned char supportedMethods[NXNumberOfPackMethods]; + unsigned int entries = NXNumberOfPackMethods; + + int method; + + if (nxagentOption(LinkType) == LINK_TYPE_NONE) + { + nxagentChangeOption(Streaming, 0); + + nxagentPackMethod = PACK_NONE; + nxagentPackLossless = PACK_NONE; + + nxagentSplitThreshold = 0; + + return; + } + + /* + * Check if we need to select the lossy + * and lossless pack methods based on + * the link type. + */ + + method = nxagentPackMethod; + + if (method == PACK_ADAPTIVE) + { + #ifdef TEST + fprintf(stderr, "nxagentSetPackMethod: Using adaptive mode for image compression.\n"); + #endif + + nxagentChangeOption(Adaptive, 1); + } + else + { + #ifdef TEST + fprintf(stderr, "nxagentSetPackMethod: Not using adaptive mode for image compression.\n"); + #endif + + nxagentChangeOption(Adaptive, 0); + } + + if (method == PACK_LOSSY || method == PACK_ADAPTIVE) + { + nxagentPackMethod = PACK_JPEG_16M_COLORS; + } + else if (method == PACK_LOSSLESS) + { + switch (nxagentOption(LinkType)) + { + case LINK_TYPE_MODEM: + case LINK_TYPE_ISDN: + case LINK_TYPE_ADSL: + case LINK_TYPE_WAN: + { + nxagentPackMethod = PACK_BITMAP_16M_COLORS; + + break; + } + case LINK_TYPE_LAN: + { + nxagentPackMethod = PACK_RLE_16M_COLORS; + + break; + } + default: + { + fprintf(stderr, "Warning: Unknown link type '%d' while setting the pack method.\n", + nxagentOption(LinkType)); + + break; + } + } + } + + /* + * Query the remote proxy to determine + * whether the selected methods are + * supported. + */ + + if (NXGetUnpackParameters(nxagentDisplay, &entries, supportedMethods) == 0 || + entries != NXNumberOfPackMethods) + { + fprintf(stderr, "Warning: Unable to retrieve the supported pack methods.\n"); + + nxagentPackMethod = PACK_NONE; + nxagentPackLossless = PACK_NONE; + } + else + { + if (nxagentPackMethod == PACK_BITMAP_16M_COLORS || + nxagentPackMethod == PACK_RLE_16M_COLORS || + nxagentPackMethod == PACK_RGB_16M_COLORS || + nxagentPackMethod == PACK_NONE) + { + nxagentPackLossless = nxagentPackMethod; + } + else + { + if (nxagentOption(LinkType) == LINK_TYPE_LAN) + { + nxagentPackLossless = PACK_RLE_16M_COLORS; + } + else + { + nxagentPackLossless = PACK_BITMAP_16M_COLORS; + } + } + + if (supportedMethods[nxagentPackLossless] == 0) + { + nxagentPackLossless = PACK_NONE; + } + + #ifdef TEST + fprintf(stderr, "nxagentSetPackMethod: Using method [%d] for lossless compression.\n", + nxagentPackLossless); + #endif + + if (supportedMethods[nxagentPackMethod] == 0) + { + fprintf(stderr, "Warning: Pack method '%d' not supported by the proxy.\n", + nxagentPackMethod); + + fprintf(stderr, "Warning: Replacing with lossless pack method '%d'.\n", + nxagentPackLossless); + + nxagentPackMethod = nxagentPackLossless; + } + } + + if (nxagentPackMethod == nxagentPackLossless) + { + nxagentPackQuality = 9; + } + + #ifdef TEST + fprintf(stderr, "nxagentSetPackMethod: Assuming pack methods [%d] and [%d] with " + "quality [%d].\n", nxagentPackMethod, nxagentPackLossless, nxagentPackQuality); + #endif +} + +/* + * Each defer level adds the following rules to the previous ones: + * + * Level 0 Eager encoding. + * + * Level 1 No data is put or copied on pixmaps, marking them always + * as corrupted and synchronizing them on demand, i.e. when + * a copy area to a window is requested, the source is syn- + * chronized before copying it. + * + * Level 2 The put images over the windows are skipped marking the + * destination as corrupted. The same happens for copy area + * and composite operations, spreading the corrupted regions + * of involved drawables. + */ + +void nxagentSetDeferLevel() +{ + int deferLevel; + int tileWidth; + int tileHeight; + int deferTimeout; + + /* + * Streaming is only partly implemented + * and is not available in this version + * of the agent. + */ + + if (nxagentOption(Streaming) == 1) + { + fprintf(stderr, "Warning: Streaming of images not available in this agent.\n"); + + nxagentChangeOption(Streaming, 0); + } + + switch (nxagentOption(LinkType)) + { + case LINK_TYPE_MODEM: + { + deferLevel = 2; + + tileWidth = 64; + tileHeight = 64; + + deferTimeout = 200; + + break; + } + case LINK_TYPE_ISDN: + { + deferLevel = 2; + + tileWidth = 64; + tileHeight = 64; + + deferTimeout = 200; + + break; + } + case LINK_TYPE_ADSL: + { + deferLevel = 2; + + deferTimeout = 200; + + tileWidth = 65536; + tileHeight = 65536; + + break; + } + case LINK_TYPE_WAN: + { + deferLevel = 1; + + deferTimeout = 200; + + tileWidth = 65536; + tileHeight = 65536; + + break; + } + case LINK_TYPE_NONE: + case LINK_TYPE_LAN: + { + deferLevel = 0; + + deferTimeout = 200; + + tileWidth = 65536; + tileHeight = 65536; + + break; + } + default: + { + fprintf(stderr, "Warning: Unknown link type [%d] processing the defer option.\n", + nxagentOption(LinkType)); + + deferLevel = 0; + + tileWidth = 64; + tileHeight = 64; + + deferTimeout = 200; + + break; + } + } + + /* + * Set the defer timeout. + */ + + if (nxagentOption(Shadow) == 1) + { + #ifdef TEST + fprintf(stderr, "nxagentSetDeferLevel: Ignoring defer timeout parameter in shadow mode.\n"); + #endif + } + else + { + nxagentChangeOption(DeferTimeout, deferTimeout); + } + + /* + * Set the defer level. + */ + + if (nxagentOption(Shadow) == 1) + { + #ifdef TEST + fprintf(stderr, "nxagentSetDeferLevel: Ignoring defer parameter in shadow mode.\n"); + #endif + } + else if (nxagentOption(DeferLevel) != UNDEFINED) + { + #ifdef TEST + fprintf(stderr, "nxagentSetDeferLevel: Not overriding the [defer] option " + "with value [%d]. Defer timeout is [%ld] ms.\n", nxagentOption(DeferLevel), + nxagentOption(DeferTimeout)); + #endif + } + else + { + nxagentChangeOption(DeferLevel, deferLevel); + + #ifdef TEST + fprintf(stderr, "nxagentSetDeferLevel: Assuming defer level [%d] with timeout of [%ld] ms.\n", + nxagentOption(DeferLevel), nxagentOption(DeferTimeout)); + #endif + } + + /* + * Set the tile width. + */ + + if (nxagentOption(TileWidth) != UNDEFINED) + { + #ifdef TEST + fprintf(stderr, "nxagentSetDeferLevel: Not overriding the [tile] option " + "width value [%d].\n", nxagentOption(TileWidth)); + #endif + } + else + { + nxagentChangeOption(TileWidth, tileWidth); + + #ifdef TEST + fprintf(stderr, "nxagentSetDeferLevel: Assuming tile width [%d].\n", + nxagentOption(TileWidth)); + #endif + } + + /* + * Set the tile height. + */ + + if (nxagentOption(TileHeight) != UNDEFINED) + { + #ifdef TEST + fprintf(stderr, "nxagentSetDeferLevel: Not overriding the [tile] option " + "height value [%d].\n", nxagentOption(TileHeight)); + #endif + } + else + { + nxagentChangeOption(TileHeight, tileHeight); + + #ifdef TEST + fprintf(stderr, "nxagentSetDeferLevel: Assuming tile height [%d].\n", + nxagentOption(TileHeight)); + #endif + } +} + +void nxagentSetBufferSize() +{ + int size; + + switch (nxagentOption(LinkType)) + { + case LINK_TYPE_MODEM: + { + size = 4096; + + break; + } + case LINK_TYPE_ISDN: + { + size = 4096; + + break; + } + case LINK_TYPE_ADSL: + { + size = 8192; + + break; + } + case LINK_TYPE_WAN: + { + size = 16384; + + break; + } + case LINK_TYPE_NONE: + case LINK_TYPE_LAN: + { + size = 16384; + + break; + } + default: + { + fprintf(stderr, "Warning: Unknown link type '%d' while setting the display buffer size.\n", + nxagentOption(LinkType)); + + size = 16384; + + break; + } + } + + nxagentChangeOption(DisplayBuffer, size); + + nxagentBuffer = size; + + if (NXSetDisplayBuffer(nxagentDisplay, nxagentBuffer) < 0) + { + fprintf(stderr, "Warning: Can't set the display buffer size to [%d].\n", + nxagentBuffer); + } +} + +void nxagentSetScheduler() +{ + #ifdef DISABLE_SMART_SCHEDULE + + #ifdef SMART_SCHEDULE + + #ifdef TEST + fprintf(stderr, "nxagentSetScheduler: Disabling the smart scheduler.\n"); + #endif + + nxagentDisableTimer(); + + #endif + + #else /* #ifdef DISABLE_SMART_SCHEDULE */ + + /* + * The smart scheduler is the default. + */ + + #ifdef SMART_SCHEDULE + + if (nxagentOption(Shadow) == 1) + { + #ifdef TEST + fprintf(stderr, "nxagentSetScheduler: Using the dumb scheduler in shadow mode.\n"); + #endif + + nxagentDisableTimer(); + } + + #endif + + #endif /* #ifdef DISABLE_SMART_SCHEDULE */ +} + +void nxagentSetCoalescence() +{ + int timeout; + + switch (nxagentOption(LinkType)) + { + case LINK_TYPE_MODEM: + { + timeout = 50; + + break; + } + case LINK_TYPE_ISDN: + { + timeout = 20; + + break; + } + case LINK_TYPE_ADSL: + { + timeout = 10; + + break; + } + case LINK_TYPE_WAN: + { + timeout = 5; + + break; + } + case LINK_TYPE_NONE: + case LINK_TYPE_LAN: + { + timeout = 0; + + break; + } + default: + { + fprintf(stderr, "Warning: Unknown link type '%d' while setting the display coalescence.\n", + nxagentOption(LinkType)); + + timeout = 0; + + break; + } + } + + #ifdef TEST + fprintf(stderr, "nxagentSetCoalescence: Using coalescence timeout of [%d] ms.\n", + timeout); + #endif + + nxagentChangeOption(DisplayCoalescence, timeout); +} + |