Annotation of 43BSDReno/contrib/emacs-18.55/src/xmenu.c, revision 1.1.1.1

1.1       root        1: /* X Communication module for terminals which understand the X protocol.
                      2:    Copyright (C) 1986, 1988 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU Emacs.
                      5: 
                      6: GNU Emacs is distributed in the hope that it will be useful,
                      7: but WITHOUT ANY WARRANTY.  No author or distributor
                      8: accepts responsibility to anyone for the consequences of using it
                      9: or for whether it serves any particular purpose or works at all,
                     10: unless he says so in writing.  Refer to the GNU Emacs General Public
                     11: License for full details.
                     12: 
                     13: Everyone is granted permission to copy, modify and redistribute
                     14: GNU Emacs, but only under the conditions described in the
                     15: GNU Emacs General Public License.   A copy of this license is
                     16: supposed to have been given to you along with GNU Emacs so you
                     17: can know your rights and responsibilities.  It should be in a
                     18: file named COPYING.  Among other things, the copyright notice
                     19: and this notice must be preserved on all copies.
                     20: 
                     21:  * X pop-up deck-of-cards menu facility for gnuemacs.
                     22:  *
                     23:  * Written by Jon Arnold and Roman Budzianowski
                     24:  * Mods and rewrite by Robert Krawitz
                     25:  *
                     26:  */
                     27: 
                     28: /* $Source: /u2/third_party/gnuemacs.chow/src/RCS/xmenu.c,v $
                     29:  * $Author: rlk $
                     30:  * $Locker:  $
                     31:  * $Header: xmenu.c,v 1.6 86/08/26 17:23:26 rlk Exp $
                     32:  *
                     33:  */
                     34: 
                     35: #ifndef lint
                     36: static char *rcsid_GXMenu_c = "$Header: xmenu.c,v 1.6 86/08/26 17:23:26 rlk Exp $";
                     37: #endif lint
                     38: 
                     39: /* On 4.3 this loses if it comes after xterm.h.  */
                     40: #include <signal.h>
                     41: #include "config.h"
                     42: #include "lisp.h"
                     43: #include "window.h"
                     44: 
                     45: /* This may include sys/types.h, and that somehow loses
                     46:    if this is not done before the other system files.  */
                     47: #ifdef X11
                     48: #include "x11term.h"
                     49: #else
                     50: #include "xterm.h"
                     51: #endif
                     52: 
                     53: /* Load sys/types.h if not already loaded.
                     54:    In some systems loading it twice is suicidal.  */
                     55: #ifndef makedev
                     56: #include <sys/types.h>
                     57: #endif
                     58: 
                     59: #include "dispextern.h"
                     60: 
                     61: #ifdef X11
                     62: #include "../oldXMenu/XMenu.h"
                     63: #define X11ONLY(arg) arg,
                     64: #else
                     65: #include <X/XMenu.h>
                     66: #define X11ONLY(arg)
                     67: #endif
                     68: 
                     69: #include "termopts.h"
                     70: 
                     71: #define min(x,y) (((x) < (y)) ? (x) : (y))
                     72: #define max(x,y) (((x) > (y)) ? (x) : (y))
                     73: 
                     74: #define NUL 0
                     75: 
                     76: #ifndef TRUE
                     77: #define TRUE 1
                     78: #define FALSE 0
                     79: #endif TRUE
                     80: 
                     81: #ifdef X11
                     82: extern XFontStruct *fontinfo;
                     83: extern Display *XXdisplay;
                     84: extern Window  XXwindow;
                     85: extern int     XXfontw;
                     86: extern int     XXfonth;
                     87: int    XXscreen;
                     88: #else
                     89: extern int XXxoffset,XXyoffset;
                     90: extern FontInfo *fontinfo;
                     91: #define        ButtonRelease ButtonReleased
                     92: #endif /* not X11 */
                     93: 
                     94: extern int (*handler)();
                     95: 
                     96: /*************************************************************/
                     97: 
                     98: /* Ignoring the args is easiest.  */
                     99: XMenuQuit ()
                    100: {
                    101:   error("Unknown XMenu error");
                    102: }
                    103: 
                    104: DEFUN ("x-popup-menu",Fx_popup_menu, Sx_popup_menu, 1, 2, 0,
                    105:        "Interface to XMenu library; permits creation and use of\n\
                    106: deck-of-cards pop-up menus.\n\
                    107: \n\
                    108: ARG is a position specification; it is a list of (Xoffset, Yoffset)\n\
                    109: from the top-left corner of the editor window.  Note that this offset\n\
                    110: is relative to the center of the first line in the first pane of the\n\
                    111: menu, not the top left of the menu as a whole.\n\
                    112: \n\
                    113: MENU is a specifier for a menu.  It is a list of the form\n\
                    114: (title pane1 pane2...), and each pane is a list of form\n\
                    115: (title (line item)...).  Each line should be a string, and item should\n\
                    116: be the return value for that line (i. e. if it is selected.")
                    117:        (arg,menu)
                    118:      Lisp_Object arg,menu;
                    119: {
                    120:   int number_of_panes;
                    121:   Lisp_Object XMenu_return;
                    122:   int XMenu_xpos,XMenu_ypos;
                    123:   char **menus;
                    124:   char ***names;
                    125:   Lisp_Object **obj_list;
                    126:   int *items;
                    127:   char *title;
                    128:   char *error_name;
                    129:   Lisp_Object ltitle, selection;
                    130:   Lisp_Object XEmacsMenu();
                    131:   int i, j;
                    132: #ifdef X11
                    133:   Window root_window, wjunk;
                    134:   int ijunk;
                    135:   extern Lisp_Object Vx_mouse_abs_pos;
                    136: #endif
                    137:   BLOCK_INPUT_DECLARE ();
                    138: 
                    139:   check_xterm();
                    140: #ifdef X11
                    141: #if 0
                    142:   if (interrupt_input)
                    143:     unrequest_sigio ();
                    144: #endif
                    145:   BLOCK_INPUT ();
                    146:   root_window = RootWindow (XXdisplay, DefaultScreen(XXdisplay));
                    147:   UNBLOCK_INPUT ();
                    148:   XMenu_xpos = Fcar (Vx_mouse_abs_pos);
                    149:   XMenu_ypos = Fcar (Fcdr (Vx_mouse_abs_pos));
                    150: #if 0
                    151:   if (interrupt_input)
                    152:     request_sigio ();
                    153: #endif
                    154: #else
                    155:   XMenu_xpos = fontinfo->width * XINT(Fcar(arg));
                    156:   XMenu_ypos = fontinfo->height * XINT(Fcar(Fcdr (arg)));
                    157:   XMenu_xpos += XXxoffset;
                    158:   XMenu_ypos += XXyoffset;
                    159: #endif
                    160:   ltitle = Fcar(menu);
                    161:   CHECK_STRING(ltitle,1);
                    162:   title = (char *) XSTRING(ltitle)->data;
                    163:   number_of_panes=list_of_panes(&obj_list, &menus, &names, &items, Fcdr(menu));
                    164: #ifdef XDEBUG
                    165:   fprintf(stderr,"Panes= %d\n", number_of_panes);
                    166:   for(i=0; i < number_of_panes; i++)
                    167:     {
                    168:       fprintf (stderr,"Pane %d lines %d title %s\n", i, items[i], menus[i]);
                    169:       for (j=0; j < items[i]; j++)
                    170:        {
                    171:          fprintf (stderr,"    Item %d %s\n", j, names[i][j]);
                    172:        }
                    173:     }
                    174: #endif
                    175:   BLOCK_INPUT ();
                    176: #ifdef X11
                    177:   XSetErrorHandler(XMenuQuit);
                    178:   selection = XEmacsMenu(root_window, XMenu_xpos, XMenu_ypos, names, menus,
                    179:                         items, number_of_panes, obj_list ,title, &error_name);
                    180:   XSetErrorHandler(handler);
                    181: #else
                    182:   XErrorHandler(XMenuQuit);
                    183:   selection = XEmacsMenu(RootWindow, XMenu_xpos, XMenu_ypos, names, menus,
                    184:                         items, number_of_panes, obj_list ,title, &error_name);
                    185:   XErrorHandler(handler);
                    186: #endif
                    187:   UNBLOCK_INPUT ();
                    188:   force_input_read ();
                    189:   /** fprintf(stderr,"selection = %x\n",selection);  **/
                    190:   if (selection != NUL)
                    191:     {                          /* selected something */
                    192:       XMenu_return = selection;
                    193:     }
                    194:   else
                    195:     {                          /* nothing selected */
                    196:       XMenu_return = Qnil;
                    197:     }
                    198:   /* now free up the strings */
                    199:   for (i=0; i < number_of_panes; i++)
                    200:     {
                    201:       free(names[i]);
                    202:       free(obj_list[i]);
                    203:     }
                    204:   free(menus);
                    205:   free(obj_list);
                    206:   free(names);
                    207:   free(items);
                    208:   /*   free(title); */
                    209:   if (error_name) error(error_name);
                    210:   return XMenu_return;
                    211: }
                    212: 
                    213: struct indices {
                    214:   int pane;
                    215:   int line;
                    216: };
                    217: 
                    218: Lisp_Object
                    219: XEmacsMenu(parent, startx, starty, line_list, pane_list, line_cnt,
                    220:           pane_cnt, item_list, title, error)
                    221:      Window parent;            
                    222:      int startx, starty;       /* upper left corner position BROKEN */
                    223:      char **line_list[];       /* list of strings for items */
                    224:      char *pane_list[];                /* list of pane titles */
                    225:      char *title;
                    226:      int pane_cnt;             /* total number of panes */
                    227:      Lisp_Object *item_list[]; /* All items */
                    228:      int line_cnt[];           /* Lines in each pane */
                    229:      char **error;             /* Error returned */
                    230: {
                    231:   XMenu *GXMenu;
                    232:   int last, panes, selidx, lpane, status;
                    233:   int lines, sofar;
                    234:   Lisp_Object entry;
                    235:   /* struct indices *datap, *datap_save; */
                    236:   char *datap;
                    237:   int ulx = 0, uly = 0, width, height;
                    238:   int dispwidth, dispheight;
                    239:   
                    240:   *error = (char *) 0;         /* Initialize error pointer to null */
                    241:   if ((GXMenu = XMenuCreate( X11ONLY (XXdisplay) parent, "emacs" )) == NUL )
                    242:     {
                    243:       *error = "Can't create menu";
                    244:       /* error("Can't create menu"); */
                    245:       return(0);
                    246:     }
                    247:   
                    248:   for (panes=0, lines=0; panes < pane_cnt; lines += line_cnt[panes], panes++ )
                    249:     ;
                    250:   /* datap = (struct indices *) xmalloc (lines * sizeof(struct indices)); */
                    251:   /*datap = (char *) xmalloc(lines * sizeof(char));
                    252:     datap_save = datap;*/
                    253:   
                    254:   for (panes = 0, sofar=0;panes < pane_cnt;sofar +=line_cnt[panes], panes++ )
                    255:     {
                    256:       /* create all the necessary panes */
                    257:       if ((lpane= XMenuAddPane( X11ONLY (XXdisplay) GXMenu, pane_list[panes] , TRUE ))
                    258:          == XM_FAILURE)
                    259:        {
                    260:          XMenuDestroy(X11ONLY (XXdisplay) GXMenu);
                    261:          *error = "Can't create pane";
                    262:          /* error("Can't create pane"); */
                    263:          /* free(datap); */
                    264:          return(0);
                    265:        }
                    266:       for ( selidx = 0; selidx < line_cnt[panes] ; selidx++ )
                    267:        {
                    268:          /* add the selection stuff to the menus */
                    269:          /* datap[selidx+sofar].pane = panes;
                    270:             datap[selidx+sofar].line = selidx; */
                    271:          if (XMenuAddSelection(X11ONLY (XXdisplay) GXMenu, lpane, 0, line_list[panes][selidx], TRUE)
                    272:              == XM_FAILURE)
                    273:            {
                    274:              XMenuDestroy(X11ONLY (XXdisplay) GXMenu);
                    275:              /* free(datap); */
                    276:              *error = "Can't add selection to menu";
                    277:              /* error ("Can't add selection to menu"); */
                    278:              return(0);
                    279:            }
                    280:        }
                    281:     }
                    282:   /* all set and ready to fly */
                    283:   XMenuRecompute(X11ONLY (XXdisplay) GXMenu);
                    284: #ifdef X11
                    285:   XXscreen = DefaultScreen(XXdisplay);
                    286:   dispwidth = DisplayWidth(XXdisplay, XXscreen);
                    287:   dispheight = DisplayHeight(XXdisplay, XXscreen);
                    288: #else
                    289:   dispwidth = DisplayWidth();
                    290:   dispheight = DisplayHeight();
                    291: #endif
                    292:   startx = min(startx, dispwidth);
                    293:   starty = min(starty, dispheight);
                    294:   startx = max(startx, 1);
                    295:   starty = max(starty, 1);
                    296:   XMenuLocate(X11ONLY (XXdisplay) GXMenu, 0, 0, startx, starty, &ulx, &uly, &width, &height);
                    297:   if (ulx+width > dispwidth)
                    298:     {
                    299:       startx -= (ulx + width) - dispwidth;
                    300:       ulx = dispwidth - width;
                    301:     }
                    302:   if (uly+height > dispheight)
                    303:     {
                    304:       starty -= (uly + height) - dispheight;
                    305:       uly = dispheight - height;
                    306:     }
                    307:   if (ulx < 0) startx -= ulx;
                    308:   if (uly < 0) starty -= uly;
                    309:     
                    310:   XMenuSetFreeze(GXMenu, TRUE);
                    311:   panes = selidx = 0;
                    312:   
                    313:   status = XMenuActivate(X11ONLY (XXdisplay) GXMenu, &panes, &selidx,
                    314:                         startx, starty, ButtonRelease, &datap);
                    315:   switch (status ) {
                    316:   case XM_SUCCESS:
                    317: #ifdef XDEBUG
                    318:     fprintf (stderr, "pane= %d line = %d\n", panes, selidx);
                    319: #endif
                    320:     entry = item_list[panes][selidx];
                    321:     break;
                    322:   case XM_FAILURE:
                    323:     /*free (datap_save); */
                    324:     XMenuDestroy(X11ONLY (XXdisplay) GXMenu);
                    325:     *error = "Can't activate menu";
                    326:     /* error("Can't activate menu"); */
                    327:   case XM_IA_SELECT:
                    328:   case XM_NO_SELECT:
                    329:     entry = Qnil;
                    330:     break;
                    331:   }
                    332:   XMenuDestroy(X11ONLY (XXdisplay) GXMenu);
                    333:   /*free(datap_save);*/
                    334:   return(entry);
                    335: }
                    336: 
                    337: syms_of_xmenu ()
                    338: {
                    339:   defsubr (&Sx_popup_menu);
                    340: }
                    341: 
                    342: list_of_panes (vector, panes, names, items, menu)
                    343:      Lisp_Object ***vector;    /* RETURN all menu objects */
                    344:      char ***panes;            /* RETURN pane names */
                    345:      char ****names;           /* RETURN all line names */
                    346:      int **items;              /* RETURN number of items per pane */
                    347:      Lisp_Object menu;
                    348: {
                    349:   Lisp_Object tail, item, item1;
                    350:   int i;
                    351:   
                    352:   if (XTYPE (menu) != Lisp_Cons) menu = wrong_type_argument(Qlistp, item);
                    353:   
                    354:   i= XFASTINT(Flength(menu,1));
                    355: 
                    356:   *vector = (Lisp_Object **) xmalloc(i * sizeof (Lisp_Object *));
                    357:   *panes = (char **) xmalloc(i * sizeof (char *));
                    358:   *items = (int *) xmalloc(i * sizeof (int));
                    359:   *names = (char ***) xmalloc(i * sizeof (char **));
                    360: 
                    361:   for (i=0,tail = menu; !NULL (tail); tail = Fcdr (tail), i++)
                    362:     {
                    363:        item = Fcdr(Fcar(tail));
                    364:        if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument(Qlistp, item);
                    365: #ifdef XDEBUG
                    366:        fprintf (stderr, "list_of_panes check tail, i=%d\n", i);
                    367: #endif
                    368:        item1 = Fcar(Fcar(tail));
                    369:        CHECK_STRING (item1, 1);
                    370: #ifdef XDEBUG
                    371:        fprintf (stderr, "list_of_panes check pane, i=%d%s\n", i,
                    372:                XSTRING(item1)->data);
                    373: #endif
                    374:        (*panes)[i] = (char *) XSTRING(item1)->data;
                    375:        (*items)[i] = list_of_items ((*vector)+i, (*names)+i, item);
                    376:        /* (*panes)[i] = (char *) xmalloc((XSTRING(item1)->size)+1);
                    377:          bcopy (XSTRING (item1)->data, (*panes)[i], XSTRING(item1)->size + 1)
                    378:          ; */
                    379:     }
                    380:   return i;
                    381: }
                    382:      
                    383: 
                    384: list_of_items (vector,names,pane)  /* get list from emacs and put to vector */
                    385:      Lisp_Object **vector;     /* RETURN menu "objects" */
                    386:      char ***names;            /* RETURN line names */
                    387:      Lisp_Object pane;
                    388: {
                    389:   Lisp_Object tail, item, item1;
                    390:   int i;
                    391: 
                    392:   if (XTYPE (pane) != Lisp_Cons) pane = wrong_type_argument(Qlistp, item);
                    393:   
                    394:   i= XFASTINT(Flength(pane,1));
                    395: 
                    396:   *vector = (Lisp_Object *) xmalloc(i * sizeof (Lisp_Object));
                    397:   *names = (char **) xmalloc(i * sizeof (char *));
                    398: 
                    399:   for (i=0,tail = pane; !NULL (tail); tail = Fcdr (tail), i++)
                    400:     {
                    401:        item = Fcar(tail);
                    402:        if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument(Qlistp, item);
                    403: #ifdef XDEBUG
                    404:        fprintf (stderr, "list_of_items check tail, i=%d\n", i);
                    405: #endif
                    406:        (*vector)[i] =  Fcdr (item);
                    407:        item1 = Fcar(item);
                    408:        CHECK_STRING (item1, 1);
                    409: #ifdef XDEBUG
                    410:        fprintf (stderr, "list_of_items check item, i=%d%s\n", i,
                    411:                XSTRING(item1)->data);
                    412: #endif
                    413:        (*names)[i] = (char *) XSTRING(item1)->data;
                    414:        /* (*names)[i] = (char *) xmalloc((XSTRING(item1)->size)+1);
                    415:        bcopy (XSTRING (item1)->data, (*names)[i], XSTRING(item1)->size + 1); */
                    416:     }
                    417:   return i;
                    418: }
                    419: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.