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