Show emview_gui.c syntax highlighted
/*
*
* Copyright (c) 2003 The Regents of the University of California. All
* rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* emview_gui.c
*
* Pedigree:
*
* connview (cerpa)
* |
* - ascentview (cerpa)
* |
* - syncview (jelson)
* |
* - demoview (jelson)
* |
* - GTK Scribble, of course
*
* $Id: emview_gui.c,v 1.28 2004/10/12 16:45:07 girod Exp $
*/
#include "emview_i.h"
#include <math.h>
/*
* coordinate transforms
*/
static int emview_real_width()
{ return _core.gui.width - _core.gui.left_reserved - _core.gui.right_reserved; }
static int emview_real_height()
{ return _core.gui.height - _core.gui.top_reserved - _core.gui.bot_reserved; }
int emview_m2p_x(float x_coord_meters)
{
return _core.gui.left_reserved +
(x_coord_meters - _core.gui.view_x) * _core.gui.zoom_factor;
}
float emview_p2m_x(int x_pixels)
{
/* reverse dir */
return (float)(x_pixels - _core.gui.left_reserved) / _core.gui.zoom_factor
+ _core.gui.view_x;
}
int emview_m2p_y(float y_coord_meters)
{
return _core.gui.top_reserved +
(y_coord_meters - _core.gui.view_y) * _core.gui.zoom_factor;
}
float emview_p2m_y(int y_pixels)
{
/* reverse dir */
return (float)(y_pixels - _core.gui.top_reserved) / _core.gui.zoom_factor
+ _core.gui.view_y;
}
void emview_recalc_zoom()
{
/* clear any partial draw */
_core.gui.incomplete = 0;
/* first recompute extent */
emview_nodes_compute_extent();
/* if not zoomed, reset the view */
if (!_core.gui.zoomed) {
float x_ppf, y_ppf;
_core.gui.view_x = _core.gui.extent_x_min;
_core.gui.view_y = _core.gui.extent_y_min;
x_ppf =
(emview_real_width() - EMVIEW_EXCESS_WIDTH) /
(float)(_core.gui.extent_x_max - _core.gui.extent_x_min);
y_ppf =
(emview_real_height() - EMVIEW_EXCESS_HEIGHT) /
(float)(_core.gui.extent_y_max - _core.gui.extent_y_min);
_core.gui.zoom_factor = f_min(x_ppf, y_ppf);
if (_core.gui.zoom_factor < 0)
_core.gui.zoom_factor = 0;
}
}
GdkFont *emview_tryfont(char *font_str)
{
GdkFont *font = gdk_font_load(font_str);
if (font == NULL) {
elog(LOG_DEBUG(5), "Can't allocate font '%s'", font_str);
return gtk_style_get_font(gtk_widget_get_style(_core.gui.window));
}
return font;
}
GdkColor *emview_color(emview_color_t color, int light)
{
if ((color < EMVIEW_MAX_COLORS) && (color != EMVIEW_COLOR_NONE))
return light ? &_core.gui.colors[color].light_color : &_core.gui.colors[color].color;
return NULL;
}
int emview_set_fg_color(GdkGC *gc, emview_color_t color, int light)
{
GdkColor *c = emview_color(color, light);
if (c) gdk_gc_set_foreground(gc, c);
return c ? TRUE : FALSE;
}
/*
* label drawing
*
* x2,y2 only used in bot just or center modes
*/
int emview_put_label_in_comp(component_t *c, char *buf,
emview_color_t bg_color, emview_color_t fg_color,
emview_color_t box_color,
int v_just, int h_just, int pad,
int bold, int italics, int p_size, int light)
{
return
emview_put_label(c->px, c->py, c->w, c->h, buf,
bg_color, fg_color, box_color, v_just, h_just,
pad, bold, italics, p_size, light);
}
int emview_put_label(int x1, int y1, int width, int height, char *buf,
emview_color_t bg_color, emview_color_t fg_color,
emview_color_t box_color,
int v_just, int h_just, int pad,
int bold, int italics, int p_size, int light)
{
static GdkGC *gc = NULL;
int x,y;
int size = p_size ? p_size : 10;
char font_name[256];
sprintf(font_name, "-*-helvetica-%s-%s-normal--%d-*-75-75-p-*-iso8859-1",
bold ? "bold" : "medium",
italics ? "i" : "r",
size);
{
GdkFont *font = emview_tryfont(font_name);
int h = gdk_string_height(font, buf);
int w = gdk_string_width(font, buf);
int x2 = x1+width;
int y2 = y1+height;
if (gc == NULL) {
gc = gdk_gc_new(_core.gui.window->window);
gdk_gc_copy(gc, _core.gui.window->style->black_gc);
}
if (buf == NULL) return 0;
switch (v_just) {
case EMVIEW_CENTER:
if (y2 == 0)
y = y1 - h/2 + h;
else
y = y1 + (y2-y1-h) / 2 + h;
break;
case EMVIEW_TOP_JUST:
y = y1 + h;
break;
case EMVIEW_BOT_JUST:
y = y2;
break;
default:
elog(LOG_WARNING, "Unrecognized v-just option %d writing string %s",
v_just, buf);
return -1;
}
switch (h_just) {
case EMVIEW_CENTER:
if (x2 == 0)
x = x1 - w/2;
else
x = x1 + (x2-x1-w) / 2;
break;
case EMVIEW_LEFT_JUST:
x = x1;
break;
case EMVIEW_RIGHT_JUST:
x = x2 - w;
break;
default:
elog(LOG_WARNING, "Unrecognized h-just option %d writing string %s",
h_just, buf);
return -1;
}
/* clear an area for the string */
if (bg_color != EMVIEW_COLOR_NONE) {
emview_set_fg_color(gc, bg_color, light);
gdk_draw_rectangle(_core.gui.fg_pixmap, gc, TRUE,
x - pad, y - h - pad,
w + 2*pad + 1,
h + 2*pad + 1);
}
/* draw box */
if (box_color != EMVIEW_COLOR_NONE) {
emview_set_fg_color(gc, box_color, light);
gdk_draw_rectangle(_core.gui.fg_pixmap, gc, FALSE,
x - pad, y - h - pad,
w + 2*pad,
h + 2*pad);
}
/* and draw the string */
emview_set_fg_color(gc, fg_color, light);
gdk_draw_string(_core.gui.fg_pixmap, font, gc, x, y, buf);
return h + 2*pad;
}
}
/*
* color map initialization
*/
static inline
int lightify(int x)
{
return i_min(65535, x + 3*65536/4);
}
void emview_color_init(int index, char *name, uint32_t hex)
{
GdkColormap *cmap;
_core.gui.colors[index].index = index;
_core.gui.colors[index].hexcode = hex;
_core.gui.colors[index].name = strdup(name);
_core.gui.colors[index].color.red = ((int)((hex & 0xFF0000) >> 16) * 65535) / 255;
_core.gui.colors[index].color.green = ((int)((hex & 0x00FF00) >> 8) * 65535) / 255;
_core.gui.colors[index].color.blue = ((int)((hex & 0x0000FF)) * 65535) / 255;
_core.gui.colors[index].light_color.red = lightify(_core.gui.colors[index].color.red);
_core.gui.colors[index].light_color.green = lightify(_core.gui.colors[index].color.green);
_core.gui.colors[index].light_color.blue = lightify(_core.gui.colors[index].color.blue);
/* Get the system color map and allocate the color */
cmap = gdk_colormap_get_system();
if (!gdk_color_alloc(cmap, &(_core.gui.colors[index].color)))
elog(LOG_WARNING, "couldn't allocate color %s", name);
if (!gdk_color_alloc(cmap, &(_core.gui.colors[index].light_color)))
elog(LOG_WARNING, "couldn't allocate color %s", name);
}
void emview_colors_init()
{
emview_color_init(EMVIEW_COLOR_WHITE, "White", 0xFFFFFF);
emview_color_init(EMVIEW_COLOR_BLACK, "Black", 0x0);
emview_color_init(EMVIEW_COLOR_RED, "Red", 0xFF0000);
emview_color_init(EMVIEW_COLOR_GREEN, "Green", 0xFF00);
emview_color_init(EMVIEW_COLOR_BLUE, "Blue", 0xFF);
emview_color_init(EMVIEW_COLOR_YELLOW, "Yellow", 0xFFFF00);
emview_color_init(EMVIEW_COLOR_MAGENTA, "Magenta", 0xFF00FF);
emview_color_init(EMVIEW_COLOR_CYAN, "Cyan", 0xFFFF);
emview_color_init(EMVIEW_COLOR_BURGANDY, "Burgandy", 0x800000);
emview_color_init(EMVIEW_COLOR_GRAY, "Gray", 0x333333);
}
/*
* redraw hook
*/
static
void emview_draw_zoom_box(int use_pixmap)
{
static GdkGC *gc = NULL;
/* zoom box gc */
if (gc == NULL) {
gc = gdk_gc_new(_core.gui.window->window);
gdk_gc_copy(gc, _core.gui.window->style->black_gc);
gdk_gc_set_function(gc, GDK_XOR);
emview_set_fg_color(gc, EMVIEW_COLOR_CYAN, 0);
}
gdk_draw_rectangle(use_pixmap ? _core.gui.fg_pixmap :
_core.gui.drawing_area->window, gc, FALSE,
i_min(_core.gui.startx, _core.gui.lastx),
i_min(_core.gui.starty, _core.gui.lasty),
abs(_core.gui.lastx - _core.gui.startx),
abs(_core.gui.lasty - _core.gui.starty));
}
static
void emview_screen_update()
{
GdkRectangle update_rect;
/* force a screen update */
update_rect.x = 0;
update_rect.y = 0;
update_rect.width = _core.gui.window->allocation.width;
update_rect.height = _core.gui.window->allocation.height;
/* draw in zoom box */
if (_core.gui.zoom_sel)
emview_draw_zoom_box(1);
gtk_widget_draw(_core.gui.window, &update_rect);
}
static
void increase_divisor(int *div)
{
if (*div == 1) *div = 5;
else if (*div == 5) *div = 10;
else if (*div == 10) *div = 20;
else if (*div == 20) *div = 50;
else *div *= 2;
}
static
int emview_redraw(void *data, int interval, g_event_t *event)
{
int i;
int f;
if (_core.gui.timer == NULL)
_core.gui.timer = g_timer_new();
/* reset and start the timer */
g_timer_reset(_core.gui.timer);
g_timer_start(_core.gui.timer);
/* recalc zoom if full redraw */
if (_core.gui.next_full) {
/* blit what we've got */
if (_core.gui.incomplete)
emview_screen_update();
/* calc zoom unsets incomplete */
emview_recalc_zoom();
_core.gui.next_full = 0;
}
if (!_core.gui.incomplete) {
static GdkGC *gc = NULL;
if (gc == NULL) {
gc = gdk_gc_new(_core.gui.window->window);
gdk_gc_copy(gc, _core.gui.window->style->black_gc);
}
/* clear any past state */
emview_draw_nodes_reset();
/* mark as incomplete */
_core.gui.incomplete = 1;
emview_set_fg_color(gc, EMVIEW_COLOR_GRAY, 1);
/* clear the pixmap to gray */
gdk_draw_rectangle (_core.gui.fg_pixmap,
gc,
TRUE,
0, 0,
_core.gui.window->allocation.width,
_core.gui.window->allocation.height);
if (_core.gui.do_grid) {
int divisor=1;
char scale_str[128];
/* graph paper */
emview_set_fg_color(gc, EMVIEW_COLOR_BLACK, 1);
/* autoscale */
while (ceilf(emview_m2p_x(0)) + 30 > ceilf(emview_m2p_x(divisor)))
increase_divisor(&divisor);
while (ceilf(emview_m2p_y(0)) + 30 > ceilf(emview_m2p_y(divisor)))
increase_divisor(&divisor);
/* vert lines */
f = ceilf(emview_p2m_x(0));
for (i=0; i<_core.gui.window->allocation.width; i++) {
if (emview_p2m_x(i) > f) {
/* draw line */
gdk_draw_line(_core.gui.fg_pixmap, gc, i, 0, i, _core.gui.window->allocation.height);
f+=divisor;
}
}
/* horiz lines */
f = ceilf(emview_p2m_y(0));
for (i=0; i<_core.gui.window->allocation.height; i++) {
if (emview_p2m_y(i) > f) {
/* draw line */
gdk_draw_line(_core.gui.fg_pixmap, gc, 0, i, _core.gui.window->allocation.width, i);
f+=divisor;
}
}
sprintf(scale_str, "%d meter grid", divisor);
emview_put_label(0,0,100,10,scale_str,
EMVIEW_COLOR_YELLOW,
EMVIEW_COLOR_BLACK,
EMVIEW_COLOR_YELLOW,0,0,
0,0,0,0,0);
}
#if 0
for (i=1; i<EMVIEW_MAX_COLORS; i++) {
emview_set_fg_color(gc, i, 0);
gdk_draw_rectangle (_core.gui.fg_pixmap, gc, TRUE, 0, i*50, 50,50);
emview_set_fg_color(gc, i, 1);
gdk_draw_rectangle (_core.gui.fg_pixmap, gc, TRUE, 50, i*50, 50,50);
}
#endif
}
/* draw (keep drawing?) the nodes */
_core.gui.incomplete = emview_draw_nodes(_core.gui.timer);
/* stop timer */
g_timer_stop(_core.gui.timer);
if (!_core.gui.incomplete) {
emview_screen_update();
#if 0
/* resched with a break */
return TIMER_RENEW_MS(EMVIEW_DEFAULT_REDRAW_INTERVAL +
(int)(g_timer_elapsed(_core.gui.timer, NULL) * 1000));
#endif
g_event_destroy(_core.gui.timer_event);
g_timer_add(EMVIEW_DEFAULT_REDRAW_INTERVAL,
emview_redraw, NULL, NULL, &(_core.gui.timer_event));
return TIMER_DONE;
}
#if 0
/* resched with a smaller break */
return TIMER_RENEW_MS((int)(g_timer_elapsed(_core.gui.timer, NULL) * 1000) +
EMVIEW_DEFAULT_REDRAW_SLICE*2);
#endif
g_event_destroy(_core.gui.timer_event);
g_timer_add(EMVIEW_DEFAULT_REDRAW_SLICE,
emview_redraw, NULL, NULL, &(_core.gui.timer_event));
return TIMER_DONE;
}
void emview_next_redraw_full()
{
_core.gui.incomplete = 0;
_core.gui.next_full = 1;
}
void emview_force_redraw()
{
emview_next_redraw_full();
emview_redraw(NULL, 0, NULL);
}
/*
* mouse handling
*/
static gboolean
emview_button_press_event(GtkWidget *widget, GdkEventButton *event)
{
/* on button 1 press, turn on zoom */
if (event->button == 1) {
if (event->type == GDK_BUTTON_PRESS) {
_core.gui.zoom_sel = 1;
_core.gui.startx = event->x;
_core.gui.starty = event->y;
_core.gui.lastx = _core.gui.startx;
_core.gui.lasty = _core.gui.starty;
}
if (event->type == GDK_2BUTTON_PRESS) {
_core.gui.zoom_sel = 0;
_core.gui.zoomed = 0;
emview_force_redraw();
}
}
return TRUE;
}
static gboolean
emview_button_release_event(GtkWidget *widget, GdkEventButton *event)
{
/* on button 1 release, turn on zoom */
if (event->button == 1) {
if (_core.gui.zoom_sel) {
_core.gui.zoom_sel = 0;
emview_draw_zoom_box(0);
/* recenter on single click */
if (((_core.gui.startx - _core.gui.lastx) == 0) &&
((_core.gui.starty - _core.gui.lasty) == 0)) {
_core.gui.view_x = emview_p2m_x(_core.gui.startx -
emview_real_width() / 2);
_core.gui.view_y = emview_p2m_y(_core.gui.starty -
emview_real_height() / 2);
_core.gui.zoomed = 1;
emview_force_redraw();
}
/* otherwise zoom in */
else {
int x1,y1;
float w;
x1 = i_min(_core.gui.startx, _core.gui.lastx);
y1 = i_min(_core.gui.starty, _core.gui.lasty);
w = abs(_core.gui.lastx - _core.gui.startx);
_core.gui.zoomed = 1;
_core.gui.view_x = emview_p2m_x(x1);
_core.gui.view_y = emview_p2m_y(y1);
if (emview_real_width() > 0)
_core.gui.zoom_factor = _core.gui.zoom_factor / w * (float)(emview_real_width());
emview_force_redraw();
}
}
}
return TRUE;
}
static gboolean
emview_motion_event(GtkWidget *widget, GdkEventMotion *event)
{
int x, y;
GdkModifierType state;
/* get the latest mouse info */
if (event->is_hint)
gdk_window_get_pointer (event->window, &x, &y, &state);
else {
x = event->x;
y = event->y;
state = event->state;
}
if (_core.gui.zoom_sel && (state & GDK_BUTTON1_MASK)) {
int x1=_core.gui.startx;
int y1=_core.gui.starty;
elog(LOG_DEBUG(10), "zooming %d,%d, %d,%d last=%d,%d", x,y,
_core.gui.startx, _core.gui.starty,
_core.gui.lastx, _core.gui.lasty);
emview_draw_zoom_box(0);
/* compute the new lastx coords */
if (emview_real_height() > 0)
x1 += (y - _core.gui.starty) *
emview_real_width() / emview_real_height();
if (emview_real_width() > 0)
y1 += (x - _core.gui.startx) *
emview_real_height() / emview_real_width();
if (abs(x-x1) > abs(y-y1)) {
_core.gui.lastx = x;
_core.gui.lasty = y1;
}
else {
_core.gui.lastx = x1;
_core.gui.lasty = y;
}
emview_draw_zoom_box(0);
}
return TRUE;
}
/*
* handle resize and redraw
*/
/* Redraw the screen if we get an expose event */
static gint emview_expose_event(GtkWidget *widget,
GdkEventExpose *event )
{
#if 0 /* this was really really slow! */
gdk_draw_pixmap(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
_core.gui.fg_pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
#endif
return FALSE;
}
/* Initialize the drawing area widget */
static gint emview_configure_event(GtkWidget *widget,
GdkEventConfigure *event )
{
/* free last pixmaps */
if (_core.gui.fg_pixmap)
gdk_pixmap_unref(_core.gui.fg_pixmap);
/* compute new size */
_core.gui.width = widget->allocation.width;
_core.gui.height = widget->allocation.height;
/* create new pixmaps */
_core.gui.fg_pixmap =
gdk_pixmap_new(widget->window,
widget->allocation.width,
widget->allocation.height,
-1);
/* make this the backing pixmap now */
gdk_window_set_back_pixmap(widget->window, _core.gui.fg_pixmap, 0);
/* alloc gc if needed */
if (_core.gui.gc == NULL) {
_core.gui.gc = gdk_gc_new(widget->window);
gdk_gc_copy(_core.gui.gc, widget->style->black_gc);
}
/* force re-zoom and redraw */
emview_force_redraw();
return TRUE;
}
/*
* Image screenshot manipulation routines
*/
static void save_image(GtkFileSelection *file_selector, gpointer user_data)
{
char image_file[1024];
GError *error;
GdkPixbuf *pixbuf = NULL;
strcpy(image_file,
gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_selector))
);
pixbuf = gdk_pixbuf_get_from_drawable(NULL,
GDK_DRAWABLE(_core.gui.fg_pixmap),
gdk_colormap_get_system(),
0,0,
0,0,
_core.gui.width,
_core.gui.height
);
/* open file and save image */
gdk_pixbuf_save(pixbuf,
image_file,
(_core.gui.type) ? (_core.gui.type) : EMVIEW_DEFAULT_TYPE,
&error,
NULL
);
/* reenable the screen refresh timer */
g_timer_start(_core.gui.timer);
}
static gint save_image_cb(void *data)
{
GtkWidget *file_selector;
/* disable screen updates while saving */
g_timer_reset(_core.gui.timer);
/* Create the selector */
file_selector = gtk_file_selection_new ("Please provide file name.");
g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->ok_button),
"clicked",
G_CALLBACK (save_image),
(gpointer) file_selector
);
/* Ensure that the dialog box is destroyed when the user clicks a button. */
g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->ok_button),
"clicked",
G_CALLBACK (gtk_widget_destroy),
(gpointer) file_selector
);
g_signal_connect_swapped(GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->cancel_button),
"clicked",
G_CALLBACK (gtk_widget_destroy),
(gpointer) file_selector
);
/* Display that dialog */
gtk_widget_show (file_selector);
return TRUE;
}
/*
* initialize main window, menus, etc.
*/
int emview_gui_init(int *argc, char **argv)
{
GtkWidget *vbox;
GtkWidget *menu;
/* initialize gtk */
gtk_init(argc, &argv);
/* initialize colormap */
emview_colors_init();
/* init gui struct */
_core.gui.top_reserved =
_core.gui.bot_reserved =
_core.gui.left_reserved =
_core.gui.right_reserved = EMVIEW_DEFAULT_MARGIN;
/* this should be a command line or menu option! */
if((_core.gui.type = malloc(MAX_TYPE_SIZE)) != NULL)
sprintf(_core.gui.type, EMVIEW_DEFAULT_TYPE);
else
elog(LOG_WARNING, "Failed to allocate memory for screenshot file"
"type");
/* Initialize the window */
_core.gui.window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW(_core.gui.window), _core.gui_title);
gtk_signal_connect(GTK_OBJECT (_core.gui.window), "destroy",
GTK_SIGNAL_FUNC(emview_exit), NULL);
/* vbox */
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add(GTK_CONTAINER (_core.gui.window), vbox);
gtk_widget_show(vbox);
/* Create the top menu bar */
_core.gui.menu_bar = gtk_menu_bar_new();
gtk_box_pack_start(GTK_BOX(vbox), _core.gui.menu_bar, FALSE, FALSE, 0);
gtk_widget_show(_core.gui.menu_bar);
/* File menu */
menu = emview_toplevel_menu("File", NULL);
emview_menu_item(menu, gtk_menu_item_new_with_label("Screenshot"), save_image_cb, NULL);
emview_menu_item(menu, gtk_menu_item_new_with_label("Quit"), emview_exit, NULL);
/* Module and Component menus */
emview_build_layout_menu();
emview_build_options_menu();
/* Create the drawing area */
_core.gui.drawing_area = gtk_drawing_area_new();
gtk_drawing_area_size(GTK_DRAWING_AREA(_core.gui.drawing_area),
_core.gui.width, _core.gui.height);
gtk_box_pack_start(GTK_BOX(vbox), _core.gui.drawing_area, TRUE, TRUE, 0);
gtk_widget_show(_core.gui.drawing_area);
/* Signals used to handle backing pixmap */
gtk_signal_connect(GTK_OBJECT(_core.gui.drawing_area), "expose_event",
(GtkSignalFunc)emview_expose_event, NULL);
gtk_signal_connect(GTK_OBJECT(_core.gui.drawing_area), "configure_event",
(GtkSignalFunc)emview_configure_event, NULL);
/* Signals used to grab mouse events */
gtk_signal_connect(GTK_OBJECT(_core.gui.drawing_area), "motion_notify_event",
(GtkSignalFunc)emview_motion_event, NULL);
gtk_signal_connect(GTK_OBJECT(_core.gui.drawing_area), "button_press_event",
(GtkSignalFunc)emview_button_press_event, NULL);
gtk_signal_connect(GTK_OBJECT(_core.gui.drawing_area), "button_release_event",
(GtkSignalFunc)emview_button_release_event, NULL);
gtk_widget_set_events(_core.gui.drawing_area,
GDK_EXPOSURE_MASK
| GDK_LEAVE_NOTIFY_MASK
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
| GDK_POINTER_MOTION_MASK
| GDK_POINTER_MOTION_HINT_MASK);
gtk_widget_show(_core.gui.window);
/* set redraw timer for frame rate */
g_event_destroy(_core.gui.timer_event);
g_timer_add(_core.gui.frame_rate, emview_redraw, NULL, NULL, &(_core.gui.timer_event));
return 0;
}
See more files for this project here