src/frame-private.c File Reference

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"
Include dependency graph for frame-private.c:

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_tframe_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.

Detailed Description

Source code for the Synema frames' private functions.

Author:
Steve Dodier <sidnioulz@gmail.com>

This source code file contains private utility functions for Synema frames.

Definition in file frame-private.c.


Function Documentation

gboolean frame_button_event ( GtkWidget *  area,
GdkEventButton *  event,
gpointer  user_data 
)

Handler for button press / release events in the drawing area.

Warning:
This is a private function.

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.

Parameters:
[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
Returns:
FALSE

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.

Warning:
This is a private function.

This function is the data computing manager. It is running as a separate thread, launched during initialisation.

Parameters:
[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.

Warning:
This is a private function.

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.

Parameters:
[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
Returns:
FALSE

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.

Warning:
This is a private function.

This function calls the free_private function of the frame, then destroys its gtkbuilder, and and frees the frame and its type.

Parameters:
[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.

Warning:
This is a private function.

This function frees the dynamically allocated members of a frame_t struct that are allocated in frame_new and then frees the frame itself.

Parameters:
[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.

Warning:
This is a private function.

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.

Parameters:
[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.

Parameters:
[in] type the type of frame to create
Returns:
the created frame or NULL on error

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.

Warning:
This is a private function.

This function removes the frame from the frames list, its parent container, and then frees it.

Parameters:
[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.

Parameters:
[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.

Warning:
This is a private function.

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.

Parameters:
[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.

Warning:
This is a private function.

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.

Parameters:
[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.

Warning:
This is a private function.

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()).

Parameters:
[in,out] f the frame which needs to refresh its content
[out] call_result the return value of the content refreshing function
Returns:
the time, in seconds, that the function took to execute

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.

Warning:
This is a private function.

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.

Parameters:
[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 }

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Tue Jan 12 00:48:44 2010 for ENSIBSynema by  doxygen 1.6.1