Esempio n. 1
0
static void
start_hndl(void *data, const char *el, const char **attr) 
{
    static int topMenu = 0;
    static int button = 0;
    char* name;
    int value, i;
    apiMenu* newMenu;
    
    if ( strcmp( el, "button" ) == 0 )
    {
	button = crStrToInt( attr[1] );
    }
    else if ( strcmp( el, "menu") == 0 )
    {
	if ( !topMenu )
	{
	    crut_server.stack = crut_server.endStack = crAlloc( sizeof(apiMenu) );
	    crut_server.stack->subMenus = 0;
	    crut_server.stack->sLast = crut_server.stack->sNext = NULL;
	    crut_server.stack->att_button = button;

	    crut_server.stack->menuID = crStrToInt( attr[1] );

	    topMenu = 1;
	}
	else
	{
	    newMenu = crAlloc( sizeof(apiMenu) );
	    
	    newMenu->name = crAlloc( strlen( attr[1] ) );
	    crStrcpy( newMenu->name, attr[1] );

	    newMenu->menuID = crStrToInt( attr[3] );
	    
	    pushMenu( newMenu );
	}
    }
    else if ( strcmp( el, "item" ) == 0 )
    {
	for ( i=0; i<=4; i+=2 )
	{
	    if ( strcmp( attr[i], "value" ) == 0 )
		value = crStrToInt( attr[i+1] );

	    if ( strcmp( attr[i], "name" ) == 0 )
		name = (char*) attr[i+1];
	}
	
	addItem( name, value);
    }
}
static void set_use_osmesa ( RenderSPU *render_spu, char *response )
{
    int val = crStrToInt( response );
#ifdef USE_OSMESA
    render_spu->use_osmesa = val;
#else
    if (val != 0)
        crError( "renderspu with Conf(use_osmesa, 1) but not compiled with -DUSE_OSMESA");
#endif
}
Esempio n. 3
0
/**
 * If several SPUs (such as Pack SPUs) are connected to a server,
 * this function will return a unique rank/index for each such SPU.
 * For example, if three Pack SPUs are connected to a crserver, and
 * each SPU calls this function, they'll be returned "0", "1" and "2",
 * respectively.
 * \return SPU index or -1 if error
 */
int crMothershipGetSPURank( CRConnection *conn )
{
	char response[1000];
	if (crMothershipSendString( conn, response, "get_spu_rank")) {
		return crStrToInt(response);
	}
	else {
		return -1;
	}
}
Esempio n. 4
0
int __copy_of_crMothershipReadResponse( CRConnection *conn, void *buf )
{
	char codestr[4];
	int code;

	crNetSingleRecv( conn, codestr, 4 );
	crNetReadline( conn, buf );

	code = crStrToInt( codestr );
	return (code == 200);
}
Esempio n. 5
0
static void set_node( void *spu, const char *response )
{
	(void) spu;
	if (*response) {
		binaryswap_spu.node_num = crStrToInt( response );
		if(binaryswap_spu.node_num == -1)
		     crError( "FATAL: No node number specified for the binaryswap SPU?" );     
	}
	else {
		crError( "FATAL: No node number specified for the binaryswap SPU?" );
	}
}
static void set_lut8( RenderSPU *render_spu, const char *response )
{
    int a;  
    char **lut;
    
    if (!response[0]) return;

    lut = crStrSplit(response, ",");
    if (!lut) return;

    for (a=0; a<256; a++)
    {
        render_spu->lut8[0][a]  = crStrToInt(lut[a]);
        render_spu->lut8[1][a]  = crStrToInt(lut[256+a]);
        render_spu->lut8[2][a]  = crStrToInt(lut[512+a]);
    }

    crFreeStrings(lut);

    render_spu->use_lut8 = 1;
}
Esempio n. 7
0
/**
 * Ask the mothership for a new tile layout.
 * Return: GL_TRUE if successfull, GL_FALSE otherwise.
 */
static GLboolean
getTilingFromMothership( WindowInfo *winInfo )
{
	char response[8000];
	char **n_tiles;
	char **tiles;
	int numTiles, i;
	int maxX, maxY;

	CRConnection *conn = crMothershipConnect();
	CRASSERT(conn);

	crMothershipIdentifySPU(conn, tilesort_spu.id);
	crMothershipRequestTileLayout(conn, response, winInfo->muralWidth, winInfo->muralHeight);
	crMothershipDisconnect(conn);

	crDebug("Getting tile information from mothership.");

	n_tiles = crStrSplitn(response, " ", 1);
	numTiles = crStrToInt( n_tiles[0] );
	if (numTiles <= 0)
		return GL_FALSE;  /* failure */

	/* remove old tile list */
	for (i = 0; i < tilesort_spu.num_servers; i++)
		winInfo->server[i].num_extents = 0;

	/* parse new tile string */
	maxX = maxY = 0;
	CRASSERT(n_tiles[1]);
	tiles = crStrSplit(n_tiles[1], ",");
	for (i = 0; i < numTiles; i++)
	{
		int server, x, y, w, h, t;
		sscanf(tiles[i], "%d %d %d %d %d", &server, &x, &y, &w, &h);
		/*crDebug("Tile on %d: %d %d %d %d", server, x1, y1, x2, y2);*/
		t = winInfo->server[server].num_extents;
		winInfo->server[server].extents[t].x1 = x;
		winInfo->server[server].extents[t].y1 = y;
		winInfo->server[server].extents[t].x2 = x + w;
		winInfo->server[server].extents[t].y2 = y + h;
		winInfo->server[server].num_extents = t + 1;
		/* update maxX, maxY */
		if (x + w > maxX)
			maxX = x + w;
		if (y + h > maxY)
			maxY = y + h;
	}

	return GL_TRUE;
}
Esempio n. 8
0
/**
 * Get response string from mothership.
 * \return 1 if OK, 0 if error
 */
