ncurses 5.9 - patch 20110917
authorThomas E. Dickey <dickey@invisible-island.net>
Sun, 18 Sep 2011 01:02:06 +0000 (01:02 +0000)
committerThomas E. Dickey <dickey@invisible-island.net>
Sun, 18 Sep 2011 01:02:06 +0000 (01:02 +0000)
+ fix compiler warning for clang 2.9
+ improve merging of mouse events (integrated patch by Damien
  Guibouret).
+ correct mask-check used in lib_mouse for wheel mouse buttons 4/5
  (patch by Damien Guibouret).

14 files changed:
NEWS
c++/cursesapp.h
c++/cursesf.cc
c++/cursesm.cc
c++/cursesm.h
c++/cursespad.cc
c++/cursesw.cc
c++/cursesw.h
c++/demo.cc
dist.mk
form/frm_driver.c
ncurses/base/lib_mouse.c
ncurses/curses.priv.h
test/ncurses.c

diff --git a/NEWS b/NEWS
index 436a726bcfc1d45047470a06aa891f76f5a0e410..a5c63a544a0c7b779c9d40932fab4eba59656223 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -25,7 +25,7 @@
 -- sale, use or other dealings in this Software without prior written        --
 -- authorization.                                                            --
 -------------------------------------------------------------------------------
--- $Id: NEWS,v 1.1781 2011/09/11 00:50:29 tom Exp $
+-- $Id: NEWS,v 1.1784 2011/09/17 22:05:18 tom Exp $
 -------------------------------------------------------------------------------
 
 This is a log of changes that ncurses has gone through since Zeyd started
@@ -45,6 +45,13 @@ See the AUTHORS file for the corresponding full names.
 Changes through 1.9.9e did not credit all contributions;
 it is not possible to add this information.
 
+20110917
+       + fix compiler warning for clang 2.9
+       + improve merging of mouse events (integrated patch by Damien
+         Guibouret).
+       + correct mask-check used in lib_mouse for wheel mouse buttons 4/5
+         (patch by Damien Guibouret).
+
 20110910
        + modify misc/gen_edit.sh to select a "linux" entry which works with
          the current kernel rather than assuming it is always "linux3.0"
index 7e995d2e39c63abdcf045c1216fbdf540719806d..e3cbc04cc6745582c22cac697c1ce349b6b9a219 100644 (file)
@@ -1,6 +1,6 @@
 // * This makes emacs happy -*-Mode: C++;-*-
 /****************************************************************************
- * Copyright (c) 1998-2003,2005 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2005,2011 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -31,7 +31,7 @@
  *   Author: Juergen Pfeifer, 1997                                          *
  ****************************************************************************/
 
-// $Id: cursesapp.h,v 1.11 2005/05/28 21:57:44 tom Exp $
+// $Id: cursesapp.h,v 1.12 2011/09/17 22:12:10 tom Exp $
 
 #ifndef NCURSES_CURSESAPP_H_incl
 #define NCURSES_CURSESAPP_H_incl
@@ -80,6 +80,7 @@ protected:
   // This method is called to initialize the SLKs. Default is nothing.
   // You may rewrite this in your derived class
   virtual void init_labels(Soft_Label_Key_Set& S) const {
+    (void) S;
   }
 
   // Your derived class must implement this method. The return value must
@@ -118,6 +119,8 @@ public:
   // Process the commandline arguments. The default implementation simply
   // ignores them. Your derived class may rewrite this.
   virtual void handleArgs(int argc, char* argv[]) {
+    (void) argc;
+    (void) argv;
   }
 
   // Does this application use colors?
@@ -138,37 +141,37 @@ public:
 
   // Attributes to use for menu and forms foregrounds
   virtual chtype foregrounds() const {
-    return b_Colors ? COLOR_PAIR(1) : A_BOLD;
+    return b_Colors ? static_cast<chtype>(COLOR_PAIR(1)) : A_BOLD;
   }
 
   // Attributes to use for menu and forms backgrounds
   virtual chtype backgrounds() const {
-    return b_Colors ? COLOR_PAIR(2) : A_NORMAL;
+    return b_Colors ? static_cast<chtype>(COLOR_PAIR(2)) : A_NORMAL;
   }
 
   // Attributes to use for inactive (menu) elements
   virtual chtype inactives() const {
-    return b_Colors ? (COLOR_PAIR(3)|A_DIM) : A_DIM;
+    return b_Colors ? static_cast<chtype>(COLOR_PAIR(3)|A_DIM) : A_DIM;
   }
 
   // Attributes to use for (form) labels and SLKs
   virtual chtype labels() const {
-    return b_Colors ? COLOR_PAIR(4) : A_NORMAL;
+    return b_Colors ? static_cast<chtype>(COLOR_PAIR(4)) : A_NORMAL;
   }
 
   // Attributes to use for form backgrounds
   virtual chtype dialog_backgrounds() const {
-    return b_Colors ? COLOR_PAIR(4) : A_NORMAL;
+    return b_Colors ? static_cast<chtype>(COLOR_PAIR(4)) : A_NORMAL;
   }
 
   // Attributes to use as default for (form) window backgrounds
   virtual chtype window_backgrounds() const {
-    return b_Colors ? COLOR_PAIR(5) : A_NORMAL;
+    return b_Colors ? static_cast<chtype>(COLOR_PAIR(5)) : A_NORMAL;
   }
 
   // Attributes to use for the title window
   virtual chtype screen_titles() const {
-    return b_Colors ? COLOR_PAIR(6) : A_BOLD;
+    return b_Colors ? static_cast<chtype>(COLOR_PAIR(6)) : A_BOLD;
   }
 
 };
