Source code for the Synema frames' private functions. More...
#include <errno.h>
#include <glib/gstdio.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include <unistd.h>
#include "application-data.h"
#include "frame-common.h"
#include "frame-private.h"
#include "frame-signals.h"
#include "frame-table.h"
#include "frame-utilities.h"
#include "gedit-spinner.h"
#include "machine.h"
#include "plugins.h"
#include "time-period.h"
Go to the source code of this file.
Functions | |
void | frame_set_id (frame_t *f, GList *list) |
Sets the ID of a frame and creates a tmp folder for this frame. | |
void | frame_on_exit (GtkWidget *button, gpointer user_data) |
Called automatically when the quit button is clicked. | |
frame_t * | frame_new (char *type) |
Creates an frame_t struct with mapped functions, not initialised. | |
void | frame_free (frame_t *f) |
Destroys a frame. | |
void | frame_free_uninitialised (frame_t *f) |
Destroys a frame that has not been initialised yet. | |
double | frame_timed_refresh_content (frame_t *f, int *call_result) |
Refresh the content of a frame and returns the CPU time used. | |
void | frame_update_size_button (frame_t *f) |
Changes the image of the size button in a frame. | |
void | frame_machine_changed (GtkComboBox *box, gpointer user_data) |
Handler for the event of the display machine combo box. | |
void | frame_time_period_changed (GtkComboBox *box, gpointer user_data) |
Handler for the event of the time period combo box. | |
gboolean | frame_button_event (GtkWidget *area, GdkEventButton *event, gpointer user_data) |
Handler for button press / release events in the drawing area. | |
gboolean | frame_expose_handler (GtkWidget *area, GdkEventExpose *event, gpointer user_data) |
Handler for the expose events in the drawing area. | |
void | frame_size_changed_event (GtkWidget *button, gpointer user_data) |
Handler for the clicked events on the size button. | |
gpointer | frame_computing_thread (gpointer data) |
Handler for the clicked events on the size button. |
Source code for the Synema frames' private functions.
This source code file contains private utility functions for Synema frames.
Definition in file frame-private.c.
gboolean frame_button_event | ( | GtkWidget * | area, | |
GdkEventButton * | event, | |||
gpointer | user_data | |||
) |
Handler for button press / release events in the drawing area.
This function handles mouse button events in a frame's drawing area. It identifies the event type and calls the appropriate function written by the plugin developers.
[in] | area | the drawing area where the event occurred |
[in] | event | the button event struct |
[in,out] | user_data | a pointer to the frame_t struct |
Definition at line 299 of file frame-private.c.
00302 { 00303 frame_t *frame = user_data; 00304 // XXX v0.1 plugins compatibility 00305 if (event->type == GDK_BUTTON_PRESS) { 00306 if (frame->button_press_handler) 00307 frame->button_press_handler (frame, event); 00308 else 00309 g_warning ("frame_button_event: No button_press_handler function in frame %u, deprecated plugin (%s) format (0.3.1)", frame->id, frame->type); 00310 } else if (event->type == GDK_BUTTON_RELEASE) { 00311 if (frame->button_release_handler) 00312 frame->button_release_handler (frame, event); 00313 else 00314 g_warning ("frame_button_event: No button_release_handler function in frame %u, deprecated plugin (%s) format (0.3.1)", frame->id, frame->type); 00315 } 00316 00317 return FALSE; 00318 }
gpointer frame_computing_thread | ( | gpointer | data | ) |
Handler for the clicked events on the size button.
This function is the data computing manager. It is running as a separate thread, launched during initialisation.
[in,out] | data | the frame to which the thread is attached |
Definition at line 388 of file frame-private.c.
00389 { 00390 synema_instance_t *inst = synema_instance (); 00391 frame_t *f = (frame_t *) data; 00392 gboolean do_refresh = FALSE; 00393 GTimeVal timeval; 00394 00395 while (f->compute) { 00396 g_mutex_lock (f->mutex); 00397 00398 g_get_current_time (&timeval); 00399 if (inst->settings->refresh_freq == REFRESH_FREQ_AUTO) { 00400 /* When timeout is 0, we decrease it X times by 1, so we can simulate 00401 * X passes of an algorithm that will calculate the total waiting time 00402 * before a refreshing was needed. Once we did that X times, we can 00403 * divide the sum by X to get an average waiting time between each 00404 * refresh. Then, we will set timeout to 10 minutes and decrease it 00405 * each time by the average time found. 00406 */ 00407 if (f->avg_refresh_timeout <= 0) { 00408 // Initialising the calculation mode 00409 GTimer *elapsed = g_timer_new (); 00410 g_timer_start (elapsed); 00411 if (f->avg_refresh_timeout == 0) 00412 f->avg_refresh_time = 0; 00413 00414 // Calculating the time till next refresh 00415 while (!f->is_refreshing_needed (f)) { 00416 g_get_current_time (&timeval); 00417 g_time_val_add (&timeval, 250000); 00418 g_cond_timed_wait (f->cond, f->mutex, &timeval); 00419 } 00420 00421 g_timer_stop (elapsed); 00422 f->avg_refresh_time += g_timer_elapsed (elapsed, NULL); 00423 g_timer_destroy (elapsed); 00424 do_refresh = TRUE; 00425 00426 // Now set timeout and go back into normal mode, if the number of 00427 // passes has been reached (remember we start and 0 and decrease 00428 // by one in each pass, so there have been X passes if we have 00429 // timeout at - (X-1)) 00430 if (f->avg_refresh_timeout == -(AVG_REFRESH_TIME_NB_PASS - 1)) { 00431 f->avg_refresh_timeout = AUTO_REFRESH_FREQ_TIMEOUT_LEN; 00432 f->avg_refresh_time /= AVG_REFRESH_TIME_NB_PASS; 00433 } else { 00434 f->avg_refresh_timeout--; 00435 } 00436 } 00437 //Timeout > 0, remaining time before next recalculation of average refresh freq 00438 else { 00439 f->avg_refresh_timeout -= f->avg_refresh_time; 00440 if (f->avg_refresh_timeout < 0) 00441 f->avg_refresh_timeout = 0; //Dont go in negatives to not screw the recalculation algorithm 00442 g_time_val_add (&timeval, f->avg_refresh_time * G_USEC_PER_SEC); 00443 g_cond_timed_wait (f->cond, f->mutex, &timeval); 00444 do_refresh = f->is_refreshing_needed (f); 00445 } 00446 } 00447 // We use a fixed refresh frequency here 00448 else { 00449 g_time_val_add (&timeval, inst->settings->refresh_freq * 1000); //Turn into usec 00450 g_cond_timed_wait (f->cond, f->mutex, &timeval); 00451 do_refresh = f->is_refreshing_needed (f); 00452 } 00453 00454 // This while statement allows requesting new recomputes while the content is 00455 // already being refreshed 00456 if ((f->compute) && (do_refresh) && (!f->hidden)) { 00457 f->show_spinner = TRUE; 00458 f->spinner_start_src = gdk_threads_add_idle (frame_spinner_start, data); 00459 do { 00460 f->computing_requested = FALSE; 00461 f->refresh_content (f); 00462 } while (f->computing_requested); 00463 f->show_spinner = FALSE; 00464 f->spinner_stop_src = gdk_threads_add_idle (frame_spinner_stop, data); 00465 } 00466 00467 g_mutex_unlock (f->mutex); 00468 } 00469 00470 return NULL; 00471 }
gboolean frame_expose_handler | ( | GtkWidget * | area, | |
GdkEventExpose * | event, | |||
gpointer | user_data | |||
) |
Handler for the expose events in the drawing area.
This function handles expose events in a frame's drawing area. It retrieves a cairo_t from the area's GdkWindow, clips it to the area that needs to be drawn again, and calls the plugin developers' draw_area function.
[in] | area | the drawing area where the event occurred |
[in] | event | the expose event struct |
[in,out] | user_data | a pointer to the frame_t struct |
Definition at line 322 of file frame-private.c.
00325 { 00326 frame_t *f = NULL; 00327 cairo_t *cr = NULL; 00328 00329 f = (frame_t *) user_data; 00330 00331 cr = gdk_cairo_create (area->window); 00332 cairo_rectangle (cr, event->area.x, event->area.y, 00333 event->area.width, event->area.height); 00334 cairo_clip (cr); 00335 00336 f->draw_area (f, cr); 00337 00338 cairo_destroy (cr); 00339 00340 return FALSE; 00341 }
void frame_free | ( | frame_t * | f | ) |
Destroys a frame.
This function calls the free_private function of the frame, then destroys its gtkbuilder, and and frees the frame and its type.
[out] | f | the frame to destroy |
Definition at line 186 of file frame-private.c.
00187 { 00188 if (f) { 00189 f->compute = FALSE; 00190 g_cond_signal (f->cond); 00191 g_thread_join (f->computing_thread); 00192 g_mutex_free (f->mutex); 00193 g_cond_free (f->cond); 00194 f->free_private (f); 00195 if (f->spinner_stop_src) 00196 g_source_remove (f->spinner_stop_src); 00197 if (f->spinner_start_src) 00198 g_source_remove (f->spinner_start_src); 00199 g_object_unref (f->signal_box); 00200 g_object_unref (f->builder); 00201 g_free (f->type); 00202 g_free (f); 00203 } 00204 }
void frame_free_uninitialised | ( | frame_t * | f | ) |
Destroys a frame that has not been initialised yet.
This function frees the dynamically allocated members of a frame_t struct that are allocated in frame_new and then frees the frame itself.
[out] | f | the frame to destroy |
Definition at line 208 of file frame-private.c.
00209 { 00210 if (f) { 00211 g_free (f->type); 00212 g_free (f); 00213 } 00214 }
void frame_machine_changed | ( | GtkComboBox * | box, | |
gpointer | user_data | |||
) |
Handler for the event of the display machine combo box.
This function checks the display machine combo box of a frame to find the new machine to display, then updates the display_machine member, and finally calls a simplified handler written by plugin developers.
[in,out] | box | the combo box that emitted the signal |
[out] | user_data | a pointer to the frame_t struct |
Definition at line 257 of file frame-private.c.
00258 { 00259 frame_t *f = NULL; 00260 GtkTreeIter iter; 00261 GtkTreeModel *model; 00262 00263 f = (frame_t *) user_data; 00264 00265 if (gtk_combo_box_get_active_iter (box, &iter)) { 00266 model = gtk_combo_box_get_model (box); 00267 gtk_tree_model_get (model, &iter, 1, &f->display_machine, -1); 00268 } 00269 00270 if (f->last_err == ERROR_MACHINE) 00271 frame_unset_error (f); 00272 00273 f->display_machine_changed (f); 00274 }
frame_t * frame_new | ( | char * | type | ) |
Creates an frame_t struct with mapped functions, not initialised.
This function allocates memory for a frame and makes sure to link it's functions to a frame specific set of functions. The frame's type depends on the parameter passed to the function, which is the name of a folder in the plugins directory. It will return NULL if the frame type's plugin cannot be loaded.
[in] | type | the type of frame to create |
Definition at line 68 of file frame-private.c.
00069 { 00070 gboolean deprecated = FALSE; 00071 frame_t *frame = g_malloc (sizeof (frame_t)); 00072 plugin_t *pt = plugin_list_find (type); 00073 00074 *(void **) (&(frame->build_func_list)) = plugin_get_symbol (pt, "build_func_list", TRUE); 00075 if (!frame->build_func_list) { 00076 g_warning ("frame_new: Failed to get mandatory symbol build_func_list"); 00077 g_free (frame); 00078 return NULL; 00079 } 00080 00081 *(void **) (&(frame->build_time_periods)) = plugin_get_symbol (pt, "build_time_periods", TRUE); 00082 if (!frame->build_time_periods) { 00083 g_warning ("frame_new: Failed to get mandatory symbol build_time_periods"); 00084 g_free (frame); 00085 return NULL; 00086 } 00087 00088 *(void **) (&(frame->is_refreshing_needed)) = plugin_get_symbol (pt, "is_refreshing_needed", TRUE); 00089 if (!frame->is_refreshing_needed) { 00090 g_warning ("frame_new: Failed to get mandatory symbol is_refreshing_needed"); 00091 g_free (frame); 00092 return NULL; 00093 } 00094 00095 *(void **) (&(frame->refresh_content)) = plugin_get_symbol (pt, "refresh_content", TRUE); 00096 if (!frame->refresh_content) { 00097 g_warning ("frame_new: Failed to get mandatory symbol refresh_content"); 00098 g_free (frame); 00099 return NULL; 00100 } 00101 00102 *(void **) (&(frame->init_private)) = plugin_get_symbol (pt, "init_private", TRUE); 00103 if (!frame->init_private) { 00104 g_warning ("frame_new: Failed to get mandatory symbol init_private"); 00105 g_free (frame); 00106 return NULL; 00107 } 00108 00109 *(void **) (&(frame->free_private)) = plugin_get_symbol (pt, "free_private", TRUE); 00110 if (!frame->free_private) { 00111 g_warning ("frame_new: Failed to get mandatory symbol free_private"); 00112 g_free (frame); 00113 return NULL; 00114 } 00115 00116 *(void **) (&(frame->display_machine_changed)) = plugin_get_symbol (pt, "display_machine_changed", TRUE); 00117 if (!frame->display_machine_changed) { 00118 g_warning ("frame_new: Failed to get mandatory symbol display_machine_changed"); 00119 g_free (frame); 00120 return NULL; 00121 } 00122 00123 *(void **) (&(frame->time_period_changed)) = plugin_get_symbol (pt, "time_period_changed", TRUE); 00124 if (!frame->time_period_changed) { 00125 g_warning ("frame_new: Failed to get mandatory symbol time_period_changed"); 00126 g_free (frame); 00127 return NULL; 00128 } 00129 00130 *(void **) (&(frame->frame_size_changed)) = plugin_get_symbol (pt, "frame_size_changed", TRUE); 00131 if (!frame->frame_size_changed) { 00132 g_warning ("frame_new: Failed to get mandatory symbol frame_size_changed"); 00133 g_free (frame); 00134 return NULL; 00135 } 00136 00137 *(void **) (&(frame->draw_area)) = plugin_get_symbol (pt, "draw_area", TRUE); 00138 if (!frame->draw_area) { 00139 g_warning ("frame_new: Failed to get mandatory symbol draw_area"); 00140 g_free (frame); 00141 return NULL; 00142 } 00143 00144 *(void **) (&(frame->get_display_name)) = plugin_get_symbol (pt, "get_display_name", TRUE); 00145 if (!frame->get_display_name) { 00146 g_warning ("frame_new: Failed to get mandatory symbol get_display_name"); 00147 g_free (frame); 00148 return NULL; 00149 } 00150 00151 00152 *(void **) (&(frame->button_press_handler)) = plugin_get_symbol (pt, "button_press_handler", FALSE); 00153 if (!frame->button_press_handler) { 00154 g_warning ("frame_new: Failed to get optional symbol button_press_handler"); 00155 deprecated = TRUE; 00156 } 00157 00158 *(void **) (&(frame->button_release_handler)) = plugin_get_symbol (pt, "button_release_handler", FALSE); 00159 if (!frame->button_release_handler) { 00160 g_warning ("frame_new: Failed to get optional symbol button_release_handler"); 00161 deprecated = TRUE; 00162 } 00163 00164 *(void **) (&(frame->restore_private)) = plugin_get_symbol (pt, "restore_private", FALSE); 00165 if (!frame->restore_private) { 00166 g_warning ("frame_new: Failed to get optional symbol restore_private"); 00167 deprecated = TRUE; 00168 } 00169 00170 *(void **) (&(frame->save_private)) = plugin_get_symbol (pt, "save_private", FALSE); 00171 if (!frame->save_private) { 00172 g_warning ("frame_new: Failed to get optional symbol save_private"); 00173 deprecated = TRUE; 00174 } 00175 00176 00177 if (deprecated) 00178 g_warning ("frame_new: plugin %s uses a deprecated API version", type); 00179 00180 frame->type = g_strdup (type); 00181 return frame; 00182 }
void frame_on_exit | ( | GtkWidget * | button, | |
gpointer | user_data | |||
) |
Called automatically when the quit button is clicked.
This function removes the frame from the frames list, its parent container, and then frees it.
[in] | button | the button that was clicked and triggered the event |
[out] | user_data | a pointer to the frame to detach and destroy |
Definition at line 59 of file frame-private.c.
00060 { 00061 frame_t *f = (frame_t *) user_data; 00062 00063 frame_table_remove (f->parent, f); 00064 }
void frame_set_id | ( | frame_t * | f, | |
GList * | list | |||
) |
Sets the ID of a frame and creates a tmp folder for this frame.
This function sets an ID for a given frame, that is different from the ones already in use by members of a frames list given as a parameter. Once a suitable ID has been found, the function will create a tmp directory for this frame.
[out] | f | the frame that needs an ID |
[in] | list | the list of frames in which the frame will be put |
Definition at line 44 of file frame-private.c.
00045 { 00046 synema_instance_t *inst = synema_instance (); 00047 f->id = unique_frame_id_generator (list); 00048 gchar *path = g_strdup_printf ("%s/frame_%u", inst->tmp_dir, f->id); 00049 00050 if (g_mkdir_with_parents (path, 0777) != 0) { 00051 g_warning ("frame_set_id: Could not create a tmp directory, the plugin may encounter problems (%s)", 00052 g_strerror (errno)); 00053 } 00054 g_free (path); 00055 }
void frame_size_changed_event | ( | GtkWidget * | button, | |
gpointer | user_data | |||
) |
Handler for the clicked events on the size button.
This function handles clicked events in a frame's resizing button. It toggles the size between large and normal, and refreshes the image in the button.
[in] | button | the button that needs updating |
[in,out] | user_data | a pointer to the frame_t struct |
Definition at line 345 of file frame-private.c.
00347 { 00348 frame_t *f = NULL; 00349 GtkWidget *area = NULL; 00350 00351 f = (frame_t *) user_data; 00352 00353 if (f->size == NORMAL) 00354 f->size = LARGE; 00355 else 00356 f->size = NORMAL; 00357 00358 frame_update_size_button (f); 00359 00360 area = (GtkWidget *) gtk_builder_get_object (f->builder, "drawing_area"); 00361 gtk_widget_set_size_request (area, frame_get_width (f), 00362 frame_get_height (f)); 00363 gtk_widget_queue_resize (frame_get_root_widget (f)); 00364 00365 f->frame_size_changed (f); 00366 }
void frame_time_period_changed | ( | GtkComboBox * | box, | |
gpointer | user_data | |||
) |
Handler for the event of the time period combo box.
This function checks the time period combo box of a frame to find the new machine to display, then updates the display_period member, and finally calls a simplified handler written by plugin developers.
[in,out] | box | the combo box that emitted the signal |
[out] | user_data | a pointer to the frame_t struct |
Definition at line 278 of file frame-private.c.
00279 { 00280 frame_t *f = NULL; 00281 GtkTreeIter iter; 00282 GtkTreeModel *model; 00283 00284 f = (frame_t *) user_data; 00285 00286 if (gtk_combo_box_get_active_iter (box, &iter)) { 00287 model = gtk_combo_box_get_model (box); 00288 gtk_tree_model_get (model, &iter, 1, &f->display_period.type, 2, &f->display_period.value, -1); 00289 } 00290 00291 if (f->last_err == ERROR_PERIOD) 00292 frame_unset_error (f); 00293 00294 f->time_period_changed (f); 00295 }
double frame_timed_refresh_content | ( | frame_t * | f, | |
int * | call_result | |||
) |
Refresh the content of a frame and returns the CPU time used.
This function will call the one in charge of refreshing the content, but it will also calculate the CPU time it takes to execute (with clock()).
[in,out] | f | the frame which needs to refresh its content |
[out] | call_result | the return value of the content refreshing function |
Definition at line 218 of file frame-private.c.
00219 { 00220 GTimer *chrono = g_timer_new (); 00221 00222 if (call_result != NULL) 00223 *call_result = f->refresh_content (f); 00224 else 00225 f->refresh_content (f); 00226 00227 g_timer_stop (chrono); 00228 00229 double result = g_timer_elapsed (chrono, NULL); 00230 00231 g_timer_destroy (chrono); 00232 00233 return result; 00234 }
void frame_update_size_button | ( | frame_t * | f | ) |
Changes the image of the size button in a frame.
This function makes sure the image used in the size toggle button of a frame is the one depicting the size mode that is not currently in use.
[in,out] | f | the frame for which the size button needs to be updated |
Definition at line 238 of file frame-private.c.
00239 { 00240 GtkWidget *button = NULL; 00241 GtkWidget *size_image = NULL; 00242 00243 button = (GtkWidget *) gtk_builder_get_object (f->builder, "size_toggle"); 00244 00245 if (f->size == NORMAL) 00246 size_image = gtk_image_new_from_stock ("gtk-zoom-in", GTK_ICON_SIZE_BUTTON); 00247 else if (f->size == LARGE) 00248 size_image = gtk_image_new_from_stock ("gtk-zoom-out", GTK_ICON_SIZE_BUTTON); 00249 else // FULL SCREEN 00250 size_image = gtk_image_new_from_stock ("gtk-leave-fullscreen", GTK_ICON_SIZE_BUTTON); 00251 00252 gtk_button_set_image (GTK_BUTTON (button), size_image); 00253 }