Esempio n. 1
0
void collabclient_sessionDisconnect( FontViewBase* fv )
{
#ifdef BUILD_COLLAB
    
    cloneclient_t *cc = fv->collabClient;

    fv->collabState = cs_disconnected;
    fv->collabClient = 0;
    FVTitleUpdate( fv );
    
    collabclient_free( (void**)&cc );

#endif
}
Esempio n. 2
0
/**
 * A timeout function which is called after a given idle period to
 * alert the user if we have not received a reply from the server yet.
 *
 * If we don't get a reply in time then the user experience will
 * suffer greatly (UI elements jumping around etc) so we ask the user
 * if they want to start again or disconnect.
 */
static void collabclient_roundTripTimer( void* ccvp )
{
    cloneclient_t *cc = (cloneclient_t*)ccvp;

//    printf("collabclient_roundTripTimer() cc: %p\n", cc );
//    printf("collabclient_roundTripTimer() waitingseq: %d\n", cc->roundTripTimerWaitingSeq );

    if( cc->roundTripTimerWaitingSeq )
    {
	cc->roundTripTimerWaitingSeq = 0;
	
	char *buts[3];
	buts[0] = _("_Reconnect");
	buts[1] = _("_Disconnect");
	buts[2] = NULL;

	if ( gwwv_ask(_("Network Issue"),
		      (const char **) buts,0,1,
		      _("FontForge expected some input from the server by now.\nWould you like to try to reconnect to the collaboration session?"))==1 )
	{
	    // break session
	    FontView* fv = FontViewFind( FontViewFind_byCollabPtr, cc );
	    if( fv )
	    {
		printf("fv:%p\n", fv );
		fv->b.collabState = cs_disconnected;
		fv->b.collabClient = 0;
		FVTitleUpdate( &fv->b );
	    }
	    
	    collabclient_free( (void**)&cc );
	    return;
	}
	
	collabclient_sessionReconnect( cc );
    }
}
Esempio n. 3
0
FontViewBase* collabclient_sessionJoin( void* ccvp, FontView *fv )
{
    FontViewBase* ret = 0;
    
#ifdef BUILD_COLLAB
    
    cloneclient_t* cc = (cloneclient_t*)ccvp;
    printf("collabclient_sessionJoin(top)\n");

    //  Get state snapshot
    cc->sequence = 0;
    zstr_sendm (cc->snapshot, "ICANHAZ?");
    zstr_send  (cc->snapshot, SUBTREE);

    // if we wait for timeoutMS millisec then we assume failure
    // timeWaitedMS is used to keep track of how long we have waited
    kvmsg_t* lastSFD = 0;
    int timeWaitedMS = 0;
    int timeoutMS = pref_collab_sessionJoinTimeoutMS;
    while (true)
    {
	printf("timeoutMS:%d timeWaitedMS:%d\n", timeoutMS, timeWaitedMS );
	if( timeWaitedMS >= timeoutMS )
	{
	    char* addrport = collabclient_makeAddressString( cc->address, cc->port );
	    gwwv_post_error(_("FontForge Collaboration"),
			    _("Failed to connect to server session at %s"),
			    addrport );
	    return 0;
	}

        kvmsg_t *kvmsg = kvmsg_recv_full( cc->snapshot, ZMQ_DONTWAIT );
	if (!kvmsg)
	{
	    int msToWait = 50;
	    g_usleep( msToWait * 1000 );
	    timeWaitedMS += msToWait;
	    continue;
        }
	
    
        /* kvmsg_t *kvmsg = kvmsg_recv (cc->snapshot); */
        /* if (!kvmsg) */
        /*     break;          //  Interrupted */
	
        if (streq (kvmsg_key (kvmsg), "KTHXBAI")) {
            cc->sequence = kvmsg_sequence (kvmsg);
            printf ("I: received snapshot=%d\n", (int) cc->sequence);
            kvmsg_destroy (&kvmsg);
	    // Done
            break;
        }
	printf ("I: storing seq=%ld ", kvmsg_sequence (kvmsg));
	if( kvmsg_get_prop (kvmsg, "type") )
	    printf(" type:%s", kvmsg_get_prop (kvmsg, "type") );
	printf ("\n");
	if( !strcmp(kvmsg_get_prop (kvmsg, "type"), MSG_TYPE_SFD ))
	{
	    if( !lastSFD ||
		kvmsg_sequence (kvmsg) > kvmsg_sequence (lastSFD))
	    {
		lastSFD = kvmsg;
	    }
	    size_t data_size = kvmsg_size(lastSFD);
	    printf("data_size:%ld\n", data_size );
	}
	kvmsg_store (&kvmsg, cc->kvmap);
    }
    printf("collabclient_sessionJoin(done with netio getting snapshot)\n");
    printf("collabclient_sessionJoin() lastSFD:%p\n", lastSFD );

//    int rc = 0;

//    void* out = 0;
//    rc = zhash_foreach ( cc->kvmap, collabclient_sessionJoin_findSFD_foreach_fn, &out );
    
//    printf("collabclient_sessionJoin() last sfd:%p\n", out );

    if( !lastSFD )
    {
	gwwv_post_error(_("FontForge Collaboration"), _("No Font Snapshot received from the server"));
	return 0;
    }
    
    if( lastSFD )
    {
	int openflags = 0;
	char filename[PATH_MAX];
	snprintf(filename, PATH_MAX, "%s/fontforge-collab-import-%d.sfd",getTempDir(),getpid());
	GFileWriteAll( filename, kvmsg_body (lastSFD) );

	/*
	 * Since we are creating a new fontview window for the collab session
	 * we "hand over" the collabClient from the current fontview used to join
	 * the session to the fontview which owns the sfd from the wire.
	 */ 
	FontViewBase* newfv = ViewPostScriptFont( filename, openflags );
	newfv->collabClient = cc;
	fv->b.collabClient = 0;
	newfv->collabState = cs_client;
	FVTitleUpdate( newfv );
	collabclient_notifySessionJoining( cc, newfv );

	ret = newfv;
	/* cloneclient_t* newc = collabclient_new( cc->address, cc->port ); */
	/* collabclient_sessionJoin( newc, fv ); */
    }

    
    printf("applying updates from server that were performed after the SFD snapshot was done...\n");
    
    kvmap_visit( cc->kvmap, kvmsg_sequence (lastSFD),
		 collabclient_sessionJoin_processmsg_foreach_fn, cc );

    /* struct collabclient_sessionJoin_processUpdates_foreach_args args; */
    /* args.cc = cc; */
    /* args.lastSFD = lastSFD; */
    /* rc = zhash_foreach ( cc->kvmap, collabclient_sessionJoin_processUpdates_foreach_fn, &args ); */
    
    

    printf("collabclient_sessionJoin(complete)\n");

#endif
    return ret;
}
Esempio n. 4
0
void collabclient_sessionStart( void* ccvp, FontView *fv )
{
#ifdef BUILD_COLLAB

    cloneclient_t* cc = (cloneclient_t*)ccvp;
    
    //
    // Fire up the fontforge-internal-collab-server process...
    //
    {
	char command_line[PATH_MAX+1];
	
#if defined(__MINGW32__)

	sprintf(command_line, "'%s/ffcollab.bat' %d", getGResourceProgramDir(), cc->port );
	
#else	
	sprintf(command_line,
		"%s/bin/FontForgeInternal/fontforge-internal-collab-server %d",
		getLibexecDir_NonWindows(), cc->port );
#endif	
	printf("command_line:%s\n", command_line );
	GError * error = 0;
	if(!getenv("FONTFORGE_USE_EXISTING_SERVER"))
	{
	    int rc = g_spawn_command_line_async( command_line, &error );
	    if( !rc )
	    {
		fprintf(stderr, "Error starting collab server\n");
		if( error )
		    fprintf(stderr, "code:%d message:%s\n", error->code, error->message );
	    }
	}
    }
    
    printf("Starting a session, sending it the current SFD as a baseline...\n");
    if( !ff_uuid_isValid( fv->b.sf->collab_uuid))
	ff_uuid_generate( fv->b.sf->collab_uuid );
    strcpy( cc->unacknowledged_beacon_uuid, fv->b.sf->collab_uuid );
    time( &cc->unacknowledged_beacon_sendTime );

    
    int s2d = 0;
    char filename[PATH_MAX];
    snprintf(filename, PATH_MAX, "%s/fontforge-collab-start-%d.sfd", getTempDir(), getpid());
    int ok = SFDWrite(filename,fv->b.sf,fv->b.map,fv->b.normal,s2d);
    printf("connecting to server...3 ok:%d\n",ok);
    if ( ok )
    {
	char* sfd = GFileReadAll( filename );
	printf("connecting to server...4 sfd:%p\n", sfd );
	collabclient_sendSFD( cc, sfd, fv->b.sf->collab_uuid, fv->b.sf->fontname );
    }
    GFileUnlink(filename);
    printf("connecting to server...sent the sfd for session start.\n");
    fv->b.collabState = cs_server;
    FVTitleUpdate( &fv->b );

    collabclient_setHaveLocalServer( 1 );

    beacon_moon_bounce_timerID = BackgroundTimer_new( 3000, beacon_moon_bounce_timer_callback, cc );

    collabclient_notifySessionJoining( cc, (FontViewBase*)fv );
#endif
}