index aaf1202ca94e3c5fb7751ea60aa710bc9ec38a3c..7956054769f4c9e70808199ece62b311a16b2090 100644 (file)
@@ -1,6 +1,6 @@
 // * this is for making emacs happy: -*-Mode: C++;-*-
 /****************************************************************************
- * Copyright (c) 1998-2003,2005 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2005,2011 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -35,7 +35,7 @@
 #include "cursesf.h"
 #include "cursesapp.h"
 
-MODULE_ID("$Id: cursesf.cc,v 1.21 2005/08/13 18:09:06 tom Exp $")
+MODULE_ID("$Id: cursesf.cc,v 1.22 2011/09/17 22:12:10 tom Exp $")
 
 NCursesFormField::~NCursesFormField ()
 {
@@ -234,11 +234,13 @@ NCursesForm::On_Form_Termination()
 void
 NCursesForm::On_Field_Init(NCursesFormField& field)
 {
+  (void) field;
 }
 
 void
 NCursesForm::On_Field_Termination(NCursesFormField& field)
 {
+  (void) field;
 }
 
 // call the form driver and do basic error checking.
@@ -260,16 +262,19 @@ NCursesForm::driver (int c)
 
 void NCursesForm::On_Request_Denied(int c) const
 {
+  (void) c;
   ::beep();
 }
 
 void NCursesForm::On_Invalid_Field(int c) const
 {
+  (void) c;
   ::beep();
 }
 
 void NCursesForm::On_Unknown_Command(int c) const
 {
+  (void) c;
   ::beep();
 }
 
@@ -373,6 +378,7 @@ NCursesForm::virtualize(int c)
 //
 bool _nc_xx_fld_fcheck(FIELD *f, const void *u)
 {
+  (void) f;
   NCursesFormField* F = reinterpret_cast<NCursesFormField*>(const_cast<void *>(u));
   assert(F != 0);
   UserDefinedFieldType* udf = reinterpret_cast<UserDefinedFieldType*>(F->fieldtype());
@@ -405,6 +411,7 @@ FIELDTYPE* UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice =
 
 bool _nc_xx_next_choice(FIELD *f, const void *u)
 {
+  (void) f;
   NCursesFormField* F = reinterpret_cast<NCursesFormField*>(const_cast<void *>(u));
   assert(F != 0);
   UserDefinedFieldType_With_Choice* udf =
@@ -415,6 +422,7 @@ bool _nc_xx_next_choice(FIELD *f, const void *u)
 
 bool _nc_xx_prev_choice(FIELD *f, const void *u)
 {
+  (void) f;
   NCursesFormField* F = reinterpret_cast<NCursesFormField*>(const_cast<void *>(u));
   assert(F != 0);
   UserDefinedFieldType_With_Choice* udf =
index c253a67999094d0e1a459f05378c9b2e33f3e801..222de46cd22edc8a930f26a96abaa62632bc5905 100644 (file)
@@ -1,6 +1,6 @@
 // * this is for making emacs happy: -*-Mode: C++;-*-
 /****************************************************************************
- * Copyright (c) 1998-2003,2005 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2005,2011 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -35,7 +35,7 @@
 #include "cursesm.h"
 #include "cursesapp.h"
 
-MODULE_ID("$Id: cursesm.cc,v 1.22 2005/04/02 20:39:05 tom Exp $")
+MODULE_ID("$Id: cursesm.cc,v 1.23 2011/09/17 22:11:32 tom Exp $")
 
 NCursesMenuItem::~NCursesMenuItem()
 {
@@ -375,33 +375,39 @@ NCursesMenu::On_Menu_Termination()
 void
 NCursesMenu::On_Item_Init(NCursesMenuItem& item)
 {
+  (void) item;
 }
 
 void
 NCursesMenu::On_Item_Termination(NCursesMenuItem& item)
 {
+  (void) item;
 }
 
 void
 NCursesMenu::On_Request_Denied(int c) const
 {
+  (void) c;
   ::beep();
 }
 
 void
 NCursesMenu::On_Not_Selectable(int c) const
 {
+  (void) c;
   ::beep();
 }
 
 void
 NCursesMenu::On_No_Match(int c) const
 {
+  (void) c;
   ::beep();
 }
 
 void
 NCursesMenu::On_Unknown_Command(int c) const
 {
+  (void) c;
   ::beep();
 }
index 4058ed07a711be77029333ea5ef7aae62cf3aa4b..d629e8eeae6ccc9cb06728dfc9f88bbd1e7ab0d2 100644 (file)
@@ -31,7 +31,7 @@
  *   Author: Juergen Pfeifer, 1997                                          *
  ****************************************************************************/
 