int crMothershipReadResponse( CRConnection *conn, void *buf )
{
	/* The connection may be already broken if we're called via the
	 * crMothershipExit() function.
	 */
	if (conn->type != CR_NO_CONNECTION) {
		char codestr[4];
		int code;
		crNetSingleRecv( conn, codestr, 4 );
		crNetReadline( conn, buf );
		code = crStrToInt( codestr );
		return (code == 200);
	}
	else {
		return 0;
	}
}
void SERVER_DISPATCH_APIENTRY
crServerDispatchLoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *string)
{
    if (target == GL_VERTEX_PROGRAM_NV &&
            cr_server.vpProjectionMatrixVariable != NULL) {
        /* scan the program string looking for 'vertprog_projection'
         * If the program was generated by Cg, the info we want will look
         * something like this:
         * #var float4x4 ModelViewProj :  : c[0], 4 : 1 : 1
         */
        CRServerProgram *prog = LookupProgram(id);
        CRASSERT(prog);
        if (prog) {
            const char *varPos, *paramPos;
            varPos = crStrstr((const char *) string, cr_server.vpProjectionMatrixVariable);
            if (varPos) {
                 paramPos = crStrstr(varPos, "c[");
                 if (paramPos) {
                        char number[10];
                        int i = 0;
                        paramPos += 2;  /* skip "c[" */
                        while (crIsDigit(paramPos[i])) {
                             number[i] = paramPos[i];
                             i++;
                        }
                        number[i] = 0;
                        prog->projParamStart = crStrToInt(number);
                 }
            }
            else {
                 crWarning("Didn't find %s parameter in vertex program string",
                                     cr_server.vpProjectionMatrixVariable);
            }
        }
    }

    /* pass through */
    crStateLoadProgramNV(&cr_server.StateTracker, target, id, len, string);
    cr_server.head_spu->dispatch_table.LoadProgramNV(target, id, len, string);
}
Esempio n. 10
0
void 
CRUT_APIENTRY
crutConnectToClients( CRUTAPI *crut_api )
{   
    int i, ind;     
    char response[8096], hostname[4096], protocol[4096];
    char **newclients;
    char* client;
    unsigned short port;

    crMothershipGetCRUTClients(crut_api->mothershipConn, response);

    newclients = crStrSplit(response, " ");
    crut_api->numclients = crStrToInt(newclients[0]);
    ind = 1;

    crut_api->crutclients = crAlloc(crut_api->numclients*sizeof(CRUTClientPointer));

    for (i=0; i<crut_api->numclients; i++) {
      
        client = newclients[ind++];
	
	if ( !crParseURL( client, protocol, hostname, &port, DEFAULT_CRUT_PORT ) )
	{
	    crError( "Malformed URL: \"%s\"", response );
	}   
	
	crut_api->crutclients[i].mtu = crMothershipGetMTU( crut_api->mothershipConn );
	
	crut_api->crutclients[i].send_conn = crNetAcceptClient( protocol, hostname, port, crut_api->crutclients[i].mtu, 0 );
	
	if (!crut_api->crutclients[i].send_conn)
	{
	    crError("Couldn't connect to the CRUT client");
	}
		    
    }

}
Esempio n. 11
0
static void set_local_visualization( Binaryswapspu *binaryswap_spu, const char *response )
{
	binaryswap_spu->local_visualization = crStrToInt( response );
}
static void set_is_master ( RenderSPU *render_spu, char *response )
{
    render_spu->is_swap_master = crStrToInt( response );
}
Esempio n. 13
0
static void
set_ztype_parm(ZpixSPU * zpix_spu, const char *response)
{
	zpix_spu->ztype_parm = crStrToInt(response);
	crDebug("Zpix SPU config: ztype_parm = %d", zpix_spu->ztype_parm);
}
Esempio n. 14
0
static void
set_no_diff(ZpixSPU * zpix_spu, const char *response)
{
	zpix_spu->no_diff = crStrToInt(response);
	crDebug("Zpix SPU config: no_diff = %d", zpix_spu->no_diff);
}
Esempio n. 15
0
static void
set_client_id(ZpixSPU * zpix_spu, const char *response)
{
	zpix_spu->client_id = crStrToInt(response);
	crDebug("Zpix SPU config: client_id = %d", zpix_spu->client_id);
}
Esempio n. 16
0
void REPLICATESPU_APIENTRY
replicatespu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
{
	unsigned int i;
	unsigned int show_window = 0;
	WindowInfo *winInfo = (WindowInfo *) crHashtableSearch( replicate_spu.windowTable, window );
	ContextInfo *newCtx = (ContextInfo *) crHashtableSearch( replicate_spu.contextTable, ctx );
	GET_THREAD(thread);

	if (!winInfo) {
		crWarning("Replicate SPU: Invalid window ID %d passed to MakeCurrent", window);
		return;
	}

	if (thread)
		replicatespuFlushAll( (void *)thread );

	if (!thread) {
		thread = replicatespuNewThread( crThreadID() );
	}
	CRASSERT(thread);
	CRASSERT(thread->packer);

	if (newCtx && winInfo) {
		newCtx->currentWindow = winInfo;

#if 000
		/* This appears to be obsolete code */
		if (replicate_spu.render_to_crut_window && !nativeWindow) {
			char response[8096];
			CRConnection *conn = crMothershipConnect();
			if (!conn) {
				crError("Replicate SPU: Couldn't connect to the mothership to get CRUT drawable-- "
								"I have no idea what to do!");
			}
			crMothershipGetParam( conn, "crut_drawable", response );
			nativeWindow = crStrToInt(response);
			crDebug("Replicate SPU: using CRUT drawable: 0x%x", nativeWindow);
			crMothershipDisconnect(conn);
		}
#endif

		if (replicate_spu.glx_display
				&& winInfo
				&& winInfo->nativeWindow != nativeWindow)
		{
			winInfo->nativeWindow = nativeWindow;
			replicatespuMonitorWindow(winInfo);
			replicatespuRePositionWindow(winInfo);
			show_window = 1;
		}

		CRASSERT(newCtx->State);  /* verify valid */

		crPackSetContext( thread->packer );
	}

	/*
	 * Send the MakeCurrent to all crservers (vnc viewers)
	 */
	for (i = 0; i < CR_MAX_REPLICANTS; i++) {
		const GLint serverWin = winInfo ? winInfo->id[i] : -1;
		const GLint serverCtx = newCtx ? newCtx->rserverCtx[i] : -1;

		if (!IS_CONNECTED(replicate_spu.rserver[i].conn))
				continue;

		/* Note: app's native window ID not needed on server side; pass zero */
		if (replicate_spu.swap)
			crPackMakeCurrentSWAP(serverWin, 0, serverCtx);
		else
			crPackMakeCurrent(serverWin, 0, serverCtx);

		if (show_window) {
			/* We may find that the window was mapped before we
			 * called MakeCurrent, if that's the case then ensure
			 * the remote end gets the WindowShow event */
			if (winInfo->viewable) {
				if (replicate_spu.swap)
					crPackWindowShowSWAP(serverWin, GL_TRUE);
				else
					crPackWindowShow(serverWin, GL_TRUE);
			}
		}

		replicatespuFlushOne(thread, i);
	}

	if (newCtx) {
		crStateMakeCurrent( newCtx->State );
		crDLMSetCurrentState(newCtx->dlmState);
	}
	else {
		crStateMakeCurrent( NULL );
		crDLMSetCurrentState(NULL);
	}

	thread->currentContext = newCtx;
}
Esempio n. 17
0
/**
 * Do CRServer initializations.  After this, we can begin servicing clients.
 */
