1 /* Copyright (C) 2011 Edward Der-Hua Liu, Hsin-Chu, Taiwan
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation version 2.1
6  * of the License.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16  */
17 
18 #include "hime.h"
19 
20 #define MAX_KEPT_TIME (5 * 60 * (gint64) 1000000)
21 static gint64 *ch_time;
22 static int ch_timeN, ch_timeN_a;
23 static GtkWidget *label_disp, *gwin_stat;
24 gboolean stat_enabled;
25 static int timeout_handle;
26 
get_ch_count(int mini)27 static int get_ch_count (int mini) {
28     gint64 t = current_time () - mini * 60 * 1000000;
29 
30     int i, N;
31     for (i = 0, N = 0; i < ch_timeN; i++)
32         if (ch_time[i] >= t)
33             N++;
34 
35     return ((double) N / mini + 0.5);
36 }
37 
disp_stat()38 void disp_stat () {
39     char tt[512];
40 
41     snprintf (tt, sizeof (tt), _ ("1,3,5 min\n%d,%d,%d/min"), get_ch_count (1), get_ch_count (3), get_ch_count (5));
42     gtk_label_set_text (GTK_LABEL (label_disp), tt);
43 }
44 
add_ch_time()45 void add_ch_time () {
46     int i;
47     gint64 tim = current_time ();
48     gint64 tim_exp = tim - MAX_KEPT_TIME;
49 
50     for (i = 0; i < ch_timeN; i++)
51         if (ch_time[i] > tim_exp)
52             break;
53 
54     if (i) {
55         int leftN = ch_timeN - i;
56         memmove (ch_time, ch_time + i, sizeof (gint64) * leftN);
57         ch_timeN = leftN;
58     }
59 
60     if (ch_timeN_a <= ch_timeN + 1) {
61         ch_timeN_a = ch_timeN + 1;
62         ch_time = trealloc (ch_time, gint64, ch_timeN_a);
63     }
64 
65     ch_time[ch_timeN++] = tim;
66 }
67 
add_ch_time_str(char * s)68 void add_ch_time_str (char *s) {
69     int len = strlen (s);
70     int i = 0;
71     while (i < len) {
72         if (!(s[i] & 0x80)) {
73             i++;
74             continue;
75         }
76         i += utf8_sz (s + i);
77         add_ch_time ();
78     }
79 
80     if (stat_enabled)
81         disp_stat ();
82 }
83 
destory_win_stat()84 void destory_win_stat () {
85     if (!gwin_stat)
86         return;
87     gtk_widget_destroy (gwin_stat);
88     gwin_stat = NULL;
89     g_source_remove (timeout_handle);
90 }
91 
timeout_update_stat(gpointer data)92 gboolean timeout_update_stat (gpointer data) {
93     disp_stat ();
94     return TRUE;
95 }
96 
create_stat_win()97 void create_stat_win () {
98     gwin_stat = gtk_window_new (GTK_WINDOW_TOPLEVEL);
99     gtk_window_set_has_resize_grip (GTK_WINDOW (gwin_stat), FALSE);
100     gtk_container_set_border_width (GTK_CONTAINER (gwin_stat), 0);
101     gtk_widget_realize (gwin_stat);
102     set_no_focus (gwin_stat);
103 
104     GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
105     gtk_orientable_set_orientation (GTK_ORIENTABLE (vbox), GTK_ORIENTATION_VERTICAL);
106     gtk_container_add (GTK_CONTAINER (gwin_stat), vbox);
107 
108     label_disp = gtk_label_new (NULL);
109 
110     gtk_box_pack_start (GTK_BOX (vbox), label_disp, TRUE, TRUE, 0);
111 
112     gtk_widget_show_all (gwin_stat);
113     timeout_handle = g_timeout_add (3000, timeout_update_stat, NULL);
114 }
115 
toggle_stat_win()116 void toggle_stat_win () {
117     stat_enabled ^= 1;
118     if (stat_enabled) {
119         create_stat_win ();
120         disp_stat ();
121     } else
122         destory_win_stat ();
123 }
124