Commits

Michele Bini committed b50d27d

Convert menu callback lists back to doubly-linked for improved performance.

Comments (0)

Files changed (2)

     gdk_window_set_cursor (GDK_WINDOW (children->data), cursor);
 }
 
+static Lisp_Object
+xg_list_insert(Lisp_Object element, Lisp_Object ring) {
+  if (NILP(ring)) {
+    XSETMENUCBNEXT(element, element);
+    XSETMENUCBPREV(element, element);
+  } else {
+    Lisp_Object p = XMENUCBPREV(ring);
+    XSETMENUCBNEXT(element, ring);
+    XSETMENUCBPREV(element, p);
+    XSETMENUCBNEXT(p, element);
+    XSETMENUCBPREV(ring, element);
+  }
+  return element;
+}
+
+static Lisp_Object
+xg_list_remove(Lisp_Object element, Lisp_Object ring) {
+  if (NILP(ring)) {
+    return ring;
+  } else {
+    Lisp_Object p, n;
+    p = XMENUCBPREV(element);
+    n = XMENUCBNEXT(element);
+    XSETMENUCBNEXT(p, n);
+    XSETMENUCBPREV(n, p);
+    if (EQ(n, element)) {
+      return Qnil;
+    } else {
+      return n;
+    }
+  }
+}
+
 /* Allocate and return a utf8 version of STR.  If STR is already
    utf8 or NULL, just return a copy of STR.
    A new string is allocated and the caller must free the result
     cl_data->highlight_cb = highlight_cb;
     cl_data->ref_count = 1;
 
-    XSETMENUCBDATA(cl_data_lisp, cl_data);
-    XSETMENUBARVECTOR(cl_data_lisp, f->menu_bar_vector);
+    XSETMENUCBDATA (cl_data_lisp, cl_data);
+
+    XSETMENUCBNEXT     (cl_data_lisp, Qnil);
+    XSETMENUCBPREV     (cl_data_lisp, Qnil);
+    XSETMENUBARVECTOR  (cl_data_lisp, f->menu_bar_vector);
+
     SET_GC_ROOT(xg_menu_cb_list,
-		Fcons(cl_data_lisp,
-		      GET_GC_ROOT(xg_menu_cb_list)));
+		xg_list_insert(cl_data_lisp, 
+			       GET_GC_ROOT(xg_menu_cb_list)));
   }
   return cl_data_lisp;
 }
       if (cl_data->ref_count == 0)
         {
 	  SET_GC_ROOT(xg_menu_cb_list,
-		      Fdelq(cl_data_lisp,
-			    GET_GC_ROOT(xg_menu_cb_list)));
+		      xg_list_remove(cl_data_lisp,
+				     GET_GC_ROOT(xg_menu_cb_list)));
         }
     }
 }
   if (!NILP(data))
     {
       SET_GC_ROOT(xg_menu_item_cb_list,
-		  Fdelq(data,
-			GET_GC_ROOT(xg_menu_item_cb_list)));
+		  xg_list_remove(data,
+				 GET_GC_ROOT(xg_menu_item_cb_list)));
     }
 }
 
   cb_data = ALLOCATE_MENUITEMCBDATA();
 
   cb_data->select_id = 0;
-  XSETMENUITEMCBDATA(cb_data_lisp, cb_data);
-  XSETMENUITEMHELP(cb_data_lisp, item->help);
-  XSETMENUITEMMENU(cb_data_lisp, cl_data_lisp);
+  XSETMENUITEMCBDATA (cb_data_lisp, cb_data);
+  XSETMENUCBNEXT     (cb_data_lisp, Qnil);
+  XSETMENUCBPREV     (cb_data_lisp, Qnil);
+  XSETMENUITEMHELP   (cb_data_lisp, item->help);
+  XSETMENUITEMMENU   (cb_data_lisp, cl_data_lisp);
   cb_data->call_data = item->call_data;
 
   XSETMENUITEMCBDATA(cb_data_lisp, cb_data);
 
   SET_GC_ROOT(xg_menu_item_cb_list,
-	      Fcons(cb_data_lisp,
-		    GET_GC_ROOT(xg_menu_item_cb_list)));
+	      xg_list_insert(cb_data_lisp,
+			     GET_GC_ROOT(xg_menu_item_cb_list)));
 
   g_signal_connect (G_OBJECT (w),
                     "destroy",
 #define XMENUCBDATA(a) ((xg_menu_cb_data *)XPNTR_OR_NULL(a))
 #define XSETMENUCBDATA(a, b) XSETPSEUDOVECTOR(a, b, PVEC_OTHER)
 
+  Lisp_Object   next, prev;
+#define XMENUCBNEXT(cbdata) AREF(cbdata, 0)
+#define XSETMENUCBNEXT(cbdata, x) ASET(cbdata, 0, x)
+#define XMENUCBPREV(cbdata) AREF(cbdata, 1)
+#define XSETMENUCBPREV(cbdata, x) ASET(cbdata, 1, x)
   Lisp_Object   ___menu_bar_vector;
-#define XMENUBARVECTOR(cbdata) AREF(cbdata, 0)
-#define XSETMENUBARVECTOR(cbdata, x) ASET(cbdata, 0, x)
+#define XMENUBARVECTOR(cbdata) AREF(cbdata, 2)
+#define XSETMENUBARVECTOR(cbdata, x) ASET(cbdata, 2, x)
 
 #define ALLOCATE_MENUCBDATA()				\
   ALLOCATE_PSEUDOVECTOR(xg_menu_cb_data,		\
 #define XMENUITEMCBDATA(a) ((xg_menu_item_cb_data *)XPNTR_OR_NULL(a))
 #define XSETMENUITEMCBDATA(a, b) XSETPSEUDOVECTOR(a, b, PVEC_OTHER)
 
+  Lisp_Object   next, prev;
   Lisp_Object   ___help;
-#define XMENUITEMHELP(cbdata) AREF(cbdata, 0)
-#define XSETMENUITEMHELP(cbdata, x) ASET(cbdata, 0, x)
+#define XMENUITEMHELP(cbdata) AREF(cbdata, 2)
+#define XSETMENUITEMHELP(cbdata, x) ASET(cbdata, 2, x)
   Lisp_Object   ___menu;
-#define XMENUITEMMENU(cbdata) AREF(cbdata, 1)
-#define XSETMENUITEMMENU(cbdata, x) ASET(cbdata, 1, x)
+#define XMENUITEMMENU(cbdata) AREF(cbdata, 3)
+#define XSETMENUITEMMENU(cbdata, x) ASET(cbdata, 3, x)
 
 #define ALLOCATE_MENUITEMCBDATA()			\
   ALLOCATE_PSEUDOVECTOR(xg_menu_item_cb_data,		\