void dump_code_vars() { int i; GtkTextIter aniter; GtkTextMark *mark; GdkRectangle coderect; int vbuf_start, vbuf_end; printf("+++ CODE +++\n"); printf("selected_code_line=%d, Selected_Code_Addr=%04X, Code_Selected=%d\n", selected_code_line, Selected_Code_Addr, Code_Selected); printf("ram=%04X, SP=%04X, PC=%04X\n", (WORD)ram, (WORD)(STACK - ram), (WORD)(PC - ram)); do_break("\n"); // printf("Codeline table\n"); // for (i = 0; i < 4; i++) // printf("addr=%04X line=%d\n", i, codelines[i]); gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(codetext), &coderect); gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(codetext), &aniter, coderect.y, NULL); vbuf_start = gtk_text_iter_get_line(&aniter); gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(codetext), &aniter, coderect.y+coderect.height, NULL); vbuf_end = gtk_text_iter_get_line(&aniter); printf("coderect: x=%d y=%d width=%d height=%d\n", coderect.x, coderect.y, coderect.width, coderect.height); printf("visible: start=%d end=%d\n", vbuf_start, vbuf_end); printf("--- CODE ---\n"); }
static std::vector<LineInfo> getLinesInfo(GtkTextView* textView, int height) { std::vector<LineInfo> linesInfo; int y1 = 0; int y2 = height; gtk_text_view_window_to_buffer_coords(textView, GTK_TEXT_WINDOW_LEFT, 0, y1, NULL, &y1); gtk_text_view_window_to_buffer_coords(textView, GTK_TEXT_WINDOW_LEFT, 0, y2, NULL, &y2); GtkTextIter iter; gtk_text_view_get_line_at_y(textView, &iter, y1, NULL); while(!gtk_text_iter_is_end(&iter)) { int y, height; gtk_text_view_get_line_yrange(textView, &iter, &y, &height); int line = gtk_text_iter_get_line(&iter); linesInfo.push_back(LineInfo(line+1, y)); if((y + height) >= y2) { break; } gtk_text_iter_forward_line(&iter); } if(linesInfo.size() == 0) { linesInfo.push_back(LineInfo(1, 1)); } return linesInfo; }
static gboolean on_view_query_tooltip (GtkSourceView *view, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, GtkSourceGutter *gutter) { GtkTextView *text_view = GTK_TEXT_VIEW (view); Renderer *renderer; gint start = 0; gint width = 0; gint y_buf; gint yline; GtkTextIter line_iter; GdkRectangle rect; if (keyboard_mode) { return FALSE; } /* Check cell renderer */ renderer = renderer_at_x (gutter, x, &start, &width); if (!renderer) { return FALSE; } gtk_text_view_window_to_buffer_coords (text_view, gutter->priv->window_type, x, y, NULL, &y_buf); gtk_text_view_get_line_at_y (GTK_TEXT_VIEW (view), &line_iter, y_buf, &yline); if (yline > y_buf) { return FALSE; } get_renderer_rect (gutter, renderer, &line_iter, yline, &rect, start); return gtk_source_gutter_renderer_query_tooltip (renderer->renderer, &line_iter, &rect, x, y, tooltip); }
static gboolean renderer_query_activatable (GtkSourceGutter *gutter, Renderer *renderer, GdkEvent *event, gint x, gint y, GtkTextIter *line_iter, GdkRectangle *rect, gint start) { gint y_buf; gint yline; GtkTextIter iter; GdkRectangle r; if (!renderer) { return FALSE; } gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (gutter->priv->view), gutter->priv->window_type, x, y, NULL, &y_buf); gtk_text_view_get_line_at_y (GTK_TEXT_VIEW (gutter->priv->view), &iter, y_buf, &yline); if (yline > y_buf) { return FALSE; } get_renderer_rect (gutter, renderer, &iter, yline, &r, start); if (line_iter) { *line_iter = iter; } if (rect) { *rect = r; } if (y < r.y || y > r.y + r.height) { return FALSE; } return gtk_source_gutter_renderer_query_activatable (renderer->renderer, &iter, &r, event); }
static VALUE textview_get_line_at_y(VALUE self, VALUE y) { GtkTextIter target_iter; gint line_top; gtk_text_view_get_line_at_y(_SELF(self), &target_iter, NUM2INT(y), &line_top); return rb_ary_new3(2, ITR2RVAL(&target_iter), INT2NUM(line_top)); }
gint gtk_mate_view_last_visible_line (GtkMateView* self) { GdkRectangle rect = {0}; gint bufy; GtkTextIter iter = {0}; gint line; g_return_val_if_fail (self != NULL, 0); gtk_text_view_get_visible_rect ((GtkTextView*) self, &rect); bufy = rect.y + rect.height; gtk_text_view_get_line_at_y ((GtkTextView*) self, &iter, bufy, NULL); line = gtk_text_iter_get_line (&iter); return line; }
CAMLprim value ml_gtk_text_view_get_line_at_y (value tv, value y) { CAMLparam2(tv,y); CAMLlocal1(res); GtkTextIter res1; int res2; gtk_text_view_get_line_at_y(GtkTextView_val(tv),&res1, Int_val(y),&res2); res = alloc_tuple(2); Store_field(res,0,Val_GtkTextIter(&res1)); Store_field(res,1,Val_int(res2)); CAMLreturn(res); }
static gint get_last_visible_line_number (GtkSourceGutterRendererLines *lines) { GtkTextView *view; GdkRectangle visible_rect; GtkTextIter iter; view = gtk_source_gutter_renderer_get_view (GTK_SOURCE_GUTTER_RENDERER (lines)); gtk_text_view_get_visible_rect (view, &visible_rect); gtk_text_view_get_line_at_y (view, &iter, visible_rect.y + visible_rect.height, NULL); gtk_text_iter_forward_line (&iter); return gtk_text_iter_get_line (&iter); }
void Show_Code(BYTE *disas_addr, gboolean force) { BYTE *p, *isabreak; int line, i, pc_line, pc_row, scrollto, win_offset; unsigned int disas_addr_line; char whole_buffer[CODE_LIST_LENGTH*48]; char br_char, pc_char; WORD code_ptr; BYTE *Start_Code_List; GtkTextIter aniter; GtkTextMark *mark; GdkRectangle coderect; gint winx, winy; int vbuf_start, vbuf_end, disas_buff_line; disas_addr_line = codelines[disas_addr - ram]; /* get line from disas addr */ printf("P1: disas_addr_line=%d force=%d buff_lines_start=%ld buff_lines_end=%ld\n", disas_addr_line, force, buff_lines_start, buff_lines_start + CODE_LIST_LENGTH); /* * (1) If 'disas_addr_line' is not in the text buffer rebuild the text buffer. * If 'force' is set, do it anyway. */ if (disas_addr_line < buff_lines_start || disas_addr_line > buff_lines_start + CODE_LIST_LENGTH || force) { buff_lines_start = disas_addr_line - BACKUP_LINES; if (buff_lines_start < 0) buff_lines_start = 0; code_ptr = 0; /* scan the codelines table */ while (codelines[code_ptr] != buff_lines_start) /*..for the new start addr */ code_ptr++; Start_Code_List = code_ptr + ram; /* set disass start addr */ p = Start_Code_List; /* tmp pointer for disass */ whole_buffer[0] = 0; /* rewind to start */ printf("Starting disassembly from %04X (line=%d) PC=%04X (line=%d)\n", (p - ram), disas_addr_line, (PC - ram), codelines[PC - ram]); for (line = 0; line < CODE_LIST_LENGTH; line++) { Disass_Str[0] = 0; isabreak = 0; /* zero if no break */ if ((((BYTE)(*p)) & 0xff) == BREAK_OP) /* possible breakpoint? */ for (i = 0; i < SBSIZE; i++) /* scan all BPs */ if (soft[i].sb_adr == (p - ram)) /* BP here? */ { isabreak = p; /* mark the BP address */ *p = soft[i].sb_oldopc; /* restore the opcode */ } sprintf(tstr, "%04X: ", /* put addr etc @ SOL */ (WORD)(p - ram)); strcat(whole_buffer, tstr); disass(&p, p - ram); /* get Opcode and Disass */ /* DEBUG: show buffered line number and code line number */ sprintf(tstr, "%02d %03d ", line, disas_addr_line + line); strcat(whole_buffer, tstr); if (show_opcodes) /* machine code display? */ { strcat(whole_buffer, Opcode_Str); /* yes - add it */ strcat(whole_buffer, " "); /* and a separator */ } strcat(whole_buffer, Disass_Str); /* add the disas string */ if (isabreak) /* breakpoint to restore? */ *isabreak = BREAK_OP; } gtk_text_buffer_set_text( /* show buffer in the win */ code_textbuffer, whole_buffer, -1); } /* END OF (1) */ /* * At this point we know that disas_addr_line is within the text buffer. * * Now we check to see if it is within the visible lines. * * If not we need to scroll the window so that disas_addr_line is in * the middle of the visible lines. */ /* Find the limits of the visible lines, upper and lower. */ gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(codetext), &coderect); // printf("coderect1: x=%d y=%d width=%d height=%d\n", // coderect.x, coderect.y, coderect.width, coderect.height); gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(codetext), &aniter, coderect.y, NULL); vbuf_start = gtk_text_iter_get_line(&aniter); gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(codetext), &aniter, coderect.y+coderect.height, NULL); vbuf_end = gtk_text_iter_get_line(&aniter) - 1; // printf("visible (modified): start=%d end=%d\n", vbuf_start, vbuf_end); /* Is the target line NOT in the visible window? */ disas_buff_line = disas_addr_line - buff_lines_start; // printf("Checking for %d between %d and %d\n", // disas_buff_line, vbuf_start, vbuf_end); if ( !(disas_buff_line >= vbuf_start && disas_buff_line <= vbuf_end ) ) { if (disas_buff_line <= vbuf_start) /* backing up or down? */ { scrollto = disas_buff_line - BACKUP_LINES; if (scrollto < 0) scrollto = 0; } else scrollto = disas_buff_line + BACKUP_LINES; // printf("scrolling to %d\n", scrollto); gtk_text_buffer_get_end_iter(code_textbuffer, &aniter); gtk_text_iter_set_line(&aniter, scrollto); mark = gtk_text_buffer_create_mark(code_textbuffer, NULL, &aniter, FALSE); gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(codetext), mark, 0.0, FALSE, 0.0, 0.0); } // printf("p1: dch\n"); do_code_highlights(); }
static void get_lines (GtkTextView *text_view, gint y1, gint y2, GArray *buffer_coords, GArray *numbers, gint *countp) { GtkTextIter iter; gint count; gint size; gint last_line_num; g_array_set_size (buffer_coords, 0); g_array_set_size (numbers, 0); /* Get iter at first y */ gtk_text_view_get_line_at_y (text_view, &iter, y1, NULL); /* For each iter, get its location and add it to the arrays. * Stop when we pass y2 */ count = 0; size = 0; while (!gtk_text_iter_is_end (&iter)) { gint y, height; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (buffer_coords, y); last_line_num = gtk_text_iter_get_line (&iter); g_array_append_val (numbers, last_line_num); ++count; if ((y + height) >= y2) break; gtk_text_iter_forward_line (&iter); } if (gtk_text_iter_is_end (&iter)) { gint y, height; gint line_num; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); line_num = gtk_text_iter_get_line (&iter); if (line_num != last_line_num) { g_array_append_val (buffer_coords, y); g_array_append_val (numbers, line_num); ++count; } } *countp = count; }
/* This function is taken and adapted from gtk+/tests/testtext.c */ static LinesInfo * get_lines_info (GtkTextView *text_view, gint first_y_buffer_coord, gint last_y_buffer_coord) { LinesInfo *info; GtkTextIter iter; gint last_line_num = -1; info = lines_info_new (); /* Get iter at first y */ gtk_text_view_get_line_at_y (text_view, &iter, first_y_buffer_coord, NULL); info->start = iter; /* For each iter, get its location and add it to the arrays. * Stop when we pass last_y_buffer_coord. */ while (!gtk_text_iter_is_end (&iter)) { gint y; gint height; gint line_num; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (info->buffer_coords, y); g_array_append_val (info->line_heights, height); info->total_height += height; line_num = gtk_text_iter_get_line (&iter); g_array_append_val (info->line_numbers, line_num); last_line_num = line_num; info->lines_count++; if (last_y_buffer_coord <= (y + height)) { break; } gtk_text_iter_forward_line (&iter); } if (gtk_text_iter_is_end (&iter)) { gint y; gint height; gint line_num; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); line_num = gtk_text_iter_get_line (&iter); if (line_num != last_line_num) { g_array_append_val (info->buffer_coords, y); g_array_append_val (info->line_heights, height); info->total_height += height; g_array_append_val (info->line_numbers, line_num); info->lines_count++; } } if (info->lines_count == 0) { gint y = 0; gint n = 0; gint height; info->lines_count = 1; g_array_append_val (info->buffer_coords, y); g_array_append_val (info->line_numbers, n); gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (info->line_heights, height); info->total_height += height; } info->end = iter; return info; }
static gboolean cb_key_press_event(GtkWidget *view, GdkEventKey *event) { GtkTextBuffer *buffer; GtkTextMark *mark; GtkTextIter iter; GdkRectangle prev_rect; if (check_preedit(view)) return FALSE; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); mark = gtk_text_buffer_get_insert(buffer); gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(view), &iter, &prev_rect); keyval = 0; //g_print("key-press-event: 0x%X\n", event->keyval); switch (event->keyval) { case GDK_Up: // Try [Shift]+[Down]. it works bad. case GDK_Down: if (gtk_text_view_move_mark_onscreen(GTK_TEXT_VIEW(view), mark)) { GdkRectangle iter_rect; gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(view), &iter, &iter_rect); if (iter_rect.y < prev_rect.y) { gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(view), &iter, iter_rect.y - iter_rect.height, NULL); gtk_text_buffer_move_mark(buffer, mark, &iter); } if (!(event->state & GDK_SHIFT_MASK)) { gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_buffer_place_cursor(buffer, &iter); } return TRUE; } break; case GDK_Page_Up: case GDK_Page_Down: if (gtk_text_view_move_mark_onscreen(GTK_TEXT_VIEW(view), mark)) { GdkRectangle visible_rect, iter_rect; gint pos = 0; gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(view), &visible_rect); gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(view), &iter, &iter_rect); if (iter_rect.y < prev_rect.y) pos = 1; if (event->keyval == GDK_Page_Up) gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(view), &iter, iter_rect.y - visible_rect.height + iter_rect.height, NULL); else gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(view), &iter, iter_rect.y + visible_rect.height - iter_rect.height, NULL); gtk_text_buffer_move_mark(buffer, mark, &iter); gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(view), mark, 0, TRUE, 0, pos); if (!(event->state & GDK_SHIFT_MASK)) { gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_buffer_place_cursor(GTK_TEXT_VIEW(view)->buffer, &iter); } return TRUE; } break; case GDK_Return: if (indent_get_state()) { indent_real(view); return TRUE; } break; case GDK_Tab: if (event->state & GDK_CONTROL_MASK) { indent_toggle_tab_width(view); return TRUE; } case GDK_ISO_Left_Tab: if (event->state & GDK_SHIFT_MASK) indent_multi_line_unindent(GTK_TEXT_VIEW(view)->buffer); else if (!check_selection_bound(GTK_TEXT_VIEW(view)->buffer)) break; else indent_multi_line_indent(GTK_TEXT_VIEW(view)->buffer); return TRUE; } keyval = event->keyval; if ((event->state & GDK_CONTROL_MASK) || (event->keyval == GDK_Control_L) || (event->keyval == GDK_Control_R)) { keyval = keyval + 0x10000; //g_print("=================================================\n"); } return FALSE; }
/* This function is taken from gtk+/tests/testtext.c */ static gint get_lines (GtkTextView *text_view, gint first_y, gint last_y, GArray *buffer_coords, GArray *line_heights, GArray *numbers, gint *countp, GtkTextIter *start, GtkTextIter *end) { GtkTextIter iter; gint count; gint last_line_num = -1; gint total_height = 0; g_array_set_size (buffer_coords, 0); g_array_set_size (numbers, 0); if (line_heights != NULL) { g_array_set_size (line_heights, 0); } /* Get iter at first y */ gtk_text_view_get_line_at_y (text_view, &iter, first_y, NULL); /* For each iter, get its location and add it to the arrays. * Stop when we pass last_y */ count = 0; *start = iter; while (!gtk_text_iter_is_end (&iter)) { gint y, height; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (buffer_coords, y); if (line_heights) { g_array_append_val (line_heights, height); } total_height += height; last_line_num = gtk_text_iter_get_line (&iter); g_array_append_val (numbers, last_line_num); ++count; if ((y + height) >= last_y) { break; } gtk_text_iter_forward_line (&iter); } if (gtk_text_iter_is_end (&iter)) { gint y, height; gint line_num; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); line_num = gtk_text_iter_get_line (&iter); if (line_num != last_line_num) { g_array_append_val (buffer_coords, y); if (line_heights) { g_array_append_val (line_heights, height); } total_height += height; g_array_append_val (numbers, line_num); ++count; } } *countp = count; if (count == 0) { gint y = 0; gint n = 0; gint height; *countp = 1; g_array_append_val (buffer_coords, y); g_array_append_val (numbers, n); if (line_heights) { gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (line_heights, height); total_height += height; } } *end = iter; return total_height; }