00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <glib.h>
00033 #include <stdio.h>
00034
00035
00036
00037
00038 #include "log.h"
00039 #include "ipc.h"
00040
00041 #define UNUSED(x) (void)(x)
00042
00043
00044
00045
00046
00047
00048 typedef struct
00049 {
00050 gint sender;
00051 GPid pid;
00052 gint fg_count;
00053 gint bg_count;
00054 } busy_count_t;
00055
00056
00057
00058
00059
00060
00061 enum
00062 {
00063 BACKGROUND,
00064 FOREGROUND
00065 };
00066
00067 const gint dialog_delay = 1000;
00068 const gint busyled_delay = 1000;
00069
00070
00071
00072
00073
00074
00075 static GSList *g_app_counters = NULL;
00076 static gchar *g_message = NULL;
00077 static guint g_dialog_source = 0;
00078 static guint g_background_count = 0;
00079 static guint g_foreground_count = 0;
00080
00081
00082
00083
00084
00085
00086 static void count_ref (gint sender, gint mode);
00087 static void count_unref (gint sender, gint mode);
00088 static void count_set_pid (gint sender, GPid pid);
00089 static void count_remove_pid (GPid pid);
00090 static gint ref_count (gint mode);
00091 static void update (void);
00092 static void show_dialog (gboolean on);
00093 static gboolean delay_dialog_cb (gpointer data);
00094
00095
00096
00097
00098
00099
00100 gboolean busy_add_background(gint sender)
00101 {
00102
00103
00104 count_ref(sender, BACKGROUND);
00105
00106 return TRUE;
00107 }
00108
00109
00110 gboolean busy_remove_background(gint sender)
00111 {
00112
00113
00114 count_unref(sender, BACKGROUND);
00115
00116 return TRUE;
00117 }
00118
00119
00120 gboolean busy_add_foreground(gint sender, enum busy_dialog dialog_mode, const char *message)
00121 {
00122 LOGPRINTF("entry");
00123
00124 count_ref(sender, FOREGROUND);
00125
00126
00127 if (g_message)
00128 {
00129 g_free(g_message);
00130 }
00131
00132 if (message)
00133 {
00134 g_message = g_strdup(message);
00135 }
00136 else
00137 {
00138 g_message = NULL;
00139 }
00140
00141 if (dialog_mode == BUSY_DIALOG_DIRECT)
00142 {
00143 show_dialog(TRUE);
00144 }
00145 else if (dialog_mode == BUSY_DIALOG_DELAYED)
00146 {
00147 if (g_dialog_source == 0)
00148 {
00149 LOGPRINTF("delay %d ms before show busy DIALOG", dialog_delay);
00150 g_dialog_source = g_timeout_add(dialog_delay, delay_dialog_cb, NULL);
00151 }
00152 else
00153 {
00154 LOGPRINTF("already waiting for busy DIALOG");
00155 }
00156 }
00157
00158 return TRUE;
00159 }
00160
00161
00162 gboolean busy_remove_foreground(gint sender)
00163 {
00164
00165
00166 count_unref(sender, FOREGROUND);
00167
00168 return TRUE;
00169 }
00170
00171
00172 gboolean is_busy_foreground()
00173 {
00174 if (g_foreground_count > 0)
00175 {
00176 return TRUE;
00177 }
00178 return FALSE;
00179 }
00180
00181
00182 gboolean is_busy_background()
00183 {
00184 if (g_background_count > 0)
00185 {
00186 return TRUE;
00187 }
00188 return FALSE;
00189 }
00190
00191
00192 void busy_set_pid(gint sender, GPid pid)
00193 {
00194
00195
00196 count_set_pid(sender, pid);
00197 }
00198
00199
00200 void busy_reset_pid(GPid pid)
00201 {
00202
00203
00204 count_remove_pid(pid);
00205 }
00206
00207
00208
00209
00210
00211
00212 static void show_dialog(gboolean on)
00213 {
00214 static gboolean is_shown = FALSE;
00215
00216 LOGPRINTF("entry: on [%d] is_shown [%d]", on, is_shown);
00217
00218 if (on && !is_shown)
00219 {
00220 LOGPRINTF("show busy DIALOG!");
00221 ipc_show_busy(TRUE, g_message);
00222 is_shown = TRUE;
00223 }
00224 else if (!on && is_shown)
00225 {
00226 LOGPRINTF("hide busy DIALOG!");
00227 ipc_show_busy(FALSE, NULL);
00228 is_shown = FALSE;
00229 }
00230 }
00231
00232
00233 static gboolean delay_dialog_cb(gpointer data)
00234 {
00235 UNUSED(data);
00236 LOGPRINTF("entry");
00237
00238 if (ref_count(FOREGROUND) > 0)
00239 {
00240 show_dialog(TRUE);
00241 }
00242 else
00243 {
00244 LOGPRINTF("busy DIALOG not needed anymore");
00245 }
00246
00247 g_dialog_source = 0;
00248
00249 return FALSE;
00250 }
00251
00252
00253 static void count_set_pid(gint sender, GPid pid)
00254 {
00255 LOGPRINTF("entry sender [%d] pid [%d]", sender, pid);
00256
00257 GSList *busy_ptr = g_app_counters;
00258 busy_count_t *cur_busy = NULL;
00259
00260
00261 while (busy_ptr)
00262 {
00263 cur_busy = (busy_count_t *) busy_ptr->data;
00264
00265 if (cur_busy->sender == sender)
00266 {
00267 cur_busy->pid = pid;
00268 return;
00269 }
00270 busy_ptr = busy_ptr->next;
00271 }
00272
00273
00274 busy_count_t *busy = g_new0 (busy_count_t, 1);
00275 if (!busy)
00276 {
00277 ERRORPRINTF("mem alloc failed");
00278 return;
00279 }
00280
00281 busy->sender = sender;
00282 busy->pid = pid;
00283
00284 g_app_counters = g_slist_prepend(g_app_counters, busy);
00285
00286 return;
00287 }
00288
00289
00290 static void count_ref(gint sender, gint mode)
00291 {
00292 LOGPRINTF("entry sender [%d], %s", sender, mode == 0 ? "BACKGROUND" : "FOREGROUND");
00293
00294 GSList *busy_ptr = g_app_counters;
00295 busy_count_t *cur_busy = NULL;
00296
00297
00298 while (busy_ptr)
00299 {
00300 cur_busy = (busy_count_t *) busy_ptr->data;
00301
00302 if (cur_busy->sender == sender)
00303 {
00304
00305 if (mode == FOREGROUND)
00306 {
00307 cur_busy->fg_count++;
00308 }
00309 cur_busy->bg_count++;
00310 LOGPRINTF("sender [%d] bg_count [%d] fg_count [%d]", sender, cur_busy->bg_count, cur_busy->fg_count);
00311
00312 update();
00313 return;
00314 }
00315 busy_ptr = busy_ptr->next;
00316 }
00317
00318
00319 busy_count_t *busy = g_new0 (busy_count_t, 1);
00320 if (!busy)
00321 {
00322 ERRORPRINTF("mem alloc failed");
00323 return;
00324 }
00325
00326 busy->sender = sender;
00327 if (mode == FOREGROUND)
00328 {
00329 busy->fg_count = 1;
00330 }
00331 busy->bg_count = 1;
00332
00333 g_app_counters = g_slist_prepend(g_app_counters, busy);
00334
00335 LOGPRINTF("sender [%d] bg_count [%d] fg_count [%d]", sender, busy->bg_count, busy->fg_count);
00336 update();
00337 return;
00338 }
00339
00340
00341 static void count_unref(gint sender, gint mode)
00342 {
00343 LOGPRINTF("entry sender [%d], mode [%d]", sender, mode);
00344
00345 GSList *busy_ptr = g_app_counters;
00346 busy_count_t *cur_busy = NULL;
00347
00348
00349 while (busy_ptr)
00350 {
00351 cur_busy = (busy_count_t *) busy_ptr->data;
00352
00353 if (cur_busy->sender == sender)
00354 {
00355
00356 if (mode == FOREGROUND)
00357 {
00358 if (cur_busy->fg_count > 0)
00359 {
00360 cur_busy->fg_count--;
00361 }
00362 }
00363 if (cur_busy->bg_count > 0)
00364 {
00365 cur_busy->bg_count--;
00366 }
00367
00368 LOGPRINTF("sender [%d] bg_count [%d] fg_count [%d]", sender, cur_busy->bg_count, cur_busy->fg_count);
00369
00370 update();
00371 return;
00372 }
00373 busy_ptr = busy_ptr->next;
00374 }
00375
00376 return;
00377 }
00378
00379
00380 static void count_remove_pid(GPid pid)
00381 {
00382 LOGPRINTF("entry pid [%d]", pid);
00383
00384 GSList *busy_ptr = g_app_counters;
00385 busy_count_t *cur_busy = NULL;
00386
00387
00388 while (busy_ptr)
00389 {
00390 cur_busy = (busy_count_t *) busy_ptr->data;
00391 if (cur_busy->pid == pid)
00392 {
00393 LOGPRINTF("found pid [%d] sender [%d] bg count [%d] fg count [%d]", cur_busy->pid, cur_busy->sender, cur_busy->bg_count, cur_busy->fg_count);
00394 g_app_counters = g_slist_delete_link(g_app_counters, busy_ptr);
00395 update();
00396 return;
00397 }
00398 busy_ptr = busy_ptr->next;
00399 }
00400
00401 return;
00402 }
00403
00404
00405 static gint ref_count(gint mode)
00406 {
00407
00408
00409 gint count = 0;
00410 GSList *busy_ptr = g_app_counters;
00411 while (busy_ptr)
00412 {
00413 if (mode == FOREGROUND)
00414 count += ((busy_count_t *) busy_ptr->data)->fg_count;
00415 else
00416 count += ((busy_count_t *) busy_ptr->data)->bg_count;
00417 busy_ptr = busy_ptr->next;
00418 }
00419
00420 if (mode == FOREGROUND)
00421 LOGPRINTF("foreground [%d]", count);
00422 else
00423 LOGPRINTF("background [%d]", count);
00424
00425 return count;
00426 }
00427
00428
00429 static gboolean do_update_rgb_led(gpointer data)
00430 {
00431 UNUSED(data);
00432 sys_update_rgb_led();
00433 return FALSE;
00434 }
00435
00436
00437 static void update()
00438 {
00439 LOGPRINTF("entry: background [%d] foreground [%d]", ref_count(BACKGROUND), ref_count(FOREGROUND));
00440
00441 guint old_foreground_count = g_foreground_count;
00442 g_background_count = ref_count(BACKGROUND);
00443 g_foreground_count = ref_count(FOREGROUND);
00444
00445 if (g_background_count == 0)
00446 {
00447
00448
00449 sys_reset_idle_time();
00450 }
00451
00452 if (g_foreground_count != old_foreground_count)
00453 {
00454 if (g_foreground_count == 1)
00455 {
00456 g_timeout_add(busyled_delay, do_update_rgb_led, NULL);
00457 }
00458 else if (g_foreground_count == 0)
00459 {
00460 if (g_dialog_source)
00461 {
00462 LOGPRINTF("stop busy dialog timer");
00463 g_source_remove(g_dialog_source);
00464 g_dialog_source = 0;
00465 }
00466 sys_update_rgb_led();
00467 show_dialog(FALSE);
00468 }
00469 }
00470 }