void
crServerInit(int argc, char *argv[])
{
    int i;
    char *mothership = NULL;
    CRMuralInfo *defaultMural;

    for (i = 1 ; i < argc ; i++)
    {
        if (!crStrcmp( argv[i], "-mothership" ))
        {
            if (i == argc - 1)
            {
                crError( "-mothership requires an argument" );
            }
            mothership = argv[i+1];
            i++;
        }
        else if (!crStrcmp( argv[i], "-port" ))
        {
            /* This is the port on which we'll accept client connections */
            if (i == argc - 1)
            {
                crError( "-port requires an argument" );
            }
            cr_server.tcpip_port = crStrToInt(argv[i+1]);
            i++;
        }
        else if (!crStrcmp( argv[i], "-vncmode" ))
        {
            cr_server.vncMode = 1;
        }
        else if (!crStrcmp( argv[i], "-help" ))
        {
            crPrintHelp();
            exit(0);
        }
    }

    signal( SIGTERM, crServerCleanup );
    signal( SIGINT, crServerCleanup );
#ifndef WINDOWS
    signal( SIGPIPE, SIG_IGN );
#endif

#if DEBUG_FP_EXCEPTIONS
    {
        fpu_control_t mask;
        _FPU_GETCW(mask);
        mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM
                  | _FPU_MASK_OM | _FPU_MASK_UM);
        _FPU_SETCW(mask);
    }