-// $Id: cursesm.h,v 1.26 2011/04/09 18:07:08 Alexander.Kolesen Exp $
+// $Id: cursesm.h,v 1.27 2011/09/17 21:37:01 tom Exp $
 
 #ifndef NCURSES_CURSESM_H_incl
 #define NCURSES_CURSESM_H_incl 1
@@ -82,6 +82,7 @@ public:
   NCursesMenuItem(const NCursesMenuItem& rhs)
     : item(0)
   {
+    (void) rhs;
   }
 
   virtual ~NCursesMenuItem ();
index 28c58fab36acaae85ff1016ecc5effdf639cf842..b5690a3e303a2dadba12ef8ce8874cc751cba816 100644 (file)
@@ -1,6 +1,6 @@
 // * this is for making emacs happy: -*-Mode: C++;-*-
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2008,2011 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -36,7 +36,7 @@
 #include <etip.h>
 #include <cursesw.h>
 
-MODULE_ID("$Id: cursespad.cc,v 1.13 2008/08/04 18:59:22 tom Exp $")
+MODULE_ID("$Id: cursespad.cc,v 1.14 2011/09/17 22:12:10 tom Exp $")
 
 NCursesPad::NCursesPad(int nlines, int ncols)
   : NCursesWindow(),
@@ -220,6 +220,7 @@ void NCursesPad::setSubWindow(NCursesWindow& sub)
 
 void NCursesFramedPad::OnOperation(int pad_req)
 {
+  (void) pad_req;
   NCursesWindow* W = Win();
   NCursesWindow* W2 = getWindow();
 
index 47e5cf64dcf0ded1e7ca1d88f1ed69cc2ae8fbfb..f2e7e94858aa4b16077a10412ae699ebe390cb90 100644 (file)
@@ -1,6 +1,6 @@
 // * this is for making emacs happy: -*-Mode: C++;-*-
 /****************************************************************************
- * Copyright (c) 2007-2008,2009 Free Software Foundation, Inc.              *
+ * Copyright (c) 2007-2009,2011 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -42,7 +42,7 @@
 #include "internal.h"
 #include "cursesw.h"
 
-MODULE_ID("$Id: cursesw.cc,v 1.51 2009/03/28 21:31:37 tom Exp $")
+MODULE_ID("$Id: cursesw.cc,v 1.52 2011/09/17 22:12:10 tom Exp $")
 
 #define COLORS_NEED_INITIALIZATION  -1
 #define COLORS_NOT_INITIALIZED       0
@@ -285,12 +285,14 @@ static RIPOFFINIT* prip = R_INIT;
 NCursesWindow::NCursesWindow(WINDOW *win, int ncols)
   : w(0), alloced(FALSE), par(0), subwins(0), sib(0)
 {
+    (void) ncols;
     initialize();
     w = win;
 }
 
 int _nc_xx_ripoff_init(WINDOW *w, int ncols)
 {
+    (void) ncols;
     int res = ERR;
 
     RIPOFFINIT init = *prip++;
index b8e921a9b7aa41edb1d5461b3a276d87a24c34f8..4472ea9ca13ac8c17f35f7bc3366b58d8bd0e917 100644 (file)
@@ -1,7 +1,7 @@
 // * This makes emacs happy -*-Mode: C++;-*-
 // vile:cppmode
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2008,2011 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -31,7 +31,7 @@
 #ifndef NCURSES_CURSESW_H_incl
 #define NCURSES_CURSESW_H_incl 1
 
-// $Id: cursesw.h,v 1.48 2008/01/19 21:09:10 tom Exp $
+// $Id: cursesw.h,v 1.49 2011/09/17 22:12:10 tom Exp $
 
 #include <etip.h>
 
@@ -1438,16 +1438,19 @@ protected:
   // The driver translates the keystroke c into an Pad_Request
 
   virtual void OnUnknownOperation(int pad_req) {
+    (void) pad_req;
     ::beep();
   }
   // This is called if the driver returns an unknown op-code
 
   virtual void OnNavigationError(int pad_req) {
+    (void) pad_req;
     ::beep();
   }
   // This is called if a navigation request couldn't be satisfied
 
   virtual void OnOperation(int pad_req) {
+    (void) pad_req;
   };
   // OnOperation is called if a Pad_Operation was executed and just before
   // the refresh() operation is done.
@@ -1542,11 +1545,15 @@ public:
   }
 
   void setWindow(NCursesWindow& view, int v_grid = 1, int h_grid = 1) {
+    (void) view;
+    (void) v_grid;
+    (void) h_grid;
     err_handler("Operation not allowed");
   }
   // Disable this call; the viewport is already defined
 
   void setSubWindow(NCursesWindow& sub) {
+    (void) sub;
     err_handler("Operation not allowed");
   }
   // Disable this call; the viewport subwindow is already defined
index 35433425f1fcc20cf383ee9c0cd1b96911b88ad4..7acdd0933f10364084e2c466cffb676c9cd1140a 100644 (file)
@@ -1,6 +1,6 @@
 // * This makes emacs happy -*-Mode: C++;-*-
 /****************************************************************************
- * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2008,2011 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -35,7 +35,7 @@
  *   Demo code for NCursesMenu and NCursesForm written by
  *   Juergen Pfeifer
  *
- * $Id: demo.cc,v 1.39 2008/12/07 02:07:34 juergen Exp $
+ * $Id: demo.cc,v 1.40 2011/09/17 22:12:10 tom Exp $
  */
 
 #include "internal.h"
@@ -220,6 +220,7 @@ private:
   int chk;
 protected:
   bool field_check(NCursesFormField& f) {
+    (void) f;
     return TRUE;
   }
   bool char_check(int c) {
diff --git a/dist.mk b/dist.mk
index 21f8935bd459d6ddbbc3cee45e4089a0b750ee11..400632bb1c16d2c185c103580b1f36a4747b058f 100644 (file)
--- a/dist.mk
+++ b/dist.mk
@@ -25,7 +25,7 @@
 # use or other dealings in this Software without prior written               #
 # authorization.                                                             #
 ##############################################################################
-# $Id: dist.mk,v 1.833 2011/09/10 15:46:42 tom Exp $
+# $Id: dist.mk,v 1.834 2011/09/17 16:04:54 tom Exp $
 # Makefile for creating ncurses distributions.
 #
 # This only needs to be used directly as a makefile by developers, but
@@ -37,7 +37,7 @@ SHELL = /bin/sh
 # These define the major/minor/patch versions of ncurses.
 NCURSES_MAJOR = 5
 NCURSES_MINOR = 9
-NCURSES_PATCH = 20110910
+NCURSES_PATCH = 20110917
 
 # We don't append the patch to the version, since this only applies to releases
 VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)
index e0892bf8d4f2f7f4c64403329bdf763dcbf3f219..f335ed2611c2a7ce8578d37ecc80dfbca1190a0c 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -32,7 +32,7 @@
 
 #include "form.priv.h"
 
-MODULE_ID("$Id: frm_driver.c,v 1.98 2010/05/01 21:11:43 tom Exp $")
+MODULE_ID("$Id: frm_driver.c,v 1.99 2011/09/17 22:12:10 tom Exp $")
 
 /*----------------------------------------------------------------------------
   This is the core module of the form library. It contains the majority
@@ -1326,7 +1326,7 @@ _nc_Synchronize_Options(FIELD *field, Field_Options newopts)
              field->opts = oldopts;
              returnCode(E_CURRENT);
            }
-         if ((form->curpage == field->page))
+         if (form->curpage == field->page)
            {
              if (changed_opts & O_VISIBLE)
                {
index 4316957918015f336833303a8440f5563a793e30..350eaa7b8c7bf49d4fb629a7d359ec55fe93a971 100644 (file)
@@ -84,7 +84,7 @@
 #define CUR SP_TERMTYPE
 #endif
 
-MODULE_ID("$Id: lib_mouse.c,v 1.122 2011/09/10 22:23:38 tom Exp $")
+MODULE_ID("$Id: lib_mouse.c,v 1.129 2011/09/17 21:52:30 tom Exp $")
 
 #include <tic.h>
 
@@ -750,6 +750,7 @@ _nc_mouse_event(SCREEN *sp)
                        eventp->bstate |= BUTTON3_RELEASED;
                    break;
                default:
+                   eventp->bstate |= REPORT_MOUSE_POSITION;
                    break;
                }
 
@@ -830,7 +831,6 @@ _nc_mouse_inline(SCREEN *sp)
 
     if (sp->_mouse_type == M_XTERM) {
        unsigned char kbuf[4];
-       mmask_t prev;
        size_t grabbed;
        int res;
 
@@ -896,35 +896,51 @@ _nc_mouse_inline(SCREEN *sp)
 
        /* processing code goes here */
        eventp->bstate = 0;
-       prev = PREV(eventp)->bstate;
 
 #if USE_EMX_MOUSE
 #define PRESS_POSITION(n) \
-       eventp->bstate = MASK_PRESS(n); \
-       if (kbuf[0] & 0x40) \
-           eventp->bstate = MASK_RELEASE(n)
+       do { \
+               eventp->bstate = MASK_PRESS(n); \
+               sp->_mouse_bstate |= MASK_PRESS(n); \
+               if (kbuf[0] & 0x40) { \
+                       eventp->bstate = MASK_RELEASE(n); \
+                       sp->_mouse_bstate &= ~MASK_PRESS(n); \
+               } \
+       } while (0)
 #else
 #define PRESS_POSITION(n) \
-       eventp->bstate = (mmask_t) (prev & MASK_PRESS(n) \
-                                   ? REPORT_MOUSE_POSITION \
-                                   : MASK_PRESS(n))
+       do { \
+               eventp->bstate = (mmask_t) (sp->_mouse_bstate & MASK_PRESS(n) \
+                                       ? REPORT_MOUSE_POSITION \
+                                       : MASK_PRESS(n)); \
+               sp->_mouse_bstate |= MASK_PRESS(n); \
+       } while (0)
 #endif
 
        switch (kbuf[0] & 0x3) {
        case 0x0:
-           if (kbuf[0] & 64)
+           if ((kbuf[0] & 96) == 96) {
                eventp->bstate = MASK_PRESS(4);
-           else
+               /* Do not record in sp->_mouse_bstate; there will be no
+                * corresponding release event.
+                */
+           } else {
                PRESS_POSITION(1);
+           }
            break;
 
        case 0x1:
+           if ((kbuf[0] & 96) == 96) {
 #if NCURSES_MOUSE_VERSION == 2
-           if (kbuf[0] & 64)
                eventp->bstate = MASK_PRESS(5);
-           else
+               /* See comment above for button 4 */
+#else
+               /* Ignore this event as it is not a true press of the button */
+               eventp->bstate = REPORT_MOUSE_POSITION;
 #endif
+           } else {
                PRESS_POSITION(2);
+           }
            break;
 
        case 0x2:
@@ -939,12 +955,13 @@ _nc_mouse_inline(SCREEN *sp)
             * release, we can infer the button actually released by looking at
             * the previous event.
             */
-           if (prev & (BUTTON_PRESSED | BUTTON_RELEASED)) {
+           if (sp->_mouse_bstate & BUTTON_PRESSED) {
                eventp->bstate = BUTTON_RELEASED;
                for (b = 1; b <= MAX_BUTTONS; ++b) {
-                   if (!(prev & MASK_PRESS(b)))
+                   if (!(sp->_mouse_bstate & MASK_PRESS(b)))
                        eventp->bstate &= ~MASK_RELEASE(b);
                }
+               sp->_mouse_bstate = 0;
            } else {
                /*
                 * XFree86 xterm will return a stream of release-events to
@@ -994,7 +1011,7 @@ mouse_activate(SCREEN *sp, bool on)
        return;
 
     if (on) {
-
+       sp->_mouse_bstate = 0;
        switch (sp->_mouse_type) {
        case M_XTERM:
 #if NCURSES_EXT_FUNCS
@@ -1074,10 +1091,13 @@ _nc_mouse_parse(SCREEN *sp, int runcount)
 /* parse a run of atomic mouse events into a gesture */
 {
     MEVENT *eventp = sp->_mouse_eventp;
-    MEVENT *ep, *runp, *next, *prev = PREV(eventp);
+    MEVENT *next, *ep;
+    MEVENT *first_valid = NULL;
+    MEVENT *first_invalid = NULL;
     int n;
     int b;
     bool merge;
+    bool endLoop;
 
     TR(MY_TRACE, ("_nc_mouse_parse(%d) called", runcount));
 
@@ -1094,7 +1114,8 @@ _nc_mouse_parse(SCREEN *sp, int runcount)
      *
      * It's possible that the run may not resolve to a single event (for
      * example, if the user quadruple-clicks).  If so, leading events
-     * in the run are ignored.
+     * in the run are ignored if user does not call getmouse in a loop (getting
+     * them from newest to older).
      *
      * Note that this routine is independent of the format of the specific
      * format of the pointing-device's reports.  We can use it to parse
@@ -1102,79 +1123,109 @@ _nc_mouse_parse(SCREEN *sp, int runcount)
      * button basis, as long as the device-dependent mouse code puts stuff
      * on the queue in MEVENT format.
      */
-    if (runcount == 1) {
-       TR(MY_TRACE,
-          ("_nc_mouse_parse: returning simple mouse event %s at slot %ld",
-           _nc_tracemouse(sp, prev),
-           (long) IndexEV(sp, prev)));
-       return (prev->id >= NORMAL_EVENT)
-           ? ((prev->bstate & sp->_mouse_mask) ? TRUE : FALSE)
-           : FALSE;
-    }
 
-    /* find the start of the run */
-    runp = eventp;
-    for (n = runcount; n > 0; n--) {
-       runp = PREV(runp);
+    /*
+     * Reset all events that were not set, in case the user sometimes calls
+     * getmouse only once and other times until there are no more events in
+     * queue.
+     *
+     * This also allows reaching the beginning of the run.
+     */
+    ep = eventp;
+    for (n = runcount; n < EV_MAX; n++) {
+       ep->id = INVALID_EVENT;
+       ep = NEXT(ep);
     }
 
 #ifdef TRACE
     if (USE_TRACEF(TRACE_IEVENT)) {
        _trace_slot(sp, "before mouse press/release merge:");
        _tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",
-               RunParams(sp, eventp, runp),
+               RunParams(sp, eventp, ep),
                runcount);
        _nc_unlock_global(tracef);
     }
 #endif /* TRACE */
 
     /* first pass; merge press/release pairs */
-    do {
-       merge = FALSE;
-       for (ep = runp; (next = NEXT(ep)) != eventp; ep = next) {
+    endLoop = FALSE;
+    while (!endLoop) {
+       next = NEXT(ep);
+       if (next == eventp) {
+           /* Will end the loop, but compact before */
+           endLoop = TRUE;
+       } else {
 
 #define MASK_CHANGED(x) (!(ep->bstate & MASK_PRESS(x)) \
                      == !(next->bstate & MASK_RELEASE(x)))
 
-           if (ep->x == next->x && ep->y == next->y
+           if (ep->id != INVALID_EVENT && next->id != INVALID_EVENT
+               && ep->x == next->x && ep->y == next->y
                && (ep->bstate & BUTTON_PRESSED)
-               && MASK_CHANGED(1)
-               && MASK_CHANGED(2)
-               && MASK_CHANGED(3)
-               && MASK_CHANGED(4)
-#if NCURSES_MOUSE_VERSION == 2
-               && MASK_CHANGED(5)
-#endif
-               ) {
+               && (!(next->bstate & BUTTON_PRESSED))) {
+               bool changed = TRUE;
+
                for (b = 1; b <= MAX_BUTTONS; ++b) {
-                   if ((sp->_mouse_mask & MASK_CLICK(b))
-                       && (ep->bstate & MASK_PRESS(b))) {
-                       ep->bstate &= ~MASK_PRESS(b);
-                       ep->bstate |= MASK_CLICK(b);
-                       merge = TRUE;
+                   if (!MASK_CHANGED(b)) {
+                       changed = FALSE;
+                       break;
                    }
                }
-               if (merge)
-                   next->id = INVALID_EVENT;
+
+               if (changed) {
+                   merge = FALSE;
+                   for (b = 1; b <= MAX_BUTTONS; ++b) {
+                       if ((sp->_mouse_mask & MASK_CLICK(b))
+                           && (ep->bstate & MASK_PRESS(b))) {
+                           next->bstate &= ~MASK_RELEASE(b);
+                           next->bstate |= MASK_CLICK(b);
+                           merge = TRUE;
+                       }
+                   }
+                   if (merge)
+                       ep->id = INVALID_EVENT;
+               }
            }
        }
-    } while
-       (merge);
 
+       /* Compact valid events */
+       if (ep->id == INVALID_EVENT) {
+           if ((first_valid != NULL) && (first_invalid == NULL)) {
+               first_invalid = ep;
+           }
+       } else {
+           if (first_valid == NULL) {
+               first_valid = ep;
+           } else if (first_invalid != NULL) {
+               *first_invalid = *ep;
+               ep->id = INVALID_EVENT;
+               first_invalid = NEXT(first_invalid);
+           }
+       }
+
+       ep = next;
+    }
+
+    if (first_invalid != NULL) {
+       eventp = first_invalid;
+    }
 #ifdef TRACE
     if (USE_TRACEF(TRACE_IEVENT)) {
        _trace_slot(sp, "before mouse click merge:");
-       _tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",
-               RunParams(sp, eventp, runp),
-               runcount);
-       _nc_unlock_global(tracef);
+       if (first_valid == NULL) {
+           _tracef("_nc_mouse_parse: no valid event");
+       } else {
+           _tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",
+                   RunParams(sp, eventp, first_valid),
+                   runcount);
+           _nc_unlock_global(tracef);
+       }
     }
 #endif /* TRACE */
 
     /*
-     * Second pass; merge click runs.  At this point, click events are
-     * each followed by one invalid event. We merge click events
-     * forward in the queue.
+     * Second pass; merge click runs.  We merge click events forward in the
+     * queue.  For example, double click can be changed to triple click.
      *
      * NOTE: There is a problem with this design!  If the application
      * allows enough click events to pile up in the circular queue so
@@ -1187,87 +1238,98 @@ _nc_mouse_parse(SCREEN *sp, int runcount)
      * but the timer element would have to have sub-second resolution,
      * which would get us into portability trouble.
      */
-    do {
-       MEVENT *follower;
-
-       merge = FALSE;
-       for (ep = runp; (next = NEXT(ep)) != eventp; ep = next)
-           if (ep->id != INVALID_EVENT) {
-               if (next->id != INVALID_EVENT)
-                   continue;
-               follower = NEXT(next);
-               if (follower->id == INVALID_EVENT)
-                   continue;
-
-               /* merge click events forward */
-               if ((ep->bstate & BUTTON_CLICKED)
-                   && (follower->bstate & BUTTON_CLICKED)) {
-                   for (b = 1; b <= MAX_BUTTONS; ++b) {
-                       if ((sp->_mouse_mask & MASK_DOUBLE_CLICK(b))
-                           && (follower->bstate & MASK_CLICK(b))) {
-                           follower->bstate &= ~MASK_CLICK(b);
-                           follower->bstate |= MASK_DOUBLE_CLICK(b);
-                           merge = TRUE;
-                       }
+    first_invalid = NULL;
+    endLoop = (first_valid == NULL);
+    ep = first_valid;
+    while (!endLoop) {
+       next = NEXT(ep);
+
+       if (next == eventp) {
+           /* Will end the loop, but check event type and compact before */
+           endLoop = true;
+       } else {
+           /* merge click events forward */
+           if ((ep->bstate & BUTTON_CLICKED)
+               && (next->bstate & BUTTON_CLICKED)) {
+               merge = FALSE;
+               for (b = 1; b <= MAX_BUTTONS; ++b) {
+                   if ((sp->_mouse_mask & MASK_DOUBLE_CLICK(b))
+                       && (ep->bstate & MASK_CLICK(b))
+                       && (next->bstate & MASK_CLICK(b))) {
+                       next->bstate &= ~MASK_CLICK(b);
+                       next->bstate |= MASK_DOUBLE_CLICK(b);
+                       merge = TRUE;
                    }
-                   if (merge)
-                       ep->id = INVALID_EVENT;
                }
+               if (merge)
+                   ep->id = INVALID_EVENT;
+           }
 
-               /* merge double-click events forward */
-               if ((ep->bstate & BUTTON_DOUBLE_CLICKED)
-                   && (follower->bstate & BUTTON_CLICKED)) {
-                   for (b = 1; b <= MAX_BUTTONS; ++b) {
-                       if ((sp->_mouse_mask & MASK_TRIPLE_CLICK(b))
-                           && (follower->bstate & MASK_CLICK(b))) {
-                           follower->bstate &= ~MASK_CLICK(b);
-                           follower->bstate |= MASK_TRIPLE_CLICK(b);
-                           merge = TRUE;
-                       }
+           /* merge double-click events forward */
+           if ((ep->bstate & BUTTON_DOUBLE_CLICKED)
+               && (next->bstate & BUTTON_CLICKED)) {
+               merge = FALSE;
+               for (b = 1; b <= MAX_BUTTONS; ++b) {
+                   if ((sp->_mouse_mask & MASK_TRIPLE_CLICK(b))
+                       && (ep->bstate & MASK_DOUBLE_CLICK(b))
+                       && (next->bstate & MASK_CLICK(b))) {
+                       next->bstate &= ~MASK_CLICK(b);
+                       next->bstate |= MASK_TRIPLE_CLICK(b);
+                       merge = TRUE;
                    }
-                   if (merge)
-                       ep->id = INVALID_EVENT;
                }
+               if (merge)
+                   ep->id = INVALID_EVENT;
            }
-    } while
-       (merge);
+       }
 
-#ifdef TRACE
-    if (USE_TRACEF(TRACE_IEVENT)) {
-       _trace_slot(sp, "before mouse event queue compaction:");
-       _tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",
-               RunParams(sp, eventp, runp),
-               runcount);
-       _nc_unlock_global(tracef);
-    }
-#endif /* TRACE */
+       /* Discard event if it does not match event mask */
+       if (!(ep->bstate & sp->_mouse_mask)) {
+           ep->id = INVALID_EVENT;
+       }
 
-    /*
-     * Now try to throw away trailing events flagged invalid, or that
-     * don't match the current event mask.
-     */
-    for (; runcount; prev = PREV(eventp), runcount--)
-       if (prev->id == INVALID_EVENT || !(prev->bstate & sp->_mouse_mask)) {
-           sp->_mouse_eventp = eventp = prev;
+       /* Compact valid events */
+       if (ep->id == INVALID_EVENT) {
+           if (ep == first_valid) {
+               first_valid = next;
+           } else if (first_invalid == NULL) {
+               first_invalid = ep;
+           }
+       } else if (first_invalid != NULL) {
+           *first_invalid = *ep;
+           ep->id = INVALID_EVENT;
+           first_invalid = NEXT(first_invalid);
        }
+
+       ep = next;
+    }
+
+    if (first_invalid == NULL) {
+       first_invalid = eventp;
+    }
+    sp->_mouse_eventp = first_invalid;
+
 #ifdef TRACE
-    if (USE_TRACEF(TRACE_IEVENT)) {
-       _trace_slot(sp, "after mouse event queue compaction:");
-       _tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",
-               RunParams(sp, eventp, runp),
-               runcount);
-       _nc_unlock_global(tracef);
+    if (first_valid != NULL) {
+       if (USE_TRACEF(TRACE_IEVENT)) {
+           _trace_slot(sp, "after mouse event queue compaction:");
+           _tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",
+                   RunParams(sp, first_invalid, first_valid),
+                   runcount);
+           _nc_unlock_global(tracef);
+       }
+       for (ep = first_valid; ep != first_invalid; ep = NEXT(ep)) {
+           if (ep->id != INVALID_EVENT)
+               TR(MY_TRACE,
+                  ("_nc_mouse_parse: returning composite mouse event %s at slot %ld",
+                   _nc_tracemouse(sp, ep),
+                   (long) IndexEV(sp, ep)));
+       }
     }
-    for (ep = runp; ep != eventp; ep = NEXT(ep))
-       if (ep->id != INVALID_EVENT)
-           TR(MY_TRACE,
-              ("_nc_mouse_parse: returning composite mouse event %s at slot %ld",
-               _nc_tracemouse(sp, ep),
-               (long) IndexEV(sp, ep)));
 #endif /* TRACE */
 
     /* after all this, do we have a valid event? */
-    return (PREV(eventp)->id != INVALID_EVENT);
+    return (PREV(first_invalid)->id != INVALID_EVENT);
 }
 
 static void
@@ -1359,17 +1421,15 @@ NCURSES_SP_NAME(getmouse) (NCURSES_SP_DCLx MEVENT * aevent)
        /* compute the current-event pointer */
        MEVENT *prev = PREV(eventp);
 
-#if 1
-       /* copy the event we find there */
-       *aevent = *prev;
-
-       TR(TRACE_IEVENT, ("getmouse: returning event %s from slot %ld",
-                         _nc_tracemouse(SP_PARM, prev),
-                         (long) IndexEV(SP_PARM, prev)));
-
-       prev->id = INVALID_EVENT;       /* so the queue slot becomes free */
-       result = OK;
-#else /* 20100102 change prevented "release" events from returning to caller */
+       /*
+        * Discard events not matching mask (there could be still some if
+        * _nc_mouse_parse was not called, e.g., when _nc_mouse_inline returns
+        * false).
+        */
+       while ((prev->id != INVALID_EVENT) && (!(prev->bstate & SP_PARM->_mouse_mask))) {
+           prev->id = INVALID_EVENT;
+           prev = PREV(prev);
+       }
        if (prev->id != INVALID_EVENT) {
            /* copy the event we find there */
            *aevent = *prev;
@@ -1379,10 +1439,16 @@ NCURSES_SP_NAME(getmouse) (NCURSES_SP_DCLx MEVENT * aevent)
                              (long) IndexEV(SP_PARM, prev)));
 
            prev->id = INVALID_EVENT;   /* so the queue slot becomes free */
-           SP_PARM->_mouse_eventp = PREV(prev);
+           SP_PARM->_mouse_eventp = prev;
            result = OK;
+       } else {
+           /* Reset the provided event */
+           aevent->bstate = 0;
+           aevent->id = INVALID_EVENT;
+           aevent->x = 0;
+           aevent->y = 0;
+           aevent->z = 0;
        }
-#endif
     }
     returnCode(result);
 }
index e0992ab53343bab5114ec7219383d71d1cfb399c..309c3e82a3fd75238376e0d26df8cf42fb8efc77 100644 (file)
@@ -34,7 +34,7 @@
  ****************************************************************************/
 
 /*
- * $Id: curses.priv.h,v 1.482 2011/08/13 14:28:05 tom Exp $
+ * $Id: curses.priv.h,v 1.483 2011/09/17 19:08:20 tom Exp $
  *
  *     curses.priv.h
  *
@@ -1075,6 +1075,7 @@ struct screen {
        int             _mouse_fd;      /* file-descriptor, if any */
        bool            _mouse_active;  /* true if initialized */
        mmask_t         _mouse_mask;
+       mmask_t         _mouse_bstate;
        NCURSES_CONST char *_mouse_xtermcap; /* string to enable/disable mouse */
        MEVENT          _mouse_events[EV_MAX];  /* hold the last mouse event seen */
        MEVENT          *_mouse_eventp; /* next free slot in event queue */
index ea5f5f867dc4079ca421e154f989f1fa42f1f570..d5b5a63fac021f36a8c2a1bba6c395b99c148eaf 100644 (file)
@@ -40,7 +40,7 @@ AUTHOR
    Author: Eric S. Raymond <esr@snark.thyrsus.com> 1993
            Thomas E. Dickey (beginning revision 1.27 in 1996).
 
-$Id: ncurses.c,v 1.369 2011/08/20 15:49:08 tom Exp $
+$Id: ncurses.c,v 1.370 2011/09/17 21:57:49 tom Exp $
 
 ***************************************************************************/
 
@@ -3360,6 +3360,7 @@ show_upper_widechars(int first, int repeat, int space, attr_t attr, short pair)
             * The repeat-count may make text wrap - avoid that.
             */
            getyx(stdscr, y, x);
+           (void) y;
            if (x >= col + (COLS / 2) - 2)
                break;
        } while (--count > 0);