repo: rxvt-unicode-sixel
action: commit
revision: 
path_from: 
revision_from: 7cb9936fd7681882288c175e988b900039405b29:
path_to: 
revision_to: 
git.thebackupbox.net
rxvt-unicode-sixel
git clone git://git.thebackupbox.net/rxvt-unicode-sixel
commit 7cb9936fd7681882288c175e988b900039405b29
Author: Emanuele Giaquinta 
Date:   Fri May 7 19:03:11 2021 +0000

    Implement xterm SGR mouse mode

diff --git a/doc/rxvt.7.pod b/doc/rxvt.7.pod
index 2ae437dc1362b0f5140cdc2e9791682e53da4d81..
index ..234d0acdf06ab61b66493c92da5ec1e6847c93eb 100644
--- a/doc/rxvt.7.pod
+++ b/doc/rxvt.7.pod
@@ -1961,7 +1961,16 @@ Unlike XTerm, coordinates larger than 2015 will work fine.
 =begin table

 	B<< C >>	Enable mouse coordinates in locale-specific encoding.
-	B<< C >>	Enable mouse coordinates as binary octets.
+	B<< C >>	Disable mouse coordinates in locale-specific encoding.
+
+=end table
+
+=item B<< C >> (X11 XTerm SGR mouse mode) (Compile frills)
+
+=begin table
+
+	B<< C >>	Enable xterm SGR mouse coordinate reporting.
+	B<< C >>	Disable xterm SGR mouse coordinate reporting.

 =end table

@@ -1988,41 +1997,10 @@ Unlike XTerm, coordinates larger than 2015 will work fine.
 =begin table

 	B<< C >>	Enable urxvt mouse coordinate reporting.
-	B<< C >>	Use old-style C encoding.
+	B<< C >>	Disable urxvt mouse coordinate reporting.

 =end table