#endif

    cr_server.firstCallCreateContext = GL_TRUE;
    cr_server.firstCallMakeCurrent = GL_TRUE;

    /*
     * Create default mural info and hash table.
     */
    cr_server.muralTable = crAllocHashtable();
    defaultMural = (CRMuralInfo *) crCalloc(sizeof(CRMuralInfo));
    crHashtableAdd(cr_server.muralTable, 0, defaultMural);

    cr_server.programTable = crAllocHashtable();

    crNetInit(crServerRecv, crServerClose);
    crStateInit();

    crServerGatherConfiguration(mothership);

    crStateLimitsInit( &(cr_server.limits) );

    /*
     * Default context
     */
    cr_server.contextTable = crAllocHashtable();
    cr_server.DummyContext = crStateCreateContext( &cr_server.limits,
                             CR_RGB_BIT | CR_DEPTH_BIT, NULL );
    cr_server.curClient->currentCtx = cr_server.DummyContext;

    crServerInitDispatch();
    crStateDiffAPI( &(cr_server.head_spu->dispatch_table) );

    crUnpackSetReturnPointer( &(cr_server.return_ptr) );
    crUnpackSetWritebackPointer( &(cr_server.writeback_ptr) );

    cr_server.barriers = crAllocHashtable();
    cr_server.semaphores = crAllocHashtable();
}
Esempio n. 18
0
void crServerSetVBoxConfiguration()
{
    CRMuralInfo *defaultMural;
    char response[8096];

    char **spuchain;
    int num_spus;
    int *spu_ids;
    char **spu_names;
    char *spu_dir = NULL;
    int i;
    /* Quadrics defaults */
    int my_rank = 0;
    int low_context = CR_QUADRICS_DEFAULT_LOW_CONTEXT;
    int high_context = CR_QUADRICS_DEFAULT_HIGH_CONTEXT;
    unsigned char key[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    char hostname[1024];
    char **clientchain, **clientlist;
    GLint dims[4];
    const char * env;

    defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
    CRASSERT(defaultMural);

    setDefaults();

    /*
     * Get my hostname
     */
    if (crGetHostname(hostname, sizeof(hostname)))
    {
        crError("CRServer: Couldn't get my own hostname?");
    }

    strcpy(response, "1 0 render");
    crDebug("CRServer: my SPU chain: %s", response);

    /* response will describe the SPU chain.
     * Example "2 5 wet 6 render"
     */
    spuchain = crStrSplit(response, " ");
    num_spus = crStrToInt(spuchain[0]);
    spu_ids = (int *) crAlloc(num_spus * sizeof(*spu_ids));
    spu_names = (char **) crAlloc((num_spus + 1) * sizeof(*spu_names));
    for (i = 0; i < num_spus; i++)
    {
        spu_ids[i] = crStrToInt(spuchain[2 * i + 1]);
        spu_names[i] = crStrdup(spuchain[2 * i + 2]);
        crDebug("SPU %d/%d: (%d) \"%s\"", i + 1, num_spus, spu_ids[i],
                        spu_names[i]);
    }
    spu_names[i] = NULL;

    //spu_dir = crStrdup(response);
    crNetSetRank(0);
    crNetSetContextRange(32, 35);
    crNetSetNodeRange("iam0", "iamvis20");
    crNetSetKey(key,sizeof(key));
    crNetSetKey(key,sizeof(key));
    cr_server.tcpip_port = 7000;

        /*cr_server.optimizeBucket = crStrToInt(response);
        cr_server.localTileSpec = crStrToInt(response);
        cr_server.useL2 = crStrToInt(response);
        cr_server.ignore_papi = crStrToInt(response);
        if (crMothershipGetServerParam(conn, response, "overlap_blending"))
        {
            if (!crStrcmp(response, "blend"))
                cr_server.overlapBlending = 1;
            else if (!crStrcmp(response, "knockout"))
                cr_server.overlapBlending = 2;
        }
        if (crMothershipGetServerParam(conn, response, "overlap_levels"))
        cr_server.only_swap_once = crStrToInt(response);
        cr_server.debug_barriers = crStrToInt(response);
        cr_server.sharedDisplayLists = crStrToInt(response);
        cr_server.sharedTextureObjects = crStrToInt(response);
        cr_server.sharedPrograms = crStrToInt(response);
        cr_server.sharedWindows = crStrToInt(response);
        cr_server.uniqueWindows = crStrToInt(response);
        cr_server.useDMX = crStrToInt(response);
        if (crMothershipGetServerParam(conn, response, "vertprog_projection_param"))
        if (crMothershipGetServerParam(conn, response, "stereo_view"))
        if (crMothershipGetServerParam(conn, response, "view_matrix"))
        if (crMothershipGetServerParam(conn, response, "right_view_matrix"))
        if (crMothershipGetServerParam(conn, response, "projection_matrix"))
        if (crMothershipGetServerParam(conn, response, "right_projection_matrix"))*/

    crDebug("CRServer: my port number is %d", cr_server.tcpip_port);

    /*
     * Load the SPUs
     */
    cr_server.head_spu =
        crSPULoadChain(num_spus, spu_ids, spu_names, spu_dir, &cr_server);

    env = crGetenv( "CR_SERVER_DEFAULT_RENDER_TYPE" );
    if (env != NULL)
    {
        GLubyte redir = (env[0] - 0x30);
        if (redir <= CR_SERVER_REDIR_MAXVAL)
        {
            int rc = crServerSetOffscreenRenderingMode(redir);
            if (!RT_SUCCESS(rc))
                crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");
        }
        else
            crWarning("invalid redir option %c", redir);
    }
#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(GLX)
    else
    {
        int rc = crServerSetOffscreenRenderingMode(CR_SERVER_REDIR_FBO_BLT);
        if (!RT_SUCCESS(rc))
            crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");

    }
#endif
    cr_server.bOffscreenRenderingDefault = cr_server.bForceOffscreenRendering;

    /* Need to do this as early as possible */

    cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_POSITION_CR, 0, GL_INT, 2, &dims[0]);
    cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, 0, GL_INT, 2, &dims[2]);
    
    defaultMural->gX = dims[0];
    defaultMural->gY = dims[1];
    defaultMural->width = dims[2];
    defaultMural->height = dims[3];

    crFree(spu_ids);
    crFreeStrings(spu_names);
    crFreeStrings(spuchain);
    if (spu_dir)
        crFree(spu_dir);

    cr_server.mtu = 1024 * 30;

    /*
     * Get a list of all the clients talking to me.
     */
    if (cr_server.vncMode) {
        /* we're inside a vnc viewer */
        /*if (!crMothershipSendString( conn, response, "getvncclient %s", hostname ))
            crError( "Bad Mothership response: %s", response );*/
    }
    else {
        //crMothershipGetClients(conn, response);
        strcpy(response, "1 tcpip 1");
    }

    crDebug("CRServer: my clients: %s", response);

    /*
     * 'response' will now contain a number indicating the number of clients
     * of this server, followed by a comma-separated list of protocol/SPU ID
     * pairs.
     * Example: "3 tcpip 1,gm 2,via 10"
     */
    clientchain = crStrSplitn(response, " ", 1);
    cr_server.numClients = crStrToInt(clientchain[0]);
    if (cr_server.numClients == 0)
    {
        crError("I have no clients!  What's a poor server to do?");
    }
    clientlist = crStrSplit(clientchain[1], ",");

    /*
     * Connect to initial set of clients.
     * Call crNetAcceptClient() for each client.
     * Also, look for a client that's _not_ using the file: protocol.
     */
    for (i = 0; i < cr_server.numClients; i++)
    {
        CRClient *newClient = (CRClient *) crCalloc(sizeof(CRClient));
#ifdef VBOX
        sscanf(clientlist[i], "%1023s %d", cr_server.protocol, &(newClient->spu_id));
#else
        sscanf(clientlist[i], "%s %d", cr_server.protocol, &(newClient->spu_id));
#endif
        newClient->conn = crNetAcceptClient(cr_server.protocol, NULL,
                                            cr_server.tcpip_port,
                                            cr_server.mtu, 0);
        newClient->currentCtxInfo = &cr_server.MainContextInfo;
        crServerAddToRunQueue(newClient);

        cr_server.clients[i] = newClient;
    }

    /* set default client and mural */
    if (cr_server.numClients > 0) {
         cr_server.curClient = cr_server.clients[0];
         cr_server.curClient->currentMural = defaultMural;
         cr_server.client_spu_id =cr_server.clients[0]->spu_id;
    }

    crFreeStrings(clientchain);
    crFreeStrings(clientlist);

    /* Ask the mothership for the tile info */
    //crServerGetTileInfoFromMothership(conn, defaultMural);

    if (cr_server.vncMode) {
        /* In vnc mode, we reset the mothership configuration so that it can be
         * used by subsequent OpenGL apps without having to spawn a new mothership
         * on a new port.
         */
        crDebug("CRServer: Resetting mothership to initial state");
        //crMothershipReset(conn);
    }

    //crMothershipDisconnect(conn);
}
static void set_draw_bbox( RenderSPU *render_spu, char *response )
{
    render_spu->draw_bbox = crStrToInt( response );
}
static void set_use_glxchoosevisual( RenderSPU *render_spu, char *response )
{
    render_spu->use_glxchoosevisual = crStrToInt( response );
}
static void set_ignore_window_moves( RenderSPU *render_spu, char *response )
{
    render_spu->ignore_window_moves = crStrToInt( response );
}
static void set_ignore_papi( RenderSPU *render_spu, char *response )
{
    render_spu->ignore_papi = crStrToInt( response );
}
static void set_nv_swap_group( RenderSPU *render_spu, char *response )
{
    render_spu->nvSwapGroup = crStrToInt( response );
    if (render_spu->nvSwapGroup < 0)
        render_spu->nvSwapGroup = 0;
}
Esempio n. 24
0
/**
 * Get the tile information (count, extents, etc) from the servers
 * and build our corresponding data structures.
 * This is called once during SPU initialization.
 * Input: conn - mothership connection
 */
