singleinstance.c 3.58 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
linphone, gtk interface.
Copyright (C) 2011 Belledonne Communications SARL
Author: Simon MORLAT (simon.morlat@linphone.org)

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "linphone.h"

static ms_thread_t pipe_thread;
24
static ortp_pipe_t server_pipe=(ortp_pipe_t)-1;
25
static gboolean server_pipe_running=TRUE;
26 27 28 29 30 31 32 33 34
static char *pipe_name=NULL;

gchar *make_name(const char *appname){
	const char *username=getenv("USER");
	if (username){
		return g_strdup_printf("%s-%s",appname,username);
	}
	return g_strdup(appname);
}
35

Margaux Clerc's avatar
Margaux Clerc committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
static gboolean execute_wakeup(char *buf){
	char uri[255]={0};
	int option;

	if (strlen(buf)>1) sscanf(buf,"%i%s",&option,uri);
	else sscanf(buf,"%i",&option);

	switch(option){
		case START_LINPHONE:
			linphone_gtk_show_main_window();
			break;
		case START_AUDIO_ASSISTANT:
			linphone_gtk_show_audio_assistant();
			break;
		case START_LINPHONE_WITH_CALL:
			linphone_gtk_refer_received(linphone_gtk_get_core(),uri);
			break;
	};

	g_free(buf);
56 57 58 59 60
	return FALSE;
}

static void * server_pipe_thread(void *pointer){
	ortp_pipe_t child;
61

62 63
	do{
		child=ortp_server_pipe_accept_client(server_pipe);
64
		if (server_pipe_running && child!=(ortp_pipe_t)-1){
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
			char buf[256]={0};
			if (ortp_pipe_read(child,(uint8_t*)buf,sizeof(buf))>0){
				g_message("Received wakeup command with arg %s",buf);
				gdk_threads_enter();
				g_timeout_add(20,(GSourceFunc)execute_wakeup,g_strdup(buf));
				gdk_threads_leave();
			}
			ortp_server_pipe_close_client(child);
		}
	}while(server_pipe_running);
	ortp_server_pipe_close(server_pipe);
	return NULL;
}

static void linphone_gtk_init_pipe(const char *name){
	server_pipe=ortp_server_pipe_create(name);
81
	if (server_pipe==(ortp_pipe_t)-1){
82
		g_warning("Fail to create server pipe for name %s: %s",name,strerror(errno));
83
		return;
84
	}
85
	server_pipe_running=TRUE;
86 87 88
	ms_thread_create(&pipe_thread,NULL,server_pipe_thread,NULL);
}

Margaux Clerc's avatar
Margaux Clerc committed
89
bool_t linphone_gtk_init_instance(const char *app_name, int option, const char *addr_to_call){
90
	ortp_pipe_t p;
91
	pipe_name=make_name(app_name);
92
	p=ortp_client_pipe_connect(pipe_name);
93
	if (p!=(ortp_pipe_t)-1){
94 95 96
		uint8_t buf[256]={0};
		g_message("There is already a running instance.");
		if (addr_to_call!=NULL){
Margaux Clerc's avatar
Margaux Clerc committed
97 98 99
			sprintf((char *)buf,"%i%s",option,addr_to_call);
		} else {
			sprintf((char *)buf,"%i",option);
100 101 102 103 104 105 106 107 108
		}
		if (ortp_pipe_write(p,buf,sizeof(buf))==-1){
			g_error("Fail to send wakeup command to running instance: %s",strerror(errno));
		}else{
			g_message("Message to running instance sent.");
		}
		ortp_client_pipe_close(p);
		return FALSE;
	}else{
109
		linphone_gtk_init_pipe(pipe_name);
110 111 112 113 114
	}
	return TRUE;
}

void linphone_gtk_uninit_instance(void){
115
	if (server_pipe!=(ortp_pipe_t)-1){
116 117 118 119 120 121 122
		ortp_pipe_t client;
		server_pipe_running=FALSE;
		/*this is to unblock the accept() of the server pipe*/
		client=ortp_client_pipe_connect(pipe_name);
		ortp_pipe_write(client,(uint8_t*)" ",1);
		ortp_client_pipe_close(client);
		ms_thread_join(pipe_thread,NULL);
123
		server_pipe=(ortp_pipe_t)-1;
124 125 126 127
		g_free(pipe_name);
		pipe_name=NULL;
	}
}