From 035edb32ade55b43abc0a364d79745a416522117 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 10 Feb 2009 02:16:41 +0000 Subject: [PATCH] - Stopped sending double the number of wheel events as appropriate to the console under Linux. - Added middle mouse button selection pasting for X systems. SVN r1420 (trunk) --- docs/rh-log.txt | 6 ++- src/c_console.cpp | 69 ++++++++++++++++++-------------- src/ct_chat.cpp | 8 ++-- src/sdl/i_input.cpp | 93 ++++++++++++++++++++++++------------------- src/sdl/i_input.h | 2 +- src/sdl/i_system.cpp | 7 +++- src/win32/i_input.cpp | 4 +- src/win32/i_input.h | 2 +- 8 files changed, 112 insertions(+), 79 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index fe1d40118..97abaa6e5 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,7 @@ +February 9, 2009 +- Stopped sending double the number of wheel events to the console under Linux. +- Added middle mouse button selection pasting for X systems. + February 8, 2009 (Changes by Graf Zahl) - Fixed parsing for MustConfirm key in skill parser. - Converted internal MAPINFOs to new syntax. @@ -5,7 +9,7 @@ February 8, 2009 (Changes by Graf Zahl) - Restored Dehacked music name replacement. February 7, 2009 -- Added GUICapture mouse events for Win32. +- Added GUICapture mouse button events for Win32. - Changed I_GetFromClipboard() to return an FString. - Added GTK+-based clipboard support for Linux. - Fixed: Most Linux filesystems do not fill in d_type for scandir(), so we diff --git a/src/c_console.cpp b/src/c_console.cpp index 0b9307ffc..164a98a61 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -108,6 +108,7 @@ static int TopLine, InsertLine; static char *BufferRover = ConsoleBuffer; static void ClearConsole (); +static void C_PasteText(FString clip, BYTE *buffer, int len); struct GameAtExit { @@ -1735,42 +1736,22 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) buffer[2 + buffer[0]] = 0; I_PutInClipboard ((char *)&buffer[2]); } - break; } else { // paste from clipboard - FString clip = I_GetFromClipboard (); - if (clip.IsNotEmpty()) - { - // Only paste the first line. - long brk = clip.IndexOfAny("\r\n\b"); - int cliplen = brk >= 0 ? brk : clip.Len(); - - // Make sure there's room for the whole thing. - if (buffer[0] + cliplen > len) - { - cliplen = len - buffer[0]; - } - - if (cliplen > 0) - { - if (buffer[1] < buffer[0]) - { - memmove (&buffer[2 + buffer[1] + cliplen], - &buffer[2 + buffer[1]], buffer[0] - buffer[1]); - } - memcpy (&buffer[2 + buffer[1]], clip, cliplen); - buffer[0] += cliplen; - buffer[1] += cliplen; - makestartposgood (); - HistPos = NULL; - } - } - break; + C_PasteText(I_GetFromClipboard(false), buffer, len); } + break; } break; } + break; + +#ifdef unix + case EV_GUI_MButtonDown: + C_PasteText(I_GetFromClipboard(true), buffer, len); + break; +#endif } // Ensure that the cursor is always visible while typing CursorTicker = C_BLINKRATE; @@ -1778,6 +1759,36 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len) return true; } +static void C_PasteText(FString clip, BYTE *buffer, int len) +{ + if (clip.IsNotEmpty()) + { + // Only paste the first line. + long brk = clip.IndexOfAny("\r\n\b"); + int cliplen = brk >= 0 ? brk : clip.Len(); + + // Make sure there's room for the whole thing. + if (buffer[0] + cliplen > len) + { + cliplen = len - buffer[0]; + } + + if (cliplen > 0) + { + if (buffer[1] < buffer[0]) + { + memmove (&buffer[2 + buffer[1] + cliplen], + &buffer[2 + buffer[1]], buffer[0] - buffer[1]); + } + memcpy (&buffer[2 + buffer[1]], clip, cliplen); + buffer[0] += cliplen; + buffer[1] += cliplen; + makestartposgood (); + HistPos = NULL; + } + } +} + bool C_Responder (event_t *ev) { if (ev->type != EV_GUI_Event || diff --git a/src/ct_chat.cpp b/src/ct_chat.cpp index 9f9d7c603..ecc3c4827 100644 --- a/src/ct_chat.cpp +++ b/src/ct_chat.cpp @@ -152,7 +152,7 @@ bool CT_Responder (event_t *ev) } else if (ev->data1 == 'V' && (ev->data3 & GKM_CTRL)) { - CT_PasteChat(I_GetFromClipboard()); + CT_PasteChat(I_GetFromClipboard(false)); } } else if (ev->subtype == EV_GUI_Char) @@ -169,10 +169,12 @@ bool CT_Responder (event_t *ev) } return true; } +#ifdef unix else if (ev->subtype == EV_GUI_MButtonDown) { - CT_PasteChat(I_GetFromClipboard()); + CT_PasteChat(I_GetFromClipboard(true)); } +#endif } return false; @@ -186,7 +188,7 @@ bool CT_Responder (event_t *ev) void CT_PasteChat(const char *clip) { - if (clip != NULL) + if (clip != NULL && *clip != '\0') { // Only paste the first line. while (*clip != '\0') diff --git a/src/sdl/i_input.cpp b/src/sdl/i_input.cpp index 6cc16feb3..249c71fcf 100644 --- a/src/sdl/i_input.cpp +++ b/src/sdl/i_input.cpp @@ -285,14 +285,17 @@ static void WheelMoved(event_t *event) { if (GUICapture) { - SDLMod mod = SDL_GetModState(); - event->type = EV_GUI_Event; - event->subtype = event->data1 == KEY_MWHEELUP ? EV_GUI_WheelUp : EV_GUI_WheelDown; - event->data1 = 0; - event->data3 = ((mod & KMOD_SHIFT) ? GKM_SHIFT : 0) | - ((mod & KMOD_CTRL) ? GKM_CTRL : 0) | - ((mod & KMOD_ALT) ? GKM_ALT : 0); - D_PostEvent(event); + if (event->type != EV_KeyUp) + { + SDLMod mod = SDL_GetModState(); + event->type = EV_GUI_Event; + event->subtype = event->data1 == KEY_MWHEELUP ? EV_GUI_WheelUp : EV_GUI_WheelDown; + event->data1 = 0; + event->data3 = ((mod & KMOD_SHIFT) ? GKM_SHIFT : 0) | + ((mod & KMOD_CTRL) ? GKM_CTRL : 0) | + ((mod & KMOD_ALT) ? GKM_ALT : 0); + D_PostEvent(event); + } } else { @@ -376,41 +379,51 @@ void MessagePump (const SDL_Event &sev) case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: - event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp; - /* These button mappings work with my Gentoo system using the - * evdev driver and a Logitech MX510 mouse. Whether or not they - * carry over to other Linux systems, I have no idea, but I sure - * hope so. (Though buttons 11 and 12 are kind of useless, since - * they also trigger buttons 4 and 5.) - */ - switch (sev.button.button) + if (!GUICapture || sev.button.button == 4 || sev.button.button == 5) { - case 1: event.data1 = KEY_MOUSE1; break; - case 2: event.data1 = KEY_MOUSE3; break; - case 3: event.data1 = KEY_MOUSE2; break; - case 4: event.data1 = KEY_MWHEELUP; break; - case 5: event.data1 = KEY_MWHEELDOWN; break; - case 6: event.data1 = KEY_MOUSE4; break; /* dunno; not generated by my mouse */ - case 7: event.data1 = KEY_MOUSE5; break; /* ditto */ - case 8: event.data1 = KEY_MOUSE4; break; - case 9: event.data1 = KEY_MOUSE5; break; - case 10: event.data1 = KEY_MOUSE6; break; - case 11: event.data1 = KEY_MOUSE7; break; - case 12: event.data1 = KEY_MOUSE8; break; - default: printf("SDL mouse button %s %d\n", - sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break; + event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp; + /* These button mappings work with my Gentoo system using the + * evdev driver and a Logitech MX510 mouse. Whether or not they + * carry over to other Linux systems, I have no idea, but I sure + * hope so. (Though buttons 11 and 12 are kind of useless, since + * they also trigger buttons 4 and 5.) + */ + switch (sev.button.button) + { + case 1: event.data1 = KEY_MOUSE1; break; + case 2: event.data1 = KEY_MOUSE3; break; + case 3: event.data1 = KEY_MOUSE2; break; + case 4: event.data1 = KEY_MWHEELUP; break; + case 5: event.data1 = KEY_MWHEELDOWN; break; + case 6: event.data1 = KEY_MOUSE4; break; /* dunno; not generated by my mouse */ + case 7: event.data1 = KEY_MOUSE5; break; /* ditto */ + case 8: event.data1 = KEY_MOUSE4; break; + case 9: event.data1 = KEY_MOUSE5; break; + case 10: event.data1 = KEY_MOUSE6; break; + case 11: event.data1 = KEY_MOUSE7; break; + case 12: event.data1 = KEY_MOUSE8; break; + default: printf("SDL mouse button %s %d\n", + sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break; + } + if (event.data1 != 0) + { + //DIKState[ActiveDIKState][event.data1] = (event.type == EV_KeyDown); + if (event.data1 == KEY_MWHEELUP || event.data1 == KEY_MWHEELDOWN) + { + WheelMoved(&event); + } + else + { + D_PostEvent(&event); + } + } } - if (event.data1 != 0) + else if (sev.button.button >= 1 && sev.button.button <= 3) { - //DIKState[ActiveDIKState][event.data1] = (event.type == EV_KeyDown); - if (event.data1 == KEY_MWHEELUP || event.data1 == KEY_MWHEELDOWN) - { - WheelMoved(&event); - } - else - { - D_PostEvent(&event); - } + event.type = EV_GUI_Event; + event.subtype = sev.type == SDL_MOUSEBUTTONDOWN ? EV_GUI_LButtonDown : EV_GUI_LButtonUp; + event.subtype += (sev.button.button - 1) * 3; + D_PostEvent(&event); } break; diff --git a/src/sdl/i_input.h b/src/sdl/i_input.h index 14b5b4624..2551159ba 100644 --- a/src/sdl/i_input.h +++ b/src/sdl/i_input.h @@ -2,7 +2,7 @@ #define __I_INPUT_H__ void I_PutInClipboard (const char *str); -FString I_GetFromClipboard (); +FString I_GetFromClipboard (bool use_primary_selection); struct GUIDName { diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 3898edcf6..1f6a15fab 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -587,21 +587,24 @@ void I_PutInClipboard (const char *str) { gtk_clipboard_set_text(clipboard, str, -1); } + /* Should I? I don't know. It's not actually a selection. clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); if (clipboard != NULL) { gtk_clipboard_set_text(clipboard, str, -1); } + */ } #endif } -FString I_GetFromClipboard () +FString I_GetFromClipboard (bool use_primary_selection) { #ifndef NO_GTK if (GtkAvailable) { - GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + GtkClipboard *clipboard = gtk_clipboard_get(use_primary_selection ? + GDK_SELECTION_PRIMARY : GDK_SELECTION_CLIPBOARD); if (clipboard != NULL) { gchar *text = gtk_clipboard_wait_for_text(clipboard); diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index c93f5e45d..15beaa2e9 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -2041,14 +2041,14 @@ void I_PutInClipboard (const char *str) CloseClipboard (); } -FString I_GetFromClipboard () +FString I_GetFromClipboard (bool return_nothing) { FString retstr; HGLOBAL cliphandle; char *clipstr; char *nlstr; - if (!IsClipboardFormatAvailable (CF_TEXT) || !OpenClipboard (Window)) + if (return_nothing || !IsClipboardFormatAvailable (CF_TEXT) || !OpenClipboard (Window)) return retstr; cliphandle = GetClipboardData (CF_TEXT); diff --git a/src/win32/i_input.h b/src/win32/i_input.h index 04ff3f7bb..84d565d85 100644 --- a/src/win32/i_input.h +++ b/src/win32/i_input.h @@ -39,7 +39,7 @@ bool I_InitInput (void *hwnd); void I_ShutdownInput (); void I_PutInClipboard (const char *str); -FString I_GetFromClipboard (); +FString I_GetFromClipboard (bool windows_has_no_selection_clipboard); void I_GetEvent ();