void
tilesortspuGetTilingFromServers(CRConnection *conn, WindowInfo *winInfo)
{
	ThreadInfo *thread0 = &(tilesort_spu.thread[0]);
	char response[8096];
	char **serverchain, **serverlist;
	int num_servers;
	int i;

	crDebug("Getting tile information from servers.");
	/* The response to this tells us how many servers and where they are 
	 *
	 * For example:  2 tcpip://foo tcpip://bar 
	 */
	crMothershipGetServers(conn, response);

	serverchain = crStrSplitn(response, " ", 1);
	num_servers = crStrToInt(serverchain[0]);
	CRASSERT(num_servers == tilesort_spu.num_servers);
	serverlist = crStrSplit(serverchain[1], ",");

	tilesort_spu.thread[0].netServer =
		(CRNetServer *) crCalloc(num_servers * sizeof(CRNetServer));
	tilesort_spu.thread[0].buffer =
		(CRPackBuffer *) crCalloc(num_servers * sizeof(CRPackBuffer));

	/** XXX: \todo there is lots of overlap between these cases. merge! */
	if (tilesort_spu.localTileSpec)
	{
		char **displaylist, **displaychain;
		double *corners;
		int num_displays, idx;
		double world_bbox[4];

		/* 
		 * Here we has tiles specified relative to the origin of 
		 * whichever display they happen to land in. First, gather
		 * the list of displays, then get the tiles that belong on it 
		 */
		crMothershipGetDisplays(conn, response);
		displaychain = crStrSplitn(response, " ", 1);
		displaylist = crStrSplit(displaychain[1], ",");

		num_displays = crStrToInt(displaychain[0]);

		corners = (double *) crAlloc(num_displays * 8 * sizeof(double));

		tilesort_spu.displays =
			(WarpDisplayInfo *) crAlloc(num_displays * sizeof(WarpDisplayInfo));

		idx = 0;

		for (i = 0; i < num_displays; i++)
		{
			float pnt[2], warped[2];

			sscanf(displaylist[i],
						 "%d %d %d %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
						 &tilesort_spu.displays[i].id, &tilesort_spu.displays[i].width,
						 &tilesort_spu.displays[i].height,
						 &tilesort_spu.displays[i].correct[0],
						 &tilesort_spu.displays[i].correct[1],
						 &tilesort_spu.displays[i].correct[2],
						 &tilesort_spu.displays[i].correct[3],
						 &tilesort_spu.displays[i].correct[4],
						 &tilesort_spu.displays[i].correct[5],
						 &tilesort_spu.displays[i].correct[6],
						 &tilesort_spu.displays[i].correct[7],
						 &tilesort_spu.displays[i].correct[8],
						 &tilesort_spu.displays[i].correct_inv[0],
						 &tilesort_spu.displays[i].correct_inv[1],
						 &tilesort_spu.displays[i].correct_inv[2],
						 &tilesort_spu.displays[i].correct_inv[3],
						 &tilesort_spu.displays[i].correct_inv[4],
						 &tilesort_spu.displays[i].correct_inv[5],
						 &tilesort_spu.displays[i].correct_inv[6],
						 &tilesort_spu.displays[i].correct_inv[7],
						 &tilesort_spu.displays[i].correct_inv[8]);

			pnt[0] = -1;
			pnt[1] = -1;
			crWarpPoint(tilesort_spu.displays[i].correct_inv, pnt, warped);
			corners[idx] = warped[0];
			corners[idx + 1] = warped[1];
			idx += 2;
			pnt[0] = -1;
			pnt[1] = 1;
			crWarpPoint(tilesort_spu.displays[i].correct_inv, pnt, warped);
			corners[idx] = warped[0];
			corners[idx + 1] = warped[1];
			idx += 2;
			pnt[0] = 1;
			pnt[1] = 1;
			crWarpPoint(tilesort_spu.displays[i].correct_inv, pnt, warped);
			corners[idx] = warped[0];
			corners[idx + 1] = warped[1];
			idx += 2;
			pnt[0] = 1;
			pnt[1] = -1;
			crWarpPoint(tilesort_spu.displays[i].correct_inv, pnt, warped);
			corners[idx] = warped[0];
			corners[idx + 1] = warped[1];
			idx += 2;
		}

		crHullInteriorBox(corners, idx / 2, world_bbox);
		crFree(corners);

		/* dummy values in case i forget to override them later */
		winInfo->muralWidth = tilesort_spu.displays[0].width;
		winInfo->muralHeight = tilesort_spu.displays[0].height;

		winInfo->passiveStereo = GL_FALSE;  /* may be set true below */

		for (i = 0; i < num_servers; i++)
		{
			char server_url[1024];
			ServerWindowInfo *servWinInfo = winInfo->server + i;
			char **tilechain, **tilelist;
			int tile;
			double cent[2], Sx, Sy;

			sscanf(serverlist[i], "%s", server_url);

			crDebug("Server %d: %s", i + 1, server_url);
			thread0->netServer[i].name = crStrdup(server_url);
			thread0->netServer[i].buffer_size = tilesort_spu.buffer_size;

			/* response is just like regular GetTiles, but each tile
			 * is preceeded by a display id */
			if (!crMothershipGetDisplayTiles(conn, response, i))
			{
				crError("No tile information for server %d!  I can't continue!", i);
			}

			tilechain = crStrSplitn(response, " ", 1);
			servWinInfo->num_extents = crStrToInt(tilechain[0]);
			tilelist = crStrSplit(tilechain[1], ",");

			servWinInfo->eyeFlags = EYE_LEFT | EYE_RIGHT;
			if (crMothershipGetServerParamFromSPU( conn, i,
																						 "stereo_view", response)) {
				if (crStrcmp(response, "left") == 0) {
					servWinInfo->eyeFlags = EYE_LEFT;
					winInfo->passiveStereo = GL_TRUE;
				}
				else if (crStrcmp(response, "right") == 0) {
					servWinInfo->eyeFlags = EYE_RIGHT;
					winInfo->passiveStereo = GL_TRUE;
				}
			}

			Sx = 2.0 / (world_bbox[2] - world_bbox[0]);
			Sy = 2.0 / (world_bbox[3] - world_bbox[1]);

			cent[0] = (world_bbox[0] + world_bbox[2]) / (2.);
			cent[1] = (world_bbox[1] + world_bbox[3]) / (2.);

			for (tile = 0; tile < servWinInfo->num_extents; tile++)
			{
				int id, x, y, w, h, a;
				float disp_w, disp_h, warped[2], *align;

				sscanf(tilelist[tile], "%d %d %d %d %d", &id, &x, &y, &w, &h);

				/* this is the local coordinate tiling */
				servWinInfo->display_ndx[tile] = -1;
				for (a = 0; a < num_displays; a++)
				{
					if (tilesort_spu.displays[a].id == id)
						servWinInfo->display_ndx[tile] = a;
				}
				if (servWinInfo->display_ndx[tile] == -1)
					crError("Invalid Display ID %d", id);
				servWinInfo->extents[tile].x1 = x;
				servWinInfo->extents[tile].y1 = y;
				servWinInfo->extents[tile].x2 = x + w;
				servWinInfo->extents[tile].y2 = y + h;

				/* warp the tile to mural space */
				disp_w = (float) tilesort_spu.displays[servWinInfo->display_ndx[tile]].width;
				disp_h = (float) tilesort_spu.displays[servWinInfo->display_ndx[tile]].height;

				servWinInfo->world_extents[tile][0] = (float) x / disp_w;
				servWinInfo->world_extents[tile][1] = (float) y / disp_h;

				servWinInfo->world_extents[tile][2] = (float) x / disp_w;
				servWinInfo->world_extents[tile][3] = (float) (y + h) / disp_h;

				servWinInfo->world_extents[tile][4] = (float) (x + w) / disp_w;
				servWinInfo->world_extents[tile][5] = (float) (y + h) / disp_h;

				servWinInfo->world_extents[tile][6] = (float) (x + w) / disp_w;
				servWinInfo->world_extents[tile][7] = (float) y / disp_h;

				for (a = 0; a < 8; a++)
					servWinInfo->world_extents[tile][a] =
						(float)2.0 * servWinInfo->world_extents[tile][a] - (float)1.0;

				align = tilesort_spu.displays[servWinInfo->display_ndx[tile]].correct_inv;
				for (a = 0; a < 4; a++)
				{
					crWarpPoint(align, servWinInfo->world_extents[tile] + 2 * a, warped);

					warped[0] = (warped[0] - (float)cent[0]) * (float) Sx;
					warped[1] = (warped[1] - (float)cent[1]) * (float) Sy;

					crDebug("%f %f warps to %f %f", servWinInfo->world_extents[tile][2 * a],
									servWinInfo->world_extents[tile][2 * a + 1], warped[0],
									warped[1]);

					servWinInfo->world_extents[tile][2 * a] = warped[0];
					servWinInfo->world_extents[tile][2 * a + 1] = warped[1];
				}


				/** XXX: \todo check that the tile fits w/i the display it is on */
			}
			crFreeStrings(tilechain);
			crFreeStrings(tilelist);
		}

		crFreeStrings(displaychain);
		crFreeStrings(displaylist);

		/* can't do any fancy bucketing with this */
		tilesort_spu.defaultBucketMode = WARPED_GRID;
	}
	else
	{
		/*
		 * Get the list of tiles from all servers.
		 * And compute mural size.
		 */
		winInfo->muralWidth = 0;
		winInfo->muralHeight = 0;
		for (i = 0; i < num_servers; i++)
		{
			char server_url[1024];
			ServerWindowInfo *servWinInfo = winInfo->server + i;
			char **tilechain, **tilelist;
			int tile;

			sscanf(serverlist[i], "%s", server_url);

			crDebug("Server %d: %s", i + 1, server_url);
			thread0->netServer[i].name = crStrdup(server_url);
			thread0->netServer[i].buffer_size = tilesort_spu.buffer_size;

			if (!crMothershipGetTiles(conn, response, i))
			{
				crError("No tile information for server %d!  I can't continue!", i);
			}

			tilechain = crStrSplitn(response, " ", 1);
			servWinInfo->num_extents = crStrToInt(tilechain[0]);
			tilelist = crStrSplit(tilechain[1], ",");

			for (tile = 0; tile < servWinInfo->num_extents; tile++)
			{
				int x, y, w, h;

				sscanf(tilelist[tile], "%d %d %d %d", &x, &y, &w, &h);
				servWinInfo->extents[tile].x1 = x;
				servWinInfo->extents[tile].y1 = y;
				servWinInfo->extents[tile].x2 = x + w;
				servWinInfo->extents[tile].y2 = y + h;

				/* update mural size */
				if (servWinInfo->extents[tile].x2 > (int) winInfo->muralWidth)
				{
					winInfo->muralWidth = servWinInfo->extents[tile].x2;
				}
				if (servWinInfo->extents[tile].y2 > (int) winInfo->muralHeight)
				{
					winInfo->muralHeight = servWinInfo->extents[tile].y2;
				}
			}

			crFreeStrings(tilechain);
			crFreeStrings(tilelist);

			/* Determine if the server should receieve left, right or both eye
			 * views when running in passive stereo mode.
			 */
			servWinInfo->eyeFlags = EYE_LEFT | EYE_RIGHT;
			if (crMothershipGetServerParamFromSPU( conn, i,
																						 "stereo_view", response)) {
				if (crStrcmp(response, "left") == 0) {
					servWinInfo->eyeFlags = EYE_LEFT;
					winInfo->passiveStereo = GL_TRUE;
				}
				else if (crStrcmp(response, "right") == 0) {
					servWinInfo->eyeFlags = EYE_RIGHT;
					winInfo->passiveStereo = GL_TRUE;
				}
			}

			/* get view matrices from the server */
			if (crMothershipGetServerParamFromSPU( conn, i,
																						 "view_matrix", response)) {
				crMatrixInitFromString(&servWinInfo->viewMatrix[0], response);
				if (!crMatrixIsIdentity(&servWinInfo->viewMatrix[0]))
					winInfo->matrixSource = MATRIX_SOURCE_SERVERS;
			}
			if (crMothershipGetServerParamFromSPU( conn, i,
																						 "right_view_matrix", response)) {
				crMatrixInitFromString(&servWinInfo->viewMatrix[1], response);
				if (!crMatrixIsIdentity(&servWinInfo->viewMatrix[1]))
					winInfo->matrixSource = MATRIX_SOURCE_SERVERS;
			}
			/*
			crMatrixPrint("Left view", &servWinInfo->viewMatrix[0]);
			crMatrixPrint("Right view", &servWinInfo->viewMatrix[1]);
			*/

			/* Also get overriding projection matrix.
			 * Note that this matrix is only relevant to FRUSTUM bucketing.
			 */
			if (crMothershipGetServerParamFromSPU( conn, i,
																			 "projection_matrix", response)) {
				/** XXX \todo projection_matrix is obsolete, keep for a while though */
				crMatrixInitFromString(&servWinInfo->projectionMatrix[0], response);
				if (!crMatrixIsIdentity(&servWinInfo->projectionMatrix[0]))
					winInfo->matrixSource = MATRIX_SOURCE_SERVERS;
			}
			if (crMothershipGetServerParamFromSPU( conn, i,
																			 "right_projection_matrix", response)) {
				crMatrixInitFromString(&servWinInfo->projectionMatrix[1], response);
				if (!crMatrixIsIdentity(&servWinInfo->projectionMatrix[1]))
					winInfo->matrixSource = MATRIX_SOURCE_SERVERS;
			}
			/*
			crMatrixPrint("Left proj", &servWinInfo->projectionMatrix[0]);
			crMatrixPrint("Right proj", &servWinInfo->projectionMatrix[1]);
			*/
		}
	}

	crFreeStrings(serverchain);
	crFreeStrings(serverlist);

	tilesortspuBucketingInit( winInfo );
}
Esempio n. 25
0
static void 
crutInitServer(char *mothership, int argc, char *argv[])
{
    char response[8096];
#ifndef WINDOWS
    int drawable;
#endif
    int displayMode;

    crNetInit( NULL/*crutServerRecv*/, crutServerClose );

    crutInitAPI( &crut_api, mothership ); /* here? */

    crMothershipIdentifyCRUTServer( crut_api.mothershipConn, response );

    crutGetWindowParams( &crut_api );
    
    /* set up GLUT window */
    glutInit(&argc, argv);

    displayMode = GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA;
    if (crut_api.compositeAlpha)
       displayMode |= GLUT_ALPHA;
    if (crut_api.compositeDepth)
       displayMode |= GLUT_STENCIL;
    glutInitDisplayMode(displayMode);

    glutInitWindowPosition( crut_api.winX,crut_api.winY );
    glutInitWindowSize( crut_api.winWidth,crut_api.winHeight );
    
    glutCreateWindow("CRUTServer Interactive Window"); 
    
    glutDisplayFunc(showWin);
    
    /* give window id to mothership */
#ifndef WINDOWS
#ifdef DARWIN
    /* XXX \todo crut get current drawable (this only gets glut win_num) */
    drawable = glutGetWindow();
#else
    /* XXX is this cast safe? */
    drawable = (int) glXGetCurrentDrawable();
#endif
    crutSetWindowID( &crut_api, drawable);
#endif

    /* use API to connect to clients */
    crutConnectToClients( &crut_api );

    /* Retrieve events to send out */
    crMothershipGetParam( crut_api.mothershipConn, "crut_callbacks_mouse", response );
    crut_server.callbacks.mouse = crStrToInt(response);

    crMothershipGetParam( crut_api.mothershipConn, "crut_callbacks_keyboard", response );
    crut_server.callbacks.keyboard = crStrToInt(response);

    crMothershipGetParam( crut_api.mothershipConn, "crut_callbacks_motion", response );
    crut_server.callbacks.motion = crStrToInt(response);

    crMothershipGetParam( crut_api.mothershipConn, "crut_callbacks_passivemotion", response );
    crut_server.callbacks.passivemotion = crStrToInt(response);

    crMothershipGetParam( crut_api.mothershipConn, "crut_callbacks_reshape", response );
    crut_server.callbacks.reshape = crStrToInt(response);

    crMothershipGetParam( crut_api.mothershipConn, "crut_callbacks_visibility", response );
    crut_server.callbacks.visibility = crStrToInt(response);

    crMothershipGetParam( crut_api.mothershipConn, "crut_callbacks_menu", response );
    crut_server.callbacks.menu = crStrToInt(response);

    /* Exit flag */
    crMothershipGetCRUTServerParam( crut_api.mothershipConn, response, "exit_on_escape");
    crut_server.exit_on_escape = crStrToInt(response);

#ifdef USE_CRUT_MENUS
    crutGetMenuXML();

    buildMenu();
#endif
 
}
static void set_num_clients ( RenderSPU *render_spu, char *response )
{
    render_spu->num_swap_clients = crStrToInt( response );
}
Esempio n. 27
0
File: load.c Progetto: OSLL/vboxhsm
/**
 * Do one-time initializations for the faker.
 * Returns TRUE on success, FALSE otherwise.
 */
