reset_adjustments(math_view);
  GTKMATHVIEW_METHOD_NAME(set_adjustments)(math_view, hadj, vadj);  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->configuration)    {      math_view->configuration->unref();      math_view->configuration = 0;    }  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;    }  gtk_math_view_release_document_resources(math_view);  if (GTK_OBJECT_CLASS(parent_class)->destroy != NULL)    (*GTK_OBJECT_CLASS(parent_class)->destroy)(object);}extern "C" gbooleanGTKMATHVIEW_METHOD_NAME(freeze)(GtkMathView* math_view){  g_return_val_if_fail(math_view != NULL, FALSE);  return (math_view->freeze_counter++ > 0);}extern "C" gbooleanGTKMATHVIEW_METHOD_NAME(thaw)(GtkMathView* math_view){  g_return_val_if_fail(math_view != NULL, FALSE);  g_return_val_if_fail(math_view->freeze_counter > 0, FALSE);  if (--math_view->freeze_counter == 0)    {      gtk_math_view_paint(math_view);      return TRUE;    }  else    return FALSE;}static voidgtk_math_view_realize(GtkWidget* widget){  GtkMathView* math_view;  GdkWindowAttr attributes;  gint attributes_mask;  g_return_if_fail (widget != NULL);  g_return_if_fail (GTK_IS_MATH_VIEW (widget));  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);  math_view = GTK_MATH_VIEW (widget);  attributes.x = widget->allocation.x;  attributes.y = widget->allocation.y;  attributes.width = widget->allocation.width;  attributes.height = widget->allocation.height;  attributes.wclass = GDK_INPUT_OUTPUT;  attributes.window_type = GDK_WINDOW_CHILD;  attributes.event_mask = gtk_widget_get_events (widget) |     GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |     GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |    GDK_POINTER_MOTION_HINT_MASK;  attributes.visual = gtk_widget_get_visual (widget);  attributes.colormap = gtk_widget_get_colormap (widget);  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);  widget->style = gtk_style_attach (widget->style, widget->window);  gdk_window_set_user_data (widget->window, widget);  gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);}#include <iostream>static voidgtk_math_view_size_request(GtkWidget* widget, GtkRequisition* requisition){  g_return_if_fail(widget != NULL);  g_return_if_fail(requisition != NULL);  g_return_if_fail(GTK_IS_MATH_VIEW(widget));  GtkMathView* math_view = GTK_MATH_VIEW(widget);  g_assert(math_view);  g_assert(math_view->view);  if (BoundingBox box = math_view->view->getBoundingBox())    {      requisition->width = Gtk_RenderingContext::toGtkPixels(box.horizontalExtent());      requisition->height = Gtk_RenderingContext::toGtkPixels(box.verticalExtent());    }}static voidgtk_math_view_size_allocate(GtkWidget* widget, GtkAllocation* allocation){  g_return_if_fail(widget != NULL);  g_return_if_fail(GTK_IS_MATH_VIEW (widget));  g_return_if_fail(allocation != NULL);  GtkMathView* math_view = GTK_MATH_VIEW(widget);    if (math_view->pixmap != NULL)    {      g_object_unref(math_view->pixmap);      math_view->pixmap = NULL;    }  widget->allocation = *allocation;  if (GTK_WIDGET_REALIZED(widget))    {      gdk_window_move_resize(widget->window,			     allocation->x, allocation->y,			     allocation->width, allocation->height);      gtk_math_view_paint(math_view);    }}static gintgtk_math_view_button_press_event(GtkWidget* widget, GdkEventButton* event){  g_return_val_if_fail(widget != NULL, FALSE);  g_return_val_if_fail(event != NULL, FALSE);  g_return_val_if_fail(GTK_IS_MATH_VIEW(widget), FALSE);  GtkMathView* math_view = GTK_MATH_VIEW(widget);  g_return_val_if_fail(math_view->view, FALSE);  if (event->button == 1)    {      math_view->select_state = SELECT_STATE_NO;      math_view->button_pressed = TRUE;      math_view->button_press_x = event->x;      math_view->button_press_y = event->y;      math_view->button_press_time = event->time;    }  else if (math_view->select_state == SELECT_STATE_YES)    {      math_view->select_state = SELECT_STATE_ABORT;      g_signal_emit(GTK_OBJECT(math_view), select_abort_signal, 0);    }    return FALSE;}static gintgtk_math_view_button_release_event(GtkWidget* widget, GdkEventButton* event){  g_return_val_if_fail(widget != NULL, FALSE);  g_return_val_if_fail(event != NULL, FALSE);  g_return_val_if_fail(GTK_IS_MATH_VIEW(widget), FALSE);  GtkMathView* math_view = GTK_MATH_VIEW(widget);  g_return_val_if_fail(math_view->view, FALSE);  if (event->button == 1)    {#if GTKMATHVIEW_USES_GMETADOM      GdomeException exc = 0;#endif      GtkMathViewModelId elem = NULL;      gtk_math_view_get_element_at(math_view, (gint) event->x, (gint) event->y, &elem, NULL, NULL);      GtkMathViewModelEvent me;      me.id = elem;      me.x = (gint) event->x;      me.y = (gint) event->y;      me.state = event->state;      if (math_view->button_pressed == TRUE &&	  math_view->select_state == SELECT_STATE_NO &&	  fabs(math_view->button_press_x - event->x) <= CLICK_SPACE_RANGE &&	  fabs(math_view->button_press_y - event->y) <= CLICK_SPACE_RANGE &&	  abs(math_view->button_press_time - event->time) <= CLICK_TIME_RANGE)	{	  // the mouse should have not moved more than one pixel in each direction	  // and the time elapsed from the press event should be no more than 250ms	  g_signal_emit(GTK_OBJECT(math_view), click_signal, 0, &me);	}      if (math_view->select_state == SELECT_STATE_YES)      	g_signal_emit(GTK_OBJECT(math_view), select_end_signal, 0, &me);      #if GTKMATHVIEW_USES_GMETADOM      if (elem != NULL)	{	  gdome_el_unref(elem, &exc);	  g_assert(exc == 0);	}#endif // GTKMATHVIEW_USES_GMETADOM      math_view->button_pressed = FALSE;      math_view->select_state = SELECT_STATE_NO;    }    return FALSE;}static gintgtk_math_view_motion_notify_event(GtkWidget* widget, GdkEventMotion* event){  g_return_val_if_fail(widget != NULL, FALSE);  g_return_val_if_fail(event != NULL, FALSE);  g_return_val_if_fail(GTK_IS_MATH_VIEW(widget), FALSE);  GtkMathView* math_view = GTK_MATH_VIEW(widget);  g_return_val_if_fail(math_view->view, FALSE);  GdkModifierType mods;  gint x = (gint) event->x;  gint y = (gint) event->y;  // using GDK hints is convenient since this handler is rather heavy  // this way we notify GDK when we are ready to process another event  if (event->is_hint || (event->window != widget->window))    gdk_window_get_pointer(widget->window, &x, &y, &mods);#if GTKMATHVIEW_USES_GMETADOM  GdomeException exc = 0;#endif  GtkMathViewModelId elem = NULL;  GTKMATHVIEW_METHOD_NAME(get_element_at)(math_view, x, y, &elem, NULL, NULL);  GtkMathViewModelEvent me;  me.id = elem;  me.x = x;  me.y = y;  me.state = event->state;  if (math_view->button_pressed == TRUE &&      (math_view->select_state == SELECT_STATE_YES ||       fabs(math_view->button_press_x - x) > CLICK_SPACE_RANGE ||       fabs(math_view->button_press_y - y) > CLICK_SPACE_RANGE ||       abs(math_view->button_press_time - event->time) > CLICK_TIME_RANGE))    {      if (math_view->select_state == SELECT_STATE_NO)	{	  g_signal_emit(GTK_OBJECT(math_view), select_begin_signal, 0, &me);	  math_view->select_state = SELECT_STATE_YES;	}      else if (math_view->select_state == SELECT_STATE_YES && math_view->current_elem != elem)	g_signal_emit(GTK_OBJECT(math_view), select_over_signal, 0, &me);    }  if (math_view->current_elem != elem)    {#if GTKMATHVIEW_USES_GMETADOM      if (math_view->current_elem != NULL)	{	  gdome_el_unref(math_view->current_elem, &exc);	  g_assert(exc == 0);	}#endif // GTKMATHVIEW_USES_GMETADOM      math_view->current_elem = elem;#if GTKMATHVIEW_USES_GMETADOM      if (math_view->current_elem != NULL)	{	  gdome_el_ref(math_view->current_elem, &exc);	  g_assert(exc == 0);	}#endif // GTKMATHVIEW_USES_GMETADOM      g_signal_emit(GTK_OBJECT(math_view), element_over_signal, 0, &me);    }#if GTKMATHVIEW_USES_GMETADOM  if (elem != NULL)    {      gdome_el_unref(elem, &exc);      g_assert(exc == 0);    }#endif // GTKMATHVIEW_USES_GMETADOM  return FALSE;}static gintgtk_math_view_expose_event(GtkWidget* widget,			   GdkEventExpose* event){  g_return_val_if_fail(widget != NULL, FALSE);  g_return_val_if_fail(event != NULL, FALSE);  g_return_val_if_fail(GTK_IS_MATH_VIEW(widget), FALSE);  GtkMathView* math_view = GTK_MATH_VIEW(widget);  // It may be that the first expose event the double-buffer has not  // been allocated yet. In this case the paint method should be used  if (math_view->pixmap == NULL)    gtk_math_view_paint(math_view);  else    gtk_math_view_update(math_view, event->area.x, event->area.y, event->area.width, event->area.height);  return FALSE;}static voidgtk_math_view_click(GtkMathView* math_view, const GtkMathViewModelEvent*){  g_return_if_fail(math_view != NULL);  // noop}static voidgtk_math_view_select_begin(GtkMathView* math_view, const GtkMathViewModelEvent*){  g_return_if_fail(math_view != NULL);  // noop}static voidgtk_math_view_select_over(GtkMathView* math_view, const GtkMathViewModelEvent*){  g_return_if_fail(math_view != NULL);  // noop}static voidgtk_math_view_select_end(GtkMathView* math_view, const GtkMathViewModelEvent*){  g_return_if_fail(math_view != NULL);  // noop}static voidgtk_math_view_select_abort(GtkMathView* math_view){  g_return_if_fail(math_view != NULL);  // noop}static voidgtk_math_view_element_over(GtkMathView* math_view, const GtkMathViewModelEvent*){  g_return_if_fail(math_view != NULL);  // noop}static voidsetup_adjustment(GtkAdjustment* adj, gfloat size, gfloat page_size){  g_return_if_fail(adj != NULL);  adj->lower = 0.0;  adj->page_size = page_size;  adj->step_increment = 10;  adj->page_increment = page_size;  adj->upper = size;  if (adj->upper < 0) adj->upper = 0.0;  if (adj->value > adj->upper - page_size) {    adj->value = std::max(0.0, adj->upper - page_size);    gtk_adjustment_value_changed(adj);  }  gtk_adjustment_changed(adj);}static voidreset_adjustments(GtkMathView* math_view){  g_return_if_fail(math_view != NULL);  math_view->old_top_x = math_view->old_top_y = math_view->top_x = math_view->top_y = 0;  if (math_view->hadjustment != NULL)    gtk_adjustment_set_value(math_view->hadjustment, 0.0);  if (math_view->vadjustment != NULL)    gtk_adjustment_set_value(math_view->vadjustment, 0.0);}static voidsetup_adjustments(GtkMathView* math_view){  g_return_if_fail(math_view != NULL);  g_return_if_fail(math_view->view);  const BoundingBox box = math_view->view->getBoundingBox();  if (math_view->hadjustment != NULL) {    const gint width = box.defined() ? Gtk_RenderingContext::toGtkPixels(box.width) : 0;    const gint page_width = GTK_WIDGET(math_view)->allocation.width;        if (math_view->top_x > width - page_width)      math_view->top_x = std::max(0, width - page_width);    setup_adjustment(math_view->hadjustment, width, page_width);  }  if (math_view->vadjustment != NULL) {    const gint height = box.defined() ? Gtk_RenderingContext::toGtkPixels(box.verticalExtent()) : 0;    const gint page_height = GTK_WIDGET(math_view)->allocation.height;    if (math_view->top_y > height - page_height)      math_view->old_top_y = math_view->top_y = std::max(0, height - page_height);    setup_adjustment(math_view->vadjustment, height, page_height);  }}#if GTKMATHVIEW_USES_GMETADOMextern "C" gbooleanGTKMATHVIEW_METHOD_NAME(load_uri)(GtkMathView* math_view, const gchar* name){  g_return_val_if_fail(math_view != NULL, FALSE);  g_return_val_if_fail(name != NULL, FALSE);  gtk_math_view_release_document_resources(math_view);  const bool res = math_view->view->loadURI(name);  gtk_math_view_paint(math_view);  return res;}extern "C" gbooleanGTKMATHVIEW_METHOD_NAME(load_buffer)(GtkMathView* math_view, const gchar* buffer){  g_return_val_if_fail(math_view != NULL, FALSE);  g_return_val_if_fail(buffer != NULL, FALSE);  gtk_math_view_release_document_resources(math_view);  const bool res = math_view->view->loadBuffer(buffer);  gtk_math_view_paint(math_view);  return res;}extern "C" gbooleanGTKMATHVIEW_METHOD_NAME(load_document)(GtkMathView* math_view, GdomeDocument* doc){  g_return_val_if_fail(math_view != NULL, FALSE);  g_return_val_if_fail(doc != NULL, FALSE);  gtk_math_view_release_document_resources(math_view);  const bool res = math_view->view->loadDocument(DOM::Document(doc));  gtk_math_view_paint(math_view);  return res;}extern "C" gbooleanGTKMATHVIEW_METHOD_NAME(load_root)(GtkMathView* math_view, GtkMathViewModelId elem){  g_return_val_if_fail(math_view != NULL, FALSE);  g_return_val_if_fail(math_view->view != NULL, FALSE);  gtk_math_view_release_document_resources(math_view);  const bool res = math_view->view->loadRootElement(DOM::Element(elem));  gtk_math_view_paint(math_view);  return res;}extern "C" GdomeDocument*GTKMATHVIEW_METHOD_NAME(get_document)(GtkMathView* math_view){  g_return_val_if_fail(math_view != NULL, NULL);  g_return_val_if_fail(math_view->view != NULL, NULL);  return reinterpret_cast<GdomeDocument*>(math_view->view->getDocument().gdome_object());}#elif GTKMATHVIEW_USES_LIBXML2extern "C" gbooleanGTKMATHVIEW_METHOD_NAME(load_uri)(GtkMathView* math_view, const gchar* name){  g_return_val_if_fail(math_view != NULL, FALSE);  g_return_val_if_fail(math_view->view != NULL, FALSE);  g_return_val_if_fail(name != NULL, FALSE);  gtk_math_view_release_document_resources(math_view);  const bool res = math_view->view->loadURI(name);  gtk_math_view_paint(math_view);  return res;}extern "C" gbooleanGTKMATHVIEW_METHOD_NAME(load_buffer)(GtkMathView* math_view, const gchar* buffer){  g_return_val_if_fail(math_view != NULL, FALSE);  g_return_val_if_fail(math_view->view != NULL, FALSE);  g_return_val_if_fail(buffer != NULL, FALSE);  gtk_math_view_release_document_resources(math_view);  const bool res = math_view->view->loadBuffer(buffer);  gtk_math_view_paint(math_view);  return res;}extern "C" gbooleanGTKMATHVIEW_METHOD_NAME(load_document)(GtkMathView* math_view, xmlDoc* doc){  g_return_val_if_fail(math_view != NULL, FALSE);  g_return_val_if_fail(math_view->view != NULL, FALSE);  g_return_val_if_fail(doc != NULL, FALSE);  gtk_math_view_release_document_resources(math_view);  const bool res = math_view->view->loadDocument(doc);  gtk_math_view_paint(math_view);  return res;}extern "C" gbooleanGTKMATHVIEW_METHOD_NAME(load_root)(GtkMathView* math_view, GtkMathViewModelId elem){  g_return_val_if_fail(math_view != NULL, FALSE);  g_return_val_if_fail(math_view->view != NULL, FALSE);  gtk_math_view_release_document_resources(math_view);  const bool res = math_view->view->loadRootElement(elem);  gtk_math_view_paint(math_view);  return res;}extern "C" xmlDoc*GTKMATHVIEW_METHOD_NAME(get_document)(GtkMathView* math_view){  g_return_val_if_fail(math_view != NULL, NULL);  g_return_val_if_fail(math_view->view != NULL, NULL);  return math_view->view->getDocument();}#elif GTKMATHVIEW_USES_CUSTOM_READERextern "C" gbooleanGTKMATHVIEW_METHOD_NAME(load_reader)(GtkMathView* math_view,				     GtkMathViewReader* reader,				     GtkMathViewReaderData user_data){  g_return_val_if_fail(math_view != NULL, FALSE);  g_return_val_if_fail(math_view->view != NULL, FALSE);  g_return_val_if_fail(reader != NULL, FALSE);  gtk_math_view_release_document_resources(math_view);  const bool res = math_view->view->loadReader(reader, user_data);  reset_adjustments(math_view);  gtk_math_view_paint(math_view);  return res;}#elif GTKMATHVIEW_USES_LIBXML2_READERextern "C" gbooleanGTKMATHVIEW_METHOD_NAME(load_reader)(GtkMathView* math_view, xmlTextReaderPtr reader){  g_return_val_if_fail(math_view != NULL, FALSE);  g_return_val_if_fail(math_view->view != NULL, NULL);  g_return_val_if_fail(reader != NULL, FALSE);  gtk_math_view_release_document_resources(math_view);  const bool res = math_view->view->loadReader(reader);  reset_adjustments(math_view);  gtk_math_view_paint(math_view);  return res;}#endif // GTKMATHVIEW_USES_LIBXML2_READERextern "C" voidGTKMATHVIEW_METHOD_NAME(unload)(GtkMathView* math_view){  g_return_if_fail(math_view != NULL);  g_return_if_fail(math_view->view != NULL);  math_view->view->resetRootElement();  gtk_math_view_release_document_resources(math_view);  gtk_math_view_paint(math_view);}extern "C" GdkPixmap*GTKMATHVIEW_METHOD_NAME(get_buffer)(GtkMathView* math_view){  g_return_val_if_fail(math_view != NULL, NULL);  return math_view->pixmap;}extern "C" voidGTKMATHVIEW_METHOD_NAME(set_adjustments)(GtkMathView* math_view,					 GtkAdjustment* hadj,					 GtkAdjustment* vadj){  g_return_if_fail(math_view != NULL);  g_return_if_fail(GTK_IS_MATH_VIEW(math_view));  if (hadj != NULL)    g_return_if_fail(GTK_IS_ADJUSTMENT(hadj));  else    hadj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));  if (vadj != NULL)    g_return_if_fail(GTK_IS_ADJUSTMENT(vadj));  else    vadj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));  if (math_view->hadjustment != NULL && (math_view->hadjustment != hadj))    {      gtk_signal_disconnect_by_data(GTK_OBJECT(math_view->hadjustment), math_view);      gtk_object_unref(GTK_OBJECT(math_view->hadjustment));    }  if (math_view->vadjustment != NULL && (math_view->vadjustment != vadj))    {      gtk_signal_disconnect_by_data(GTK_OBJECT(math_view->vadjustment), math_view);      gtk_object_unref(GTK_OBJECT(math_view->vadjustment));    }  if (math_view->hadjustment != hadj)    {      math_view->hadjustment = hadj;      gtk_object_ref(GTK_OBJECT(math_view->hadjustment));      gtk_object_sink(GTK_OBJECT(math_view->hadjustment));            math_view->hsignal = 	g_signal_connect(GTK_OBJECT(hadj), 			 "value_changed",			 G_CALLBACK(hadjustment_value_changed),			 math_view);    }  if (math_view->vadjustment != vadj)    {      math_view->vadjustment = vadj;      gtk_object_ref(GTK_OBJECT(math_view->vadjustment));      gtk_object_sink(GTK_OBJECT(math_view->vadjustment));            math_view->vsignal =	g_signal_connect(GTK_OBJECT(vadj), 			 "value_changed",			 G_CALLBACK(vadjustment_value_changed),			 math_view);    }    setup_adjustments(math_view);}