vrpn_Mutex::vrpn_Mutex(const char *name, vrpn_Connection *c) : d_connection(c) { char *servicename; servicename = vrpn_copy_service_name(name); if (c) { c->addReference(); d_myId = c->register_sender(servicename); d_requestIndex_type = c->register_message_type(requestIndex_type); d_requestMutex_type = c->register_message_type(requestMutex_type); d_release_type = c->register_message_type(release_type); d_releaseNotification_type = c->register_message_type(releaseNotification_type); d_grantRequest_type = c->register_message_type(grantRequest_type); d_denyRequest_type = c->register_message_type(denyRequest_type); d_initialize_type = c->register_message_type(initialize_type); } if (servicename) { try { delete[] servicename; } catch (...) { fprintf(stderr, "vrpn_Mutex::vrpn_Mutex(): delete failed\n"); return; } } }
vrpn_BaseClass::vrpn_BaseClass (const char * name, vrpn_Connection * c) { bool firstTimeCalled = (d_connection==NULL); // has the constructor been called before? // note that this might also be true if it was called once before but failed. if (firstTimeCalled) { // Get the connection for this object established. If the user passed in a // NULL connection object, then we determine the connection from the name of // the object itself (for example, [email protected] will make a // connection to the machine mumble on the standard VRPN port). // // The vrpn_BassClassUnique destructor handles telling the connection we // are no longer referring to it. Since we only add the reference once // here (when d_connection is NULL), it is okay for the unique destructor // to remove the reference. if (c) { // using existing connection. d_connection = c; d_connection->addReference(); } else { // This will implicitly add the reference to the connection. d_connection = vrpn_get_connection_by_name(name); } // Get the part of the name for this device that does not include the connection. // The vrpn_BassClassUnique destructor handles the deletion of the space. d_servicename = vrpn_copy_service_name(name); } }
bool vrpn_Imager_Stream_Buffer::setup_handlers_for_logging_connection( vrpn_Connection *c) { // Create a vrpn_Imager_Remote on this connection and set its callbacks so // that they will do what needs doing; the callbacks point to the // Imager_Stream_Buffer object, not to the imager_remote object; access it // through the member variable pointer. d_imager_remote = new vrpn_Imager_Remote(d_imager_server_name, c); if (d_imager_remote == NULL) { fprintf(stderr, "vrpn_Imager_Stream_Buffer::setup_handlers_for_logging_" "connection(): Cannot create vrpn_Imager_Remote\n"); return false; } d_imager_remote->register_description_handler(this, handle_image_description); // Figure out the remote type IDs from the server for the messages we want // to forward. This is really dangerous, because we need to make sure to // explicitly list all the ones we might need. If we forget an important // one (or it gets added later to either the base class or the imager class) // then it won't get forwarded. d_server_description_m_id = c->register_message_type("vrpn_Imager Description"); d_server_begin_frame_m_id = c->register_message_type("vrpn_Imager Begin_Frame"); d_server_end_frame_m_id = c->register_message_type("vrpn_Imager End_Frame"); d_server_discarded_frames_m_id = c->register_message_type("vrpn_Imager Discarded_Frames"); d_server_regionu8_m_id = c->register_message_type("vrpn_Imager Regionu8"); d_server_regionu16_m_id = c->register_message_type("vrpn_Imager Regionu16"); d_server_regionu12in16_m_id = c->register_message_type("vrpn_Imager Regionu12in16"); d_server_regionf32_m_id = c->register_message_type("vrpn_Imager Regionf32"); d_server_text_m_id = c->register_message_type("vrpn_Base text_message"); d_server_ping_m_id = c->register_message_type("vrpn_Base ping_message"); d_server_pong_m_id = c->register_message_type("vrpn_Base pong_message"); // Set up handlers for the other messages from the server so that they can // be passed on up to the initial thread and on to the client as // appropriate. // Be sure to strip the "@" part off the device name before registering the // sender // so that it is the same as the one used by the d_imager_remote. c->register_handler( vrpn_ANY_TYPE, static_handle_server_messages, this, c->register_sender(vrpn_copy_service_name(d_imager_server_name))); return true; }
int main(int argc, char* argv[]) { // Declare a new text receiver (all objects are text senders) // and find out what connection it is using. r = new vrpn_Text_Receiver (argv[1]); c = r->connectionPtr(); // Declare the same sender and message types that the BaseClass // will use for doing the ping/pong, so we can use the same // mechanism. Register a handler for the pong message, so we // can deal with them. ping_message_id = c->register_message_type("Server, are you there?"); pong_message_id = c->register_message_type("Server is here!"); sender = c->register_sender(vrpn_copy_service_name(argv[1])); c->register_handler(pong_message_id, my_pong_handler, NULL, sender); // Let the user kill the program "nicely." signal(SIGINT, handle_cntl_c); // Wait a few seconds (spinning while we do) in order to allow the // real pong message to clear from the system. struct timeval then, diff; vrpn_gettimeofday(&then, NULL); do { vrpn_gettimeofday(&now, NULL); r->mainloop(); diff = vrpn_TimevalDiff(now, then); } while ( vrpn_TimevalMsecs(vrpn_TimevalNormalize(diff)) < 2000); // Send a new ping request to the server, and start counting how // long it takes to respond. vrpn_gettimeofday(&last_ping, NULL); c->pack_message(0, last_ping, ping_message_id, sender, NULL, vrpn_CONNECTION_RELIABLE); // Loop forever. while (1) { r->mainloop(); } }
bool vrpn_Imager_Stream_Buffer::teardown_handlers_for_logging_connection( vrpn_Connection *c) { if (!d_imager_remote) { fprintf(stderr, "vrpn_Imager_Stream_Buffer::teardown_handlers_for_" "logging_connection(): No imager remote\n"); return false; } if (d_imager_remote->unregister_description_handler( this, handle_image_description) != 0) { fprintf(stderr, "vrpn_Imager_Stream_Buffer::teardown_handlers_for_" "logging_connection(): Cannot unregister handler\n"); return false; } // Tear down handlers for the other messages from the server. c->unregister_handler( vrpn_ANY_TYPE, static_handle_server_messages, this, c->register_sender(vrpn_copy_service_name(d_imager_server_name))); delete d_imager_remote; d_imager_remote = NULL; return true; }
int main(int argc, char **argv) { char default_imager[] = "TestImage@localhost"; char *device_name = default_imager; char *logfile_name = NULL; int i; // Parse the command line. If there is one argument, it is the device // name. If there is a second, it is a logfile name. if (argc >= 2) { device_name = argv[1]; } if (argc >= 3) { logfile_name = argv[2]; } if (argc > 3) { fprintf(stderr, "Usage: %s [device_name [logfile_name]]\n", argv[0]); exit(-1); } // In case we end up loading an video from a file, make sure we // neither pre-load nor accumulate the images. vrpn_FILE_CONNECTIONS_SHOULD_PRELOAD = false; vrpn_FILE_CONNECTIONS_SHOULD_ACCUMULATE = false; // Say that we've posted a redisplay so that the callback handler // for endframe doesn't try to post one before glut is open. g_already_posted = true; // Create a log file of the video if we've been asked to do logging. // This has the side effect of having the imager also use this same // connection, because VRPN maps the same connection name to the // same one rather than creating a new one. if (logfile_name) { g_connection = vrpn_get_connection_by_name(device_name, logfile_name); } // Open the Imager client and set the callback // for new data and for information about the size of // the image. printf("Opening %s\n", device_name); g_imager = new vrpn_Imager_Remote(device_name); g_imager->register_description_handler(NULL, handle_description_message); g_imager->register_region_handler(g_imager, handle_region_change); g_imager->register_discarded_frames_handler(NULL, handle_discarded_frames); g_imager->register_end_frame_handler(g_imager, handle_end_of_frame); printf("Waiting to hear the image dimensions...\n"); while (!g_got_dimensions) { g_imager->mainloop(); vrpn_SleepMsecs(1); } // Because the vrpn_Imager server doesn't follow "The VRPN Way" in that // it will continue to attempt to flood the network with more data than // can be sent, we need to tell the client's connection to stop handling // incoming messages after some finite number, to avoid getting stuck down // in the imager's mainloop() and never returning control to the main // program. This strange-named function does this for us. If the camera // is not sending too many messages for the network, this should not have // any effect. g_imager->connectionPtr()->Jane_stop_this_crazy_thing(50); // Allocate memory for the image and clear it, so that things that // don't get filled in will be black. if ( (g_image = new unsigned char[g_Xdim * g_Ydim * 3]) == NULL) { fprintf(stderr,"Out of memory when allocating image!\n"); return -1; } for (i = 0; i < g_Xdim * g_Ydim * 3; i++) { g_image[i] = 0; } g_ready_for_region = true; printf("Receiving images at size %dx%d\n", g_Xdim, g_Ydim); printf("Press '0'-'9' in OpenGL window to throttle incoming images.\n"); printf("Press '-' to disable throttling.\n"); printf("Press 'a' to enable/disable autoscaling of brightness.\n"); printf("Press 'q' or 'Q' or ESC to quit.\n"); // Initialize GLUT and create the window that will display the // video -- name the window after the device that has been // opened in VRPN. glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(g_Xdim, g_Ydim); glutInitWindowPosition(100, 100); glutCreateWindow(vrpn_copy_service_name(device_name)); // Set the display function and idle function for GLUT (they // will do all the work) and then give control over to GLUT. glutDisplayFunc(myDisplayFunc); glutIdleFunc(myIdleFunc); glutKeyboardFunc(myKeyboardFunc); glutMainLoop(); // Clean up objects and return. This code is never called because // glutMainLoop() never returns. return 0; }
int main(int argc, char **argv) { char *device_name = "TestImage@localhost:4511"; int i; //------------------------------------------------------------------ // Initialize GLUT so that it fixes the command-line arguments. glutInit(&argc, argv); //------------------------------------------------------------------ // Read command-line arguments for the program. switch (argc) { case 1: break; case 2: device_name = argv[1]; break; default: fprintf(stderr,"Usage: %s [device_to_connect_to]\n", argv[0]); fprintf(stderr," device_to_connect_to: Default TestImage@localhost:4511\n"); exit(-1); } //------------------------------------------------------------------ // Generic Tcl startup. Getting and interpreter and mainwindow. char command[256]; Tcl_Interp *tk_control_interp; Tk_Window tk_control_window; tk_control_interp = Tcl_CreateInterp(); /* Start a Tcl interpreter */ if (Tcl_Init(tk_control_interp) == TCL_ERROR) { fprintf(stderr, "Tcl_Init failed: %s\n",tk_control_interp->result); return(-1); } /* Start a Tk mainwindow to hold the widgets */ if (Tk_Init(tk_control_interp) == TCL_ERROR) { fprintf(stderr, "Tk_Init failed: %s\n",tk_control_interp->result); return(-1); } tk_control_window = Tk_MainWindow(tk_control_interp); if (tk_control_window == NULL) { fprintf(stderr,"%s\n", tk_control_interp->result); return(-1); } //------------------------------------------------------------------ // Loading the particular definition files we need. russ_widgets is // required by the Tclvar_float_with_scale class. simple_magnet_drive // is application-specific and sets up the controls for the integer // and float variables. /* Load the Tcl scripts that handle widget definition and * variable controls */ sprintf(command, "source russ_widgets.tcl"); if (Tcl_Eval(tk_control_interp, command) != TCL_OK) { fprintf(stderr, "Tcl_Eval(%s) failed: %s\n", command, tk_control_interp->result); return(-1); } //------------------------------------------------------------------ // Put the version number into the main window. sprintf(command, "label .versionlabel -text Argonot_v:_%s", Version_string); if (Tcl_Eval(tk_control_interp, command) != TCL_OK) { fprintf(stderr, "Tcl_Eval(%s) failed: %s\n", command, tk_control_interp->result); return(-1); } sprintf(command, "pack .versionlabel"); if (Tcl_Eval(tk_control_interp, command) != TCL_OK) { fprintf(stderr, "Tcl_Eval(%s) failed: %s\n", command, tk_control_interp->result); return(-1); } //------------------------------------------------------------------ // This routine must be called in order to initialize all of the // variables that came into scope before the interpreter was set // up, and to tell the variables which interpreter to use. It is // called once, after the interpreter exists. // Initialize the variables using the interpreter if (Tclvar_init(tk_control_interp)) { fprintf(stderr,"Can't do init!\n"); return -1; } // Open the Imager client and set the callback // for new data and for information about the size of // the image. printf("Opening %s\n", device_name); g_ti = new vrpn_Imager_Remote(device_name); g_ti->register_description_handler(NULL, handle_description_message); g_ti->register_region_handler(NULL, handle_region_change); printf("Waiting to hear the image dimensions...\n"); while (!g_got_dimensions) { g_ti->mainloop(); vrpn_SleepMsecs(1); } if ( (g_image = new unsigned char[g_ti->nCols() * g_ti->nRows() * 3]) == NULL) { fprintf(stderr,"Out of memory when allocating image!\n"); return -1; } if ( (g_background = new int[g_ti->nCols() * g_ti->nRows()]) == NULL) { fprintf(stderr,"Out of memory when allocating image!\n"); return -1; } for (i = 0; i < g_ti->nCols() * g_ti->nRows(); i++) { g_background[i] = 0; } g_ready_for_region = true; printf("Receiving images at size %dx%d\n", g_ti->nCols(), g_ti->nRows()); //------------------------------------------------------------------ // Initialize GLUT display modes and create the window that will display the // video -- name the window after the device that has been // opened in VRPN. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(g_ti->nCols(), g_ti->nRows()); glutInitWindowPosition(100, 100); g_window_id = glutCreateWindow(vrpn_copy_service_name(device_name)); // Set the display function and idle function for GLUT (they // will do all the work) and then give control over to GLUT. glutDisplayFunc(myDisplayFunc); glutIdleFunc(myIdleFunc); glutMainLoop(); // Clean up objects and return. cleanup(); return 0; }