1 /* app.c
2 * Copyright (C) 2002-2004 Pascal Eberhard <pascal.ebo@netcourrier.com>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20
21 #include <sys/types.h>
22 #include "common.h"
23 #include <string.h>
24
25 // used by app_new_noname & app_list_find_noname
26 #define APP_NONAME_CMDLINE ""
27 #define APP_NONAME_PATH ""
28 #define APP_NONAME_ICON ""
29
30 // ----------------------------------------------------------------------------
31 // ----------------------------------------------------------------------------
app_new(gchar * cmdline,gchar * path,gchar * icon,gint x,gint y)32 app_t * app_new(gchar *cmdline, gchar *path, gchar *icon, gint x, gint y)
33 {
34 app_t *app;
35
36 g_assert(cmdline != NULL && path != NULL && icon != NULL);
37
38 app = (app_t *) malloc(sizeof(app_t));
39 g_assert(app != NULL);
40
41 app->cmdline = cmdline;
42 app->path = path;
43 app->icon = icon;
44 app->x = x;
45 app->y = y;
46 return app;
47 }
48
49 // ----------------------------------------------------------------------------
app_new_noname(gint x,gint y)50 app_t * app_new_noname(gint x, gint y)
51 {
52 app_t *app;
53 app = app_new(g_strdup(APP_NONAME_CMDLINE), g_strdup(APP_NONAME_PATH),
54 g_strdup(APP_NONAME_ICON), x, y);
55 return app;
56 }
57 // ----------------------------------------------------------------------------
app_free(app_t ** app)58 void app_free(app_t **app)
59 {
60 g_assert(app != NULL && *app != NULL);
61
62 TRACE("app:%p", *app);
63 if ((*app)->cmdline)
64 g_free((*app)->cmdline);
65 if ((*app)->path)
66 g_free((*app)->path);
67 if ((*app)->icon)
68 g_free((*app)->icon);
69 free((*app));
70 (*app) = NULL;
71 }
72 // ----------------------------------------------------------------------------
app_clone(app_t * app)73 app_t * app_clone(app_t *app)
74 {
75 app_t *newapp;
76
77 g_assert(app != NULL);
78
79 newapp = (app_t *) malloc(sizeof(app_t));
80 g_assert(newapp != NULL);
81
82 newapp->cmdline = g_strdup(app->cmdline);
83 newapp->path = g_strdup(app->path);
84 newapp->icon = g_strdup(app->icon);
85 newapp->x = app->x;
86 newapp->y = app->y;
87 return newapp;
88 }
89 // ----------------------------------------------------------------------------
app_exec(app_t * app,gboolean exit_at_app_launch)90 gboolean app_exec(app_t *app, gboolean exit_at_app_launch)
91 {
92 gboolean spawned;
93
94 g_assert(app != NULL);
95 spawned = sys_spawn(app->cmdline, app->path);
96 if (!spawned)
97 {
98 WARN("sys_spawn, cmdline:%s, path:%s", app->cmdline, app->path);
99 return FALSE;
100 }
101 if (exit_at_app_launch)
102 gtk_main_quit();
103 return TRUE;
104 }
105 // ----------------------------------------------------------------------------
app_dump(app_t * app)106 void app_dump(app_t *app)
107 {
108 g_assert(app != NULL);
109 TRACE("icon:%s, cmdline:%s, x:%d, y:%d",
110 app->icon, app->cmdline, app->x, app->y);
111 }
112 // ----------------------------------------------------------------------------
app_dumpln(app_t * app)113 void app_dumpln(app_t *app)
114 {
115 g_assert(app != NULL);
116 TRACE("[app|icon:%s, cmdline:%s, x:%d, y:%d]",
117 app->icon, app->cmdline, app->x, app->y);
118 }
119 // ----------------------------------------------------------------------------
app_is_executable(app_t * app)120 gboolean app_is_executable(app_t *app)
121 {
122 int argcp;
123 char **argvp;
124 gboolean res, is_exec;
125 g_assert(app != NULL && app->cmdline != NULL);
126 res = g_shell_parse_argv(app->cmdline, &argcp, &argvp, NULL/*GError*/);
127 if (res == TRUE)
128 {
129 if (g_path_is_absolute(argvp[0]))
130 is_exec = g_file_test(argvp[0], G_FILE_TEST_IS_EXECUTABLE);
131 else
132 {
133 char *absolute_path;
134 absolute_path = g_find_program_in_path(argvp[0]);
135 is_exec = g_file_test(absolute_path, G_FILE_TEST_IS_EXECUTABLE);
136 g_free(absolute_path);
137 }
138 g_strfreev(argvp);
139 }
140 else
141 return FALSE;
142 return is_exec;
143 }
144 // ----------------------------------------------------------------------------
app_path_is_valid(app_t * app)145 gboolean app_path_is_valid(app_t *app)
146 {
147 gboolean is_valid;
148 g_assert(app != NULL && app->path != NULL);
149 if (strcmp("", app->path) == 0)
150 return TRUE;
151 is_valid = g_file_test(app->path, G_FILE_TEST_IS_DIR);
152 return is_valid;
153 }
154 // ----------------------------------------------------------------------------
app_icon_is_valid(app_t * app)155 gboolean app_icon_is_valid(app_t *app)
156 {
157 gboolean is_valid;
158 g_assert(app != NULL && app->icon != NULL);
159 is_valid = g_file_test(app->icon, G_FILE_TEST_EXISTS);
160 return is_valid;
161 }
162 // ----------------------------------------------------------------------------
app_get_cmdline(app_t * app)163 const char *app_get_cmdline(app_t *app)
164 {
165 g_assert(app != NULL);
166 return app->cmdline;
167 }
168 // ----------------------------------------------------------------------------
app_set_cmdline(app_t * app,const char * value)169 void app_set_cmdline(app_t *app, const char *value)
170 {
171 g_assert(app != NULL && value != NULL);
172 TRACE("%s", "");
173 if (app->cmdline)
174 g_free(app->cmdline);
175 app->cmdline = g_strdup(value);
176 g_assert(app->cmdline != NULL);
177 }
178 // ----------------------------------------------------------------------------
app_get_path(app_t * app)179 const char *app_get_path(app_t *app)
180 {
181 g_assert(app != NULL);
182 return app->path;
183 }
184 // ----------------------------------------------------------------------------
app_set_path(app_t * app,const char * value)185 void app_set_path(app_t *app, const char *value)
186 {
187 g_assert(app != NULL && value != NULL);
188 TRACE("%s", "");
189 if (app->path)
190 g_free(app->path);
191 app->path = g_strdup(value);
192 g_assert(app->path != NULL);
193 }
194 // ----------------------------------------------------------------------------
app_get_icon(app_t * app)195 const char *app_get_icon(app_t *app)
196 {
197 g_assert(app != NULL);
198 return app->icon;
199 }
200 // ----------------------------------------------------------------------------
app_set_icon(app_t * app,const char * value)201 void app_set_icon(app_t *app, const char *value)
202 {
203 g_assert(app != NULL && value != NULL);
204 TRACE("%s", "");
205 if (app->icon)
206 g_free(app->icon);
207 app->icon = g_strdup(value);
208 g_assert(app->icon != NULL);
209 }
210 // ----------------------------------------------------------------------------
211 // ----------------------------------------------------------------------------
212 // ----------------------------------------------------------------------------
213 // ----------------------------------------------------------------------------
214 // ----------------------------------------------------------------------------
215 // ----------------------------------------------------------------------------
app_list_new(void)216 app_list_t* app_list_new(void)
217 {
218 app_list_t *apps;
219 apps = (app_list_t *) malloc(sizeof(app_list_t));
220 g_assert(apps != NULL);
221 apps->apps = NULL;
222 apps->hamster = NULL;
223 return apps;
224 }
225
226 // ----------------------------------------------------------------------------
app_list_free(app_list_t ** apps)227 void app_list_free(app_list_t **apps)
228 {
229 app_t *app;
230
231 g_assert(apps != NULL && *apps != NULL);
232
233 TRACE("apps:%p", apps);
234 while ((*apps)->apps)
235 {
236 (*apps)->hamster = g_list_first((*apps)->apps);
237 if ((*apps)->hamster)
238 app = (*apps)->hamster->data;
239 else
240 {
241 WARN("list:%p, (*apps)->hamster:%p",
242 (*apps)->apps, (*apps)->hamster);
243 }
244 (*apps)->apps = g_list_remove((*apps)->apps, app);
245 app_free(&app);
246 }
247 }
248
249 // ----------------------------------------------------------------------------
app_list_add(app_list_t * apps,app_t * app)250 int app_list_add(app_list_t *apps, app_t *app)
251 {
252 gboolean empty;
253 gint try_new_pos;
254
255 g_assert(apps != NULL && app != NULL);
256
257 try_new_pos = 0;
258 empty = app_list_xy_empty(apps, app->x, app->y);
259 while (!empty)
260 {
261 TRACE("dupplicate icon at x:%d, y:%d, "
262 "change second icon position", app->x, app->y);
263 app->x++;
264 empty = app_list_xy_empty(apps, app->x, app->y);
265 if (try_new_pos > 20)
266 {
267 WARN("whaou, try:%d > 20, it's big! icon:%s, cmdline:%s, x:%d, y:%d",
268 try_new_pos, app->icon, app->cmdline, app->x, app->y);
269 return -1;
270 }
271 try_new_pos++;
272 }
273 apps->apps = g_list_append(apps->apps, app);
274 return 0;
275 }
276 // ----------------------------------------------------------------------------
app_list_remove(app_list_t * apps,app_t * app)277 int app_list_remove(app_list_t *apps, app_t *app)
278 {
279 GList *apps_new;
280 gint len;
281
282 g_assert(apps != NULL && app != NULL);
283
284 TRACE("apps:%p, app:%p", apps, app);
285 len = app_list_length(apps);
286 apps_new = g_list_remove(apps->apps, app);
287 if ((!apps_new) && (len !=1))
288 {
289 WARN("app:%p introuvable dans apps:%p", app, apps);
290 return -1;
291 }
292 apps->apps = apps_new;
293 app_free(&app);
294 return 0;
295 }
296 // ----------------------------------------------------------------------------
app_list_first(app_list_t * apps)297 app_t *app_list_first(app_list_t *apps)
298 {
299 g_assert(apps != NULL);
300
301 if (!apps->apps)
302 return NULL;
303 apps->hamster = g_list_first(apps->apps);
304 return apps->hamster->data;
305 }
306 // ----------------------------------------------------------------------------
app_list_next(app_list_t * apps)307 app_t *app_list_next(app_list_t *apps)
308 {
309 g_assert(apps != NULL);
310 g_assert(apps->apps != NULL && apps->hamster != NULL);
311
312 apps->hamster = g_list_next(apps->hamster);
313 if (!apps->hamster)
314 return NULL;
315 return apps->hamster->data;
316 }
317 // ----------------------------------------------------------------------------
app_list_nth(app_list_t * apps,int nth)318 app_t *app_list_nth(app_list_t *apps, int nth)
319 {
320 g_assert(apps != NULL && apps->apps != NULL);
321
322 apps->hamster = g_list_nth(apps->apps, nth);
323 if (!apps->hamster)
324 return NULL;
325 return apps->hamster->data;
326 }
327
328 // ----------------------------------------------------------------------------
app_list_length(app_list_t * apps)329 int app_list_length(app_list_t *apps)
330 {
331 g_assert(apps != NULL && apps->apps != NULL);
332
333 return g_list_length(apps->apps);
334 }
335 // ----------------------------------------------------------------------------
app_list_dump(app_list_t * apps)336 void app_list_dump(app_list_t *apps)
337 {
338 app_t *app;
339
340 g_assert(apps != NULL);
341
342 app = app_list_first(apps);
343 while(app)
344 {
345 g_print("app[");
346 app_dump(app);
347 g_print("]\n");
348 app = app_list_next(apps);
349 }
350 }
351 // ----------------------------------------------------------------------------
352 // ----------------------------------------------------------------------------
app_list_delta_x(app_list_t * apps)353 gint app_list_delta_x(app_list_t *apps)
354 {
355 app_t *app;
356 gint x_min;
357 gint x_max;
358
359 g_assert(apps != NULL && apps->apps != NULL);
360
361 app = app_list_first(apps);
362 x_min = app->x;
363 x_max = app->x;
364 app = app_list_next(apps);
365 while(app)
366 {
367 if (x_max < app->x)
368 x_max = app->x;
369 if (x_min > app->x)
370 x_min = app->x;
371 app = app_list_next(apps);
372 }
373 return (x_max - x_min);
374 }
375 // ----------------------------------------------------------------------------
app_list_delta_y(app_list_t * apps)376 gint app_list_delta_y(app_list_t *apps)
377 {
378 app_t *app;
379 gint y_min;
380 gint y_max;
381
382 g_assert(apps != NULL && apps->apps != NULL);
383
384 app = app_list_first(apps);
385 y_min = app->y;
386 y_max = app->y;
387 app = app_list_next(apps);
388 while(app)
389 {
390 if (y_max < app->y)
391 y_max = app->y;
392 if (y_min > app->y)
393 y_min = app->y;
394 app = app_list_next(apps);
395 }
396 return (y_max - y_min);
397 }
398 // ----------------------------------------------------------------------------
app_list_min_x(app_list_t * apps)399 int app_list_min_x(app_list_t *apps)
400 {
401 app_t *app;
402 gint x_min;
403
404 g_assert(apps != NULL && apps->apps != NULL);
405
406 app = app_list_first(apps);
407 x_min = app->x;
408 app = app_list_next(apps);
409 while(app)
410 {
411 if (x_min > app->x)
412 x_min = app->x;
413 app = app_list_next(apps);
414 }
415 return x_min;
416 }
417 // ----------------------------------------------------------------------------
app_list_min_y(app_list_t * apps)418 int app_list_min_y(app_list_t *apps)
419 {
420 app_t *app;
421 gint y_min;
422
423 g_assert(apps != NULL && apps->apps != NULL);
424
425 app = app_list_first(apps);
426 y_min = app->y;
427 app = app_list_next(apps);
428 while(app)
429 {
430 if (y_min > app->y)
431 y_min = app->y;
432 app = app_list_next(apps);
433 }
434 return y_min;
435 }
436 // ----------------------------------------------------------------------------
app_list_max_x(app_list_t * apps)437 int app_list_max_x(app_list_t *apps)
438 {
439 app_t *app;
440 gint x_max;
441
442 g_assert(apps != NULL && apps->apps != NULL);
443
444 app = app_list_first(apps);
445 x_max = app->x;
446 app = app_list_next(apps);
447 while(app)
448 {
449 if (x_max < app->x)
450 x_max = app->x;
451 app = app_list_next(apps);
452 }
453 return x_max;
454 }
455 // ----------------------------------------------------------------------------
app_list_max_y(app_list_t * apps)456 int app_list_max_y(app_list_t *apps)
457 {
458 app_t *app;
459 gint y_max;
460
461 g_assert(apps != NULL && apps->apps != NULL);
462
463 app = app_list_first(apps);
464 y_max = app->y;
465 app = app_list_next(apps);
466 while(app)
467 {
468 if (y_max < app->y)
469 y_max = app->y;
470 app = app_list_next(apps);
471 }
472 return y_max;
473 }
474 // ----------------------------------------------------------------------------
app_list_at_xy(app_list_t * apps,gint x,gint y)475 app_t * app_list_at_xy(app_list_t *apps, gint x, gint y)
476 {
477 app_t *app;
478 GList *hamster;
479 g_assert(apps != NULL);
480 hamster = g_list_first(apps->apps);
481 while(hamster != NULL)
482 {
483 app = hamster->data;
484 if ((app->x == x) && (app->y == y))
485 {
486 return app;
487 }
488 hamster = g_list_next(hamster);
489 }
490 return NULL;
491 }
492 // ----------------------------------------------------------------------------
app_list_xy_empty(app_list_t * apps,gint x,gint y)493 gboolean app_list_xy_empty(app_list_t *apps, gint x, gint y)
494 {
495 app_t *app;
496
497 g_assert(apps != NULL);
498
499 if (!apps->apps)
500 return TRUE;
501
502 app = app_list_at_xy(apps, x, y);
503 if (app)
504 return FALSE;
505 return TRUE;
506 }
507 // ----------------------------------------------------------------------------
app_list_find_noname(app_list_t * apps)508 app_t * app_list_find_noname(app_list_t *apps)
509 {
510 app_t *app;
511 GList *hamster;
512 g_assert(apps != NULL);
513 hamster = g_list_first(apps->apps);
514 while(hamster != NULL)
515 {
516 app = hamster->data;
517 if (!strcmp(app->cmdline, APP_NONAME_CMDLINE) &&
518 !strcmp(app->path, APP_NONAME_PATH) &&
519 !strcmp(app->icon, APP_NONAME_ICON))
520 return app;
521 hamster = g_list_next(hamster);
522 }
523 return NULL;
524 }
525 // ----------------------------------------------------------------------------
526 // ----------------------------------------------------------------------------
527