4 * Copyright (C) 2004-2011 Simon Wunderlich <dotslash@packetmixer.de>
6 * This file is part of s3d, a 3d network display server.
7 * See http://s3d.berlios.de/ for more updates.
9 * s3d is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * s3d 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.
19 * You should have received a copy of the GNU General Public License
20 * along with s3d; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <stdlib.h> /* for malloc, free */
26 #include <string.h> /* strncmp(), strncpy() */
27 /* this piece of code handles processes */
29 #define mcp_p (&procs_p[0])
30 struct t_process
*procs_p
= NULL
; /* pointer to the processes */
31 int procs_n
; /* number of processes */
32 static int p_del(struct t_process
*p
); /* local prototype */
33 static int process_list_rm(int pid
);
34 static int process_sys_init(struct t_process
*p
);
36 /* protocol request for process initialization */
37 struct t_process
*process_protinit(struct t_process
*p
, const char *name
)
41 if ((strncmp(name
, "sys_", 4) == 0)) { /* we don't like "sys_"-apps, kicking this */
42 errds(VHIGH
, "process_protinit()", "appnames starting with 'sys_' not allowed.");
45 if ((p
->id
!= MCP
) && (strncmp(name
, "mcp", 3) == 0)) {
46 if (procs_p
[MCP
].con_type
== CON_NULL
) {
47 s3dprintf(MED
, "free mcp place, pid %d becoming mcp!", p
->id
);
48 con_type
= p
->con_type
; /* move connection data */
50 procs_p
[MCP
].sockid
= p
->sockid
; /* don't save contype yet,
51 or p_del will notify mcp about a deleted
52 mcp-object (which is itselfs, actually) */
55 memcpy(&procs_p
[MCP
].shmsock
, &p
->shmsock
, sizeof(struct t_shmcb
));
57 p_del(p
); /* deleting data/mcp object */
58 procs_p
[MCP
].con_type
= con_type
;
60 process_list_rm(p
->id
); /* remove old process, but don't kill connection */
63 s3dprintf(LOW
, "the place for the mcp is already taken ...");
67 strncpy(p
->name
, name
, S3D_NAME_MAX
);
70 /* register the new process in the mcp */
71 if (-1 != (mcp_oid
= obj_new(&procs_p
[MCP
]))) {
72 mcp_p
->object
[mcp_oid
]->oflags
|= OF_VIRTUAL
| OF_VISIBLE
| OF_SELECTABLE
;
73 mcp_p
->object
[mcp_oid
]->virtual_pid
= p
->id
;
75 /* mcp_p->object[mcp_oid]->p_mat=(struct t_material *)new_p; */
76 /* dirty, but it's just a pointer after all ... */
78 s3dprintf(LOW
, "process %d now has mcp_oid %d", p
->id
, mcp_oid
);
79 mcp_rep_object(mcp_oid
);
80 if (mcp_p
->con_type
== CON_NULL
) { /* there is no mcp connected! setting focus to the new program: */
84 s3dprintf(LOW
, "couldn't add object to mcp ...");
90 /* adds system objects to the app, like camera, pointers etc ... */
91 static int process_sys_init(struct t_process
*p
)
98 /* this is only called once within process_init, later mcp's are
99 will be registered as "real" apps first */
100 p
->object
[cam
]->translate
.z
= 5;
101 p
->object
[cam
]->oflags
= OF_CAM
;
102 p
->object
[ptr
]->translate
.z
= -1;
103 p
->object
[ptr
]->oflags
= OF_POINTER
;
104 link_insert(p
, ptr
, cam
);
106 /* TODO: ... get the cam and ptr position of the mcp, somehow */
107 p
->object
[cam
]->oflags
= OF_CAM
;
109 if (OBJ_VALID(mcp_p
, get_pointer(mcp_p
), o
)) { /* get parent pointer, copy parent */
110 p
->object
[ptr
]->rotate
.x
= o
->rotate
.x
;
111 p
->object
[ptr
]->rotate
.y
= o
->rotate
.y
;
112 p
->object
[ptr
]->rotate
.z
= o
->rotate
.z
;
113 p
->object
[ptr
]->translate
.x
= o
->translate
.x
;
114 p
->object
[ptr
]->translate
.y
= o
->translate
.y
;
115 p
->object
[ptr
]->translate
.z
= o
->translate
.z
;
117 p
->object
[ptr
]->oflags
= OF_POINTER
;
118 link_insert(p
, ptr
, cam
);
120 s3dprintf(MED
, "process_sys_init(): added object cam0 %d", cam
);
121 s3dprintf(MED
, "process_sys_init(): added object ptr0 %d", ptr
);
122 obj_pos_update(get_proc_by_pid(MCP
), cam
, cam
);
123 obj_pos_update(get_proc_by_pid(MCP
), ptr
, ptr
);
124 event_obj_info(p
, 0); /* tell the new program about the thing */
129 /* this is to be called when a new connection appears. a pointer to the added process will be returned */
130 struct t_process
*process_add(void)
132 struct t_process
*new_p
;
134 procs_p
= (struct t_process
*)realloc(procs_p
, sizeof(struct t_process
) * procs_n
); /* increase the block */
135 new_p
= &procs_p
[procs_n
- 1];
137 new_p
->id
= procs_n
- 1;
138 new_p
->object
= NULL
;
141 new_p
->biggest_obj
= -1;
142 new_p
->con_type
= CON_NULL
; /* this is to be changed by the caller */
143 new_p
->name
[0] = '\0';
147 /* deletes the process with pid */
148 int process_del(int pid
)
151 n_remove(&procs_p
[pid
]);
152 p_del(&procs_p
[pid
]);
155 if ((pid
> 0) && (pid
< procs_n
)) {
156 n_remove(&procs_p
[pid
]);
157 p_del(&procs_p
[pid
]);
158 process_list_rm(pid
);
164 /* just kick process out of the process list, no network/mcp-oid cleanup */
165 static int process_list_rm(int pid
)
167 if (pid
!= (procs_n
- 1)) { /* copy last block, swap pid */
168 memcpy(&procs_p
[pid
], &procs_p
[procs_n
- 1], sizeof(struct t_process
));
169 procs_p
[pid
].id
= pid
; /* change the pid of the new procs_p */
170 if (procs_p
[pid
].mcp_oid
!= -1) /* the last process could just appear without initializing yet ... */
171 procs_p
[0].object
[procs_p
[pid
].mcp_oid
]->virtual_pid
= pid
;
172 /* change the mcp-objects pid-pointer to the right position! */
173 /* this is kind of pointer madness */
176 procs_p
= (struct t_process
*)realloc(procs_p
, sizeof(struct t_process
) * procs_n
); /* decrease the block,
181 struct t_process
*get_proc_by_pid(int pid
)
183 if ((pid
>= 0) && (pid
< procs_n
))
184 return &procs_p
[pid
];
188 /* this actually deleted the process with all it's parts */
189 /* it's quite the same as the original version, but without free() */
190 static int p_del(struct t_process
*p
)
194 if (p
->mcp_oid
!= -1) {
195 for (j
= 0; j
< mcp_p
->n_obj
; j
++) /* remove clones and links pointing on this app-object ... */
196 if (mcp_p
->object
[j
] != NULL
) {
197 if ((mcp_p
->object
[j
]->oflags
& OF_CLONE
) && (mcp_p
->object
[j
]->clone_ooid
== p
->mcp_oid
)) { /* it's linking to our object! */
198 mcp_p
->object
[j
]->oflags
&= ~OF_CLONE
; /* disable clone flag */
199 mcp_p
->object
[j
]->clone_ooid
= 0; /* and "clone reference" to 0 */
200 mcp_p
->object
[j
]->r
= 0.0F
; /* empty object, so radius is zero! */
203 obj_free(mcp_p
, p
->mcp_oid
); /* free the mcp-app-object. */
204 mcp_del_object(p
->mcp_oid
); /* tell MCP that it's object is beeing deleted. */
207 for (i
= 0; i
< p
->n_obj
; i
++)
213 /* the mcp keeps in our memory ... */
214 /* so we just delete the objects added */
215 /* by the last mcp */
216 s3dprintf(MED
, "clean up mcp's junk ...");
217 for (i
= 0; i
< p
->n_obj
; i
++) {
218 if (p
->object
[i
] != NULL
)
219 if (!(p
->object
[i
]->oflags
& (OF_SYSTEM
| OF_VIRTUAL
)))
223 return 0; /* successfully deleted */
226 int process_init(void)
232 strncpy(mcp_p
->name
, "mcp", S3D_NAME_MAX
);
233 mcp_p
->con_type
= CON_NULL
;
234 process_sys_init(mcp_p
);
238 int process_quit(void)
241 s3dprintf(HIGH
, "telling %d processes to go away", procs_n
);
242 for (i
= (procs_n
- 1); i
>= 0; i
--) {
243 s3dprintf(HIGH
, "[QUIT] for %d", i
);
244 event_quit(&procs_p
[i
]);