=== Custom Transform Orientation ===
[blender.git] / source / blender / src / verse_common.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * Contributor(s): Jiri Hnidek.
24  *
25  * ***** END GPL/BL DUAL LICENSE BLOCK *****
26  */
27
28 #ifdef WITH_VERSE
29
30 #include <string.h>
31 #include <stdlib.h>
32
33 #include "MEM_guardedalloc.h"
34
35 #include "mydevice.h"
36
37 #include "DNA_object_types.h"
38 #include "DNA_mesh_types.h"
39
40 #include "BKE_global.h"
41 #include "BKE_blender.h"
42
43 #include "BIF_verse.h"
44 #include "BIF_space.h"
45 #include "BIF_interface.h"
46
47 extern ListBase session_list;
48 extern ListBase server_list;
49
50 /*
51  * this function creates popup menu with all active VerseSessions
52  * it return pointer at selected VerseSession, if no VerseSession
53  * is selected, then NULL is returned
54  */
55 VerseSession *session_menu(void)
56 {
57         struct VerseSession *session;
58         char session_number[10];
59         short i=1, num=1;
60         char session_address_list[1024];        /* pupmenu business */
61
62         session_number[0] = '\0';
63         session_address_list[0] = '\0';
64
65         strcat(session_address_list, "Session list %t");
66
67         session = session_list.first;
68
69         while(session){
70                 strcat(session_address_list, "| ");
71                 strcat(session_address_list, session->address);
72                 strcat(session_address_list, " %x");
73                 sprintf(session_number, "%d", num);
74                 strcat(session_address_list, session_number);
75                 num++;
76                 session = session->next;
77         }
78
79         printf("session list: %s\n", session_address_list);
80         num = pupmenu(session_address_list);
81
82         if(num==-1) return NULL;
83
84         session = session_list.first;
85
86         while(session) {
87                 if(i==num) return session;
88                 i++;
89                 session = session->next;
90         }
91
92         return NULL;
93 }
94
95 /*
96  * returns name of verse client (it is used as avatar's name)
97  */
98 char *verse_client_name(void)
99 {
100         char *client_name;
101         char blender_version[5];
102         short name_lenght = 14;
103
104 #ifndef WIN32
105         char *hostname;
106         hostname = getenv("HOSTNAME");
107         if(hostname) name_lenght += strlen(hostname);
108 #endif
109
110         client_name = (char*)MEM_mallocN(sizeof(char)*name_lenght, "verse client name");
111         client_name[0] = '\0';
112
113         strcat(client_name, "blender_");
114         blender_version[0] = '\0';
115         sprintf(blender_version, "%d", BLENDER_VERSION);
116         strcat(client_name, blender_version);
117
118 #ifndef WIN32
119         /* add at the end of the client name hostname */
120         if(hostname) {
121                 strcat(client_name, ":");
122                 strcat(client_name, hostname);
123         }
124 #endif
125
126         return client_name;
127 }
128
129 /*===========================================================
130  *
131  *   functions executed after calling callback functions
132  *
133  ============================================================*/
134
135 /*
136  * this function is called, when some tag was changed or new tag was created
137  */
138 void post_tag_change(VTag *vtag)
139 {
140         printf("\tnew tag %s was created or changed\n", vtag->name);
141 }
142
143 /*
144  * this function is called, when verse taggroup was created
145  */
146 void post_taggroup_create(VTagGroup *vtaggroup)
147 {
148         printf("\tnew taggroup %s was created\n", vtaggroup->name);
149 }
150
151 /*
152  * this function is called after creating of new VerseNode
153  */
154 void post_node_create(VNode *vnode)
155 {
156         struct VerseSession *session = vnode->session;
157
158         if((session->flag & VERSE_AUTOSUBSCRIBE) && (vnode->owner_id != VN_OWNER_MINE)) {
159                 if(vnode->type == V_NT_OBJECT) {
160                         create_object_from_verse_node(vnode);
161                 }
162                 else if(vnode->type == V_NT_GEOMETRY) {
163                         create_mesh_from_geom_node(vnode);;
164                 }
165         }
166
167         allqueue(REDRAWOOPS, 0);
168 }
169
170 /*
171  * this function is called after destroying of VerseNode
172  */
173 void post_node_destroy(VNode *vnode)
174 {
175         allqueue(REDRAWOOPS, 0);
176
177         /* TODO: destroy bindings between vnode and blender data structures */
178 }
179
180 /*
181  * this function is calles after renaming of VerseNode by verse_server
182  */
183 void post_node_name_set(VNode *vnode)
184 {
185         /* if VerseNode has coresponding blender data structure, then
186          * change ID name of data structure */
187         if(vnode->type==V_NT_OBJECT) {
188                 struct Object *ob;
189                 ob = (Object*)((VObjectData*)vnode->data)->object;
190                 if(ob) {
191                         char *str;
192                         str = (char*)malloc(sizeof(char)*(strlen(vnode->name)+3));
193                         str[0] = '\0';
194                         strcat(str, "OB");
195                         strcat(str, vnode->name);
196                         strncpy(ob->id.name, str, 23);
197                         printf("\tob->id.name: %s\n", ob->id.name);
198                         free(str);
199                 }
200         }
201         else if(vnode->type==V_NT_GEOMETRY) {
202                 struct Mesh *me;
203
204                 me = (Mesh*)((VGeomData*)vnode->data)->mesh;
205                 if(me) {
206                         char *str;
207                         str = (char*)malloc(sizeof(char)*(strlen(vnode->name)+3));
208                         str[0] = '\0';
209                         strcat(str, "ME");
210                         strcat(str, vnode->name);
211                         strncpy(me->id.name, str, 23);
212                         printf("\tme->id.name: %s\n", me->id.name);
213                         free(str);
214                 }
215         }
216
217         allqueue(REDRAWALL, 0);
218 }
219
220 /*
221  * this function is called after acception connection with verse server
222  */
223 void post_connect_accept(VerseSession *session)
224 {
225         VerseServer *server;
226         
227         G.f |= G_VERSE_CONNECTED;
228
229         session->counter = 0;
230
231         server = server_list.first;
232         while(server) {
233                 if(strcmp(server->ip, session->address)==0) {
234                         server->flag = session->flag;
235                         break;
236                 }
237                 server = server->next;
238         }
239
240         allqueue(REDRAWOOPS, 0);
241 }
242
243 void post_server_add(void)
244 {
245         allqueue(REDRAWOOPS, 0);
246 }
247
248 /*
249  * this function is called, when connestion with verse server is ended/terminated/etc.
250  */
251 void post_connect_terminated(VerseSession *session)
252 {
253         VerseServer *server;
254         server = server_list.first;
255         while(server) {
256                 if(strcmp(server->ip, session->address)==0) {
257                         server->flag = 0;
258                         server->session=NULL;
259                         break;
260                 }
261                 server = server->next;
262         }
263
264         /* if it is last session, then no other will exist ... set Global flag */
265         if((session->prev==NULL) && (session->next==NULL))
266                 G.f &= ~G_VERSE_CONNECTED;
267
268         allqueue(REDRAWOOPS, 0);
269 }
270
271 /*
272  * if connection wasn't accepted, then free VerseSession
273  * and print warning message with popupmenu
274  */
275 void post_connect_update(VerseSession *session)
276 {
277         if(session->flag & VERSE_CONNECTING) {
278                 session->counter++;
279                 if(session->counter > MAX_UNCONNECTED_EVENTS) {
280                         char *str;
281                         /* popup menu*/
282                         str = malloc(sizeof(char)*(strlen(session->address)+35));
283                         str[0]='\0';
284                         strcat(str, "Error%t|No response from server: ");
285                         strcat(str, session->address);
286                         pupmenu(str);
287                         free(str);
288
289                         session->flag = 0;
290                         session->counter = 0;
291                         session->post_connect_terminated(session);
292                         free_verse_session(session);
293                 }
294         }
295 }
296
297 #endif
298