-Changes all mouse reporting codes to use decimal parameters instead of
-octets or characters.
-
-This mode should be enabled I actually enabling mouse reporting,
-for semi-obvious reasons.
-
-The sequences received for various modes are as follows:
-
-   ESC [ M o o o    !1005, !1015 (three octets)
-   ESC [ M c c c    1005, !1015 (three characters)
-   ESC [ Pm M       1015 (three or more numeric parameters)
-
-The first three parameters are C, C and C. Code is the numeric
-code as for the other modes (but encoded as a decimal number, including
-the additional offset of 32, so you have to subtract 32 first), C and
-C are the coordinates (1|1 is the upper left corner, just as with
-cursor positioning).
-
-Example: Shift-Button-1 press at top row, column 80.
-
-   ESC [ 37 ; 80 ; 1 M
-
-One can use this feature by simply enabling it and then looking for
-parameters to the C reply - if there are any, this mode is
-active, otherwise one of the old reporting styles is used.
-
-Other (to be implemented) reply sequences will use a similar encoding.
-
-In the future, more parameters might get added (pixel coordinates for
-example - anybody out there who needs this?).
-
 =item B<< C >> (B)

 =begin table
@@ -2129,12 +2107,14 @@ X

 =head1 Mouse Reporting

+When mouse reporting is enabled and none of the extended mouse modes
+(1005, 1006, 1015) is active, urxvt sends the following sequence on a
+mouse event:
+
 =over 4

 =item B<< C<< ESC [ M    >> >>

-report mouse position
-
 =back

 The lower 2 bits of B<< C<<  >> >> indicate the button:
@@ -2172,12 +2152,89 @@ button was pressed and are added together (X11 mouse report only):

 =end table

-Col = B<< C<<  - SPACE >> >>
+=back
+
+C and C encode the coordinates (1|1 is the upper left corner,
+just as with cursor positioning):
+
+=over 4
+
+=item Col = B<< C<<  - SPACE >> >>
+
+=item Row = B<< C<<  - SPACE >> >>
+
+=back
+
+The parameters include an offset of 32 to ensure that they are
+printable characters.
+
+Example: Shift-Button-1 press at top row, column 80.
+
+   ESC [ M $ p !
+
+The largest coordinate that can be represented in this encoding is
+223. The range can be extended by using one of the extended mouse
+modes, which should be enabled I enabling mouse reporting, for
+semi-obvious reasons.

-Row = B<< C<<  - SPACE >> >>
+=head2 Mode 1005
+
+If mode 1005 is active, urxvt sends the sequence
+
+=over 4
+
+=item B<< C<< ESC [ M    >> >>
+
+=back
+
+with the coordinates provided as characters in locale-encoding instead
+of 1 byte octets. This mode does not work sensibly in non-UTF-8
+locales and should therefore be avoided.
+
+=head2 Mode 1006
+
+If mode 1006 is active, urxvt sends the following sequences:
+
+=over 4
+
+=item B<< C<< ESC [ < ;; M >> >>
+
+button press and motion
+
+=item B<< C<< ESC [ < ;; m >> >>
+
+button release

 =back

+where the parameters are provided as decimal numbers instead of
+octets and do not include an offset of 32.
+
+The lower 2 bits of C encode the button number also on button
+release (instead of the value C<3>). The final character of the
+sequence (M or m) specifies the event type (press/motion or release).
+
+Example: Shift-Button-1 press at top row, column 80.
+
+   ESC [ < 4 ; 80 ; 1 M
+
+=head2 Mode 1015
+
+If mode 1015 is active, urxvt sends the sequence
+
+=over 4
+
+=item B<< C<< ESC [ ;; M >> >>
+
+=back
+
+where the parameters are provided as decimal numbers instead of
+octets and only C includes an offset of 32.
+
+Example: Shift-Button-1 press at top row, column 80.
+
+   ESC [ 36 ; 80 ; 1 M
+
 =head1 Key Codes

 X
@@ -2460,7 +2517,7 @@ in combination with other switches) is:
   skip builtin block graphics (-sbg)
   separate highlight colour (-highlightColor, -highlightTextColor)
   focus reporting mode (1004).
-  extended mouse reporting modes (1005 and 1015).
+  extended mouse reporting modes (1005, 1006 and 1015).
   visual selection via -visual and -depth.

 It also enables some non-essential features otherwise disabled, such as:
diff --git a/src/command.C b/src/command.C
--- a/src/command.C
+++ b/src/command.C
@@ -1279,9 +1279,9 @@ rxvt_term::pointer_cb (ev::timer &w, int revents)
 void
 rxvt_term::mouse_report (XButtonEvent &ev)
 {
-  int button_number, key_state = 0;
+  int button_number, state = 0;
   int x, y;
-  int code = 32;
+  bool release = ev.type == ButtonRelease;

   x = Pixel2Col (ev.x) + 1;
   y = Pixel2Row (ev.y) + 1;
@@ -1293,18 +1293,13 @@ rxvt_term::mouse_report (XButtonEvent &ev)

       mouse_row = x;
       mouse_col = y;
-      code += 32;
+      state += 32;
     }

-  if (MEvent.button == AnyButton)
-    button_number = 3;
-  else
-    {
-      button_number = MEvent.button - Button1;
-      /* add 0x3D for wheel events, like xterm does */
-      if (button_number >= 3)
-        button_number += 64 - 3;
-    }
+  button_number = MEvent.button - Button1;
+  /* add 0x3D for wheel events, like xterm does */
+  if (button_number >= 3)
+    button_number += 64 - 3;

   if (priv_modes & PrivMode_MouseX10)
     {
@@ -1312,8 +1307,7 @@ rxvt_term::mouse_report (XButtonEvent &ev)
        * do not report ButtonRelease
        * no state info allowed
        */
-      key_state = 0;
-      if (button_number == 3)
+      if (release)
         return;
     }
   else
@@ -1325,23 +1319,25 @@ rxvt_term::mouse_report (XButtonEvent &ev)
        * plus will add in our own Double-Click reporting
        *  32 = Double Click
        */
-      key_state = ((MEvent.state & ShiftMask) ? 4 : 0)
-                  + ((MEvent.state & ModMetaMask) ? 8 : 0)
-                  + ((MEvent.state & ControlMask) ? 16 : 0);
+      state += ((MEvent.state & ShiftMask) ? 4 : 0)
+               + ((MEvent.state & ModMetaMask) ? 8 : 0)
+               + ((MEvent.state & ControlMask) ? 16 : 0);
 #ifdef MOUSE_REPORT_DOUBLECLICK
-      key_state += ((MEvent.clicks > 1) ? 32 : 0);
+      state += ((MEvent.clicks > 1) ? 32 : 0);
 #endif
     }

+  int code = 32 + (release ? 3 : button_number) + state;
+
 #if DEBUG_MOUSEREPORT
   fprintf (stderr, "Mouse [");
-  if (key_state & 16)
+  if (state & 16)
     fputc ('C', stderr);
-  if (key_state & 4)
+  if (state & 4)
     fputc ('S', stderr);
-  if (key_state & 8)
+  if (state & 8)
     fputc ('A', stderr);
-  if (key_state & 32)
+  if (state & 32)
     fputc ('2', stderr);
   fprintf (stderr, "]: <%d>, %d/%d\n",
           button_number,
@@ -1350,20 +1346,26 @@ rxvt_term::mouse_report (XButtonEvent &ev)
 #endif

 #if ENABLE_FRILLS
-  if (priv_modes & PrivMode_ExtMouseRight)
+  if (priv_modes & PrivMode_ExtMouseSGR)
+    tt_printf ("\033[<%d;%d;%d%c",
+              button_number + state,
+              x,
+              y,
+              release ? 'm' : 'M');
+  else if (priv_modes & PrivMode_ExtMouseRight)
     tt_printf ("\033[%d;%d;%dM",
-              code + button_number + key_state,
+              code,
               x,
               y);
   else if (priv_modes & PrivMode_ExtModeMouse)
     tt_printf ("\033[M%c%lc%lc",
-              code + button_number + key_state,
+              code,
               wint_t (32 + x),
               wint_t (32 + y));
   else
 #endif
     tt_printf ("\033[M%c%c%c",
-              code + button_number + key_state,
+              code,
               32 + x,
               32 + y);
 }
@@ -2151,11 +2153,11 @@ rxvt_term::button_release (XButtonEvent &ev)
                       > multiClickTime / 2)))
             {
               MEvent.clicks = 0;
-              MEvent.button = AnyButton;
+              MEvent.button = ev.button;
               mouse_report (ev);
             }
 #else				/* MOUSE_REPORT_DOUBLECLICK */
-          MEvent.button = AnyButton;
+          MEvent.button = ev.button;
           mouse_report (ev);
 #endif /* MOUSE_REPORT_DOUBLECLICK */
           return;
@@ -2876,7 +2878,7 @@ rxvt_term::process_csi_seq ()
                 scr_soft_reset ();

                 static const int pm_h[] = { 7, 25 };
-                static const int pm_l[] = { 1, 3, 4, 5, 6, 9, 66, 1000, 1001, 1005, 1015, 1049 };
+                static const int pm_l[] = { 1, 3, 4, 5, 6, 9, 66, 1000, 1001, 1005, 1006, 1015, 1049 };

                 process_terminal_mode ('h', 0, ecb_array_length (pm_h), pm_h);
                 process_terminal_mode ('l', 0, ecb_array_length (pm_l), pm_l);
@@ -3703,6 +3705,7 @@ rxvt_term::process_terminal_mode (int mode, int priv ecb_unused, unsigned int na
 #if ENABLE_FRILLS
                   { 1004, PrivMode_FocusEvent },
                   { 1005, PrivMode_ExtModeMouse },
+                  { 1006, PrivMode_ExtMouseSGR },
 #endif
                   { 1010, PrivMode_TtyOutputInh }, // rxvt extension
                   { 1011, PrivMode_Keypress }, // rxvt extension
@@ -3981,7 +3984,7 @@ rxvt_term::process_sgr_mode (unsigned int nargs, const int *arg)
             {
               unsigned int fgbg = arg[i] == 38 ? Color_fg : Color_bg;
               unsigned int idx;
-            
+
               if (nargs > i + 2 && arg[i + 1] == 5)
                 {
                   idx = minCOLOR + arg[i + 2];
diff --git a/src/rxvt.h b/src/rxvt.h
--- a/src/rxvt.h
+++ b/src/rxvt.h
@@ -578,6 +578,7 @@ enum {
 #define PrivMode_ExtMouseRight  (1UL<<24) // xterm pseudo-utf-8, but works in non-utf-8-locales
 #define PrivMode_BlinkingCursor (1UL<<25)
 #define PrivMode_FocusEvent     (1UL<<26)
+#define PrivMode_ExtMouseSGR    (1UL<<27)

 #define PrivMode_mouse_report   (PrivMode_MouseX10|PrivMode_MouseX11|PrivMode_MouseBtnEvent|PrivMode_MouseAnyEvent)

-----END OF PAGE-----