Fixed all gcc 4 warnings in blenkernel. Found 2 potentially harmful
[blender.git] / source / blender / blenkernel / intern / verse_node.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
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_listBase.h"
35 #include "DNA_userdef_types.h"
36
37 #include "BLI_dynamiclist.h"
38 #include "BLI_blenlib.h"
39
40 #include "BIF_verse.h"
41
42 #include "BKE_verse.h"
43
44 #include "verse.h"
45
46 /* function prototypes of static functions */
47         /* for tags */
48 static void free_verse_tag_data(struct VTag *vtag);
49 static struct VTag *find_tag_in_queue(struct VTagGroup *vtaggroup, const char *name);
50 static struct VTag *create_verse_tag(struct VTagGroup *vtaggroup, uint16 tag_id, const char *name, VNTagType type, const VNTag *tag);
51         /* for verse tag groups */
52 static void free_verse_taggroup_data(struct VTagGroup *taggroup);
53 static struct VTagGroup *find_taggroup_in_queue(struct VNode *vnode, const char *name);
54 static struct VTagGroup *create_verse_taggroup(VNode *vnode, uint16 group_id, const char *name);
55         /* for verse nodes */
56 static void move_verse_node_to_dlist(struct VerseSession *session, VNodeID vnode_id);
57         /* function prototypes of node callback functions */
58 static void cb_tag_destroy(void *user_data, VNodeID node_id, uint16 group_id, uint16 tag_id);
59 static void cb_tag_create(void *user_data, VNodeID node_id, uint16 group_id, uint16 tag_id, const char *name, VNTagType type, const VNTag *tag);
60 static void cb_tag_group_destroy(void *user_data, VNodeID node_id, uint16 group_id);
61 static void cb_tag_group_create(void *user_data, VNodeID node_id, uint16 group_id, const char *name);
62 static void cb_node_name_set(void *user_data, VNodeID node_id, const char *name);
63 static void cb_node_destroy(void *user_data, VNodeID node_id);
64 static void cb_node_create(void *user_data, VNodeID node_id, uint8 type, VNodeID owner_id);
65
66 /*
67  * send new tag to verse server 
68  */
69 void send_verse_tag(VTag *vtag)
70 {
71         verse_send_tag_create(vtag->vtaggroup->vnode->id,
72                         vtag->vtaggroup->id,
73                         vtag->id,
74                         vtag->name,
75                         vtag->type,
76                         vtag->tag);
77 }
78
79 /*
80  * free tag data
81  */
82 static void free_verse_tag_data(VTag *vtag)
83 {
84         /* free name of verse tag */
85         MEM_freeN(vtag->name);
86         /* free value of tag */
87         MEM_freeN(vtag->tag);
88 }
89
90 /*
91  * try to find tag in sending queue ... if tag will be found, then
92  * this function will removed tag from queue and will return pointer
93  * at this tag
94  */
95 static VTag *find_tag_in_queue(VTagGroup *vtaggroup, const char *name)
96 {
97         struct VTag *vtag;
98
99         vtag = vtaggroup->queue.first;
100
101         while(vtag) {
102                 if(strcmp(vtag->name, name)==0) {
103                         BLI_remlink(&(vtaggroup->queue), vtag);
104                         break;
105                 }
106                 vtag = vtag->next;
107         }
108
109         return vtag;
110 }
111
112 /*
113  * create new verse tag
114  */
115 static VTag *create_verse_tag(
116                 VTagGroup *vtaggroup,
117                 uint16 tag_id,
118                 const char *name,
119                 VNTagType type,
120                 const VNTag *tag)
121 {
122         struct VTag *vtag;
123
124         vtag = (VTag*)MEM_mallocN(sizeof(VTag), "VTag");
125
126         vtag->vtaggroup = vtaggroup;
127         vtag->id = tag_id;
128         vtag->name = (char*)MEM_mallocN(sizeof(char)*(strlen(name)+1), "VTag name");
129         strcpy(vtag->name, name);
130         vtag->type = type;
131
132         vtag->tag = (VNTag*)MEM_mallocN(sizeof(VNTag), "VNTag");
133         *vtag->tag = *tag;
134
135         vtag->value = NULL;
136
137         return vtag;
138 }
139
140 /*
141  * send taggroup to verse server
142  */
143 void send_verse_taggroup(VTagGroup *vtaggroup)
144 {
145         verse_send_tag_group_create(
146                         vtaggroup->vnode->id,
147                         vtaggroup->id,
148                         vtaggroup->name);
149 }
150
151 /*
152  * free taggroup data
153  */
154 static void free_verse_taggroup_data(VTagGroup *taggroup)
155 {
156         struct VerseSession *session = taggroup->vnode->session;
157         struct VTag *vtag;
158
159         vtag = taggroup->tags.lb.first;
160
161         while(vtag) {
162                 free_verse_tag_data(vtag);
163                 vtag = vtag->next;
164         }
165
166         /* unsubscribe from taggroup */
167         if(session->flag & VERSE_CONNECTED)
168                 verse_send_tag_group_unsubscribe(taggroup->vnode->id, taggroup->id);
169         
170         BLI_dlist_destroy(&(taggroup->tags));
171         MEM_freeN(taggroup->name);
172 }
173
174 /*
175  * move taggroup from queue to dynamic list with access array,
176  * set up taggroup id and return pointer at this taggroup
177  */
178 static VTagGroup *find_taggroup_in_queue(VNode *vnode, const char *name)
179 {
180         struct VTagGroup *vtaggroup;
181
182         vtaggroup = vnode->queue.first;
183
184         while(vtaggroup) {
185                 if(strcmp(vtaggroup->name, name)==0) {
186                         BLI_remlink(&(vnode->queue), vtaggroup);
187                         break;
188                 }
189                 vtaggroup = vtaggroup->next;
190         }
191
192         return vtaggroup;
193 }
194
195 /*
196  * create new verse group of tags
197  */
198 static VTagGroup *create_verse_taggroup(VNode *vnode, uint16 group_id, const char *name)
199 {
200         struct VTagGroup *taggroup;
201
202         taggroup = (VTagGroup*)MEM_mallocN(sizeof(VTagGroup), "VTagGroup");
203
204         taggroup->vnode = vnode;
205         taggroup->id = group_id;
206         taggroup->name = (char*)MEM_mallocN(sizeof(char)*(strlen(name)+1), "VTagGroup name");
207         strcpy(taggroup->name, name);
208
209         BLI_dlist_init(&(taggroup->tags));
210         taggroup->queue.first = taggroup->queue.last = NULL;
211
212         taggroup->post_tag_change = post_tag_change;
213         taggroup->post_taggroup_create = post_taggroup_create;
214
215         return taggroup;
216 }
217
218 /*
219  * move first VerseNode waiting in sending queue to dynamic list of VerseNodes
220  * (it usually happens, when "our" VerseNode was received from verse server)
221  */
222 static void move_verse_node_to_dlist(VerseSession *session, VNodeID vnode_id)
223 {
224         VNode *vnode;
225
226         vnode = session->queue.first;
227
228         if(vnode) {
229                 BLI_remlink(&(session->queue), vnode);
230                 BLI_dlist_add_item_index(&(session->nodes), (void*)vnode, vnode_id);
231         }
232 }
233
234 /*
235  * send VerseNode to verse server
236  */
237 void send_verse_node(VNode *vnode)
238 {
239         verse_send_node_create(
240                         vnode->id,
241                         vnode->type,
242                         vnode->session->avatar);
243 }
244
245 /*
246  * free Verse Node data
247  */
248 void free_verse_node_data(VNode *vnode)
249 {
250         struct VerseSession *session = vnode->session;
251         struct VTagGroup *vtaggroup;
252
253         /* free node data (object, geometry, etc.) */
254         switch(vnode->type){
255                 case V_NT_OBJECT:
256                         free_object_data(vnode);
257                         break;
258                 case V_NT_GEOMETRY:
259                         free_geom_data(vnode);
260                         break;
261                 case V_NT_BITMAP:
262                         free_bitmap_node_data(vnode);
263                         break;
264                 default:
265                         break;
266         }
267
268         /* free all tag groups in dynamic list with access array */
269         vtaggroup = vnode->taggroups.lb.first;
270         while(vtaggroup) {
271                 free_verse_taggroup_data(vtaggroup);
272                 vtaggroup = vtaggroup->next;
273         }
274         BLI_dlist_destroy(&(vnode->taggroups));
275
276         /* free all tag groups still waiting in queue */
277         vtaggroup = vnode->queue.first;
278         while(vtaggroup) {
279                 free_verse_taggroup_data(vtaggroup);
280                 vtaggroup = vtaggroup->next;
281         }
282         BLI_freelistN(&(vnode->queue));
283
284         /* unsubscribe from node */
285         if(session->flag & VERSE_CONNECTED)
286                 verse_send_node_unsubscribe(vnode->id);
287         
288         /* free node name */
289         MEM_freeN(vnode->name);
290         vnode->name = NULL;
291
292         /* free node data */
293         MEM_freeN(vnode->data);
294         vnode->data = NULL;
295         
296 }
297
298 /*
299  * free VerseNode
300  */
301 void free_verse_node(VNode *vnode)
302 {
303         free_verse_node_data(vnode);
304
305         BLI_dlist_free_item(&(vnode->session->nodes), vnode->id);
306 }
307
308 /*
309  * create new Verse Node
310  */
311 VNode* create_verse_node(VerseSession *session, VNodeID node_id, uint8 type, VNodeID owner_id)
312 {
313         struct VNode *vnode;
314
315         vnode = (VNode*)MEM_mallocN(sizeof(VNode), "VerseNode");
316
317         vnode->session = session;
318         vnode->id = node_id;
319         vnode->owner_id = owner_id;
320         vnode->name = NULL;
321         vnode->type = type;
322
323         BLI_dlist_init(&(vnode->taggroups));
324         vnode->queue.first = vnode->queue.last = NULL;
325
326         vnode->data = NULL;
327
328         vnode->counter = 0;
329
330         vnode->flag = 0;
331
332         vnode->post_node_create = post_node_create;
333         vnode->post_node_destroy = post_node_destroy;
334         vnode->post_node_name_set = post_node_name_set;
335
336         return vnode;
337 }
338
339 /*
340  * callback function: tag was destroyed
341  */
342 static void cb_tag_destroy(
343                 void *user_data,
344                 VNodeID node_id,
345                 uint16 group_id,
346                 uint16 tag_id)
347 {
348         struct VerseSession *session = (VerseSession*)current_verse_session();
349         struct VNode *vnode;
350         struct VTagGroup *vtaggroup;
351         struct VTag *vtag;
352
353         if(!session) return;
354
355         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
356         if(!vnode) return;
357
358         /* try to find tag group in list of tag groups */
359         vtaggroup = BLI_dlist_find_link(&(vnode->taggroups), group_id);
360
361         if(!vtaggroup) return;
362
363         /* try to find verse tag in dynamic list of tags in tag group */
364         vtag = (VTag*)BLI_dlist_find_link(&(vtaggroup->tags), tag_id);
365
366         if(vtag) {
367                 free_verse_tag_data(vtag);
368                 BLI_dlist_free_item(&(vtaggroup->tags), vtag->id);
369         }
370 }
371
372 /*
373  * callback function: new tag was created
374  */
375 static void cb_tag_create(
376                 void *user_data,
377                 VNodeID node_id,
378                 uint16 group_id,
379                 uint16 tag_id,
380                 const char *name,
381                 VNTagType type,
382                 const VNTag *tag)
383 {
384         struct VerseSession *session = (VerseSession*)current_verse_session();
385         struct VNode *vnode;
386         struct VTagGroup *vtaggroup;
387         struct VTag *vtag;
388
389         if(!session) return;
390
391         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
392         if(!vnode) return;
393
394         /* try to find tag group in list of tag groups */
395         vtaggroup = BLI_dlist_find_link(&(vnode->taggroups), group_id);
396
397         if(!vtaggroup) return;
398
399         /* try to find verse tag in dynamic list of tags in tag group */
400         vtag = (VTag*)BLI_dlist_find_link(&(vtaggroup->tags), tag_id);
401
402         if(!vtag) {
403                 /* we will try to find vtag in sending queue */
404                 vtag = find_tag_in_queue(vtaggroup, name);
405
406                 /* when we didn't create this tag, then we will have to create one */
407                 if(!vtag) vtag = create_verse_tag(vtaggroup, tag_id, name, type, tag);
408                 else vtag->id = tag_id;
409
410                 /* add tag to the list of tags in tag group */
411                 BLI_dlist_add_item_index(&(vtaggroup->tags), vtag, tag_id);
412
413                 /* post change/create method */
414                 vtaggroup->post_tag_change(vtag);
415         }
416         else {
417                 /* this tag exists, then we will propably change value of this tag */
418                 if((vtag->type != type) || (strcmp(vtag->name, name)!=0)) {
419                         /* changes of type or name are not allowed and such
420                          * stupid changes will be returned back */
421                         send_verse_tag(vtag);
422                 }
423                 else {
424                         /* post change/create method */
425                         vtaggroup->post_tag_change(vtag);
426                 }
427         }
428 }
429
430 /*
431  * callback function: tag group was destroyed
432  */
433 static void cb_tag_group_destroy(
434                 void *user_data,
435                 VNodeID node_id,
436                 uint16 group_id)
437 {
438         struct VerseSession *session = (VerseSession*)current_verse_session();
439         struct VNode *vnode;
440         struct VTagGroup *vtaggroup;
441
442         if(!session) return;
443
444         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
445         if(!vnode) return;
446
447         vtaggroup = BLI_dlist_find_link(&(vnode->taggroups), group_id);
448
449         if(vtaggroup) {
450                 free_verse_taggroup_data(vtaggroup);
451                 BLI_dlist_free_item(&(vnode->taggroups), vtaggroup->id);
452         }
453 }
454
455 /*
456  * callback function: new tag group was created
457  */
458 static void cb_tag_group_create(
459                 void *user_data,
460                 VNodeID node_id,
461                 uint16 group_id,
462                 const char *name)
463 {
464         struct VerseSession *session = (VerseSession*)current_verse_session();
465         struct VNode *vnode;
466         struct VTagGroup *vtaggroup;
467
468         if(!session) return;
469
470         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
471         if(!vnode) return;
472
473         /* name of taggroup has to begin with string "blender:" */
474         if(strncmp("blender:", name, 8)) return;
475
476         /* try to find tag group in list of tag groups */
477         vtaggroup = BLI_dlist_find_link(&(vnode->taggroups), group_id);
478
479         if(!vtaggroup) {
480                 /* subscribe to tag group (when new tag will be created, then blender will
481                  * receive command about it) */
482                 verse_send_tag_group_subscribe(vnode->id, group_id);
483                 verse_callback_update(0);
484
485                 /* try to find taggroup in waiting queue */
486                 vtaggroup = find_taggroup_in_queue(vnode, name);
487
488                 /* if no taggroup exist, then new has to be created */
489                 if(!vtaggroup) vtaggroup = create_verse_taggroup(vnode, group_id, name);
490                 else vtaggroup->id = group_id;
491
492                 /* add tag group to dynamic list with access array */
493                 BLI_dlist_add_item_index(&(vnode->taggroups), (void*)vtaggroup, (unsigned int)group_id);
494
495                 /* post create method */
496                 vtaggroup->post_taggroup_create(vtaggroup);
497         }
498         else {
499                 /* this taggroup exist and somebody try to change its name */
500                 if(strcmp(vtaggroup->name, name)!=0) {
501                         /* blender doesn't allow such stupid and dangerous things */
502                         send_verse_taggroup(vtaggroup);
503                 }
504         }
505 }
506
507 /*
508  * callback function: change name of node
509  */
510 static void cb_node_name_set(
511                 void *user_data,
512                 VNodeID node_id,
513                 const char *name)
514 {
515         struct VerseSession *session = (VerseSession*)current_verse_session();
516         struct VNode *vnode;
517
518         if(!session) return;
519
520         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
521         if(vnode && name) {
522                 if(!vnode->name) {
523                         vnode->name = (char*)MEM_mallocN(sizeof(char)*(strlen(name)+1), "VerseNode name");
524                 }
525                 else if(strlen(name) > strlen(vnode->name)) {
526                         MEM_freeN(vnode->name);
527                         vnode->name = (char*)MEM_mallocN(sizeof(char)*(strlen(name)+1), "VerseNode name");
528                 }
529                 strcpy(vnode->name, name);
530
531                 vnode->post_node_name_set(vnode);
532         }
533 }
534
535 /*
536  * callback function for deleting node
537  */
538 static void cb_node_destroy(
539                 void *user_data,
540                 VNodeID node_id)
541 {
542         struct VerseSession *session = (VerseSession*)current_verse_session();
543         struct VNode *vnode;
544
545         if(!session) return;
546
547         vnode = BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
548
549         if(vnode) {
550                 /* remove VerseNode from dynamic list */
551                 BLI_dlist_rem_item(&(session->nodes), (unsigned int)node_id);
552                 /* do post destroy operations */
553                 vnode->post_node_destroy(vnode);
554                 /* free verse data */
555                 free_verse_node_data(vnode);
556                 /* free VerseNode */
557                 MEM_freeN(vnode);
558         };
559 }
560
561
562 /*
563  * callback function for new created node
564  */
565 static void cb_node_create(
566                 void *user_data,
567                 VNodeID node_id,
568                 uint8 type,
569                 VNodeID owner_id)
570 {
571         struct VerseSession *session = (VerseSession*)current_verse_session();
572         struct VNode *vnode;
573         
574         if(!session) return;
575
576         /* subscribe to node */
577         if((type==V_NT_OBJECT) || (type==V_NT_GEOMETRY) || (type==V_NT_BITMAP))
578                 verse_send_node_subscribe(node_id);
579         else
580                 return;
581
582         switch(type){
583                 case V_NT_OBJECT :
584                         if(owner_id==VN_OWNER_MINE) {
585                                 struct VLink *vlink;
586                                 /* collect VerseNode from VerseNode queue */
587                                 move_verse_node_to_dlist(session, node_id);
588                                 /* send next VerseNode waiting in queue */
589                                 if(session->queue.first) send_verse_node(session->queue.first);
590                                 /* get received VerseNode from list of VerseNodes */
591                                 vnode = BLI_dlist_find_link(&(session->nodes), node_id);
592                                 /* set up ID */
593                                 vnode->id = node_id;
594                                 /* set up flags */
595                                 vnode->flag |= NODE_RECEIVED;
596                                 /* find unsent link pointing at this VerseNode */
597                                 vlink = find_unsent_child_vlink(session, vnode);
598                                 /* send VerseLink */
599                                 if(vlink) send_verse_link(vlink);
600                                 /* send name of object node */
601                                 verse_send_node_name_set(node_id, vnode->name);
602                                 /* subscribe to changes of object node transformations */
603                                 verse_send_o_transform_subscribe(node_id, 0);
604                                 /* send object transformation matrix */
605                                 send_verse_object_position(vnode);
606                                 send_verse_object_rotation(vnode);
607                                 send_verse_object_scale(vnode);
608                         }
609                         else {
610                                 /* create new VerseNode */
611                                 vnode = create_verse_node(session, node_id, type, owner_id);
612                                 /* add VerseNode to list of nodes */
613                                 BLI_dlist_add_item_index(&(session->nodes), (void*)vnode, (unsigned int)node_id);
614                                 /* set up flags */
615                                 vnode->flag |= NODE_RECEIVED;
616                                 /* create object data */
617                                 vnode->data = create_object_data();
618                                 /* set up avatar's name */
619                                 if(node_id == session->avatar) {
620                                         verse_send_node_name_set(node_id, U.verseuser);
621                                 }
622                                 else if(session->flag & VERSE_AUTOSUBSCRIBE) {
623                                         /* subscribe to changes of object node transformations */
624                                         verse_send_o_transform_subscribe(node_id, 0);
625                                 }
626                         }
627                         break;
628                 case V_NT_GEOMETRY :
629                         if(owner_id==VN_OWNER_MINE){
630                                 struct VLink *vlink;
631                                 struct VLayer *vlayer;
632                                 /* collect VerseNode from VerseNode queue */
633                                 move_verse_node_to_dlist(session, node_id);
634                                 /* send next VerseNode waiting in queue */
635                                 if(session->queue.first) send_verse_node(session->queue.first);
636                                 /* get received VerseNode from list of VerseNodes */
637                                 vnode = BLI_dlist_find_link(&(session->nodes), node_id);
638                                 /* set up ID */
639                                 vnode->id = node_id;
640                                 /* set up flags */
641                                 vnode->flag |= NODE_RECEIVED;
642                                 /* find unsent link pointing at this VerseNode */
643                                 vlink = find_unsent_parent_vlink(session, vnode);
644                                 /* send VerseLink */
645                                 if(vlink) send_verse_link(vlink);
646                                 /* send name of geometry node */
647                                 verse_send_node_name_set(node_id, vnode->name);
648                                 /* send all not sent layer to verse server */
649                                 vlayer = (VLayer*)((VGeomData*)vnode->data)->queue.first;
650                                 if(vlayer) {
651                                         while(vlayer) {
652                                                 send_verse_layer(vlayer);
653                                                 vlayer = vlayer->next;
654                                         }
655                                 }
656                                 else {
657                                         /* send two verse layers to verse server */
658 /*                                      verse_send_g_layer_create(node_id, 0, "vertex", VN_G_LAYER_VERTEX_XYZ, 0, 0);
659                                         verse_send_g_layer_create(node_id, 1, "polygon", VN_G_LAYER_POLYGON_CORNER_UINT32, 0, 0);*/
660                                 }
661                         }
662                         else {
663                                 /* create new VerseNode*/
664                                 vnode = create_verse_node(session, node_id, type, owner_id);
665                                 /* add VerseNode to dlist of nodes */
666                                 BLI_dlist_add_item_index(&(session->nodes), (void*)vnode, (unsigned int)node_id);
667                                 /* set up flags */
668                                 vnode->flag |= NODE_RECEIVED;
669                                 /* create geometry data */
670                                 vnode->data = (void*)create_geometry_data();
671                         }
672                         break;
673                 case V_NT_BITMAP :
674                         if(owner_id==VN_OWNER_MINE) {
675                                 /* collect VerseNode from VerseNode queue */
676                                 move_verse_node_to_dlist(session, node_id);
677                                 /* send next VerseNode waiting in queue */
678                                 if(session->queue.first) send_verse_node(session->queue.first);
679                                 /* get received VerseNode from list of VerseNodes */
680                                 vnode = BLI_dlist_find_link(&(session->nodes), node_id);
681                                 /* set up ID */
682                                 vnode->id = node_id;
683                                 /* set up flags */
684                                 vnode->flag |= NODE_RECEIVED;
685                                 /* send name of object node */
686                                 verse_send_node_name_set(node_id, vnode->name);
687                                 /* send dimension of image to verse server */
688                                 verse_send_b_dimensions_set(node_id,
689                                                 ((VBitmapData*)vnode->data)->width,
690                                                 ((VBitmapData*)vnode->data)->height,
691                                                 ((VBitmapData*)vnode->data)->depth);
692                         }
693                         else {
694                                 /* create new VerseNode*/
695                                 vnode = create_verse_node(session, node_id, type, owner_id);
696                                 /* add VerseNode to dlist of nodes */
697                                 BLI_dlist_add_item_index(&(session->nodes), (void*)vnode, (unsigned int)node_id);
698                                 /* set up flags */
699                                 vnode->flag |= NODE_RECEIVED;
700                                 /* create bitmap data */
701                                 vnode->data = (void*)create_bitmap_data();
702                         }
703                 default:
704                         vnode = NULL;
705                         break;
706         }
707
708         vnode->post_node_create(vnode);
709 }
710
711 /*
712  * set up all callbacks for verse nodes
713  */
714 void set_node_callbacks(void)
715 {
716         /* new node created */
717         verse_callback_set(verse_send_node_create, cb_node_create, NULL);
718         /* node was deleted */
719         verse_callback_set(verse_send_node_destroy, cb_node_destroy, NULL);
720         /* name of node was set */
721         verse_callback_set(verse_send_node_name_set, cb_node_name_set, NULL);
722
723         /* new tag group was created */
724         verse_callback_set(verse_send_tag_group_create, cb_tag_group_create, NULL);
725         /* tag group was destroy */
726         verse_callback_set(verse_send_tag_group_destroy, cb_tag_group_destroy, NULL);
727
728         /* new tag was created */
729         verse_callback_set(verse_send_tag_create, cb_tag_create, NULL);
730         /* tag was destroy */
731         verse_callback_set(verse_send_tag_destroy, cb_tag_destroy, NULL);
732 }
733
734 #endif