1 /* gapcmon.c serial-0088-0 *****************************************
3 GKT+ GUI with Notification Area (System Tray) support. Program for
4 monitoring the apcupsd.sourceforge.net package.
5 Copyright (C) 2006 James Scott, Jr. <skoona@users.sourceforge.net>
7 Command Line Syntax: gapcmon [--help]
9 This program 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 This program 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 this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 /* ************************************************************************** *
26 * ------------------------ -------------------------------------------------
27 * GtkWindow Main Control Program Thread ----
28 * EggTrayIcon Notification system tray icon for main app.
29 * * GtkNotebook Main Interface
30 * * GtkTreeView Monitors pg: list of active monitors and state
31 * - EggTrayIcon Notification system tray icon for monitors.
32 * - GtkWindow Monitor Information Window -
33 * TrayIcon and InfoWindow compose a monitor
34 * * PG-n GtkNotebook Active monitor notebook with four pages;
35 * summary chart, detailed, eventlog, statuslog pages.
36 * - nbPage HISTORY A lg_Graph histogram line chart of
37 * LINEV, LOADPCT, BCHARGE, CUMONBATT, TIMELEFT
38 * g_timeout_add Monitor g_timeout per monitor for data updates
39 * g_timeout_add Monitor g_timeout per graph 1:30 collection updates
40 * - nbPage DETAILS Grouped results from the status output.
41 * - nbPage EVENTS Current events log
42 * - nbPage STATUS Current status log, same as APCACCESS
43 * * GtkTreeView Preferences pg: For Main app, and Monitors
44 * * GtkVBox About pg: Program copyright info
45 * * GtkHBox Action info
46 * - GtkLabel Program Title line
47 * - GtkButton Program Close button
48 * * GtkStatusbar Status message line
50 * ------------------------ ---------------------------------------------------
51 * + GConfClient Tied to Preferences page
52 * Produces direct change on application state and
53 * operation by monitoring changes to config values
54 * ------------------------ ---------------------------------------------------
55 * + GThread Network Communication via socket io using GIOChannels
56 * Communication to interface gtkthread through
57 * a GAsyncQueue, with additional instance mutex
58 * - protect hash table from multi-thread access
59 * - protect GTK from multi-thread access
60 * gdk_thread_[enter|leave] around gtk calls in timer
61 * routines and threads - and gtk_main_loop.
62 * ------------------------ ---------------------------------------------------
65 * key /schemas/apps/gapcmon/controller/keys
66 * /apps/gapcmon/monitor/x/monitor-keys
67 * Where x is the internal monitor number.
68 * max monitors=unlimted or sizeof guint
69 * Where key is the actual keyname like enabled, host_name, port_name, or
70 * refresh_interval, etc.
71 * ************************************************************************** *
74 #include <unistd.h> /* close() */
75 #include <sys/types.h> /* socket() */
76 #include <sys/socket.h> /* socket() */
77 #include <netinet/in.h> /* sockaddr_in */
78 #include <arpa/inet.h> /* ntohs() */
79 #include <netinet/in.h> /* sockaddr_in */
80 #include <netdb.h> /* gethostbyname() */
82 #include <string.h> /* memset() */
84 #include <stdlib.h> /* malloc() */
86 #include <gconf/gconf-client.h>
88 #include "eggtrayicon.h"
91 static gboolean
cb_monitor_dedicated_one_time_refresh(PGAPC_MONITOR pm
);
92 static gboolean
cb_monitor_automatic_refresh(PGAPC_MONITOR pm
);
93 static gboolean
cb_monitor_refresh_control(PGAPC_MONITOR pm
);
94 static gboolean
gapc_monitor_update_tooltip_msg(PGAPC_MONITOR pm
);
95 static gint
gapc_monitor_update(PGAPC_MONITOR pm
);
97 static gdouble
gapc_util_point_filter_set(PGAPC_SUMS sq
, gdouble this_point
);
98 static gdouble
gapc_util_point_filter_reset(PGAPC_SUMS sq
);
99 static void lg_graph_set_chart_title (PLGRAPH plg
, gchar
* pch_text
);
100 static void lg_graph_set_y_label_text (PLGRAPH plg
, gchar
* pch_text
);
101 static void lg_graph_set_x_label_text (PLGRAPH plg
, gchar
* pch_text
);
103 static void lg_graph_set_chart_title_color (PLGRAPH plg
, gchar
* pch_color
);
104 static void lg_graph_set_chart_scales_color (PLGRAPH plg
, gchar
* pch_color
);
105 static void lg_graph_set_chart_window_fg_color (PLGRAPH plg
, gchar
* pch_color
);
106 static void lg_graph_set_chart_window_bg_color (PLGRAPH plg
, gchar
* pch_color
);
108 static PLGRAPH
lg_graph_create (GtkWidget
* box
, gint width
, gint height
);
109 static void lg_graph_set_ranges (PLGRAPH plg
,
114 gint yminor_by
, gint ymajor_by
, gint y_min
, gint y_max
);
115 static void lg_graph_redraw (PLGRAPH plg
);
117 static gint
lg_graph_data_series_add (PLGRAPH plg
, gchar
* pch_legend_text
,
118 gchar
* pch_color_text
);
119 static gboolean
lg_graph_data_series_remove_all (PLGRAPH plg
);
120 static gboolean
lg_graph_data_series_add_value (PLGRAPH plg
, gint i_series_number
,
122 static gint
lg_graph_data_series_draw (PLGRAPH plg
, PLG_SERIES psd
);
125 * Private Interfaces */
126 static gint
lg_graph_draw_tooltip (PLGRAPH plg
);
127 static gint
lg_graph_data_series_draw_all (PLGRAPH plg
, gboolean redraw_control
);
128 static void lg_graph_get_default_sizes (PLGRAPH plg
, gint
* width
, gint
* height
);
129 static void lg_graph_draw_x_grid_labels (PLGRAPH plg
);
130 static void lg_graph_draw_y_grid_labels (PLGRAPH plg
);
131 static gint
lg_graph_draw_grid_lines (PLGRAPH plg
);
132 static gint
lg_graph_draw_horizontal_text (PLGRAPH plg
,
134 GdkRectangle
* rect
, gboolean redraw_control
);
135 static gint
lg_graph_draw_vertical_text (PLGRAPH plg
,
137 GdkRectangle
* rect
, gboolean redraw_control
);
138 static gint
lg_graph_draw (PLGRAPH plg
);
139 static gint
lg_graph_configure_event_cb (GtkWidget
* widget
,
140 GdkEventConfigure
* event
, PLGRAPH plg
);
141 static gint
lg_graph_expose_event_cb (GtkWidget
* widget
, GdkEventExpose
* event
,
143 static gboolean
lg_graph_motion_notify_event_cb (GtkWidget
* widget
, GdkEventMotion
* ev
,
145 static gboolean
lg_graph_button_press_event_cb (GtkWidget
* widget
, GdkEventButton
* ev
,
147 static gboolean
cb_util_barchart_handle_exposed(GtkWidget
* widget
,
148 GdkEventExpose
* event
, gpointer data
);
149 static gboolean
cb_util_line_chart_refresh(PGAPC_HISTORY pg
);
151 static gboolean
cb_util_manage_iconify_event(GtkWidget
*widget
,
152 GdkEventWindowState
*event
,
154 static void gapc_util_text_view_append(GtkWidget
* view
, gchar
* pch
);
155 static void gapc_util_text_view_prepend(GtkWidget
* view
, gchar
* pch
);
156 static gboolean
gapc_util_text_view_clear_buffer(GtkWidget
* view
);
157 static gboolean
gapc_util_treeview_get_iter_from_monitor(GtkTreeModel
* model
,
158 GtkTreeIter
* iter
, gint i_value
);
159 static gint
gapc_util_update_hashtable(PGAPC_MONITOR pm
, gchar
* pch_unparsed
);
160 static void cb_panel_systray_icon_destroy(GtkObject
* object
, gpointer gp
);
161 static void cb_main_interface_button_quit(GtkWidget
* button
, PGAPC_CONFIG pcfg
);
162 static void gapc_monitor_interface_destroy(PGAPC_CONFIG pcfg
, gint i_monitor
);
163 static GtkWidget
*gapc_monitor_interface_create(PGAPC_CONFIG pcfg
, gint i_monitor
,
165 static void cb_panel_monitor_list_activated(GtkTreeView
* treeview
,
166 GtkTreePath
* arg1
, GtkTreeViewColumn
* arg2
, PGAPC_CONFIG pcfg
);
167 static gint
gapc_panel_glossary_page(PGAPC_CONFIG pcfg
, GtkWidget
* notebook
);
168 static gint
gapc_panel_graph_property_page(PGAPC_CONFIG pcfg
, GtkWidget
* notebook
);
171 * Common interface to the various versions of gethostbyname_r().
172 * Implemented in gethostname.c.
174 struct hostent
* gethostname_re
175 (const char *host
,struct hostent
*hostbuf
,char **tmphstbuf
,size_t *hstbuflen
);
178 * Some small number of globals are required
180 static gboolean lg_graph_debug
= FALSE
;
183 /* ************************************************************************* */
186 * Draws one data series points to chart
187 * returns number of points processed
189 static gint
lg_graph_data_series_draw (PLGRAPH plg
, PLG_SERIES psd
)
192 GdkPoint
*point_pos
= NULL
;
194 g_return_val_if_fail (plg
!= NULL
, -1);
195 g_return_val_if_fail (psd
!= NULL
, -1);
196 g_return_val_if_fail (psd
->point_pos
!= NULL
, -1);
198 gdk_gc_set_rgb_fg_color (plg
->series_gc
, &psd
->legend_color
);
199 gdk_gc_set_line_attributes (plg
->series_gc
, 2,
200 GDK_LINE_SOLID
, GDK_CAP_BUTT
, GDK_JOIN_MITER
);
202 point_pos
= psd
->point_pos
;
204 /* trap first and only point */
205 if (psd
->i_point_count
== 0)
209 if (psd
->i_point_count
== 1)
211 point_pos
[0].x
= plg
->plot_box
.x
;
213 (plg
->plot_box
.y
+ plg
->plot_box
.height
) -
214 ((psd
->lg_point_dvalue
[0] *
215 (gdouble
) ((gdouble
) plg
->plot_box
.height
/
216 (gdouble
) plg
->y_range
.i_max_scale
)));
218 gdk_draw_arc (plg
->pixmap
, plg
->series_gc
, TRUE
,
219 point_pos
[0].x
- 1, point_pos
[0].y
- 2, 3, 3, 0, 360 * 64);
223 for (v_index
= 0; v_index
< psd
->i_point_count
; v_index
++)
225 point_pos
[v_index
].x
= plg
->plot_box
.x
+ (v_index
* plg
->x_range
.i_minor_inc
);
226 point_pos
[v_index
].y
= (plg
->plot_box
.y
+ plg
->plot_box
.height
) -
227 ((psd
->lg_point_dvalue
[v_index
] *
228 (gdouble
) ((gdouble
) plg
->plot_box
.height
/
229 (gdouble
) plg
->y_range
.i_max_scale
)));
231 if ((v_index
!= 0) && (v_index
< psd
->i_point_count
- 1))
233 gdk_draw_arc (plg
->pixmap
, plg
->series_gc
, TRUE
,
234 point_pos
[v_index
].x
- 1,
235 point_pos
[v_index
].y
- 2, 3, 3, 0, 360 * 64);
236 gdk_draw_arc (plg
->pixmap
, plg
->series_gc
, FALSE
,
237 point_pos
[v_index
].x
- 1,
238 point_pos
[v_index
].y
- 2, 3, 3, 0, 360 * 64);
242 gdk_draw_lines (plg
->pixmap
, plg
->series_gc
, point_pos
, psd
->i_point_count
);
248 * Draws all data series points to chart
249 * returns number of series processed, or -1 if not drawable
251 static gint
lg_graph_data_series_draw_all (PLGRAPH plg
, gboolean redraw_control
)
253 PLG_SERIES psd
= NULL
;
254 GList
*data_sets
= NULL
;
257 g_return_val_if_fail (plg
!= NULL
, -1);
259 if ( !(GTK_WIDGET_DRAWABLE (plg
->drawing_area
)) ) {
263 data_sets
= g_list_first (plg
->lg_series
);
266 psd
= data_sets
->data
;
269 lg_graph_data_series_draw (plg
, psd
);
272 data_sets
= g_list_next (data_sets
);
277 g_print ("DrawAllDataSeries: series=%d\n", v_index
);
284 * Add a single value to the requested data series
285 * auto indexes the value is max is reach (appends to the end)
287 static gboolean
lg_graph_data_series_add_value (PLGRAPH plg
, gint i_series_number
,
290 PLG_SERIES psd
= NULL
;
291 GList
*data_sets
= NULL
;
292 gint v_index
= 0, time_count
= 0;
293 gboolean b_found
= FALSE
;
295 g_return_val_if_fail (plg
!= NULL
, FALSE
);
297 data_sets
= g_list_first (plg
->lg_series
);
300 psd
= data_sets
->data
;
301 if (psd
->i_series_id
== i_series_number
)
306 data_sets
= g_list_next (data_sets
);
311 g_message ("lg_graph_data_series_add_value(%d): Invalid data series number",
316 if (y_value
>= plg
->y_range
.i_max_scale
)
318 y_value
= (gdouble
) plg
->y_range
.i_max_scale
* 0.98;
321 if (psd
->i_point_count
== psd
->i_max_points
+ 1)
323 for (v_index
= 0; v_index
< psd
->i_max_points
; v_index
++)
325 psd
->lg_point_dvalue
[v_index
] = psd
->lg_point_dvalue
[v_index
+ 1];
327 psd
->lg_point_dvalue
[psd
->i_max_points
] = y_value
;
331 psd
->lg_point_dvalue
[psd
->i_point_count
++] = y_value
;
334 psd
->d_max_value
= MAX (y_value
, psd
->d_max_value
);
335 psd
->d_min_value
= MIN (y_value
, psd
->d_min_value
);
337 plg
->i_points_available
= MAX (plg
->i_points_available
, psd
->i_point_count
);
339 /* record current time with data points */
340 if (psd
->i_series_id
== plg
->i_num_series
- 1)
342 GList
*gl_remove
= NULL
;
344 gl_remove
= g_list_first (plg
->lg_series_time
);
346 time_count
= g_list_length (plg
->lg_series_time
);
347 if (time_count
== psd
->i_max_points
+ 1)
349 plg
->lg_series_time
=
350 g_list_remove_all (plg
->lg_series_time
, gl_remove
->data
);
352 plg
->lg_series_time
=
353 g_list_append (plg
->lg_series_time
, GINT_TO_POINTER ((time_t) time (NULL
)));
359 ("DataSeriesAddValue: series=%d, value=%3.1f, index=%d, count=%d, time_count=%d, max_pts=%d\n",
360 i_series_number
, y_value
, v_index
, psd
->i_point_count
, time_count
, psd
->i_max_points
);
368 * destroys all the data series and any assocaited dynamic data
370 static gboolean
lg_graph_data_series_remove_all (PLGRAPH plg
)
372 PLG_SERIES psd
= NULL
;
373 GList
*data_sets
= NULL
;
376 g_return_val_if_fail (plg
!= NULL
, FALSE
);
378 data_sets
= g_list_first (plg
->lg_series
);
381 psd
= data_sets
->data
;
382 g_free (psd
->lg_point_dvalue
);
383 g_free (psd
->point_pos
);
385 data_sets
= g_list_next (data_sets
);
388 g_list_free (plg
->lg_series
);
389 g_list_free (plg
->lg_series_time
);
390 plg
->lg_series
= NULL
;
391 plg
->lg_series_time
= NULL
;
392 plg
->i_num_series
= 0;
393 plg
->i_points_available
= 0;
397 g_print ("DataSeriesRemoveAll: series total=%d\n", i_count
);
404 * allocates space for another data series
405 * returns the series number of this dataset
407 static gint
lg_graph_data_series_add (PLGRAPH plg
, gchar
* pch_legend_text
,
408 gchar
* pch_color_text
)
410 PLG_SERIES psd
= NULL
;
412 g_return_val_if_fail (plg
!= NULL
, -1);
413 g_return_val_if_fail (pch_legend_text
!= NULL
, -1);
414 g_return_val_if_fail (pch_color_text
!= NULL
, -1);
416 psd
= (PLG_SERIES
) g_new0 (LG_SERIES
, 1);
417 g_return_val_if_fail (psd
!= NULL
, -1);
419 psd
->lg_point_dvalue
= (gdouble
*) g_new0 (gdouble
, (plg
->x_range
.i_max_scale
+ 4));
420 g_return_val_if_fail (psd
->lg_point_dvalue
!= NULL
, -1);
422 psd
->point_pos
= g_new0 (GdkPoint
, (plg
->x_range
.i_max_scale
+ 4));
423 g_return_val_if_fail (psd
->point_pos
!= NULL
, -1);
425 g_snprintf (psd
->ch_legend_text
, sizeof (psd
->ch_legend_text
), "%s", pch_legend_text
);
426 psd
->i_max_points
= plg
->x_range
.i_max_scale
;
427 gdk_color_parse (pch_color_text
, &psd
->legend_color
);
428 g_snprintf (psd
->ch_legend_color
, sizeof (psd
->ch_legend_color
), "%s",
430 psd
->cb_id
= CB_SERIES_ID
;
432 plg
->lg_series
= g_list_append (plg
->lg_series
, psd
);
433 psd
->i_series_id
= plg
->i_num_series
++;
437 g_print ("DataSeriesAdd: series=%d, max_pts=%d\n",
438 psd
->i_series_id
, psd
->i_max_points
);
441 return psd
->i_series_id
;
445 * Set the bottom x label text
447 static void lg_graph_set_x_label_text (PLGRAPH plg
, gchar
* pch_text
)
449 g_return_if_fail (plg
!= NULL
);
451 if (plg
->x_label_text
!= NULL
)
453 g_free (plg
->x_label_text
);
455 plg
->x_label_text
= g_strdup (pch_text
);
457 static void lg_graph_set_y_label_text (PLGRAPH plg
, gchar
* pch_text
)
459 g_return_if_fail (plg
!= NULL
);
461 if (plg
->y_label_text
!= NULL
)
463 g_free (plg
->y_label_text
);
465 plg
->y_label_text
= g_strdup (pch_text
);
467 static void lg_graph_set_chart_title (PLGRAPH plg
, gchar
* pch_text
)
469 g_return_if_fail (plg
!= NULL
);
471 if (plg
->x_title_text
!= NULL
)
473 g_free (plg
->x_title_text
);
475 plg
->x_title_text
= g_strdup (pch_text
);
477 static void lg_graph_set_chart_window_bg_color (PLGRAPH plg
, gchar
* pch_color
)
479 g_return_if_fail (plg
!= NULL
);
480 g_snprintf (plg
->ch_color_window_bg
, sizeof (plg
->ch_color_window_bg
),
483 static void lg_graph_set_chart_window_fg_color (PLGRAPH plg
, gchar
* pch_color
)
485 g_return_if_fail (plg
!= NULL
);
486 g_snprintf (plg
->ch_color_chart_bg
, sizeof (plg
->ch_color_chart_bg
), "%s", pch_color
);
488 static void lg_graph_set_chart_scales_color (PLGRAPH plg
, gchar
* pch_color
)
490 g_return_if_fail (plg
!= NULL
);
491 g_snprintf (plg
->ch_color_scale_fg
, sizeof (plg
->ch_color_scale_fg
), "%s", pch_color
);
493 static void lg_graph_set_chart_title_color (PLGRAPH plg
, gchar
* pch_color
)
495 g_return_if_fail (plg
!= NULL
);
496 g_snprintf (plg
->ch_color_title_fg
, sizeof (plg
->ch_color_title_fg
), "%s", pch_color
);
498 static void lg_graph_redraw (PLGRAPH plg
)
500 GdkRectangle update_rect
;
501 GdkRegion
*region
= NULL
;
503 g_return_if_fail (plg
!= NULL
);
507 update_rect
.width
= plg
->drawing_area
->allocation
.width
;
508 update_rect
.height
= plg
->drawing_area
->allocation
.height
;
510 /* --- And then draw it (calls expose event) --- */
511 region
= gdk_region_rectangle (&update_rect
);
512 gdk_window_invalidate_region (plg
->drawing_area
->window
, region
, FALSE
);
513 gdk_region_destroy (region
);
517 * Toggle the legend function on off
518 * "button-press-event"
520 static gboolean
lg_graph_button_press_event_cb (GtkWidget
* widget
,
521 GdkEventButton
* ev
, PLGRAPH plg
)
523 g_return_val_if_fail (plg
!= NULL
, FALSE
);
525 if ((ev
->type
& GDK_BUTTON_PRESS
) && (ev
->button
== 1))
527 plg
->b_tooltip_active
= plg
->b_tooltip_active
? FALSE
: TRUE
;
528 lg_graph_redraw (plg
);
531 if ((ev
->type
& GDK_BUTTON_PRESS
) && (ev
->button
== 2) && plg
->b_mouse_onoff
)
533 lg_graph_debug
= lg_graph_debug
? FALSE
: TRUE
;
537 if ((ev
->type
& GDK_BUTTON_PRESS
) && (ev
->button
== 3))
539 plg
->b_mouse_onoff
= plg
->b_mouse_onoff
? FALSE
: TRUE
;
547 * Track the mouse pointer position
548 * "motion-notify-event"
550 static gboolean
lg_graph_motion_notify_event_cb (GtkWidget
* widget
,
551 GdkEventMotion
* ev
, PLGRAPH plg
)
553 GdkModifierType state
;
556 g_return_val_if_fail (plg
!= NULL
, FALSE
);
560 gdk_window_get_pointer (ev
->window
, &x
, &y
, &state
);
569 plg
->mouse_pos
.x
= x
;
570 plg
->mouse_pos
.y
= y
;
571 plg
->mouse_state
= state
;
573 if ( lg_graph_draw_tooltip (plg
) ) {
574 lg_graph_redraw (plg
);
579 g_print ("mouse is at x=%d, y=%d, with a state of %d\n", x
, y
, state
);
586 * Draw the chart x scale legend
588 static void lg_graph_draw_x_grid_labels (PLGRAPH plg
)
590 gchar ch_grid_label
[GAPC_MAX_BUFFER
];
591 gchar ch_work
[GAPC_MAX_BUFFER
];
592 PangoLayout
*layout
= NULL
;
593 PangoTabArray
*p_tabs
= NULL
;
594 gint x_adj
= 0, x1_adj
= 0, width
= 0, height
= 0, h_index
= 0, x_scale
= 0;
596 g_return_if_fail (plg
!= NULL
);
598 g_snprintf (ch_grid_label
, GAPC_MAX_BUFFER
, "<small>%d</small>",
599 plg
->x_range
.i_max_scale
);
600 layout
= gtk_widget_create_pango_layout (plg
->drawing_area
, ch_grid_label
);
602 pango_layout_set_markup (layout
, ch_grid_label
, -1);
603 pango_layout_get_pixel_size (layout
, &width
, &height
);
607 g_snprintf (ch_grid_label
, GAPC_MAX_BUFFER
, "<small>%s", "0");
608 for (h_index
= plg
->x_range
.i_inc_major_scale_by
;
609 h_index
<= plg
->x_range
.i_max_scale
;
610 h_index
+= plg
->x_range
.i_inc_major_scale_by
)
612 g_strlcpy (ch_work
, ch_grid_label
, GAPC_MAX_BUFFER
);
613 g_snprintf (ch_grid_label
, GAPC_MAX_BUFFER
, "%s\t%d", ch_work
, h_index
);
619 g_strlcpy (ch_work
, ch_grid_label
, GAPC_MAX_BUFFER
);
620 g_snprintf (ch_grid_label
, GAPC_MAX_BUFFER
, "%s</small>", ch_work
);
622 pango_layout_set_markup (layout
, ch_grid_label
, -1);
626 g_print ("(%d:%d:%d)x_Labels=[%s]\n", x_adj
, x1_adj
, x_scale
, ch_grid_label
);
629 p_tabs
= pango_tab_array_new (plg
->x_range
.i_num_major
, TRUE
);
630 for (h_index
= 0; h_index
<= plg
->x_range
.i_num_major
; h_index
++)
634 if (h_index
> x_scale
)
636 xbase
= (h_index
* plg
->x_range
.i_major_inc
);
640 xbase
= (h_index
* plg
->x_range
.i_major_inc
) + x1_adj
;
644 xbase
= plg
->x_range
.i_major_inc
+ x1_adj
;
646 pango_tab_array_set_tab (p_tabs
, h_index
, PANGO_TAB_LEFT
, xbase
);
648 pango_layout_set_tabs (layout
, p_tabs
);
650 pango_layout_context_changed (layout
);
652 gdk_draw_layout (plg
->pixmap
,
654 plg
->plot_box
.x
- x_adj
,
655 plg
->plot_box
.y
+ plg
->plot_box
.height
, layout
);
657 pango_tab_array_free (p_tabs
);
658 g_object_unref (layout
);
664 * Draw the chart y scale legend
666 static void lg_graph_draw_y_grid_labels (PLGRAPH plg
)
668 gchar ch_grid_label
[GAPC_MAX_BUFFER
];
669 gchar ch_work
[GAPC_MAX_BUFFER
];
670 PangoLayout
*layout
= NULL
;
671 gint y_adj
= 0, width
= 0, height
= 0, v_index
= 0;
673 g_return_if_fail (plg
!= NULL
);
675 g_snprintf (ch_grid_label
, GAPC_MAX_BUFFER
, "<small>%d</small>",
676 plg
->y_range
.i_max_scale
);
677 layout
= gtk_widget_create_pango_layout (plg
->drawing_area
, ch_grid_label
);
679 pango_layout_set_markup (layout
, ch_grid_label
, -1);
680 pango_layout_get_pixel_size (layout
, &width
, &height
);
683 g_snprintf (ch_grid_label
, GAPC_MAX_BUFFER
, "<small>%d", plg
->y_range
.i_max_scale
);
685 plg
->y_range
.i_max_scale
- plg
->y_range
.i_inc_major_scale_by
;
686 v_index
> 0; v_index
-= plg
->y_range
.i_inc_major_scale_by
)
688 g_strlcpy (ch_work
, ch_grid_label
, GAPC_MAX_BUFFER
);
689 g_snprintf (ch_grid_label
, GAPC_MAX_BUFFER
, "%s\n%d", ch_work
, v_index
);
691 g_strlcpy (ch_work
, ch_grid_label
, GAPC_MAX_BUFFER
);
692 g_snprintf (ch_grid_label
, GAPC_MAX_BUFFER
, "%s</small>", ch_work
);
694 pango_layout_set_spacing (layout
,
695 ((plg
->y_range
.i_major_inc
- height
) * PANGO_SCALE
));
696 pango_layout_set_alignment (layout
, PANGO_ALIGN_RIGHT
);
697 pango_layout_set_markup (layout
, ch_grid_label
, -1);
701 g_print ("(%d:%d)y_Labels=[%s]\n", y_adj
, plg
->y_range
.i_major_inc
,
705 pango_layout_context_changed (layout
);
707 gdk_draw_layout (plg
->pixmap
,
709 plg
->plot_box
.x
- (width
* 1.2), plg
->plot_box
.y
- y_adj
, layout
);
711 g_object_unref (layout
);
717 * Draws the minor and major grid lines inside the current plot_area
718 * returns -1 on error, or TRUE;
720 static gint
lg_graph_draw_grid_lines (PLGRAPH plg
)
722 GtkWidget
*drawing_area
= NULL
;
723 gint y_minor_inc
= 0, y_pos
= 0, y_index
= 0;
724 gint y_major_inc
= 0;
725 gint x_minor_inc
= 0, x_pos
= 0, x_index
= 0;
726 gint x_major_inc
= 0;
727 gint count_major
= 0, count_minor
= 0;
728 GdkSegment
*seg_minor
= NULL
;
729 GdkSegment
*seg_major
= NULL
;
731 g_return_val_if_fail (plg
!= NULL
, -1);
732 g_return_val_if_fail (GTK_WIDGET_DRAWABLE (plg
->drawing_area
), -1);
734 drawing_area
= plg
->drawing_area
;
736 count_major
= plg
->y_range
.i_num_major
;
737 count_minor
= plg
->y_range
.i_num_minor
;
738 y_minor_inc
= plg
->y_range
.i_minor_inc
;
739 y_major_inc
= plg
->y_range
.i_major_inc
;
744 ("count_major=%d, count_minor=%d, y_minor_inc=%d, y_major_inc=%d\n",
745 count_major
, count_minor
, y_minor_inc
, y_major_inc
);
748 seg_minor
= g_new0 (GdkSegment
, count_minor
+ 8);
749 seg_major
= g_new0 (GdkSegment
, count_major
+ 8);
750 x_pos
= plg
->plot_box
.width
;
751 y_pos
= plg
->plot_box
.y
;
752 for (y_index
= 0; y_index
< count_minor
; y_index
++)
754 seg_minor
[y_index
].x1
= plg
->plot_box
.x
;
755 seg_minor
[y_index
].y1
= y_pos
+ (y_minor_inc
* (y_index
+ 1));
756 seg_minor
[y_index
].x2
= plg
->plot_box
.x
+ x_pos
- 2;
757 seg_minor
[y_index
].y2
= seg_minor
[y_index
].y1
;
760 x_pos
= plg
->plot_box
.width
;
761 y_pos
= plg
->plot_box
.y
;
762 for (y_index
= 0; y_index
< count_major
; y_index
++)
764 seg_major
[y_index
].x1
= plg
->plot_box
.x
;
765 seg_major
[y_index
].y1
= y_pos
+ (y_major_inc
* (y_index
+ 1));
766 seg_major
[y_index
].x2
= plg
->plot_box
.x
+ x_pos
- 2;
767 seg_major
[y_index
].y2
= seg_major
[y_index
].y1
;
770 gdk_gc_set_line_attributes (plg
->window_gc
,
771 1, GDK_LINE_SOLID
, GDK_CAP_BUTT
, GDK_JOIN_BEVEL
);
772 gdk_draw_segments (plg
->pixmap
, plg
->window_gc
, seg_minor
, count_minor
- 1);
774 gdk_gc_set_line_attributes (plg
->window_gc
,
775 2, GDK_LINE_SOLID
, GDK_CAP_ROUND
, GDK_JOIN_BEVEL
);
776 gdk_draw_segments (plg
->pixmap
, plg
->window_gc
, seg_major
, count_major
- 1);
781 count_major
= plg
->x_range
.i_num_major
;
782 count_minor
= plg
->x_range
.i_num_minor
;
783 x_minor_inc
= plg
->x_range
.i_minor_inc
;
784 x_major_inc
= plg
->x_range
.i_major_inc
;
789 ("count_major=%d, count_minor=%d, x_minor_inc=%d, x_major_inc=%d\n",
790 count_major
, count_minor
, x_minor_inc
, x_major_inc
);
793 seg_minor
= g_new0 (GdkSegment
, count_minor
+ 8);
794 seg_major
= g_new0 (GdkSegment
, count_major
+ 8);
795 x_pos
= plg
->plot_box
.x
;
796 y_pos
= plg
->plot_box
.height
;
797 for (x_index
= 0; x_index
< count_minor
; x_index
++)
799 seg_minor
[x_index
].x1
= plg
->plot_box
.x
+ (x_minor_inc
* (x_index
+ 1));
800 seg_minor
[x_index
].y1
= plg
->plot_box
.y
+ 2;
801 seg_minor
[x_index
].x2
= seg_minor
[x_index
].x1
;
802 seg_minor
[x_index
].y2
= plg
->plot_box
.y
+ y_pos
;
805 x_pos
= plg
->plot_box
.x
;
806 y_pos
= plg
->plot_box
.height
;
807 for (x_index
= 0; x_index
< count_major
; x_index
++)
809 seg_major
[x_index
].x1
= plg
->plot_box
.x
+ (x_major_inc
* (x_index
+ 1));
810 seg_major
[x_index
].y1
= plg
->plot_box
.y
+ 2;
811 seg_major
[x_index
].x2
= seg_major
[x_index
].x1
;
812 seg_major
[x_index
].y2
= plg
->plot_box
.y
+ y_pos
;
815 gdk_gc_set_line_attributes (plg
->window_gc
,
816 1, GDK_LINE_SOLID
, GDK_CAP_BUTT
, GDK_JOIN_BEVEL
);
817 gdk_draw_segments (plg
->pixmap
, plg
->window_gc
, seg_minor
, count_minor
- 1);
819 gdk_gc_set_line_attributes (plg
->window_gc
,
820 2, GDK_LINE_SOLID
, GDK_CAP_ROUND
, GDK_JOIN_BEVEL
);
821 gdk_draw_segments (plg
->pixmap
, plg
->window_gc
, seg_major
, count_major
- 1);
830 * Draws the tooltip legend message at top or bottom of chart
831 * returns the width of the text area, or -1 on error
832 * requires plg->b_tooltip_active to be TRUE, (toggled by mouse)
834 static gint
lg_graph_draw_tooltip (PLGRAPH plg
)
836 PangoLayout
*layout
= NULL
;
837 gint x_pos
= 0, y_pos
= 0, width
= 0, height
= 0;
838 gint v_index
= 0, x_adj
= 0;
839 PLG_SERIES psd
= NULL
;
840 GList
*data_sets
= NULL
;
841 GdkRegion
*region
= NULL
;
842 gboolean b_found
= FALSE
;
844 g_return_val_if_fail (plg
!= NULL
, -1);
845 g_return_val_if_fail (GTK_WIDGET_DRAWABLE (plg
->drawing_area
), -1);
847 if (!plg
->b_tooltip_active
)
851 if (plg
->i_points_available
< 1) {
856 * Create tooltip if needed */
857 region
= gdk_region_rectangle (&plg
->plot_box
);
858 x_adj
= (plg
->x_range
.i_minor_inc
/ plg
->x_range
.i_inc_minor_scale_by
);
861 * see if ptr is at a x-range point */
862 if (!gdk_region_point_in (region
, plg
->mouse_pos
.x
, plg
->mouse_pos
.y
))
864 gdk_region_destroy (region
);
867 gdk_region_destroy (region
);
869 for (v_index
= 0; v_index
<= plg
->x_range
.i_max_scale
; v_index
++)
871 x_pos
= plg
->plot_box
.x
+ (v_index
* x_adj
);
872 if ((plg
->mouse_pos
.x
> (x_pos
- (x_adj
/ 3))) &&
873 (plg
->mouse_pos
.x
< (x_pos
+ (x_adj
/ 3))))
875 if (v_index
< plg
->i_points_available
)
884 * All we needed was x, so now post a tooltip */
887 gchar ch_buffer
[GAPC_MAX_BUFFER
];
888 gchar ch_work
[GAPC_MAX_BUFFER
];
889 gchar ch_time_r
[GAPC_MAX_TEXT
];
890 gchar
*pch_time
= NULL
;
893 point_time
= (time_t) g_list_nth_data (plg
->lg_series_time
, v_index
);
895 pch_time
= ctime_r (&point_time
, ch_time_r
);
897 g_strdelimit (pch_time
, "\n", ' ');
899 g_snprintf (ch_buffer
, sizeof (ch_buffer
),
900 "<small>{ <u>sample #%d @ %s</u>}\n", v_index
, pch_time
);
901 data_sets
= g_list_first (plg
->lg_series
);
904 psd
= data_sets
->data
;
907 g_snprintf (ch_work
, sizeof (ch_work
), "%s", ch_buffer
);
908 g_snprintf (ch_buffer
, sizeof (ch_buffer
),
909 "%s{%3.0f%% <span foreground=\"%s\">%s</span>}",
911 psd
->lg_point_dvalue
[v_index
],
912 psd
->ch_legend_color
, psd
->ch_legend_text
);
914 data_sets
= g_list_next (data_sets
);
917 g_snprintf (ch_work
, sizeof (ch_work
), "%s", ch_buffer
);
918 g_snprintf (ch_buffer
, sizeof (ch_buffer
), "%s</small>", ch_work
);
919 g_snprintf (plg
->ch_tooltip_text
, sizeof (plg
->ch_tooltip_text
), "%s",
928 layout
= gtk_widget_create_pango_layout (plg
->drawing_area
, plg
->ch_tooltip_text
);
929 pango_layout_set_alignment (layout
, PANGO_ALIGN_CENTER
);
931 pango_layout_set_markup (layout
, plg
->ch_tooltip_text
, -1);
933 pango_layout_get_pixel_size (layout
, &width
, &height
);
935 x_pos
= plg
->x_tooltip
.x
+ ((plg
->x_tooltip
.width
- width
) / 2);
936 y_pos
= plg
->x_tooltip
.y
+ ((plg
->x_tooltip
.height
- height
) / 2);
938 gdk_draw_rectangle (plg
->pixmap
, plg
->window_gc
, /* box_gc, */
941 plg
->x_tooltip
.y
, plg
->x_tooltip
.width
, plg
->x_tooltip
.height
);
942 gdk_draw_rectangle (plg
->pixmap
, plg
->box_gc
,
945 plg
->x_tooltip
.y
, plg
->x_tooltip
.width
, plg
->x_tooltip
.height
);
947 gdk_draw_layout (plg
->pixmap
, plg
->scale_gc
, x_pos
, y_pos
, layout
);
949 g_object_unref (layout
);
953 g_print ("DrawToolTip: x=%d, y=%d Width=%d, Height=%d, Text=%s\n",
954 x_pos
, y_pos
, width
, height
, plg
->ch_tooltip_text
);
960 #if GTK_CHECK_VERSION(2,6,0)
962 * Draws a label text on the Y axis
963 * sets the width, height values of the input rectangle to the size of textbox
964 * returns the height of the text area, or -1 on error
966 static gint
lg_graph_draw_vertical_text (PLGRAPH plg
,
968 GdkRectangle
* rect
, gboolean redraw_control
)
970 PangoRenderer
*renderer
= NULL
;
971 PangoMatrix matrix
= PANGO_MATRIX_INIT
;
972 PangoContext
*context
= NULL
;
973 PangoLayout
*layout
= NULL
;
976 g_return_val_if_fail (plg
!= NULL
, -1);
977 g_return_val_if_fail (pch_text
!= NULL
, -1);
978 g_return_val_if_fail (rect
!= NULL
, -1);
979 g_return_val_if_fail (GTK_WIDGET_DRAWABLE (plg
->drawing_area
), -1);
981 if (rect
->width
&& redraw_control
)
983 gdk_draw_rectangle (plg
->pixmap
, plg
->window_gc
,
984 TRUE
, rect
->x
, rect
->y
, rect
->width
, rect
->height
);
987 /* Get the default renderer for the screen, and set it up for drawing */
988 renderer
= gdk_pango_renderer_get_default (gtk_widget_get_screen (plg
->drawing_area
));
989 gdk_pango_renderer_set_drawable (GDK_PANGO_RENDERER (renderer
), plg
->pixmap
);
990 gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (renderer
), plg
->title_gc
);
992 context
= gtk_widget_get_pango_context (plg
->drawing_area
);
994 layout
= pango_layout_new (context
);
995 pango_layout_set_markup (layout
, pch_text
, -1);
997 pango_matrix_rotate (&matrix
, 90.0);
998 pango_context_set_matrix (context
, &matrix
);
1000 pango_layout_context_changed (layout
);
1002 /* xy switched due to rotate func */
1003 pango_layout_get_pixel_size (layout
, &rect
->height
, &rect
->width
);
1004 y_pos
= rect
->y
+ ((plg
->plot_box
.height
- rect
->height
) / 2);
1006 gdk_draw_layout (plg
->pixmap
, plg
->title_gc
, rect
->x
, y_pos
, layout
);
1008 /* Clean up default renderer, since it is shared */
1009 gdk_pango_renderer_set_drawable (GDK_PANGO_RENDERER (renderer
), NULL
);
1010 gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (renderer
), NULL
);
1011 pango_context_set_matrix (context
, NULL
);
1013 /* free the objects we created */
1014 g_object_unref (layout
);
1018 g_print ("Vertical Label: x=%d, y=%d Width=%d, Height=%d Text:%s\n",
1019 rect
->x
, rect
->y
, rect
->width
, rect
->height
, pch_text
);
1024 GdkRegion
*region
= NULL
;
1026 region
= gdk_region_rectangle (rect
);
1027 gdk_window_invalidate_region (plg
->drawing_area
->window
, region
, FALSE
);
1028 gdk_region_destroy (region
);
1031 return rect
->height
;
1034 static gint
lg_graph_draw_vertical_text (PLGRAPH plg
,
1036 GdkRectangle
* rect
, gboolean redraw_control
)
1038 PangoContext
*context
= NULL
;
1039 PangoLayout
*layout
= NULL
;
1041 GdkPixmap
*norm_pixmap
= NULL
;
1043 gint rot_width
, rot_height
;
1044 GdkPixbuf
*norm_pixbuf
= NULL
, *rot_pixbuf
= NULL
;
1045 guint32
*norm_pix
, *rot_pix
;
1048 g_return_val_if_fail (plg
!= NULL
, -1);
1049 g_return_val_if_fail (pch_text
!= NULL
, -1);
1050 g_return_val_if_fail (rect
!= NULL
, -1);
1051 g_return_val_if_fail (GTK_WIDGET_DRAWABLE (plg
->drawing_area
), -1);
1054 context
= gtk_widget_get_pango_context (plg
->drawing_area
);
1055 layout
= pango_layout_new (context
);
1056 pango_layout_set_markup (layout
, pch_text
, -1);
1057 pango_layout_get_pixel_size (layout
, &width
, &height
);
1058 if (width
<= 0 || height
<= 0)
1063 /* Figure out the rotated width and height */
1064 rect
->width
= rot_width
= height
;
1065 rect
->height
= rot_height
= width
;
1067 norm_pixmap
= gdk_pixmap_new (plg
->drawing_area
->window
, width
, height
, -1);
1068 gdk_draw_rectangle (norm_pixmap
, plg
->window_gc
, TRUE
, 0, 0, width
, height
);
1069 gdk_draw_layout (norm_pixmap
, plg
->title_gc
, 0, 0, layout
);
1071 norm_pixbuf
= gdk_pixbuf_new (GDK_COLORSPACE_RGB
, TRUE
, 8, width
, height
);
1072 norm_pixbuf
= gdk_pixbuf_get_from_drawable (norm_pixbuf
, norm_pixmap
, NULL
,
1073 0, 0, 0, 0, width
, height
);
1075 /* Get the raw pixel pointer of client buffer */
1076 norm_pix
= (guint32
*) gdk_pixbuf_get_pixels (norm_pixbuf
);
1078 /* Allocate a new client buffer with rotated memory */
1079 rot_pixbuf
= gdk_pixbuf_new (GDK_COLORSPACE_RGB
, TRUE
, 8, rot_width
, rot_height
);
1080 rot_pix
= (guint32
*) gdk_pixbuf_get_pixels (rot_pixbuf
);
1082 /* Actually rotate */
1084 for (j
= width
- 1; j
>= 0; j
--)
1087 for (i
= 0; i
< height
; i
++, k
++, l
+= width
)
1089 rot_pix
[k
] = norm_pix
[l
];
1093 /* compute a centered position on chart */
1094 y_pos
= rect
->y
+ ((plg
->plot_box
.height
- rect
->height
) / 2);
1096 /* Draw it to the chart */
1097 gdk_pixbuf_render_to_drawable ( rot_pixbuf
,
1102 rect
->width
, rect
->height
,
1103 GDK_RGB_DITHER_NONE
, 0, 0);
1105 /* Free everything */
1106 g_object_unref (layout
);
1107 g_object_unref (G_OBJECT (norm_pixmap
));
1108 g_object_unref (G_OBJECT (norm_pixbuf
));
1109 g_object_unref (G_OBJECT (rot_pixbuf
));
1112 return rect
->height
;
1117 * Draws a label text on the X axis
1118 * sets the width, height values of the input rectangle to the size of textbox
1119 * returns the width of the text area, or -1 on error
1120 * redraw_control = 1 causes an expose_event, 0 or != 1 does not
1122 static gint
lg_graph_draw_horizontal_text (PLGRAPH plg
,
1124 GdkRectangle
* rect
, gboolean redraw_control
)
1126 PangoLayout
*layout
= NULL
;
1129 g_return_val_if_fail (plg
!= NULL
, -1);
1130 g_return_val_if_fail (pch_text
!= NULL
, -1);
1131 g_return_val_if_fail (rect
!= NULL
, -1);
1132 g_return_val_if_fail (GTK_WIDGET_DRAWABLE (plg
->drawing_area
), -1);
1134 if (rect
->width
&& redraw_control
)
1136 gdk_draw_rectangle (plg
->pixmap
, plg
->window_gc
,
1137 TRUE
, rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1140 layout
= gtk_widget_create_pango_layout (plg
->drawing_area
, pch_text
);
1141 pango_layout_set_markup (layout
, pch_text
, -1);
1142 pango_layout_set_alignment (layout
, PANGO_ALIGN_CENTER
);
1144 pango_layout_get_pixel_size (layout
, &rect
->width
, &rect
->height
);
1145 x_pos
= rect
->x
+ ((plg
->plot_box
.width
- rect
->width
) / 2);
1147 gdk_draw_layout (plg
->pixmap
, plg
->title_gc
, x_pos
, rect
->y
, layout
);
1149 g_object_unref (layout
);
1153 g_print ("Horizontal Label: x=%d, y=%d Width=%d, Height=%d Text:%s\n",
1154 x_pos
, rect
->y
, rect
->width
, rect
->height
, pch_text
);
1160 GdkRegion
*region
= NULL
;
1162 region
= gdk_region_rectangle (rect
);
1163 gdk_window_invalidate_region (plg
->drawing_area
->window
, region
, FALSE
);
1164 gdk_region_destroy (region
);
1171 * Computes the size of 3 proportional charactor using default font
1173 static void lg_graph_get_default_sizes (PLGRAPH plg
, gint
* width
, gint
* height
)
1175 PangoLayout
*layout
= NULL
;
1177 g_return_if_fail (plg
!= NULL
);
1179 layout
= gtk_widget_create_pango_layout (plg
->drawing_area
, "1M5");
1181 pango_layout_set_markup (layout
, "<big><b>M5</b></big>", -1);
1183 pango_layout_get_pixel_size (layout
, width
, height
);
1185 g_object_unref (layout
);
1189 g_print ("Default Sizing(1M5): Width=%d, Height=%d\n", *width
, *height
);
1196 * Compute and set x-y ranges
1198 static void lg_graph_set_ranges (PLGRAPH plg
,
1203 gint yminor_by
, gint ymajor_by
, gint y_min
, gint y_max
)
1205 g_return_if_fail (plg
!= NULL
);
1207 plg
->x_range
.i_inc_minor_scale_by
= xminor_by
; /* minimum scale value - ex: 0 */
1208 plg
->x_range
.i_inc_major_scale_by
= xmajor_by
; /* minimum scale value - ex: 0 */
1210 plg
->x_range
.i_min_scale
= x_min
; /* minimum scale value - ex: 0 */
1211 plg
->x_range
.i_max_scale
= x_max
; /* maximum scale value - ex: 100 */
1212 plg
->x_range
.i_num_minor
= x_max
/ xminor_by
; /* number of minor points */
1213 plg
->x_range
.i_num_major
= x_max
/ xmajor_by
; /* number of major points */
1215 plg
->y_range
.i_inc_minor_scale_by
= yminor_by
; /* minimum scale value - ex: 0 */
1216 plg
->y_range
.i_inc_major_scale_by
= ymajor_by
; /* minimum scale value - ex: 0 */
1218 plg
->y_range
.i_min_scale
= y_min
; /* minimum scale value - ex: 0 */
1219 plg
->y_range
.i_max_scale
= y_max
; /* maximum scale value - ex: 100 */
1220 plg
->y_range
.i_num_minor
= y_max
/ yminor_by
; /* number of minor points */
1221 plg
->y_range
.i_num_major
= y_max
/ ymajor_by
; /* number of major points */
1229 * data - widget to repaint
1231 static gint
lg_graph_draw (PLGRAPH plg
)
1233 GtkWidget
*drawing_area
= NULL
;
1235 g_return_val_if_fail (plg
!= NULL
, TRUE
);
1237 drawing_area
= plg
->drawing_area
;
1239 if ( !(GTK_WIDGET_DRAWABLE (drawing_area
)) ) {
1244 * Clear the whole area
1246 gdk_draw_rectangle (plg
->pixmap
, plg
->window_gc
,
1248 plg
->drawing_area
->allocation
.width
,
1249 plg
->drawing_area
->allocation
.height
);
1254 gdk_draw_rectangle (plg
->pixmap
,
1258 plg
->plot_box
.y
, plg
->plot_box
.width
, plg
->plot_box
.height
);
1260 gdk_gc_set_line_attributes (plg
->drawing_area
->style
->black_gc
,
1261 2, GDK_LINE_SOLID
, GDK_CAP_BUTT
, GDK_JOIN_BEVEL
);
1262 gdk_draw_rectangle (plg
->pixmap
,
1263 plg
->drawing_area
->style
->black_gc
,
1266 plg
->plot_box
.y
, plg
->plot_box
.width
, plg
->plot_box
.height
);
1271 ("Window: Width=%d, Height=%d, Plot Area x=%d y=%d width=%d, height=%d\n",
1272 drawing_area
->allocation
.width
, drawing_area
->allocation
.height
,
1273 plg
->plot_box
.x
, plg
->plot_box
.y
, plg
->plot_box
.width
, plg
->plot_box
.height
);
1279 lg_graph_draw_horizontal_text (plg
, plg
->x_title_text
, &plg
->x_title
, FALSE
);
1281 lg_graph_draw_horizontal_text (plg
, plg
->x_label_text
, &plg
->x_label
, FALSE
);
1283 lg_graph_draw_vertical_text (plg
, plg
->y_label_text
, &plg
->y_label
, FALSE
);
1285 lg_graph_draw_grid_lines (plg
);
1287 lg_graph_draw_x_grid_labels (plg
);
1289 lg_graph_draw_y_grid_labels (plg
);
1291 lg_graph_data_series_draw_all (plg
, FALSE
);
1293 lg_graph_draw_tooltip (plg
);
1295 /* The entire pixmap is going to be copied
1296 * onto the window so the rect is configured
1297 * as the size of the window.
1299 lg_graph_redraw (plg
);
1307 * Create a new backing pixmap of the appropriate size
1308 * Of course, this is called whenever the window is
1309 * resized. We have to free up things we allocated.
1311 static gint
lg_graph_configure_event_cb (GtkWidget
* widget
,
1312 GdkEventConfigure
* event
, PLGRAPH plg
)
1314 GdkRectangle clip_area
;
1315 gint xfactor
= 0, yfactor
= 0;
1317 /* --- Free background if we created it --- */
1320 gdk_pixmap_unref (plg
->pixmap
);
1323 /* --- Create a new pixmap with new size --- */
1324 plg
->pixmap
= gdk_pixmap_new (widget
->window
,
1325 widget
->allocation
.width
,
1326 widget
->allocation
.height
, -1);
1328 gdk_draw_rectangle (plg
->pixmap
, plg
->window_gc
,
1329 TRUE
, 0, 0, widget
->allocation
.width
, widget
->allocation
.height
);
1331 plg
->width
= widget
->allocation
.width
;
1332 plg
->height
= widget
->allocation
.height
;
1336 clip_area
.width
= widget
->allocation
.width
;
1337 clip_area
.height
= widget
->allocation
.height
;
1339 xfactor
= MAX (plg
->x_range
.i_num_minor
, plg
->x_range
.i_num_major
);
1340 yfactor
= MAX (plg
->y_range
.i_num_minor
, plg
->y_range
.i_num_major
);
1342 lg_graph_get_default_sizes (plg
, &plg
->x_border
, &plg
->y_border
);
1346 plg
->x_label
.x
= plg
->x_border
* 6; /* define top-left corner of textbox */
1347 plg
->x_label
.y
= plg
->height
- (plg
->y_border
* 4) + 2;
1349 plg
->y_label
.x
= plg
->x_border
;
1350 plg
->y_label
.y
= plg
->y_border
* 6;
1352 plg
->x_title
.x
= plg
->x_border
* 6;
1353 plg
->x_title
.y
= 1; /* /plg->y_border ; */
1355 plg
->x_tooltip
.x
= plg
->x_border
;
1356 plg
->x_tooltip
.y
= plg
->y_border
;
1357 plg
->x_tooltip
.width
= plg
->width
- (plg
->x_border
* 2);
1358 plg
->x_tooltip
.height
= plg
->y_border
* 7;
1360 plg
->plot_box
.x
= plg
->x_border
* 6;
1361 plg
->plot_box
.y
= plg
->y_border
* 6;
1362 plg
->plot_box
.width
=
1363 ((gint
) (plg
->width
- (plg
->x_border
* 10)) / xfactor
) * xfactor
;
1364 plg
->plot_box
.height
=
1365 ((gint
) (plg
->height
- (plg
->y_border
* 14)) / yfactor
) * yfactor
;
1367 /* reposition the box according to scale-able increments */
1368 plg
->plot_box
.x
= (((gfloat
) (plg
->width
- plg
->plot_box
.width
) / 10.0) * 7) + 4;
1369 plg
->plot_box
.y
= (((gfloat
) (plg
->height
- plg
->plot_box
.height
) / 10.0) * 5) + 4;
1370 plg
->x_label
.x
= plg
->x_title
.x
= plg
->plot_box
.x
;
1371 plg
->y_label
.y
= plg
->plot_box
.y
;
1373 plg
->y_range
.i_minor_inc
= plg
->plot_box
.height
/ plg
->y_range
.i_num_minor
;
1374 plg
->y_range
.i_major_inc
= plg
->plot_box
.height
/ plg
->y_range
.i_num_major
;
1376 plg
->x_range
.i_minor_inc
= plg
->plot_box
.width
/ plg
->x_range
.i_num_minor
;
1377 plg
->x_range
.i_major_inc
= plg
->plot_box
.width
/ plg
->x_range
.i_num_major
;
1379 g_timeout_add (250, (GSourceFunc
) lg_graph_draw
, plg
);
1387 * When the window is exposed to the viewer or
1388 * the gdk_widget_draw routine is called, this
1389 * routine is called. Copies the background pixmap
1392 static gint
lg_graph_expose_event_cb (GtkWidget
* widget
, GdkEventExpose
* event
,
1396 g_return_val_if_fail (GDK_IS_DRAWABLE (widget
->window
), FALSE
);
1398 /* --- Copy pixmap to the window --- */
1399 gdk_draw_pixmap (widget
->window
,
1400 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
1402 event
->area
.x
, event
->area
.y
,
1403 event
->area
.x
, event
->area
.y
, event
->area
.width
, event
->area
.height
);
1408 static void cb_util_popup_menu_response_exit(GtkWidget
* widget
, gpointer gp
)
1410 PGAPC_CONFIG pcfg
= NULL
;
1411 PGAPC_MONITOR pm
= NULL
;
1412 gchar
*penabled
= NULL
;
1414 g_return_if_fail(gp
!= NULL
);
1416 if (((PGAPC_MONITOR
) gp
)->cb_id
== CB_MONITOR_ID
) {
1417 /* this is a monitor struct (2) */
1418 pm
= (PGAPC_MONITOR
) gp
;
1420 penabled
= g_strdup_printf(GAPC_ENABLE_KEY
, pm
->cb_monitor_num
);
1421 gconf_client_set_bool(pm
->client
, penabled
, FALSE
, NULL
);
1424 /* this is a config struct (1) */
1425 pcfg
= (PGAPC_CONFIG
) gp
;
1426 gtk_widget_destroy(GTK_WIDGET(pcfg
->window
));
1431 static void cb_util_popup_menu_response_jumpto(GtkWidget
* widget
, gpointer gp
)
1433 PGAPC_CONFIG pcfg
= NULL
;
1434 PGAPC_MONITOR pm
= NULL
;
1435 GtkWindow
*window
= NULL
;
1437 g_return_if_fail(gp
!= NULL
);
1439 if (((PGAPC_MONITOR
) gp
)->cb_id
== CB_MONITOR_ID
) {
1440 /* this is a monitor struct (2) */
1441 pm
= (PGAPC_MONITOR
) gp
;
1442 window
= GTK_WINDOW(pm
->window
);
1444 /* this is a config struct (1) */
1445 pcfg
= (PGAPC_CONFIG
) gp
;
1446 window
= GTK_WINDOW(pcfg
->window
);
1449 if (window
!= NULL
) {
1450 gtk_window_present(window
);
1457 * Change the color values back to their original defaults
1459 static void cb_panel_property_color_reset (GtkButton
*button
, PGAPC_CONFIG pcfg
)
1461 gchar
*pstring
= NULL
;
1463 g_return_if_fail (pcfg
!= NULL
);
1465 gdk_color_parse ("green", &pcfg
->color_linev
);
1466 pstring
= gtk_color_selection_palette_to_string ( &pcfg
->color_linev
, 1);
1467 if (pstring
!= NULL
) {
1468 gconf_client_set_string(pcfg
->client
, GAPC_COLOR_LINEV_KEY
, pstring
, NULL
);
1472 gdk_color_parse ("blue", &pcfg
->color_loadpct
);
1473 pstring
= gtk_color_selection_palette_to_string ( &pcfg
->color_loadpct
, 1);
1474 if (pstring
!= NULL
) {
1475 gconf_client_set_string(pcfg
->client
, GAPC_COLOR_LOADPCT_KEY
, pstring
, NULL
);
1479 gdk_color_parse ("red", &pcfg
->color_timeleft
);
1480 pstring
= gtk_color_selection_palette_to_string ( &pcfg
->color_timeleft
, 1);
1481 if (pstring
!= NULL
) {
1482 gconf_client_set_string(pcfg
->client
, GAPC_COLOR_TIMELEFT_KEY
, pstring
, NULL
);
1486 gdk_color_parse ("yellow", &pcfg
->color_bcharge
);
1487 pstring
= gtk_color_selection_palette_to_string ( &pcfg
->color_bcharge
, 1);
1488 if (pstring
!= NULL
) {
1489 gconf_client_set_string(pcfg
->client
, GAPC_COLOR_BCHARGE_KEY
, pstring
, NULL
);
1493 gdk_color_parse ("black", &pcfg
->color_battv
);
1494 pstring
= gtk_color_selection_palette_to_string ( &pcfg
->color_battv
, 1);
1495 if (pstring
!= NULL
) {
1496 gconf_client_set_string(pcfg
->client
, GAPC_COLOR_BATTV_KEY
, pstring
, NULL
);
1500 gdk_color_parse ("white", &pcfg
->color_window
);
1501 pstring
= gtk_color_selection_palette_to_string ( &pcfg
->color_window
, 1);
1502 if (pstring
!= NULL
) {
1503 gconf_client_set_string(pcfg
->client
, GAPC_COLOR_WINDOW_KEY
, pstring
, NULL
);
1507 gdk_color_parse ("light blue", &pcfg
->color_chart
);
1508 pstring
= gtk_color_selection_palette_to_string ( &pcfg
->color_chart
, 1);
1509 if (pstring
!= NULL
) {
1510 gconf_client_set_string(pcfg
->client
, GAPC_COLOR_CHART_KEY
, pstring
, NULL
);
1514 gdk_color_parse ("blue", &pcfg
->color_title
);
1515 pstring
= gtk_color_selection_palette_to_string ( &pcfg
->color_title
, 1);
1516 if (pstring
!= NULL
) {
1517 gconf_client_set_string(pcfg
->client
, GAPC_COLOR_TITLE_KEY
, pstring
, NULL
);
1524 * catch the color change signal and save its value into gconf
1526 static void cb_panel_property_color_change (GtkColorButton
*widget
, gchar
*color_key
)
1528 GConfClient
*client
= NULL
;
1530 gchar
*pstring
= NULL
;
1532 g_return_if_fail(GTK_IS_COLOR_BUTTON(widget
));
1533 g_return_if_fail(color_key
!= NULL
);
1535 gtk_color_button_get_color (GTK_COLOR_BUTTON(widget
), &color
);
1536 pstring
= gtk_color_selection_palette_to_string ( &color
, 1);
1537 if (pstring
== NULL
) {
1541 client
= (GConfClient
*)g_object_get_data (G_OBJECT(widget
), "gconf-client");
1542 if (client
!= NULL
) {
1543 gconf_client_set_string (client
, color_key
, pstring
, NULL
);
1551 * Changes the Applets icon if needed
1552 * returns FALSE if OK
1553 * return TRUE is any error
1555 static gint
gapc_util_change_icons(PGAPC_MONITOR pm
)
1557 GdkPixbuf
*pixbuf
= NULL
;
1558 GdkPixbuf
*scaled
= NULL
;
1559 GtkOrientation orientation
;
1562 g_return_val_if_fail(pm
!= NULL
, TRUE
);
1564 if (pm
->i_icon_index
>= GAPC_N_ICONS
) {
1565 pm
->i_icon_index
= GAPC_ICON_ONLINE
;
1568 pixbuf
= pm
->my_icons
[pm
->i_icon_index
];
1570 if (pm
->tray_image
!= NULL
) {
1571 orientation
= egg_tray_icon_get_orientation(EGG_TRAY_ICON(pm
->tray_icon
));
1572 if (orientation
== GTK_ORIENTATION_HORIZONTAL
) {
1573 size
= pm
->i_icon_height
;
1575 size
= pm
->i_icon_width
;
1580 scaled
= gdk_pixbuf_scale_simple(pixbuf
, size
, size
, GDK_INTERP_BILINEAR
);
1581 gtk_image_set_from_pixbuf(GTK_IMAGE(pm
->tray_image
), scaled
);
1582 gtk_widget_show(pm
->tray_image
);
1583 gdk_pixbuf_unref(scaled
);
1586 if (pm
->window
!= NULL
)
1587 gtk_window_set_icon(GTK_WINDOW(pm
->window
), pixbuf
);
1594 * used to switch timers when d_refresh changes
1595 * b_timer_control True trigger the target timer to stop and have this one
1596 * restart it; so it can pickup the new interval;
1598 static gboolean
cb_util_line_chart_refresh_control(PGAPC_MONITOR pm
)
1600 GtkWidget
*w
= NULL
;
1601 gchar
*pch1
= NULL
, *pch
= NULL
;
1603 g_return_val_if_fail(pm
!= NULL
, FALSE
);
1605 if ((!pm
->b_run
) || !(pm
->cb_enabled
))
1606 return FALSE
; /* stop timers */
1608 pm
->b_graph_control
= FALSE
;
1609 pm
->phs
.d_xinc
= pm
->d_graph
* pm
->d_refresh
;
1611 pm
->tid_graph_refresh
=
1612 g_timeout_add((guint
) (pm
->phs
.d_xinc
* GAPC_REFRESH_FACTOR_1K
),
1613 (GSourceFunc
) cb_util_line_chart_refresh
, &pm
->phs
);
1615 pch
= g_strdup_printf(
1616 "<i>sampled every %3.1f seconds</i>",
1618 lg_graph_set_x_label_text (pm
->phs
.plg
, pch
);
1622 w
= g_hash_table_lookup(pm
->pht_Widgets
, "StatusBar");
1624 if ((pm
->tid_graph_refresh
!= 0) && (w
!= NULL
)) {
1625 gtk_statusbar_pop(GTK_STATUSBAR(w
), pm
->i_info_context
);
1626 pch1
= g_strdup_printf
1627 ("Graphing refresh cycle changed for host %s completed!...", pm
->pch_host
);
1628 gtk_statusbar_push(GTK_STATUSBAR(w
), pm
->i_info_context
, pch1
);
1637 * used to switch timers when d_refresh changes
1638 * b_timer_control True trigger the target timer to stop and have this one
1639 * restart it; so it can pickup the new interval;
1641 static gboolean
cb_monitor_refresh_control(PGAPC_MONITOR pm
)
1643 GtkWidget
*w
= NULL
;
1646 g_return_val_if_fail(pm
!= NULL
, FALSE
);
1648 if ((!pm
->b_run
) || !(pm
->cb_enabled
))
1649 return FALSE
; /* stop timers */
1651 pm
->b_timer_control
= FALSE
;
1653 pm
->tid_automatic_refresh
=
1654 g_timeout_add((guint
) (pm
->d_refresh
* GAPC_REFRESH_FACTOR_1K
),
1655 (GSourceFunc
) cb_monitor_automatic_refresh
, pm
);
1657 w
= g_hash_table_lookup(pm
->pht_Widgets
, "StatusBar");
1659 if ((pm
->tid_automatic_refresh
!= 0) && (w
!= NULL
)) {
1660 gtk_statusbar_pop(GTK_STATUSBAR(w
), pm
->i_info_context
);
1661 pch1
= g_strdup_printf("Refresh Cycle Change for host %s Completed!...",
1663 gtk_statusbar_push(GTK_STATUSBAR(w
), pm
->i_info_context
, pch1
);
1671 * timer service routine for IPL refresh and refresh_button.
1672 * used to overcome the multi-threaded startup delay. very short
1674 static gboolean
cb_monitor_dedicated_one_time_refresh(PGAPC_MONITOR pm
)
1676 GtkWidget
*w
= NULL
;
1679 g_return_val_if_fail(pm
!= NULL
, FALSE
);
1681 if ((!pm
->b_run
) || !(pm
->cb_enabled
)) {
1685 if (!g_mutex_trylock(pm
->gm_update
)) {
1686 w
= g_hash_table_lookup(pm
->pht_Widgets
, "StatusBar");
1688 gtk_statusbar_pop(GTK_STATUSBAR(w
), pm
->i_info_context
);
1689 pch1
= g_strdup_printf("Quick refresh for %s failed!"
1690 " Network thread is busy...", pm
->pch_host
);
1691 gtk_statusbar_push(GTK_STATUSBAR(w
), pm
->i_info_context
, pch1
);
1694 return TRUE
; /* thread must be busy */
1697 gdk_threads_enter();
1699 w
= g_hash_table_lookup(pm
->pht_Widgets
, "StatusBar");
1701 gtk_statusbar_pop(GTK_STATUSBAR(w
), pm
->i_info_context
);
1704 gapc_monitor_update_tooltip_msg(pm
);
1706 if (!gapc_monitor_update(pm
)) {
1708 pch1
= g_strdup_printf("Refresh for %s failed! "
1709 "(retry enabled)... network busy!", pm
->pch_host
);
1710 gtk_statusbar_push(GTK_STATUSBAR(w
), pm
->i_info_context
, pch1
);
1713 if (pm
->i_netbusy_counter
++ % 10) { /* Fall thru and quit after ten trys */
1714 g_mutex_unlock(pm
->gm_update
);
1716 gdk_threads_leave();
1717 return TRUE
; /* try again */
1722 pch1
= g_strdup_printf("One-Time Refresh for %s Completed...", pm
->pch_host
);
1723 gtk_statusbar_push(GTK_STATUSBAR(w
), pm
->i_info_context
, pch1
);
1727 g_mutex_unlock(pm
->gm_update
);
1729 gdk_threads_leave();
1731 return FALSE
; /* this will terminate the timer */
1735 * used to make a work request to network queue
1737 static gboolean
cb_monitor_automatic_refresh(PGAPC_MONITOR pm
)
1740 GtkWidget
*w
= NULL
;
1742 g_return_val_if_fail(pm
!= NULL
, FALSE
);
1744 if ((!pm
->b_run
) || !(pm
->cb_enabled
))
1745 return FALSE
; /* stop timers */
1747 if (pm
->b_timer_control
) {
1748 g_timeout_add(100, (GSourceFunc
) cb_monitor_refresh_control
, pm
);
1752 if (!g_mutex_trylock(pm
->gm_update
)) {
1753 w
= g_hash_table_lookup(pm
->pht_Widgets
, "StatusBar");
1755 gtk_statusbar_pop(GTK_STATUSBAR(w
), pm
->i_info_context
);
1756 pch1
= g_strdup_printf("Automatic refresh for %s failed!"
1757 " Network thread is busy...", pm
->pch_host
);
1758 gtk_statusbar_push(GTK_STATUSBAR(w
), pm
->i_info_context
, pch1
);
1761 return TRUE
; /* thread must be busy */
1764 gdk_threads_enter();
1766 w
= g_hash_table_lookup(pm
->pht_Widgets
, "StatusBar");
1768 gtk_statusbar_pop(GTK_STATUSBAR(w
), pm
->i_info_context
);
1771 gapc_monitor_update_tooltip_msg(pm
); /* false = OK */
1772 if (gapc_monitor_update(pm
)) {
1775 g_strdup_printf("Automatic refresh for %s complete...", pm
->pch_host
);
1776 gtk_statusbar_push(GTK_STATUSBAR(w
), pm
->i_info_context
, pch1
);
1781 pch1
= g_strdup_printf("Automatic refresh for %s failed!"
1782 " Network thread is busy...", pm
->pch_host
);
1783 gtk_statusbar_push(GTK_STATUSBAR(w
), pm
->i_info_context
, pch1
);
1786 if (pm
->i_netbusy_counter
++ % 10) { /* fall thru every tenth time to queue a message */
1787 g_mutex_unlock(pm
->gm_update
);
1789 gdk_threads_leave();
1796 * This is the work request to network queue */
1797 g_async_queue_push(pm
->q_network
, (gpointer
) pm
);
1799 g_mutex_unlock(pm
->gm_update
);
1801 gdk_threads_leave();
1807 * Manage the state icon in the panel and the associated tooltip
1808 * Composes the expanded tooltip message
1810 static gboolean
gapc_monitor_update_tooltip_msg(PGAPC_MONITOR pm
)
1812 gchar
*pchx
= NULL
, *pmsg
= NULL
, *ptitle
= NULL
, *pch5
= NULL
, *pch5a
=
1813 NULL
, *pch5b
= NULL
;
1814 gchar
*pch1
= NULL
, *pch2
= NULL
, *pch3
= NULL
, *pch4
= NULL
;
1815 gchar
*pch6
= NULL
, *pch7
= NULL
, *pch8
= NULL
, *pch9
= NULL
;
1816 gchar
*pchb
= NULL
, *pchc
= NULL
, *pchd
= NULL
, *pche
= NULL
;
1817 gchar
*pcha
= NULL
, *pmview
= NULL
, *pch_watt
= NULL
;
1818 GtkWidget
*w
= NULL
;
1819 gdouble d_value
= 0.0, d_watt
=0.0, d_loadpct
= 0.0;
1820 gboolean b_flag
= FALSE
, b_valid
= FALSE
;
1825 g_return_val_if_fail(pm
!= NULL
, TRUE
);
1827 if (pm
->b_run
!= TRUE
)
1830 w
= g_hash_table_lookup(pm
->pht_Widgets
, "StatusBar");
1832 pm
->i_icon_index
= GAPC_ICON_ONLINE
;
1834 pch1
= g_hash_table_lookup(pm
->pht_Status
, "UPSNAME");
1835 pch2
= g_hash_table_lookup(pm
->pht_Status
, "HOSTNAME");
1837 pch2
= pm
->pch_host
;
1842 pch3
= g_hash_table_lookup(pm
->pht_Status
, "STATUS");
1846 pch4
= g_hash_table_lookup(pm
->pht_Status
, "NUMXFERS");
1847 pch5a
= g_hash_table_lookup(pm
->pht_Status
, "TONBATT");
1848 if (pch5a
== NULL
) {
1851 pch5b
= g_hash_table_lookup(pm
->pht_Status
, "CUMONBATT");
1852 if (pch5b
== NULL
) {
1855 pch5
= g_hash_table_lookup(pm
->pht_Status
, "XONBATT");
1859 pch6
= g_hash_table_lookup(pm
->pht_Status
, "LINEV");
1860 pch7
= g_hash_table_lookup(pm
->pht_Status
, "BCHARGE");
1864 pch8
= g_hash_table_lookup(pm
->pht_Status
, "LOADPCT");
1865 if ( pch8
!= NULL
) {
1866 d_loadpct
= g_strtod (pch8
, NULL
);
1869 pch_watt
= g_hash_table_lookup(pm
->pht_Status
, "NOMPOWER");
1870 if ( pch_watt
!= NULL
) {
1871 pm
->i_watt
= g_strtod (pch_watt
, NULL
);
1872 d_watt
= d_loadpct
* pm
->i_watt
;
1874 d_watt
= d_loadpct
* pm
->i_watt
;
1877 pch9
= g_hash_table_lookup(pm
->pht_Status
, "TIMELEFT");
1878 pcha
= g_hash_table_lookup(pm
->pht_Status
, "VERSION");
1879 pchb
= g_hash_table_lookup(pm
->pht_Status
, "STARTTIME");
1880 pchc
= g_hash_table_lookup(pm
->pht_Status
, "MODEL");
1881 pchd
= g_hash_table_lookup(pm
->pht_Status
, "UPSMODE");
1882 pche
= g_hash_table_lookup(pm
->pht_Status
, "CABLE");
1884 if (pm
->b_data_available
) {
1885 d_value
= g_strtod(pch7
, NULL
);
1887 if (g_strrstr(pch3
, "COMMLOST") != NULL
) {
1888 pchx
= " cable un-plugged...";
1889 pm
->i_icon_index
= GAPC_ICON_UNPLUGGED
;
1891 } else if ((d_value
< 99.0) && (g_strrstr(pch3
, "LINE") != NULL
)) {
1892 pchx
= " and charging...";
1894 pm
->i_icon_index
= GAPC_ICON_CHARGING
;
1895 } else if (g_strrstr(pch3
, "BATT") != NULL
) {
1896 pchx
= " on battery...";
1897 pm
->i_icon_index
= GAPC_ICON_ONBATT
;
1901 pchx
= " NIS network error...";
1903 g_hash_table_replace(pm
->pht_Status
, g_strdup("STATUS"), g_strdup(pch3
));
1904 pm
->i_icon_index
= GAPC_ICON_NETWORKERROR
;
1905 for (i_series
= 0; i_series
< pm
->phs
.plg
->i_num_series
; i_series
++) {
1906 gapc_util_point_filter_set(&(pm
->phs
.sq
[i_series
]), 0.0);
1911 ptitle
= g_strdup_printf("<span foreground=\"red\" size=\"large\">"
1912 "%s@%s\nis %s%s" "</span>",
1913 (pch1
!= NULL
) ? pch1
: "unknown",
1914 (pch2
!= NULL
) ? pch2
: "unknown",
1915 (pch3
!= NULL
) ? pch3
: "n/a", (pchx
!= NULL
) ? pchx
: " ");
1917 ptitle
= g_strdup_printf("<span foreground=\"blue\" size=\"large\">"
1918 "%s@%s\nis %s%s" "</span>",
1919 (pch1
!= NULL
) ? pch1
: "unknown",
1920 (pch2
!= NULL
) ? pch2
: "unknown",
1921 (pch3
!= NULL
) ? pch3
: "n/a", (pchx
!= NULL
) ? pchx
: " ");
1924 pmsg
= g_strdup_printf("%s@%s\nStatus: %s%s\n"
1925 "Refresh occurs every %3.1f seconds\n"
1926 "----------------------------------------------------------\n"
1927 "%s Outage[s]\n" "Last on %s\n" "%s Utility VAC\n"
1928 "%s Battery Charge\n"
1930 "%3.0f of %d watts\n"
1932 "----------------------------------------------------------\n"
1933 "Build: %s\n" "Started: %s\n"
1934 "----------------------------------------------------------\n"
1935 "Model: %s\n" " Mode: %s\n" "Cable: %s",
1936 (pch1
!= NULL
) ? pch1
: "unknown",
1937 (pch2
!= NULL
) ? pch2
: "unknown",
1938 (pch3
!= NULL
) ? pch3
: "n/a",
1939 (pchx
!= NULL
) ? pchx
: " ",
1941 (pch4
!= NULL
) ? pch4
: "n/a",
1942 (pch5
!= NULL
) ? pch5
: "n/a",
1943 (pch6
!= NULL
) ? pch6
: "n/a",
1944 (pch7
!= NULL
) ? pch7
: "n/a",
1945 (pch8
!= NULL
) ? pch8
: "n/a",
1947 (pch9
!= NULL
) ? pch9
: "n/a",
1948 (pcha
!= NULL
) ? pcha
: "n/a",
1949 (pchb
!= NULL
) ? pchb
: "n/a",
1950 (pchc
!= NULL
) ? pchc
: "n/a",
1951 (pchd
!= NULL
) ? pchd
: "n/a", (pche
!= NULL
) ? pche
: "n/a");
1954 switch (pm
->i_icon_index
) {
1955 case GAPC_ICON_NETWORKERROR
:
1956 pmview
= g_strdup_printf("<span foreground=\"red\" size=\"large\">"
1957 "<b><i>%s@%s</i></b></span>\n"
1958 "NIS network connection not Responding!",
1959 (pch1
!= NULL
) ? pch1
: "unknown", (pch2
!= NULL
) ? pch2
: "unknown");
1961 case GAPC_ICON_UNPLUGGED
:
1962 pmview
= g_strdup_printf("<span foreground=\"red\" size=\"large\">"
1963 "<b><i>%s@%s</i></b></span>\n"
1965 (pch1
!= NULL
) ? pch1
: "unknown",
1966 (pch2
!= NULL
) ? pch2
: "unknown", (pchx
!= NULL
) ? pchx
: " un-plugged");
1968 case GAPC_ICON_CHARGING
:
1969 pmview
= g_strdup_printf("<span foreground=\"blue\">"
1970 "<b><i>%s@%s</i></b></span>\n"
1971 "%s Outage, Last on %s\n"
1972 "%s VAC, %s Charge\n"
1973 "%s Remaining, %s total on battery, %3.0f of %d watts",
1974 (pch1
!= NULL
) ? pch1
: "unknown",
1975 (pch2
!= NULL
) ? pch2
: "unknown",
1976 (pch4
!= NULL
) ? pch4
: "n/a",
1977 (pch5
!= NULL
) ? pch5
: "n/a",
1978 (pch6
!= NULL
) ? pch6
: "n/a",
1979 (pch7
!= NULL
) ? pch7
: "n/a",
1980 (pch9
!= NULL
) ? pch9
: "n/a",
1981 (pch5b
!= NULL
) ? pch5b
: "n/a",
1982 d_watt
, pm
->i_watt
);
1984 case GAPC_ICON_ONBATT
:
1985 pmview
= g_strdup_printf("<span foreground=\"yellow\">"
1986 "<b><i>%s@%s</i></b></span>\n"
1987 "%s Outage, Last on %s\n"
1988 "%s Charge, %s total on battery\n"
1989 "%s Remaining, %s on battery, %3.0f of %d watts",
1990 (pch1
!= NULL
) ? pch1
: "unknown",
1991 (pch2
!= NULL
) ? pch2
: "unknown",
1992 (pch4
!= NULL
) ? pch4
: "n/a",
1993 (pch5
!= NULL
) ? pch5
: "n/a",
1994 (pch7
!= NULL
) ? pch7
: "n/a",
1995 (pch5b
!= NULL
) ? pch5b
: "n/a",
1996 (pch9
!= NULL
) ? pch9
: "n/a",
1997 (pch5a
!= NULL
) ? pch5a
: "n/a ",
1998 d_watt
, pm
->i_watt
);
2000 case GAPC_ICON_ONLINE
:
2001 case GAPC_ICON_DEFAULT
:
2003 pmview
= g_strdup_printf("<b><i>%s@%s</i></b>\n"
2004 "%s Outage, Last on %s\n"
2005 "%s VAC, %s Charge %s %3.0f of %d watts",
2006 (pch1
!= NULL
) ? pch1
: "unknown",
2007 (pch2
!= NULL
) ? pch2
: "unknown",
2008 (pch4
!= NULL
) ? pch4
: "n/a",
2009 (pch5
!= NULL
) ? pch5
: "n/a",
2010 (pch6
!= NULL
) ? pch6
: "n/a",
2011 (pch7
!= NULL
) ? pch7
: "n/a",
2012 (pchx
!= NULL
) ? pchx
: " ",
2013 d_watt
, pm
->i_watt
);
2017 pixbuf
= pm
->my_icons
[pm
->i_icon_index
];
2018 if (pm
->i_old_icon_index
!= pm
->i_icon_index
) {
2024 if ((pm
->tooltips
!= NULL
) && (pm
->tray_icon
!= NULL
)) {
2025 gtk_tooltips_set_tip(pm
->tooltips
, GTK_WIDGET(pm
->tray_icon
), pmsg
, NULL
);
2027 gapc_util_change_icons(pm
);
2032 gapc_util_treeview_get_iter_from_monitor(pm
->monitor_model
, &miter
,
2033 pm
->cb_monitor_num
);
2036 gtk_list_store_set(GTK_LIST_STORE(pm
->monitor_model
), &miter
,
2037 GAPC_MON_STATUS
, pmview
, GAPC_MON_UPSSTATE
, pch3
,
2038 GAPC_MON_ICON
, pixbuf
, -1);
2040 gtk_list_store_set(GTK_LIST_STORE(pm
->monitor_model
), &miter
,
2041 GAPC_MON_STATUS
, pmview
, GAPC_MON_UPSSTATE
, pch3
, -1);
2045 if ((w
= g_hash_table_lookup(pm
->pht_Widgets
, "TitleStatus"))) {
2046 gtk_label_set_markup(GTK_LABEL(w
), ptitle
);
2047 lg_graph_set_chart_title (pm
->phs
.plg
, ptitle
);
2048 g_snprintf(pm
->ch_title_info
, GAPC_MAX_TEXT
, "%s", ptitle
);
2050 lg_graph_draw ( pm
->phs
.plg
);
2056 /* g_free (pmview); */
2062 * main data updating routine.
2063 * -- collects and pushes data to all ui
2065 static gint
gapc_monitor_update(PGAPC_MONITOR pm
)
2068 GtkWidget
*win
= NULL
, *w
= NULL
;
2069 gchar
*pch
= NULL
, *pch1
= NULL
, *pch2
= NULL
, *pch3
= NULL
, *pch4
= NULL
;
2070 gchar
*pch_watt
= NULL
, *pch5
= NULL
, *pch6
= NULL
;
2071 gdouble dValue
= 0.00, dScale
= 0.0, dtmp
= 0.0, dCharge
= 0.0, d_loadpct
= 0.0, d_watt
= 0.0;
2072 gchar ch_buffer
[GAPC_MAX_TEXT
];
2073 PGAPC_BAR_H pbar
= NULL
;
2075 g_return_val_if_fail(pm
!= NULL
, FALSE
);
2077 if (pm
->window
== NULL
) /* not created yet */
2080 if (pm
->b_run
== FALSE
)
2083 if (pm
->b_data_available
== FALSE
)
2086 w
= g_hash_table_lookup(pm
->pht_Widgets
, "StatusPage");
2087 if (gapc_util_text_view_clear_buffer(GTK_WIDGET(w
))) {
2090 for (i_x
= 1; pm
->pach_status
[i_x
] != NULL
; i_x
++) {
2091 gapc_util_text_view_append(GTK_WIDGET(w
), pm
->pach_status
[i_x
]);
2094 w
= g_hash_table_lookup(pm
->pht_Widgets
, "EventsPage");
2095 gapc_util_text_view_clear_buffer(GTK_WIDGET(w
));
2096 for (i_x
= 0; pm
->pach_events
[i_x
] != NULL
; i_x
++) {
2097 gapc_util_text_view_prepend(GTK_WIDGET(w
), pm
->pach_events
[i_x
]);
2101 * compute graphic points */
2102 pch
= g_hash_table_lookup(pm
->pht_Status
, "LINEV");
2106 dValue
= g_strtod(pch
, NULL
);
2107 dScale
= (( dValue
- 200 ) > 1) ? 230.0 : 120.0;
2109 gapc_util_point_filter_set(&(pm
->phs
.sq
[0]), dValue
);
2110 pbar
= g_hash_table_lookup(pm
->pht_Status
, "HBar1");
2111 pbar
->d_value
= dValue
;
2112 g_snprintf(pbar
->c_text
, sizeof(pbar
->c_text
), "%s from Utility", pch
);
2113 w
= g_hash_table_lookup(pm
->pht_Widgets
, "HBar1-Widget");
2114 if (GTK_WIDGET_DRAWABLE(w
))
2115 gdk_window_invalidate_rect(w
->window
, &pbar
->rect
, FALSE
);
2117 pch
= g_hash_table_lookup(pm
->pht_Status
, "BATTV");
2121 pch1
= g_hash_table_lookup(pm
->pht_Status
, "NOMBATTV");
2125 dValue
= g_strtod(pch
, NULL
);
2126 dScale
= g_strtod(pch1
, NULL
);
2128 dScale
= ((gint
) (dValue
- 20)) ? 24 : 12;
2130 gapc_util_point_filter_set(&(pm
->phs
.sq
[4]), dValue
);
2131 pbar
= g_hash_table_lookup(pm
->pht_Status
, "HBar2");
2132 pbar
->d_value
= (dValue
> 1.0) ? 1.0 : dValue
;
2133 g_snprintf(pbar
->c_text
, sizeof(pbar
->c_text
), "%s DC on Battery", pch
);
2135 w
= g_hash_table_lookup(pm
->pht_Widgets
, "HBar2-Widget");
2136 if (GTK_WIDGET_DRAWABLE(w
))
2137 gdk_window_invalidate_rect(w
->window
, &pbar
->rect
, FALSE
);
2139 pch
= g_hash_table_lookup(pm
->pht_Status
, "BCHARGE");
2143 dCharge
= dValue
= g_strtod(pch
, NULL
);
2145 gapc_util_point_filter_set(&(pm
->phs
.sq
[3]), dValue
);
2146 pbar
= g_hash_table_lookup(pm
->pht_Status
, "HBar3");
2147 pbar
->d_value
= dValue
;
2148 g_snprintf(pbar
->c_text
, sizeof(pbar
->c_text
), "%s Battery Charge", pch
);
2149 w
= g_hash_table_lookup(pm
->pht_Widgets
, "HBar3-Widget");
2150 if (GTK_WIDGET_DRAWABLE(w
))
2151 gdk_window_invalidate_rect(w
->window
, &pbar
->rect
, FALSE
);
2153 pch
= g_hash_table_lookup(pm
->pht_Status
, "LOADPCT");
2157 dValue
= g_strtod(pch
, NULL
);
2158 d_loadpct
= dtmp
= dValue
/= 100.0;
2159 gapc_util_point_filter_set(&(pm
->phs
.sq
[1]), dValue
);
2160 pbar
= g_hash_table_lookup(pm
->pht_Status
, "HBar4");
2161 pbar
->d_value
= (dValue
> 1.0) ? 1.0 : dValue
;
2162 g_snprintf(pbar
->c_text
, sizeof(pbar
->c_text
), "%s", pch
);
2164 w
= g_hash_table_lookup(pm
->pht_Widgets
, "HBar4-Widget");
2165 if (GTK_WIDGET_DRAWABLE(w
))
2166 gdk_window_invalidate_rect(w
->window
, &pbar
->rect
, FALSE
);
2168 pch
= g_hash_table_lookup(pm
->pht_Status
, "TIMELEFT");
2172 dValue
= g_strtod(pch
, NULL
);
2173 dScale
= dValue
/ (1 - dtmp
);
2175 gapc_util_point_filter_set(&(pm
->phs
.sq
[2]), dValue
);
2176 pbar
= g_hash_table_lookup(pm
->pht_Status
, "HBar5");
2177 pbar
->d_value
= dValue
;
2178 g_snprintf(pbar
->c_text
, sizeof(pbar
->c_text
), "%s Remaining", pch
);
2179 w
= g_hash_table_lookup(pm
->pht_Widgets
, "HBar5-Widget");
2180 if (GTK_WIDGET_DRAWABLE(w
))
2181 gdk_window_invalidate_rect(w
->window
, &pbar
->rect
, FALSE
);
2184 * information window update */
2185 win
= g_hash_table_lookup(pm
->pht_Widgets
, "SoftwareInformation");
2186 pch
= g_hash_table_lookup(pm
->pht_Status
, "VERSION");
2187 pch1
= g_hash_table_lookup(pm
->pht_Status
, "UPSNAME");
2188 pch2
= g_hash_table_lookup(pm
->pht_Status
, "CABLE");
2189 pch3
= g_hash_table_lookup(pm
->pht_Status
, "UPSMODE");
2190 pch4
= g_hash_table_lookup(pm
->pht_Status
, "STARTTIME");
2191 pch5
= g_hash_table_lookup(pm
->pht_Status
, "STATUS");
2192 g_snprintf(ch_buffer
, sizeof(ch_buffer
),
2193 "<span foreground=\"blue\">" "%s\n%s\n%s\n%s\n%s\n%s" "</span>",
2194 (pch
!= NULL
) ? pch
: "N/A", (pch1
!= NULL
) ? pch1
: "N/A",
2195 (pch2
!= NULL
) ? pch2
: "N/A", (pch3
!= NULL
) ? pch3
: "N/A",
2196 (pch4
!= NULL
) ? pch4
: "N/A", (pch5
!= NULL
) ? pch5
: "N/A");
2197 gtk_label_set_markup(GTK_LABEL(win
), ch_buffer
);
2199 win
= g_hash_table_lookup(pm
->pht_Widgets
, "PerformanceSummary");
2200 pch
= g_hash_table_lookup(pm
->pht_Status
, "SELFTEST");
2201 pch1
= g_hash_table_lookup(pm
->pht_Status
, "NUMXFERS");
2202 pch2
= g_hash_table_lookup(pm
->pht_Status
, "LASTXFER");
2203 pch3
= g_hash_table_lookup(pm
->pht_Status
, "XONBATT");
2204 pch4
= g_hash_table_lookup(pm
->pht_Status
, "XOFFBATT");
2205 pch5
= g_hash_table_lookup(pm
->pht_Status
, "TONBATT");
2206 pch6
= g_hash_table_lookup(pm
->pht_Status
, "CUMONBATT");
2207 g_snprintf(ch_buffer
, sizeof(ch_buffer
),
2208 "<span foreground=\"blue\">" "%s\n%s\n%s\n%s\n%s\n%s\n%s" "</span>",
2209 (pch
!= NULL
) ? pch
: "N/A", (pch1
!= NULL
) ? pch1
: "N/A",
2210 (pch2
!= NULL
) ? pch2
: "N/A", (pch3
!= NULL
) ? pch3
: "N/A",
2211 (pch4
!= NULL
) ? pch4
: "N/A", (pch5
!= NULL
) ? pch5
: "N/A",
2212 (pch6
!= NULL
) ? pch6
: "N/A");
2213 gtk_label_set_markup(GTK_LABEL(win
), ch_buffer
);
2215 win
= g_hash_table_lookup(pm
->pht_Widgets
, "ProductInformation");
2216 pch
= g_hash_table_lookup(pm
->pht_Status
, "MODEL");
2217 pch1
= g_hash_table_lookup(pm
->pht_Status
, "SERIALNO");
2218 pch2
= g_hash_table_lookup(pm
->pht_Status
, "MANDATE");
2219 pch3
= g_hash_table_lookup(pm
->pht_Status
, "FIRMWARE");
2220 pch4
= g_hash_table_lookup(pm
->pht_Status
, "BATTDATE");
2221 pch_watt
= g_hash_table_lookup(pm
->pht_Status
, "NOMPOWER");
2222 if (pch_watt
!= NULL
) {
2223 pm
->i_watt
= g_strtod (pch_watt
, NULL
);
2224 d_watt
= d_loadpct
* pm
->i_watt
;
2226 d_watt
= d_loadpct
* pm
->i_watt
;
2228 g_snprintf(ch_buffer
, sizeof(ch_buffer
),
2229 "<span foreground=\"blue\">" "%s\n%s\n%s\n%s\n%s\n%3.0f of %d" "</span>",
2230 (pch
!= NULL
) ? pch
: "N/A", (pch1
!= NULL
) ? pch1
: "N/A",
2231 (pch2
!= NULL
) ? pch2
: "N/A", (pch3
!= NULL
) ? pch3
: "N/A",
2232 (pch4
!= NULL
) ? pch4
: "N/A", d_watt
, pm
->i_watt
);
2233 gtk_label_set_markup(GTK_LABEL(win
), ch_buffer
);
2237 /* sknet_util_log_msg()
2238 * capture the current application related error values
2239 * output the composed str only if debug_flag is on
2241 static void sknet_util_log_msg (gchar
* pch_func
, gchar
* pch_topic
, gchar
* pch_emsg
)
2245 g_print ("%s(%s) msg=%s\n", pch_func
, pch_topic
, pch_emsg
);
2252 * Write nbytes to the network.
2253 * It may require several writes.
2255 static gint
sknet_net_write_nbytes (GIOChannel
* ioc
, gchar
* ptr
, gsize nbytes
)
2259 GError
*gerror
= NULL
;
2261 gboolean b_eof
= TRUE
;
2268 ios
= g_io_channel_write_chars (ioc
, ptr
, nleft
, &nwritten
, &gerror
);
2271 case G_IO_STATUS_ERROR
:
2272 sknet_util_log_msg ("sknet_net_write_nbytes", "G_IO_STATUS_ERROR", gerror
->message
);
2273 g_error_free (gerror
);
2276 case G_IO_STATUS_AGAIN
:
2277 sknet_util_log_msg ("sknet_net_write_nbytes", "G_IO_STATUS_AGAIN", "retry enabled");
2280 case G_IO_STATUS_EOF
:
2281 sknet_util_log_msg ("sknet_net_write_nbytes", "G_IO_STATUS_EOF", "ok");
2284 case G_IO_STATUS_NORMAL
:
2287 sknet_util_log_msg ("sknet_net_write_nbytes", "unknown state", "aborted");
2295 while ((nleft
> 0) && (b_eof
!= TRUE
));
2297 return (nbytes
- nleft
);
2301 * Send a message over the network. The send consists of
2302 * two network packets. The first is sends a short containing
2303 * the length of the data packet which follows.
2304 * Returns number of bytes sent
2305 * Returns -1 on error
2307 static gint
sknet_net_send (GIOChannel
* ioc
, gchar
* buff
, gsize len
)
2312 /* send short containing size of data packet */
2313 pktsiz
= g_htons ((gshort
) len
);
2314 rc
= sknet_net_write_nbytes (ioc
, (gchar
*) &pktsiz
, sizeof (gshort
));
2315 if (rc
!= sizeof (gshort
))
2317 sknet_util_log_msg ("sknet_net_send", "send message size", "failed");
2321 /* send data packet */
2322 rc
= sknet_net_write_nbytes (ioc
, buff
, len
);
2325 sknet_util_log_msg ("sknet_net_send", "send message buffer", "failed");
2333 * Read nbytes from the network.
2334 * It is possible that the total bytes requires several
2335 * read requests, which will happen automatically.
2336 * Returns: count of bytes read, or -1 for error
2338 static gint
sknet_net_read_nbytes (GIOChannel
* ioc
, gchar
* ptr
, gsize nbytes
)
2342 GError
*gerror
= NULL
;
2344 gboolean b_eof
= FALSE
;
2351 ios
= g_io_channel_read_chars (ioc
, ptr
, nleft
, &nread
, &gerror
);
2354 case G_IO_STATUS_ERROR
:
2355 sknet_util_log_msg ("sknet_net_read_nbytes", "G_IO_STATUS_ERROR", gerror
->message
);
2356 g_error_free (gerror
);
2359 case G_IO_STATUS_AGAIN
:
2360 sknet_util_log_msg ("sknet_net_read_nbytes", "G_IO_STATUS_AGAIN", "aborted");
2363 case G_IO_STATUS_EOF
:
2364 sknet_util_log_msg ("sknet_net_read_nbytes", "G_IO_STATUS_EOF", "ok");
2367 case G_IO_STATUS_NORMAL
:
2370 sknet_util_log_msg ("sknet_net_read_nbytes", "unknown state", "aborted");
2378 while ((nleft
> 0) && (b_eof
!= TRUE
));
2380 return (nbytes
- nleft
); /* return >= 0 */
2384 * Receive a message from the other end. Each message consists of
2385 * two packets. The first is a header that contains the size
2386 * of the data that follows in the second packet.
2387 * Returns number of bytes read
2388 * Returns 0 on end of file
2389 * Returns -1 on hard end of file (i.e. network connection close)
2390 * Returns -2 on error
2392 static gint
sknet_net_recv (GIOChannel
* ioc
, gchar
* buff
, gsize maxlen
)
2397 /* get data size -- in short */
2398 nbytes
= sknet_net_read_nbytes (ioc
, (gchar
*) &pktsiz
, sizeof (gshort
));
2401 sknet_util_log_msg ("sknet_net_recv", "read msg_len", "failed");
2402 return -1; /* assume hard EOF received */
2404 if (nbytes
!= sizeof (gshort
))
2406 sknet_util_log_msg ("sknet_net_recv", "read short_len", "failed");
2410 pktsiz
= g_ntohs (pktsiz
); /* decode no. of bytes that follow */
2411 if (pktsiz
> maxlen
)
2413 sknet_util_log_msg ("sknet_net_recv", "msg_len gt buffer", "overflow");
2419 sknet_util_log_msg ("sknet_net_recv", "Soft error", "End-of-File");
2420 return 0; /* soft EOF */
2423 /* now read the actual data */
2424 nbytes
= sknet_net_read_nbytes (ioc
, buff
, pktsiz
);
2427 sknet_util_log_msg ("sknet_net_recv", "read message", "failed");
2430 if (nbytes
!= pktsiz
)
2432 sknet_util_log_msg ("sknet_net_recv", "read incomplete", "length error");
2436 return (nbytes
); /* return actual length of message */
2439 /* sknet_net_close()
2440 * Close the active or error'ed socket
2442 static void sknet_net_close (GIOChannel
*ioc
, gboolean b_flush
)
2445 GError
*gerror
= NULL
;
2446 GIOStatus ios
= G_IO_STATUS_NORMAL
;
2448 sockfd
= g_io_channel_unix_get_fd (ioc
);
2449 ios
= g_io_channel_shutdown (ioc
, b_flush
, &gerror
);
2452 sknet_util_log_msg ("sknet_channel_close", "error", gerror
->message
);
2453 g_error_free (gerror
);
2455 if (ios
!= G_IO_STATUS_NORMAL
) {
2456 g_message ("net_close: g_io_channel_shutdown(%d) failed with %d", sockfd
, ios
);
2459 g_io_channel_unref (ioc
);
2466 * Open a TCP connection using GIOChannels to a host
2467 * Returns NULL on error, with err text in ch_error_message
2468 * Returns GIOChannel ptr otherwise
2469 * Affects: -psk->gip, which is a sockaddr_in address of partner host
2470 * this value is allocated and retained for the life of this program
2471 * -psk->b_network_control, if true causes the addr to be resolved again
2472 * or if false, it uses the current value - saving a dns hit/query
2474 static GIOChannel
*sknet_net_open (PSKCOMM psk
)
2476 GIOChannel
*ioc
= NULL
;
2478 struct sockaddr_in
*tcp_serv_addr
= NULL
;
2481 g_return_val_if_fail (psk
!= NULL
, NULL
);
2484 * Allocate a new address struct if it does not exist
2486 if (psk
->gip
== NULL
) {
2487 psk
->b_network_control
=TRUE
;
2488 psk
->gip
= g_new0( struct sockaddr_in
, 1);
2489 g_return_val_if_fail (psk
->gip
!= NULL
, NULL
);
2490 tcp_serv_addr
= (struct sockaddr_in
*)psk
->gip
;
2492 tcp_serv_addr
= (struct sockaddr_in
*)psk
->gip
;
2496 * Fill in the structure serv_addr with the address of
2497 * the server that we want to connect with.
2499 if ( psk
->b_network_control
) {
2500 memset ((char *)tcp_serv_addr
, 0, sizeof (struct sockaddr_in
));
2501 tcp_serv_addr
->sin_family
= AF_INET
;
2502 tcp_serv_addr
->sin_port
= g_htons (psk
->i_port
);
2504 nrc
= inet_aton (psk
->ch_ip_string
, (struct in_addr
*)&tcp_serv_addr
->sin_addr
.s_addr
);
2505 if ( nrc
== 0) /* inet_aton failed */
2507 struct hostent he
, *phe
;
2511 phe
= gethostname_re(psk
->ch_ip_string
, &he
, &buff
, &bufflen
);
2515 sknet_util_log_msg ("sknet_net_open", "gethostbyname() failed", "");
2516 g_snprintf(psk
->ch_error_msg
, sizeof(psk
->ch_error_msg
), "gethostbyname() failed");
2520 if (he
.h_length
!= sizeof (struct in_addr
) || he
.h_addrtype
!= AF_INET
)
2523 sknet_util_log_msg ("sknet_net_open", "struct hostent", "argument error");
2524 g_snprintf(psk
->ch_error_msg
, sizeof(psk
->ch_error_msg
),"%s","argument error");
2529 tcp_serv_addr
->sin_addr
.s_addr
= *(unsigned int *) he
.h_addr
;
2531 } /* end if inet_addr */
2533 } /* end if b_network */
2536 /* Open a TCP socket */
2537 if ((sockfd
= socket (AF_INET
, SOCK_STREAM
, 0)) < 0)
2539 sknet_util_log_msg ("sknet_net_open", "socket() api failed",
2540 (gchar
*) g_strerror (errno
));
2541 g_snprintf(psk
->ch_error_msg
, sizeof(psk
->ch_error_msg
),"%s",
2542 (gchar
*) g_strerror (errno
));
2551 tv
.tv_usec
= 200000;
2553 rcx
= setsockopt(sockfd
, SOL_SOCKET
, SO_RCVTIMEO
| SO_SNDTIMEO
,
2554 &tv
, (socklen_t
) sizeof(struct timeval
));
2556 sknet_util_log_msg ("sknet_net_open", "setsockopt(200ms) failed!",
2557 (gchar
*) g_strerror (errno
));
2562 /* connect to server */
2563 if ((connect (sockfd
, (struct sockaddr
*) tcp_serv_addr
, sizeof (struct sockaddr_in
))) == -1)
2565 sknet_util_log_msg ("sknet_net_open", "connect() api failed",
2566 (gchar
*) g_strerror (errno
));
2567 g_snprintf(psk
->ch_error_msg
, sizeof(psk
->ch_error_msg
),"%s",
2568 (gchar
*) g_strerror (errno
));
2571 psk
->b_network_control
= TRUE
;
2576 psk
->b_network_control
= FALSE
;
2578 ioc
= g_io_channel_unix_new (sockfd
);
2579 g_io_channel_set_encoding (ioc
, NULL
, NULL
);
2580 g_io_channel_set_buffered (ioc
, FALSE
);
2586 /* sknet_net_client_init()
2587 * Create a control structure and set ip values
2589 * return NULL on error.
2591 static PSKCOMM
sknet_net_client_init (gchar
*pch_remote_ip
, gint i_remote_port
)
2595 psk
= g_new0(SKNET_COMMS
, 1);
2596 g_return_val_if_fail(psk
!= NULL
, NULL
);
2598 psk
->gp_reserved
= NULL
;
2599 psk
->cb_id
= 0; /* initialize count of instances created */
2600 g_snprintf( psk
->ch_ip_string
, sizeof(psk
->ch_ip_string
), "%s", pch_remote_ip
);
2601 psk
->i_port
= i_remote_port
;
2602 psk
->b_network_control
= TRUE
;
2604 g_snprintf (psk
->ch_error_msg
, sizeof (psk
->ch_error_msg
),
2605 "client init(client ready to connect to %s:%6d",
2606 psk
->ch_ip_string
, psk
->i_port
);
2607 sknet_util_log_msg ("sknet_net_client_init", psk
->ch_error_msg
, "Ready");
2613 * Close server socket if open and release internal storage
2615 static void sknet_net_shutdown (PSKCOMM psk
)
2618 g_return_if_fail (psk
!= NULL
);
2620 if (psk
->gp_reserved
!= NULL
) {
2621 ((PSKCOMM
)psk
->gp_reserved
)->cb_id
--; /* decrement count of instances created */
2622 } else { /* or close main socket */
2625 close (psk
->fd_server
);
2629 if (psk
->gip
!= NULL
) {
2639 * performs a complete NIS transaction by sending cmd and
2640 * loading each result line into the pch array.
2641 * also, refreshes status key/value pairs in hastable.
2642 * return error = 0, or number of lines read from network
2644 static gint
gapc_net_transaction_service(PGAPC_MONITOR pm
, gchar
* cp_cmd
, gchar
** pch
)
2646 gint n
= 0, iflag
= 0;
2647 GIOChannel
*ioc
= NULL
;
2649 g_return_val_if_fail(pm
, -1);
2650 g_return_val_if_fail(pm
->psk
, -1);
2651 g_return_val_if_fail(pm
->pch_host
, -1);
2654 ioc
= sknet_net_open(pm
->psk
);
2659 n
= sknet_net_send( ioc
, cp_cmd
, g_utf8_strlen(cp_cmd
, -1));
2661 sknet_net_close( ioc
, TRUE
);
2665 /* clear current data */
2666 for (iflag
= 0; iflag
< GAPC_MAX_ARRAY
; iflag
++) {
2667 if (pch
[iflag
] != NULL
) {
2674 while (iflag
< GAPC_MAX_ARRAY
) {
2675 n
= sknet_net_recv(ioc
, pm
->psk
->ch_session_message
, sizeof(pm
->psk
->ch_session_message
));
2679 pm
->psk
->ch_session_message
[n
] = 0;
2680 pch
[iflag
++] = g_strdup(pm
->psk
->ch_session_message
);
2682 if (g_str_equal(cp_cmd
, "status") && iflag
> 1)
2683 gapc_util_update_hashtable(pm
, pm
->psk
->ch_session_message
);
2686 sknet_net_close(ioc
, TRUE
);
2688 return iflag
; /* count of records received */
2692 * Worker thread for network communications.
2694 static gpointer
*gapc_net_thread_qwork(PGAPC_MONITOR pm
)
2697 GAsyncQueue
*thread_queue
= NULL
;
2699 g_return_val_if_fail(pm
!= NULL
, NULL
);
2700 g_return_val_if_fail(pm
->q_network
!= NULL
, NULL
);
2702 g_async_queue_ref(pm
->q_network
);
2703 thread_queue
= pm
->q_network
;
2705 if (pm
->psk
== NULL
) {
2706 pm
->psk
= sknet_net_client_init (pm
->pch_host
, pm
->i_port
);
2707 if (pm
->psk
== NULL
) {
2708 g_async_queue_unref(thread_queue
);
2709 g_thread_exit(GINT_TO_POINTER(0));
2713 while ((pm
= (PGAPC_MONITOR
) g_async_queue_pop(thread_queue
))) {
2714 if (pm
->b_thread_stop
) {
2719 g_mutex_lock(pm
->gm_update
);
2720 if (!pm
->b_run
) { /* may have waited a while for lock */
2721 g_mutex_unlock(pm
->gm_update
);
2725 if ((rc
= gapc_net_transaction_service(pm
, "status", pm
->pach_status
))) {
2726 gapc_net_transaction_service(pm
, "events", pm
->pach_events
);
2728 g_mutex_unlock(pm
->gm_update
);
2731 pm
->b_data_available
= TRUE
;
2733 pm
->b_data_available
= FALSE
;
2736 pm
->b_data_available
= FALSE
;
2740 if (pm
->psk
!= NULL
) {
2741 sknet_net_shutdown (pm
->psk
);
2745 g_async_queue_unref(thread_queue
);
2747 g_thread_exit(GINT_TO_POINTER(1));
2753 * return the answer and reset the internal controls to zero
2755 static gdouble
gapc_util_point_filter_reset(PGAPC_SUMS sq
)
2757 gdouble d_the_final_answer
= 0.0;
2759 g_mutex_lock(sq
->gm_graph
);
2761 d_the_final_answer
= sq
->last_answer
;
2763 sq
->point_count
= 0;
2765 sq
->this_point
= 0.0;
2766 sq
->last_point
= 0.0;
2768 sq
->this_answer
= 0.0;
2769 sq
->last_answer
= 0.0;
2771 sq
->answer_summ
= 0.0;
2772 sq
->point_min
= 0.0;
2773 sq
->point_max
= 0.0;
2775 g_mutex_unlock(sq
->gm_graph
);
2777 return (d_the_final_answer
);
2781 * Compute the average of the given data point
2783 static gdouble
gapc_util_point_filter_set(PGAPC_SUMS sq
, gdouble this_point
)
2785 g_mutex_lock(sq
->gm_graph
);
2787 sq
->this_point
= this_point
;
2789 sq
->this_point
*= 100;
2792 /* some calc here */
2793 sq
->answer_summ
+= sq
->this_point
;
2794 sq
->this_answer
= sq
->answer_summ
/ sq
->point_count
;
2796 sq
->last_point
= sq
->this_point
;
2797 sq
->last_answer
= sq
->this_answer
;
2799 if (sq
->point_min
> sq
->this_point
)
2800 sq
->point_min
= sq
->this_point
;
2801 if (sq
->point_max
< sq
->this_point
)
2802 sq
->point_max
= sq
->this_point
;
2804 g_mutex_unlock(sq
->gm_graph
);
2806 return (sq
->this_answer
);
2810 * Get a iter to the list_store record containing this monitor key.
2811 * Will search either list_store
2812 * - monitor col is the same in both models
2813 * Returns: TRUE and iter is found, FALSE and invalid iter if not found
2815 static gboolean
gapc_util_treeview_get_iter_from_monitor(GtkTreeModel
* model
,
2816 GtkTreeIter
* iter
, gint i_value
)
2818 gboolean valid
= FALSE
, b_result
= FALSE
;
2821 g_return_val_if_fail(model
!= NULL
, FALSE
);
2822 g_return_val_if_fail(iter
!= NULL
, FALSE
);
2824 valid
= gtk_tree_model_get_iter_first(model
, iter
);
2826 gtk_tree_model_get(model
, iter
, GAPC_PREFS_MONITOR
, &i_monitor
, -1);
2828 if (i_monitor
== i_value
) {
2829 /* set sucess flag */
2833 valid
= gtk_tree_model_iter_next(model
, iter
);
2840 * Add a preferences record to the gconf instance and prefs_model
2841 * returns FALSE on error
2842 * returns TRUE on sucess
2844 static gboolean
gapc_panel_preferences_gconf_add_rec(PGAPC_CONFIG pcfg
,
2850 g_return_val_if_fail(pcfg
!= NULL
, FALSE
);
2851 g_return_val_if_fail(pcfg
->client
!= NULL
, FALSE
);
2852 g_return_val_if_fail(pcfg
->prefs_model
!= NULL
, FALSE
);
2854 pkey
= GAPC_MID_GROUP_KEY
;
2855 g_snprintf(pk
.k_enabled
, GAPC_MAX_TEXT
, "%s/%d/%s", pkey
, i_monitor
, "enabled");
2856 g_snprintf(pk
.k_use_systray
, GAPC_MAX_TEXT
, "%s/%d/%s", pkey
, i_monitor
,
2858 g_snprintf(pk
.k_port_number
, GAPC_MAX_TEXT
, "%s/%d/%s", pkey
, i_monitor
,
2860 g_snprintf(pk
.k_network_interval
, GAPC_MAX_TEXT
, "%s/%d/%s", pkey
, i_monitor
,
2861 "network_interval");
2862 g_snprintf(pk
.k_graph_interval
, GAPC_MAX_TEXT
, "%s/%d/%s", pkey
, i_monitor
,
2864 g_snprintf(pk
.k_host_name
, GAPC_MAX_TEXT
, "%s/%d/%s", pkey
, i_monitor
,
2866 g_snprintf(pk
.v_host_name
, GAPC_MAX_TEXT
, "%s", GAPC_HOST_DEFAULT
);
2868 gconf_client_set_bool(pcfg
->client
, pk
.k_enabled
, FALSE
, NULL
);
2869 gconf_client_set_bool(pcfg
->client
, pk
.k_use_systray
, FALSE
, NULL
);
2870 gconf_client_set_int(pcfg
->client
, pk
.k_port_number
, GAPC_PORT_DEFAULT
, NULL
);
2871 gconf_client_set_float(pcfg
->client
, pk
.k_network_interval
, GAPC_REFRESH_DEFAULT
,
2873 gconf_client_set_float(pcfg
->client
, pk
.k_graph_interval
,
2874 GAPC_LINEGRAPH_REFRESH_FACTOR
, NULL
);
2875 gconf_client_set_string(pcfg
->client
, pk
.k_host_name
, pk
.v_host_name
, NULL
);
2881 * capture the current application related error values centrally
2883 static void gapc_util_log_app_msg(gchar
* pch_func
, gchar
* pch_topic
,
2888 g_return_if_fail(pch_func
!= NULL
);
2890 pch
= g_strdup_printf("%s(%s) emsg=%s", pch_func
, pch_topic
, pch_emsg
);
2900 * parses received line of text into key/value pairs to be inserted
2901 * into the status hashtable.
2903 static gint
gapc_util_update_hashtable(PGAPC_MONITOR pm
, gchar
* pch_unparsed
)
2905 gchar
*pch_in
= NULL
;
2907 gchar
*pch_end
= NULL
;
2910 g_return_val_if_fail(pm
!= NULL
, FALSE
);
2911 g_return_val_if_fail(pch_unparsed
!= NULL
, -1);
2913 /* unparsed contains - keystring : keyvalue nl */
2914 pch_in
= g_strdup(pch_unparsed
);
2915 pch_end
= g_strrstr(pch_in
, "\n");
2916 if (pch_end
!= NULL
)
2919 ilen
= g_utf8_strlen(pch_in
, -1);
2921 pch
= g_strstr_len(pch_in
, ilen
, ":");
2923 pch_in
= g_strchomp(pch_in
);
2925 pch
= g_strstrip(pch
);
2927 g_hash_table_replace(pm
->pht_Status
, g_strdup(pch_in
), g_strdup(pch
));
2935 * Implements a Horizontal Bar Chart...
2936 * - data value has a range of 0.0 to 1.0 for 0-100% display
2937 * - in chart text is limited to about 30 chars
2939 static gboolean
cb_util_barchart_handle_exposed(GtkWidget
* widget
,
2940 GdkEventExpose
* event
, gpointer data
)
2942 PGAPC_BAR_H pbar
= data
;
2944 PangoLayout
*playout
= NULL
;
2946 g_return_val_if_fail(data
, FALSE
); /* error exit */
2950 pbar
->rect
.width
= widget
->allocation
.width
;
2951 pbar
->rect
.height
= widget
->allocation
.height
;
2953 /* scale up the less than zero data value */
2955 (gint
) ((gdouble
) (widget
->allocation
.width
/ 100.0) *
2956 (gdouble
) (pbar
->d_value
* 100.0));
2958 /* the frame of the chart */
2959 gtk_paint_box(widget
->style
, widget
->window
, GTK_WIDGET_STATE(widget
),
2960 GTK_SHADOW_ETCHED_IN
, &pbar
->rect
, widget
, "gapc_hbar_frame", 0, 0,
2961 widget
->allocation
.width
- 1, widget
->allocation
.height
- 1);
2963 /* the scaled value */
2964 gtk_paint_box(widget
->style
, widget
->window
, GTK_STATE_ACTIVE
, GTK_SHADOW_OUT
,
2965 &pbar
->rect
, widget
, "gapc_hbar_value", 1, 1, i_percent
,
2966 widget
->allocation
.height
- 4);
2968 if (pbar
->c_text
[0]) {
2971 playout
= gtk_widget_create_pango_layout(widget
, pbar
->c_text
);
2972 pango_layout_set_markup(playout
, pbar
->c_text
, -1);
2974 pango_layout_get_pixel_size(playout
, &x
, &y
);
2975 x
= (widget
->allocation
.width
- x
) / 2;
2976 y
= (widget
->allocation
.height
- y
) / 2;
2978 gtk_paint_layout(widget
->style
, widget
->window
, GTK_STATE_NORMAL
, TRUE
,
2979 &pbar
->rect
, widget
, "gapc_hbar_text",
2980 (pbar
->b_center_text
) ? x
: 6, y
, playout
);
2982 g_object_unref(playout
);
2989 * creates horizontal bar chart and allocates control data
2990 * requires cb_h_bar_chart_exposed() routine
2991 * return drawing area widget
2993 static GtkWidget
*gapc_util_barchart_create(PGAPC_MONITOR pm
, GtkWidget
* vbox
,
2994 gchar
* pch_hbar_name
, gdouble d_percent
, gchar
* pch_text
)
2996 PGAPC_BAR_H pbar
= NULL
;
2997 GtkWidget
*drawing_area
= NULL
;
3000 g_return_val_if_fail(pm
!= NULL
, NULL
);
3002 pbar
= g_new0(GAPC_BAR_H
, 1);
3003 pbar
->d_value
= d_percent
;
3004 pbar
->b_center_text
= FALSE
;
3005 g_strlcpy(pbar
->c_text
, pch_text
, sizeof(pbar
->c_text
));
3007 drawing_area
= gtk_drawing_area_new(); /* manual bargraph */
3008 gtk_widget_set_size_request(drawing_area
, 100, 20);
3009 g_signal_connect(G_OBJECT(drawing_area
), "expose_event",
3010 G_CALLBACK(cb_util_barchart_handle_exposed
), (gpointer
) pbar
);
3012 gtk_box_pack_start(GTK_BOX(vbox
), drawing_area
, TRUE
, TRUE
, 0);
3013 gtk_widget_show(drawing_area
);
3014 g_hash_table_insert(pm
->pht_Status
, g_strdup(pch_hbar_name
), pbar
);
3015 pch
= g_strdup_printf("%s-Widget", pch_hbar_name
);
3016 g_hash_table_insert(pm
->pht_Widgets
, pch
, drawing_area
);
3018 return drawing_area
;
3022 * Utility Routines for text views
3024 static gboolean
gapc_util_text_view_clear_buffer(GtkWidget
* view
)
3026 GtkTextIter start
, end
;
3027 GtkTextBuffer
*buffer
= NULL
;
3029 g_return_val_if_fail(view
!= NULL
, TRUE
);
3031 buffer
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(view
));
3032 gtk_text_buffer_get_bounds(buffer
, &start
, &end
);
3033 gtk_text_buffer_delete(buffer
, &start
, &end
);
3039 * Utility Routines for text views
3041 static void gapc_util_text_view_prepend(GtkWidget
* view
, gchar
* pch
)
3044 GtkTextBuffer
*buffer
;
3046 g_return_if_fail(view
!= NULL
);
3047 g_return_if_fail(pch
!= NULL
);
3049 buffer
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(view
));
3050 gtk_text_buffer_get_start_iter(buffer
, &iter
);
3051 gtk_text_buffer_insert(buffer
, &iter
, pch
, -1);
3055 * Utility Routines for text views
3057 static void gapc_util_text_view_append(GtkWidget
* view
, gchar
* pch
)
3060 GtkTextBuffer
*buffer
;
3062 g_return_if_fail(view
!= NULL
);
3063 g_return_if_fail(pch
!= NULL
);
3065 buffer
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(view
));
3066 gtk_text_buffer_get_end_iter(buffer
, &iter
);
3067 gtk_text_buffer_insert(buffer
, &iter
, pch
, -1);
3070 static gint
gapc_panel_monitor_model_rec_add(PGAPC_CONFIG pcfg
, PGAPC_MONITOR pm
)
3075 g_return_val_if_fail(pcfg
!= NULL
, -1);
3076 g_return_val_if_fail(pm
!= NULL
, -1);
3077 g_return_val_if_fail(pcfg
->monitor_model
!= NULL
, -1);
3078 g_return_val_if_fail(pcfg
->monitor_select
!= NULL
, -1);
3080 gtk_list_store_append(GTK_LIST_STORE(pcfg
->monitor_model
), &iter
);
3082 pch
= g_hash_table_lookup(pm
->pht_Status
, "STATUS");
3087 gtk_list_store_set(GTK_LIST_STORE(pcfg
->monitor_model
), &iter
, GAPC_MON_ICON
,
3088 pm
->my_icons
[pm
->i_icon_index
], GAPC_MON_STATUS
,
3089 pm
->ch_title_info
, GAPC_MON_MONITOR
, pm
->cb_monitor_num
,
3090 GAPC_MON_POINTER
, (gpointer
) pm
, GAPC_MON_UPSSTATE
, g_strdup(pch
), -1);
3092 gtk_tree_selection_select_iter(pcfg
->monitor_select
, &iter
);
3097 static gint
gapc_panel_preferences_model_rec_remove(PGAPC_CONFIG pcfg
)
3099 GtkTreeIter iter
, *piter
= NULL
;
3100 gboolean result
= FALSE
;
3102 gchar ch
[GAPC_MAX_TEXT
];
3103 gchar chk
[GAPC_MAX_TEXT
];
3104 GError
*gerror
= NULL
;
3106 g_return_val_if_fail(pcfg
!= NULL
, -1);
3107 g_return_val_if_fail(pcfg
->prefs_model
!= NULL
, -1);
3109 if (gtk_tree_selection_get_selected(pcfg
->prefs_select
, NULL
, &iter
)) {
3110 piter
= gtk_tree_iter_copy(&iter
);
3111 if (gtk_tree_model_iter_next(GTK_TREE_MODEL(pcfg
->prefs_model
), piter
)) {
3112 gtk_tree_selection_select_iter(pcfg
->prefs_select
, piter
);
3114 gtk_tree_iter_free(piter
);
3115 gtk_tree_model_get(GTK_TREE_MODEL(pcfg
->prefs_model
), &iter
,
3116 GAPC_PREFS_MONITOR
, &i_monitor
, -1);
3118 /* now remove the record from gconf */
3119 g_snprintf(ch
, GAPC_MAX_TEXT
, "%s/%d", GAPC_MID_GROUP_KEY
, i_monitor
);
3121 gconf_client_unset(pcfg
->client
, ch
, &gerror
);
3122 if (gerror
!= NULL
) {
3123 gapc_util_log_app_msg("gapc_panel_preferences_model_rec_remove()",
3124 "gconf_client_unset(DIR) Failed", gerror
->message
);
3125 g_error_free(gerror
);
3129 gconf_client_suggest_sync(pcfg
->client
, &gerror
);
3130 if (gerror
!= NULL
) {
3131 gapc_util_log_app_msg("gapc_panel_preferences_model_rec_remove()",
3132 "gconf_client_suggest_sync() Failed", gerror
->message
);
3133 g_error_free(gerror
);
3137 g_snprintf(chk
, GAPC_MAX_TEXT
, "%s/%s", ch
, "enabled");
3138 gconf_client_unset(pcfg
->client
, chk
, NULL
);
3140 g_snprintf(chk
, GAPC_MAX_TEXT
, "%s/%s", ch
, "use_systray");
3141 gconf_client_unset(pcfg
->client
, chk
, NULL
);
3143 g_snprintf(chk
, GAPC_MAX_TEXT
, "%s/%s", ch
, "skip_pagers");
3144 gconf_client_unset(pcfg
->client
, chk
, NULL
);
3146 g_snprintf(chk
, GAPC_MAX_TEXT
, "%s/%s", ch
, "port_number");
3147 gconf_client_unset(pcfg
->client
, chk
, NULL
);
3149 g_snprintf(chk
, GAPC_MAX_TEXT
, "%s/%s", ch
, "network_interval");
3150 gconf_client_unset(pcfg
->client
, chk
, NULL
);
3152 g_snprintf(chk
, GAPC_MAX_TEXT
, "%s/%s", ch
, "graph_interval");
3153 gconf_client_unset(pcfg
->client
, chk
, NULL
);
3155 g_snprintf(chk
, GAPC_MAX_TEXT
, "%s/%s", ch
, "host_name");
3156 gconf_client_unset(pcfg
->client
, chk
, NULL
);
3158 gconf_client_unset(pcfg
->client
, ch
, &gerror
); /* again to drop it in gconf */
3159 if (gerror
!= NULL
) {
3160 gapc_util_log_app_msg("gapc_panel_preferences_model_rec_remove()",
3161 "gconf_client_unset(DIR) Failed", gerror
->message
);
3162 g_error_free(gerror
);
3166 gconf_client_suggest_sync(pcfg
->client
, &gerror
);
3167 if (gerror
!= NULL
) {
3168 gapc_util_log_app_msg("gapc_panel_preferences_model_rec_remove()",
3169 "gconf_client_suggest_sync() Failed", gerror
->message
);
3170 g_error_free(gerror
);
3179 static gint
gapc_panel_preferences_model_rec_add(PGAPC_CONFIG pcfg
)
3181 g_return_val_if_fail(pcfg
!= NULL
, -1);
3182 g_return_val_if_fail(pcfg
->prefs_model
!= NULL
, -1);
3183 g_return_val_if_fail(pcfg
->prefs_select
!= NULL
, -1);
3185 gapc_panel_preferences_gconf_add_rec(pcfg
, ++pcfg
->prefs_last_monitor
);
3191 * EggTrayIcon Callbacks
3193 static void cb_panel_systray_icon_activated(GtkPlug
* plug
, gpointer gp
)
3195 PGAPC_CONFIG pcfg
= NULL
;
3196 PGAPC_MONITOR pm
= NULL
;
3198 g_return_if_fail(plug
!= NULL
);
3199 g_return_if_fail(gp
!= NULL
);
3201 if (((PGAPC_MONITOR
) gp
)->cb_id
== CB_MONITOR_ID
) {
3202 /* this is a monitor struct (2) */
3203 pm
= (PGAPC_MONITOR
) gp
;
3204 if (pm
->window
!= NULL
) {
3205 g_object_set(pm
->window
, "skip-pager-hint", TRUE
, "skip-taskbar-hint",
3210 /* this is a config struct (1) */
3211 pcfg
= (PGAPC_CONFIG
) gp
;
3212 if (pcfg
->window
!= NULL
) {
3213 g_object_set(pcfg
->window
, "skip-pager-hint", TRUE
, "skip-taskbar-hint",
3222 static gboolean
cb_panel_systray_icon_configure(GtkWidget
* widget
,
3223 GdkEventConfigure
* event
, gpointer gp
)
3225 PGAPC_CONFIG pcfg
= NULL
;
3226 PGAPC_MONITOR pm
= NULL
;
3228 gint
*pi_icon_size
= NULL
;
3230 g_return_val_if_fail(gp
!= NULL
, FALSE
);
3231 g_return_val_if_fail(event
!= NULL
, FALSE
);
3233 if (((PGAPC_MONITOR
) gp
)->cb_id
== CB_MONITOR_ID
) {
3234 /* this is a monitor struct (2) */
3235 pm
= (PGAPC_MONITOR
) gp
;
3236 pi_icon_size
= &pm
->i_icon_size
;
3237 pm
->i_icon_height
= event
->height
;
3238 pm
->i_icon_width
= event
->width
;
3240 /* this is a config struct (1) */
3241 pcfg
= (PGAPC_CONFIG
) gp
;
3242 pi_icon_size
= &pcfg
->i_icon_size
;
3243 pcfg
->i_icon_height
= event
->height
;
3244 pcfg
->i_icon_width
= event
->width
;
3247 *pi_icon_size
= MIN(event
->width
, event
->height
);
3251 static gboolean
cb_panel_systray_icon_handle_clicked(GtkWidget
* widget
,
3252 GdkEventButton
* event
, gpointer gp
)
3254 PGAPC_CONFIG pcfg
= NULL
;
3255 PGAPC_MONITOR pm
= NULL
;
3256 GtkWidget
*window
= NULL
;
3257 gboolean b_visible
= FALSE
;
3258 GtkWidget
*menu
= NULL
;
3260 g_return_val_if_fail(gp
!= NULL
, FALSE
);
3261 g_return_val_if_fail(widget
!= NULL
, FALSE
);
3263 if (((PGAPC_MONITOR
) gp
)->cb_id
== CB_MONITOR_ID
) {
3264 /* this is a monitor struct (2) */
3265 pm
= (PGAPC_MONITOR
) gp
;
3266 window
= pm
->window
;
3267 b_visible
= pm
->b_visible
;
3270 /* this is a config struct (1) */
3271 pcfg
= (PGAPC_CONFIG
) gp
;
3272 window
= pcfg
->window
;
3273 b_visible
= pcfg
->b_visible
;
3277 if (window
== NULL
) {
3281 if (event
->type
== GDK_BUTTON_PRESS
) {
3282 switch (event
->button
) {
3285 gtk_widget_hide(GTK_WIDGET(window
));
3287 gtk_window_present(GTK_WINDOW(window
));
3293 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
, NULL
, NULL
, event
->button
,
3307 static void cb_panel_systray_icon_destroy(GtkObject
* object
, gpointer gp
)
3309 PGAPC_CONFIG pcfg
= NULL
;
3310 PGAPC_MONITOR pm
= NULL
;
3312 g_return_if_fail(gp
!= NULL
);
3314 if (((PGAPC_MONITOR
) gp
)->cb_id
== CB_MONITOR_ID
) {
3315 /* this is a monitor struct (2) */
3316 pm
= (PGAPC_MONITOR
) gp
;
3317 pm
->tray_icon
= NULL
;
3318 pm
->tray_image
= NULL
;
3320 if (pm
->b_run
&& (pm
->window
!= NULL
)) {
3321 g_object_set(pm
->window
, "skip-pager-hint", FALSE
, "skip-taskbar-hint",
3323 gtk_window_present(GTK_WINDOW(pm
->window
));
3327 /* this is a config struct (1) */
3328 pcfg
= (PGAPC_CONFIG
) gp
;
3329 pcfg
->tray_icon
= NULL
;
3330 pcfg
->tray_image
= NULL
;
3332 if (pcfg
->b_run
&& (pcfg
->window
!= NULL
)) {
3333 g_object_set(pcfg
->window
, "skip-pager-hint", FALSE
, "skip-taskbar-hint",
3335 gtk_window_present(GTK_WINDOW(pcfg
->window
));
3342 static gboolean
gapc_panel_systray_icon_create(gpointer gp
)
3344 PGAPC_CONFIG pcfg
= NULL
;
3345 PGAPC_MONITOR pm
= NULL
;
3347 EggTrayIcon
**tray_icon
= NULL
;
3348 GtkWidget
**tray_image
= NULL
;
3349 GdkPixbuf
*pixbuf
= NULL
;
3350 GtkTooltips
*tooltips
= NULL
;
3351 gchar
*pch_title
= NULL
;
3353 g_return_val_if_fail(gp
!= NULL
, FALSE
);
3355 if (((PGAPC_MONITOR
) gp
)->cb_id
== CB_MONITOR_ID
) {
3356 /* this is a monitor struct (2) */
3357 pm
= (PGAPC_MONITOR
) gp
;
3358 tray_icon
= &pm
->tray_icon
;
3359 tray_image
= &pm
->tray_image
;
3360 tooltips
= pm
->tooltips
;
3361 pixbuf
= pm
->my_icons
[GAPC_ICON_DEFAULT
];
3363 if (!pm
->cb_use_systray
) {
3367 pch_title
= pm
->ch_title_info
;
3369 /* this is a config struct (1) */
3370 pcfg
= (PGAPC_CONFIG
) gp
;
3371 tray_icon
= &pcfg
->tray_icon
;
3372 tray_image
= &pcfg
->tray_image
;
3373 tooltips
= pcfg
->tooltips
;
3374 pixbuf
= pcfg
->my_icons
[GAPC_ICON_DEFAULT
];
3375 pch_title
= GAPC_WINDOW_TITLE
;
3377 if (!pcfg
->b_use_systray
) {
3382 g_return_val_if_fail(*tray_icon
== NULL
, FALSE
);
3383 g_return_val_if_fail(*tray_image
== NULL
, FALSE
);
3385 *tray_icon
= egg_tray_icon_new(pch_title
);
3386 g_return_val_if_fail(*tray_icon
!= NULL
, FALSE
);
3388 g_signal_connect(*tray_icon
, "embedded",
3389 G_CALLBACK(cb_panel_systray_icon_activated
), gp
);
3390 g_signal_connect(*tray_icon
, "destroy",
3391 G_CALLBACK(cb_panel_systray_icon_destroy
), gp
);
3392 g_signal_connect(*tray_icon
, "configure-event",
3393 G_CALLBACK(cb_panel_systray_icon_configure
), gp
);
3394 g_signal_connect(*tray_icon
, "button-press-event",
3395 G_CALLBACK(cb_panel_systray_icon_handle_clicked
), gp
);
3397 *tray_image
= gtk_image_new_from_pixbuf(pixbuf
);
3398 gtk_container_add(GTK_CONTAINER(*tray_icon
), *tray_image
);
3399 gtk_widget_show(*tray_image
);
3401 gtk_widget_show_all(GTK_WIDGET(*tray_icon
));
3403 if (tooltips
!= NULL
) {
3404 gtk_tooltips_set_tip(tooltips
, GTK_WIDGET(*tray_icon
), pch_title
, NULL
);
3410 static gboolean
gapc_panel_systray_icon_remove(gpointer gp
)
3412 PGAPC_CONFIG pcfg
= NULL
;
3413 PGAPC_MONITOR pm
= NULL
;
3415 EggTrayIcon
**tray_icon
= NULL
;
3416 GtkWidget
**tray_image
= NULL
;
3418 g_return_val_if_fail(gp
!= NULL
, FALSE
);
3420 if (((PGAPC_MONITOR
) gp
)->cb_id
== CB_MONITOR_ID
) {
3421 /* this is a monitor struct (2) */
3422 pm
= (PGAPC_MONITOR
) gp
;
3423 tray_icon
= &pm
->tray_icon
;
3424 tray_image
= &pm
->tray_image
;
3426 /* this is a config struct (1) */
3427 pcfg
= (PGAPC_CONFIG
) gp
;
3428 tray_icon
= &pcfg
->tray_icon
;
3429 tray_image
= &pcfg
->tray_image
;
3432 g_return_val_if_fail(*tray_icon
!= NULL
, FALSE
);
3433 g_return_val_if_fail(*tray_image
!= NULL
, FALSE
);
3435 gtk_widget_destroy(*tray_image
);
3436 gtk_widget_destroy(GTK_WIDGET(*tray_icon
));
3442 * Handle the prefs add record button action
3444 static void cb_panel_prefs_button_add_rec(GtkWidget
* button
, PGAPC_CONFIG pcfg
)
3446 g_return_if_fail(pcfg
!= NULL
);
3448 gapc_panel_preferences_model_rec_add(pcfg
);
3454 * Handle the prefs remove record button action
3456 static void cb_panel_prefs_button_remove_rec(GtkWidget
* button
, PGAPC_CONFIG pcfg
)
3458 g_return_if_fail(pcfg
!= NULL
);
3460 gapc_panel_preferences_model_rec_remove(pcfg
);
3466 * Handle the prefs use-systray checkbutton action
3468 static void cb_panel_prefs_button_use_systray(GtkWidget
* button
, PGAPC_CONFIG pcfg
)
3470 gboolean b_value
= FALSE
;
3473 g_return_if_fail(pcfg
!= NULL
);
3475 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button
))) {
3481 pch
= pcfg
->pch_gkeys
[GAPC_PREFS_SYSTRAY
];
3482 gconf_client_set_bool(pcfg
->client
, pch
, b_value
, NULL
);
3488 * Handled the toggle of a checkbox in the preferences dialog
3490 * enabled - enabled this monitor to run
3491 * systray - include the notification tray icon
3492 * pagers - remove from task_list and pager_list
3494 static void cb_panel_prefs_handle_cell_toggled(GtkCellRendererToggle
* cell
,
3495 gchar
* path_str
, PGAPC_PREFS_COLUMN pcolumn
)
3497 GtkTreeModel
*model
;
3499 GtkTreePath
*path
= NULL
;
3501 gint col_number
= 0, i_monitor
= 0;
3502 gchar
*penabled
= NULL
;
3504 g_return_if_fail(pcolumn
!= NULL
);
3505 g_return_if_fail(path_str
!= NULL
);
3507 model
= pcolumn
->prefs_model
;
3508 col_number
= pcolumn
->i_col_num
;
3510 /* get toggled iter */
3511 path
= gtk_tree_path_new_from_string(path_str
);
3512 gtk_tree_model_get_iter(model
, &iter
, path
);
3513 gtk_tree_path_free(path
);
3515 /* get the column id they asked for -- hope its boolean */
3516 gtk_tree_model_get(model
, &iter
, col_number
, &b_value
, GAPC_PREFS_MONITOR
,
3519 /* do something with the value */
3522 switch (col_number
) {
3523 case GAPC_PREFS_ENABLED
:
3524 penabled
= g_strdup_printf(GAPC_ENABLE_KEY
, i_monitor
);
3525 gconf_client_set_bool(pcolumn
->client
, penabled
, b_value
, NULL
);
3528 case GAPC_PREFS_SYSTRAY
:
3529 penabled
= g_strdup_printf(GAPC_SYSTRAY_KEY
, i_monitor
);
3530 gconf_client_set_bool(pcolumn
->client
, penabled
, b_value
, NULL
);
3534 g_message("Cell_Toggled:Unknown key for Value(%s)\n",
3535 b_value
? "True" : "False");
3543 * A callback routine that collect changes to the path row and save it directly
3544 * to the desired location, also passes it back to the treeview for display.
3545 * These data point use this routine.
3550 * - Monitor - not a visible field
3551 * We update gconf here and gconf updates the
3552 * list_store in cb_panel_preference_gconf_changed()
3554 static void cb_panel_prefs_handle_cell_edited(GtkCellRendererText
* cell
,
3555 gchar
* path_string
, gchar
* pch_new
, PGAPC_PREFS_COLUMN pcolumn
)
3557 GtkTreeModel
*model
;
3560 gint col_number
= 0, i_port
= 0, i_monitor
= 0, i_len
= 0;
3561 gfloat f_refresh
= 0.0, f_graph
= 0.0;
3562 gchar ch
[GAPC_MAX_TEXT
], *pch
= NULL
;
3563 gboolean b_dupped
= FALSE
;
3565 g_return_if_fail(pcolumn
!= NULL
);
3566 g_return_if_fail(pch_new
!= NULL
);
3567 g_return_if_fail(path_string
!= NULL
);
3569 model
= pcolumn
->prefs_model
;
3570 col_number
= pcolumn
->i_col_num
;
3572 i_len
= g_snprintf(ch
, GAPC_MAX_TEXT
, "%s", pch_new
);
3574 * get iter to record
3576 path
= gtk_tree_path_new_from_string(path_string
);
3577 gtk_tree_model_get_iter(model
, &iter
, path
);
3578 gtk_tree_path_free(path
);
3581 * get data from that row
3583 gtk_tree_model_get(model
, &iter
, GAPC_PREFS_MONITOR
, &i_monitor
, -1);
3585 switch (col_number
) {
3586 case GAPC_PREFS_HOST
:
3588 gchar
*phost
= g_strdup_printf(GAPC_HOST_KEY
, i_monitor
);
3590 if ((pch_new
== NULL
) || (i_len
< 2)) {
3591 pch
= g_strdup(GAPC_HOST_DEFAULT
);
3596 gconf_client_set_string(pcolumn
->client
, phost
, pch
, NULL
);
3600 case GAPC_PREFS_PORT
:
3602 gchar
*pport
= g_strdup_printf(GAPC_PORT_KEY
, i_monitor
);
3604 i_port
= (gint
) g_strtod(pch_new
, NULL
);
3607 i_port
= GAPC_PORT_DEFAULT
;
3608 pch
= g_strdup_printf("%d", i_port
);
3613 gconf_client_set_int(pcolumn
->client
, pport
, i_port
, NULL
);
3617 case GAPC_PREFS_WATT
:
3619 gchar
*pport
= g_strdup_printf(GAPC_WATT_KEY
, i_monitor
);
3621 i_port
= (gint
) g_strtod(pch_new
, NULL
);
3624 i_port
= GAPC_WATT_DEFAULT
;
3625 pch
= g_strdup_printf("%d", i_port
);
3630 gconf_client_set_int(pcolumn
->client
, pport
, i_port
, NULL
);
3634 case GAPC_PREFS_REFRESH
:
3636 gchar
*prefresh
= g_strdup_printf(GAPC_REFRESH_KEY
, i_monitor
);
3638 f_refresh
= (gfloat
) g_strtod(pch_new
, NULL
);
3640 if (f_refresh
< GAPC_REFRESH_MIN_INCREMENT
) {
3641 f_refresh
= GAPC_REFRESH_DEFAULT
;
3642 pch
= g_strdup_printf("%3.1f", f_refresh
);
3647 gconf_client_set_float(pcolumn
->client
, prefresh
, f_refresh
, NULL
);
3651 case GAPC_PREFS_GRAPH
:
3653 gchar
*prefresh
= g_strdup_printf(GAPC_GRAPH_KEY
, i_monitor
);
3655 f_graph
= (gfloat
) g_strtod(pch_new
, NULL
);
3657 if (f_graph
< GAPC_REFRESH_MIN_INCREMENT
) {
3658 f_graph
= GAPC_LINEGRAPH_REFRESH_FACTOR
;
3659 pch
= g_strdup_printf("%3.1f", f_graph
);
3664 gconf_client_set_float(pcolumn
->client
, prefresh
, f_graph
, NULL
);
3669 g_message("Cell_Edited:Unknown key for Value(%s)\n", pch_new
);
3670 g_object_set(cell
, "text", pch_new
, NULL
);
3674 if ((pch
!= NULL
) && !b_dupped
) {
3682 * Cell data function used to format floating point numbers
3683 * This gets called a thousand times...
3685 static void cb_panel_prefs_handle_float_format(GtkTreeViewColumn
* col
,
3686 GtkCellRenderer
* renderer
, GtkTreeModel
* model
, GtkTreeIter
* iter
, gpointer gp
)
3691 gchar
*pch_format
= NULL
;
3693 g_return_if_fail(gp
!= NULL
);
3695 colnum
= GPOINTER_TO_UINT(gp
);
3697 pch_format
= (gchar
*) g_object_get_data(G_OBJECT(col
), "float_format");
3699 gtk_tree_model_get(model
, iter
, colnum
, &d_value
, -1);
3702 g_snprintf(buf
, sizeof(buf
), pch_format
, d_value
);
3704 g_snprintf(buf
, sizeof(buf
), "%3.0f", d_value
);
3707 g_object_set(renderer
, "text", buf
, NULL
);
3712 /* This routine initializes a user-data structure for use by the renderers of
3713 * the preference treeview
3715 static PGAPC_PREFS_COLUMN
gapc_panel_prefs_col_data_init(PGAPC_CONFIG pcfg
,
3716 GAPC_PrefsType col_num
)
3718 PGAPC_PREFS_COLUMN pcol
= NULL
;
3720 pcol
= g_new0(GAPC_PREFS_COLUMN
, 1);
3721 g_return_val_if_fail(pcol
!= NULL
, NULL
);
3723 pcol
->cb_id
= CB_COLUMN_ID
;
3724 pcol
->prefs_model
= pcfg
->prefs_model
;
3725 pcol
->i_col_num
= col_num
;
3726 pcol
->client
= pcfg
->client
;
3732 * Gets the gconf instance preferences for all monitors
3733 * and loads the prefs_model.
3734 * returns FALSE on error
3735 * returns TRUE on sucess
3737 static gboolean
gapc_panel_preferences_data_model_load(PGAPC_CONFIG pcfg
)
3739 GError
*gerror
= NULL
;
3740 GSList
*monitors
= NULL
;
3742 gboolean b_valid
= FALSE
;
3744 gboolean v_use_systray
;
3747 gfloat v_network_interval
;
3748 gfloat v_graph_interval
;
3751 gchar k_enabled
[GAPC_MAX_TEXT
];
3752 gchar k_use_systray
[GAPC_MAX_TEXT
];
3753 gchar k_port_number
[GAPC_MAX_TEXT
];
3754 gchar k_network_interval
[GAPC_MAX_TEXT
];
3755 gchar k_graph_interval
[GAPC_MAX_TEXT
];
3756 gchar k_host_name
[GAPC_MAX_TEXT
];
3757 gchar k_watt_number
[GAPC_MAX_TEXT
];
3759 g_return_val_if_fail(pcfg
!= NULL
, FALSE
);
3760 g_return_val_if_fail(pcfg
->client
!= NULL
, FALSE
);
3761 g_return_val_if_fail(pcfg
->prefs_model
!= NULL
, FALSE
);
3763 b_valid
= gconf_client_dir_exists(pcfg
->client
, GAPC_MID_GROUP_KEY
, &gerror
);
3764 if (gerror
!= NULL
) {
3765 gapc_util_log_app_msg("gapc_panel_preferences_data_model_load",
3766 "gconf_dir_exists() Failed", gerror
->message
);
3767 g_error_free(gerror
);
3773 if (b_valid
== FALSE
) {
3774 gapc_util_log_app_msg("gapc_panel_preferences_data_model_load",
3775 "No monitors predefined.", "very first startup");
3779 monitors
= gconf_client_all_dirs(pcfg
->client
, GAPC_MID_GROUP_KEY
, &gerror
);
3780 if (gerror
!= NULL
) {
3781 gapc_util_log_app_msg("gapc_panel_preferences_data_model_load",
3782 "gconf_client_all_dirs() Failed", gerror
->message
);
3783 g_error_free(gerror
);
3788 while (monitors
) { /* should be the regular text key */
3791 GtkWidget
*widget
= NULL
;
3793 pmon
= g_strrstr((gchar
*) monitors
->data
, "/");
3795 i_monitor
= (gint
) g_strtod(pmon
+ 1, NULL
);
3796 pcfg
->prefs_last_monitor
= MAX(pcfg
->prefs_last_monitor
, i_monitor
);
3798 g_free(monitors
->data
);
3799 monitors
= g_slist_next(monitors
);
3803 g_snprintf(k_enabled
, GAPC_MAX_TEXT
, "%s/%s", (gchar
*) monitors
->data
,
3805 g_snprintf(k_use_systray
, GAPC_MAX_TEXT
, "%s/%s", (gchar
*) monitors
->data
,
3807 g_snprintf(k_port_number
, GAPC_MAX_TEXT
, "%s/%s", (gchar
*) monitors
->data
,
3809 g_snprintf(k_watt_number
, GAPC_MAX_TEXT
, "%s/%s", (gchar
*) monitors
->data
,
3811 g_snprintf(k_network_interval
, GAPC_MAX_TEXT
, "%s/%s",
3812 (gchar
*) monitors
->data
, "network_interval");
3813 g_snprintf(k_graph_interval
, GAPC_MAX_TEXT
, "%s/%s", (gchar
*) monitors
->data
,
3815 g_snprintf(k_host_name
, GAPC_MAX_TEXT
, "%s/%s", (gchar
*) monitors
->data
,
3818 v_enabled
= gconf_client_get_bool(pcfg
->client
, k_enabled
, NULL
);
3819 v_use_systray
= gconf_client_get_bool(pcfg
->client
, k_use_systray
, NULL
);
3820 v_port_number
= gconf_client_get_int(pcfg
->client
, k_port_number
, NULL
);
3821 if (v_port_number
== 0) {
3822 v_port_number
= GAPC_PORT_DEFAULT
;
3824 v_watt_number
= gconf_client_get_int(pcfg
->client
, k_watt_number
, NULL
);
3825 if (v_watt_number
== 0) {
3826 v_watt_number
= GAPC_WATT_DEFAULT
;
3828 v_network_interval
=
3829 gconf_client_get_float(pcfg
->client
, k_network_interval
, NULL
);
3830 if (v_network_interval
== 0.0) {
3831 v_network_interval
= GAPC_REFRESH_DEFAULT
;
3834 gconf_client_get_float(pcfg
->client
, k_graph_interval
, NULL
);
3835 if (v_graph_interval
== 0.0) {
3836 v_graph_interval
= GAPC_LINEGRAPH_REFRESH_FACTOR
;
3838 v_host_name
= gconf_client_get_string(pcfg
->client
, k_host_name
, NULL
);
3839 if (v_host_name
== NULL
) {
3840 v_host_name
= g_strdup(GAPC_HOST_DEFAULT
);
3843 gtk_list_store_append(GTK_LIST_STORE(pcfg
->prefs_model
), &iter
);
3844 gtk_list_store_set(GTK_LIST_STORE(pcfg
->prefs_model
), &iter
,
3845 GAPC_PREFS_MONITOR
, i_monitor
,
3846 GAPC_PREFS_SYSTRAY
, v_use_systray
,
3847 GAPC_PREFS_ENABLED
, v_enabled
,
3848 GAPC_PREFS_PORT
, v_port_number
,
3849 GAPC_PREFS_REFRESH
, v_network_interval
,
3850 GAPC_PREFS_GRAPH
, v_graph_interval
,
3851 GAPC_PREFS_HOST
, v_host_name
,
3852 GAPC_PREFS_WATT
, v_watt_number
,
3855 /* Startup Processing */
3857 widget
= gapc_monitor_interface_create(pcfg
, i_monitor
, &iter
);
3858 if ((widget
!= NULL
) && !v_use_systray
) {
3859 gtk_window_present( GTK_WINDOW(widget
));
3862 g_free(monitors
->data
);
3863 monitors
= g_slist_next(monitors
);
3865 g_slist_free(monitors
);
3871 * Create a data model to hold the preferences for this program. We are
3872 * using the list store model to hold the all data. Then we create the
3873 * complete GtkTreeView and initialize the columns.
3874 * returns GtkTreeView or NULL
3876 static GtkWidget
*gapc_panel_preferences_model_init(PGAPC_CONFIG pcfg
)
3878 GtkWidget
*treeview
= NULL
;
3879 GtkTreeModel
*model
= NULL
;
3880 GtkTreeViewColumn
*column
= NULL
;
3881 GtkCellRenderer
*renderer_enabled
= NULL
, *renderer_systray
= NULL
,
3882 *renderer_port
= NULL
, *renderer_watt
= NULL
, *renderer_refresh
= NULL
,
3883 *renderer_graph
= NULL
, *renderer_host
= NULL
, *anyrndr
= NULL
;
3884 PGAPC_PREFS_COLUMN col_enabled
= NULL
, col_systray
= NULL
, col_port
= NULL
,
3885 col_refresh
= NULL
, col_graph
= NULL
, col_host
= NULL
, col_watt
= NULL
;
3887 g_return_val_if_fail(pcfg
!= NULL
, NULL
);
3889 /* Don't create it twice */
3890 if (pcfg
->prefs_treeview
!= NULL
)
3891 return GTK_WIDGET(pcfg
->prefs_treeview
);
3893 /* Create the model -- this column order and that of the enum must match */
3894 model
= GTK_TREE_MODEL(gtk_list_store_new(GAPC_N_PREFS_COLUMNS
,
3895 G_TYPE_INT
, /* Monitor base-1 */
3896 G_TYPE_BOOLEAN
, /* enabled */
3897 G_TYPE_BOOLEAN
, /* systray icon */
3898 G_TYPE_INT
, /* Port */
3899 G_TYPE_FLOAT
, /* network Refresh */
3900 G_TYPE_FLOAT
, /* graph Refresh */
3901 G_TYPE_STRING
, /* Host */
3902 G_TYPE_INT
/* Wattage */
3904 /* store it for later */
3905 pcfg
->prefs_model
= model
;
3907 /* load the data model */
3908 gapc_panel_preferences_data_model_load(pcfg
);
3910 /* create the display columns and treeview */
3911 treeview
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(model
));
3912 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(treeview
));
3913 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview
), TRUE
);
3914 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(treeview
), FALSE
);
3916 /* allocate control struct for viewable columns */
3917 col_enabled
= gapc_panel_prefs_col_data_init(pcfg
, GAPC_PREFS_ENABLED
);
3918 col_systray
= gapc_panel_prefs_col_data_init(pcfg
, GAPC_PREFS_SYSTRAY
);
3919 col_port
= gapc_panel_prefs_col_data_init(pcfg
, GAPC_PREFS_PORT
);
3920 col_watt
= gapc_panel_prefs_col_data_init(pcfg
, GAPC_PREFS_WATT
);
3921 col_refresh
= gapc_panel_prefs_col_data_init(pcfg
, GAPC_PREFS_REFRESH
);
3922 col_graph
= gapc_panel_prefs_col_data_init(pcfg
, GAPC_PREFS_GRAPH
);
3923 col_host
= gapc_panel_prefs_col_data_init(pcfg
, GAPC_PREFS_HOST
);
3925 /* create display formatters where needed */
3926 renderer_enabled
= gtk_cell_renderer_toggle_new();
3927 renderer_systray
= gtk_cell_renderer_toggle_new();
3928 renderer_port
= gtk_cell_renderer_text_new();
3929 renderer_watt
= gtk_cell_renderer_text_new();
3930 renderer_refresh
= gtk_cell_renderer_text_new();
3931 renderer_graph
= gtk_cell_renderer_text_new();
3932 renderer_host
= gtk_cell_renderer_text_new();
3933 anyrndr
= gtk_cell_renderer_text_new();
3935 /* set renderers attributes */
3936 g_object_set(G_OBJECT(renderer_port
), "xalign", 0.5, "editable", TRUE
, NULL
);
3937 g_object_set(G_OBJECT(renderer_watt
), "xalign", 0.5, "editable", TRUE
, NULL
);
3938 g_object_set(G_OBJECT(renderer_graph
), "xalign", 0.5, "editable", TRUE
, NULL
);
3939 g_object_set(G_OBJECT(renderer_refresh
), "xalign", 0.5, "editable", TRUE
, NULL
);
3940 g_object_set(G_OBJECT(renderer_host
), "editable", TRUE
, NULL
);
3943 /* prepare callbacks to correctly handle the columns
3944 * careful to use these only once per column --
3945 * using an auto g_free to release allocated storage
3947 gtk_signal_connect_full(GTK_OBJECT(renderer_enabled
), "toggled",
3948 G_CALLBACK(cb_panel_prefs_handle_cell_toggled
), NULL
,
3949 col_enabled
, g_free
, FALSE
, TRUE
);
3950 gtk_signal_connect_full(GTK_OBJECT(renderer_systray
), "toggled",
3951 G_CALLBACK(cb_panel_prefs_handle_cell_toggled
), NULL
,
3952 col_systray
, g_free
, FALSE
, TRUE
);
3953 gtk_signal_connect_full(GTK_OBJECT(renderer_port
), "edited",
3954 G_CALLBACK(cb_panel_prefs_handle_cell_edited
), NULL
,
3955 col_port
, g_free
, FALSE
, TRUE
);
3956 gtk_signal_connect_full(GTK_OBJECT(renderer_watt
), "edited",
3957 G_CALLBACK(cb_panel_prefs_handle_cell_edited
), NULL
,
3958 col_watt
, g_free
, FALSE
, TRUE
);
3959 gtk_signal_connect_full(GTK_OBJECT(renderer_refresh
), "edited",
3960 G_CALLBACK(cb_panel_prefs_handle_cell_edited
), NULL
,
3961 col_refresh
, g_free
, FALSE
, TRUE
);
3962 gtk_signal_connect_full(GTK_OBJECT(renderer_graph
), "edited",
3963 G_CALLBACK(cb_panel_prefs_handle_cell_edited
), NULL
,
3964 col_graph
, g_free
, FALSE
, TRUE
);
3965 gtk_signal_connect_full(GTK_OBJECT(renderer_host
), "edited",
3966 G_CALLBACK(cb_panel_prefs_handle_cell_edited
), NULL
,
3967 col_host
, g_free
, FALSE
, TRUE
);
3969 /* Define the column order and attributes */
3970 column
= gtk_tree_view_column_new_with_attributes("Enabled", renderer_enabled
,
3971 "active", GAPC_PREFS_ENABLED
, NULL
);
3972 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
3974 column
= gtk_tree_view_column_new_with_attributes("use\nTrayIcon",
3975 renderer_systray
, "active", GAPC_PREFS_SYSTRAY
, NULL
);
3976 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
3978 column
= gtk_tree_view_column_new_with_attributes("network\nRefresh",
3979 renderer_refresh
, "text", GAPC_PREFS_REFRESH
, NULL
);
3980 g_object_set_data(G_OBJECT(column
), "float_format", "%3.1f");
3981 gtk_tree_view_column_set_cell_data_func(column
, renderer_refresh
,
3982 cb_panel_prefs_handle_float_format
,
3983 GUINT_TO_POINTER(GAPC_PREFS_REFRESH
), NULL
);
3984 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
3986 column
= gtk_tree_view_column_new_with_attributes("Port", renderer_port
, "text",
3987 GAPC_PREFS_PORT
, NULL
);
3988 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
3990 column
= gtk_tree_view_column_new_with_attributes("graph\nRefresh",
3991 renderer_graph
, "text", GAPC_PREFS_GRAPH
, NULL
);
3992 g_object_set_data(G_OBJECT(column
), "float_format", "%3.0f");
3993 gtk_tree_view_column_set_cell_data_func(column
, renderer_graph
,
3994 cb_panel_prefs_handle_float_format
, GUINT_TO_POINTER(GAPC_PREFS_GRAPH
), NULL
);
3995 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
3997 column
= gtk_tree_view_column_new_with_attributes("Rated\nWattage", renderer_watt
, "text",
3998 GAPC_PREFS_WATT
, NULL
);
3999 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
4001 column
= gtk_tree_view_column_new_with_attributes("Host Name or IP Address",
4002 renderer_host
, "text", GAPC_PREFS_HOST
, NULL
);
4003 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
4005 column
= gtk_tree_view_column_new_with_attributes("Monitor", anyrndr
,
4006 "text", GAPC_PREFS_MONITOR
, NULL
);
4007 gtk_tree_view_column_set_sort_column_id(column
, GAPC_PREFS_MONITOR
);
4008 gtk_tree_view_column_clicked(column
);
4009 g_object_set(G_OBJECT(column
), "visible", FALSE
, NULL
);
4010 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
4016 * Create a data model to hold the current list of active monitors. We are
4017 * using the list store model to hold the active data. Then we create the
4018 * complete GtkTreeView and initialize the columns.
4019 * returns GtkTreeView or NULL
4021 static GtkWidget
*gapc_panel_monitors_model_init(PGAPC_CONFIG pcfg
)
4023 GtkWidget
*treeview
= NULL
;
4024 GtkTreeModel
*model
= NULL
;
4025 GtkCellRenderer
*renderer_icon
= NULL
, *renderer_text
= NULL
,
4026 *renderer_state
= NULL
, *renderer_any
= NULL
;
4027 GtkTreeViewColumn
*column
= NULL
;
4029 g_return_val_if_fail(pcfg
!= NULL
, NULL
);
4031 /* Don't create it twice */
4032 if (pcfg
->monitor_treeview
!= NULL
)
4033 return GTK_WIDGET(pcfg
->monitor_treeview
);
4035 /* Create the model -- this column order and that of the enum must match */
4036 model
= GTK_TREE_MODEL(gtk_list_store_new(GAPC_N_MON_COLUMNS
, G_TYPE_INT
, /* Monitor Num */
4037 GDK_TYPE_PIXBUF
, /* ICON */
4038 G_TYPE_STRING
, /* Status Text */
4039 G_TYPE_POINTER
, /* monitor ptr */
4040 G_TYPE_STRING
/* State Text */
4042 /* store it for later */
4043 pcfg
->monitor_model
= model
;
4045 /* create the display columns and treeview */
4046 treeview
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(model
));
4047 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview
), TRUE
);
4048 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(treeview
));
4049 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(treeview
), FALSE
);
4050 g_signal_connect(treeview
, "row-activated",
4051 G_CALLBACK(cb_panel_monitor_list_activated
), pcfg
);
4053 renderer_icon
= gtk_cell_renderer_pixbuf_new();
4054 renderer_text
= gtk_cell_renderer_text_new();
4055 renderer_state
= gtk_cell_renderer_text_new();
4056 renderer_any
= gtk_cell_renderer_text_new();
4057 g_object_set(G_OBJECT(renderer_state
), "xalign", 0.5, NULL
);
4058 g_object_set(G_OBJECT(renderer_text
), "xalign", 0.0, NULL
);
4059 g_object_set(G_OBJECT(renderer_text
), "yalign", 0.5, NULL
);
4062 column
= gtk_tree_view_column_new();
4064 gtk_tree_view_column_set_title(column
, "Status");
4066 gtk_tree_view_column_pack_start(column
, renderer_icon
, TRUE
);
4068 gtk_tree_view_column_add_attribute(column
, renderer_icon
, "pixbuf",
4071 gtk_tree_view_column_pack_end(column
, renderer_state
, FALSE
);
4073 gtk_tree_view_column_add_attribute(column
, renderer_state
, "markup",
4076 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
4078 column
= gtk_tree_view_column_new_with_attributes("Current summary ups info",
4079 renderer_text
, "markup", GAPC_MON_STATUS
, NULL
);
4080 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
4082 column
= gtk_tree_view_column_new_with_attributes("Monitor", renderer_any
,
4083 "text", GAPC_MON_MONITOR
, NULL
);
4084 gtk_tree_view_column_set_sort_column_id(column
, GAPC_MON_MONITOR
);
4085 g_object_set(G_OBJECT(column
), "visible", FALSE
, NULL
);
4086 gtk_tree_view_column_clicked(column
);
4087 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview
), column
);
4094 * Load ICONs and set default icon
4095 * return TRUE if ok, FALSE otherwise
4097 static gboolean
gapc_util_load_icons(PGAPC_CONFIG pcfg
)
4099 guint i_x
= 0, x
= 0;
4100 GError
*gerror
= NULL
;
4101 GdkPixbuf
*pixbuf
= NULL
;
4102 gboolean b_rc
= TRUE
;
4103 gchar pch_file
[GAPC_MAX_ARRAY
];
4104 gchar
*pch_2
= "./";
4105 gchar
*pch_3
= "../pixmaps/";
4106 gchar
*pch_4
= NULL
;
4107 gchar
*pch_image_names
[] = {
4117 g_return_val_if_fail(pcfg
!= NULL
, FALSE
);
4119 /* build system path for icons */
4120 pch_4
= g_strconcat (ICON_DIR
, "/pixmaps/", NULL
);
4124 if (g_file_test(pch_image_names
[0], G_FILE_TEST_EXISTS
)) {
4129 g_snprintf(pch_file
, GAPC_MAX_ARRAY
, "%s%s", pch_2
, pch_image_names
[0]);
4130 if (g_file_test(pch_file
, G_FILE_TEST_EXISTS
)) {
4135 g_snprintf(pch_file
, GAPC_MAX_ARRAY
, "%s%s", pch_3
, pch_image_names
[0]);
4136 if (g_file_test(pch_file
, G_FILE_TEST_EXISTS
)) {
4141 g_snprintf(pch_file
, GAPC_MAX_ARRAY
, "%s%s", pch_4
, pch_image_names
[0]);
4142 if (g_file_test(pch_file
, G_FILE_TEST_EXISTS
)) {
4151 gapc_util_log_app_msg("gapc_util_load_icons", "Unable to find icons",
4157 for (x
= 0; (pch_image_names
[x
] != NULL
) && (x
< GAPC_N_ICONS
); x
++) {
4160 g_snprintf(pch_file
, GAPC_MAX_ARRAY
, "%s", pch_image_names
[x
]);
4163 g_snprintf(pch_file
, GAPC_MAX_ARRAY
, "%s%s", pch_2
, pch_image_names
[x
]);
4166 g_snprintf(pch_file
, GAPC_MAX_ARRAY
, "%s%s", pch_3
, pch_image_names
[x
]);
4169 g_snprintf(pch_file
, GAPC_MAX_ARRAY
, "%s%s", pch_4
, pch_image_names
[x
]);
4172 g_return_val_if_reached(FALSE
);
4176 pixbuf
= gdk_pixbuf_new_from_file(pch_file
, &gerror
);
4177 if (gerror
!= NULL
) {
4180 pch
= g_strdup_printf("Get Icon=%s Failed", pch_file
);
4181 gapc_util_log_app_msg("gapc_util_load_icons", pch
, gerror
->message
);
4182 g_error_free(gerror
);
4186 pcfg
->my_icons
[x
] = NULL
;
4189 gdk_pixbuf_scale_simple(pixbuf
, GAPC_ICON_SIZE
, GAPC_ICON_SIZE
,
4190 GDK_INTERP_BILINEAR
);
4191 g_object_unref(pixbuf
);
4200 * Monitor List "row-activated"
4202 static void cb_panel_monitor_list_activated(GtkTreeView
* treeview
,
4203 GtkTreePath
* arg1
, GtkTreeViewColumn
* arg2
, PGAPC_CONFIG pcfg
)
4205 PGAPC_MONITOR pm
= NULL
;
4208 g_return_if_fail(pcfg
!= NULL
);
4210 if (gtk_tree_model_get_iter(pcfg
->monitor_model
, &iter
, arg1
)) {
4211 gtk_tree_model_get(pcfg
->monitor_model
, &iter
, GAPC_MON_POINTER
, &pm
, -1);
4213 if ((pm
!= NULL
) && (pm
->window
!= NULL
)) {
4214 if (pm
->b_visible
) {
4215 gtk_widget_hide(GTK_WIDGET(pm
->window
));
4217 gtk_window_present(GTK_WINDOW(pm
->window
));
4226 * Active monitor selection
4228 static void cb_panel_monitor_list_selection(GtkTreeSelection
* selection
,
4232 GtkTreeModel
*model
;
4235 g_return_if_fail(pcfg
!= NULL
);
4237 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
)) {
4238 gtk_tree_model_get(model
, &iter
, GAPC_MON_MONITOR
, &i_monitor
, -1);
4240 pcfg
->cb_last_monitor
= i_monitor
;
4247 * The Active Monitor Icon List for the information window
4248 * returns created notebook page number.
4250 static gint
gapc_panel_monitor_list_page(PGAPC_CONFIG pcfg
, GtkNotebook
* notebook
)
4252 GtkWidget
*label
= NULL
, *frame
= NULL
, *vbox
= NULL
, *sw
= NULL
;
4253 GtkWidget
*treeview
= NULL
;
4254 GtkTreeSelection
*select
= NULL
;
4259 g_return_val_if_fail(pcfg
!= NULL
, -1);
4260 g_return_val_if_fail(notebook
!= NULL
, -1);
4262 /* Create notebook page */
4263 frame
= gtk_frame_new(NULL
);
4264 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
4265 label
= gtk_label_new("Active Monitors");
4266 i_page
= gtk_notebook_append_page(notebook
, frame
, label
);
4267 gtk_widget_show(frame
);
4269 label
= gtk_label_new("<span foreground=\"blue\">"
4270 "<i>double-click a row to popup information window.</i>" "</span>");
4271 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
4272 gtk_label_set_justify(GTK_LABEL(label
), GTK_JUSTIFY_CENTER
);
4274 vbox
= gtk_event_box_new();
4275 gtk_container_add(GTK_CONTAINER(frame
), vbox
);
4276 gtk_widget_show(vbox
);
4277 frame
= gtk_frame_new("");
4278 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_IN
);
4279 gtk_frame_set_label_widget(GTK_FRAME(frame
), label
);
4280 gtk_frame_set_label_align(GTK_FRAME(frame
), 0.5, 0.8);
4281 gtk_container_add(GTK_CONTAINER(vbox
), frame
);
4282 gtk_widget_show(frame
);
4284 /* Create the container for the icon view */
4285 sw
= gtk_scrolled_window_new(NULL
, NULL
);
4286 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
),
4287 GTK_SHADOW_ETCHED_IN
);
4288 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_NEVER
,
4289 GTK_POLICY_AUTOMATIC
);
4290 gtk_container_add(GTK_CONTAINER(frame
), sw
);
4291 gtk_widget_show(sw
);
4293 /* create the active monitor list in a treeview */
4294 treeview
= gapc_panel_monitors_model_init(pcfg
);
4295 pcfg
->monitor_treeview
= GTK_TREE_VIEW(treeview
);
4296 gtk_container_add(GTK_CONTAINER(sw
), treeview
);
4297 gtk_widget_show(GTK_WIDGET(treeview
));
4299 /* Setup the selection handler */
4300 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview
));
4301 pcfg
->monitor_select
= select
;
4302 gtk_tree_selection_set_mode(select
, GTK_SELECTION_SINGLE
);
4303 g_signal_connect(G_OBJECT(select
), "changed",
4304 G_CALLBACK(cb_panel_monitor_list_selection
), pcfg
);
4306 /* Selection the first record */
4307 if (gtk_tree_model_get_iter_first(pcfg
->monitor_model
, &iter
)) {
4308 gtk_tree_selection_select_iter(select
, &iter
);
4315 * The Preferences List for the information window
4316 * returns created notebook page number.
4318 static gint
gapc_panel_preferences_page(PGAPC_CONFIG pcfg
, GtkNotebook
* notebook
)
4320 GtkWidget
*label
= NULL
, *frame
= NULL
, *vbox
= NULL
, *sw
= NULL
;
4321 GtkWidget
*pbox
= NULL
, *box
= NULL
, *cbox
= NULL
;
4322 GtkWidget
*treeview
= NULL
;
4323 GtkTreeSelection
*select
= NULL
;
4327 g_return_val_if_fail(pcfg
!= NULL
, -1);
4328 g_return_val_if_fail(notebook
!= NULL
, -1);
4330 /* Create notebook page */
4331 frame
= gtk_frame_new(NULL
);
4332 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
4333 label
= gtk_label_new("Preferences");
4334 i_page
= gtk_notebook_append_page(notebook
, frame
, label
);
4335 gtk_widget_show(frame
);
4337 label
= gtk_label_new("<span foreground=\"blue\">"
4338 "<i>double-click a columns value to change it.</i>" "</span>");
4339 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
4340 gtk_label_set_justify(GTK_LABEL(label
), GTK_JUSTIFY_CENTER
);
4342 box
= gtk_event_box_new();
4343 gtk_container_add(GTK_CONTAINER(frame
), box
);
4344 gtk_widget_show(box
);
4345 vbox
= gtk_vbox_new(FALSE
, 0);
4346 gtk_container_add(GTK_CONTAINER(box
), vbox
);
4347 gtk_widget_show(vbox
);
4348 frame
= gtk_frame_new("");
4349 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_IN
);
4350 gtk_frame_set_label_widget(GTK_FRAME(frame
), label
);
4351 gtk_frame_set_label_align(GTK_FRAME(frame
), 0.5, 0.8);
4352 gtk_container_add(GTK_CONTAINER(vbox
), frame
);
4353 gtk_widget_show(frame
);
4354 pbox
= gtk_vbox_new(FALSE
, 0);
4355 gtk_container_add(GTK_CONTAINER(frame
), pbox
);
4356 gtk_widget_show(pbox
);
4358 /* Create the container for the icon view */
4359 sw
= gtk_scrolled_window_new(NULL
, NULL
);
4360 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
),
4361 GTK_SHADOW_ETCHED_IN
);
4362 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_NEVER
,
4363 GTK_POLICY_AUTOMATIC
);
4364 gtk_container_add(GTK_CONTAINER(pbox
), sw
);
4365 gtk_widget_show(sw
);
4367 /* create the preferences in a treeview */
4368 treeview
= gapc_panel_preferences_model_init(pcfg
);
4369 pcfg
->prefs_treeview
= GTK_TREE_VIEW(treeview
);
4370 gtk_container_add(GTK_CONTAINER(sw
), treeview
);
4371 gtk_widget_show(GTK_WIDGET(treeview
));
4373 /* Setup the selection handler */
4374 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview
));
4375 pcfg
->prefs_select
= select
;
4376 gtk_tree_selection_set_mode(select
, GTK_SELECTION_BROWSE
);
4378 /* Select the first record */
4379 if (gtk_tree_model_get_iter_first(pcfg
->prefs_model
, &iter
)) {
4380 gtk_tree_selection_select_iter(select
, &iter
);
4383 /* add options for adding monitors */
4384 box
= gtk_hbox_new(FALSE
, 4);
4385 gtk_box_pack_start(GTK_BOX(pbox
), box
, FALSE
, FALSE
, 0);
4386 gtk_widget_show(box
);
4388 cbox
= gtk_button_new_from_stock(GTK_STOCK_ADD
);
4389 g_signal_connect(cbox
, "clicked", G_CALLBACK(cb_panel_prefs_button_add_rec
),
4391 gtk_tooltips_set_tip(pcfg
->tooltips
, GTK_WIDGET(cbox
),
4392 "Adds a new monitor\ndefinition to the system.", NULL
);
4393 gtk_box_pack_start(GTK_BOX(box
), cbox
, FALSE
, FALSE
, 2);
4394 gtk_widget_show(cbox
);
4396 cbox
= gtk_button_new_from_stock(GTK_STOCK_REMOVE
);
4397 g_signal_connect(cbox
, "clicked", G_CALLBACK(cb_panel_prefs_button_remove_rec
),
4399 gtk_tooltips_set_tip(pcfg
->tooltips
, GTK_WIDGET(cbox
),
4400 "Removes selected monitor\ndefinition from the system.", NULL
);
4401 gtk_box_pack_start(GTK_BOX(box
), cbox
, FALSE
, FALSE
, 2);
4402 gtk_widget_show(cbox
);
4404 /* add options for control panel */
4405 frame
= gtk_frame_new("Control panel options");
4406 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_IN
);
4407 gtk_box_pack_start(GTK_BOX(vbox
), frame
, FALSE
, FALSE
, 0);
4408 gtk_widget_show(frame
);
4410 box
= gtk_hbox_new(FALSE
, 4);
4411 gtk_container_add(GTK_CONTAINER(frame
), box
);
4412 gtk_widget_show(box
);
4414 cbox
= gtk_check_button_new_with_mnemonic("Use _tray Icon");
4415 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cbox
), pcfg
->b_use_systray
);
4416 g_signal_connect(cbox
, "toggled", G_CALLBACK(cb_panel_prefs_button_use_systray
),
4418 gtk_tooltips_set_tip(pcfg
->tooltips
, GTK_WIDGET(cbox
),
4419 "Creates a notification area icon\nfor this control panel.", NULL
);
4420 gtk_box_pack_start(GTK_BOX(box
), cbox
, FALSE
, FALSE
, 2);
4421 gtk_widget_show(cbox
);
4422 g_hash_table_insert(pcfg
->pht_Widgets
, g_strdup("UseTrayIcon"), cbox
);
4428 * The about page in the information window
4429 * returns created notebook page number.
4431 static gint
gapc_panel_about_page(GtkNotebook
* notebook
, gchar
* pch_pname
,
4432 gchar
* pch_pversion
, GdkPixbuf
* icon
)
4434 GtkWidget
*label
= NULL
, *frame
= NULL
, *vbox
= NULL
;
4435 GtkWidget
*hbox
= NULL
, *image
= NULL
;
4436 gchar
*about_text
= NULL
;
4437 gchar
*about_msg
= NULL
;
4438 GdkPixbuf
*scaled
= NULL
;
4441 g_return_val_if_fail(notebook
!= NULL
, -1);
4445 g_strdup_printf("<b><big>%s</big>\nVersion %s</b>\n", pch_pname
, pch_pversion
);
4448 g_strdup_printf("<b>gui monitor for UPSs under the management"
4449 " of the APCUPSD.sourceforge.net package</b>\n"
4450 "<i>http://gapcmon.sourceforge.net/</i>\n\n"
4451 "Copyright \xC2\xA9 2006 James Scott, Jr.\n"
4452 "skoona@users.sourceforge.net\n\n"
4453 "Released under the GNU Public License\n"
4454 "%s comes with\nABSOLUTELY NO WARRANTY", pch_pname
);
4456 /* Create About page */
4457 frame
= gtk_frame_new(NULL
);
4458 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
4459 label
= gtk_label_new("About");
4460 i_page
= gtk_notebook_append_page(notebook
, frame
, label
);
4461 gtk_widget_show(frame
);
4463 vbox
= gtk_vbox_new(FALSE
, 8);
4464 gtk_container_add(GTK_CONTAINER(frame
), vbox
);
4465 gtk_widget_show(vbox
);
4467 hbox
= gtk_hbox_new(FALSE
, 0);
4468 gtk_box_pack_start(GTK_BOX(vbox
), hbox
, FALSE
, TRUE
, 0);
4469 gtk_widget_show(hbox
);
4471 image
= gtk_image_new();
4472 gtk_misc_set_alignment((GtkMisc
*) image
, 1.0, 0.5);
4473 scaled
= gdk_pixbuf_scale_simple(icon
, 48, 48, GDK_INTERP_BILINEAR
);
4474 gtk_image_set_from_pixbuf(GTK_IMAGE(image
), scaled
);
4475 gtk_box_pack_start(GTK_BOX(hbox
), image
, TRUE
, TRUE
, 0);
4476 gtk_widget_show(image
);
4477 gdk_pixbuf_unref(scaled
);
4479 label
= gtk_label_new(about_text
);
4480 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
4481 gtk_label_set_justify(GTK_LABEL(label
), GTK_JUSTIFY_LEFT
);
4482 gtk_label_set_line_wrap(GTK_LABEL(label
), TRUE
);
4483 gtk_misc_set_alignment((GtkMisc
*) label
, 0.0, 0.7);
4484 gtk_box_pack_start(GTK_BOX(hbox
), label
, TRUE
, TRUE
, 0);
4485 gtk_widget_show(label
);
4487 label
= gtk_label_new(about_msg
);
4488 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
4489 gtk_label_set_justify(GTK_LABEL(label
), GTK_JUSTIFY_CENTER
);
4490 gtk_label_set_line_wrap(GTK_LABEL(label
), TRUE
);
4491 gtk_misc_set_alignment((GtkMisc
*) label
, 0.5, 0.5);
4492 gtk_box_pack_start(GTK_BOX(vbox
), label
, TRUE
, TRUE
, 0);
4493 gtk_widget_show(label
);
4501 static void cb_monitor_interface_show(GtkWidget
* widget
, PGAPC_MONITOR pm
)
4503 g_return_if_fail(pm
!= NULL
);
4504 pm
->b_visible
= TRUE
;
4505 lg_graph_draw ( pm
->phs
.plg
);
4508 static void cb_monitor_interface_hide(GtkWidget
* widget
, PGAPC_MONITOR pm
)
4510 g_return_if_fail(pm
!= NULL
);
4511 pm
->b_visible
= FALSE
;
4514 static gboolean
cb_monitor_interface_delete_event(GtkWidget
* widget
,
4515 GdkEvent
* event
, PGAPC_MONITOR pm
)
4517 g_return_val_if_fail(pm
!= NULL
, FALSE
);
4519 return gtk_widget_hide_on_delete(widget
);
4523 * Handle the close button action from the information window
4526 static void cb_monitor_interface_button_close(GtkWidget * button, PGAPC_MONITOR pm)
4528 g_return_if_fail(pm != NULL);
4529 gtk_widget_hide(GTK_WIDGET(pm->window));
4535 * Handle the refresh button action from the information window
4537 static void cb_monitor_interface_button_refresh(GtkWidget
* button
, PGAPC_MONITOR pm
)
4539 g_return_if_fail(pm
!= NULL
);
4541 if ((!pm
->b_run
) || !(pm
->cb_enabled
) || (pm
->window
== NULL
)) {
4545 g_async_queue_push(pm
->q_network
, pm
);
4546 g_timeout_add(GAPC_REFRESH_FACTOR_ONE_TIME
,
4547 (GSourceFunc
) cb_monitor_dedicated_one_time_refresh
, pm
);
4552 static void cb_main_interface_show(GtkWidget
* widget
, PGAPC_CONFIG pcfg
)
4554 g_return_if_fail(pcfg
!= NULL
);
4555 pcfg
->b_visible
= TRUE
;
4558 static void cb_main_interface_hide(GtkWidget
* widget
, PGAPC_CONFIG pcfg
)
4560 g_return_if_fail(pcfg
!= NULL
);
4561 pcfg
->b_visible
= FALSE
;
4564 /* "window-state-event"
4565 * iconify/minimize verus hide needs this routine to manage visibility
4567 static gboolean
cb_util_manage_iconify_event(GtkWidget
*widget
, GdkEventWindowState
*event
,
4570 g_return_val_if_fail(gp
!= NULL
, FALSE
);
4573 if ((event
->type
== GDK_WINDOW_STATE
) && (
4574 ((event
->changed_mask
& GDK_WINDOW_STATE_ICONIFIED
) && (event
->new_window_state
& GDK_WINDOW_STATE_ICONIFIED
)) ||
4575 ((event
->changed_mask
& GDK_WINDOW_STATE_WITHDRAWN
) && (event
->new_window_state
& GDK_WINDOW_STATE_WITHDRAWN
))
4577 if ( ((PGAPC_MONITOR
)gp
)->cb_id
== CB_MONITOR_ID
) {
4578 if ( event
->window
== GTK_WIDGET(((PGAPC_MONITOR
)gp
)->window
)->window
) {
4579 ((PGAPC_MONITOR
)gp
)->b_visible
= FALSE
;
4582 if ( event
->window
== GTK_WIDGET(((PGAPC_CONFIG
)gp
)->window
)->window
) {
4583 ((PGAPC_CONFIG
)gp
)->b_visible
= FALSE
;
4590 /* un - iconified */
4591 if ((event
->type
== GDK_WINDOW_STATE
) && (
4592 ((event
->changed_mask
& GDK_WINDOW_STATE_ICONIFIED
) && !(event
->new_window_state
& GDK_WINDOW_STATE_ICONIFIED
)) ||
4593 ((event
->changed_mask
& GDK_WINDOW_STATE_WITHDRAWN
) && !(event
->new_window_state
& GDK_WINDOW_STATE_WITHDRAWN
)))
4595 if ( ((PGAPC_MONITOR
)gp
)->cb_id
== CB_MONITOR_ID
) {
4596 if ( event
->window
== GTK_WIDGET(((PGAPC_MONITOR
)gp
)->window
)->window
) {
4597 ((PGAPC_MONITOR
)gp
)->b_visible
= TRUE
;
4600 if ( event
->window
== GTK_WIDGET(((PGAPC_CONFIG
)gp
)->window
)->window
) {
4601 ((PGAPC_CONFIG
)gp
)->b_visible
= TRUE
;
4611 static gboolean
cb_main_interface_delete_event(GtkWidget
* widget
, GdkEvent
* event
,
4614 g_return_val_if_fail(pcfg
!= NULL
, FALSE
);
4615 cb_main_interface_button_quit(widget
, pcfg
);
4620 * Handle the quit button action from the information window
4622 static void cb_main_interface_button_quit(GtkWidget
* button
, PGAPC_CONFIG pcfg
)
4625 PGAPC_MONITOR pm
= NULL
;
4626 gboolean valid
= FALSE
;
4628 g_return_if_fail(pcfg
!= NULL
);
4630 valid
= gtk_tree_model_get_iter_first(pcfg
->monitor_model
, &iter
);
4632 gtk_tree_model_get(pcfg
->monitor_model
, &iter
, GAPC_MON_POINTER
, &pm
, -1);
4633 if ((pm
!= NULL
) && (pm
->window
!= NULL
)) {
4635 gtk_widget_destroy(GTK_WIDGET(pm
->window
));
4639 valid
= gtk_tree_model_iter_next(pcfg
->monitor_model
, &iter
);
4642 gtk_widget_destroy(GTK_WIDGET(pcfg
->window
));
4648 * Handles changes to use_systray and skip_pager for the control panel.
4649 * Triggers for this routine should not be installed until after the
4650 * control panel has been created.
4652 static void cb_panel_controller_gconf_changed(GConfClient
* client
, guint cnxn_id
,
4653 GConfEntry
* entry
, PGAPC_CONFIG pcfg
)
4655 gboolean b_new_value
= FALSE
;
4656 GtkWidget
*cbox
= NULL
;
4657 gchar
const *pstring
= NULL
;
4658 GdkColor
*pcolor
= NULL
;
4660 g_return_if_fail(pcfg
!= NULL
);
4661 g_return_if_fail(entry
!= NULL
);
4662 g_return_if_fail(entry
->value
!= NULL
);
4663 g_return_if_fail(pcfg
->window
!= NULL
);
4665 switch (entry
->value
->type
) {
4666 case GCONF_VALUE_STRING
:
4667 /* take action to propagate the value to all monitors */
4668 pstring
= gconf_value_get_string(entry
->value
);
4669 if (pstring
== NULL
) {
4673 if (g_str_equal(entry
->key
, GAPC_COLOR_LINEV_KEY
)) {
4674 pcolor
= &pcfg
->color_linev
;
4675 cbox
= g_hash_table_lookup(pcfg
->pht_Widgets
, "color-linev");
4677 if (g_str_equal(entry
->key
, GAPC_COLOR_LOADPCT_KEY
)) {
4678 pcolor
= &pcfg
->color_loadpct
;
4679 cbox
= g_hash_table_lookup(pcfg
->pht_Widgets
, "color-loadpct");
4681 if (g_str_equal(entry
->key
, GAPC_COLOR_TIMELEFT_KEY
)) {
4682 pcolor
= &pcfg
->color_timeleft
;
4683 cbox
= g_hash_table_lookup(pcfg
->pht_Widgets
, "color-timeleft");
4685 if (g_str_equal(entry
->key
, GAPC_COLOR_BCHARGE_KEY
)) {
4686 pcolor
= &pcfg
->color_bcharge
;
4687 cbox
= g_hash_table_lookup(pcfg
->pht_Widgets
, "color-bcharge");
4689 if (g_str_equal(entry
->key
, GAPC_COLOR_BATTV_KEY
)) {
4690 pcolor
= &pcfg
->color_battv
;
4691 cbox
= g_hash_table_lookup(pcfg
->pht_Widgets
, "color-battv");
4693 if (g_str_equal(entry
->key
, GAPC_COLOR_WINDOW_KEY
)) {
4694 pcolor
= &pcfg
->color_window
;
4695 cbox
= g_hash_table_lookup(pcfg
->pht_Widgets
, "color-window");
4697 if (g_str_equal(entry
->key
, GAPC_COLOR_CHART_KEY
)) {
4698 pcolor
= &pcfg
->color_chart
;
4699 cbox
= g_hash_table_lookup(pcfg
->pht_Widgets
, "color-chart");
4701 if (g_str_equal(entry
->key
, GAPC_COLOR_TITLE_KEY
)) {
4702 pcolor
= &pcfg
->color_title
;
4703 cbox
= g_hash_table_lookup(pcfg
->pht_Widgets
, "color-title");
4706 gdk_color_parse (pstring
, pcolor
);
4709 gtk_color_button_set_color (GTK_COLOR_BUTTON(cbox
), pcolor
);
4712 case GCONF_VALUE_BOOL
:
4713 b_new_value
= gconf_value_get_bool(entry
->value
);
4714 if (g_str_equal(entry
->key
, pcfg
->pch_gkeys
[GAPC_PREFS_SYSTRAY
])) {
4715 if (pcfg
->b_use_systray
== b_new_value
) {
4719 pcfg
->b_use_systray
= b_new_value
;
4721 if (pcfg
->tray_icon
== NULL
) {
4722 gapc_panel_systray_icon_create(pcfg
);
4725 if (pcfg
->tray_icon
!= NULL
) {
4726 gapc_panel_systray_icon_remove(pcfg
);
4729 cbox
= g_hash_table_lookup(pcfg
->pht_Widgets
, "UseTrayIcon");
4730 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cbox
), pcfg
->b_use_systray
);
4735 gapc_util_log_app_msg("cb_panel_controller_gconf_changed",
4736 "(UnKnown Data Type for key)", entry
->key
);
4744 * Handles changes to prefs_model, or the master list of monitors in the preferences page.
4745 * Triggers for this routine should not be installed until after the
4746 * control panel has been created.
4748 static void cb_panel_preferences_gconf_changed(GConfClient
* client
, guint cnxn_id
,
4749 GConfEntry
* entry
, PGAPC_CONFIG pcfg
)
4751 gchar
*pch_value
= NULL
;
4752 gchar
*pkey
= NULL
, **pkey_l
= NULL
;
4754 gboolean ov_b_tray
= FALSE
;
4757 gfloat ov_f_graph
= 0.0;
4758 gfloat ov_f_refresh
= 0.0;
4759 gchar
*ov_s_host
= NULL
;
4763 gint i_value
= 0, i_len
= 0;
4764 gfloat f_value
= 0.0;
4765 gchar
*s_value
= NULL
, ch
[GAPC_MAX_TEXT
];
4766 gboolean b_value
= FALSE
, b_flag_dupped
= FALSE
;
4768 gboolean b_ls_valid
= FALSE
;
4769 gboolean b_v_valid
= FALSE
;
4770 gboolean b_k_valid
= FALSE
;
4771 gboolean b_k_is_dir
= FALSE
;
4772 gboolean b_m_valid
= FALSE
;
4773 gboolean b_m_enabled
= FALSE
, b_add
= TRUE
, b_active_valid
= FALSE
;
4776 PGAPC_MONITOR pm
= NULL
;
4778 g_return_if_fail(pcfg
!= NULL
);
4779 g_return_if_fail(entry
!= NULL
);
4780 g_return_if_fail(pcfg
->window
!= NULL
);
4782 /* Parse out monitor number and item.key */
4783 pkey_l
= g_strsplit(entry
->key
, "/", -1);
4784 if (pkey_l
[5] != NULL
) {
4785 pkey
= g_strdup(pkey_l
[5]);
4790 if (pkey_l
[4] != NULL
) {
4791 i_monitor
= (gint
) g_strtod(pkey_l
[4], NULL
);
4796 gdk_threads_enter();
4798 /* Determine control bools */
4800 gapc_util_treeview_get_iter_from_monitor(pcfg
->prefs_model
, &iter
, i_monitor
);
4802 gtk_tree_model_get(pcfg
->prefs_model
, &iter
,
4803 GAPC_PREFS_ENABLED
, &b_m_enabled
,
4804 GAPC_PREFS_SYSTRAY
, &ov_b_tray
,
4805 GAPC_PREFS_PORT
, &ov_i_port
,
4806 GAPC_PREFS_WATT
, &ov_i_watt
,
4807 GAPC_PREFS_GRAPH
, &ov_f_graph
,
4808 GAPC_PREFS_REFRESH
, &ov_f_refresh
,
4809 GAPC_PREFS_HOST
, &ov_s_host
, -1);
4811 if (entry
->value
!= NULL
) {
4812 pch_value
= (gchar
*) gconf_value_to_string(entry
->value
);
4813 if (pch_value
!= NULL
) {
4818 /* perform record.level operations */
4819 if (b_ls_valid
&& !b_k_valid
&& !b_v_valid
) { /* delete null dir - no key val */
4821 gapc_monitor_interface_destroy(pcfg
, i_monitor
);
4822 b_m_enabled
= FALSE
;
4824 gtk_list_store_remove(GTK_LIST_STORE(pcfg
->prefs_model
), &iter
);
4826 pcfg
->cb_last_monitor_deleted
= i_monitor
;
4828 if (i_monitor
== pcfg
->cb_last_monitor_deleted
) { /* override gconf_unset-kde issue */
4831 b_m_enabled
= FALSE
;
4833 if (!b_ls_valid
&& b_v_valid
&& b_k_valid
) { /* add new rec if keys valid -nfound */
4834 gtk_list_store_append(GTK_LIST_STORE(pcfg
->prefs_model
), &iter
);
4835 gtk_list_store_set(GTK_LIST_STORE(pcfg
->prefs_model
), &iter
,
4836 GAPC_PREFS_MONITOR
, i_monitor
,
4837 GAPC_PREFS_SYSTRAY
, FALSE
,
4838 GAPC_PREFS_ENABLED
, FALSE
,
4839 GAPC_PREFS_PORT
, GAPC_PORT_DEFAULT
,
4840 GAPC_PREFS_GRAPH
, GAPC_LINEGRAPH_REFRESH_FACTOR
,
4841 GAPC_PREFS_HOST
, GAPC_HOST_DEFAULT
,
4842 GAPC_PREFS_REFRESH
, GAPC_REFRESH_DEFAULT
,
4843 GAPC_PREFS_WATT
, GAPC_WATT_DEFAULT
,
4848 b_m_enabled
= FALSE
;
4851 /* perform cell.level operations */
4852 if (b_ls_valid
&& b_v_valid
&& b_k_valid
) {
4855 gapc_util_treeview_get_iter_from_monitor(pcfg
->monitor_model
, &miter
,
4857 if (b_active_valid
) {
4858 gtk_tree_model_get(pcfg
->monitor_model
, &miter
, GAPC_MON_POINTER
, &pm
, -1);
4860 b_active_valid
= FALSE
;
4863 if ((pm
== NULL
) || (pm
->window
== NULL
)) {
4864 b_active_valid
= FALSE
;
4867 if (g_str_equal(pkey
, "enabled")) {
4868 b_value
= gconf_value_get_bool(entry
->value
);
4869 if (b_value
!= b_m_enabled
) {
4870 gtk_list_store_set(GTK_LIST_STORE(pcfg
->prefs_model
), &iter
,
4871 GAPC_PREFS_ENABLED
, b_value
, -1);
4873 if (b_value
&& !b_m_enabled
&& !b_active_valid
) {
4874 gtk_widget_show_all(gapc_monitor_interface_create(pcfg
, i_monitor
,
4877 if (!b_value
&& b_m_enabled
&& b_active_valid
) {
4878 gapc_monitor_interface_destroy(pcfg
, i_monitor
);
4881 if (g_str_equal(pkey
, "use_systray")) {
4882 b_value
= gconf_value_get_bool(entry
->value
);
4883 if (b_value
!= ov_b_tray
) {
4884 gtk_list_store_set(GTK_LIST_STORE(pcfg
->prefs_model
), &iter
,
4885 GAPC_PREFS_SYSTRAY
, b_value
, -1);
4887 if ((b_m_enabled
) && (b_active_valid
)) {
4888 pm
->cb_use_systray
= b_value
;
4890 gapc_panel_systray_icon_create(pm
);
4892 gapc_panel_systray_icon_remove(pm
);
4896 if (g_str_equal(pkey
, "port_number")) {
4897 i_value
= gconf_value_get_int(entry
->value
);
4898 if (i_value
!= ov_i_port
) {
4899 gtk_list_store_set(GTK_LIST_STORE(pcfg
->prefs_model
), &iter
,
4900 GAPC_PREFS_PORT
, i_value
, -1);
4902 if ((b_m_enabled
) && (b_active_valid
)) {
4903 pm
->i_port
= i_value
;
4904 pm
->b_network_control
= TRUE
;
4905 if (pm
->psk
!= NULL
) {
4906 pm
->psk
->i_port
= i_value
;
4907 pm
->psk
->b_network_control
= TRUE
;
4911 if (g_str_equal(pkey
, "ups_wattage")) {
4912 i_value
= gconf_value_get_int(entry
->value
);
4913 if (i_value
!= ov_i_watt
) {
4914 gtk_list_store_set(GTK_LIST_STORE(pcfg
->prefs_model
), &iter
,
4915 GAPC_PREFS_WATT
, i_value
, -1);
4918 pm
->i_watt
= i_value
;
4921 if (g_str_equal(pkey
, "network_interval")) {
4922 f_value
= gconf_value_get_float(entry
->value
);
4923 if (f_value
!= ov_f_refresh
) {
4924 gtk_list_store_set(GTK_LIST_STORE(pcfg
->prefs_model
), &iter
,
4925 GAPC_PREFS_REFRESH
, f_value
, -1);
4927 if ((b_m_enabled
) && (b_active_valid
)) {
4928 pm
->d_refresh
= f_value
;
4929 pm
->b_timer_control
= TRUE
;
4932 if (g_str_equal(pkey
, "graph_interval")) {
4933 f_value
= gconf_value_get_float(entry
->value
);
4934 if (f_value
!= ov_f_graph
) {
4935 gtk_list_store_set(GTK_LIST_STORE(pcfg
->prefs_model
), &iter
,
4936 GAPC_PREFS_GRAPH
, f_value
, -1);
4938 if ((b_m_enabled
) && (b_active_valid
)) {
4939 pm
->d_graph
= f_value
;
4940 pm
->b_graph_control
= TRUE
;
4943 if (g_str_equal(pkey
, "host_name")) {
4944 s_value
= (gchar
*) gconf_value_get_string(entry
->value
);
4945 i_len
= g_snprintf(ch
, GAPC_MAX_TEXT
, "%s", s_value
);
4947 s_value
= g_strdup(GAPC_HOST_DEFAULT
);
4948 b_flag_dupped
= TRUE
;
4950 if (!g_str_equal(s_value
, ov_s_host
)) {
4951 gtk_list_store_set(GTK_LIST_STORE(pcfg
->prefs_model
), &iter
,
4952 GAPC_PREFS_HOST
, s_value
, -1);
4954 if ((b_m_enabled
) && (b_active_valid
)) {
4955 if (pm
->pch_host
!= NULL
) {
4956 g_free(pm
->pch_host
);
4958 pm
->pch_host
= g_strdup(s_value
);
4959 pm
->b_network_control
= TRUE
;
4960 if (pm
->psk
!= NULL
) {
4961 g_snprintf(pm
->psk
->ch_ip_string
, sizeof(pm
->psk
->ch_ip_string
), "%s", s_value
);
4962 pm
->psk
->b_network_control
= TRUE
;
4965 if (b_flag_dupped
) {
4967 b_flag_dupped
= FALSE
;
4978 if (pch_value
!= NULL
) {
4983 gdk_threads_leave();
4989 * Clears the gconf directory watchers for the control panel
4990 * returns FALSE on error
4991 * returns TRUE on sucess
4993 static gboolean
gapc_panel_gconf_destroy(PGAPC_CONFIG pcfg
)
4995 g_return_val_if_fail(pcfg
!= NULL
, FALSE
);
4997 if (pcfg
->i_group_id
> 0) {
4998 gconf_client_remove_dir(pcfg
->client
, GAPC_MID_GROUP_KEY
, NULL
);
4999 gconf_client_remove_dir(pcfg
->client
, GAPC_CP_GROUP_KEY
, NULL
);
5000 gconf_client_notify_remove(pcfg
->client
, pcfg
->i_group_id
);
5001 gconf_client_notify_remove(pcfg
->client
, pcfg
->i_prefs_id
);
5003 g_object_unref(pcfg
->client
);
5005 g_free(pcfg
->pch_gkeys
[GAPC_PREFS_SYSTRAY
]);
5007 pcfg
->i_group_id
= 0;
5008 pcfg
->i_prefs_id
= 0;
5009 pcfg
->client
= NULL
;
5010 pcfg
->pch_gkeys
[GAPC_PREFS_SYSTRAY
] = NULL
;
5016 * Set the gconf directory watchers for the control panel
5017 * returns FALSE on error
5018 * returns TRUE on sucess
5020 static gboolean
gapc_panel_gconf_watch(PGAPC_CONFIG pcfg
)
5022 GError
*gerror
= NULL
;
5024 g_return_val_if_fail(pcfg
!= NULL
, FALSE
);
5026 /* Have gconf call us if something does change */
5028 gconf_client_notify_add(pcfg
->client
, GAPC_CP_GROUP_KEY
,
5029 (GConfClientNotifyFunc
)
5030 cb_panel_controller_gconf_changed
, pcfg
, NULL
, &gerror
);
5031 if (gerror
!= NULL
) {
5032 gapc_util_log_app_msg("gapc_panel_gconf_watch",
5033 "gconf_client_notify_add(controller.group) Failed", gerror
->message
);
5034 g_error_free(gerror
);
5035 pcfg
->i_group_id
= 0;
5041 gconf_client_notify_add(pcfg
->client
, GAPC_MID_GROUP_KEY
,
5042 (GConfClientNotifyFunc
)
5043 cb_panel_preferences_gconf_changed
, pcfg
, NULL
, &gerror
);
5044 if (gerror
!= NULL
) {
5045 gapc_util_log_app_msg("gapc_panel_gconf_watch",
5046 "gconf_client_notify_add(prefs.group) Failed", gerror
->message
);
5047 g_error_free(gerror
);
5048 pcfg
->i_group_id
= 0;
5057 * Gets the gconf instance preferences for this program
5058 * and init the control panel values.
5059 * returns FALSE on error
5060 * returns TRUE on sucess
5062 static gboolean
gapc_panel_gconf_init(PGAPC_CONFIG pcfg
)
5064 GError
*gerror
= NULL
;
5065 gchar
*pstring
= NULL
;
5067 g_return_val_if_fail(pcfg
!= NULL
, FALSE
);
5069 /* prepare control panel keys */
5070 pcfg
->pch_gkeys
[GAPC_PREFS_SYSTRAY
] = g_strdup(GAPC_CP_SYSTRAY_KEY
);
5072 /* contact gconf2 */
5073 pcfg
->client
= gconf_client_get_default();
5074 g_return_val_if_fail(pcfg
->client
!= NULL
, FALSE
);
5076 /* Have gconf watch for changes in this controller directory */
5077 gconf_client_add_dir(pcfg
->client
, GAPC_CP_GROUP_KEY
,
5078 GCONF_CLIENT_PRELOAD_ONELEVEL
, &gerror
);
5079 if (gerror
!= NULL
) {
5080 gapc_util_log_app_msg("gapc_panel_gconf_init", "gconf_client_add_dir() Failed",
5082 g_error_free(gerror
);
5087 /* Have gconf watch for changes in this monitor directory */
5088 gconf_client_add_dir(pcfg
->client
, GAPC_MID_GROUP_KEY
,
5089 GCONF_CLIENT_PRELOAD_ONELEVEL
, &gerror
);
5090 if (gerror
!= NULL
) {
5091 gapc_util_log_app_msg("gapc_panel_gconf_init", "gconf_client_add_dir() Failed",
5093 g_error_free(gerror
);
5098 /* Defaults are FALSE */
5099 pcfg
->b_use_systray
=
5100 gconf_client_get_bool(pcfg
->client
, pcfg
->pch_gkeys
[GAPC_PREFS_SYSTRAY
], NULL
);
5102 /* Load graph colors or set defaults */
5103 pstring
= gconf_client_get_string(pcfg
->client
, GAPC_COLOR_LINEV_KEY
, NULL
);
5105 gdk_color_parse (pstring
, &pcfg
->color_linev
);
5107 gdk_color_parse ("green", &pcfg
->color_linev
);
5109 pstring
= gconf_client_get_string(pcfg
->client
, GAPC_COLOR_LOADPCT_KEY
, NULL
);
5111 gdk_color_parse (pstring
, &pcfg
->color_loadpct
);
5113 gdk_color_parse ("blue", &pcfg
->color_loadpct
);
5115 pstring
= gconf_client_get_string(pcfg
->client
, GAPC_COLOR_TIMELEFT_KEY
, NULL
);
5117 gdk_color_parse (pstring
, &pcfg
->color_timeleft
);
5119 gdk_color_parse ("red", &pcfg
->color_timeleft
);
5121 pstring
= gconf_client_get_string(pcfg
->client
, GAPC_COLOR_BCHARGE_KEY
, NULL
);
5123 gdk_color_parse (pstring
, &pcfg
->color_bcharge
);
5125 gdk_color_parse ("yellow", &pcfg
->color_bcharge
);
5127 pstring
= gconf_client_get_string(pcfg
->client
, GAPC_COLOR_BATTV_KEY
, NULL
);
5129 gdk_color_parse (pstring
, &pcfg
->color_battv
);
5131 gdk_color_parse ("black", &pcfg
->color_battv
);
5133 pstring
= gconf_client_get_string(pcfg
->client
, GAPC_COLOR_WINDOW_KEY
, NULL
);
5135 gdk_color_parse (pstring
, &pcfg
->color_window
);
5137 gdk_color_parse ("white", &pcfg
->color_window
);
5139 pstring
= gconf_client_get_string(pcfg
->client
, GAPC_COLOR_CHART_KEY
, NULL
);
5141 gdk_color_parse (pstring
, &pcfg
->color_chart
);
5143 gdk_color_parse ("light blue", &pcfg
->color_chart
);
5145 pstring
= gconf_client_get_string(pcfg
->client
, GAPC_COLOR_TITLE_KEY
, NULL
);
5147 gdk_color_parse (pstring
, &pcfg
->color_title
);
5149 gdk_color_parse ("blue", &pcfg
->color_title
);
5156 * Handle Object.Destroy Signal
5157 * have no choice be go away when destroyed
5159 static void cb_monitor_interface_destroy(GtkWidget
* widget
, PGAPC_MONITOR pm
)
5161 PGAPC_CONFIG pcfg
= (PGAPC_CONFIG
)pm
->gp
;
5162 GtkWidget
*sbar
= NULL
;
5165 g_return_if_fail(pm
!= NULL
);
5166 g_return_if_fail(pcfg
!= NULL
);
5170 if (pm
->tid_graph_refresh
) {
5171 g_source_remove(pm
->tid_graph_refresh
);
5173 if (pm
->tid_automatic_refresh
) {
5174 g_source_remove(pm
->tid_automatic_refresh
);
5177 if (pm
->tid_thread_qwork
!= NULL
) {
5178 pm
->b_thread_stop
= TRUE
;
5179 g_async_queue_push(pm
->q_network
, pm
);
5180 g_thread_join(pm
->tid_thread_qwork
);
5183 g_mutex_free(pm
->gm_update
);
5184 g_async_queue_unref(pm
->q_network
);
5187 for (h_index
= 0; h_index
< GAPC_LINEGRAPH_MAX_SERIES
; h_index
++) {
5188 if (pm
->phs
.sq
[h_index
].gm_graph
!= NULL
) {
5189 g_mutex_free(pm
->phs
.sq
[h_index
].gm_graph
);
5193 if (pm
->pht_Widgets
!= NULL
) {
5194 g_hash_table_destroy(pm
->pht_Widgets
);
5195 g_hash_table_destroy(pm
->pht_Status
);
5196 pm
->pht_Widgets
= NULL
;
5197 pm
->pht_Status
= NULL
;
5200 for (h_index
= 0; h_index
< GAPC_MAX_ARRAY
; h_index
++) {
5201 if (pm
->pach_events
[h_index
] != NULL
) {
5202 g_free(pm
->pach_events
[h_index
]);
5204 pm
->pach_events
[h_index
] = NULL
;
5205 if (pm
->pach_status
[h_index
] != NULL
) {
5206 g_free(pm
->pach_status
[h_index
]);
5208 pm
->pach_status
[h_index
] = NULL
;
5211 if (pm
->tray_icon
!= NULL
) {
5212 gtk_widget_destroy(GTK_WIDGET(pm
->tray_icon
));
5213 pm
->tray_icon
= NULL
;
5214 pm
->tray_image
= NULL
;
5216 if (pm
->menu
!= NULL
) {
5217 gtk_widget_destroy(GTK_WIDGET(pm
->menu
));
5221 g_object_unref (pm
->tooltips
);
5223 lg_graph_data_series_remove_all ( pm
->phs
.plg
);
5225 sbar
= g_hash_table_lookup (pcfg
->pht_Widgets
, "StatusBar");
5229 gtk_statusbar_pop(GTK_STATUSBAR(sbar
), pcfg
->i_info_context
);
5230 pch
= g_strdup_printf
5231 ("Monitor for %s Destroyed!...", pm
->pch_host
);
5232 gtk_statusbar_push(GTK_STATUSBAR(sbar
), pcfg
->i_info_context
, pch
);
5240 static void cb_main_interface_destroy(GtkWidget
* widget
, PGAPC_CONFIG pcfg
)
5244 g_return_if_fail(pcfg
!= NULL
);
5246 pcfg
->b_run
= FALSE
;
5248 gapc_panel_gconf_destroy(pcfg
);
5250 if (GTK_IS_TREE_VIEW(pcfg
->prefs_treeview
)) {
5251 gtk_widget_destroy(GTK_WIDGET(pcfg
->prefs_treeview
));
5252 pcfg
->prefs_treeview
= NULL
;
5254 if (GTK_IS_TREE_VIEW(pcfg
->monitor_treeview
)) {
5255 gtk_widget_destroy(GTK_WIDGET(pcfg
->monitor_treeview
));
5256 pcfg
->monitor_treeview
= NULL
;
5258 if (pcfg
->prefs_model
!= NULL
) {
5259 gtk_list_store_clear(GTK_LIST_STORE(pcfg
->prefs_model
));
5260 g_object_unref(G_OBJECT(pcfg
->prefs_model
));
5261 pcfg
->prefs_model
= NULL
;
5263 if (pcfg
->monitor_model
!= NULL
) {
5264 gtk_list_store_clear(GTK_LIST_STORE(pcfg
->monitor_model
));
5265 g_object_unref(G_OBJECT(pcfg
->monitor_model
));
5266 pcfg
->monitor_model
= NULL
;
5268 if (pcfg
->pht_Widgets
!= NULL
) {
5269 g_hash_table_destroy(pcfg
->pht_Widgets
);
5270 g_hash_table_destroy(pcfg
->pht_Status
);
5272 for (x
= 0; x
< GAPC_N_ICONS
; x
++) {
5273 g_object_unref(pcfg
->my_icons
[x
]);
5276 g_object_unref (pcfg
->tooltips
);
5283 * returns TRUE if helps was offered, else FALSE if input was all ok.
5285 static gint
gapc_main_interface_parse_args(gint argc
, gchar
** argv
,
5289 GString
*gs_parm1
= NULL
, *gs_parm2
= NULL
;
5291 gs_parm1
= g_string_new(GAPC_CP_GROUP_KEY
);
5292 gs_parm2
= g_string_new(GAPC_CP_GROUP_KEY
);
5294 /* *********************************************************** *
5296 * - default to known values
5297 * - check config file for saved values -- careful not to override cmdline
5299 while (--argc
> 0) { /* ADJUST COUNTER HERE */
5300 g_string_assign(gs_parm1
, argv
[argc
]);
5301 if (argv
[argc
+ 1] != NULL
) {
5302 g_string_assign(gs_parm2
, argv
[argc
+ 1]);
5305 pch
= g_strstr_len(gs_parm1
->str
, 6, "-help");
5307 g_print("\nsyntax: gapcmon [--help]\n"
5308 "where: --help, this message, no command line options are available\n"
5309 "Skoona@Users.SourceForge.Net (GPL) 2006 \n\n");
5311 g_string_free(gs_parm1
, TRUE
);
5312 g_string_free(gs_parm2
, TRUE
);
5313 return TRUE
; /* trigger exit */
5317 g_string_free(gs_parm1
, TRUE
);
5318 g_string_free(gs_parm2
, TRUE
);
5320 /* *********************************************************
5321 * Apply instance value
5328 * Create main interface with the following panels
5330 * - preferences panel
5333 static GtkWidget
*gapc_main_interface_create(PGAPC_CONFIG pcfg
)
5335 GtkWindow
*window
= NULL
;
5336 GdkPixbuf
*pixbuf
= NULL
;
5337 GtkWidget
*sbar
= NULL
, *notebook
= NULL
, *menu
= NULL
, *menu_item
= NULL
;
5338 GtkWidget
*label
= NULL
, *button
= NULL
;
5339 GtkWidget
*bbox
= NULL
, *lbox
= NULL
, *nbox
= NULL
, *box
= NULL
;
5342 g_return_val_if_fail(pcfg
!= NULL
, NULL
);
5344 /* Create hash table for easy access to system widgets */
5345 pcfg
->pht_Status
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
, g_free
);
5346 pcfg
->pht_Widgets
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
, NULL
);
5347 pixbuf
= pcfg
->my_icons
[GAPC_ICON_DEFAULT
];
5348 pcfg
->b_visible
= FALSE
;
5349 pcfg
->tooltips
= gtk_tooltips_new();
5350 g_object_ref (pcfg
->tooltips
);
5351 gtk_object_sink (GTK_OBJECT(pcfg
->tooltips
));
5353 pcfg
->cb_last_monitor_deleted
= -1;
5356 * Create the top level window for the notebook to be packed into.*/
5357 window
= g_object_new(GTK_TYPE_WINDOW
, "border-width", 0, "destroy-with-parent",
5358 TRUE
, "icon", pixbuf
, "resizable", TRUE
, "title",
5359 GAPC_WINDOW_TITLE
, "type", GTK_WINDOW_TOPLEVEL
, "type-hint",
5360 GDK_WINDOW_TYPE_HINT_NORMAL
, "window-position", GTK_WIN_POS_NONE
, NULL
);
5362 pcfg
->window
= GTK_WIDGET(window
);
5363 g_signal_connect(window
, "destroy", G_CALLBACK(cb_main_interface_destroy
), pcfg
);
5364 g_signal_connect(window
, "delete-event",
5365 G_CALLBACK(cb_main_interface_delete_event
), pcfg
);
5366 g_signal_connect(window
, "show", G_CALLBACK(cb_main_interface_show
), pcfg
);
5367 g_signal_connect(window
, "hide", G_CALLBACK(cb_main_interface_hide
), pcfg
);
5368 g_signal_connect(window
, "window-state-event",
5369 G_CALLBACK(cb_util_manage_iconify_event
), pcfg
);
5371 gapc_panel_systray_icon_create(pcfg
);
5373 lbox
= gtk_vbox_new(FALSE
, 2);
5374 gtk_container_add(GTK_CONTAINER(window
), lbox
);
5375 gtk_widget_show(lbox
);
5380 bbox
= gtk_vbox_new(FALSE
, 0);
5381 gtk_container_set_border_width(GTK_CONTAINER(bbox
), 6);
5382 gtk_box_pack_start(GTK_BOX(lbox
), bbox
, TRUE
, TRUE
, 2);
5383 gtk_widget_show(bbox
);
5384 nbox
= gtk_hbox_new(TRUE
, 0);
5385 gtk_box_pack_start(GTK_BOX(bbox
), nbox
, TRUE
, TRUE
, 0);
5386 gtk_widget_show(nbox
);
5388 /* create the status bar */
5389 sbar
= gtk_statusbar_new();
5390 gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(sbar
), FALSE
);
5391 g_hash_table_insert(pcfg
->pht_Widgets
, g_strdup("StatusBar"), sbar
);
5392 gtk_box_pack_end(GTK_BOX(lbox
), sbar
, FALSE
, TRUE
, 0);
5393 gtk_widget_show(sbar
);
5394 pcfg
->i_info_context
=
5395 gtk_statusbar_get_context_id(GTK_STATUSBAR(sbar
), "Informational");
5398 bbox
= gtk_hbox_new(FALSE
, 0);
5399 gtk_container_set_border_width(GTK_CONTAINER(bbox
), 0);
5400 gtk_box_pack_end(GTK_BOX(lbox
), bbox
, FALSE
, FALSE
, 0);
5401 gtk_widget_show(bbox
);
5402 box
= gtk_hbutton_box_new();
5403 gtk_container_set_border_width(GTK_CONTAINER(box
), 6);
5404 gtk_box_pack_end(GTK_BOX(bbox
), box
, FALSE
, FALSE
, 2);
5405 gtk_widget_show(box
);
5407 /* Create the top-level notebook */
5408 notebook
= gtk_notebook_new();
5409 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook
), GTK_POS_TOP
);
5410 gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook
), TRUE
);
5411 gtk_notebook_set_homogeneous_tabs(GTK_NOTEBOOK(notebook
), TRUE
);
5412 gtk_box_pack_start(GTK_BOX(nbox
), notebook
, TRUE
, TRUE
, 0);
5413 gtk_widget_show(notebook
);
5415 /* Create the main pages */
5416 gapc_panel_monitor_list_page(pcfg
, GTK_NOTEBOOK(notebook
));
5417 i_page
= gapc_panel_preferences_page(pcfg
, GTK_NOTEBOOK(notebook
));
5418 gapc_panel_graph_property_page(pcfg
, notebook
);
5419 gapc_panel_glossary_page(pcfg
, notebook
);
5420 gapc_panel_about_page(GTK_NOTEBOOK(notebook
), GAPC_WINDOW_TITLE
, GAPC_VERSION
,
5423 label
= gtk_label_new("<big>" GAPC_GROUP_TITLE
"</big>");
5424 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5425 gtk_label_set_line_wrap(GTK_LABEL(label
), FALSE
);
5426 gtk_box_pack_start(GTK_BOX(bbox
), label
, TRUE
, TRUE
, 0);
5427 gtk_widget_show(label
);
5429 /* quit Control button */
5431 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
5432 g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_widget_hide), GTK_WIDGET(window));
5433 gtk_box_pack_end(GTK_BOX(box), button, TRUE, TRUE, 0);
5434 gtk_widget_show(button);
5436 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
5437 gtk_widget_grab_default(button);
5440 button
= gtk_button_new_from_stock(GTK_STOCK_QUIT
);
5441 g_signal_connect(button
, "clicked", G_CALLBACK(cb_main_interface_button_quit
),
5443 gtk_box_pack_end(GTK_BOX(box
), button
, TRUE
, TRUE
, 0);
5444 gtk_widget_show(button
);
5447 gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook
), i_page
);
5449 pcfg
->menu
= menu
= gtk_menu_new();
5450 menu_item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_JUMP_TO
, NULL
);
5451 g_signal_connect(G_OBJECT(menu_item
), "activate",
5452 G_CALLBACK(cb_util_popup_menu_response_jumpto
), pcfg
);
5453 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), menu_item
);
5454 gtk_widget_show(menu_item
);
5455 menu_item
= gtk_separator_menu_item_new();
5456 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), menu_item
);
5457 gtk_widget_show(menu_item
);
5458 menu_item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT
, NULL
);
5459 g_signal_connect(G_OBJECT(menu_item
), "activate",
5460 G_CALLBACK(cb_util_popup_menu_response_exit
), pcfg
);
5461 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), menu_item
);
5462 gtk_widget_show(menu_item
);
5463 gtk_widget_show(menu
);
5465 gtk_widget_show_all(lbox
);
5467 return GTK_WIDGET(window
);
5471 * Creates a GtkGLGraph histogram linechart page
5473 static gint
gapc_monitor_history_page(PGAPC_MONITOR pm
, GtkWidget
* notebook
)
5475 PGAPC_HISTORY pphs
= (PGAPC_HISTORY
) & pm
->phs
;
5476 PGAPC_CONFIG pcfg
= (PGAPC_CONFIG
) pm
->gp
;
5478 gint i_page
= 0, i_series
= 0, h_index
= 0;
5479 GtkWidget
*label
= NULL
, *box
= NULL
;
5481 gchar
*pch_colors
[6];
5482 gchar
*pch_legend
[] = { "LINEV", "LOADPCT", "TIMELEFT", "BCHARGE", "BATTV" };
5484 g_return_val_if_fail(pm
!= NULL
, -1);
5487 * Prepare the environment */
5488 pphs
->gp
= (gpointer
) pm
;
5489 pphs
->d_xinc
= pm
->d_refresh
* pm
->d_graph
;
5490 lg_graph_debug
= FALSE
;
5492 for (h_index
= 0; h_index
< GAPC_LINEGRAPH_MAX_SERIES
; h_index
++) {
5493 if (pm
->phs
.sq
[h_index
].gm_graph
!= NULL
) {
5494 g_mutex_free(pm
->phs
.sq
[h_index
].gm_graph
);
5496 pm
->phs
.sq
[h_index
].gm_graph
= g_mutex_new();
5499 /* get values from graph properties */
5500 pch_colors
[0] = gtk_color_selection_palette_to_string ( &pcfg
->color_linev
, 1);
5501 pch_colors
[1] = gtk_color_selection_palette_to_string ( &pcfg
->color_loadpct
, 1);
5502 pch_colors
[2] = gtk_color_selection_palette_to_string ( &pcfg
->color_timeleft
, 1);
5503 pch_colors
[3] = gtk_color_selection_palette_to_string ( &pcfg
->color_bcharge
, 1);
5504 pch_colors
[4] = gtk_color_selection_palette_to_string ( &pcfg
->color_battv
, 1);
5505 pch_colors
[5] = NULL
;
5508 * Create notebook page page */
5509 box
= gtk_vbox_new(FALSE
, 0);
5510 g_object_set_data ( G_OBJECT(box
), "pcfg-pointer", pm
->gp
);
5511 label
= gtk_label_new("Historical Summary");
5512 i_page
= gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), box
, label
);
5513 gtk_widget_show(GTK_WIDGET(box
));
5514 gtk_widget_show(label
);
5517 * Create Chart surface */
5518 plg
= pphs
->plg
= lg_graph_create ( box
, 300, 200 );
5520 for (i_series
= 0; i_series
< GAPC_LINEGRAPH_MAX_SERIES
; i_series
++) {
5521 lg_graph_data_series_add (plg
, pch_legend
[i_series
], pch_colors
[i_series
]);
5522 g_free (pch_colors
[i_series
]);
5525 pch
= g_strdup_printf(
5526 "<i>sampled every %3.1f seconds</i>",
5528 lg_graph_set_x_label_text (plg
, pch
);
5531 lg_graph_set_chart_title (plg
, pm
->ch_title_info
);
5534 pm
->tid_graph_refresh
=
5535 gtk_timeout_add(((guint
) (pphs
->d_xinc
* GAPC_REFRESH_FACTOR_1K
)),
5536 (GSourceFunc
) cb_util_line_chart_refresh
, pphs
);
5538 /* collect one right away */
5539 pphs
->b_startup
= TRUE
;
5540 g_timeout_add((guint
) (pm
->d_refresh
* GAPC_REFRESH_FACTOR_1K
+ 75),
5541 (GSourceFunc
) cb_util_line_chart_refresh
, pphs
);
5547 * Add a new data point until xrange is reached
5548 * then rotate back the y points and add new point to end
5549 * return TRUE is successful, FALSE other wise
5551 static gboolean
cb_util_line_chart_refresh(PGAPC_HISTORY pg
)
5555 PGAPC_MONITOR pm
= NULL
;
5557 g_return_val_if_fail(pg
!= NULL
, FALSE
);
5559 pm
= (PGAPC_MONITOR
) pg
->gp
;
5561 g_return_val_if_fail(plg
!= NULL
, FALSE
);
5562 g_return_val_if_fail(pm
!= NULL
, FALSE
);
5564 if (!pm
->b_run
) /* stop this timer */
5567 if (pm
->b_graph_control
) {
5568 g_timeout_add(100, (GSourceFunc
) cb_util_line_chart_refresh_control
, pm
);
5573 gdk_threads_enter();
5575 for (h_index
= 0; h_index
< plg
->i_num_series
; h_index
++) {
5576 lg_graph_data_series_add_value (plg
, h_index
,
5577 gapc_util_point_filter_reset(&(pg
->sq
[h_index
])) );
5580 if (plg
->i_points_available
>= plg
->x_range
.i_max_scale
) {
5581 lg_graph_draw ( plg
);
5583 lg_graph_data_series_draw_all (plg
, TRUE
);
5584 lg_graph_redraw ( plg
);
5588 gdk_threads_leave();
5590 if (pg
->b_startup
) {
5591 pg
->b_startup
= FALSE
;
5595 /* first data point collected */
5601 * Create and Initialize a Line Chart
5603 static PLGRAPH
lg_graph_create (GtkWidget
* box
, gint width
, gint height
)
5606 PGAPC_CONFIG pcfg
= NULL
;
5607 GtkWidget
*drawing_area
= NULL
;
5609 PangoFontDescription
*font_desc
= NULL
;
5610 gchar
*pstring
= NULL
;
5612 pcfg
= (PGAPC_CONFIG
)g_object_get_data (G_OBJECT(box
), "pcfg-pointer");
5613 g_return_val_if_fail (pcfg
!= NULL
, NULL
);
5615 plg
= g_new0 (LGRAPH
, 1);
5616 g_return_val_if_fail (plg
!= NULL
, NULL
);
5618 plg
->cb_id
= CB_GRAPH_ID
;
5619 plg
->x_range
.cb_id
= CB_RANGE_ID
;
5620 plg
->y_range
.cb_id
= CB_RANGE_ID
;
5621 plg
->b_tooltip_active
= TRUE
;
5623 * These must be set before the first drawing_area configure event
5625 lg_graph_set_chart_title (plg
, "Waiting for Update");
5626 lg_graph_set_y_label_text (plg
, "Precentage of 100% normal");
5627 lg_graph_set_x_label_text (plg
, "Waiting for Update");
5629 g_snprintf (plg
->ch_tooltip_text
, sizeof (plg
->ch_tooltip_text
), "%s",
5630 "Waiting for Graphable Data...");
5632 pstring
= gtk_color_selection_palette_to_string ( &pcfg
->color_title
, 1);
5633 lg_graph_set_chart_title_color (plg
, pstring
);
5636 lg_graph_set_chart_scales_color (plg
, "black");
5638 pstring
= gtk_color_selection_palette_to_string ( &pcfg
->color_chart
, 1);
5639 lg_graph_set_chart_window_fg_color (plg
, pstring
);
5642 pstring
= gtk_color_selection_palette_to_string ( &pcfg
->color_window
, 1);
5643 lg_graph_set_chart_window_bg_color (plg
, pstring
);
5646 /* Xminor divisions, Xmajor divisions, Xbotton scale, Xtop scale, ...y */
5647 lg_graph_set_ranges (plg
, 1, 2, 0, 40, 2, 10, 0, 110);
5649 drawing_area
= plg
->drawing_area
= gtk_drawing_area_new ();
5650 gtk_widget_set_events (drawing_area
,
5651 GDK_EXPOSURE_MASK
| GDK_BUTTON_PRESS_MASK
|
5652 GDK_POINTER_MOTION_MASK
| GDK_POINTER_MOTION_HINT_MASK
);
5653 gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area
), width
, height
);
5654 gtk_box_pack_start (GTK_BOX (box
), drawing_area
, TRUE
, TRUE
, 0);
5656 font_desc
= pango_font_description_from_string ("Monospace 10");
5657 gtk_widget_modify_font (drawing_area
, font_desc
);
5658 pango_font_description_free (font_desc
);
5660 gtk_widget_realize (drawing_area
);
5661 gtk_widget_show (drawing_area
);
5663 plg
->series_gc
= gdk_gc_new (drawing_area
->window
);
5664 plg
->window_gc
= gdk_gc_new (drawing_area
->window
);
5665 plg
->box_gc
= gdk_gc_new (drawing_area
->window
);
5666 plg
->scale_gc
= gdk_gc_new (drawing_area
->window
);
5667 plg
->title_gc
= gdk_gc_new (drawing_area
->window
);
5669 gdk_gc_copy (plg
->series_gc
,
5670 drawing_area
->style
->fg_gc
[GTK_WIDGET_STATE (drawing_area
)]);
5671 gdk_gc_copy (plg
->window_gc
,
5672 drawing_area
->style
->bg_gc
[GTK_WIDGET_STATE (drawing_area
)]);
5673 gdk_gc_copy (plg
->box_gc
,
5674 drawing_area
->style
->fg_gc
[GTK_WIDGET_STATE (drawing_area
)]);
5675 gdk_gc_copy (plg
->scale_gc
,
5676 drawing_area
->style
->fg_gc
[GTK_WIDGET_STATE (drawing_area
)]);
5677 gdk_gc_copy (plg
->title_gc
,
5678 drawing_area
->style
->text_aa_gc
[GTK_WIDGET_STATE (drawing_area
)]);
5680 gdk_color_parse (plg
->ch_color_window_bg
, &color
);
5681 gdk_gc_set_rgb_fg_color (plg
->window_gc
, &color
);
5683 gdk_color_parse (plg
->ch_color_chart_bg
, &color
);
5684 gdk_gc_set_rgb_fg_color (plg
->box_gc
, &color
);
5686 gdk_color_parse (plg
->ch_color_scale_fg
, &color
);
5687 gdk_gc_set_rgb_fg_color (plg
->scale_gc
, &color
);
5689 gdk_color_parse (plg
->ch_color_title_fg
, &color
);
5690 gdk_gc_set_rgb_fg_color (plg
->title_gc
, &color
);
5692 /* --- Signals used to handle backing pixmap --- */
5693 gtk_signal_connect (GTK_OBJECT (drawing_area
), "configure_event",
5694 (GtkSignalFunc
) lg_graph_configure_event_cb
, plg
);
5695 gtk_signal_connect (GTK_OBJECT (drawing_area
), "expose_event",
5696 (GtkSignalFunc
) lg_graph_expose_event_cb
, plg
);
5697 gtk_signal_connect (GTK_OBJECT (drawing_area
), "motion_notify_event",
5698 (GtkSignalFunc
) lg_graph_motion_notify_event_cb
, plg
);
5699 gtk_signal_connect (GTK_OBJECT (drawing_area
), "button_press_event",
5700 (GtkSignalFunc
) lg_graph_button_press_event_cb
, plg
);
5707 * Detailed Information Notebook Page
5709 static gint
gapc_monitor_information_page(PGAPC_MONITOR pm
, GtkWidget
* notebook
)
5711 GtkWidget
*frame
, *label
, *pbox
, *lbox
, *rbox
, *gbox
;
5712 GtkWidget
*tbox
, *tlbox
, *trbox
;
5715 /* Create a Notebook Page */
5716 gbox
= gtk_frame_new(NULL
);
5717 gtk_container_set_border_width(GTK_CONTAINER(gbox
), 4);
5718 gtk_frame_set_shadow_type(GTK_FRAME(gbox
), GTK_SHADOW_NONE
);
5719 label
= gtk_label_new("Detailed Information");
5720 i_page
= gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), gbox
, label
);
5721 gtk_widget_show(gbox
);
5723 tbox
= gtk_hbox_new(FALSE
, 4);
5724 gtk_container_add(GTK_CONTAINER(gbox
), tbox
);
5725 gtk_widget_show(tbox
);
5728 * create basic frame */
5729 tlbox
= gtk_vbox_new(TRUE
, 2);
5730 gtk_box_pack_start(GTK_BOX(tbox
), tlbox
, TRUE
, TRUE
, 0);
5731 gtk_widget_show(tlbox
);
5732 trbox
= gtk_vbox_new(TRUE
, 2);
5733 gtk_box_pack_end(GTK_BOX(tbox
), trbox
, TRUE
, TRUE
, 0);
5734 gtk_widget_show(trbox
);
5736 frame
= gtk_frame_new("<b><i>Performance Summary</i></b>");
5737 gtk_frame_set_label_align(GTK_FRAME(frame
), 0.1, 0.8);
5738 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_OUT
);
5739 label
= gtk_frame_get_label_widget(GTK_FRAME(frame
));
5740 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5741 gtk_box_pack_start(GTK_BOX(tlbox
), frame
, TRUE
, TRUE
, 0);
5742 gtk_widget_show(frame
);
5744 pbox
= gtk_hbox_new(FALSE
, 4);
5745 gtk_container_add(GTK_CONTAINER(frame
), pbox
);
5746 gtk_widget_show(pbox
);
5747 lbox
= gtk_vbox_new(FALSE
, 0);
5748 gtk_box_pack_start(GTK_BOX(pbox
), lbox
, FALSE
, TRUE
, 0);
5749 gtk_widget_show(lbox
);
5750 rbox
= gtk_vbox_new(FALSE
, 0);
5751 gtk_box_pack_end(GTK_BOX(pbox
), rbox
, TRUE
, TRUE
, 0);
5752 gtk_widget_show(rbox
);
5754 label
= gtk_label_new("Selftest running\n" "Number of transfers\n"
5755 "Reason last transfer\n" "Last transfer to battery\n"
5756 "Last transfer off battery\n" "Time on battery\n" "Cummulative on battery");
5757 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5758 gtk_label_set_justify(GTK_LABEL(label
), GTK_JUSTIFY_RIGHT
);
5759 gtk_label_set_line_wrap(GTK_LABEL(label
), TRUE
);
5760 gtk_misc_set_alignment((GtkMisc
*) label
, 1.0, 0.5);
5761 gtk_box_pack_start(GTK_BOX(lbox
), label
, FALSE
, FALSE
, 0);
5762 gtk_widget_show(label
);
5764 label
= gtk_label_new("Waiting for refresh\n");
5765 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5766 gtk_label_set_justify(GTK_LABEL(label
), GTK_JUSTIFY_LEFT
);
5767 gtk_label_set_line_wrap(GTK_LABEL(label
), TRUE
);
5768 gtk_misc_set_alignment((GtkMisc
*) label
, 0.0, 0.0);
5769 gtk_box_pack_start(GTK_BOX(rbox
), label
, TRUE
, TRUE
, 0);
5770 g_hash_table_insert(pm
->pht_Widgets
, g_strdup("PerformanceSummary"), label
);
5771 gtk_widget_show(label
);
5773 frame
= gtk_frame_new("<b><i>Software Information</i></b>");
5774 gtk_frame_set_label_align(GTK_FRAME(frame
), 0.1, 0.8);
5775 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_OUT
);
5776 label
= gtk_frame_get_label_widget(GTK_FRAME(frame
));
5777 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5778 gtk_box_pack_end(GTK_BOX(tlbox
), frame
, TRUE
, TRUE
, 0);
5779 gtk_widget_show(frame
);
5781 pbox
= gtk_hbox_new(FALSE
, 4);
5782 gtk_container_add(GTK_CONTAINER(frame
), pbox
);
5783 gtk_widget_show(pbox
);
5784 lbox
= gtk_vbox_new(FALSE
, 0);
5785 gtk_box_pack_start(GTK_BOX(pbox
), lbox
, FALSE
, FALSE
, 0);
5786 gtk_widget_show(lbox
);
5787 rbox
= gtk_vbox_new(FALSE
, 0);
5788 gtk_box_pack_end(GTK_BOX(pbox
), rbox
, TRUE
, TRUE
, 0);
5789 gtk_widget_show(rbox
);
5791 label
= gtk_label_new("APCUPSD version\n" "Monitored UPS name\n"
5792 "Cable Driver type\n" "Configuration mode\n" "Last started\n" "UPS State");
5793 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5794 gtk_label_set_justify(GTK_LABEL(label
), GTK_JUSTIFY_RIGHT
);
5795 gtk_label_set_line_wrap(GTK_LABEL(label
), TRUE
);
5796 gtk_misc_set_alignment((GtkMisc
*) label
, 1.0, 0.5);
5797 gtk_box_pack_start(GTK_BOX(lbox
), label
, FALSE
, FALSE
, 0);
5798 gtk_widget_show(label
);
5800 label
= gtk_label_new("Waiting for refresh\n");
5801 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5802 gtk_label_set_justify(GTK_LABEL(label
), GTK_JUSTIFY_LEFT
);
5803 gtk_label_set_line_wrap(GTK_LABEL(label
), TRUE
);
5804 gtk_misc_set_alignment((GtkMisc
*) label
, 0.0, 0.0);
5805 gtk_box_pack_start(GTK_BOX(rbox
), label
, TRUE
, TRUE
, 0);
5806 g_hash_table_insert(pm
->pht_Widgets
, g_strdup("SoftwareInformation"), label
);
5807 gtk_widget_show(label
);
5809 frame
= gtk_frame_new("<b><i>UPS Metrics</i></b>");
5810 gtk_frame_set_label_align(GTK_FRAME(frame
), 0.1, 0.8);
5811 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_OUT
);
5812 label
= gtk_frame_get_label_widget(GTK_FRAME(frame
));
5813 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5814 gtk_box_pack_start(GTK_BOX(trbox
), frame
, TRUE
, TRUE
, 0);
5815 gtk_widget_show(frame
);
5817 gbox
= gtk_vbox_new(TRUE
, 2);
5818 gtk_container_add(GTK_CONTAINER(frame
), gbox
);
5819 gtk_widget_show(gbox
);
5821 gapc_util_barchart_create(pm
, gbox
, "HBar1", 10.8, "Waiting for refresh");
5822 gapc_util_barchart_create(pm
, gbox
, "HBar2", 40.8, "Waiting for refresh");
5823 gapc_util_barchart_create(pm
, gbox
, "HBar3", 0.8, "Waiting for refresh");
5824 gapc_util_barchart_create(pm
, gbox
, "HBar4", 40.8, "Waiting for refresh");
5825 gapc_util_barchart_create(pm
, gbox
, "HBar5", 10.8, "Waiting for refresh");
5827 frame
= gtk_frame_new("<b><i>Product Information</i></b>");
5828 gtk_frame_set_label_align(GTK_FRAME(frame
), 0.1, 0.8);
5829 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_OUT
);
5830 label
= gtk_frame_get_label_widget(GTK_FRAME(frame
));
5831 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5832 gtk_box_pack_end(GTK_BOX(trbox
), frame
, TRUE
, TRUE
, 0);
5833 gtk_widget_show(frame
);
5835 pbox
= gtk_hbox_new(FALSE
, 4);
5836 gtk_container_add(GTK_CONTAINER(frame
), pbox
);
5837 gtk_widget_show(pbox
);
5838 lbox
= gtk_vbox_new(FALSE
, 0);
5839 gtk_box_pack_start(GTK_BOX(pbox
), lbox
, FALSE
, FALSE
, 0);
5840 gtk_widget_show(lbox
);
5841 rbox
= gtk_vbox_new(FALSE
, 0);
5842 gtk_box_pack_end(GTK_BOX(pbox
), rbox
, TRUE
, TRUE
, 0);
5843 gtk_widget_show(rbox
);
5845 label
= gtk_label_new("Device\n" "Serial\n" "Manf date\n" "Firmware\n"
5846 "Batt date\n" "Wattage");
5847 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5848 gtk_label_set_justify(GTK_LABEL(label
), GTK_JUSTIFY_RIGHT
);
5849 gtk_label_set_line_wrap(GTK_LABEL(label
), TRUE
);
5850 gtk_misc_set_alignment((GtkMisc
*) label
, 1.0, 0.5);
5851 gtk_box_pack_start(GTK_BOX(lbox
), label
, FALSE
, FALSE
, 0);
5852 gtk_widget_show(label
);
5854 label
= gtk_label_new("Waiting for refresh\n");
5855 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5856 gtk_label_set_justify(GTK_LABEL(label
), GTK_JUSTIFY_LEFT
);
5857 gtk_label_set_line_wrap(GTK_LABEL(label
), TRUE
);
5858 gtk_misc_set_alignment((GtkMisc
*) label
, 0.0, 0.0);
5859 gtk_box_pack_start(GTK_BOX(rbox
), label
, TRUE
, TRUE
, 0);
5860 g_hash_table_insert(pm
->pht_Widgets
, g_strdup("ProductInformation"), label
);
5861 gtk_widget_show(label
);
5867 * Events and Status Report Pages
5869 static gint
gapc_monitor_text_report_page(PGAPC_MONITOR pm
, GtkWidget
* notebook
,
5870 gchar
* pchTitle
, gchar
* pchKey
)
5872 PangoFontDescription
*font_desc
;
5873 GtkWidget
*scrolled
, *view
, *label
;
5876 scrolled
= gtk_scrolled_window_new(NULL
, NULL
);
5877 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled
),
5878 GTK_SHADOW_ETCHED_IN
);
5879 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled
),
5880 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
5881 label
= gtk_label_new(pchTitle
);
5882 i_page
= gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), scrolled
, label
);
5883 gtk_widget_show(scrolled
);
5885 view
= gtk_text_view_new();
5886 gtk_container_add(GTK_CONTAINER(scrolled
), view
);
5887 gtk_widget_show(view
);
5889 /* Change default font throughout the widget */
5890 font_desc
= pango_font_description_from_string("Monospace 9");
5891 gtk_widget_modify_font(view
, font_desc
);
5892 pango_font_description_free(font_desc
);
5894 gtk_text_view_set_editable(GTK_TEXT_VIEW(view
), FALSE
);
5895 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(view
), 5);
5897 g_hash_table_insert(pm
->pht_Widgets
, g_strdup(pchKey
), view
);
5902 static gint
gapc_panel_glossary_page(PGAPC_CONFIG pcfg
, GtkWidget
* notebook
)
5904 GtkWidget
*scrolled
, *label
, *vbox
;
5906 gchar
*ptext
= GAPC_GLOSSARY
;
5909 gdk_color_parse("white", &color
);
5911 vbox
= gtk_vbox_new(FALSE
, 0);
5912 label
= gtk_label_new("Glossary");
5913 i_page
= gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), vbox
, label
);
5914 gtk_widget_show(vbox
);
5916 scrolled
= gtk_scrolled_window_new(NULL
, NULL
);
5917 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled
),
5918 GTK_SHADOW_ETCHED_IN
);
5919 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled
),
5920 GTK_POLICY_NEVER
, GTK_POLICY_AUTOMATIC
);
5921 gtk_container_add(GTK_CONTAINER(vbox
), scrolled
);
5922 gtk_widget_show(GTK_WIDGET(scrolled
));
5924 label
= gtk_label_new(ptext
);
5925 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5926 gtk_label_set_justify(GTK_LABEL(label
), GTK_JUSTIFY_FILL
);
5927 gtk_label_set_line_wrap(GTK_LABEL(label
), TRUE
);
5929 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled
), label
);
5930 gtk_widget_show(label
);
5932 gtk_widget_modify_bg(gtk_widget_get_parent(label
), GTK_STATE_NORMAL
, &color
);
5937 static gint
gapc_panel_graph_property_page(PGAPC_CONFIG pcfg
, GtkWidget
* notebook
)
5939 GtkWidget
*s_frame
, *w_frame
, *label
, *s_box
, *w_box
, *frame
, *hbox
, *pbox
;
5940 GtkWidget
*cb_linev
, *cb_loadpct
, *cb_timeleft
, *cb_bcharge
, *cb_battv
;
5941 GtkWidget
*cb_window
, *cb_chart
, *cb_text
;
5942 GtkWidget
*bbox
, *b_undo
;
5946 frame
= gtk_vbox_new(FALSE
, 0);
5947 gtk_container_set_border_width(GTK_CONTAINER(frame
), 4);
5948 label
= gtk_label_new("Graph Properties");
5949 i_page
= gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), frame
, label
);
5950 gtk_widget_show(frame
);
5953 * Prepare the top color choice area */
5954 hbox
= gtk_hbox_new(FALSE
, 2);
5955 gtk_container_add ( GTK_CONTAINER (frame
), hbox
);
5956 gtk_widget_show(hbox
);
5959 * Prepare the bottom button/message area */
5960 bbox
= gtk_hbox_new(FALSE
, 0);
5961 gtk_box_pack_end ( GTK_BOX (frame
), bbox
, TRUE
, TRUE
, 2);
5962 gtk_widget_show(bbox
);
5964 b_undo
= gtk_button_new_from_stock (GTK_STOCK_UNDO
);
5965 gtk_box_pack_start ( GTK_BOX (bbox
), b_undo
, FALSE
, TRUE
, 2);
5966 gtk_widget_show(b_undo
);
5967 g_signal_connect (GTK_OBJECT(b_undo
), "clicked",
5968 G_CALLBACK(cb_panel_property_color_reset
), pcfg
);
5970 label
= gtk_label_new("These values will be used during the"
5971 " creation of a monitor. Disable and "
5972 "enable existing monitors to push values now.");
5973 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
5974 gtk_label_set_line_wrap(GTK_LABEL(label
), TRUE
);
5975 gtk_box_pack_end ( GTK_BOX (bbox
), label
, TRUE
, TRUE
, 2);
5976 gtk_widget_show(label
);
5979 * Prepare the top color choice area */
5980 s_frame
= gtk_frame_new("Series Color");
5981 gtk_container_set_border_width(GTK_CONTAINER(s_frame
), 4);
5982 gtk_frame_set_shadow_type(GTK_FRAME(s_frame
), GTK_SHADOW_IN
);
5983 gtk_box_pack_start(GTK_BOX(hbox
), s_frame
, TRUE
, TRUE
, 0);
5984 gtk_widget_show(s_frame
);
5986 s_box
= gtk_vbox_new(FALSE
, 0);
5987 gtk_container_add ( GTK_CONTAINER (s_frame
), s_box
);
5988 gtk_widget_show(s_box
);
5990 pbox
= gtk_hbox_new(TRUE
, 4);
5991 gtk_box_pack_start(GTK_BOX(s_box
), pbox
, FALSE
, FALSE
, 0);
5992 label
= gtk_label_new("LINEV");
5993 gtk_box_pack_start(GTK_BOX(pbox
), label
, FALSE
, FALSE
, 0);
5994 gtk_widget_show(label
);
5997 cb_linev
= gtk_color_button_new_with_color( &pcfg
->color_linev
);
5998 gtk_color_button_set_title (GTK_COLOR_BUTTON(cb_linev
), "LINEV");
5999 gtk_box_pack_start(GTK_BOX(pbox
), cb_linev
, FALSE
, FALSE
, 0);
6000 gtk_widget_show(cb_linev
);
6001 g_object_set_data (G_OBJECT(cb_linev
), "gconf-client", pcfg
->client
);
6002 g_signal_connect ( GTK_OBJECT(cb_linev
), "color-set",
6003 G_CALLBACK(cb_panel_property_color_change
),
6004 GAPC_COLOR_LINEV_KEY
);
6005 g_hash_table_insert(pcfg
->pht_Widgets
, g_strdup("color-linev"), cb_linev
);
6007 pbox
= gtk_hbox_new(TRUE
, 4);
6008 gtk_box_pack_start(GTK_BOX(s_box
), pbox
, FALSE
, FALSE
, 0);
6009 label
= gtk_label_new("LOADPCT");
6010 gtk_box_pack_start(GTK_BOX(pbox
), label
, FALSE
, FALSE
, 0);
6011 gtk_widget_show(label
);
6013 cb_loadpct
= gtk_color_button_new_with_color( &pcfg
->color_loadpct
);
6014 gtk_color_button_set_title (GTK_COLOR_BUTTON(cb_loadpct
), "LOADPCT");
6015 gtk_box_pack_start(GTK_BOX(pbox
), cb_loadpct
, FALSE
, FALSE
, 0);
6016 gtk_widget_show(cb_loadpct
);
6017 g_object_set_data (G_OBJECT(cb_loadpct
), "gconf-client", pcfg
->client
);
6018 g_signal_connect ( GTK_OBJECT(cb_loadpct
), "color-set",
6019 G_CALLBACK(cb_panel_property_color_change
),
6020 GAPC_COLOR_LOADPCT_KEY
);
6021 g_hash_table_insert(pcfg
->pht_Widgets
, g_strdup("color-loadpct"), cb_loadpct
);
6023 pbox
= gtk_hbox_new(TRUE
, 4);
6024 gtk_box_pack_start(GTK_BOX(s_box
), pbox
, FALSE
, FALSE
, 0);
6025 label
= gtk_label_new("TIMELEFT");
6026 gtk_box_pack_start(GTK_BOX(pbox
), label
, FALSE
, FALSE
, 0);
6027 gtk_widget_show(label
);
6029 cb_timeleft
= gtk_color_button_new_with_color( &pcfg
->color_timeleft
);
6030 gtk_color_button_set_title (GTK_COLOR_BUTTON(cb_timeleft
), "TIMELEFT");
6031 gtk_box_pack_start(GTK_BOX(pbox
), cb_timeleft
, FALSE
, FALSE
, 0);
6032 gtk_widget_show(cb_timeleft
);
6033 g_object_set_data (G_OBJECT(cb_timeleft
), "gconf-client", pcfg
->client
);
6034 g_signal_connect ( GTK_OBJECT(cb_timeleft
), "color-set",
6035 G_CALLBACK(cb_panel_property_color_change
),
6036 GAPC_COLOR_TIMELEFT_KEY
);
6037 g_hash_table_insert(pcfg
->pht_Widgets
, g_strdup("color-timeleft"), cb_timeleft
);
6039 pbox
= gtk_hbox_new(TRUE
, 4);
6040 gtk_box_pack_start(GTK_BOX(s_box
), pbox
, FALSE
, FALSE
, 0);
6041 label
= gtk_label_new("BCHARGE");
6042 gtk_box_pack_start(GTK_BOX(pbox
), label
, FALSE
, FALSE
, 0);
6043 gtk_widget_show(label
);
6045 cb_bcharge
= gtk_color_button_new_with_color( &pcfg
->color_bcharge
);
6046 gtk_color_button_set_title (GTK_COLOR_BUTTON(cb_bcharge
), "BCHARGE");
6047 gtk_box_pack_start(GTK_BOX(pbox
), cb_bcharge
, FALSE
, FALSE
, 0);
6048 gtk_widget_show(cb_bcharge
);
6049 g_object_set_data (G_OBJECT(cb_bcharge
), "gconf-client", pcfg
->client
);
6050 g_signal_connect ( GTK_OBJECT(cb_bcharge
), "color-set",
6051 G_CALLBACK(cb_panel_property_color_change
),
6052 GAPC_COLOR_BCHARGE_KEY
);
6053 g_hash_table_insert(pcfg
->pht_Widgets
, g_strdup("color-bcharge"), cb_bcharge
);
6055 pbox
= gtk_hbox_new(TRUE
, 4);
6056 gtk_box_pack_start(GTK_BOX(s_box
), pbox
, FALSE
, FALSE
, 0);
6057 label
= gtk_label_new("BATTV");
6058 gtk_box_pack_start(GTK_BOX(pbox
), label
, FALSE
, FALSE
, 0);
6059 gtk_widget_show(label
);
6061 cb_battv
= gtk_color_button_new_with_color( &pcfg
->color_battv
);
6062 gtk_color_button_set_title (GTK_COLOR_BUTTON(cb_battv
), "BATTV");
6063 gtk_box_pack_start(GTK_BOX(pbox
), cb_battv
, FALSE
, FALSE
, 0);
6064 gtk_widget_show(cb_battv
);
6065 g_object_set_data (G_OBJECT(cb_battv
), "gconf-client", pcfg
->client
);
6066 g_signal_connect ( GTK_OBJECT(cb_battv
), "color-set",
6067 G_CALLBACK(cb_panel_property_color_change
),
6068 GAPC_COLOR_BATTV_KEY
);
6069 g_hash_table_insert(pcfg
->pht_Widgets
, g_strdup("color-battv"), cb_battv
);
6071 w_frame
= gtk_frame_new("Window Colors");
6072 gtk_container_set_border_width(GTK_CONTAINER(w_frame
), 4);
6073 gtk_frame_set_shadow_type(GTK_FRAME(w_frame
), GTK_SHADOW_IN
);
6074 gtk_box_pack_start(GTK_BOX(hbox
), w_frame
, TRUE
, TRUE
, 0);
6075 gtk_widget_show(w_frame
);
6077 w_box
= gtk_vbox_new(FALSE
, 0);
6078 gtk_container_add ( GTK_CONTAINER (w_frame
), w_box
);
6079 gtk_widget_show(w_box
);
6081 pbox
= gtk_hbox_new(TRUE
, 4);
6082 gtk_box_pack_start(GTK_BOX(w_box
), pbox
, FALSE
, FALSE
, 0);
6083 label
= gtk_label_new("Window Background");
6084 gtk_box_pack_start(GTK_BOX(pbox
), label
, FALSE
, FALSE
, 0);
6085 gtk_widget_show(label
);
6087 cb_window
= gtk_color_button_new_with_color( &pcfg
->color_window
);
6088 gtk_color_button_set_title (GTK_COLOR_BUTTON(cb_window
), "Window Background");
6089 gtk_box_pack_start(GTK_BOX(pbox
), cb_window
, FALSE
, FALSE
, 0);
6090 gtk_widget_show(cb_window
);
6091 g_object_set_data (G_OBJECT(cb_window
), "gconf-client", pcfg
->client
);
6092 g_signal_connect ( GTK_OBJECT(cb_window
), "color-set",
6093 G_CALLBACK(cb_panel_property_color_change
),
6094 GAPC_COLOR_WINDOW_KEY
);
6095 g_hash_table_insert(pcfg
->pht_Widgets
, g_strdup("color-window"), cb_window
);
6097 pbox
= gtk_hbox_new(TRUE
, 4);
6098 gtk_box_pack_start(GTK_BOX(w_box
), pbox
, FALSE
, FALSE
, 0);
6099 label
= gtk_label_new("Chart Background");
6100 gtk_box_pack_start(GTK_BOX(pbox
), label
, FALSE
, FALSE
, 0);
6101 gtk_widget_show(label
);
6103 cb_chart
= gtk_color_button_new_with_color( &pcfg
->color_chart
);
6104 gtk_color_button_set_title (GTK_COLOR_BUTTON(cb_chart
), "Chart Background");
6105 gtk_box_pack_start(GTK_BOX(pbox
), cb_chart
, FALSE
, FALSE
, 0);
6106 gtk_widget_show(cb_chart
);
6107 g_object_set_data (G_OBJECT(cb_chart
), "gconf-client", pcfg
->client
);
6108 g_signal_connect ( GTK_OBJECT(cb_chart
), "color-set",
6109 G_CALLBACK(cb_panel_property_color_change
),
6110 GAPC_COLOR_CHART_KEY
);
6111 g_hash_table_insert(pcfg
->pht_Widgets
, g_strdup("color-chart"), cb_chart
);
6113 pbox
= gtk_hbox_new(TRUE
, 4);
6114 gtk_box_pack_start(GTK_BOX(w_box
), pbox
, FALSE
, FALSE
, 0);
6115 label
= gtk_label_new("Title Texts");
6116 gtk_box_pack_start(GTK_BOX(pbox
), label
, FALSE
, FALSE
, 0);
6117 gtk_widget_show(label
);
6119 cb_text
= gtk_color_button_new_with_color( &pcfg
->color_title
);
6120 gtk_color_button_set_title (GTK_COLOR_BUTTON(cb_text
), "Title Texts");
6121 gtk_box_pack_start(GTK_BOX(pbox
), cb_text
, FALSE
, FALSE
, 0);
6122 gtk_widget_show(cb_text
);
6123 g_object_set_data (G_OBJECT(cb_text
), "gconf-client", pcfg
->client
);
6124 g_signal_connect ( GTK_OBJECT(cb_text
), "color-set",
6125 G_CALLBACK(cb_panel_property_color_change
),
6126 GAPC_COLOR_TITLE_KEY
);
6127 g_hash_table_insert(pcfg
->pht_Widgets
, g_strdup("color-title"), cb_text
);
6134 * Creates monitor interface with the normal panels
6136 static GtkWidget
*gapc_monitor_interface_create(PGAPC_CONFIG pcfg
, gint i_monitor
,
6139 GtkWindow
*window
= NULL
;
6140 GdkPixbuf
*pixbuf
= NULL
;
6141 GtkWidget
*sbar
= NULL
, *notebook
= NULL
, *menu
= NULL
, *menu_item
= NULL
;
6142 GtkWidget
*label
= NULL
, *button
= NULL
;
6143 GtkWidget
*bbox
= NULL
, *lbox
= NULL
, *nbox
= NULL
, *box
= NULL
;
6144 PGAPC_MONITOR pm
= NULL
;
6147 g_return_val_if_fail(pcfg
!= NULL
, NULL
);
6149 pm
= g_new0(GAPC_MONITOR
, 1);
6150 g_return_val_if_fail(pm
!= NULL
, NULL
);
6151 pm
->cb_id
= CB_MONITOR_ID
;
6152 pm
->cb_monitor_num
= i_monitor
;
6153 pm
->gp
= (gpointer
) pcfg
;
6154 pm
->phs
.gp
= (gpointer
) pm
;
6155 pm
->phs
.cb_id
= CB_HISTORY_ID
;
6156 pm
->phs
.sq
[0].cb_id
= CB_SUMM_ID
;
6157 pm
->phs
.sq
[1].cb_id
= CB_SUMM_ID
;
6158 pm
->phs
.sq
[2].cb_id
= CB_SUMM_ID
;
6159 pm
->phs
.sq
[3].cb_id
= CB_SUMM_ID
;
6160 pm
->phs
.sq
[4].cb_id
= CB_SUMM_ID
;
6162 pm
->my_icons
= pcfg
->my_icons
;
6163 pm
->pht_Status
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
, g_free
);
6164 pm
->pht_Widgets
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
, NULL
);
6165 pm
->phs
.b_startup
= TRUE
;
6167 pm
->cb_enabled
= TRUE
;
6168 pm
->b_visible
= FALSE
;
6170 pm
->i_icon_index
= GAPC_ICON_DEFAULT
;
6171 pm
->i_old_icon_index
= GAPC_ICON_ONLINE
;
6172 pm
->tray_icon
= NULL
;
6173 pm
->tray_image
= NULL
;
6174 if (pm
->pch_host
!= NULL
) {
6175 g_free(pm
->pch_host
);
6177 gtk_tree_model_get(GTK_TREE_MODEL(pcfg
->prefs_model
), iter
,
6178 GAPC_PREFS_SYSTRAY
, &(pm
->cb_use_systray
),
6179 GAPC_PREFS_PORT
, &(pm
->i_port
),
6180 GAPC_PREFS_WATT
, &(pm
->i_watt
),
6181 GAPC_PREFS_GRAPH
, &(pm
->d_graph
),
6182 GAPC_PREFS_HOST
, &(pm
->pch_host
),
6183 GAPC_PREFS_REFRESH
, &(pm
->d_refresh
),
6184 GAPC_PREFS_MONITOR
, &z_monitor
, -1);
6186 pixbuf
= pm
->my_icons
[GAPC_ICON_DEFAULT
];
6187 pm
->tooltips
= gtk_tooltips_new();
6188 g_object_ref (pm
->tooltips
);
6189 gtk_object_sink (GTK_OBJECT(pm
->tooltips
));
6190 pm
->gm_update
= g_mutex_new();
6191 pm
->client
= pcfg
->client
;
6192 pm
->i_old_icon_index
= GAPC_ICON_DEFAULT
;
6193 pm
->monitor_model
= pcfg
->monitor_model
;
6194 g_snprintf(pm
->ch_title_info
, GAPC_MAX_TEXT
, "%s {%s}", GAPC_WINDOW_TITLE
,
6197 if (pm
->d_refresh
< GAPC_REFRESH_MIN_INCREMENT
) {
6198 pm
->d_refresh
= GAPC_REFRESH_DEFAULT
;
6200 if (pm
->d_graph
< GAPC_REFRESH_MIN_INCREMENT
) {
6201 pm
->d_graph
= GAPC_LINEGRAPH_REFRESH_FACTOR
;
6205 * Start the central network thread */
6206 pm
->q_network
= g_async_queue_new();
6207 g_return_val_if_fail(pm
->q_network
!= NULL
, NULL
);
6209 pm
->b_thread_stop
= FALSE
;
6210 pm
->tid_thread_qwork
=
6211 g_thread_create((GThreadFunc
) gapc_net_thread_qwork
, pm
, TRUE
, NULL
);
6214 * Create the top level window for the notebook to be packed into.*/
6215 window
= g_object_new(GTK_TYPE_WINDOW
, "border-width", 0, "destroy-with-parent",
6216 TRUE
, "icon", pixbuf
, "resizable", TRUE
, "title",
6217 pm
->ch_title_info
, "type", GTK_WINDOW_TOPLEVEL
, "type-hint",
6218 GDK_WINDOW_TYPE_HINT_NORMAL
, "window-position", GTK_WIN_POS_NONE
, NULL
);
6220 pm
->window
= GTK_WIDGET(window
);
6221 g_signal_connect(window
, "destroy", G_CALLBACK(cb_monitor_interface_destroy
), pm
);
6222 g_signal_connect(window
, "delete-event",
6223 G_CALLBACK(cb_monitor_interface_delete_event
), pm
);
6224 g_signal_connect(window
, "show", G_CALLBACK(cb_monitor_interface_show
), pm
);
6225 g_signal_connect(window
, "hide", G_CALLBACK(cb_monitor_interface_hide
), pm
);
6226 g_signal_connect(window
, "window-state-event",
6227 G_CALLBACK(cb_util_manage_iconify_event
), pm
);
6229 g_snprintf(pm
->ch_title_info
, GAPC_MAX_TEXT
, "%s\n<b><i>{%s}</i></b>",
6230 GAPC_WINDOW_TITLE
, pm
->pch_host
);
6232 lbox
= gtk_vbox_new(FALSE
, 2);
6233 gtk_container_add(GTK_CONTAINER(window
), lbox
);
6234 gtk_widget_show(lbox
);
6239 bbox
= gtk_vbox_new(FALSE
, 0);
6240 gtk_container_set_border_width(GTK_CONTAINER(bbox
), 6);
6241 gtk_box_pack_start(GTK_BOX(lbox
), bbox
, TRUE
, TRUE
, 2);
6242 gtk_widget_show(bbox
);
6243 nbox
= gtk_hbox_new(TRUE
, 0);
6244 gtk_box_pack_start(GTK_BOX(bbox
), nbox
, TRUE
, TRUE
, 0);
6245 gtk_widget_show(nbox
);
6247 /* create the status bar */
6248 sbar
= gtk_statusbar_new();
6249 gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(sbar
), FALSE
);
6250 g_hash_table_insert(pm
->pht_Widgets
, g_strdup("StatusBar"), sbar
);
6251 gtk_box_pack_end(GTK_BOX(lbox
), sbar
, FALSE
, TRUE
, 0);
6252 gtk_widget_show(sbar
);
6253 pm
->i_info_context
=
6254 gtk_statusbar_get_context_id(GTK_STATUSBAR(sbar
), "Informational");
6257 bbox
= gtk_hbox_new(FALSE
, 0);
6258 gtk_container_set_border_width(GTK_CONTAINER(bbox
), 0);
6259 gtk_box_pack_end(GTK_BOX(lbox
), bbox
, FALSE
, FALSE
, 0);
6260 gtk_widget_show(bbox
);
6261 box
= gtk_hbutton_box_new();
6262 gtk_hbutton_box_set_layout_default(GTK_BUTTONBOX_SPREAD
);
6263 gtk_container_set_border_width(GTK_CONTAINER(box
), 4);
6264 gtk_box_pack_end(GTK_BOX(bbox
), box
, TRUE
, TRUE
, 0);
6265 gtk_widget_show(box
);
6267 /* Create the top-level notebook */
6268 pm
->notebook
= notebook
= gtk_notebook_new();
6269 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook
), GTK_POS_TOP
);
6270 gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook
), TRUE
);
6271 gtk_notebook_set_homogeneous_tabs(GTK_NOTEBOOK(notebook
), FALSE
);
6272 gtk_box_pack_start(GTK_BOX(nbox
), notebook
, TRUE
, TRUE
, 0);
6273 gtk_widget_show(notebook
);
6275 /* Create the main pages */
6276 gapc_monitor_history_page(pm
, notebook
);
6277 gapc_monitor_information_page(pm
, notebook
);
6278 gapc_monitor_text_report_page(pm
, notebook
, "Power Events", "EventsPage");
6279 gapc_monitor_text_report_page(pm
, notebook
, "Full UPS Status", "StatusPage");
6281 /* Create the main pages */
6283 label
= gtk_label_new(pm
->ch_title_info
);
6284 gtk_label_set_use_markup(GTK_LABEL(label
), TRUE
);
6285 gtk_label_set_line_wrap(GTK_LABEL(label
), FALSE
);
6286 gtk_box_pack_start(GTK_BOX(bbox
), label
, TRUE
, TRUE
, 0);
6287 gtk_widget_show(label
);
6288 g_hash_table_insert(pm
->pht_Widgets
, g_strdup("TitleStatus"), label
);
6290 /* refresh Control button */
6291 button
= gtk_button_new_from_stock(GTK_STOCK_REFRESH
);
6292 GTK_WIDGET_SET_FLAGS(button
, GTK_CAN_DEFAULT
);
6293 g_signal_connect(button
, "clicked",
6294 G_CALLBACK(cb_monitor_interface_button_refresh
), pm
);
6295 gtk_box_pack_end(GTK_BOX(box
), button
, TRUE
, TRUE
, 0);
6296 gtk_widget_show(button
);
6297 gtk_widget_grab_default(button
);
6300 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
6301 g_signal_connect(button, "clicked",
6302 G_CALLBACK(cb_monitor_interface_button_close), pm);
6303 gtk_box_pack_end(GTK_BOX(box), button, TRUE, TRUE, 0);
6304 gtk_widget_show(button);
6306 gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook
), 0);
6308 gapc_panel_monitor_model_rec_add(pcfg
, pm
);
6310 gapc_panel_systray_icon_create(pm
);
6312 g_async_queue_push(pm
->q_network
, (gpointer
) pm
);
6314 pm
->tid_automatic_refresh
=
6315 g_timeout_add((guint
) (pm
->d_refresh
* GAPC_REFRESH_FACTOR_1K
),
6316 (GSourceFunc
) cb_monitor_automatic_refresh
, pm
);
6318 pm
->menu
= menu
= gtk_menu_new();
6319 menu_item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_JUMP_TO
, NULL
);
6320 g_signal_connect(G_OBJECT(menu_item
), "activate",
6321 G_CALLBACK(cb_util_popup_menu_response_jumpto
), pm
);
6322 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), menu_item
);
6323 gtk_widget_show(menu_item
);
6324 menu_item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT
, NULL
);
6325 g_signal_connect(G_OBJECT(menu_item
), "activate",
6326 G_CALLBACK(cb_util_popup_menu_response_exit
), pm
);
6327 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), menu_item
);
6328 gtk_widget_show(menu_item
);
6329 gtk_widget_show(menu
);
6331 sbar
= g_hash_table_lookup (pcfg
->pht_Widgets
, "StatusBar");
6335 gtk_statusbar_pop(GTK_STATUSBAR(sbar
), pcfg
->i_info_context
);
6336 pch
= g_strdup_printf
6337 ("Monitor for %s Created!...", pm
->pch_host
);
6338 gtk_statusbar_push(GTK_STATUSBAR(sbar
), pcfg
->i_info_context
, pch
);
6342 return GTK_WIDGET(window
);
6346 * Creates monitor interface with the normal panels
6348 static void gapc_monitor_interface_destroy(PGAPC_CONFIG pcfg
, gint i_monitor
)
6351 PGAPC_MONITOR pm
= NULL
;
6353 g_return_if_fail(pcfg
!= NULL
);
6355 if (gapc_util_treeview_get_iter_from_monitor(pcfg
->monitor_model
, &iter
,
6357 gtk_tree_model_get(pcfg
->monitor_model
, &iter
, GAPC_MON_POINTER
, &pm
, -1);
6360 if ((pm
== NULL
) || (pm
->window
== NULL
)) {
6364 if (!pm
->cb_enabled
) {
6370 gtk_list_store_remove(GTK_LIST_STORE(pcfg
->monitor_model
), &iter
);
6372 if (pm
->cb_use_systray
) {
6373 gapc_panel_systray_icon_remove(pm
);
6376 if (pm
->menu
!= NULL
) {
6377 gtk_widget_destroy(pm
->menu
);
6380 if (pm
->window
!= NULL
) {
6381 gtk_widget_destroy(pm
->window
);
6390 extern int main(int argc
, char *argv
[])
6392 PGAPC_CONFIG pcfg
= NULL
;
6393 GtkWidget
*window
= NULL
;
6396 * Initialize GLib thread support, and GTK
6399 g_thread_init(NULL
);
6403 gtk_init(&argc
, &argv
);
6405 pcfg
= g_new0(GAPC_CONFIG
, 1);
6406 pcfg
->cb_id
= CB_CONTROL_ID
;
6409 * Get the instance number for this execution */
6410 if (gapc_main_interface_parse_args(argc
, argv
, pcfg
)) {
6411 return 1; /* exit if user only wanted help */
6414 gapc_util_load_icons(pcfg
);
6416 gapc_panel_gconf_init(pcfg
);
6418 window
= gapc_main_interface_create(pcfg
);
6419 if (!pcfg
->b_use_systray
) {
6420 pcfg
->b_visible
= TRUE
;
6421 g_object_set(pcfg
->window
,
6422 "skip-pager-hint", FALSE
,
6423 "skip-taskbar-hint", FALSE
,
6425 gtk_window_present(GTK_WINDOW(pcfg
->window
));
6428 gapc_panel_gconf_watch(pcfg
);
6431 * enter the GTK main loop
6433 gdk_threads_enter();
6436 gdk_threads_leave();