static bool
stubInitLocked(void)
{
    /* Here is where we contact the mothership to find out what we're supposed
     * to  be doing.  Networking code in a DLL initializer.  I sure hope this
     * works :)
     *
     * HOW can I pass the mothership address to this if I already know it?
     */

    CRConnection *conn = NULL;
    char response[1024];
    char **spuchain;
    int num_spus;
    int *spu_ids;
    char **spu_names;
    const char *app_id;
    int i;
    int disable_sync = 0;

    stubInitVars();

    crGetProcName(response, 1024);
    crDebug("Stub launched for %s", response);

#if defined(CR_NEWWINTRACK) && !defined(WINDOWS)
    /*@todo when vm boots with compiz turned on, new code causes hang in xcb_wait_for_reply in the sync thread
     * as at the start compiz runs our code under XGrabServer.
     */
    if (!crStrcmp(response, "compiz") || !crStrcmp(response, "compiz_real") || !crStrcmp(response, "compiz.real")
	|| !crStrcmp(response, "compiz-bin"))
    {
        disable_sync = 1;
    }
#elif defined(WINDOWS) && defined(VBOX_WITH_WDDM) && defined(VBOX_WDDM_MINIPORT_WITH_VISIBLE_RECTS)
    if (GetModuleHandle(VBOX_MODNAME_DISPD3D))
    {
        disable_sync = 1;
        crDebug("running with " VBOX_MODNAME_DISPD3D);
        stub.trackWindowVisibleRgn = 0;
        stub.bRunningUnderWDDM = true;
    }
#endif

    /* @todo check if it'd be of any use on other than guests, no use for windows */
    app_id = crGetenv( "CR_APPLICATION_ID_NUMBER" );

    crNetInit( NULL, NULL );

#ifndef WINDOWS
    {
        CRNetServer ns;

        ns.name = "vboxhgcm://host:0";
        ns.buffer_size = 1024;
        crNetServerConnect(&ns
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , NULL
#endif
                );
        if (!ns.conn)
        {
            crWarning("Failed to connect to host. Make sure 3D acceleration is enabled for this VM.");
            return false;
        }
        else
        {
            crNetFreeConnection(ns.conn);
        }
#if 0 && defined(CR_NEWWINTRACK)
        {
            Status st = XInitThreads();
            if (st==0)
            {
                crWarning("XInitThreads returned %i", (int)st);
            }
        }
#endif
    }
#endif

    strcpy(response, "2 0 feedback 1 pack");
    spuchain = crStrSplit( response, " " );
    num_spus = crStrToInt( spuchain[0] );
    spu_ids = (int *) crAlloc( num_spus * sizeof( *spu_ids ) );
    spu_names = (char **) crAlloc( num_spus * sizeof( *spu_names ) );
    for (i = 0 ; i < num_spus ; i++)
    {
        spu_ids[i] = crStrToInt( spuchain[2*i+1] );
        spu_names[i] = crStrdup( spuchain[2*i+2] );
        crDebug( "SPU %d/%d: (%d) \"%s\"", i+1, num_spus, spu_ids[i], spu_names[i] );
    }

    stubSetDefaultConfigurationOptions();

    stub.spu = crSPULoadChain( num_spus, spu_ids, spu_names, stub.spu_dir, NULL );

    crFree( spuchain );
    crFree( spu_ids );
    for (i = 0; i < num_spus; ++i)
        crFree(spu_names[i]);
    crFree( spu_names );

    // spu chain load failed somewhere
    if (!stub.spu) {
        return false;
    }

    crSPUInitDispatchTable( &glim );

    /* This is unlikely to change -- We still want to initialize our dispatch
     * table with the functions of the first SPU in the chain. */
    stubInitSPUDispatch( stub.spu );

    /* we need to plug one special stub function into the dispatch table */
    glim.GetChromiumParametervCR = stub_GetChromiumParametervCR;

#if !defined(VBOX_NO_NATIVEGL)
    /* Load pointers to native OpenGL functions into stub.nativeDispatch */
    stubInitNativeDispatch();
#endif

/*crDebug("stub init");
raise(SIGINT);*/

#ifdef WINDOWS
# ifndef CR_NEWWINTRACK
    stubInstallWindowMessageHook();
# endif
#endif

#ifdef CR_NEWWINTRACK
    {
        int rc;

        RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);

        if (!disable_sync)
        {
            crDebug("Starting sync thread");

            rc = RTThreadCreate(&stub.hSyncThread, stubSyncThreadProc, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "Sync");
            if (RT_FAILURE(rc))
            {
                crError("Failed to start sync thread! (%x)", rc);
            }
            RTThreadUserWait(stub.hSyncThread, 60 * 1000);
            RTThreadUserReset(stub.hSyncThread);

            crDebug("Going on");
        }
    }
