gint motion_notify_event(GtkWidget *widget, GdkEventMotion *event) { gint x, y; GdkModifierType mask; GtkTextIter iter; guint offset; gint buffer_x, buffer_y; GdkRectangle location; gboolean too_far=FALSE; #ifdef __WIN32__ HCURSOR hCursor; #else GdkCursor *cursor; #endif // LOG(LOG_DEBUG, "IN : motion_notify_event(x=%f,y=%f (%d %d))", event->x, event->y, buffer_x, buffer_y); // If you don't convert position as buffer origin, // position will be invalid when scrolling gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT, (gint)(event->x), (gint)(event->y), &buffer_x, &buffer_y); gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget), &iter, buffer_x, buffer_y); offset = gtk_text_iter_get_offset(&iter); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(widget), &iter, &location); if((buffer_x > location.x + font_width) || (buffer_x < location.x - font_width)) too_far = TRUE; else too_far = FALSE; #ifdef __WIN32__ if(scan_link(offset) && !too_far){ hCursor = LoadCursor(NULL, IDC_HAND); // Because IDC_HAND can not be used in NT if(hCursor == 0) hCursor = LoadCursor(NULL, IDC_ARROW); } else { hCursor = LoadCursor(NULL, IDC_IBEAM); } SetCursor(hCursor); #else if(scan_link(offset) && !too_far){ cursor = gdk_cursor_new (CURSOR_LINK); } else { cursor = gdk_cursor_new(CURSOR_NORMAL); } gdk_window_set_cursor(gtk_text_view_get_window(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT), cursor); gdk_cursor_unref(cursor); gdk_window_get_pointer(widget->window, &x, &y, &mask); #endif // LOG(LOG_DEBUG, "OUT : motion_notify_event()"); if(event->state & GDK_BUTTON1_MASK) return(FALSE); else return(TRUE); }
static void dma_sparse_view_paint_margin (DmaSparseView *view, GdkEventExpose *event) { GtkTextView *text_view; GdkWindow *win; PangoLayout *layout; gint y1, y2; gint y, height; gchar str [16]; gint margin_width; gint margin_length; gint text_width; DmaSparseIter buf_iter; GtkTextIter text_iter; guint prev_address = G_MAXUINT; text_view = GTK_TEXT_VIEW (view); if (!view->priv->show_line_numbers && !view->priv->show_line_markers) { gtk_text_view_set_border_window_size (text_view, GTK_TEXT_WINDOW_LEFT, 0); return; } win = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_LEFT); y1 = event->area.y; y2 = y1 + event->area.height; /* get the extents of the line printing */ gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y1, NULL, &y1); gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y2, NULL, &y2); /* set size. */ g_snprintf (str, sizeof (str), "0x%X", G_MAXUINT); margin_length = strlen(str) - 2; layout = gtk_widget_create_pango_layout (GTK_WIDGET (view), str); pango_layout_get_pixel_size (layout, &text_width, NULL); pango_layout_set_width (layout, text_width); pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); /* determine the width of the left margin. */ if (view->priv->show_line_numbers) margin_width = text_width + 4; else margin_width = 0; if (view->priv->show_line_markers) margin_width += GUTTER_PIXMAP; g_return_if_fail (margin_width != 0); gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_LEFT, margin_width); /* Display all addresses */ dma_sparse_iter_copy (&buf_iter, &view->priv->start); gtk_text_buffer_get_start_iter (gtk_text_view_get_buffer (text_view), &text_iter); /* Skip line while position doesn't need to be repaint */ gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height); if (y < y1) { do { if (!dma_sparse_iter_forward_lines (&buf_iter, 1)) return; if (!gtk_text_iter_forward_line (&text_iter)) return; gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height); } while (y < y1); } /* Display address */ do { gint pos; guint address; gtk_text_view_buffer_to_window_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y, NULL, &pos); address = dma_sparse_iter_get_address (&buf_iter); if (view->priv->show_line_numbers) { g_snprintf (str, sizeof (str),"0x%0*lX", margin_length, (long unsigned int)address); pango_layout_set_markup (layout, str, -1); gtk_paint_layout (gtk_widget_get_style (GTK_WIDGET (view)), win, gtk_widget_get_state (GTK_WIDGET (view)), FALSE, NULL, GTK_WIDGET (view), NULL, text_width + 2, pos, layout); } /* Display marker */ if ((prev_address != address) && (view->priv->show_line_markers)) { gint current_marker = dma_sparse_buffer_get_marks (view->priv->buffer, address); if (current_marker) { gint x; if (view->priv->show_line_numbers) x = text_width + 4; else x = 0; draw_line_markers (view, current_marker, x, pos); prev_address = address; } } if (!dma_sparse_iter_forward_lines (&buf_iter, 1)) return; if (!gtk_text_iter_forward_line (&text_iter)) return; gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height); } while (y < y2); g_object_unref (G_OBJECT (layout)); }
static GdkWindow * get_window (GtkSourceGutter *gutter) { return gtk_text_view_get_window (GTK_TEXT_VIEW (gutter->priv->view), gutter->priv->window_type); }
static void draw_line_markers (DmaSparseView *view, gint current_marker, gint x, gint y) { GdkPixbuf *composite; gint width, height; gint i; composite = NULL; width = height = 0; /* composite all the pixbufs for the markers present at the line */ for (i = 0; i < MAX_MARKER; i++) { if (current_marker & (1 << i)) { GdkPixbuf *pixbuf = view->priv->marker_pixbuf[i]; if (pixbuf) { if (!composite) { composite = gdk_pixbuf_copy (pixbuf); width = gdk_pixbuf_get_width (composite); height = gdk_pixbuf_get_height (composite); } else { gint pixbuf_w; gint pixbuf_h; pixbuf_w = gdk_pixbuf_get_width (pixbuf); pixbuf_h = gdk_pixbuf_get_height (pixbuf); gdk_pixbuf_composite (pixbuf, composite, 0, 0, width, height, 0, 0, (double) pixbuf_w / width, (double) pixbuf_h / height, GDK_INTERP_BILINEAR, COMPOSITE_ALPHA); } //g_object_unref (pixbuf); } else { g_warning ("Unknown marker %d used", i); } current_marker &= ~ (1 << i); if (current_marker == 0) break; } } /* render the result to the left window */ if (composite) { GdkWindow *window; window = gtk_text_view_get_window (GTK_TEXT_VIEW (view), GTK_TEXT_WINDOW_LEFT); gdk_draw_pixbuf (GDK_DRAWABLE (window), NULL, composite, 0, 0, x, y, width, height, GDK_RGB_DITHER_NORMAL, 0, 0); g_object_unref (composite); } }