summaryrefslogtreecommitdiff
path: root/src/xmenu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmenu.c')
-rw-r--r--src/xmenu.c338
1 files changed, 193 insertions, 145 deletions
diff --git a/src/xmenu.c b/src/xmenu.c
index 553e5b35a7a..ff82793f24d 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -15,9 +15,9 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-/* X pop-up deck-of-cards menu facility for gnuemacs.
+ * X pop-up deck-of-cards menu facility for gnuemacs.
*
* Written by Jon Arnold and Roman Budzianowski
* Mods and rewrite by Robert Krawitz
@@ -34,20 +34,28 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef lint
static char *rcsid_GXMenu_c = "$Header: xmenu.c,v 1.6 86/08/26 17:23:26 rlk Exp $";
#endif lint
-#ifdef XDEBUG
-#include <stdio.h>
-#endif
/* On 4.3 this loses if it comes after xterm.h. */
#include <signal.h>
#include "config.h"
-#include "lisp.h"
-#include "screen.h"
-#include "window.h"
/* This may include sys/types.h, and that somehow loses
if this is not done before the other system files. */
+#ifdef X11
+#include "x11term.h"
+/* #include <X11/X10.h> */
+#else
#include "xterm.h"
+#endif
+
+/* Prepare for lisp.h definition of NULL.
+ Sometimes x11term.h includes stddef.h. */
+#ifdef NULL
+#undef NULL
+#endif
+
+#include "lisp.h"
+#include "window.h"
/* Load sys/types.h if not already loaded.
In some systems loading it twice is suicidal. */
@@ -57,12 +65,16 @@ static char *rcsid_GXMenu_c = "$Header: xmenu.c,v 1.6 86/08/26 17:23:26 rlk Exp
#include "dispextern.h"
-#ifdef HAVE_X11
+#ifdef X11
#include "../oldXMenu/XMenu.h"
+#define X11ONLY(arg) arg,
#else
#include <X/XMenu.h>
+#define X11ONLY(arg)
#endif
+#include "termopts.h"
+
#define min(x,y) (((x) < (y)) ? (x) : (y))
#define max(x,y) (((x) > (y)) ? (x) : (y))
@@ -73,43 +85,48 @@ static char *rcsid_GXMenu_c = "$Header: xmenu.c,v 1.6 86/08/26 17:23:26 rlk Exp
#define FALSE 0
#endif TRUE
-#ifdef HAVE_X11
-extern Display *x_current_display;
+#ifdef X11
+extern XFontStruct *fontinfo;
+extern Display *XXdisplay;
+extern Window XXwindow;
+extern int XXfontw;
+extern int XXfonth;
+int XXscreen;
#else
+extern int XXxoffset,XXyoffset;
+extern FontInfo *fontinfo;
#define ButtonReleaseMask ButtonReleased
-#endif /* not HAVE_X11 */
+#endif /* not X11 */
-Lisp_Object xmenu_show ();
-extern int x_error_handler ();
+extern int (*handler)();
/*************************************************************/
-#if 0
/* Ignoring the args is easiest. */
-xmenu_quit ()
+XMenuQuit ()
{
- error ("Unknown XMenu error");
+ error("Unknown XMenu error");
}
-#endif
DEFUN ("x-popup-menu",Fx_popup_menu, Sx_popup_menu, 1, 2, 0,
- "Pop up a deck-of-cards menu and return user's selection.\n\
-ARG is a position specification: a list ((XOFFSET YOFFSET) WINDOW)\n\
-where XOFFSET and YOFFSET are positions in characters from the top left\n\
-corner of WINDOW's screen. A mouse-event list will serve for this.\n\
-This controls the position of the center of the first line\n\
-in the first pane of the menu, not the top left of the menu as a whole.\n\
+ "Interface to XMenu library; permits creation and use of\n\
+deck-of-cards pop-up menus.\n\
+\n\
+ARG is a position specification; it is a list of (Xoffset, Yoffset)\n\
+from the top-left corner of the editor window. Note that this offset\n\
+is relative to the center of the first line in the first pane of the\n\
+menu, not the top left of the menu as a whole.\n\
\n\
MENU is a specifier for a menu. It is a list of the form\n\
-\(TITLE PANE1 PANE2...), and each pane is a list of form\n\
-\(TITLE (LINE ITEM)...). Each line should be a string, and item should\n\
-be the return value for that line (i.e. if it is selected.")
- (arg, menu)
- Lisp_Object arg, menu;
+(title pane1 pane2...), and each pane is a list of form\n\
+(title (line item)...). Each line should be a string, and item should\n\
+be the return value for that line (i. e. if it is selected.")
+ (arg,menu)
+ Lisp_Object arg,menu;
{
int number_of_panes;
Lisp_Object XMenu_return;
- int XMenu_xpos, XMenu_ypos;
+ int XMenu_xpos,XMenu_ypos;
char **menus;
char ***names;
Lisp_Object **obj_list;
@@ -117,43 +134,66 @@ be the return value for that line (i.e. if it is selected.")
char *title;
char *error_name;
Lisp_Object ltitle, selection;
+ Lisp_Object XEmacsMenu();
int i, j;
- SCREEN_PTR s;
- Lisp_Object x, y, window;
-
- window = Fcar (Fcdr (arg));
- x = Fcar (Fcar (arg));
- y = Fcar (Fcdr (Fcar (arg)));
- CHECK_WINDOW (window, 0);
- CHECK_NUMBER (x, 0);
- CHECK_NUMBER (y, 0);
- s = XSCREEN (WINDOW_SCREEN (XWINDOW (window)));
-
- XMenu_xpos = FONT_WIDTH (s->display.x->font) * XINT (x);
- XMenu_ypos = FONT_HEIGHT (s->display.x->font) * XINT (y);
- XMenu_xpos += s->display.x->left_pos;
- XMenu_ypos += s->display.x->top_pos;
-
- ltitle = Fcar (menu);
- CHECK_STRING (ltitle, 1);
- title = (char *) XSTRING (ltitle)->data;
- number_of_panes=list_of_panes (&obj_list, &menus, &names, &items, Fcdr (menu));
+#ifdef X11
+ Window root_window, wjunk;
+ int ijunk;
+ extern Lisp_Object Vx_mouse_abs_pos;
+#endif
+ BLOCK_INPUT_DECLARE ();
+
+ check_xterm();
+#ifdef X11
+#if 0
+ if (interrupt_input)
+ unrequest_sigio ();
+#endif
+ BLOCK_INPUT ();
+ root_window = RootWindow (XXdisplay, DefaultScreen(XXdisplay));
+ UNBLOCK_INPUT ();
+ XMenu_xpos = Fcar (Vx_mouse_abs_pos);
+ XMenu_ypos = Fcar (Fcdr (Vx_mouse_abs_pos));
+#if 0
+ if (interrupt_input)
+ request_sigio ();
+#endif
+#else
+ XMenu_xpos = fontinfo->width * XINT(Fcar(arg));
+ XMenu_ypos = fontinfo->height * XINT(Fcar(Fcdr (arg)));
+ XMenu_xpos += XXxoffset;
+ XMenu_ypos += XXyoffset;
+#endif
+ ltitle = Fcar(menu);
+ CHECK_STRING(ltitle,1);
+ title = (char *) XSTRING(ltitle)->data;
+ number_of_panes=list_of_panes(&obj_list, &menus, &names, &items, Fcdr(menu));
#ifdef XDEBUG
- fprintf (stderr, "Panes= %d\n", number_of_panes);
- for (i=0; i < number_of_panes; i++)
+ fprintf(stderr,"Panes= %d\n", number_of_panes);
+ for(i=0; i < number_of_panes; i++)
{
- fprintf (stderr, "Pane %d lines %d title %s\n", i, items[i], menus[i]);
+ fprintf (stderr,"Pane %d lines %d title %s\n", i, items[i], menus[i]);
for (j=0; j < items[i]; j++)
{
- fprintf (stderr, " Item %d %s\n", j, names[i][j]);
+ fprintf (stderr," Item %d %s\n", j, names[i][j]);
}
}
#endif
- BLOCK_INPUT;
- selection = xmenu_show (ROOT_WINDOW, XMenu_xpos, XMenu_ypos, names, menus,
- items, number_of_panes, obj_list, title, &error_name);
- UNBLOCK_INPUT;
- /** fprintf (stderr, "selection = %x\n", selection); **/
+ BLOCK_INPUT ();
+#ifdef X11
+ XSetErrorHandler(XMenuQuit);
+ selection = XEmacsMenu(root_window, XMenu_xpos, XMenu_ypos, names, menus,
+ items, number_of_panes, obj_list ,title, &error_name);
+ XSetErrorHandler(handler);
+#else
+ XErrorHandler(XMenuQuit);
+ selection = XEmacsMenu(RootWindow, XMenu_xpos, XMenu_ypos, names, menus,
+ items, number_of_panes, obj_list ,title, &error_name);
+ XErrorHandler(handler);
+#endif
+ UNBLOCK_INPUT ();
+ force_input_read ();
+ /** fprintf(stderr,"selection = %x\n",selection); **/
if (selection != NUL)
{ /* selected something */
XMenu_return = selection;
@@ -165,15 +205,15 @@ be the return value for that line (i.e. if it is selected.")
/* now free up the strings */
for (i=0; i < number_of_panes; i++)
{
- free (names[i]);
- free (obj_list[i]);
+ free(names[i]);
+ free(obj_list[i]);
}
- free (menus);
- free (obj_list);
- free (names);
- free (items);
- /* free (title); */
- if (error_name) error (error_name);
+ free(menus);
+ free(obj_list);
+ free(names);
+ free(items);
+ /* free(title); */
+ if (error_name) error(error_name);
return XMenu_return;
}
@@ -183,8 +223,8 @@ struct indices {
};
Lisp_Object
-xmenu_show (parent, startx, starty, line_list, pane_list, line_cnt,
- pane_cnt, item_list, title, error)
+XEmacsMenu(parent, startx, starty, line_list, pane_list, line_cnt,
+ pane_cnt, item_list, title, error)
Window parent;
int startx, starty; /* upper left corner position BROKEN */
char **line_list[]; /* list of strings for items */
@@ -201,60 +241,66 @@ xmenu_show (parent, startx, starty, line_list, pane_list, line_cnt,
Lisp_Object entry;
/* struct indices *datap, *datap_save; */
char *datap;
- int ulx, uly, width, height;
+ int ulx = 0, uly = 0, width, height;
int dispwidth, dispheight;
*error = (char *) 0; /* Initialize error pointer to null */
- GXMenu = XMenuCreate (XDISPLAY parent, "emacs");
- if (GXMenu == NUL)
+ if ((GXMenu = XMenuCreate( X11ONLY (XXdisplay) parent, "emacs" )) == NUL )
{
*error = "Can't create menu";
- return (0);
+ /* error("Can't create menu"); */
+ return(0);
}
- for (panes=0, lines=0; panes < pane_cnt; lines += line_cnt[panes], panes++)
+ for (panes=0, lines=0; panes < pane_cnt; lines += line_cnt[panes], panes++ )
;
- /* datap = (struct indices *) xmalloc (lines * sizeof (struct indices)); */
- /*datap = (char *) xmalloc (lines * sizeof (char));
+ /* datap = (struct indices *) xmalloc (lines * sizeof(struct indices)); */
+ /*datap = (char *) xmalloc(lines * sizeof(char));
datap_save = datap;*/
- for (panes = 0, sofar=0;panes < pane_cnt;sofar +=line_cnt[panes], panes++)
+ for (panes = 0, sofar=0;panes < pane_cnt;sofar +=line_cnt[panes], panes++ )
{
/* create all the necessary panes */
- lpane = XMenuAddPane (XDISPLAY GXMenu, pane_list[panes], TRUE);
- if (lpane == XM_FAILURE)
+ if ((lpane= XMenuAddPane( X11ONLY (XXdisplay) GXMenu, pane_list[panes] , TRUE ))
+ == XM_FAILURE)
{
- XMenuDestroy (XDISPLAY GXMenu);
+ XMenuDestroy(X11ONLY (XXdisplay) GXMenu);
*error = "Can't create pane";
- return (0);
+ /* error("Can't create pane"); */
+ /* free(datap); */
+ return(0);
}
- for (selidx = 0; selidx < line_cnt[panes] ; selidx++)
+ for ( selidx = 0; selidx < line_cnt[panes] ; selidx++ )
{
/* add the selection stuff to the menus */
/* datap[selidx+sofar].pane = panes;
datap[selidx+sofar].line = selidx; */
- if (XMenuAddSelection (XDISPLAY GXMenu, lpane, 0,
- line_list[panes][selidx], TRUE)
+ if (XMenuAddSelection(X11ONLY (XXdisplay) GXMenu, lpane, 0, line_list[panes][selidx], TRUE)
== XM_FAILURE)
{
- XMenuDestroy (XDISPLAY GXMenu);
- /* free (datap); */
+ XMenuDestroy(X11ONLY (XXdisplay) GXMenu);
+ /* free(datap); */
*error = "Can't add selection to menu";
/* error ("Can't add selection to menu"); */
- return (0);
+ return(0);
}
}
}
/* all set and ready to fly */
- XMenuRecompute (XDISPLAY GXMenu);
- dispwidth = DisplayWidth (x_current_display, XDefaultScreen (x_current_display));
- dispheight = DisplayHeight (x_current_display, XDefaultScreen (x_current_display));
- startx = min (startx, dispwidth);
- starty = min (starty, dispheight);
- startx = max (startx, 1);
- starty = max (starty, 1);
- XMenuLocate (XDISPLAY GXMenu, 0, 0, startx, starty,
- &ulx, &uly, &width, &height);
+ XMenuRecompute(X11ONLY (XXdisplay) GXMenu);
+#ifdef X11
+ XXscreen = DefaultScreen(XXdisplay);
+ dispwidth = DisplayWidth(XXdisplay, XXscreen);
+ dispheight = DisplayHeight(XXdisplay, XXscreen);
+#else
+ dispwidth = DisplayWidth();
+ dispheight = DisplayHeight();
+#endif
+ startx = min(startx, dispwidth);
+ starty = min(starty, dispheight);
+ startx = max(startx, 1);
+ starty = max(starty, 1);
+ XMenuLocate(X11ONLY (XXdisplay) GXMenu, 0, 0, startx, starty, &ulx, &uly, &width, &height);
if (ulx+width > dispwidth)
{
startx -= (ulx + width) - dispwidth;
@@ -268,32 +314,31 @@ xmenu_show (parent, startx, starty, line_list, pane_list, line_cnt,
if (ulx < 0) startx -= ulx;
if (uly < 0) starty -= uly;
- XMenuSetFreeze (GXMenu, TRUE);
+ XMenuSetFreeze(GXMenu, TRUE);
panes = selidx = 0;
- status = XMenuActivate (XDISPLAY GXMenu, &panes, &selidx,
- startx, starty, ButtonReleaseMask, &datap);
- switch (status)
- {
- case XM_SUCCESS:
+ status = XMenuActivate(X11ONLY (XXdisplay) GXMenu, &panes, &selidx,
+ startx, starty, ButtonReleaseMask, &datap);
+ switch (status ) {
+ case XM_SUCCESS:
#ifdef XDEBUG
- fprintf (stderr, "pane= %d line = %d\n", panes, selidx);
+ fprintf (stderr, "pane= %d line = %d\n", panes, selidx);
#endif
- entry = item_list[panes][selidx];
- break;
- case XM_FAILURE:
- /*free (datap_save); */
- XMenuDestroy (XDISPLAY GXMenu);
- *error = "Can't activate menu";
- /* error ("Can't activate menu"); */
- case XM_IA_SELECT:
- case XM_NO_SELECT:
- entry = Qnil;
- break;
- }
- XMenuDestroy (XDISPLAY GXMenu);
- /*free (datap_save);*/
- return (entry);
+ entry = item_list[panes][selidx];
+ break;
+ case XM_FAILURE:
+ /*free (datap_save); */
+ XMenuDestroy(X11ONLY (XXdisplay) GXMenu);
+ *error = "Can't activate menu";
+ /* error("Can't activate menu"); */
+ case XM_IA_SELECT:
+ case XM_NO_SELECT:
+ entry = Qnil;
+ break;
+ }
+ XMenuDestroy(X11ONLY (XXdisplay) GXMenu);
+ /*free(datap_save);*/
+ return(entry);
}
syms_of_xmenu ()
@@ -311,39 +356,39 @@ list_of_panes (vector, panes, names, items, menu)
Lisp_Object tail, item, item1;
int i;
- if (XTYPE (menu) != Lisp_Cons) menu = wrong_type_argument (Qlistp, menu);
-
- i= XFASTINT (Flength (menu, 1));
+ if (XTYPE (menu) != Lisp_Cons) menu = wrong_type_argument(Qlistp, menu);
+
+ i= XFASTINT(Flength(menu,1));
- *vector = (Lisp_Object **) xmalloc (i * sizeof (Lisp_Object *));
- *panes = (char **) xmalloc (i * sizeof (char *));
- *items = (int *) xmalloc (i * sizeof (int));
- *names = (char ***) xmalloc (i * sizeof (char **));
+ *vector = (Lisp_Object **) xmalloc(i * sizeof (Lisp_Object *));
+ *panes = (char **) xmalloc(i * sizeof (char *));
+ *items = (int *) xmalloc(i * sizeof (int));
+ *names = (char ***) xmalloc(i * sizeof (char **));
- for (i=0, tail = menu; !NULL (tail); tail = Fcdr (tail), i++)
+ for (i=0,tail = menu; !NULL (tail); tail = Fcdr (tail), i++)
{
- item = Fcdr (Fcar (tail));
- if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument (Qlistp, item);
+ item = Fcdr(Fcar(tail));
+ if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument(Qlistp, item);
#ifdef XDEBUG
fprintf (stderr, "list_of_panes check tail, i=%d\n", i);
#endif
- item1 = Fcar (Fcar (tail));
+ item1 = Fcar(Fcar(tail));
CHECK_STRING (item1, 1);
#ifdef XDEBUG
fprintf (stderr, "list_of_panes check pane, i=%d%s\n", i,
- XSTRING (item1)->data);
+ XSTRING(item1)->data);
#endif
- (*panes)[i] = (char *) XSTRING (item1)->data;
+ (*panes)[i] = (char *) XSTRING(item1)->data;
(*items)[i] = list_of_items ((*vector)+i, (*names)+i, item);
- /* (*panes)[i] = (char *) xmalloc ((XSTRING (item1)->size)+1);
- bcopy (XSTRING (item1)->data, (*panes)[i], XSTRING (item1)->size + 1)
+ /* (*panes)[i] = (char *) xmalloc((XSTRING(item1)->size)+1);
+ bcopy (XSTRING (item1)->data, (*panes)[i], XSTRING(item1)->size + 1)
; */
}
return i;
}
-list_of_items (vector, names, pane) /* get list from emacs and put to vector */
+list_of_items (vector,names,pane) /* get list from emacs and put to vector */
Lisp_Object **vector; /* RETURN menu "objects" */
char ***names; /* RETURN line names */
Lisp_Object pane;
@@ -351,28 +396,31 @@ list_of_items (vector, names, pane) /* get list from emacs and put to vector */
Lisp_Object tail, item, item1;
int i;
- if (XTYPE (pane) != Lisp_Cons) pane = wrong_type_argument (Qlistp, pane);
-
- i= XFASTINT (Flength (pane, 1));
+ if (XTYPE (pane) != Lisp_Cons) pane = wrong_type_argument(Qlistp, pane);
+
+ i= XFASTINT(Flength(pane,1));
- *vector = (Lisp_Object *) xmalloc (i * sizeof (Lisp_Object));
- *names = (char **) xmalloc (i * sizeof (char *));
+ *vector = (Lisp_Object *) xmalloc(i * sizeof (Lisp_Object));
+ *names = (char **) xmalloc(i * sizeof (char *));
- for (i=0, tail = pane; !NULL (tail); tail = Fcdr (tail), i++)
+ for (i=0,tail = pane; !NULL (tail); tail = Fcdr (tail), i++)
{
- item = Fcar (tail);
- if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument (Qlistp, item);
+ item = Fcar(tail);
+ if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument(Qlistp, item);
#ifdef XDEBUG
fprintf (stderr, "list_of_items check tail, i=%d\n", i);
#endif
(*vector)[i] = Fcdr (item);
- item1 = Fcar (item);
+ item1 = Fcar(item);
CHECK_STRING (item1, 1);
#ifdef XDEBUG
fprintf (stderr, "list_of_items check item, i=%d%s\n", i,
- XSTRING (item1)->data);
+ XSTRING(item1)->data);
#endif
- (*names)[i] = (char *) XSTRING (item1)->data;
+ (*names)[i] = (char *) XSTRING(item1)->data;
+ /* (*names)[i] = (char *) xmalloc((XSTRING(item1)->size)+1);
+ bcopy (XSTRING (item1)->data, (*names)[i], XSTRING(item1)->size + 1); */
}
return i;
}
+