diff --git a/gtkedit/editdraw.c b/gtkedit/editdraw.c index b3cb6d602..b864e1cf6 100644 --- a/gtkedit/editdraw.c +++ b/gtkedit/editdraw.c @@ -78,7 +78,7 @@ void edit_status (WEdit * edit) widget_move (edit, edit->have_frame, edit->have_frame); i = w > 24 ? 18 : w - 6; i = i < 13 ? 13 : i; - sprintf (s, "%s", name_trunc (edit->filename ? edit->filename : "", i)); + sprintf (s, "%s", (char *) name_trunc (edit->filename ? edit->filename : "", i)); i += strlen (s); s[strlen (s)] = ' '; t = w - 20; @@ -103,8 +103,10 @@ void rerender_text (CWidget * wdt); #ifdef GTK -void edit_status (WEdit *edit) +void edit_status (WEdit * edit) { + GtkEntry *entry; + GtkWidget *widget; int w, i, t; char id[33]; char s[160]; @@ -127,8 +129,9 @@ void edit_status (WEdit *edit) status_string (edit, s + i + 2, t, 0, FONT_MEAN_WIDTH); } s[w] = 0; - if (strcmp (s, GTK_LABEL(edit->widget->status)->label)) - gtk_label_set (GTK_LABEL(edit->widget->status), s); + entry = GTK_ENTRY (edit->widget->status); + if (strcmp (s, gtk_entry_get_text (entry))) + gtk_entry_set_text (entry, s); } #else @@ -467,8 +470,6 @@ void render_edit_text (WEdit * edit, long start_row, long start_column, long end #ifndef MIDNIGHT static unsigned long prev_win = 0; #endif - int fg, bg; - int force = edit->force; long b; diff --git a/gtkedit/editwidget.c b/gtkedit/editwidget.c index a66831af0..ba1c49e54 100644 --- a/gtkedit/editwidget.c +++ b/gtkedit/editwidget.c @@ -25,10 +25,8 @@ #ifndef MIDNIGHT #include /* CARD32 */ #include -#ifndef GTK #include "app_glob.c" #include "coollocal.h" -#endif #include "editcmddef.h" #include "mousemark.h" #endif @@ -51,11 +49,7 @@ void edit_destroy_callback (CWidget * w) CError ("Trying to destroy non-existing editor widget.\n"); } -#ifdef GTK - -#else void link_hscrollbar_to_editor (CWidget * scrollbar, CWidget * editor, XEvent * xevent, CEvent * cwevent, int whichscrbutton); -#endif /* returns the position in the edit buffer of a window click */ long edit_get_click_pos (WEdit * edit, int x, int y) @@ -83,7 +77,7 @@ void edit_translate_xy (int xs, int ys, int *x, int *y) extern int just_dropped_something; -static void mouse_redraw (WEdit * edit, long click) +void mouse_redraw (WEdit * edit, long click) { edit->force |= REDRAW_PAGE | REDRAW_LINE; edit_update_curs_row (edit); @@ -145,20 +139,7 @@ static void release_mark (WEdit * edit, XEvent * event) edit_mark_cmd (edit, 1); if (edit->mark1 != edit->mark2 && event) { edit_get_selection (edit); -#ifdef GTK - { -#if 0 - long start_mark = 0, end_mark = 0; - edit->widget->editable.has_selection = !eval_marks (edit, &start_mark, &end_mark); - edit->widget->editable.selection_start_pos = start_mark; - edit->widget->editable.selection_end_pos = end_mark; - if (edit->widget->editable.has_selection) -#endif - gtk_selection_owner_set (GTK_WIDGET (edit->widget), GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); - } -#else XSetSelectionOwner (CDisplay, XA_PRIMARY, CWindowOf (edit->widget), event->xbutton.time); -#endif } else { edit->widget->editable.has_selection = TRUE; } @@ -211,7 +192,6 @@ char *filename_from_url (char *data, int size, int i) static int insert_drop (WEdit * e, Window from, unsigned char *data, int size, int xs, int ys, Atom type, Atom action) { -#ifndef GTK long start_mark = 0, end_mark = 0; int x, y; @@ -256,7 +236,6 @@ static int insert_drop (WEdit * e, Window from, unsigned char *data, int size, i } } CExpose (e->widget->ident); -#endif return 0; } @@ -284,8 +263,6 @@ struct mouse_funcs edit_mouse_funcs = mime_majors }; -#ifndef GTK - extern int option_editor_bg_normal; void edit_tri_cursor (Window win); @@ -360,17 +337,6 @@ CWidget *CDrawEditor (const char *identifier, Window parent, int x, int y, return w; } -#endif - -#ifdef GTK - -void update_scroll_bars (WEdit * e) -{ - -} - -#else - void update_scroll_bars (WEdit * e) { int i, x1, x2; @@ -412,8 +378,6 @@ void update_scroll_bars (WEdit * e) } } -#endif - void edit_mouse_mark (WEdit * edit, XEvent * event, int double_click) { edit_update_curs_row (edit); @@ -434,10 +398,6 @@ void edit_mouse_mark (WEdit * edit, XEvent * event, int double_click) ); } -#ifdef GTK - -#else - void link_scrollbar_to_editor (CWidget * scrollbar, CWidget * editor, XEvent * xevent, CEvent * cwevent, int whichscrbutton) { int i, start_line; @@ -489,12 +449,6 @@ void link_scrollbar_to_editor (CWidget * scrollbar, CWidget * editor, XEvent * x } } -#endif - -#ifdef GTK - -#else - void link_hscrollbar_to_editor (CWidget * scrollbar, CWidget * editor, XEvent * xevent, CEvent * cwevent, int whichscrbutton) { int i, start_col; @@ -544,8 +498,6 @@ void link_hscrollbar_to_editor (CWidget * scrollbar, CWidget * editor, XEvent * } } -#endif - /* This section comes from rxvt-2.21b1/src/screen.c by Robert Nation & @@ -597,7 +549,6 @@ void selection_send (XSelectionRequestEvent * rq) /*{{{ paste selection */ -#ifndef GTK /* * Respond to a notification that a primary selection has been sent */ @@ -641,8 +592,6 @@ void selection_paste (WEdit * edit, Window win, unsigned prop, int delete) edit->force |= REDRAW_COMPLETELY | REDRAW_LINE; } -#endif - /*}}} */ void selection_clear (void) @@ -670,19 +619,8 @@ void edit_update_screen (WEdit * e) /* pop all events for this window for internal handling */ if (e->force & (REDRAW_CHAR_ONLY | REDRAW_COMPLETELY)) { edit_render_keypress (e); -#ifdef GTK - } else if ( -#if 0 -/* *** */ - gtk_edit_key_pending () || gtk_edit_mouse_pending () -#else - 0 -#endif - ) { -#else } else if (CCheckWindowEvent (e->widget->winid, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, 0) || CKeyPending ()) { -#endif e->force |= REDRAW_PAGE; return; } else { @@ -690,6 +628,7 @@ void edit_update_screen (WEdit * e) } } + extern int space_width; #ifdef HAVE_DND @@ -796,8 +735,6 @@ void handle_client_message (CWidget * w, XEvent * xevent) } #endif -#ifndef GTK - int eh_editor (CWidget * w, XEvent * xevent, CEvent * cwevent) { WEdit *e = w->editor; @@ -909,8 +846,6 @@ int eh_editor (CWidget * w, XEvent * xevent, CEvent * cwevent) return r; } -#endif /* ! GTK */ - #else WEdit *wedit; diff --git a/gtkedit/gtkedit.c b/gtkedit/gtkedit.c index 0d110d9dd..13bc51bf7 100644 --- a/gtkedit/gtkedit.c +++ b/gtkedit/gtkedit.c @@ -40,6 +40,7 @@ #define GDK_FONT_XFONT(font) (((GdkFontPrivate*) font)->xfont) int edit_key_emulation = 0; +int column_highlighting = 0; static GtkWidgetClass *parent_class = NULL; @@ -51,6 +52,7 @@ static void gtk_edit_set_position (GtkEditable *editable, gint position); void edit_mouse_mark (WEdit * edit, XEvent * event, int double_click); void edit_move_to_prev_col (WEdit * edit, long p); int edit_load_file_from_filename (WEdit *edit, char *exp); +static void gtk_edit_set_selection (GtkEditable * editable, gint start, gint end); guchar gtk_edit_font_width_per_char[256]; @@ -298,11 +300,11 @@ static void gtk_edit_destroy (GtkObject * object) gtk_timeout_remove (edit->timer); edit->timer = 0; } - if (edit->funcs) { - free (edit->funcs); + edit_clean (edit->editor); + if (edit->editor) { + free (edit->editor); + edit->editor = NULL; } - edit_destroy_callback (edit); - GTK_OBJECT_CLASS (parent_class)->destroy (object); } @@ -525,16 +527,84 @@ static gint return FALSE; } -static gint - gtk_edit_button_press_release (GtkWidget * widget, - GdkEventButton * event) +void edit_update_screen (WEdit * e) +{ + if (!e) + return; + if (!e->force) + return; + + edit_scroll_screen_over_cursor (e); + edit_update_curs_row (e); + edit_update_curs_col (e); +#if 0 + update_scroll_bars (e); +#endif + edit_status (e); + + if (e->force & REDRAW_COMPLETELY) + e->force |= REDRAW_PAGE; + +/* pop all events for this window for internal handling */ + if (e->force & (REDRAW_CHAR_ONLY | REDRAW_COMPLETELY)) { + edit_render_keypress (e); +#if 0 + } else if (CCheckWindowEvent (e->widget->winid, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, 0) + || CKeyPending ()) { + e->force |= REDRAW_PAGE; + return; +#endif + } else { + edit_render_keypress (e); + } +} + + +void gtk_edit_mouse_redraw (WEdit * edit, long click) +{ + edit->force |= REDRAW_PAGE | REDRAW_LINE; + edit_update_curs_row (edit); + edit_update_curs_col (edit); + edit->prev_col = edit_get_col (edit); + edit_update_screen (edit); + edit->search_start = click; +} + +/* returns the position in the edit buffer of a window click */ +static long edit_get_click_pos (WEdit * edit, int x, int y) +{ + long click; +/* (1) goto to left margin */ + click = edit_bol (edit, edit->curs1); + +/* (1) move up or down */ + if (y > (edit->curs_row + 1)) + click = edit_move_forward (edit, click, y - (edit->curs_row + 1), 0); + if (y < (edit->curs_row + 1)) + click = edit_move_backward (edit, click, (edit->curs_row + 1) - y); + +/* (3) move right to x pos */ + click = edit_move_forward3 (edit, click, x - edit->start_col - 1, 0); + return click; +} + +static void edit_translate_xy (int xs, int ys, int *x, int *y) +{ + *x = xs - EDIT_TEXT_HORIZONTAL_OFFSET; + *y = (ys - EDIT_TEXT_VERTICAL_OFFSET - option_text_line_spacing / 2 - 1) / FONT_PIX_PER_LINE + 1; +} + +static gint gtk_edit_button_press_release (GtkWidget * widget, + GdkEventButton * event) { - int double_click = 0; - XEvent xevent; - GtkEdit *edit; GtkEditable *editable; + GtkEdit *edit; + WEdit *e; static GdkAtom ctext_atom = GDK_NONE; - long start_mark = 0, end_mark = 0; + int x_text = 0, y_text = 0; + long mouse_pos; + static long button_down_pos; + static long dragging = 0; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_EDIT (widget), FALSE); @@ -544,45 +614,73 @@ static gint ctext_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE); edit = GTK_EDIT (widget); + e = edit->editor; editable = GTK_EDITABLE (widget); if (!GTK_WIDGET_HAS_FOCUS (widget)) if (!(event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK))) gtk_widget_grab_focus (widget); + edit_translate_xy (event->x, event->y, &x_text, &y_text); + mouse_pos = edit_get_click_pos (e, x_text, y_text); + switch (event->type) { + case GDK_BUTTON_RELEASE: + if (!dragging) + return FALSE; case GDK_MOTION_NOTIFY: - xevent.type = MotionNotify; + if (mouse_pos == button_down_pos) + return FALSE; + dragging = 1; + edit_cursor_move (e, mouse_pos - e->curs1); + gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, button_down_pos); + gtk_edit_mouse_redraw (e, mouse_pos); break; case GDK_BUTTON_PRESS: - xevent.type = ButtonPress; + dragging = 0; + if (event->button == 2) { + edit_cursor_move (e, mouse_pos - e->curs1); + editable->current_pos = mouse_pos; + gtk_selection_convert (GTK_WIDGET (edit), GDK_SELECTION_PRIMARY, + ctext_atom, event->time); + gtk_edit_mouse_redraw (e, mouse_pos); + editable->selection_start_pos = e->mark1; + editable->selection_end_pos = e->mark2; + return FALSE; + } + button_down_pos = mouse_pos; +#if 0 + if (editable->has_selection) + if (mouse_pos >= editable->selection_start_pos + && mouse_pos < editable->selection_end_pos) + gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, mouse_pos); +#endif + edit_cursor_move (e, mouse_pos - e->curs1); + gtk_edit_mouse_redraw (e, mouse_pos); break; case GDK_2BUTTON_PRESS: - xevent.type = ButtonPress; - double_click = 1; - break; - case GDK_BUTTON_RELEASE: - xevent.type = ButtonRelease; + dragging = 0; + edit_cursor_move (e, mouse_pos - e->curs1); + edit_right_word_move (e); + mouse_pos = e->curs1; + edit_left_word_move (e); + button_down_pos = e->curs1; + gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, button_down_pos); + gtk_edit_mouse_redraw (e, mouse_pos); break; case GDK_3BUTTON_PRESS: + dragging = 0; + mouse_pos = edit_bol (e, mouse_pos); + edit_cursor_move (e, mouse_pos - e->curs1); + button_down_pos = edit_eol (e, mouse_pos) + 1; + gtk_edit_set_selection (GTK_EDITABLE (widget), mouse_pos, button_down_pos); + gtk_edit_mouse_redraw (e, mouse_pos); + break; default: - return FALSE; + dragging = 0; break; } - xevent.xbutton.window = (guint32) event->window; - xevent.xbutton.x = event->x; - xevent.xbutton.y = event->y; - xevent.xbutton.state = event->state; - - edit_mouse_mark (edit->editor, &xevent, double_click); - - editable->current_pos = edit->editor->curs1; - editable->has_selection = !eval_marks (edit->editor, &start_mark, &end_mark); - editable->selection_start_pos = start_mark; - editable->selection_end_pos = end_mark; - if (event->type == GDK_BUTTON_PRESS && event->button == 2) - gtk_selection_convert (GTK_WIDGET (edit), GDK_SELECTION_PRIMARY, - ctext_atom, event->time); + editable->current_pos = e->curs1; return FALSE; } @@ -638,22 +736,19 @@ short key_sym_mod (gint key, gint state) return key; } -static gint - gtk_edit_key_press (GtkWidget * widget, - GdkEventKey * event) +static gint gtk_edit_key_press (GtkWidget * widget, GdkEventKey * event) { - GtkEdit *edit; GtkEditable *editable; + GtkEdit *edit; + WEdit *e; gint command = 0, insert = -1, r = 0; guint key, state; - g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_EDIT (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); - edit = GTK_EDIT (widget); editable = GTK_EDITABLE (widget); - + e = edit->editor; if (!edit_translate_key (0, event->keyval, event->state, &command, &insert)) { return FALSE; } @@ -661,17 +756,20 @@ static gint state = event->state; if (!command && insert < 0) { /* no translation took place, so lets see if we have a macro */ if ((key == GDK_r || key == GDK_R) && (state & ControlMask)) { - command = edit->editor->macro_i < 0 ? CK_Begin_Record_Macro : CK_End_Record_Macro; + command = e->macro_i < 0 ? CK_Begin_Record_Macro : CK_End_Record_Macro; } else { command = key_sym_mod (key, state); if (command > 0) command = CK_Macro (command); } } - r = edit_execute_key_command (edit->editor, command, insert); + r = edit_execute_key_command (e, command, insert); if (r) - edit_update_screen (edit->editor); - + edit_update_screen (e); + editable->selection_start_pos = e->mark1; + editable->selection_end_pos = ((e->mark2 < 0) ? e->curs1 : e->mark2); + editable->has_selection = editable->selection_start_pos != editable->selection_end_pos; + editable->current_pos = e->curs1; return r; } @@ -729,26 +827,15 @@ static void gtk_edit_set_selection (GtkEditable * editable, gint end) { GtkEdit *edit = GTK_EDIT (editable); - guint start1, end1, start2, end2; + WEdit *e; + e = edit->editor; if (end < 0) end = edit->editor->last_byte; - start1 = MIN (start, end); - end1 = MAX (start, end); - start2 = MIN (editable->selection_start_pos, editable->selection_end_pos); - end2 = MAX (editable->selection_start_pos, editable->selection_end_pos); - if (start2 < start1) { - guint tmp; - tmp = start1; - start1 = start2; - start2 = tmp; - tmp = end1; - end1 = end2; - end2 = tmp; - } - editable->selection_start_pos = start; - editable->selection_end_pos = end; - editable->has_selection = TRUE; - return; + editable->selection_start_pos = e->mark1 = MIN (start, end); + editable->selection_end_pos = e->mark2 = MAX (start, end); + editable->has_selection = (e->mark2 != e->mark1); + gtk_edit_mouse_redraw (e, e->curs1); + gtk_editable_claim_selection (editable, TRUE, GDK_CURRENT_TIME); } static void gtk_edit_insert_text (GtkEditable * editable, @@ -818,8 +905,6 @@ static void gtk_edit_class_init (GtkEditClass * class) get_home_dir (); } -extern struct mouse_funcs edit_mouse_funcs; - static void gtk_edit_init (GtkEdit * edit) { static made_directory = 0; @@ -833,7 +918,6 @@ static void gtk_edit_init (GtkEdit * edit) edit->menubar = 0; edit->status = 0; edit->options = 0; - edit->funcs = mouse_funcs_new (edit->editor, &edit_mouse_funcs); gtk_edit_configure_font_dimensions (edit); @@ -1261,7 +1345,7 @@ int edit (const char *file, int line) { { GNOME_APP_UI_ITEM, - N_ ("About..."), N_ ("Info about GNOME hello"), + N_ ("About..."), N_ ("Info about Mcedit"), about_cb, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, 0, (GdkModifierType) 0, NULL @@ -1283,7 +1367,8 @@ int edit (const char *file, int line) }; gtk_widget_realize (app); - statusbar = gtk_label_new (file ? file : ""); + statusbar = gtk_entry_new (); + gtk_entry_set_editable (GTK_ENTRY (statusbar), 0); gtk_widget_set_usize (app, 400, 400); gnome_app_create_menus (GNOME_APP (app), main_menu); gnome_app_set_contents (GNOME_APP (app), edit); @@ -1303,7 +1388,7 @@ int edit (const char *file, int line) return 1; } gtk_edit_set_cursor_line (edit, line); - gtk_widget_show (app); + gtk_widget_show_all (app); gtk_widget_grab_focus (edit); } return 0; diff --git a/gtkedit/gtkedit.h b/gtkedit/gtkedit.h index dbb70fc1f..a4304b562 100644 --- a/gtkedit/gtkedit.h +++ b/gtkedit/gtkedit.h @@ -58,7 +58,6 @@ struct _GtkEdit void (*destroy_me) (void *); void *destroy_me_user_data; struct editor_widget *editor; - struct mouse_funcs *funcs; gulong options; gint timer; }; diff --git a/gtkedit/mousemark.c b/gtkedit/mousemark.c index 069a683b0..e69de29bb 100644 --- a/gtkedit/mousemark.c +++ b/gtkedit/mousemark.c @@ -1,507 +0,0 @@ -/* mousemark.c - mouse stuff marking dragging - - Copyright (C) 1996, 1997 the Free Software Foundation - - Authors: 1996, 1997 Paul Sheer - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include -#ifndef GTK -#include "coolwidget.h" -#endif - -int just_dropped_something = 0; - -#include "edit.h" -#include -#include -#ifndef GTK -#include "app_glob.c" -#include "coollocal.h" -#endif -#include "editcmddef.h" -#include "xdnd.h" -#ifdef GTK -#include "src/mad.h" -#else -#include "mad.h" -#endif - -#ifndef HAVE_DND - -Atom **xdnd_typelist_send = 0; -Atom **xdnd_typelist_receive = 0; - -#define NUM_SIMPLE_TYPES 10 - -/* each entry is listed in order of what we would like the RECEIVE */ -static char *mime_type_send[NUM_SIMPLE_TYPES][10] = -{ - {0}, /* DndUnknown 0 */ - {0}, /* DndRawData 1 */ - {"url/url", "text/plain", 0}, /* DndFile 2 (input widget) */ - {"text/plain", "text/uri-list", 0}, /* DndFiles 3 (fielded text box) */ - {"text/plain", "application/octet-stream", 0}, /* DndText 4 (editor widget) */ -/* don't use these: */ - {0}, /* DndLink 5 */ - {0}, /* DndDir 6 */ - {0}, /* DndExe 7 */ - {0}, /* DndURL 8 */ - {0}, /* DndMIME 9 */ -}; - -static char *mime_type_recieve[NUM_SIMPLE_TYPES][10] = -{ - {0}, /* DndUnknown 0 */ - {0}, /* DndRawData 1 */ - {"url/url", "text/uri-list", "text/plain", 0}, /* DndFile 2 (input widget) */ - {0}, /* DndFiles 3 */ - {"url/url", "text/plain", "application/octet-stream", "text/uri-list", 0}, /* DndText 4 (editor widget) */ -/* don't use these: */ - {0}, /* DndLink 5 */ - {0}, /* DndDir 6 */ - {0}, /* DndExe 7 */ - {0}, /* DndURL 8 */ - {0}, /* DndMIME 9 */ -}; - -#ifndef GTK - -static char dnd_directory[MAX_PATH_LEN] = "/"; - -char *striptrailing (char *s, int c) -{ - int i; - i = strlen (s) - 1; - - while (i >= 0) { - if (s[i] == c) { - s[i--] = 0; - continue; - } - break; - } - return s; -} - -/* return the prepending directory (see CDndFileList() below) */ -char *CDndDirectory (void) -{ - return dnd_directory; -} - -/* - Sets the directory, must be a null terminated complete path. - Strips trailing slashes. - */ -void CSetDndDirectory (char *d) -{ - if (!d) - return; - strcpy (dnd_directory, d); - striptrailing (dnd_directory, '/'); - if (*dnd_directory) - return; - *dnd_directory = '/'; -} - -/* - Takes a newline seperated list of files, - returns a newline seperated list of complete `file:' path names - by prepending dnd_directory to each file name. - returns 0 if no files in list. - result must always be free'd. - returns l as the total length of data. - returns num_files as the number of files in the list. - Alters t - */ -char *CDndFileList (char *t, int *l, int *num_files) -{ - char *p, *q, *r, *result; - int i, len, done = 0; - -/* strip leading newlines */ - while (*t == '\n') - t++; - -/* strip trailing newlines */ - striptrailing (t, '\n'); - - if (!*t) - return 0; - -/* count files */ - for (i = 1, p = t; *p; p++) - if (*p == '\n') - i++; - - *num_files = i; - - len = (unsigned long) p - (unsigned long) t; - result = CMalloc ((strlen (dnd_directory) + strlen ("file:") + 2) * i + len + 2); - - r = result; - p = t; - while (!done) { - q = strchr (p, '\n'); - if (q) - *q = 0; - else - done = 1; - strcpy (r, "file:"); - if (*p != '/') { - strcat (r, dnd_directory); - strcat (r, "/"); - } - strcat (r, p); - r += strlen (r); - *r++ = '\n'; - p = ++q; - } - *r = 0; - *l = (unsigned long) r - (unsigned long) result; - return result; -} - -Window get_focus_border_widget (void); - -static void widget_apply_leave (DndClass * dnd, Window widgets_window) -{ - CWidget *w; - w = CWidgetOfWindow (widgets_window); - if (get_focus_border_widget () == widgets_window) - destroy_focus_border (); - if (w) - CExpose (w->ident); -} - -static int widget_insert_drop (DndClass * dnd, unsigned char *data, int length, int remaining, Window into, Window from, Atom type) -{ - CWidget *w; - char *p; - w = CWidgetOfWindow (into); - if (!w) - return 1; - if (*w->funcs->insert_drop) { - int r; - Window child_return; - int xd, yd; - if (!dnd->user_hook1) - dnd->user_hook2 = dnd->user_hook1 = CMalloc (length + remaining + 1); - memcpy (dnd->user_hook2, data, length); - p = dnd->user_hook2; - p += length; /* avoids ansi warning */ - dnd->user_hook2 = p; - if (remaining) - return 0; - XTranslateCoordinates (CDisplay, CRoot, into, dnd->x, dnd->y, &xd, &yd, &child_return); - r = (*w->funcs->insert_drop) (w->funcs->data, from, dnd->user_hook1, (unsigned long) dnd->user_hook2 - (unsigned long) dnd->user_hook1, xd, yd, type, dnd->supported_action); - free (dnd->user_hook1); - dnd->user_hook1 = dnd->user_hook2 = 0; - if (get_focus_border_widget () == into) - destroy_focus_border (); - CExpose (w->ident); - return r; - } - return 1; -} - -static int array_length (Atom * a) -{ - int n; - for (n = 0; a[n]; n++); - return n; -} - -static int widget_apply_position (DndClass * dnd, Window widgets_window, Window from, - Atom action, int x, int y, Time t, Atom * typelist, - int *want_position, Atom * supported_action, Atom * desired_type, - XRectangle * rectangle) -{ - CWidget *w; - Window child_return; - int xt, yt; - int xd, yd; - long click; - int i, j; - Atom result = 0; - - w = CWidgetOfWindow (widgets_window); - if (!w) - return 0; - -/* input widgets can't drop to themselves :-( */ - if (w->kind == C_TEXTINPUT_WIDGET && widgets_window == from) - return 0; - -/* look up mime types from my own list of supported types */ - for (j = 0; xdnd_typelist_receive[w->funcs->types][j]; j++) { - for (i = 0; typelist[i]; i++) { - if (typelist[i] == xdnd_typelist_receive[w->funcs->types][j]) { - result = typelist[i]; - break; - } - } - if (result) - break; - } - - if (!result && w->funcs->mime_majors) { - char **names_return; - names_return = CMalloc ((array_length (typelist) + 1) * sizeof (char *)); - if (XGetAtomNames (CDisplay, typelist, array_length (typelist), names_return)) { - for (i = 0; i < array_length (typelist); i++) { - for (j = 0; w->funcs->mime_majors[j]; j++) { - if (!strncmp (w->funcs->mime_majors[j], names_return[i], strlen (w->funcs->mime_majors[j]))) { - result = typelist[i]; - break; - } - } - if (result) - break; - } - } - } -/* not supported, so return false */ - if (!result) - return 0; - - XTranslateCoordinates (CDisplay, CRoot, widgets_window, x, y, &xd, &yd, &child_return); - if (xd < 0 || yd < 0 || xd >= CWidthOf (w) || yd >= CHeightOf (w)) - return 0; - - if (w->funcs->xy && w->funcs->cp && w->funcs->move) { - (*w->funcs->xy) (xd, yd, &xt, &yt); - click = (*w->funcs->cp) (w->funcs->data, xt, yt); - if (w->funcs->fin_mark) - (*w->funcs->fin_mark) (w->funcs->data); - if (w->funcs->move) - (*w->funcs->move) (w->funcs->data, click, yt); - if (w->funcs->redraw) - (*w->funcs->redraw) (w->funcs->data, click); - } -/* we want more position messages */ - *want_position = 1; - -/* we only support copy and move */ - if (action == dnd->XdndActionMove) { - *supported_action = dnd->XdndActionMove; - } else { - *supported_action = dnd->XdndActionCopy; - } - *desired_type = result; - rectangle->x = x; - rectangle->y = y; - rectangle->width = rectangle->height = 0; - if (get_focus_border_widget () != widgets_window) { - destroy_focus_border (); - create_focus_border (w, 4); - } - CExpose (w->ident); - return 1; -} - -static void widget_get_data (DndClass * dnd, Window window, unsigned char **data, int *length, Atom type) -{ - int t = DndText; - long start_mark, end_mark; - CWidget *w; - w = CWidgetOfWindow (window); - if (!w) { - return; - } - if (!w->funcs) - return; - if ((*w->funcs->marks) (w->funcs->data, &start_mark, &end_mark)) { - return; - } - if (type == XInternAtom (dnd->display, "url/url", False)) - t = DndFile; - else if (type == XInternAtom (dnd->display, "text/uri-list", False)) - t = DndFiles; - *data = (unsigned char *) (*w->funcs->get_block) (w->funcs->data, start_mark, end_mark, &t, length); -} - -static int widget_exists (DndClass * dnd, Window window) -{ - return (CWidgetOfWindow (window) != 0); -} - -static void handle_expose_events (DndClass * dnd, XEvent * xevent) -{ - if (!xevent->xexpose.count) - render_focus_border (xevent->xexpose.window); - return; -} - - -void mouse_init (void) -{ - CDndClass->handle_expose_events = handle_expose_events; - CDndClass->widget_insert_drop = widget_insert_drop; - CDndClass->widget_exists = widget_exists; - CDndClass->widget_apply_position = widget_apply_position; - CDndClass->widget_get_data = widget_get_data; - CDndClass->widget_apply_leave = widget_apply_leave; - CDndClass->options |= XDND_OPTION_NO_HYSTERESIS; - CDndClass->user_hook1 = CDndClass->user_hook2 = 0; - if (!xdnd_typelist_receive) { - int i; - xdnd_typelist_receive = malloc ((NUM_SIMPLE_TYPES + 1) * sizeof (Atom *)); - xdnd_typelist_send = malloc ((NUM_SIMPLE_TYPES + 1) * sizeof (Atom *)); - for (i = 0; i < NUM_SIMPLE_TYPES; i++) { - int j; - xdnd_typelist_receive[i] = CMalloc (32 * sizeof (Atom)); - for (j = 0; mime_type_recieve[i][j]; j++) { - xdnd_typelist_receive[i][j] = XInternAtom (CDndClass->display, mime_type_recieve[i][j], False); - xdnd_typelist_receive[i][j + 1] = 0; - } - xdnd_typelist_receive[i + 1] = 0; - xdnd_typelist_send[i] = CMalloc (32 * sizeof (Atom)); - for (j = 0; mime_type_send[i][j]; j++) { - xdnd_typelist_send[i][j] = XInternAtom (CDndClass->display, mime_type_send[i][j], False); - xdnd_typelist_send[i][j + 1] = 0; - } - xdnd_typelist_send[i + 1] = 0; - } - } -} - -void mouse_shut (void) -{ - if (xdnd_typelist_receive) { - int i; - for (i = 0; xdnd_typelist_send[i]; i++) - free (xdnd_typelist_send[i]); - free (xdnd_typelist_send); - xdnd_typelist_send = 0; - for (i = 0; xdnd_typelist_receive[i]; i++) - free (xdnd_typelist_receive[i]); - free (xdnd_typelist_receive); - xdnd_typelist_receive = 0; - } -} - -#endif /* !GTK */ - -struct mouse_funcs *mouse_funcs_new (void *data, struct mouse_funcs *m) -{ - struct mouse_funcs *p; - p = CMalloc (sizeof (*m)); - memcpy (p, m, sizeof (*m)); - p->data = data; - return p; -} - -#endif /* HAVE_DND */ - -void mouse_mark (XEvent * event, int double_click, struct mouse_funcs *funcs) -{ - void *data; - static unsigned long win_press = 0; - static int state = 0; /* 0 = button up, 1 = button pressed, 2 = button pressed and dragging */ - static int x_last, y_last; - long click; - data = funcs->data; - - if (event->type == ButtonPress) { - long start_mark, end_mark; - state = 1; - win_press = (unsigned long) event->xbutton.window; - (*funcs->xy) (event->xbutton.x, event->xbutton.y, &x_last, &y_last); - click = (*funcs->cp) (data, x_last, y_last); - if (!(*funcs->marks) (data, &start_mark, &end_mark)) { - if ((*funcs->range) (data, start_mark, end_mark, click)) { /* if clicked on highlighted text */ - unsigned char *t; - int l; -#ifdef HAVE_DND - int type; - t = (unsigned char *) (*funcs->get_block) (data, start_mark, end_mark, &type, &l); - if (t) { - just_dropped_something = 1; - CDrag (event->xbutton.window, type, t, l, event->xbutton.button == Button1 ? Button1Mask : 0); - free (t); - } -#else -#ifndef GTK - /* this is just to get the type which depends on the number of lines selected for - the fileselection box: */ - t = (unsigned char *) (*funcs->get_block) (data, start_mark, end_mark, &funcs->types, &l); - if (t) { - free (t); - if (xdnd_drag (CDndClass, event->xbutton.window, - event->xbutton.button == Button1 ? CDndClass->XdndActionCopy : CDndClass->XdndActionMove, - xdnd_typelist_send[funcs->types]) == CDndClass->XdndActionMove) { - if (funcs->delete_block) - (*funcs->delete_block) (data); - } - } -#endif -#endif - if (funcs->fin_mark) - (*funcs->fin_mark) (data); - return; - } - } - just_dropped_something = 0; - if (funcs->fin_mark) - (*funcs->fin_mark) (data); - (*funcs->move) (data, click, y_last); - if (double_click && funcs->dclick) { - (*funcs->dclick) (data, event); - state = 0; - } - if (funcs->redraw) - (*funcs->redraw) (data, click); - } else if (event->type == ButtonRelease && state > 0 && win_press == (unsigned long) event->xbutton.window && !double_click) { - int x, y; - long start_mark, end_mark; - (*funcs->xy) (event->xbutton.x, event->xbutton.y, &x, &y); - click = (*funcs->cp) (data, x, y); - (*funcs->move) (data, click, y); - if (state == 2) - goto unhighlight; - if (!(*funcs->marks) (data, &start_mark, &end_mark)) { - if ((*funcs->range) (data, start_mark, end_mark, click)) { /* if clicked on highlighted text */ - unhighlight: - if (funcs->release_mark) - (*funcs->release_mark) (data, event); - } - } - state = 0; - if (funcs->redraw) - (*funcs->redraw) (data, click); - } else if (event->type == MotionNotify && state > 0 && win_press == (unsigned long) event->xbutton.window && event->xbutton.state) { - int x, y; - if (!event->xmotion.state) - return; - (*funcs->xy) (event->xbutton.x, event->xbutton.y, &x, &y); - if (x == x_last && y == y_last && state == 1) - return; - click = (*funcs->cp) (data, x, y); - if (state == 1) { - state = 2; - if (funcs->move_mark) - (funcs->move_mark) (data); - } - (*funcs->move) (data, click, y); - if (funcs->motion) - (*funcs->motion) (data, click); - if (funcs->redraw) - (*funcs->redraw) (data, click); - } -} - diff --git a/gtkedit/mousemark.h b/gtkedit/mousemark.h index 6c5ba0010..e69de29bb 100644 --- a/gtkedit/mousemark.h +++ b/gtkedit/mousemark.h @@ -1,69 +0,0 @@ -/* Copyright (C) 1996, 1997 the Free Software Foundation - - Authors: 1996, 1997 Paul Sheer - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _MOUSE_MARK -#define _MOUSE_MARK - -/* mouse_mark.h */ - -struct mouse_funcs { - void *data; - void (*xy) (int, int, int *, int *); - /* (row, pixel-x-pos) from click pos (x,y) */ - long (*cp) (void *, int, int); /* get buffer offset from (row, pixel-x-pos) */ - int (*marks) (void *, long *, long *); - /* get mark start and end */ - int (*range) (void *, long, long, long); - /* is click between marks? */ - void (*fin_mark) (void *); /* set marks to not-moving mode (optional) */ - void (*move_mark) (void *); /* set marks to moving mode (optional) */ - void (*release_mark) (void *, XEvent *); - /* set marks when button is release. - possibly sets selection owner (could be - same as fin_mark) (optional) */ - char * (*get_block) (void *, long, long, int *, int *); - /* return block from between marks, - result is free'd by mouse_mark - int *, int * is Dnd type, length */ - void (*move) (void *, long, int); /* move cursor, int is row if needed */ - void (*motion) (void *, long); /* move second mark position */ - void (*dclick) (void *, XEvent *); /* called on double click (optional) */ - void (*redraw) (void *, long);/* called before exit, passing mouse - pos in buffer (optional) */ - int (*insert_drop) (void *, Window, unsigned char *, int, int, int, Atom, Atom); - void (*delete_block) (void *); - -/* this is one of the old dnd types. these are our preference -for drag between cooledits */ - int types; - -/* anything else that the widget can recieve eg {"text", "video"} */ - char **mime_majors; -}; - -void mouse_mark (XEvent * event, int double_click, struct mouse_funcs *funcs); - -struct mouse_funcs *mouse_funcs_new (void *data, struct mouse_funcs *m); -void mouse_shut (void); -void mouse_init (void); - -extern Atom **xdnd_typelist_receive; -extern Atom **xdnd_typelist_send; - -#endif -