Integrate adding files with the file manager
[anjuta-git-plugin.git] / plugins / debug-manager / data_view.c
blob63aa290be1e6e7705c059a74c428959b12caad08
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 data_view.c
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>
33 #include <stdlib.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
40 struct _DmaDataView
42 GtkContainer parent;
44 GtkWidget *address;
45 GtkWidget *data;
46 GtkWidget *ascii;
47 GtkWidget *range;
49 GtkWidget *goto_window;
50 GtkWidget *goto_entry;
52 guint16 shadow_type;
53 GtkAllocation frame;
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;
67 gulong start;
69 guint bytes_by_line;
70 guint line_by_page;
71 guint char_by_byte;
72 guint char_height;
73 guint char_width;
76 struct _DmaDataViewClass
78 GtkContainerClass parent_class;
81 static GtkWidgetClass *parent_class = NULL;
83 /* Helper functions
84 *---------------------------------------------------------------------------*/
86 #if 0
87 static void
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,*/
99 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);
108 #endif
110 /* Goto address window
111 *---------------------------------------------------------------------------*/
113 static void
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), "");
120 static gboolean
121 dma_data_view_goto_delete_event (GtkWidget *widget,
122 GdkEventAny *event,
123 DmaDataView *view)
125 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
127 dma_data_view_goto_window_hide (view);
129 return TRUE;
132 static gboolean
133 dma_data_view_goto_key_press_event (GtkWidget *widget,
134 GdkEventKey *event,
135 DmaDataView *view)
137 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
138 g_return_val_if_fail (IS_DMA_DATA_VIEW (view), FALSE);
140 /* Close window */
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);
147 return TRUE;
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)
155 gulong adr;
156 const gchar *text;
157 gchar *end;
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);
169 return TRUE;
172 return FALSE;
175 static void
176 dma_data_view_goto_position_func (DmaDataView *view)
178 gint x, y;
179 gint win_x, win_y;
180 GdkWindow *window = GTK_WIDGET (view)->window;
181 GdkScreen *screen = gdk_drawable_get_screen (window);
182 gint monitor_num;
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 */
198 static void
199 send_focus_change (GtkWidget *widget,
200 gboolean in)
202 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
204 g_object_ref (widget);
206 if (in)
207 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
208 else
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);
223 static void
224 dma_data_view_goto_activate (GtkWidget *menu_item,
225 DmaDataView *view)
227 GtkWidget *toplevel;
228 GtkWidget *frame;
229 GtkWidget *vbox;
230 GtkWidget *icon;
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));
244 else
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),
255 view);
256 g_signal_connect (view->goto_window, "key_press_event",
257 G_CALLBACK (dma_data_view_goto_key_press_event),
258 view);
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);
270 /* add entry */
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,
275 GTK_IMAGE (icon));
276 gtk_widget_show (view->goto_entry);
277 gtk_container_add (GTK_CONTAINER (vbox),
278 view->goto_entry);
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);
293 /* Private functions
294 *---------------------------------------------------------------------------*/
296 static void
297 dma_data_view_address_size_request (DmaDataView *view,
298 GtkRequisition *requisition)
300 PangoLayout *layout;
301 char text[] = "0";
302 int width;
303 int height;
305 layout = gtk_widget_create_pango_layout(view->address, text);
306 pango_layout_get_pixel_size(layout, &(requisition->width), &(requisition->height));
309 text[0]++;
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;
325 static void
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);
343 static void
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);
362 static void
363 dma_data_view_value_changed (GtkAdjustment *adj,
364 DmaDataView *view)
366 view->start = ((gulong)adj->value) - (((gulong)adj->value) % view->bytes_by_line);
367 dma_data_view_refresh (view);
370 static void
371 dma_data_view_populate_popup (GtkTextView *widget,
372 GtkMenu *menu,
373 DmaDataView *view)
375 GtkWidget *menu_item;
377 /* separator */
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);
390 static void
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;
421 static void
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;
431 gint width;
432 gint height;
433 gint bytes_by_line;
434 gint step;
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)
446 - ADDRESS_BORDER
447 - ASCII_BORDER
448 - SCROLLBAR_SPACING
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)
462 need_fill = TRUE;
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))
473 need_fill = TRUE;
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);
480 /* Scroll bar */
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;
487 /* Frame */
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;
499 /* Address */
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;
506 /* Data */
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;
514 /* Ascii */
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;
519 if (need_fill)
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);
535 static void
536 dma_data_view_paint (GtkWidget *widget,
537 GdkRectangle *area)
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",
546 view->frame.x,
547 view->frame.y,
548 view->frame.width,
549 view->frame.height);
553 static gint
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);
564 return FALSE;
567 static void
568 dma_data_view_create_widget (DmaDataView *view)
570 GtkAdjustment *adj;
571 GtkWidget* wid;
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)
597 ,1,4,4));
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);
604 g_object_ref (wid);
605 view->range = wid;
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 ();
611 g_object_ref (wid);
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);
617 view->ascii = wid;
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 ();
624 g_object_ref (wid);
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);
630 view->data = wid;
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 ();
637 g_object_ref (wid);
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);
643 view->address = wid;
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);
653 static void
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);
662 /* Public functions
663 *---------------------------------------------------------------------------*/
665 void
666 dma_data_view_goto_address (DmaDataView *view, const void *address)
668 gtk_adjustment_set_value (view->view_range, (gdouble)((gulong)address));
671 GtkWidget *
672 dma_data_view_get_address (DmaDataView *view)
674 return view->address;
677 GtkWidget *
678 dma_data_view_get_data (DmaDataView *view)
680 return view->data;
683 GtkWidget *
684 dma_data_view_get_ascii (DmaDataView *view)
686 return view->ascii;
689 void
690 dma_data_view_refresh (DmaDataView *view)
692 gchar *data = "";
693 gint offset;
694 GtkTextIter cur;
695 GtkTextMark *mark;
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);
706 g_free (data);
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);
722 g_free (data);
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);
738 g_free (data);
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 *---------------------------------------------------------------------------*/
751 static GType
752 dma_data_view_child_type (GtkContainer *container)
754 return GTK_TYPE_NONE;
757 static void
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 *---------------------------------------------------------------------------*/
780 static void
781 dma_data_view_destroy (GtkObject *object)
783 DmaDataView *view;
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);
809 /* GObject functions
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.*/
817 static void
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,
826 view);
827 g_object_unref (view->buffer);
828 view->buffer = NULL;
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
836 * memory */
838 static void
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
852 * call. */
854 static void
855 dma_data_view_instance_init (DmaDataView *view)
857 view->buffer = NULL;
860 /* class_init intialize the class itself not the instance */
862 static void
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;
892 GType
893 dma_data_view_get_type (void)
895 static GType type = 0;
897 if (!type)
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),
908 0, /* n_preallocs */
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);
917 return type;
920 /* Creation and Destruction
921 *---------------------------------------------------------------------------*/
923 GtkWidget*
924 dma_data_view_new_with_buffer (DmaDataBuffer* buffer)
926 DmaDataView *view;
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),
935 "changed_notify",
936 G_CALLBACK (dma_data_view_changed_notify),
937 view);
939 dma_data_view_create_widget (view);
941 return GTK_WIDGET (view);
944 void
945 dma_data_view_free (DmaDataView *view)
947 g_object_unref (view);