#endif

#ifdef GLX
    stub.xshmSI.shmid = -1;
    stub.bShmInitFailed = GL_FALSE;
    stub.pGLXPixmapsHash = crAllocHashtable();

    stub.bXExtensionsChecked = GL_FALSE;
    stub.bHaveXComposite = GL_FALSE;
    stub.bHaveXFixes = GL_FALSE;
#endif

    return true;
}
Esempio n. 28
0
static void
set_verbose(ZpixSPU * zpix_spu, const char *response)
{
	zpix_spu->verbose = crStrToInt(response);
	crDebug("Zpix SPU config: verbose = %d", zpix_spu->verbose);
}
Esempio n. 29
0
static void
set_debug(ZpixSPU * zpix_spu, const char *response)
{
	zpix_spu->debug = crStrToInt(response);
	crDebug("Zpix SPU config: debug = %d", zpix_spu->debug);
}
Esempio n. 30
0
int
main(int argc, char *argv[])
{
	const int port = 10000;
	CRConnection *conn[MAX_SERVERS];
	const char *servers[MAX_SERVERS];
	int numServers = 0;
	int bufferSize = 10000;
	int numBuffers = 10;
	int autoMode = 0;
	int size;
	int i, j;

	if (argc < 2) {
		PrintHelp();
		return 0;
	}

	for (i = 1; i < argc; i++) {
		if (!crStrcmp(argv[i], "-a")) {
			autoMode = 1;
		}
		else if (!crStrcmp(argv[i], "-b") && (i + 1 < argc)) {
			bufferSize = crStrToInt(argv[i + 1]);
			i++;
		}
		else if (!crStrcmp(argv[i], "-h")) {
			PrintHelp();
			return 0;
		}
		else if (!crStrcmp(argv[i], "-m") && (i + 1 < argc)) {
			MTU = crStrToInt(argv[i + 1]);
			i++;
		}
		else if (!crStrcmp(argv[i], "-n") && (i + 1 < argc)) {
			numBuffers = crStrToInt(argv[i + 1]);
			i++;
		}
		else if ((argv[i][0] != '-') && (numServers < MAX_SERVERS)) {
			servers[numServers] = argv[i];
			numServers++;
		}
	}

	if (numServers == 0) {
		printf("npclient error: need to specify at least one server\n");
		return 1;
	}

	if (autoMode)
		printf("npclient:  MTU=%d  (automatic buffer sizing)\n", MTU);
	else
		printf("npclient:  MTU=%d  bufferSize=%d  numBuffers=%d\n",
					 MTU, bufferSize, numBuffers);

	MyTimer = crTimerNewTimer();
	crNetInit( ReceiveFunc, CloseFunc );

	printf("npclient:  Connecting to servers\n");
	for (i = 0; i < numServers; i++) {
		conn[i] = crNetConnectToServer(servers[i], (unsigned short) port, MTU, 0);
		if (conn[i]) {
			printf("npclient:  Connection to %s OK.\n", servers[i]);
		}
		else {
			printf("npclient:  Connection to %s failed!\n", servers[i]);
			exit(1);
		}
	}

	printf("npclient:  Testing...\n");

	if (autoMode) {
		bufferSize = 10000;
		for (size = 0; size < 5; size++) {
			double t0, t1, dt, rate;
			double bytes;
			int buffers;

			bytes = 0.0;
			buffers = 0;
			crStartTimer(MyTimer);
			t0 = crTimerTime(MyTimer);

			do {
				for (j = 0; j < numServers; j++) {
					SendOpcodes(conn[j], bufferSize, 0);
				}
				bytes += (double) bufferSize;
				buffers++;
				t1 = crTimerTime(MyTimer);
			} while (t1 - t0 < 5.0);

			crStopTimer(MyTimer);

			dt = t1 - t0;
			rate = (double) bytes / dt / 1000000.0;
			printf("npclient:  %8.3f MB/s (%d bytes / buffer, %d buffers, %d servers)\n",
						 rate, bufferSize, buffers, numServers);
			if (rate < 0.0) {
				char *t = 0;
				*t = 0;
				CRASSERT(rate >= 0.0);
			}
			bufferSize *= 10;
		}
	}
	else {
		double t0, t1, dt, rate;
		double bytes;

		crStartTimer(MyTimer);
		t0 = crTimerTime(MyTimer);
		bytes = 0.0;
		for (i = 0; i < numBuffers; i++) {
			for (j = 0; j < numServers; j++) {
				SendOpcodes(conn[j], bufferSize, 0);
			}
			bytes += (double) bufferSize;
		}
		t1 = crTimerTime(MyTimer);

		dt = t1 - t0;
		rate = (double) bytes / dt / 1000000.0;
		printf("npclient:  %8.3f MB/s (%d bytes / buffer, %d buffers, %d servers)\n",
					 rate, bufferSize, numBuffers, numServers);
	}


	/* Send exit message to servers */
	for (j = 0; j < numServers; j++) {
		SendOpcodes(conn[j], 100, 1);
	}

	for (j = 0; j < numServers; j++) {
		crNetDisconnect(conn[j]);
	}

	printf("npclient:  done!\n");

	return 0;
}