1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2006 Sebastien Granjoux
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "data_view.h"
23 #include "chunk_view.h"
25 #include "anjuta-marshal.h"
27 #include "sexy-icon-entry.h"
29 #include <glib/gi18n.h>
31 #include <gdk/gdkkeysyms.h>
35 /* Size in pixel of border between text view widget */
36 #define ADDRESS_BORDER 4
37 #define ASCII_BORDER 2
38 #define SCROLLBAR_SPACING 4
49 GtkWidget
*goto_window
;
50 GtkWidget
*goto_entry
;
55 GtkTextBuffer
*adr_buffer
;
56 GtkTextBuffer
*data_buffer
;
57 GtkTextBuffer
*ascii_buffer
;
59 GtkAdjustment
*hadjustment
;
60 GtkAdjustment
*vadjustment
;
62 GtkAdjustment
* view_range
;
63 GtkAdjustment
* buffer_range
;
65 DmaDataBuffer
*buffer
;
76 struct _DmaDataViewClass
78 GtkContainerClass parent_class
;
81 static GtkWidgetClass
*parent_class
= NULL
;
84 *---------------------------------------------------------------------------*/
88 get_widget_char_size (GtkWidget
*widget
, gint
*width
, gint
*height
)
90 PangoFontMetrics
*metrics
;
91 PangoContext
*context
;
92 PangoFontDescription
*font_desc
;
94 font_desc
= pango_font_description_from_string ("Monospace 10");
96 context
= gtk_widget_get_pango_context (widget
);
97 metrics
= pango_context_get_metrics (context
,
98 /*widget->style->font_desc,*/
100 pango_context_get_language (context
));
102 *height
= PANGO_PIXELS (pango_font_metrics_get_ascent (metrics
) +
103 pango_font_metrics_get_descent (metrics
));
104 *width
= (pango_font_metrics_get_approximate_char_width (metrics
) + PANGO_SCALE
- 1) / PANGO_SCALE
;
105 pango_font_metrics_unref (metrics
);
106 pango_font_description_free (font_desc
);
110 /* Goto address window
111 *---------------------------------------------------------------------------*/
114 dma_data_view_goto_window_hide (DmaDataView
*view
)
116 gtk_widget_hide (view
->goto_window
);
117 // gtk_entry_set_text (GTK_ENTRY (view->goto_entry), "");
121 dma_data_view_goto_delete_event (GtkWidget
*widget
,
125 g_return_val_if_fail (GTK_IS_WIDGET (widget
), FALSE
);
127 dma_data_view_goto_window_hide (view
);
133 dma_data_view_goto_key_press_event (GtkWidget
*widget
,
137 g_return_val_if_fail (GTK_IS_WIDGET (widget
), FALSE
);
138 g_return_val_if_fail (IS_DMA_DATA_VIEW (view
), FALSE
);
141 if (event
->keyval
== GDK_Escape
||
142 event
->keyval
== GDK_Tab
||
143 event
->keyval
== GDK_KP_Tab
||
144 event
->keyval
== GDK_ISO_Left_Tab
)
146 dma_data_view_goto_window_hide (view
);
150 /* Goto to address and close window */
151 if (event
->keyval
== GDK_Return
||
152 event
->keyval
== GDK_ISO_Enter
||
153 event
->keyval
== GDK_KP_Enter
)
159 text
= gtk_entry_get_text (GTK_ENTRY (view
->goto_entry
));
160 adr
= strtoul (text
, &end
, 0);
162 if ((*text
!= '\0') && (*end
== '\0'))
164 /* Valid input goto to address */
165 gtk_adjustment_set_value (view
->buffer_range
, adr
);
168 dma_data_view_goto_window_hide (view
);
176 dma_data_view_goto_position_func (DmaDataView
*view
)
180 GdkWindow
*window
= GTK_WIDGET (view
)->window
;
181 GdkScreen
*screen
= gdk_drawable_get_screen (window
);
183 GdkRectangle monitor
;
185 monitor_num
= gdk_screen_get_monitor_at_window (screen
, window
);
186 gdk_screen_get_monitor_geometry (screen
, monitor_num
, &monitor
);
188 gtk_widget_realize (view
->goto_window
);
190 gdk_window_get_origin (window
, &win_x
, &win_y
);
191 x
= MAX(12, win_x
+ 12);
192 y
= MAX(12, win_y
+ 12);
194 gtk_window_move (GTK_WINDOW (view
->goto_window
), x
, y
);
197 /* Cut and paste from gtkwindow.c */
199 send_focus_change (GtkWidget
*widget
,
202 GdkEvent
*fevent
= gdk_event_new (GDK_FOCUS_CHANGE
);
204 g_object_ref (widget
);
207 GTK_WIDGET_SET_FLAGS (widget
, GTK_HAS_FOCUS
);
209 GTK_WIDGET_UNSET_FLAGS (widget
, GTK_HAS_FOCUS
);
211 fevent
->focus_change
.type
= GDK_FOCUS_CHANGE
;
212 fevent
->focus_change
.window
= g_object_ref (widget
->window
);
213 fevent
->focus_change
.in
= in
;
215 gtk_widget_event (widget
, fevent
);
217 g_object_notify (G_OBJECT (widget
), "has-focus");
219 g_object_unref (widget
);
220 gdk_event_free (fevent
);
224 dma_data_view_goto_activate (GtkWidget
*menu_item
,
232 toplevel
= gtk_widget_get_toplevel (GTK_WIDGET (view
));
234 if (view
->goto_window
!= NULL
)
236 if (GTK_WINDOW (toplevel
)->group
)
237 gtk_window_group_add_window (GTK_WINDOW (toplevel
)->group
,
238 GTK_WINDOW (view
->goto_window
));
239 else if (GTK_WINDOW (view
->goto_window
)->group
)
240 gtk_window_group_remove_window (GTK_WINDOW (view
->goto_window
)->group
,
241 GTK_WINDOW (view
->goto_window
));
246 view
->goto_window
= gtk_window_new (GTK_WINDOW_POPUP
);
248 if (GTK_WINDOW (toplevel
)->group
)
249 gtk_window_group_add_window (GTK_WINDOW (toplevel
)->group
,
250 GTK_WINDOW (view
->goto_window
));
252 gtk_window_set_modal (GTK_WINDOW (view
->goto_window
), TRUE
);
253 g_signal_connect (view
->goto_window
, "delete_event",
254 G_CALLBACK (dma_data_view_goto_delete_event
),
256 g_signal_connect (view
->goto_window
, "key_press_event",
257 G_CALLBACK (dma_data_view_goto_key_press_event
),
260 frame
= gtk_frame_new (NULL
);
261 gtk_frame_set_shadow_type (GTK_FRAME (frame
), GTK_SHADOW_ETCHED_IN
);
262 gtk_widget_show (frame
);
263 gtk_container_add (GTK_CONTAINER (view
->goto_window
), frame
);
265 vbox
= gtk_vbox_new (FALSE
, 0);
266 gtk_widget_show (vbox
);
267 gtk_container_add (GTK_CONTAINER (frame
), vbox
);
268 gtk_container_set_border_width (GTK_CONTAINER (vbox
), 3);
271 view
->goto_entry
= sexy_icon_entry_new ();
272 icon
= gtk_image_new_from_stock (GTK_STOCK_JUMP_TO
, GTK_ICON_SIZE_MENU
);
273 sexy_icon_entry_set_icon (SEXY_ICON_ENTRY(view
->goto_entry
),
274 SEXY_ICON_ENTRY_PRIMARY
,
276 gtk_widget_show (view
->goto_entry
);
277 gtk_container_add (GTK_CONTAINER (vbox
),
280 gtk_widget_realize (view
->goto_entry
);
283 dma_data_view_goto_position_func (view
);
284 gtk_entry_set_text (GTK_ENTRY (view
->goto_entry
), "0x");
285 gtk_widget_show (view
->goto_window
);
287 gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view
->address
), FALSE
);
288 gtk_widget_grab_focus (view
->goto_entry
);
289 send_focus_change (view
->goto_entry
, TRUE
);
290 gtk_editable_set_position (GTK_EDITABLE (view
->goto_entry
), -1);
294 *---------------------------------------------------------------------------*/
297 dma_data_view_address_size_request (DmaDataView
*view
,
298 GtkRequisition
*requisition
)
305 layout
= gtk_widget_create_pango_layout(view
->address
, text
);
306 pango_layout_get_pixel_size(layout
, &(requisition
->width
), &(requisition
->height
));
310 pango_layout_get_pixel_size(layout
, &width
, &height
);
311 if (width
> requisition
->width
) requisition
->width
= width
;
312 if (height
> requisition
->height
) requisition
->height
= height
;
313 } while (text
[0] == '9');
314 for (text
[0] = 'A'; text
[0] != 'G'; text
[0]++)
316 pango_layout_get_pixel_size(layout
, &width
, &height
);
317 if (width
> requisition
->width
) requisition
->width
= width
;
318 if (height
> requisition
->height
) requisition
->height
= height
;
320 g_object_unref(G_OBJECT(layout
));
322 requisition
->width
*= sizeof(view
->start
) * 2;
326 dma_data_view_data_size_request (DmaDataView
*view
,
327 GtkRequisition
*requisition
)
329 PangoFontMetrics
*metrics
;
330 PangoContext
*context
;
332 context
= gtk_widget_get_pango_context (view
->data
);
333 metrics
= pango_context_get_metrics (context
,
334 view
->data
->style
->font_desc
,
335 pango_context_get_language (context
));
337 requisition
->height
= PANGO_PIXELS (pango_font_metrics_get_ascent (metrics
) +
338 pango_font_metrics_get_descent (metrics
));
339 requisition
->width
= (pango_font_metrics_get_approximate_char_width (metrics
) + PANGO_SCALE
- 1) / PANGO_SCALE
;
340 pango_font_metrics_unref (metrics
);
344 dma_data_view_ascii_size_request (DmaDataView
*view
,
345 GtkRequisition
*requisition
)
347 PangoFontMetrics
*metrics
;
348 PangoContext
*context
;
350 context
= gtk_widget_get_pango_context (view
->ascii
);
351 metrics
= pango_context_get_metrics (context
,
352 view
->ascii
->style
->font_desc
,
353 pango_context_get_language (context
));
355 requisition
->height
= PANGO_PIXELS (pango_font_metrics_get_ascent (metrics
) +
356 pango_font_metrics_get_descent (metrics
));
357 requisition
->width
= (pango_font_metrics_get_approximate_char_width (metrics
) + PANGO_SCALE
- 1) / PANGO_SCALE
;
359 pango_font_metrics_unref (metrics
);
363 dma_data_view_value_changed (GtkAdjustment
*adj
,
366 view
->start
= ((gulong
)adj
->value
) - (((gulong
)adj
->value
) % view
->bytes_by_line
);
367 dma_data_view_refresh (view
);
371 dma_data_view_populate_popup (GtkTextView
*widget
,
375 GtkWidget
*menu_item
;
378 menu_item
= gtk_menu_item_new ();
379 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu
), menu_item
);
380 gtk_widget_show (menu_item
);
382 /* create goto menu_item. */
383 menu_item
= gtk_menu_item_new_with_mnemonic (_("_Goto address"));
384 g_signal_connect (G_OBJECT (menu_item
), "activate",
385 G_CALLBACK (dma_data_view_goto_activate
), view
);
386 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu
), menu_item
);
387 gtk_widget_show (menu_item
);
391 dma_data_view_size_request (GtkWidget
*widget
,
392 GtkRequisition
*requisition
)
394 DmaDataView
*view
= DMA_DATA_VIEW (widget
);
395 GtkRequisition child_requisition
;
397 gtk_widget_size_request (view
->range
, requisition
);
399 dma_data_view_address_size_request (view
, &child_requisition
);
400 if (child_requisition
.height
> requisition
->height
) requisition
->height
= child_requisition
.height
;
401 requisition
->width
+= child_requisition
.width
;
402 requisition
->width
+= ADDRESS_BORDER
;
404 dma_data_view_data_size_request (view
, &child_requisition
);
405 if (child_requisition
.height
> requisition
->height
) requisition
->height
= child_requisition
.height
;
406 requisition
->width
+= child_requisition
.width
* view
->char_by_byte
;
407 requisition
->width
+= ASCII_BORDER
;
409 dma_data_view_ascii_size_request (view
, &child_requisition
);
410 if (child_requisition
.height
> requisition
->height
) requisition
->height
= child_requisition
.height
;
411 requisition
->width
+= child_requisition
.width
;
413 if (view
->shadow_type
!= GTK_SHADOW_NONE
)
415 requisition
->width
+= 2 * widget
->style
->xthickness
;
416 requisition
->height
+= 2 * widget
->style
->ythickness
;
418 requisition
->width
+= SCROLLBAR_SPACING
;
422 dma_data_view_size_allocate (GtkWidget
*widget
,
423 GtkAllocation
*allocation
)
425 DmaDataView
*view
= DMA_DATA_VIEW (widget
);
426 GtkAllocation child_allocation
;
427 GtkRequisition range_requisition
;
428 GtkRequisition address_requisition
;
429 GtkRequisition data_requisition
;
430 GtkRequisition ascii_requisition
;
435 gboolean need_fill
= FALSE
;
437 gtk_widget_get_child_requisition (view
->range
, &range_requisition
);
438 dma_data_view_address_size_request (view
, &address_requisition
);
439 dma_data_view_data_size_request (view
, &data_requisition
);
440 dma_data_view_ascii_size_request (view
, &ascii_requisition
);
442 /* Compute number of byte per line */
443 width
= allocation
->width
444 - 2 * GTK_CONTAINER (view
)->border_width
445 - (view
->shadow_type
== GTK_SHADOW_NONE
? 0 : 2 * widget
->style
->xthickness
)
449 - range_requisition
.width
450 - address_requisition
.width
451 - data_requisition
.width
* view
->char_by_byte
452 - ascii_requisition
.width
;
454 step
= (ascii_requisition
.width
+ data_requisition
.width
* (view
->char_by_byte
+ 1));
455 for (bytes_by_line
= 1; width
>= step
* bytes_by_line
; bytes_by_line
*= 2)
457 width
-= step
* bytes_by_line
;
460 if (bytes_by_line
!= view
->bytes_by_line
)
463 view
->bytes_by_line
= bytes_by_line
;
466 /* Compute number of line by page */
467 height
= allocation
->height
468 - 2 * GTK_CONTAINER (view
)->border_width
469 - (view
->shadow_type
== GTK_SHADOW_NONE
? 0 : 2 * widget
->style
->ythickness
);
471 if (view
->line_by_page
!= (height
/ address_requisition
.height
))
474 view
->line_by_page
= (height
/ address_requisition
.height
);
477 child_allocation
.y
= allocation
->y
+ GTK_CONTAINER (view
)->border_width
;
478 child_allocation
.height
= MAX (1, (gint
) allocation
->height
- (gint
) GTK_CONTAINER (view
)->border_width
* 2);
481 child_allocation
.x
= allocation
->x
+ allocation
->width
- GTK_CONTAINER (view
)->border_width
- range_requisition
.width
;
482 child_allocation
.width
= range_requisition
.width
;
483 gtk_widget_size_allocate (view
->range
, &child_allocation
);
485 child_allocation
.x
= allocation
->x
+ GTK_CONTAINER (view
)->border_width
;
488 if (view
->shadow_type
!= GTK_SHADOW_NONE
)
490 view
->frame
.x
= allocation
->x
+ GTK_CONTAINER (view
)->border_width
;
491 view
->frame
.y
= allocation
->y
+ GTK_CONTAINER (view
)->border_width
;
492 view
->frame
.width
= allocation
->width
- range_requisition
.width
- SCROLLBAR_SPACING
- 2 * (GTK_CONTAINER (view
)->border_width
);
493 view
->frame
.height
= allocation
->height
- 2 * (GTK_CONTAINER (view
)->border_width
);
494 child_allocation
.x
+= widget
->style
->xthickness
;
495 child_allocation
.y
+= widget
->style
->ythickness
;
496 child_allocation
.height
-= 2 * widget
->style
->ythickness
;
500 child_allocation
.width
= address_requisition
.width
;
501 gtk_widget_size_allocate (view
->address
, &child_allocation
);
502 child_allocation
.x
+= child_allocation
.width
;
504 child_allocation
.x
+= ADDRESS_BORDER
;
508 child_allocation
.width
= (view
->bytes_by_line
* (view
->char_by_byte
+ 1) - 1) * data_requisition
.width
;
509 gtk_widget_size_allocate (view
->data
, &child_allocation
);
510 child_allocation
.x
+= child_allocation
.width
;
512 child_allocation
.x
+= ASCII_BORDER
;
515 child_allocation
.width
= view
->bytes_by_line
* ascii_requisition
.width
;
516 gtk_widget_size_allocate (view
->ascii
, &child_allocation
);
517 child_allocation
.x
+= child_allocation
.width
;
521 view
->buffer_range
->step_increment
= view
->bytes_by_line
;
522 view
->buffer_range
->page_increment
= view
->bytes_by_line
* (view
->line_by_page
- 1);
523 view
->buffer_range
->page_size
= (gulong
)(view
->buffer_range
->upper
) % (view
->bytes_by_line
) + view
->buffer_range
->page_increment
;
525 if (view
->start
+ view
->buffer_range
->page_size
> view
->buffer_range
->upper
)
527 view
->start
= view
->buffer_range
->upper
- view
->buffer_range
->page_size
+ view
->bytes_by_line
- 1;
528 view
->start
-= view
->start
% view
->bytes_by_line
;
530 dma_data_view_refresh (view
);
536 dma_data_view_paint (GtkWidget
*widget
,
539 DmaDataView
*view
= DMA_DATA_VIEW (widget
);
541 if (view
->shadow_type
!= GTK_SHADOW_NONE
)
543 gtk_paint_shadow (widget
->style
, widget
->window
,
544 GTK_STATE_NORMAL
, view
->shadow_type
,
545 area
, widget
, "dma_data_view",
554 dma_data_view_expose (GtkWidget
*widget
,
555 GdkEventExpose
*event
)
557 if (GTK_WIDGET_DRAWABLE (widget
))
559 dma_data_view_paint (widget
, &event
->area
);
561 (* GTK_WIDGET_CLASS (parent_class
)->expose_event
) (widget
, event
);
568 dma_data_view_create_widget (DmaDataView
*view
)
572 PangoFontDescription
*font_desc
;
574 wid
= GTK_WIDGET (view
);
576 GTK_WIDGET_SET_FLAGS (wid
, GTK_NO_WINDOW
);
577 GTK_WIDGET_SET_FLAGS (wid
, GTK_CAN_FOCUS
);
578 gtk_widget_set_redraw_on_allocate (wid
, FALSE
);
580 view
->char_by_byte
= 2;
581 view
->bytes_by_line
= 16;
582 view
->line_by_page
= 16;
584 view
->hadjustment
= NULL
;
585 view
->vadjustment
= NULL
;
587 view
->shadow_type
= GTK_SHADOW_IN
;
589 view
->goto_window
= NULL
;
590 view
->goto_entry
= NULL
;
592 font_desc
= pango_font_description_from_string ("Monospace 10");
594 view
->buffer_range
= GTK_ADJUSTMENT (gtk_adjustment_new (0,
595 dma_data_buffer_get_lower (view
->buffer
),
596 dma_data_buffer_get_upper (view
->buffer
)
598 g_signal_connect (view
->buffer_range
, "value_changed",
599 G_CALLBACK (dma_data_view_value_changed
), view
);
601 gtk_widget_push_composite_child ();
603 wid
= gtk_vscrollbar_new (view
->buffer_range
);
606 gtk_widget_set_parent (wid
, GTK_WIDGET (view
));
607 adj
= view
->view_range
;
608 gtk_widget_show (wid
);
610 wid
= dma_chunk_view_new ();
612 gtk_widget_modify_font (wid
, font_desc
);
613 gtk_widget_set_parent (wid
, GTK_WIDGET (view
));
614 gtk_widget_set_size_request (wid
, -1, 0);
615 gtk_widget_show (wid
);
616 gtk_text_view_set_editable (GTK_TEXT_VIEW (wid
), FALSE
);
618 view
->ascii_buffer
= gtk_text_view_get_buffer (GTK_TEXT_VIEW (wid
));
619 dma_chunk_view_set_scroll_adjustment (DMA_CHUNK_VIEW (wid
), view
->buffer_range
);
620 g_signal_connect (wid
, "populate_popup",
621 G_CALLBACK (dma_data_view_populate_popup
), view
);
623 wid
= dma_chunk_view_new ();
625 gtk_widget_modify_font (wid
, font_desc
);
626 gtk_widget_set_parent (wid
, GTK_WIDGET (view
));
627 gtk_widget_set_size_request (wid
, -1, 0);
628 gtk_widget_show (wid
);
629 gtk_text_view_set_editable (GTK_TEXT_VIEW (wid
), FALSE
);
631 view
->data_buffer
= gtk_text_view_get_buffer (GTK_TEXT_VIEW (wid
));
632 dma_chunk_view_set_scroll_adjustment (DMA_CHUNK_VIEW (wid
), view
->buffer_range
);
633 g_signal_connect (wid
, "populate_popup",
634 G_CALLBACK (dma_data_view_populate_popup
), view
);
636 wid
= dma_chunk_view_new ();
638 gtk_widget_modify_font (wid
, font_desc
);
639 gtk_widget_set_parent (wid
, GTK_WIDGET (view
));
640 gtk_widget_set_size_request (wid
, -1, 0);
641 gtk_widget_show (wid
);
642 gtk_text_view_set_editable (GTK_TEXT_VIEW (wid
), FALSE
);
644 view
->adr_buffer
= gtk_text_view_get_buffer (GTK_TEXT_VIEW (wid
));
645 dma_chunk_view_set_scroll_adjustment (DMA_CHUNK_VIEW (wid
), view
->buffer_range
);
646 g_signal_connect (wid
, "populate_popup",
647 G_CALLBACK (dma_data_view_populate_popup
), view
);
649 gtk_widget_pop_composite_child ();
650 pango_font_description_free (font_desc
);
654 dma_data_view_changed_notify (DmaDataBuffer
* buffer
, gulong lower
, gulong upper
, DmaDataView
*view
)
656 if ((upper
>= view
->start
) && (lower
< (view
->start
+ view
->line_by_page
* view
->bytes_by_line
)))
658 dma_data_view_refresh (view
);
663 *---------------------------------------------------------------------------*/
666 dma_data_view_goto_address (DmaDataView
*view
, const void *address
)
668 gtk_adjustment_set_value (view
->view_range
, (gdouble
)((gulong
)address
));
672 dma_data_view_get_address (DmaDataView
*view
)
674 return view
->address
;
678 dma_data_view_get_data (DmaDataView
*view
)
684 dma_data_view_get_ascii (DmaDataView
*view
)
690 dma_data_view_refresh (DmaDataView
*view
)
696 GtkTextBuffer
*buffer
;
698 /* Save all cursor offset */
699 buffer
= gtk_text_view_get_buffer (GTK_TEXT_VIEW (view
->address
));
700 mark
= gtk_text_buffer_get_insert (buffer
);
701 gtk_text_buffer_get_iter_at_mark (buffer
, &cur
, mark
);
702 offset
= gtk_text_iter_get_offset (&cur
);
704 data
= dma_data_buffer_get_address (view
->buffer
, view
->start
, view
->line_by_page
* view
->bytes_by_line
, view
->bytes_by_line
, sizeof(view
->start
) * 2);
705 gtk_text_buffer_set_text (buffer
, data
, -1);
708 mark
= gtk_text_buffer_get_insert (buffer
);
709 gtk_text_buffer_get_iter_at_mark (buffer
, &cur
, mark
);
710 gtk_text_iter_set_offset (&cur
, offset
);
711 gtk_text_buffer_move_mark_by_name (buffer
, "insert", &cur
);
712 gtk_text_buffer_move_mark_by_name (buffer
, "selection_bound", &cur
);
715 buffer
= gtk_text_view_get_buffer (GTK_TEXT_VIEW (view
->data
));
716 mark
= gtk_text_buffer_get_insert (buffer
);
717 gtk_text_buffer_get_iter_at_mark (buffer
, &cur
, mark
);
718 offset
= gtk_text_iter_get_offset (&cur
);
720 data
= dma_data_buffer_get_data (view
->buffer
, view
->start
, view
->line_by_page
* view
->bytes_by_line
, view
->bytes_by_line
, DMA_HEXADECIMAL_BASE
);
721 gtk_text_buffer_set_text (buffer
, data
, -1);
724 mark
= gtk_text_buffer_get_insert (buffer
);
725 gtk_text_buffer_get_iter_at_mark (buffer
, &cur
, mark
);
726 gtk_text_iter_set_offset (&cur
, offset
);
727 gtk_text_buffer_move_mark_by_name (buffer
, "insert", &cur
);
728 gtk_text_buffer_move_mark_by_name (buffer
, "selection_bound", &cur
);
731 buffer
= gtk_text_view_get_buffer (GTK_TEXT_VIEW (view
->ascii
));
732 mark
= gtk_text_buffer_get_insert (buffer
);
733 gtk_text_buffer_get_iter_at_mark (buffer
, &cur
, mark
);
734 offset
= gtk_text_iter_get_offset (&cur
);
736 data
= dma_data_buffer_get_data (view
->buffer
, view
->start
, view
->line_by_page
* view
->bytes_by_line
, view
->bytes_by_line
, DMA_ASCII_BASE
);
737 gtk_text_buffer_set_text (buffer
, data
, -1);
740 mark
= gtk_text_buffer_get_insert (buffer
);
741 gtk_text_buffer_get_iter_at_mark (buffer
, &cur
, mark
);
742 gtk_text_iter_set_offset (&cur
, offset
);
743 gtk_text_buffer_move_mark_by_name (buffer
, "insert", &cur
);
744 gtk_text_buffer_move_mark_by_name (buffer
, "selection_bound", &cur
);
748 /* GtkContainer functions
749 *---------------------------------------------------------------------------*/
752 dma_data_view_child_type (GtkContainer
*container
)
754 return GTK_TYPE_NONE
;
758 dma_data_view_forall (GtkContainer
*container
,
759 gboolean include_internals
,
760 GtkCallback callback
,
761 gpointer callback_data
)
763 DmaDataView
*view
= DMA_DATA_VIEW (container
);
765 g_return_if_fail (callback
!= NULL
);
767 if (include_internals
)
769 callback (view
->address
, callback_data
);
770 callback (view
->data
, callback_data
);
771 callback (view
->ascii
, callback_data
);
772 callback (view
->range
, callback_data
);
777 /* GtkObject functions
778 *---------------------------------------------------------------------------*/
781 dma_data_view_destroy (GtkObject
*object
)
785 g_return_if_fail (IS_DMA_DATA_VIEW (object
));
787 view
= DMA_DATA_VIEW (object
);
789 gtk_widget_unparent (view
->address
);
790 gtk_widget_destroy (view
->address
);
791 gtk_widget_unparent (view
->data
);
792 gtk_widget_destroy (view
->data
);
793 gtk_widget_unparent (view
->ascii
);
794 gtk_widget_destroy (view
->ascii
);
795 gtk_widget_unparent (view
->range
);
796 gtk_widget_destroy (view
->range
);
798 if (view
->goto_window
)
800 gtk_widget_destroy (view
->goto_window
);
801 view
->goto_window
= NULL
;
802 view
->goto_entry
= NULL
;
805 GTK_OBJECT_CLASS (parent_class
)->destroy (object
);
810 *---------------------------------------------------------------------------*/
812 /* dispose is the first destruction step. It is used to unref object created
813 * with instance_init in order to break reference counting cycles. This
814 * function could be called several times. All function should still work
815 * after this call. It has to called its parents.*/
818 dma_data_view_dispose (GObject
*object
)
820 DmaDataView
*view
= DMA_DATA_VIEW (object
);
822 if (view
->buffer
!= NULL
)
824 g_signal_handlers_disconnect_by_func (view
->buffer
,
825 dma_data_view_changed_notify
,
827 g_object_unref (view
->buffer
);
831 G_OBJECT_CLASS (parent_class
)->dispose (object
);
834 /* finalize is the last destruction step. It must free all memory allocated
835 * with instance_init. It is called only one time just before releasing all
839 dma_data_view_finalize (GObject
*object
)
841 DmaDataView
*view
= DMA_DATA_VIEW (object
);
843 g_object_unref (view
->address
);
844 g_object_unref (view
->data
);
845 g_object_unref (view
->ascii
);
846 g_object_unref (view
->range
);
848 G_OBJECT_CLASS (parent_class
)->finalize (object
);
851 /* instance_init is the constructor. All functions should work after this
855 dma_data_view_instance_init (DmaDataView
*view
)
860 /* class_init intialize the class itself not the instance */
863 dma_data_view_class_init (DmaDataViewClass
* klass
)
865 GObjectClass
*gobject_class
;
866 GtkObjectClass
*object_class
;
867 GtkWidgetClass
*widget_class
;
868 GtkContainerClass
*container_class
;
870 g_return_if_fail (klass
!= NULL
);
872 gobject_class
= G_OBJECT_CLASS (klass
);
873 object_class
= GTK_OBJECT_CLASS (klass
);
874 widget_class
= GTK_WIDGET_CLASS (klass
);
875 container_class
= GTK_CONTAINER_CLASS (klass
);
876 parent_class
= GTK_WIDGET_CLASS (g_type_class_peek_parent (klass
));
878 gobject_class
->dispose
= dma_data_view_dispose
;
879 gobject_class
->finalize
= dma_data_view_finalize
;
881 object_class
->destroy
= dma_data_view_destroy
;
883 widget_class
->size_request
= dma_data_view_size_request
;
884 widget_class
->size_allocate
= dma_data_view_size_allocate
;
885 widget_class
->expose_event
= dma_data_view_expose
;
887 container_class
->forall
= dma_data_view_forall
;
888 container_class
->child_type
= dma_data_view_child_type
;
893 dma_data_view_get_type (void)
895 static GType type
= 0;
899 static const GTypeInfo type_info
=
901 sizeof (DmaDataViewClass
),
902 (GBaseInitFunc
) NULL
,
903 (GBaseFinalizeFunc
) NULL
,
904 (GClassInitFunc
) dma_data_view_class_init
,
905 (GClassFinalizeFunc
) NULL
,
906 NULL
, /* class_data */
907 sizeof (DmaDataView
),
909 (GInstanceInitFunc
) dma_data_view_instance_init
,
910 NULL
/* value_table */
913 type
= g_type_register_static (GTK_TYPE_CONTAINER
,
914 "DmaDataView", &type_info
, 0);
920 /* Creation and Destruction
921 *---------------------------------------------------------------------------*/
924 dma_data_view_new_with_buffer (DmaDataBuffer
* buffer
)
928 view
= g_object_new (DMA_DATA_VIEW_TYPE
, NULL
);
929 g_assert (view
!= NULL
);
931 view
->buffer
= buffer
;
932 g_object_ref (buffer
);
934 g_signal_connect (G_OBJECT (buffer
),
936 G_CALLBACK (dma_data_view_changed_notify
),
939 dma_data_view_create_widget (view
);
941 return GTK_WIDGET (view
);
945 dma_data_view_free (DmaDataView
*view
)
947 g_object_unref (view
);