static void dma_sparse_view_set_scroll_adjustments (GtkTextView *text_view, GtkAdjustment *hadj, GtkAdjustment *vadj) { DmaSparseView *view = DMA_SPARSE_VIEW (text_view); if (vadj) g_return_if_fail (GTK_IS_ADJUSTMENT (vadj)); if (view->priv->vadjustment && (view->priv->vadjustment != vadj)) { g_signal_handlers_disconnect_by_func (view->priv->vadjustment, dma_sparse_view_value_changed, view); g_object_unref (view->priv->vadjustment); } if (view->priv->vadjustment != vadj) { GTK_TEXT_VIEW_CLASS (parent_class)->set_scroll_adjustments (GTK_TEXT_VIEW (view), hadj, NULL); if (vadj != NULL) { g_object_ref_sink (vadj); g_signal_connect (vadj, "value_changed", G_CALLBACK (dma_sparse_view_value_changed), view); gtk_adjustment_set_upper (vadj, dma_sparse_buffer_get_upper (view->priv->buffer)); gtk_adjustment_set_lower (vadj, dma_sparse_buffer_get_lower (view->priv->buffer)); gtk_adjustment_set_value (vadj, 0); } view->priv->vadjustment = vadj; dma_sparse_view_update_adjustement (view); } }
static gboolean dma_disassembly_iter_refresh (DmaSparseIter *iter) { /* Call this after updating node according to base */ gint line = -1; DmaDisassemblyBufferNode *node = (DmaDisassemblyBufferNode *)iter->node; if (iter->node != NULL) { /* Find line corresponding to base */ if ((iter->node->lower <= iter->base) && (iter->base <= iter->node->upper)) { /* Iterator in current node */ if ((iter->line >= 0) && (iter->line < ((DmaDisassemblyBufferNode *)iter->node)->size) && (((DmaDisassemblyBufferNode *)iter->node)->data[iter->line].address == iter->base)) { /* Already get the right node */ line = iter->line; } else { /* Search for correct line */ if (iter->offset >= 0) { for (line = 0; line < node->size; line++) { if (node->data[line].address >= iter->base) break; } } else { for (line = node->size - 1; line >= 0; line--) { if (node->data[line].address <= iter->base) break; } } if (node->data[line].address == iter->base) { iter->line = line; } else if (iter->line >= DMA_DISASSEMBLY_VALID_ADDRESS) { iter->line = iter->offset == 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS : DMA_DISASSEMBLY_UNKNOWN_ADDRESS; } } } else if (iter->base == iter->node->upper + 1) { line = node->size; if (iter->line >= DMA_DISASSEMBLY_VALID_ADDRESS) { iter->line = iter->offset == 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS : DMA_DISASSEMBLY_UNKNOWN_ADDRESS; } } else { /* Invalid base address */ if (iter->line >= DMA_DISASSEMBLY_VALID_ADDRESS) { iter->line = iter->offset == 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS : DMA_DISASSEMBLY_UNKNOWN_ADDRESS; } } } else { /* Invalid base address */ if (iter->line >= DMA_DISASSEMBLY_VALID_ADDRESS) { iter->line = iter->offset == 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS : DMA_DISASSEMBLY_UNKNOWN_ADDRESS; } } /* Try to reduce offset */ if (line != -1) { if (iter->offset > 0) { /* Need to go upper if possible */ guint up = (DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH + iter->offset - 1)/ DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH; for (;;) { gint len = node->size - line; if (up < len) { iter->node = (DmaSparseBufferNode *)node; iter->line = line + up; iter->base = node->data[iter->line].address; iter->offset = 0; return TRUE; } if (iter->node->upper == dma_sparse_buffer_get_upper (iter->buffer)) { gboolean move = iter->line != node->size - 1; iter->node = (DmaSparseBufferNode *)node; iter->line = node->size - 1; iter->base = node->data[iter->line].address; iter->offset = 0; return move; } up -= len; if ((node->parent.next == NULL) || (node->parent.upper != node->parent.next->lower - 1)) { /* No following node */ iter->node = (DmaSparseBufferNode *)node; iter->base = node->parent.upper + 1; iter->offset = up * DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH; if (iter->line >= DMA_DISASSEMBLY_VALID_ADDRESS) { iter->line = iter->offset == 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS : DMA_DISASSEMBLY_UNKNOWN_ADDRESS; } break; } node = (DmaDisassemblyBufferNode *)node->parent.next; line = 0; } } else if (iter->offset < 0) { /* Need to go down if possible */ gint down = (- iter->offset) / DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH; for (;;) { guint len = line; if (down <= len) { iter->node = (DmaSparseBufferNode *)node; iter->line = line - down; iter->base = node->data[iter->line].address; iter->offset = 0; return TRUE; } if (iter->node->lower == dma_sparse_buffer_get_lower (iter->buffer)) { gboolean move = iter->line != 0; iter->node = (DmaSparseBufferNode *)node; iter->line = 0; iter->base = node->data[0].address; iter->offset = 0; return move; } down -= len; if ((node->parent.prev == NULL) || (node->parent.lower != node->parent.prev->upper + 1)) { /* No following node */ iter->node = (DmaSparseBufferNode *)node; iter->base = node->parent.lower; iter->offset = -down * DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH; if (iter->line >= DMA_DISASSEMBLY_VALID_ADDRESS) { iter->line = iter->offset == 0 ? DMA_DISASSEMBLY_KNOW_ADDRESS : DMA_DISASSEMBLY_UNKNOWN_ADDRESS; } break; } node = (DmaDisassemblyBufferNode *)node->parent.prev; line = node->size; } } } /* Round offset */ if (iter->offset < 0) { gulong address; gboolean move = TRUE; address = iter->offset + iter->base; if ((address < dma_sparse_buffer_get_lower (iter->buffer)) || (address > iter->base)) { address = dma_sparse_buffer_get_lower (iter->buffer); move = FALSE; } address -= address % DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH; iter->offset = address - iter->base; return move; } else if ((iter->offset > 0) || (iter->line == DMA_DISASSEMBLY_UNKNOWN_ADDRESS)) { gulong address; gboolean move = TRUE; address = iter->offset + iter->base; if ((address > dma_sparse_buffer_get_upper (iter->buffer)) || (address < iter->base)) { address = dma_sparse_buffer_get_upper (iter->buffer); move = FALSE; } address -= address % DMA_DISASSEMBLY_DEFAULT_LINE_LENGTH; iter->offset = address - iter->base; return move; } /* return FALSE if iterator reach the lower or upper limit */ return TRUE; }