[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: CVS update: Makefile.am



  User: cnieves 
  Date: 05/02/19 18:27:11

  Modified:    .        Makefile.am g_keys.nw g_register.nw globals.nw
                        i_basic.nw i_callbacks.nw o_basic.nw o_complex.nw
                        o_copy.nw o_delete.nw o_grips.nw o_misc.nw
                        o_move.nw rcstrings.nw x_event.nw
  Added:       .        o_picture.nw
  Log:
  Added support for pictures within schematics and symbols.
  
  
  
  
  
  
  Revision  Changes    Path
  1.10      +1 -1      eda/geda/devel/gschem/noweb/Makefile.am
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Makefile.am
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/Makefile.am,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -b -r1.9 -r1.10
  --- Makefile.am	16 Jan 2005 04:32:10 -0000	1.9
  +++ Makefile.am	19 Feb 2005 23:27:07 -0000	1.10
  @@ -9,7 +9,7 @@
                x_color.nw x_dialog.nw x_event.nw x_fileselect.nw x_grid.nw \
                x_image.nw x_log.nw x_menus.nw x_multiattrib.nw \
                x_pagesel.nw x_preview.nw x_print.nw \
  -             x_script.nw x_stroke.nw x_window.nw
  +             x_script.nw x_stroke.nw x_window.nw o_picture.nw
   
   MOSTLYCLEANFILES = *.log *~
   CLEANFILES = *.log *~
  
  
  
  1.5       +3 -1      eda/geda/devel/gschem/noweb/g_keys.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: g_keys.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/g_keys.nw,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -b -r1.4 -r1.5
  --- g_keys.nw	13 Feb 2005 21:53:24 -0000	1.4
  +++ g_keys.nw	19 Feb 2005 23:27:07 -0000	1.5
  @@ -280,6 +280,8 @@
   DEFINE_G_KEYS(add_line_hotkey)
   DEFINE_G_KEYS(add_box)
   DEFINE_G_KEYS(add_box_hotkey)
  +DEFINE_G_KEYS(add_picture)
  +DEFINE_G_KEYS(add_picture_hotkey)
   DEFINE_G_KEYS(add_circle)
   DEFINE_G_KEYS(add_circle_hotkey)
   DEFINE_G_KEYS(add_arc)
  @@ -326,7 +328,7 @@
   hack */
   DEFINE_G_KEYS(cancel)
   
  -@ %def DEFINE_G_KEYS g_keys_file_new g_keys_file_new_window g_keys_file_open g_keys_file_script g_keys_file_save g_keys_file_save_as g_keys_file_save_all g_keys_file_print g_keys_file_write_png g_keys_file_close g_keys_file_quit g_keys_edit_undo g_keys_edit_redo g_keys_edit_select g_keys_edit_copy g_keys_edit_copy_hotkey g_keys_edit_move g_keys_edit_move_hotkey g_keys_edit_delete g_keys_edit_rotate_90 g_keys_edit_rotate_90_hotkey g_keys_edit_mirror g_keys_edit_mirror_hotkey g_keys_edit_stretch g_keys_edit_stretch_hotkey g_keys_edit_slot g_keys_edit_color g_keys_edit_edit g_keys_edit_text g_keys_edit_lock g_keys_edit_unlock g_keys_edit_linetype g_keys_edit_filltype g_keys_edit_translate g_keys_edit_embed g_keys_edit_unembed g_keys_edit_show_hidden g_keys_buffer_copy1 g_keys_buffer_copy2 g_keys_buffer_copy3 g_keys_buffer_copy4 g_keys_buffer_copy5 g_keys_buffer_cut1 g_keys_buffer_cut2 g_keys_buffer_cut3 g_keys_buffer_cut4 g_keys_buffer_cut5 g_keys_buffer_paste1 g_keys_buffer_paste2 g_keys_buffer_paste3 g_keys_buffer_paste4 g_keys_buffer_paste5 g_keys_buffer_paste1_hotkey g_keys_buffer_paste2_hotkey g_keys_buffer_paste3_hotkey g_keys_buffer_paste4_hotkey g_keys_buffer_paste5_hotkey g_keys_view_redraw g_keys_view_zoom_full g_keys_view_zoom_extents g_keys_view_zoom_in g_keys_view_zoom_out g_keys_view_zoom_in_hotkey g_keys_view_zoom_out_hotkey g_keys_view_zoom_box g_keys_view_zoom_box_hotkey g_keys_view_pan g_keys_view_pan_hotkey g_keys_view_update_cues g_keys_page_manager g_keys_page_next g_keys_page_prev g_keys_page_new g_keys_page_close g_keys_page_revert g_keys_page_discard g_keys_page_print g_keys_add_component g_keys_add_attribute g_keys_add_attribute_hotkey g_keys_add_net g_keys_add_net_hotkey g_keys_add_bus g_keys_add_bus_hotkey g_keys_add_text g_keys_add_line g_keys_add_line_hotkey g_keys_add_box g_keys_add_box_hotkey g_keys_add_circle g_keys_add_circle_hotkey g_keys_add_arc g_keys_add_arc_hotkey g_keys_add_pin g_keys_add_pin_hotkey g_keys_hierarchy_down_schematic g_keys_hierarchy_down_symbol g_keys_hierarchy_up g_keys_hierarchy_documentation g_keys_attributes_attach g_keys_attributes_detach g_keys_attributes_show_name g_keys_attributes_show_value g_keys_attributes_show_both g_keys_attributes_visibility_toggle g_keys_script_console g_keys_options_text_size g_keys_options_afeedback g_keys_options_grid g_keys_options_snap g_keys_options_snap_size g_keys_options_rubberband g_keys_options_show_log_window g_keys_options_show_coord_window g_keys_misc g_keys_misc2 g_keys_misc3 g_keys_help_about g_keys_help_manual g_keys_help_hotkeys g_keys_cancel
  +@ %def DEFINE_G_KEYS g_keys_file_new g_keys_file_new_window g_keys_file_open g_keys_file_script g_keys_file_save g_keys_file_save_as g_keys_file_save_all g_keys_file_print g_keys_file_write_png g_keys_file_close g_keys_file_quit g_keys_edit_undo g_keys_edit_redo g_keys_edit_select g_keys_edit_copy g_keys_edit_copy_hotkey g_keys_edit_move g_keys_edit_move_hotkey g_keys_edit_delete g_keys_edit_rotate_90 g_keys_edit_rotate_90_hotkey g_keys_edit_mirror g_keys_edit_mirror_hotkey g_keys_edit_stretch g_keys_edit_stretch_hotkey g_keys_edit_slot g_keys_edit_color g_keys_edit_edit g_keys_edit_text g_keys_edit_lock g_keys_edit_unlock g_keys_edit_linetype g_keys_edit_filltype g_keys_edit_translate g_keys_edit_embed g_keys_edit_unembed g_keys_edit_show_hidden g_keys_buffer_copy1 g_keys_buffer_copy2 g_keys_buffer_copy3 g_keys_buffer_copy4 g_keys_buffer_copy5 g_keys_buffer_cut1 g_keys_buffer_cut2 g_keys_buffer_cut3 g_keys_buffer_cut4 g_keys_buffer_cut5 g_keys_buffer_paste1 g_keys_buffer_paste2 g_keys_buffer_paste3 g_keys_buffer_paste4 g_keys_buffer_paste5 g_keys_buffer_paste1_hotkey g_keys_buffer_paste2_hotkey g_keys_buffer_paste3_hotkey g_keys_buffer_paste4_hotkey g_keys_buffer_paste5_hotkey g_keys_view_redraw g_keys_view_zoom_full g_keys_view_zoom_extents g_keys_view_zoom_in g_keys_view_zoom_out g_keys_view_zoom_in_hotkey g_keys_view_zoom_out_hotkey g_keys_view_zoom_box g_keys_view_zoom_box_hotkey g_keys_view_pan g_keys_view_pan_hotkey g_keys_view_update_cues g_keys_page_manager g_keys_page_next g_keys_page_prev g_keys_page_new g_keys_page_close g_keys_page_revert g_keys_page_discard g_keys_page_print g_keys_add_component g_keys_add_attribute g_keys_add_attribute_hotkey g_keys_add_net g_keys_add_net_hotkey g_keys_add_bus g_keys_add_bus_hotkey g_keys_add_text g_keys_add_line g_keys_add_line_hotkey g_keys_add_box g_keys_add_box_hotkey g_keys_add_picture g_keys_add_picture_hotkey g_keys_add_circle g_keys_add_circle_hotkey g_keys_add_arc g_keys_add_arc_hotkey g_keys_add_pin g_keys_add_pin_hotkey g_keys_hierarchy_down_schematic g_keys_hierarchy_down_symbol g_keys_hierarchy_up g_keys_hierarchy_documentation g_keys_attributes_attach g_keys_attributes_detach g_keys_attributes_show_name g_keys_attributes_show_value g_keys_attributes_show_both g_keys_attributes_visibility_toggle g_keys_script_console g_keys_options_text_size g_keys_options_afeedback g_keys_options_grid g_keys_options_snap g_keys_options_snap_size g_keys_options_rubberband g_keys_options_show_log_window g_keys_options_show_coord_window g_keys_misc g_keys_misc2 g_keys_misc3 g_keys_help_about g_keys_help_manual g_keys_help_hotkeys g_keys_cancel
   
   
   @section Function @code{g_get_selected_filename()}
  
  
  
  1.26      +2 -0      eda/geda/devel/gschem/noweb/g_register.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: g_register.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/g_register.nw,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -b -r1.25 -r1.26
  --- g_register.nw	8 Feb 2005 22:28:58 -0000	1.25
  +++ g_register.nw	19 Feb 2005 23:27:07 -0000	1.26
  @@ -278,6 +278,8 @@
     { "add-line-hotkey",           0, 0, 0, g_keys_add_line_hotkey },
     { "add-box",                   0, 0, 0, g_keys_add_box },
     { "add-box-hotkey",            0, 0, 0, g_keys_add_box_hotkey },
  +  { "add-picture",               0, 0, 0, g_keys_add_picture},
  +  { "add-picture-hotkey",        0, 0, 0, g_keys_add_picture_hotkey},
     { "add-circle",                0, 0, 0, g_keys_add_circle },
     { "add-circle-hotkey",         0, 0, 0, g_keys_add_circle_hotkey },
     { "add-arc",                   0, 0, 0, g_keys_add_arc },
  
  
  
  1.5       +3 -0      eda/geda/devel/gschem/noweb/globals.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: globals.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/globals.nw,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -b -r1.4 -r1.5
  --- globals.nw	4 Feb 2005 04:39:29 -0000	1.4
  +++ globals.nw	19 Feb 2005 23:27:07 -0000	1.5
  @@ -82,6 +82,9 @@
   /* these are required by libgeda */
   void (*arc_draw_func)()      = o_arc_draw;
   void (*box_draw_func)()      = o_box_draw;
  +#ifndef HAS_GTK12
  +void (*picture_draw_func)()  = o_picture_draw;
  +#endif
   void (*circle_draw_func)()   = o_circle_draw;
   void (*complex_draw_func)()  = o_complex_draw;
   void (*line_draw_func)()     = o_line_draw;
  
  
  
  1.19      +7 -0      eda/geda/devel/gschem/noweb/i_basic.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: i_basic.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/i_basic.nw,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -b -r1.18 -r1.19
  --- i_basic.nw	4 Feb 2005 22:40:54 -0000	1.18
  +++ i_basic.nw	19 Feb 2005 23:27:07 -0000	1.19
  @@ -192,6 +192,9 @@
     case DRAWBOX:
     case ENDBOX:
       return _("Box Mode");
  +  case DRAWPICTURE:
  +  case ENDPICTURE:
  +    return _("Picture Mode");
     case DRAWCIRCLE:
     case ENDCIRCLE:
       return _("Circle Mode");
  @@ -445,6 +448,7 @@
    	case(DRAWCOMP): /* TODO */
    	case(DRAWLINE): /* TODO */
    	case(DRAWBOX): /* TODO */
  + 	case(DRAWPICTURE): /* TODO */
    	case(DRAWPIN): /* TODO */
    	case(DRAWCIRCLE): /* TODO */
    	case(DRAWARC): /* TODO */
  @@ -459,6 +463,7 @@
    	case(ENDMOVE): /* TODO */
    	case(ENDLINE): /* TODO */
    	case(ENDBOX): /* TODO */
  + 	case(ENDPICTURE): /* TODO */
    	case(ENDCIRCLE): /* TODO */
    	case(ENDARC): /* TODO */
    	case(ENDPIN): /* TODO */
  @@ -738,6 +743,7 @@
    	case(DRAWCOMP): /* TODO */
    	case(DRAWLINE): /* TODO */
    	case(DRAWBOX): /* TODO */
  + 	case(DRAWPICTURE): /* TODO */
    	case(DRAWPIN): /* TODO */
    	case(DRAWCIRCLE): /* TODO */
    	case(DRAWARC): /* TODO */
  @@ -752,6 +758,7 @@
    	case(ENDMOVE): /* TODO */
    	case(ENDLINE): /* TODO */
    	case(ENDBOX): /* TODO */
  + 	case(ENDPICTURE): /* TODO */
    	case(ENDCIRCLE): /* TODO */
    	case(ENDARC): /* TODO */
    	case(ENDPIN): /* TODO */
  
  
  
  1.39      +43 -0     eda/geda/devel/gschem/noweb/i_callbacks.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: i_callbacks.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/i_callbacks.nw,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -b -r1.38 -r1.39
  --- i_callbacks.nw	11 Feb 2005 21:49:14 -0000	1.38
  +++ i_callbacks.nw	19 Feb 2005 23:27:07 -0000	1.39
  @@ -137,6 +137,8 @@
   <<i_callbacks.c : i_callback_add_line_hotkey()>>
   <<i_callbacks.c : i_callback_add_box()>>
   <<i_callbacks.c : i_callback_add_box_hotkey()>>
  +<<i_callbacks.c : i_callback_add_picture()>>
  +<<i_callbacks.c : i_callback_add_picture_hotkey()>>
   <<i_callbacks.c : i_callback_add_circle()>>
   <<i_callbacks.c : i_callback_add_circle_hotkey()>>
   <<i_callbacks.c : i_callback_add_arc()>>
  @@ -3421,6 +3423,47 @@
   
   @ %def i_callback_add_box_hotkey
   
  +@section Function @code{i_callback_add_picture()}
  +
  +@defun i_callback_add_picture data callback_action widget
  +@end defun
  +
  +<<i_callbacks.c : i_callback_add_picture()>>=
  +DEFINE_I_CALLBACK(add_picture)
  +{
  +  TOPLEVEL *w_current = (TOPLEVEL *) data;
  +
  +  exit_if_null(w_current);
  +
  +  o_erase_rubber(w_current);
  +
  +  w_current->inside_action = 0;
  +  i_set_state(w_current, SELECT);
  +  i_update_toolbar(w_current);
  +
  +  picture_selection_dialog(w_current);
  +}
  +
  +
  +@ %def i_callback_add_picture
  +
  +
  +@section Function @code{i_callback_add_picture_hotkey()}
  +
  +@defun i_callback_add_picture_hotkey data callback_action widget
  +@end defun
  +
  +<<i_callbacks.c : i_callback_add_picture_hotkey()>>=
  +DEFINE_I_CALLBACK(add_picture_hotkey)
  +{
  +  /* FIXME: If this function necessary? */
  +  fprintf(stderr, "Define add picture hotkey function if necessary!!\n");
  +}
  +
  +
  +@ %def i_callback_add_picture_hotkey
  +
  +
   
   @section Function @code{i_callback_add_circle()}
   
  
  
  
  1.11      +7 -0      eda/geda/devel/gschem/noweb/o_basic.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: o_basic.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/o_basic.nw,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -b -r1.10 -r1.11
  --- o_basic.nw	4 Feb 2005 04:39:29 -0000	1.10
  +++ o_basic.nw	19 Feb 2005 23:27:07 -0000	1.11
  @@ -799,6 +799,13 @@
           o_box_eraserubber(w_current);
        break;
   
  +     case(DRAWPICTURE):
  +     case(ENDPICTURE):
  +#ifndef HAS_GTK12
  +        o_picture_eraserubber(w_current);
  +#endif
  +     break;
  +
        case(DRAWCIRCLE):
        case(ENDCIRCLE):
           o_circle_eraserubber(w_current);
  
  
  
  1.17      +12 -0     eda/geda/devel/gschem/noweb/o_complex.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: o_complex.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/o_complex.nw,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -b -r1.16 -r1.17
  --- o_complex.nw	4 Feb 2005 22:40:55 -0000	1.16
  +++ o_complex.nw	19 Feb 2005 23:27:07 -0000	1.17
  @@ -152,6 +152,10 @@
           o_box_draw_xor(w_current, dx, dy, o_current);
           break;
   
  +      case(OBJ_PICTURE):
  +        o_picture_draw_xor(w_current, dx, dy, o_current);
  +        break;
  +
         case(OBJ_CIRCLE):
           o_circle_draw_xor(w_current, dx, dy, o_current);
           break;
  @@ -572,6 +576,10 @@
           o_box_draw_xor(w_current, x1, y1, o_current);
           break;
   
  +      case(OBJ_PICTURE):
  +        o_picture_draw_xor(w_current, x1, y1, o_current);
  +        break;
  +
         case(OBJ_CIRCLE):
           o_circle_draw_xor(w_current, x1, y1, o_current);
           break;
  @@ -641,6 +649,10 @@
           o_box_draw_xor(w_current, x1, y1, o_current);
           break;
   
  +      case(OBJ_PICTURE):
  +        o_picture_draw_xor(w_current, x1, y1, o_current);
  +        break;
  +
         case(OBJ_CIRCLE):
           o_circle_draw_xor(w_current, x1, y1, o_current);
           break;
  
  
  
  1.10      +22 -0     eda/geda/devel/gschem/noweb/o_copy.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: o_copy.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/o_copy.nw,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -b -r1.9 -r1.10
  --- o_copy.nw	4 Feb 2005 04:39:29 -0000	1.9
  +++ o_copy.nw	19 Feb 2005 23:27:07 -0000	1.10
  @@ -324,6 +324,28 @@
           
           break;
   
  +#ifndef HAS_GTK12
  +      case(OBJ_PICTURE):
  +        new_object = (OBJECT *) o_picture_copy(w_current,
  +					       w_current->page_current->
  +					       object_tail,
  +					       object);
  +        if (w_current->actionfeedback_mode == OUTLINE) {
  +          o_picture_draw_xor(w_current,
  +			     screen_diff_x,
  +			     screen_diff_y,
  +			     object);
  +        }
  +        o_picture_translate_world(w_current,
  +				  diff_x, diff_y,
  +				  new_object);
  +        
  +        o_selection_add(temp_list, new_object);
  +        new_object->saved_color = object->saved_color;
  +        o_picture_draw(w_current, new_object);
  +        
  +        break;
  +#endif
         case(OBJ_CIRCLE):
           new_object = (OBJECT *) o_circle_copy(w_current,
                                                 w_current->page_current->
  
  
  
  1.9       +28 -0     eda/geda/devel/gschem/noweb/o_delete.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: o_delete.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/o_delete.nw,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -b -r1.8 -r1.9
  --- o_delete.nw	4 Feb 2005 04:39:29 -0000	1.8
  +++ o_delete.nw	19 Feb 2005 23:27:07 -0000	1.9
  @@ -17,6 +17,9 @@
   <<o_delete.c : o_delete_complex()>>
   <<o_delete.c : o_delete_line()>>
   <<o_delete.c : o_delete_box()>>
  +#ifndef HAS_GTK12
  +<<o_delete.c : o_delete_picture()>>
  +#endif
   <<o_delete.c : o_delete_circle()>>
   <<o_delete.c : o_delete_text()>>
   <<o_delete.c : o_delete_arc()>>
  @@ -236,6 +239,25 @@
   
   @ %def o_delete_box
   
  +@section Function @code{o_delete_picture()}
  +
  +@defun o_delete_picture w_current obj
  +@end defun
  +
  +<<o_delete.c : o_delete_picture()>>=
  +static void
  +o_delete_picture(TOPLEVEL *w_current, OBJECT *obj)
  +{
  +  o_picture_erase(w_current, obj);
  +  o_picture_erase_grips(w_current, obj);
  +
  +  s_delete(w_current, obj);
  +  w_current->page_current->object_tail =
  +  (OBJECT *) return_tail(w_current->page_current->object_head);
  +}
  +
  +
  +@ %def o_delete_box
   
   @section Function @code{o_delete_circle()}
   
  @@ -349,6 +371,12 @@
           o_delete_box(w_current, object);
           break;
   
  +      case(OBJ_PICTURE):
  +#ifndef HAS_GTK12
  +        o_delete_picture(w_current, object);
  +#endif
  +        break;
  +
         case(OBJ_CIRCLE):
           o_delete_circle(w_current, object);
           break;
  
  
  
  1.13      +293 -1    eda/geda/devel/gschem/noweb/o_grips.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: o_grips.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/o_grips.nw,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -b -r1.12 -r1.13
  --- o_grips.nw	4 Feb 2005 04:39:29 -0000	1.12
  +++ o_grips.nw	19 Feb 2005 23:27:07 -0000	1.13
  @@ -17,24 +17,36 @@
   <<o_grips.c : o_grips_search()>>
   <<o_grips.c : o_grips_search_arc()>>
   <<o_grips.c : o_grips_search_box()>>
  +#ifndef HAS_GTK12
  +<<o_grips.c : o_grips_search_picture()>>
  +#endif
   <<o_grips.c : o_grips_search_circle()>>
   <<o_grips.c : o_grips_search_line()>>
   
   <<o_grips.c : o_grips_start()>>
   <<o_grips.c : o_grips_start_arc()>>
   <<o_grips.c : o_grips_start_box()>>
  +#ifndef HAS_GTK12
  +<<o_grips.c : o_grips_start_picture()>>
  +#endif
   <<o_grips.c : o_grips_start_circle()>>
   <<o_grips.c : o_grips_start_line()>>
   
   <<o_grips.c : o_grips_motion()>>
   <<o_grips.c : o_grips_motion_arc()>>
   <<o_grips.c : o_grips_motion_box()>>
  +#ifndef HAS_GTK12
  +<<o_grips.c : o_grips_motion_picture()>>
  +#endif
   <<o_grips.c : o_grips_motion_circle()>>
   <<o_grips.c : o_grips_motion_line()>>
   
   <<o_grips.c : o_grips_end()>>
   <<o_grips.c : o_grips_end_arc()>>
   <<o_grips.c : o_grips_end_box()>>
  +#ifndef HAS_GTK12
  +<<o_grips.c : o_grips_end_picture()>>
  +#endif
   <<o_grips.c : o_grips_end_circle()>>
   <<o_grips.c : o_grips_end_line()>>
   
  @@ -97,7 +109,18 @@
   #define GET_BOX_TOP(w)                          \
   	        min((w)->start_y, (w)->last_y);
   
  -@ %def GET_BOX_WIDTH GET_BOX_HEIGHT GET_BOX_LEFT GET_BOX_TOP
  +#define GET_PICTURE_WIDTH(w)			\
  +	abs((w)->last_x - (w)->start_x) 
  +#define GET_PICTURE_HEIGHT(w)			\
  +	(w)->pixbuf_wh_ratio == 0 ? 0 : abs((w)->last_x - (w)->start_x)/(w)->pixbuf_wh_ratio
  +#define GET_PICTURE_LEFT(w)				\
  +	min((w)->start_x, (w)->last_x);
  +#define GET_PICTURE_TOP(w)				\
  +	(w)->start_y < (w)->last_y ? (w)->start_y  : \
  +                                     (w)->start_y-abs((w)->last_x - (w)->start_x)/(w)->pixbuf_wh_ratio;
  +
  +@ %def GET_BOX_WIDTH GET_BOX_HEIGHT GET_BOX_LEFT GET_BOX_TOP \
  +       GET_PICTURE_WIDTH GET_PICTURE_HEIGHT GET_PICTURE_LEFT GET_PICTURE_TOP
   
   
   @section Global Variables [[whichone_changing]] and [[object_changing]]
  @@ -168,6 +191,15 @@
             if(found != NULL) return found;
             break;
   		  
  +        case(OBJ_PICTURE):
  +          /* check the grips of the picture object */
  +#ifndef HAS_GTK12
  +          found = o_grips_search_picture(w_current, object,
  +                                         x, y, size, whichone);
  +          if(found != NULL) return found;
  +#endif
  +          break;
  +		  
           case(OBJ_CIRCLE):
             /* check the grips of the circle object */
             found = o_grips_search_circle(w_current, object,
  @@ -251,6 +283,17 @@
           return(TRUE);
           break;
   				
  +      case(OBJ_PICTURE):
  +				/* start the modification of a grip on a picture */
  +#ifndef HAS_GTK12
  +        o_grips_start_picture(w_current, object, x, y, whichone);
  +				
  +        whichone_changing = whichone;
  +        object_changing = object;
  +        return(TRUE);
  +#endif
  +        break;
  +				
         case(OBJ_CIRCLE):
   				/* start the modification of a grip on a circle */
           o_grips_start_circle(w_current, object, x, y, whichone);
  @@ -390,6 +433,13 @@
       o_grips_motion_box(w_current, x, y, whichone_changing);
       break;
   		
  +    case(OBJ_PICTURE):
  +    /* erase, update and draw a box */
  +#ifndef HAS_GTK12
  +    o_grips_motion_picture(w_current, x, y, whichone_changing);
  +#endif
  +    break;
  +		
       case(OBJ_CIRCLE):
       /* erase, update and draw a circle */
       o_grips_motion_circle(w_current, x, y, whichone_changing);
  @@ -455,6 +505,13 @@
       o_grips_end_box(w_current, object, whichone_changing);
       break;
   	  
  +    case(OBJ_PICTURE):
  +    /* modify a picture object */
  +#ifndef HAS_GTK12
  +    o_grips_end_picture(w_current, object, whichone_changing);
  +#endif
  +    break;
  +	  
       case(OBJ_CIRCLE):
       /* modify a circle object */
       o_grips_end_circle(w_current, object, whichone_changing);
  @@ -1134,6 +1191,241 @@
   
   @
   
  +@section Function [[o_grips_start_picture()]]
  +
  +@defun o_grips_start_picture w_current o_current x y whichone
  +This function initializes the grip motion process for a picture. From the [[o_current]] pointed object, it stores into the TOPLEVEL structure the .... These variables are used in the grip process.
  +@end defun
  +
  +The function first erases the grips.
  +
  +The coordinates of the selected corner are put in ([[w_current->last_x]],[[w_current->last_y]]).
  +
  +The coordinates of the opposite corner go in ([[w_current->start_x]],[[w_current->start_y]]). They are not suppose to change during the action.
  +
  +<<o_grips.c : o_grips_start_picture()>>=
  +void
  +o_grips_start_picture(TOPLEVEL *w_current, OBJECT *o_current,
  +				  int x, int y, int whichone)
  +{
  +  w_current->last_drawb_mode = -1;
  +	
  +  /* erase the picture before */
  +  o_picture_erase(w_current, o_current);
  +  w_current->current_pixbuf = o_current->picture->original_picture;
  +  w_current->pixbuf_filename = o_current->picture->filename;
  +  w_current->pixbuf_wh_ratio = o_current->picture->ratio;
  +
  +  /* (last_x,last_y)    is the selected corner */
  +  /* (start_x, start_y) is the opposite corner */
  +  switch(whichone) {
  +    case PICTURE_UPPER_LEFT: 
  +      w_current->last_x  = o_current->picture->screen_upper_x;
  +      w_current->last_y  = o_current->picture->screen_upper_y;
  +      w_current->start_x = o_current->picture->screen_lower_x;
  +      w_current->start_y = o_current->picture->screen_lower_y;
  +      break;
  +    case PICTURE_LOWER_RIGHT: 
  +      w_current->last_x  = o_current->picture->screen_lower_x;
  +      w_current->last_y  = o_current->picture->screen_lower_y;
  +      w_current->start_x = o_current->picture->screen_upper_x;
  +      w_current->start_y = o_current->picture->screen_upper_y;
  +      break;
  +    case PICTURE_UPPER_RIGHT: 
  +      w_current->last_x  = o_current->picture->screen_lower_x;
  +      w_current->last_y  = o_current->picture->screen_upper_y;
  +      w_current->start_x = o_current->picture->screen_upper_x;
  +      w_current->start_y = o_current->picture->screen_lower_y;
  +      break;
  +    case PICTURE_LOWER_LEFT: 
  +      w_current->last_x  = o_current->picture->screen_upper_x;
  +      w_current->last_y  = o_current->picture->screen_lower_y;
  +      w_current->start_x = o_current->picture->screen_lower_x;
  +      w_current->start_y = o_current->picture->screen_upper_y;
  +      break;
  +    default:
  +      return; /* error */
  +  }
  +
  +  /* draw the first temporary picture */
  +  o_picture_rubberbox_xor(w_current);
  +
  +}
  +
  +@ %def o_grips_start_picture
  +
  +
  +@section Function [[o_grips_search_picture()]]
  +
  +@defun o_grips_search_picture w_current o_current x y whichone
  +This function checks if the pointer event occuring at ([[x]],[[y]]) is inside one of the grips of the [[o_current]] pointed picture object. 
  +If so, the [[whichone]] pointed integer is set to the identifier of this grip and the returned pointer is a pointer on this object. 
  +If the point is not inside a grip the function returns a NULL pointer and the [[whichone]] pointed integer is unset.
  +@end defun
  +
  +A picture object has four grips : one at each corner of the picture. The identifiers of each corner are [[PICTURE_UPPER_LEFT]], [[PICTURE_UPPER_RIGHT]], [[PICTURE_LOWER_LEFT]] and [[PICTURE_LOWER_RIGHT]].
  +
  +The [[x]] and [[y]] parameters are in screen units.
  +
  +The [[size]] parameter is half the width (and half the height) of the square representing a grip in screen unit.
  +
  +<<o_grips.c : o_grips_search_picture()>>=
  +OBJECT *
  +o_grips_search_picture(TOPLEVEL *w_current, OBJECT *o_current,
  +				   int x, int y, int size, int *whichone)
  +{
  +  int left, right, top, bottom;
  +  int x2size;
  +
  +  /* width/height of the grip */
  +  x2size = 2 * size;
  +
  +  /* inside upper left grip ? */
  +  left   = o_current->picture->screen_upper_x - size;
  +  top    = o_current->picture->screen_upper_y - size;
  +  right  = left + x2size;
  +  bottom = top  + x2size;
  +  if (inside_region(left, top, right, bottom, x, y)) {
  +    *whichone = PICTURE_UPPER_LEFT;
  +    return(o_current);
  +  }
  +
  +  /* inside lower right grip ? */
  +  left   = o_current->picture->screen_lower_x - size;
  +  top    = o_current->picture->screen_lower_y - size;
  +  right  = left + x2size;
  +  bottom = top  + x2size;
  +  if (inside_region(left, top, right, bottom, x, y)) {
  +    *whichone = PICTURE_LOWER_RIGHT;
  +    return(o_current);
  +  }
  +
  +  /* inside upper right grip ? */
  +  left   = o_current->picture->screen_lower_x - size;
  +  top    = o_current->picture->screen_upper_y - size;
  +  right  = left + x2size;
  +  bottom = top  + x2size;
  +  if (inside_region(left, top, right, bottom, x, y)) {
  +    *whichone = PICTURE_UPPER_RIGHT;
  +    return(o_current);
  +  }
  +
  +  /* inside lower left grip ? */
  +  left   = o_current->picture->screen_upper_x - size;
  +  top    = o_current->picture->screen_lower_y - size;
  +  right  = left + x2size;
  +  bottom = top  + x2size;
  +  if (inside_region(left, top, right, bottom, x, y)) {
  +    *whichone = PICTURE_LOWER_LEFT;
  +    return(o_current);
  +  }
  +
  +  return NULL;
  +}
  +
  +@ %def o_grips_search_picture
  +
  +
  +@section Function [[o_grips_motion_picture()]]
  +
  +@defun o_grips_motion_picture w_current x y whichone
  +This function is the refreshing part of the grip motion process. It is called whenever the position of the pointer is changed, therefore requiring the TOPLEVEL variables to be updated.
  +Depending on the grip selected and moved, the temporary TOPLEVEL variables are changed according to the current position of the pointer and the modifications temporary drawn.
  +@end defun
  +
  +This function only makes a call to [[o_picture_rubberpicture()]] that updates the TOPLEVEL variables, erase the previous temporary picture and draw the new temporary picture.
  +
  +<<o_grips.c : o_grips_motion_picture()>>=
  +void
  +o_grips_motion_picture(TOPLEVEL *w_current, int x, int y, int whichone)
  +{
  +	/* erase, update and draw the temporary picture */
  +	o_picture_rubberbox(w_current, x, y);
  +
  +}
  +
  +@ %def o_grips_motion_picture
  +
  +@section Function [[o_grips_end_picture()]]
  +
  +@defun o_grips_end_picture w_current o_current whichone
  +@end defun
  +
  +<<o_grips.c : o_grips_end_picture()>>=
  +void
  +o_grips_end_picture(TOPLEVEL *w_current, OBJECT *o_current, int whichone)
  +{
  +	int picture_width, picture_height;
  +	int x, y;
  +
  +	<<o_grips_end_picture() : get the new coordinates of the picture>>
  +	
  +	<<o_grips_end_picture() : check the new width and height>>
  +
  +	<<o_grips_end_picture() : modify the picture object>>
  +
  +	<<o_grips_end_picture() : erase the temporary picture and draw the modified picture>>
  +
  +}
  +
  +@ %def o_grips_end_picture
  +
  +
  +
  +<<o_grips_end_picture() : get the new coordinates of the picture>>=
  +picture_width  = GET_PICTURE_WIDTH (w_current);
  +picture_height = GET_PICTURE_HEIGHT(w_current);
  +
  +@ 
  +
  +
  +<<o_grips_end_picture() : check the new width and height>>=
  +/* don't allow zero width/height picturees
  + * this ends the picture drawing behavior 
  + * we want this? hack */
  +if ((picture_width == 0) && (picture_height == 0))
  +{
  +	w_current->start_x = (-1);
  +	w_current->start_y = (-1);
  +	w_current->last_x  = (-1);
  +	w_current->last_y  = (-1);
  +	
  +	w_current->inside_action=0;
  +	i_set_state(w_current, SELECT);
  +	
  +	o_redraw_single(w_current, o_current);
  +        i_update_toolbar(w_current);
  +	
  +	return;
  +}
  +
  +@ 
  +
  +
  +<<o_grips_end_picture() : modify the picture object>>=
  +SCREENtoWORLD(w_current, 
  +			  w_current->last_x, w_current->last_y,
  +			  &x, &y);
  +x = snap_grid(w_current, x);
  +y = snap_grid(w_current, y);
  +
  +o_picture_modify(w_current, o_current, x, y, whichone);
  +
  +@ 
  +
  +
  +<<o_grips_end_picture() : erase the temporary picture and draw the modified picture>>=
  +/* erase the temporary picture */
  +o_picture_rubberbox_xor(w_current);
  +
  +/* draw the modified picture */
  +o_redraw_single(w_current, o_current);
  +
  +w_current->current_pixbuf = NULL;
  +w_current->pixbuf_filename = NULL;
  +w_current->pixbuf_wh_ratio = 0;
  +
  +@
   
   @section Function [[o_grips_search_circle()]]
   
  
  
  
  1.31      +28 -0     eda/geda/devel/gschem/noweb/o_misc.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: o_misc.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/o_misc.nw,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -b -r1.30 -r1.31
  --- o_misc.nw	4 Feb 2005 22:40:55 -0000	1.30
  +++ o_misc.nw	19 Feb 2005 23:27:08 -0000	1.31
  @@ -146,6 +146,11 @@
       multi_attrib_edit(w_current, list);
       break;
   
  +    case(OBJ_PICTURE):
  +#ifndef HAS_GTK12
  +    picture_change_filename_dialog(w_current);
  +#endif
  +    break;
       case(OBJ_TEXT):
       if(strchr(o_current->text->string,'=')) {
   
  @@ -441,6 +446,19 @@
           o_box_draw(w_current, object);
           break;
   
  +      case(OBJ_PICTURE):
  +				/* erase the current selection */
  +#ifndef HAS_GTK12
  +        o_picture_erase_grips(w_current, object);
  +        o_picture_erase(w_current, object);
  +
  +        o_picture_rotate(w_current, centerx, centery, 
  +                     90, object);
  +
  +        o_picture_draw(w_current, object);
  +#endif
  +        break;
  +
         case(OBJ_CIRCLE):
           o_circle_erase_grips(w_current, object);
           o_circle_erase(w_current, object);
  @@ -743,6 +761,16 @@
           o_box_draw(w_current, object);
           break;
   
  +      case(OBJ_PICTURE):
  +#ifndef HAS_GTK12
  +        o_picture_erase_grips(w_current, object);
  +        o_picture_erase(w_current, object);
  +        o_picture_mirror(w_current,
  +			 centerx, centery, object);
  +        o_picture_draw(w_current, object);
  +#endif
  +        break;
  +
         case(OBJ_CIRCLE):
           o_circle_erase_grips(w_current, object);
           o_circle_erase(w_current, object);
  
  
  
  1.12      +9 -1      eda/geda/devel/gschem/noweb/o_move.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: o_move.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/o_move.nw,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -b -r1.11 -r1.12
  --- o_move.nw	4 Feb 2005 04:39:30 -0000	1.11
  +++ o_move.nw	19 Feb 2005 23:27:08 -0000	1.12
  @@ -164,6 +164,12 @@
           o_box_translate_world(w_current, diff_x, diff_y, object);
           break;
   
  +      case (OBJ_PICTURE):
  +#ifndef HAS_GTK12
  +        o_picture_translate_world(w_current, diff_x, diff_y, object);
  +#endif
  +        break;
  +
         case (OBJ_CIRCLE):
           o_circle_translate_world(w_current, diff_x, diff_y, object);
           break;
  @@ -262,6 +268,7 @@
         case (OBJ_BUS):
         case (OBJ_LINE):
         case (OBJ_BOX):
  +      case (OBJ_PICTURE):
         case (OBJ_CIRCLE):
         case (OBJ_ARC):
         case (OBJ_TEXT):
  @@ -659,7 +666,8 @@
     }
   
   #if DEBUG
  -  printf("%d\n", g_list_length(*moved_objects));
  +  /* FIXME: moved_objects doesn't exist? */
  +  /*printf("%d\n", g_list_length(*moved_objects));*/
     printf("%d\n", g_list_length(*other_objects));
     printf("%d\n", g_list_length(*connected_objects));
   #endif
  
  
  
  1.4       +1 -0      eda/geda/devel/gschem/noweb/rcstrings.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: rcstrings.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/rcstrings.nw,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -b -r1.3 -r1.4
  --- rcstrings.nw	18 Oct 2002 02:40:53 -0000	1.3
  +++ rcstrings.nw	19 Feb 2005 23:27:08 -0000	1.4
  @@ -81,6 +81,7 @@
   _("Text...")
   _("Line")
   _("Box")
  +_("Image")
   _("Circle")
   _("Arc")
   _("Pin")
  
  
  
  1.19      +38 -0     eda/geda/devel/gschem/noweb/x_event.nw
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: x_event.nw
  ===================================================================
  RCS file: /home/cvspsrv/cvsroot/eda/geda/devel/gschem/noweb/x_event.nw,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -b -r1.18 -r1.19
  --- x_event.nw	11 Feb 2005 18:22:10 -0000	1.18
  +++ x_event.nw	19 Feb 2005 23:27:08 -0000	1.19
  @@ -269,6 +269,26 @@
           w_current->event_state = DRAWBOX;
           break;
   
  +      case(DRAWPICTURE):
  +#ifndef HAS_GTK12
  +        o_picture_start(w_current,
  +                    (int) event->x,
  +                    (int) event->y);
  +        w_current->event_state = ENDPICTURE;
  +        w_current->inside_action = 1;
  +#endif
  +        break;
  +
  +      case(ENDPICTURE):
  +#ifndef HAS_GTK12
  +        o_picture_end(w_current,
  +                  (int) event->x,
  +                  (int) event->y);
  +        w_current->inside_action = 0;
  +        w_current->event_state = DRAWPICTURE;
  +#endif
  +        break;
  +
         case(DRAWCIRCLE):
           o_circle_start(w_current,
                          (int) event->x,
  @@ -594,6 +614,15 @@
           o_box_eraserubber(w_current);
           break;
   
  +        case(DRAWPICTURE):
  +        case(ENDPICTURE):
  +#ifndef HAS_GTK12
  +        w_current->inside_action = 0;
  +	i_set_state(w_current, DRAWPICTURE);
  +        o_picture_eraserubber(w_current);
  +#endif
  +        break;
  +
           case(DRAWCIRCLE):
           case(ENDCIRCLE):
           w_current->inside_action = 0;
  @@ -968,6 +997,15 @@
                        (int) event->y);
       break;
   
  +    case(ENDPICTURE):
  +#ifndef HAS_GTK12
  +    if (w_current->inside_action)
  +    o_picture_rubberbox( w_current,
  +                        (int) event->x,
  +                        (int) event->y);
  +#endif
  +    break;
  +
       case(ENDCIRCLE):
       if (w_current->inside_action)
       o_circle_rubbercircle(w_current,
  
  
  
  1.1                  eda/geda/devel/gschem/noweb/o_picture.nw
  
  Index: o_picture.nw
  ===================================================================
  @c -*- mode: Noweb; noweb-doc-mode: texinfo-mode; noweb-code-mode: c-mode -*-
  
  @node File o_picture.c,,,Top
  @chapter File @file{o_picture.c}
  
  @section File header
  
  <<o_picture.c : *>>=
  
  <<o_picture.c : copyright and license>>
  
  /* DO NOT read or edit this file ! Use ../noweb/o_box.nw instead */
  
  <<o_picture.c : include directives>>
  #ifndef HAS_GTK12
  <<o_picture.c : macros>>
  <<o_picture.c : o_picture_start()>>
  <<o_picture.c : o_picture_end()>>
  #endif
  <<o_picture.c : picture_selection_dialog()>>
  #ifndef HAS_GTK12
  <<o_picture.c : picture_selection_ok()>>
  <<o_picture.c : picture_selection_cancel()>>
  <<o_picture.c : o_picture_eraserubber()>>
  <<o_picture.c : o_picture_rubberbox()>>
  <<o_picture.c : o_picture_rubberbox_xor()>>
  <<o_picture.c : o_picture_draw()>>
  <<o_picture.c : o_picture_draw_grips()>>
  <<o_picture.c : o_picture_erase_grips()>>
  <<o_picture.c : o_picture_erase()>>
  <<o_picture.c : o_picture_draw_xor()>>
  <<o_picture.c : picture_change_selection_cancel()>>
  <<o_picture.c : picture_change_selection_ok()>>
  <<o_picture.c : picture_change_filename_dialog()>>
  
  #endif
  @ 
  
  <<o_picture.c : copyright and license>>=
  /* gEDA - GPL Electronic Design Automation
   * gschem - gEDA Schematic Capture
   * Copyright (C) 1998-2000 Ales V. Hvezda
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
   */
  
  @ 
  
  <<o_picture.c : include directives>>=
  #include <config.h>
  #include <math.h>
  #include <stdio.h>
  
  #include <libgeda/libgeda.h>
  #ifndef HAS_GTK12
  #include <gdk-pixbuf/gdk-pixbuf.h>
  #endif
  #include "../include/globals.h"
  #include "../include/prototype.h"
  @ 
  
  <<o_picture.c : macros>>=
  /* This works, but using one macro inside of other don't */
  #define GET_PICTURE_WIDTH(w)			\
  	abs((w)->last_x - (w)->start_x) 
  #define GET_PICTURE_HEIGHT(w)			\
  	(w)->pixbuf_wh_ratio == 0 ? 0 : abs((w)->last_x - (w)->start_x)/(w)->pixbuf_wh_ratio
  #define GET_PICTURE_LEFT(w)				\
  	min((w)->start_x, (w)->last_x);
  #define GET_PICTURE_TOP(w)				\
  	(w)->start_y < (w)->last_y ? (w)->start_y  : \
                                       (w)->start_y-abs((w)->last_x - (w)->start_x)/(w)->pixbuf_wh_ratio;
  
  
  @ %def GET_PICTURE_WIDTH GET_PICTURE_HEIGHT GET_PICTURE_LEFT GET_PICTURE_TOP
  
  
  @section Function [[o_picture_start]]
  
  @defun o_picture_start w_current x y
  This function starts the process to input a new picture. Parameters for this picture are put into/extracted from the [[w_current]] toplevel structure.
  [[x]] and [[y]] are current coordinates of the pointer in screen coordinates.
  @end defun
  
  The first step is to input one corner of the picture. This corner is ([[x]],[[y]]) snapped to the grid and saved in [[w_current->start_x]] and [[w_current->start_y]].
  
  The other corner will be saved in ([[w_current->last_x]],[[w_current->last_y]]).
  
  <<o_picture.c : o_picture_start()>>=
  void
  o_picture_start(TOPLEVEL *w_current, int x, int y)
  {
  #if DEBUG
    printf("o_picture_start called\n");
  #endif
    /* init start_[x|y], last_[x|y] to describe box */
    w_current->last_x = w_current->start_x = fix_x(w_current, x);
    w_current->last_y = w_current->start_y = fix_y(w_current, y);
  
    /* start to draw the box */
    o_picture_rubberbox_xor(w_current);
  
  }
  
  @ %def o_picture_start
  
  
  @section Function [[o_picture_end()]]
  
  @defun o_picture_end w_current x y
  This function ends the input of the second corner of a picture. The ([[x]],[[y]]) point is set to be this second corner. The picture is then defined by ([[w_current->start_x]],[[w_current->start_y]] and ([[w_current->last_x]],[[w_current->last_y]] that is a snapped version of ([[x]],[[y]]).
  [[x]] and [[y]] are in screen unit.
  @end defun
  
  The temporary picture is erased ; a new picture object is allocated, initialized and linked to the object list ; The object is finally drawn on the current sheet.
  
  <<o_picture.c : o_picture_end()>>=
  void
  o_picture_end(TOPLEVEL *w_current, int x, int y)
  {
    int x1, y1;
    int x2, y2;
    int picture_width, picture_height;
    int picture_left, picture_top;
  
    if (w_current->inside_action == 0) {
      o_redraw(w_current, w_current->page_current->object_head);
      return;
    }
  
    /* get the last coords of the pointer */
    w_current->last_x = fix_x(w_current, x);
    w_current->last_y = fix_y(w_current, y);
  
    /* erase the temporary picture */
    o_picture_rubberbox_xor(w_current);
    
    picture_width  = GET_PICTURE_WIDTH (w_current);
    picture_height = GET_PICTURE_HEIGHT(w_current);
    picture_left   = GET_PICTURE_LEFT  (w_current);
    picture_top    = GET_PICTURE_TOP   (w_current);
  
    /* pictures with null width and height are not allowed */
    if ((picture_width == 0) && (picture_height == 0)) {
  	  /* cancel the object creation */
  	  w_current->start_x = (-1);
  	  w_current->start_y = (-1);
  	  w_current->last_x  = (-1);
  	  w_current->last_y  = (-1);
  	  return;
    }
  
    /* calculate the world coords of the upper left and lower right corners */
    SCREENtoWORLD(w_current, picture_left, picture_top, &x1, &y1);
    SCREENtoWORLD(w_current,
                  picture_left + picture_width, picture_top  + picture_height, &x2, &y2);
    x1 = snap_grid(w_current, x1);
    y1 = snap_grid(w_current, y1);
    x2 = snap_grid(w_current, x2);
    y2 = snap_grid(w_current, y2);
  
    /* create the object */
    w_current->page_current->object_tail = 
    o_picture_add(w_current,
                  w_current->page_current->object_tail,
  		w_current->current_pixbuf,
  		w_current->pixbuf_filename,
  		w_current->pixbuf_wh_ratio,
                  OBJ_PICTURE, x1, y1, x2, y2, 0, FALSE, FALSE);
  
    /* draw it */
    o_redraw_single(w_current, w_current->page_current->object_tail);
    
  #if DEBUG
    printf("coords: %d %d %d %d\n", x1, y2, x2, y2);
  #endif
  	
    w_current->start_x = (-1);
    w_current->start_y = (-1);
    w_current->last_x  = (-1);
    w_current->last_y  = (-1);
  	
    w_current->page_current->CHANGED = 1;
  
    o_undo_savestate(w_current, UNDO_ALL);
  
  }
  
  @ %def o_picture_end
  
  @section Function @code{picture_selection_dialog()}
  
  @defun picture_selection_ok widget w_current
  @end defun
  
  <<o_picture.c : picture_selection_ok()>>=
  void
  picture_selection_ok (GtkWidget *widget, TOPLEVEL *w_current)
  {
    GtkWidget *file_selector = (GtkWidget *)w_current->pfswindow;
    const gchar *selected_filename;
    GdkPixbuf *pixbuf;
    GError *error;
    
  
    selected_filename = (char *) g_strdup(gtk_file_selection_get_filename (GTK_FILE_SELECTION (file_selector)));
  #if DEBUG
    g_print ("Selected picture: %s\n", selected_filename);
  #endif   
    picture_selection_cancel(widget, w_current);
    
    error = NULL;
    pixbuf = gdk_pixbuf_new_from_file (selected_filename, &error);
  
    if (!pixbuf) {
      GtkWidget *dialog;
      
      dialog = gtk_message_dialog_new (GTK_WINDOW (w_current->main_window),
                                       GTK_DIALOG_DESTROY_WITH_PARENT,
                                       GTK_MESSAGE_ERROR,
                                       GTK_BUTTONS_CLOSE,
                                       "Failed to load picture: %s",
                                       error->message);
      g_error_free (error);
       
      g_signal_connect (dialog, "response",
                        G_CALLBACK (gtk_widget_destroy), NULL);
  
      gtk_widget_show (dialog);
      return;
    }
  
  #if DEBUG
    printf("Picture loaded succesfully.\n");
  #endif
  
    exit_if_null(w_current);
  
    o_erase_rubber(w_current);
  
    i_update_middle_button(w_current, i_callback_add_picture, _("Picture"));
    w_current->inside_action = 0;
  
    o_picture_set_pixbuf(w_current, pixbuf, (char *) selected_filename);
    /* o_picture_set_pixbuf allocates memory for filename, so free the pointer */
    free((char *)selected_filename);
  
    w_current->page_current->CHANGED=1;
  
    i_allow_expose();
    i_set_state(w_current, DRAWPICTURE);
     
  }
  
  @ %def picture_selection_cancel
  
  @defun picture_selection_cancel widget w_current
  @end defun
  
  <<o_picture.c : picture_selection_cancel()>>=
  void
  picture_selection_cancel (GtkWidget *widget, TOPLEVEL *w_current)
  {
    i_set_state(w_current, SELECT);
    i_update_toolbar(w_current);
    gtk_widget_destroy(w_current->pfswindow);
    w_current->pfswindow=NULL;
  }
  
  @ %def picture_selection_cancel
  
  
  @section Function @code{picture_selection_dialog()}
  
  @defun picture_selection_dialog w_current
  @end defun
  
  <<o_picture.c : picture_selection_dialog()>>=
  void
  picture_selection_dialog (TOPLEVEL *w_current)
  {
  
  #ifdef HAS_GTK12
    GtkWidget *dialog, *label, *okay_button;
    
     /* Create the widgets */
     
     dialog = gtk_dialog_new();
     label = gtk_label_new ("Gschem doesn't support pictures if it has been compiled using GTK 1.2");
     okay_button = gtk_button_new_with_label("OK");
     
     /* Ensure that the dialog box is destroyed when the user clicks ok. */
     
     gtk_signal_connect_object (GTK_OBJECT (okay_button), "clicked",
                                GTK_SIGNAL_FUNC (gtk_widget_destroy), dialog);
     gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area),
                        okay_button);
  
     /* Add the label, and show everything we've added to the dialog. */
  
     gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
                        label);
     gtk_widget_show_all (dialog);
  #else
     GtkWidget *file_selector;
  
     /* Create the selector */
     if (!w_current->pfswindow) {
  #if DEBUG
       printf("Creating new picture file selection dialog\n");
  #endif
       w_current->pfswindow = gtk_file_selection_new ("Please select a picture file.");
       file_selector = w_current->pfswindow;
       if (w_current->pixbuf_filename)
         gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_selector), w_current->pixbuf_filename);
       gtk_window_position(GTK_WINDOW (w_current->pfswindow),
                           GTK_WIN_POS_NONE);
       
       g_signal_connect (G_OBJECT (file_selector), "destroy",
  		       G_CALLBACK (picture_selection_cancel), w_current);
       
       
       g_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_selector)->ok_button),
                         "clicked",
                         G_CALLBACK (picture_selection_ok),
                         w_current);
     			   
       /* Ensure that the dialog box is destroyed when the user clicks the cancel button. */
       g_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_selector)->cancel_button),
                                 "clicked",
                                 G_CALLBACK (picture_selection_cancel),
                                 w_current); 
     		       
     }
  
     /* Display that dialog */
     if (!GTK_WIDGET_VISIBLE (w_current->pfswindow)) {
       gtk_widget_show (w_current->pfswindow);
       #if 0
       gtk_grab_add (w_current->pfswindow);
       #endif
     } else {
       gdk_window_raise(w_current->pfswindow->window);
     }
  #endif
  }
  
  @ %def picture_selection_dialog
  
  
  @ %def picture_change_selection_cancel
  
  @defun picture_change_selection_cancel widget w_current
  @end defun
  
  <<o_picture.c : picture_change_selection_cancel()>>=
  void
  picture_change_selection_cancel (GtkWidget *widget, TOPLEVEL *w_current)
  {
    i_set_state(w_current, SELECT);
    i_update_toolbar(w_current);
    gtk_widget_destroy(w_current->pcfswindow);
    w_current->pcfswindow=NULL;
  }
  
  @ %def picture_change_selection_cancel
  
  @section Function @code{picture_change_selection_dialog()}
  
  @defun picture_change_selection_ok widget w_current
  @end defun
  
  <<o_picture.c : picture_change_selection_ok()>>=
  void
  picture_change_selection_ok (GtkWidget *widget, TOPLEVEL *w_current)
  {
    GtkWidget *file_selector = (GtkWidget *)w_current->pcfswindow;
    const gchar *selected_filename;
    GdkPixbuf *pixbuf;
    GError *error;
    SELECTION *list;  
  
    selected_filename = (char *) g_strdup(gtk_file_selection_get_filename (GTK_FILE_SELECTION (file_selector)));
  #if DEBUG
    g_print ("Selected picture: %s\n", selected_filename);
  #endif   
    picture_change_selection_cancel(widget, w_current);
    
    error = NULL;
    pixbuf = gdk_pixbuf_new_from_file (selected_filename, &error);
  
    if (!pixbuf) {
      GtkWidget *dialog;
      
      dialog = gtk_message_dialog_new (GTK_WINDOW (w_current->main_window),
                                       GTK_DIALOG_DESTROY_WITH_PARENT,
                                       GTK_MESSAGE_ERROR,
                                       GTK_BUTTONS_CLOSE,
                                       "Failed to load picture: %s",
                                       error->message);
      g_error_free (error);
       
      g_signal_connect (dialog, "response",
                        G_CALLBACK (gtk_widget_destroy), NULL);
  
      gtk_widget_show (dialog);
      return;
    }
  #if DEBUG
    printf("Picture loaded succesfully.\n");
  #endif
  
    exit_if_null(w_current);
  
    o_erase_rubber(w_current);
  
    w_current->inside_action = 0;
  
    list = w_current->page_current->selection2_head->next;
    while (list != NULL) {
      OBJECT *object;
      
      object = list->selected_object;
      if (object == NULL) {
        fprintf(stderr, _("ERROR: NULL object!\n"));
        exit(-1);
      }
      if (!object->attached_to) {
        /* It's selected. Then change picture if it's a picture */
        if (object->type == OBJ_PICTURE) {
  	/* Erase previous picture */
  	o_picture_erase(w_current, object);
  
  	/* Change picture attributes */
  	if (object->picture->original_picture != NULL) {
  	  free(object->picture->original_picture);
  	  object->picture->original_picture=NULL;
  	}
  	
  	if (object->picture->filename != NULL) {
  	  free(object->picture->filename);
  	  object->picture->filename=NULL;
  	}
  	/* Create a copy of the pixbuf rotated */
  	object->picture->original_picture = gdk_pixbuf_rotate(pixbuf, 0);
  	
  	if (object->picture->original_picture == NULL) {
  	  fprintf(stderr, "change picture: Couldn't get enough memory for the new picture\n");
  	  return;
  	}
  
  	object->picture->filename = (char *) g_strdup(selected_filename);
    
  	object->picture->ratio = gdk_pixbuf_get_width(pixbuf) / 
  	  gdk_pixbuf_get_height(pixbuf);
  	/* Draw new picture */
  	o_picture_draw(w_current, object);
  
        }
      }
      list = list->next;
    }
    
    free ((char *) selected_filename);
    free(pixbuf);
    w_current->page_current->CHANGED=1;
  
    i_allow_expose();
     
  }
  
  @ %def picture_change_selection_cancel
  
  
  @section Function @code{picture_change_filename_dialog()}
  
  @defun picture_change_filename_dialog w_current
  @end defun
  
  <<o_picture.c : picture_change_filename_dialog()>>=
  void
  picture_change_filename_dialog (TOPLEVEL *w_current)
  {
  
     GtkWidget *file_selector;
  
     /* Create the selector */
     if (!w_current->pcfswindow) {
  #if DEBUG
       printf("Creating change picture file selection dialog\n");
  #endif
       w_current->pcfswindow = gtk_file_selection_new ("Please select a picture file.");
       file_selector = w_current->pcfswindow;
       if (w_current->pixbuf_filename)
         gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_selector), w_current->pixbuf_filename);
       gtk_window_position(GTK_WINDOW (w_current->pcfswindow),
                           GTK_WIN_POS_NONE);
       
       g_signal_connect (G_OBJECT (file_selector), "destroy",
  		       G_CALLBACK (picture_change_selection_cancel), w_current);
       
       
       g_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_selector)->ok_button),
                         "clicked",
                         G_CALLBACK (picture_change_selection_ok),
                         w_current);
     			   
       /* Ensure that the dialog box is destroyed when the user clicks the cancel button. */
       g_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_selector)->cancel_button),
                                 "clicked",
                                 G_CALLBACK (picture_change_selection_cancel),
                                 w_current); 
     		       
     }
  
     /* Display that dialog */
     if (!GTK_WIDGET_VISIBLE (w_current->pcfswindow)) {
       gtk_widget_show (w_current->pcfswindow);
       #if 0
       gtk_grab_add (w_current->pcfswindow);
       #endif
     } else {
       gdk_window_raise(w_current->pcfswindow->window);
     }
  }
  
  @ %def picture_change_filename_dialog
  
  
  
  @section Function @code{o_picture_eraserubber()}
  
  @defun o_picture_eraserubber w_current
  @end defun
  
  <<o_picture.c : o_picture_eraserubber()>>=
  /* used in button cancel code in x_events.c */
  void
  o_picture_eraserubber(TOPLEVEL *w_current)
  {
  #if DEBUG
    printf("o_picture_eraserubber called\n");
  #endif
    o_picture_rubberbox_xor(w_current);
  }
  
  
  @ %def o_picture_eraserubber
  
  
  
  @section Function [[o_picture_rubberbox_xor]]
  
  @defun o_picture_rubberbox_xor w_current
  This function draws the box from the variables in the toplevel structure [[*w_current]].
  One corner of the box is at ([[w_current->start_x]],[[w_current->start_y]]) and the second corner is at ([[w_current->last_x]],[[w_current->last_y]].
  @end defun
  
  The box is drawn with a xor-function over the current sheet with the selection color.
  
  <<o_picture.c : o_picture_rubberbox_xor()>>=
  void
  o_picture_rubberbox_xor(TOPLEVEL *w_current)
  {
  	int picture_width, picture_height, picture_left, picture_top;
  
  	/* get the width/height and the upper left corner of the picture */
  	picture_width  = GET_PICTURE_WIDTH (w_current);
  	picture_height = GET_PICTURE_HEIGHT(w_current);
  	picture_left   = GET_PICTURE_LEFT  (w_current);
  	picture_top    = GET_PICTURE_TOP   (w_current);
  
  #if DEBUG
  	printf("o_picture_rubberbox_xor called:\n");
  	printf("pixbuf wh ratio: %i\n", w_current->pixbuf_wh_ratio);
  	printf("start: %i, %i\n", w_current->start_x, w_current->start_y);
  	printf("last: %i, %i\n", w_current->last_x, w_current->last_y);
  	printf("Left: %i\nTop: %i\nWidth: %i\nHeight: %i\n", picture_left, picture_top, picture_width, picture_height);
  #endif
  	/* draw the picture from the previous variables */
  	gdk_gc_set_foreground(w_current->xor_gc, 
  			      x_get_darkcolor(w_current->select_color)); 
  	gdk_gc_set_line_attributes(w_current->xor_gc, 0, 
  				   GDK_LINE_SOLID, GDK_CAP_NOT_LAST, 
  				   GDK_JOIN_MITER);
  	gdk_draw_rectangle(w_current->window, w_current->xor_gc,
  					   FALSE, picture_left, picture_top, picture_width, picture_height);
  	
  }
  
  @ %def o_picture_rubberbox_xor
  
  
  
  
  @section Function [[o_picture_rubberbox]]
  
  @defun o_picture_rubberbox w_current x y
  This function is used to draw the box while dragging one of its edge or angle. It erases the previous temporary box drawn before, and draws a new updated one. [[x]] and [[y]] are the new position of the mobile point, ie the mouse.
  @end defun
  
  The old values are inside the [[w_current]] pointed structure. Old width, height and left and top values are recomputed by the corresponding macros. The box is then erased by performing a xor-drawing over the box.
  
  <<o_picture.c : o_picture_rubberbox()>>=
  void
  o_picture_rubberbox(TOPLEVEL *w_current, int x, int y)
  {
  #if DEBUG
    printf("o_picture_rubberbox called\n");
  #endif
    if (w_current->inside_action == 0) {
      o_redraw(w_current, w_current->page_current->object_head);
      return;
    }
  
    /* erase the previous temporary box */
    o_picture_rubberbox_xor(w_current);
  
  @ %def o_picture_rubberbox
  
  New values are fixed according to the [[x]] and [[y]] parameters. These are saved in [[w_current]] pointed structure as new temporary values. The new box is then drawn.
  
  <<o_picture.c : o_picture_rubberbox()>>=
    /* update the coords of the corner */
    w_current->last_x = fix_x(w_current, x);
    w_current->last_y = fix_y(w_current, y);
  
    /* draw the new temporary box */
    o_picture_rubberbox_xor(w_current);
    
  }
  
  @ %def o_picture_rubberbox
  
  
  
  @section Function [[o_picture_draw()]]
  
  @defun o_picture_draw w_current o_current
  This function is used to draw a picture on screen. The picture is described in the 
  OBJECT which is referred by [[o_current]]. The picture is displayed according 
  to the current state, described in the TOPLEVEL object pointed by 
  [[w_current]].
  @end defun
  
  It first checks if the OBJECT pointed is valid or not. If not it returns and 
  do not output anything. That should never happen though.
  
  <<o_picture.c : o_picture_draw()>>=
  void
  o_picture_draw(TOPLEVEL *w_current, OBJECT *o_current)
  {
    int wleft, wright, wtop, wbottom; /* world bounds */
    if (o_current->picture == NULL) {
      return;
    }
  
  @ %def o_picture_draw
  
  The function now recalculates the OBJECT as a picture. It involves calculating 
  every single dimensions according to the zoom factor the position, @dots{}.
  It also recalculates the bounding picture of the object and check whether this 
  object is visible or not. If not there is no reason to draw it !
  
  <<o_picture.c : o_picture_draw()>>=	
    o_picture_recalc(w_current, o_current);
  
  	/* Get read to check for visibility of this line by using it's
  	 * bounding picture */
    world_get_picture_bounds(w_current, o_current->picture,
                             &wleft, &wtop, &wright, &wbottom);
  	
    if (!visible(w_current, wleft, wtop, wright, wbottom)) {
      return;
    }
  	
  #if  DEBUG 
    printf("drawing picture\n\n");
  	
    printf("drawing picture: %d %d %d %d\n",
           o_current->picture->screen_upper_x,
           o_current->picture->screen_upper_y,
           o_current->picture->screen_upper_x +
           abs(o_current->picture->screen_lower_x -
               o_current->picture->screen_upper_x),
           o_current->picture->screen_upper_y +
           abs(o_current->picture->screen_lower_y -
               o_current->picture->screen_upper_y));
  #endif
  
  @ 
  
  First, the picture is drawn.
  Finally the function takes care of the grips.
  
  <<o_picture.c : o_picture_draw()>>=	
    if (o_current->picture->displayed_picture != NULL) {
      free(o_current->picture->displayed_picture);
      o_current->picture->displayed_picture = NULL;
    }
    /* If it's not drawing using the background color then draw the image */
    if (w_current->override_color != w_current->background_color) { 
      GdkPixbuf *temp_pixbuf1, *temp_pixbuf2;
  
      /* Create a copy of the pixbuf rotated */
      temp_pixbuf1 = gdk_pixbuf_rotate(o_current->picture->original_picture, 
  				    o_current->picture->angle);
  
      if (temp_pixbuf1 == NULL) {
        fprintf(stderr, "Couldn't get enough memory for rotating the picture\n");
        return;
      }
  
      temp_pixbuf2 = gdk_pixbuf_mirror_flip(temp_pixbuf1, o_current->picture->mirrored, FALSE);
      free(temp_pixbuf1);
  
      if (temp_pixbuf2 == NULL) {
        fprintf(stderr, "Couldn't get enough memory for mirroring the picture\n");
        return;
      }
  
      o_current->picture->displayed_picture = 
      gdk_pixbuf_scale_simple(temp_pixbuf2, 
                              abs(o_current->picture->screen_lower_x -
                                  o_current->picture->screen_upper_x), 
                              abs(o_current->picture->screen_lower_y - 
                                  o_current->picture->screen_upper_y), 
                              GDK_INTERP_BILINEAR);
      free(temp_pixbuf2);
  
      if (o_current->picture->displayed_picture == NULL) {
        fprintf(stderr, "Couldn't get enough memory for scaling the picture\n");
        return;
      }
  
      gdk_draw_pixbuf(w_current->window, w_current->gc, o_current->picture->displayed_picture, 
  		    0, 0, o_current->picture->screen_upper_x, o_current->picture->screen_upper_y, 
  		    -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
      gdk_draw_pixbuf(w_current->backingstore, w_current->gc, o_current->picture->displayed_picture, 
  		    0, 0, o_current->picture->screen_upper_x, o_current->picture->screen_upper_y, 
  		    -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
    }
    else {
      /* Erase the picture, drawing a rectangle with the background color */
      gdk_gc_set_foreground(w_current->gc, x_get_color(w_current->background_color));
      gdk_draw_rectangle(w_current->window, w_current->gc, TRUE, 
  		       o_current->picture->screen_upper_x, o_current->picture->screen_upper_y,
  		       abs(o_current->picture->screen_lower_x -
  			   o_current->picture->screen_upper_x), 
  		       abs(o_current->picture->screen_lower_y - 
  			   o_current->picture->screen_upper_y));
      gdk_draw_rectangle(w_current->backingstore, w_current->gc, TRUE, 
  		       o_current->picture->screen_upper_x, o_current->picture->screen_upper_y,
  		       abs(o_current->picture->screen_lower_x -
  			   o_current->picture->screen_upper_x), 
  		       abs(o_current->picture->screen_lower_y - 
  			   o_current->picture->screen_upper_y));
    }
  
    /* Grip specific stuff */
    if ((o_current->draw_grips == TRUE) && (w_current->draw_grips == TRUE)) {	
  	 
        if (!o_current->selected) {
  	  	/* object is no more selected, erase the grips */
  		o_current->draw_grips = FALSE;
  		o_picture_erase_grips(w_current, o_current); 
    	} else {
  		/* object is selected, draw the grips on the picture */
  		o_picture_draw_grips(w_current, o_current); 
  	}
  	
    }
  
  }
  
  @
  
  @section Function [[o_picture_draw_grips()]]
  
  @defun o_picture_draw_grips w_current w o_current
  This function draws four grips on the corners of the picture described by [[*o_current]].
  @end defun
  
  <<o_picture.c : o_picture_draw_grips()>>=
  void
  o_picture_draw_grips(TOPLEVEL *w_current, OBJECT *o_current) 
  {
  #if DEBUG
    printf("o_picture_draw_grips called\n");
  #endif
    if (w_current->draw_grips == FALSE)
  	  return;
  
    /* grip on upper left corner (whichone = PICTURE_UPPER_LEFT) */
    o_grips_draw(w_current,
  			   o_current->picture->screen_upper_x,
  			   o_current->picture->screen_upper_y);
  
    /* grip on upper right corner (whichone = PICTURE_UPPER_RIGHT) */
    o_grips_draw(w_current,
  			   o_current->picture->screen_lower_x,
  			   o_current->picture->screen_upper_y);
    
    /* grip on lower left corner (whichone = PICTURE_LOWER_LEFT) */
    o_grips_draw(w_current,
  			   o_current->picture->screen_upper_x,
  			   o_current->picture->screen_lower_y);
  
    /* grip on lower right corner (whichone = PICTURE_LOWER_RIGHT) */
    o_grips_draw(w_current,
  			   o_current->picture->screen_lower_x,
  			   o_current->picture->screen_lower_y);
  
    /* Box surrounding the picture */
    gdk_draw_rectangle(w_current->window, w_current->gc, FALSE, 
  		     o_current->picture->screen_upper_x, o_current->picture->screen_upper_y,
  		     abs(o_current->picture->screen_upper_x - o_current->picture->screen_lower_x),
  		     abs(o_current->picture->screen_upper_y - o_current->picture->screen_lower_y));
    gdk_draw_rectangle(w_current->backingstore, w_current->gc, FALSE, 
  		     o_current->picture->screen_upper_x, o_current->picture->screen_upper_y,
  		     abs(o_current->picture->screen_upper_x - o_current->picture->screen_lower_x),
  		     abs(o_current->picture->screen_upper_y - o_current->picture->screen_lower_y));
  }
  
  @ %def o_picture_draw_grips
  
  
  @section Function [[o_picture_erase_grips()]]
  
  @defun o_picture_erase_grips
  This function erases the four grips displayed on the [[*o_current]] picture object. These grips are on each of the corner.
  @end defun
  
  <<o_picture.c : o_picture_erase_grips()>>=
  void
  o_picture_erase_grips(TOPLEVEL *w_current, OBJECT *o_current) 
  {
  #if DEBUG
    printf("o_picture_erase_grips called\n");
  #endif
    if (w_current->draw_grips == FALSE)
  	  return;
  
    /* grip on upper left corner (whichone = PICTURE_UPPER_LEFT) */
    o_grips_erase(w_current,
  				o_current->picture->screen_upper_x,
  				o_current->picture->screen_upper_y);
  
    /* grip on upper right corner (whichone = PICTURE_UPPER_RIGHT) */
    o_grips_erase(w_current,
  				o_current->picture->screen_lower_x,
  				o_current->picture->screen_upper_y);
    
    /* grip on lower left corner (whichone = PICTURE_LOWER_LEFT) */
    o_grips_erase(w_current,
  				o_current->picture->screen_upper_x,
  				o_current->picture->screen_lower_y);
  
    /* grip on lower right corner (whichone = PICTURE_LOWER_RIGHT) */
    o_grips_erase(w_current,
  				o_current->picture->screen_lower_x,
  				o_current->picture->screen_lower_y);
  
    /* Box surrounding the picture */
    gdk_draw_rectangle(w_current->window, w_current->gc, FALSE, 
  		     o_current->picture->screen_upper_x, o_current->picture->screen_upper_y,
  		     abs(o_current->picture->screen_upper_x - o_current->picture->screen_lower_x),
  		     abs(o_current->picture->screen_upper_y - o_current->picture->screen_lower_y));
    gdk_draw_rectangle(w_current->backingstore, w_current->gc, FALSE, 
  		     o_current->picture->screen_upper_x, o_current->picture->screen_upper_y,
  		     abs(o_current->picture->screen_upper_x - o_current->picture->screen_lower_x),
  		     abs(o_current->picture->screen_upper_y - o_current->picture->screen_lower_y));
  
    
  }
  
  @ %def o_picture_erase_grips
  
  @section Function [[o_picture_erase]]
  
  @defun o_picture_erase w_current o_current
  This function erases a picture, described in a [[OBJECT]] structure pointed by [[o_current]].
  @end defun
  
  It makes a call to the function [[o_picture_draw()]] after setting the special color. Therefore a picture is drawn with background color over the previous one.
  
  <<o_picture.c : o_picture_erase()>>=
  void
  o_picture_erase(TOPLEVEL *w_current, OBJECT *o_current)
  {
  #if DEBUG
    printf("o_picture_erase called\n");
  #endif
      gdk_gc_set_foreground(w_current->gc,
                            x_get_color(w_current->background_color));
      w_current->override_color = w_current->background_color;
      o_picture_draw(w_current, o_current);
      w_current->override_color = -1;
  }
  
  @ %def o_picture_erase
  
  @section Function [[o_picture_draw_xor]]
  
  @defun o_picture_draw_xor w_current dx dy o_current
  This function daws the picture object described by [[*o_current]] translated by the vector ([[dx]],[[dy]]) with an xor-function over the current sheet.
  The translation vector is in screen unit.
  @end defun
  
  The picture is displayed with the color of the object.
  
  <<o_picture.c : o_picture_draw_xor()>>=
  void
  o_picture_draw_xor(TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current)
  {
    int screen_x1, screen_y1;
    int screen_x2, screen_y2;
    int color;
  
  #if DEBUG
    printf("o_picture_draw_xor called.\n");
  #endif
    if (o_current->picture == NULL) {
      return;
    }
  
    screen_x1 = o_current->picture->screen_upper_x;
    screen_y1 = o_current->picture->screen_upper_y;
    screen_x2 = o_current->picture->screen_lower_x;
    screen_y2 = o_current->picture->screen_lower_y;
  
    if (o_current->saved_color != -1) {
      color = o_current->saved_color;
    } else {
      color = o_current->color;
    }
    
    gdk_gc_set_foreground(w_current->outline_xor_gc,
                          x_get_darkcolor(color));
    
    gdk_draw_rectangle(w_current->window,
                       w_current->outline_xor_gc, FALSE,
                       screen_x1 + dx,
                       screen_y1 + dy,
                       abs(screen_x2 - screen_x1),
                       abs(screen_y2 - screen_y1));
  }
  
  @ %def o_picture_draw_xor