Example #1
0
static void* pyFF_maybeCallCVPreserveState( PyFF_Glyph *self )
{
    if( !inPythonStartedCollabSession )
	return 0;
#ifndef BUILD_COLLAB
    return 0;
#else
    
    CharView* cv = 0;
    static GHashTable* ht = 0;
    if( !ht )
    {
	ht = g_hash_table_new( g_direct_hash, g_direct_equal );
    }
    fprintf(stderr,"hash size:%d\n", g_hash_table_size(ht));

    gpointer cache = g_hash_table_lookup( ht, self->sc );
    if( cache )
    {
	return cache;
    }
    
    SplineFont *sf = self->sc->parent;
    FontView* fv = (FontView*)FontViewFind( FontViewFind_bySplineFont, sf );
    if( !fv )
    {
	fprintf(stderr,"Collab error: can not find fontview for the SplineFont of the active char\n");
    }
    else
    {
	int old_no_windowing_ui = no_windowing_ui;
	no_windowing_ui = 0;

	// FIXME: need to find the existing cv if available!
	cv = CharViewCreate( self->sc, fv, -1 );
	g_hash_table_insert( ht, self->sc, cv );
        fprintf(stderr,"added... hash size:%d\n", g_hash_table_size(ht));
	CVPreserveState( &cv->b );
	collabclient_CVPreserveStateCalled( &cv->b );
	    
	no_windowing_ui = old_no_windowing_ui;
	printf("called CVPreserveState()\n");
    }

    return cv;
#endif
}
Example #2
0
void collabclient_free( void** ccvp )
{
#ifdef BUILD_COLLAB
    
    cloneclient_t* cc = (cloneclient_t*)*ccvp;
    if( !cc )
	return;
    if( cc->magic_number != MAGIC_VALUE )
    {
	fprintf(stderr,"collabclient_free() called on an invalid client object!\n");
	return;
    }
    cc->magic_number = MAGIC_VALUE + 1;

    {
	int fd = 0;
	size_t fdsz = sizeof(fd);
	int rc = zmq_getsockopt( cc->subscriber, ZMQ_FD, &fd, &fdsz );
	GDrawRemoveReadFD( 0, fd, cc );
    }
    
    
    zsocket_destroy( cc->ctx, cc->snapshot   );
    zsocket_destroy( cc->ctx, cc->subscriber );
    zsocket_destroy( cc->ctx, cc->publisher  );
    BackgroundTimer_remove( cc->roundTripTimer );

    FontView* fv = FontViewFind( FontViewFind_byCollabPtr, cc );
    if( fv )
    {
	fv->b.collabClient = 0;
    }

    zhash_destroy (&cc->kvmap);
    free(cc->address);
    free(cc);
    *ccvp = 0;

#endif
}
Example #3
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 );
    }
}
Example #4
0
/**
 * Process the given kvmsg from the server. If create is set and we do
 * not have any charview for a changed glyph then we first create a
 * charview for it. This allows the updates from a server to be
 * processed at startup time, getting us up to speed with any glyphs
 * that have changed.
 *
 * This function is mainly called in response to an update which is
 * published from the server. However, in sessionJoin() we also call
 * here to handle the incremental updates to glyphs that have occurred
 * after the SFD was sent to the server.
 */
static void zeromq_subscriber_process_update( cloneclient_t* cc, kvmsg_t *kvmsg, int create )
{
    cc->sequence = kvmsg_sequence (kvmsg);
    if( cc->sequence >= cc->roundTripTimerWaitingSeq )
	cc->roundTripTimerWaitingSeq = 0;
		    

    char* uuid = kvmsg_get_prop (kvmsg, "uuid" );
    byte* data = kvmsg_body (kvmsg);
    size_t data_size = kvmsg_size (kvmsg);

    printf("cc process_update() uuid:%s\n", uuid );
    FontView* fv = FontViewFind( FontViewFind_byXUIDConnected, uuid );
    printf("fv:%p\n", fv );
    if( fv )
    {
	if( !data_size )
	{
	    printf("WARNING: zero length message!\n" );
	    return;
	}
			
	SplineFont *sf = fv->b.sf;
	if( !sf )
	{
	    printf("ERROR: font view does not have the splinefont set!\n" );
	    return;
	}
	
	char* pos  = kvmsg_get_prop (kvmsg, "pos" );
	char* name = kvmsg_get_prop (kvmsg, "name" );
	printf("pos:%s\n", pos );
//	SplineChar *sc = sf->glyphs[ atoi(pos) ];
	SplineChar* sc = SFGetOrMakeChar( sf, -1, name );
	
	printf("sc:%p\n", sc );
	if( !sc )
	{
	    printf("WARNING: font view does not have a glyph for pos:%s\n",  pos );
	    printf("WARNING: font view does not have a glyph for name:%s\n", name );
	    return;
	}
	
	printf("sc.name:%s\n", sc->name );
	printf("data.size:%ld\n", data_size );
	if( DEBUG_SHOW_SFD_CHUNKS )
	    printf("data:%s\n", data );
		    
	int current_layer = 0;

	if( !sc->views && create )
	{
	    int show = 0;
	    CharView* cv = CharViewCreateExtended( sc, fv, -1, show );
	    printf("created charview:%p\n", cv );
	}
	
	for( CharViewBase* cv = sc->views; cv; cv = cv->next )
	{
	    printf("have charview:%p\n", cv );
	    
	    char filename[PATH_MAX];
	    snprintf(filename, PATH_MAX, "%s/fontforge-collab-inx-%d.sfd", getTempDir(), getpid() );
	    GFileWriteAll( filename, (char*)data);
	    FILE* file = fopen( filename, "rb" );
	    Undoes* undo = SFDGetUndo( sf, file, sc,
				       "UndoOperation",
				       "EndUndoOperation",
				       current_layer );
	    fclose(file);
	    if( !undo )
	    {
		printf("***** ERROR ****** reading back undo instance!\n");
		printf("data: %s\n\n", data );
	    }
	    if( undo )
	    {
		// NOT HANDLED!
		if( undo->undotype == ut_statehint )
		{
		    printf("*** warning ut_statehint not handled\n");
		    break;
		}
		
		printf("________________________ READ undo.layer: %d  dm:%d layer_sz:%d\n",
		       undo->layer, cv->drawmode, cv->sc->layer_cnt );
		int selectedlayer = cv->drawmode;
		if( undo->layer != UNDO_LAYER_UNKNOWN )
		    selectedlayer = undo->layer;    

		// use oldlayer to store current setting and switch to the
		// selected layer for this block.
		int oldlayer = cv->drawmode;
		cv->drawmode = selectedlayer;
		undo->next = 0;
		undo->next = cv->layerheads[selectedlayer]->redoes;
		cv->layerheads[selectedlayer]->redoes = undo;
		CVDoRedo( cv );

		char* isLocalUndo = kvmsg_get_prop (kvmsg, "isLocalUndo" );
		if( isLocalUndo )
		{
		    if( isLocalUndo[0] == '1' )
		    {
			Undoes* undo = cv->layerheads[selectedlayer]->undoes;
			if( undo )
			{
			    cv->layerheads[selectedlayer]->undoes = undo->next;
			    undo->next = cv->layerheads[selectedlayer]->redoes;
			    cv->layerheads[selectedlayer]->redoes = undo;
			}
		    }
		}

		if( cv->drawmode != oldlayer )
		{
		    cv->drawmode = oldlayer;
		    CVCharChangedUpdate( cv );

		}
		
		
	    }
			    
	    break;
	}
    }
		    
    printf ("I: processed update=%d\n", (int) cc->sequence);
}