update_widget(GtkMathView* math_view)
update_widget(GtkMathView* math_view, gint x0, gint y0, gint width, gint height)
static void gtk_math_view_destroy(GtkObject*);/* GtkWidget functions */static gboolean gtk_math_view_configure_event(GtkWidget*, GdkEventConfigure*, GtkMathView*);static gboolean gtk_math_view_expose_event(GtkWidget*, GdkEventExpose*, GtkMathView*);static gboolean gtk_math_view_button_press_event(GtkWidget*, GdkEventButton*, GtkMathView*);static gboolean gtk_math_view_button_release_event(GtkWidget*, GdkEventButton*, GtkMathView*);static gboolean gtk_math_view_motion_notify_event(GtkWidget*, GdkEventMotion*, GtkMathView*);static void     gtk_math_view_realize(GtkWidget*, GtkMathView*);static void     gtk_math_view_size_request(GtkWidget*, GtkRequisition*);/* GtkMathView Signals */static void gtk_math_view_click(GtkMathView*, GtkMathViewElementId, int);static void gtk_math_view_select_begin(GtkMathView*, GtkMathViewElementId, int);static void gtk_math_view_select_over(GtkMathView*, GtkMathViewElementId, int);static void gtk_math_view_select_end(GtkMathView*, GtkMathViewElementId, int);static void gtk_math_view_select_abort(GtkMathView*);static void gtk_math_view_element_over(GtkMathView*, GtkMathViewElementId, int);/* auxiliary functions */static void setup_adjustment(GtkAdjustment*, gfloat, gfloat);static void setup_adjustments(GtkMathView*);static void reset_adjustments(GtkMathView*);/* Local data */static GtkEventBoxClass* parent_class = NULL;static guint click_signal = 0;static guint select_begin_signal = 0;static guint select_over_signal = 0;static guint select_end_signal = 0;static guint select_abort_signal = 0;static guint element_over_signal = 0;/* auxiliary C++ functions */#if GTKMATHVIEW_USES_GMETADOMstatic SmartPtr<Element>elementOfModelElement(const SmartPtr<Builder>& b, GtkMathViewElementId el){  if (SmartPtr<gmetadom_Builder> builder = smart_cast<gmetadom_Builder>(b))    if (SmartPtr<Element> elem = builder->findElement(DOM::Element((el))))      return elem;  return 0;}#elif GTKMATHVIEW_USES_LIBXML2static SmartPtr<Element>elementOfModelElement(const SmartPtr<Builder>& b, GtkMathViewElementId el){  if (SmartPtr<libxml2_Builder> builder = smart_cast<libxml2_Builder>(b))    if (SmartPtr<Element> elem = builder->findElement(el))      return elem;  return 0;}#elsestatic SmartPtr<Element>elementOfModelElement(const SmartPtr<Builder>&, GtkMathViewElementId){ return 0; }#endifstatic SmartPtr<const Gtk_WrapperArea>findGtkWrapperArea(const SmartPtr<View>& view, GtkMathViewElementId node){  if (SmartPtr<Element> elem = elementOfModelElement(view->getBuilder(), node))    if (SmartPtr<const Gtk_WrapperArea> area = smart_cast<const Gtk_WrapperArea>(elem->getArea()))      return area;  return 0;}/* widget implementation */static voidupdate_widget(GtkMathView* math_view){  GtkWidget* widget = GTK_WIDGET(math_view->area);  const gint width = widget->allocation.width;  const gint height = widget->allocation.height;  gdk_draw_pixmap(widget->window,		  widget->style->fg_gc[GTK_WIDGET_STATE(widget)],		  math_view->pixmap,		  0, 0, 0, 0, width, height);#if 1  if (math_view->cursor_elem)    {      gint y0 = 0;      if (AreaRef rootArea = math_view->view->getRootArea())	y0 = Gtk_RenderingContext::toGtkY(rootArea->box().height);      gint x;      gint y;      GtkMathViewBox gbox;      if (GTKMATHVIEW_METHOD_NAME(get_element_location)(math_view, math_view->cursor_elem,							&x, &y, &gbox))	{	  printf("DRAWING CURSOR AT (y offset = %d) (%d,%d) [%d,%d,%d]\n", y0, x, y, gbox.width, gbox.height, gbox.depth);	  gtk_paint_focus(widget->style,			  widget->window,			  GTK_STATE_NORMAL,			  NULL,			  widget,			  "?",			  x + MARGIN, MARGIN - y0 + y - gbox.height, gbox.width, gbox.height + gbox.depth);	}    }#endif}static voidpaint_widget(GtkMathView* math_view){  g_return_if_fail(math_view != NULL);  g_return_if_fail(math_view->area != NULL);  if (!GTK_WIDGET_MAPPED(GTK_WIDGET(math_view)) || math_view->freeze_counter > 0) return;  GtkWidget* widget = GTK_WIDGET(math_view->area);  setup_adjustments(math_view);  const gint width = widget->allocation.width;  const gint height = widget->allocation.height;  gdk_draw_rectangle(math_view->pixmap, widget->style->white_gc, TRUE, 0, 0, width, height);  //Rectangle rect(px2sp(math_view->top_x - MARGIN), px2sp(math_view->top_y - MARGIN), px2sp(width), px2sp(height));  math_view->view->setOrigin(Gtk_RenderingContext::fromGtkX(math_view->top_x - MARGIN),			     Gtk_RenderingContext::fromGtkY(math_view->top_y - MARGIN));  math_view->view->render(*math_view->renderingContext);  update_widget(math_view);}static voidhadjustment_value_changed(GtkAdjustment* adj, GtkMathView* math_view){  g_return_if_fail(adj != NULL);  g_return_if_fail(math_view != NULL);  if (adj->value > adj->upper - adj->page_size) adj->value = adj->upper - adj->page_size;  if (adj->value < adj->lower) adj->value = adj->lower;  math_view->old_top_x = math_view->top_x;  math_view->top_x = static_cast<int>(adj->value);  if (math_view->old_top_x != math_view->top_x)    paint_widget(math_view);}static voidvadjustment_value_changed(GtkAdjustment* adj, GtkMathView* math_view){  g_return_if_fail(adj != NULL);  g_return_if_fail(math_view != NULL);  if (adj->value > adj->upper - adj->page_size) adj->value = adj->upper - adj->page_size;  if (adj->value < adj->lower) adj->value = adj->lower;  math_view->old_top_y = math_view->top_y;  math_view->top_y = static_cast<int>(adj->value);  if (math_view->old_top_y != math_view->top_y)    paint_widget(math_view);}extern "C" GTypeGTKMATHVIEW_METHOD_NAME(get_type)(void){  static GType math_view_type = 0;  if (!math_view_type) {    static const GTypeInfo math_view_info = {      sizeof(GtkMathViewClass),      NULL,      NULL,      (GClassInitFunc) gtk_math_view_class_init,      NULL,      NULL,      sizeof(GtkMathView),      0,      (GInstanceInitFunc) gtk_math_view_init,    };    math_view_type = g_type_register_static(GTK_TYPE_EVENT_BOX, "GtkMathView",					    &math_view_info, (GTypeFlags) 0);  }  return math_view_type;}static voidinitGlobalData(const char* confPath){  static bool done = false;  assert(!done);  initTokens();  bool res = false;  if (confPath != NULL) res = GtkMathView_Setup::loadConfiguration(Globals::configuration, confPath);  if (!res) res = GtkMathView_Setup::loadConfiguration(Globals::configuration, PKGDATADIR"/math-engine-configuration.xml");  if (!res) res = GtkMathView_Setup::loadConfiguration(Globals::configuration, "config/math-engine-configuration.xml");  if (!res)    {      Globals::logger(LOG_ERROR, "could not load configuration file");      exit(-1);    }  if (!Globals::configuration.getDictionaries().empty())    for (std::vector<std::string>::const_iterator dit = Globals::configuration.getDictionaries().begin();	 dit != Globals::configuration.getDictionaries().end();	 dit++)      {	Globals::logger(LOG_DEBUG, "loading dictionary `%s'", (*dit).c_str());	if (!GtkMathView_Setup::loadOperatorDictionary(Globals::dictionary, (*dit).c_str()))	  Globals::logger(LOG_WARNING, "could not load `%s'", (*dit).c_str());      }  else {    bool res = GtkMathView_Setup::loadOperatorDictionary(Globals::dictionary, "config/dictionary.xml");    if (!res) GtkMathView_Setup::loadOperatorDictionary(Globals::dictionary, PKGDATADIR"/dictionary.xml");  }  done = true;}static voidgtk_math_view_class_init(GtkMathViewClass* klass){  GtkObjectClass* object_class;  GtkWidgetClass* widget_class;	  object_class = (GtkObjectClass*) klass;  widget_class = (GtkWidgetClass*) klass;	  klass->click = gtk_math_view_click;  klass->select_begin = gtk_math_view_select_begin;  klass->select_over = gtk_math_view_select_over;  klass->select_end = gtk_math_view_select_end;  klass->select_abort = gtk_math_view_select_abort;  klass->element_over = gtk_math_view_element_over;  klass->set_scroll_adjustments = gtk_math_view_set_adjustments;  parent_class = (GtkEventBoxClass*) gtk_type_class(gtk_event_box_get_type());  object_class->destroy = gtk_math_view_destroy;  widget_class->size_request = gtk_math_view_size_request;  	  widget_class->set_scroll_adjustments_signal =     g_signal_new("set_scroll_adjustments",		 G_OBJECT_CLASS_TYPE(object_class),		 G_SIGNAL_RUN_LAST,		 G_STRUCT_OFFSET(GtkMathViewClass,set_scroll_adjustments),		 NULL, NULL,		 gtk_marshal_NONE__POINTER_POINTER,		 G_TYPE_NONE , 2 , GTK_TYPE_ADJUSTMENT,GTK_TYPE_ADJUSTMENT); 	  click_signal =     g_signal_new("click",		 G_OBJECT_CLASS_TYPE(object_class),		 G_SIGNAL_RUN_FIRST,		 G_STRUCT_OFFSET(GtkMathViewClass, click),		 NULL, NULL,		 gtk_marshal_NONE__POINTER_INT,		 G_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_INT);  select_begin_signal=    g_signal_new("select_begin",		 G_OBJECT_CLASS_TYPE(object_class),		 G_SIGNAL_RUN_FIRST,		 G_STRUCT_OFFSET(GtkMathViewClass,select_begin),		 NULL,NULL,		 gtk_marshal_NONE__POINTER_INT,		 G_TYPE_NONE, 2 ,GTK_TYPE_POINTER, GTK_TYPE_INT);	  select_over_signal =     g_signal_new("select_over",		 G_OBJECT_CLASS_TYPE(object_class),		 G_SIGNAL_RUN_FIRST,		 G_STRUCT_OFFSET(GtkMathViewClass,select_over),		 NULL,NULL,		 gtk_marshal_NONE__POINTER_INT,		 G_TYPE_NONE, 2 ,GTK_TYPE_POINTER,GTK_TYPE_INT);	  select_end_signal =     g_signal_new("select_end",		 G_OBJECT_CLASS_TYPE(object_class),		 G_SIGNAL_RUN_FIRST,		 G_STRUCT_OFFSET(GtkMathViewClass,select_end),		 NULL,NULL,		 gtk_marshal_NONE__POINTER_INT,		 G_TYPE_NONE, 2 ,GTK_TYPE_POINTER, GTK_TYPE_INT);	  select_abort_signal =     g_signal_new("select_abort",		 G_OBJECT_CLASS_TYPE(object_class),		 G_SIGNAL_RUN_FIRST,		 G_STRUCT_OFFSET(GtkMathViewClass,select_abort),		 NULL,NULL,		 gtk_marshal_NONE__NONE,		 G_TYPE_NONE,0);	  element_over_signal =     g_signal_new("element_over",		 G_OBJECT_CLASS_TYPE(object_class),		 G_SIGNAL_RUN_FIRST,		 G_STRUCT_OFFSET(GtkMathViewClass,element_over),		 NULL,NULL,		 gtk_marshal_NONE__POINTER_INT,		 G_TYPE_NONE, 2 , GTK_TYPE_POINTER,GTK_TYPE_INT);	  initGlobalData(getenv("MATHENGINECONF"));}#include "MathML.hh"static voidgtk_math_view_init(GtkMathView* math_view){  g_return_if_fail(math_view != NULL);  math_view->pixmap          = NULL;  math_view->view            = 0;  math_view->renderingContext = 0;  math_view->freeze_counter  = 0;  math_view->select_state    = SELECT_STATE_NO;  math_view->button_pressed  = FALSE;  math_view->current_elem    = NULL;  math_view->cursor_elem     = NULL;  math_view->cursor_index    = 0;  math_view->cursor_visible  = FALSE;  math_view->hadjustment = NULL;  math_view->vadjustment = NULL;  math_view->area = gtk_drawing_area_new();  GTK_WIDGET_SET_FLAGS(GTK_WIDGET(math_view->area), GTK_CAN_FOCUS);  gtk_container_add(GTK_CONTAINER(math_view), math_view->area);  gtk_widget_show(math_view->area);  // BOHHHHHHHHHHHHHHH  math_view->top_x = math_view->top_y = 0;  math_view->old_top_x = math_view->old_top_y = 0;#if GTKMATHVIEW_USES_CUSTOM_READER  SmartPtr<View> view = View::create(custom_reader_Builder::create());#elif GTKMATHVIEW_USES_LIBXML2_READER  SmartPtr<View> view = View::create(libxml2_reader_Builder::create());#elif GTKMATHVIEW_USES_LIBXML2  SmartPtr<View> view = View::create(libxml2_Builder::create());#elif GTKMATHVIEW_USES_GMETADOM  SmartPtr<View> view = View::create(gmetadom_Builder::create());#endif  view->initialize(Gtk_MathGraphicDevice::create(math_view->area),		   Gtk_BoxGraphicDevice::create(math_view->area));  view->ref();  math_view->view = view;  math_view->renderingContext = new Gtk_RenderingContext;  math_view->renderingContext->setWidget(math_view->area);  //math_view->renderingContext->setDrawable(math_view->pixmap);  //math_view->renderingContext->setForegroundColor(DEFAULT_SELECT_FOREGROUND, 1);  //math_view->renderingContext->setBackgroundColor(DEFAULT_SELECT_BACKGROUND, 1);  // BOHHHHHHHHHHHHHHH  g_signal_connect(GTK_OBJECT(math_view->area),		   "configure_event",		   G_CALLBACK(gtk_math_view_configure_event), 		   math_view);  g_signal_connect(GTK_OBJECT(math_view->area), 		   "expose_event",		   G_CALLBACK(gtk_math_view_expose_event), 		   math_view);  g_signal_connect(GTK_OBJECT(math_view->area), 		   "realize",		   G_CALLBACK(gtk_math_view_realize), 		   math_view);  g_signal_connect(GTK_OBJECT(math_view->area), 		   "button_press_event",		   G_CALLBACK(gtk_math_view_button_press_event), 		   math_view);  g_signal_connect(GTK_OBJECT(math_view->area), 		   "button_release_event",		   G_CALLBACK(gtk_math_view_button_release_event), 		   math_view);  g_signal_connect(GTK_OBJECT(math_view->area), 		   "motion_notify_event",		   G_CALLBACK(gtk_math_view_motion_notify_event), 		   math_view);  gtk_widget_add_events(GTK_WIDGET(math_view->area),			GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);}extern "C" GtkWidget*GTKMATHVIEW_METHOD_NAME(new)(GtkAdjustment*, GtkAdjustment*){  GtkMathView* math_view = (GtkMathView*) gtk_type_new(GTKMATHVIEW_METHOD_NAME(get_type)());  g_return_val_if_fail(math_view != NULL, NULL);  return GTK_WIDGET(math_view);}static voidgtk_math_view_destroy(GtkObject* object){  GtkMathView* math_view;  g_return_if_fail(object != NULL);  g_return_if_fail(GTK_IS_MATH_VIEW(object));  math_view = GTK_MATH_VIEW(object);  g_assert(math_view != NULL);  if (math_view->view)    {      math_view->view->resetRootElement();      math_view->view->unref();      math_view->view = 0;    }  if (math_view->renderingContext)    {      delete math_view->renderingContext;      math_view->renderingContext = 0;    }  if (math_view->hadjustment != NULL)    {      gtk_object_unref(GTK_OBJECT(math_view->hadjustment));      math_view->hadjustment = NULL;    }  if (math_view->vadjustment != NULL)    {      gtk_object_unref(GTK_OBJECT(math_view->vadjustment));      math_view->vadjustment = NULL;    }  if (math_view->pixmap != NULL)    {      g_object_unref(G_OBJECT(math_view->pixmap));      math_view->pixmap = NULL;    }  if (math_view->current_elem != NULL)    {#if GTKMATHVIEW_USES_GMETADOM      GdomeException exc = 0;      gdome_el_unref(math_view->current_elem, &exc);      g_assert(exc == 0);#endif      math_view->current_elem = NULL;    }  if (math_view->cursor_elem != NULL)    {#if GTKMATHVIEW_USES_GMETADOM      GdomeException exc = 0;      gdome_el_unref(math_view->cursor_elem, &exc);      g_assert(exc == 0);#endif      math_view->cursor_elem = NULL;    }#if 1  /* ATTEMPT: since this class is derived from a container   * then contained object will be destroyed by the parent class'   * method   */  if (GTK_OBJECT_CLASS(parent_class)->destroy != NULL)    (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);#endif}