Annotation of researchv9/X11/src/X.V11R1/clients/emacs/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 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: /@/orpheus/u1/X11/clients/emacs/RCS/xmenu.c,v $
                     29:  * $Author: newman $
                     30:  * $Locker:  $
                     31:  * $Header: xmenu.c,v 1.1 87/09/12 16:33:40 newman Exp $
                     32:  *
                     33:  */
                     34: 
                     35: #ifndef lint
                     36: static char *rcsid_GXMenu_c = "$Header: xmenu.c,v 1.1 87/09/12 16:33:40 newman Exp $";
                     37: #endif lint
                     38: 
                     39: #ifdef HAVE_X_MENU
                     40: 
                     41: #include "config.h"
                     42: #include <signal.h>
                     43: #include "xterm.h"
                     44: 
                     45: /* Load sys/types.h if not already loaded.
                     46:    In some systems loading it twice is suicidal.  */
                     47: #ifndef makedev
                     48: #include <sys/types.h>
                     49: #endif
                     50: 
                     51: #include <stdio.h>
                     52: #undef NULL
                     53: #include "dispextern.h"
                     54: #include <sys/time.h>
                     55: #include <fcntl.h>
                     56: #include "lisp.h"
                     57: #include "window.h"
                     58: #include <X11/XMenu.h>
                     59: 
                     60: #define min(x,y) (((x) < (y)) ? (x) : (y))
                     61: #define max(x,y) (((x) > (y)) ? (x) : (y))
                     62: 
                     63: #define NUL 0
                     64: 
                     65: #ifndef TRUE
                     66: #define TRUE 1
                     67: #define FALSE 0
                     68: #endif TRUE
                     69: extern Display *XXdisplay;
                     70: extern int XXxoffset,XXyoffset;
                     71: extern int XXfontw,XXfonth;
                     72: extern int (*handler)();
                     73: extern int request_sigio(), unrequest_sigio();
                     74: 
                     75: /*************************************************************/
                     76: 
                     77: XMenuQuit ()
                     78: {
                     79:   error("Unknown XMenu error");
                     80: }
                     81: 
                     82: DEFUN ("x-popup-menu",Fx_popup_menu, Sx_popup_menu, 1, 2, 0,
                     83:        "Interface to XMenu library; permits creation and use of\n\
                     84: deck-of-cards pop-up menus.\n\
                     85: \n\
                     86: ARG is a position specification; it is a list of (Xoffset, Yoffset)\n\
                     87: from the top-left corner of the editor window.  Note that this offset\n\
                     88: is relative to the center of the first line in the first pane of the\n\
                     89: menu, not the top left of the menu as a whole.\n\
                     90: \n\
                     91: MENU is a specifier for a menu.  It is a list of the form\n\
                     92: (title pane1 pane2...), and each pane is a list of form\n\
                     93: (title (line item)...).  Each line should be a string, and item should\n\
                     94: be the return value for that line (i. e. if it is selected.")
                     95:        (arg,menu)
                     96:      Lisp_Object arg,menu;
                     97: {
                     98:   int number_of_panes;
                     99:   Lisp_Object XMenu_return;
                    100:   int XMenu_xpos,XMenu_ypos;
                    101:   char **menus;
                    102:   char ***names;
                    103:   Lisp_Object **obj_list;
                    104:   int *items;
                    105:   char *title;
                    106:   char *error_name;
                    107:   Lisp_Object ltitle, selection;
                    108:   extern Lisp_Object Vx_mouse_abs_pos;
                    109:   Lisp_Object XEmacsMenu();
                    110:   int i;
                    111:   int mask;
                    112: 
                    113:   check_xterm();
                    114:   XMenu_xpos = XINT(Fcar(Vx_mouse_abs_pos));
                    115:   XMenu_ypos = XINT(Fcar(Fcdr (Vx_mouse_abs_pos)));
                    116:   ltitle = Fcar(menu);
                    117:   CHECK_STRING(ltitle,1);
                    118:   title = (char *) XSTRING(ltitle)->data;
                    119:   /* title = (char *) xmalloc ((XSTRING(ltitle)->size + 1) * sizeof(char));
                    120:      bcopy (XSTRING(ltitle)->data, title, XSTRING(ltitle)->size); */
                    121:   number_of_panes=list_of_panes(&obj_list, &menus, &names, &items, Fcdr(menu));
                    122: #ifdef XDEBUG
                    123:   fprintf(stderr,"Panes= %d\n", number_of_panes);
                    124:   for(i=0; i < number_of_panes; i++)
                    125:     {
                    126:       fprintf (stderr,"Pane %d lines %d title %s\n", i, items[i], menus[i]);
                    127:       for (j=0; j < items[i]; j++)
                    128:        {
                    129:          fprintf (stderr,"    Item %d %s\n", j, names[i][j]);
                    130:        }
                    131:     }
                    132: #endif
                    133:   mask = sigblock (sigmask (SIGIO));
                    134:   XSetErrorHandler(XMenuQuit);
                    135:   selection = XEmacsMenu(RootWindow(XXdisplay,0), XMenu_xpos, XMenu_ypos, names, menus,
                    136:                         items, number_of_panes, obj_list ,title, &error_name);
                    137:   XSetErrorHandler(handler);
                    138:   sigsetmask (mask);
                    139:   /** fprintf(stderr,"selection = %x\n",selection);  **/
                    140:   if (selection != NUL)
                    141:     {                          /* selected something */
                    142:       XMenu_return = selection;
                    143:     }
                    144:   else
                    145:     {                          /* nothing selected */
                    146:       XMenu_return = Qnil;
                    147:     }
                    148:   /* now free up the strings */
                    149:   for (i=0; i < number_of_panes; i++)
                    150:     {
                    151:       free(names[i]);
                    152:       free(obj_list[i]);
                    153:     }
                    154:   free(menus);
                    155:   free(obj_list);
                    156:   free(names);
                    157:   free(items);
                    158:   /*   free(title); */
                    159:   if (error_name) error(error_name);
                    160:   return XMenu_return;
                    161: }
                    162: 
                    163: struct indices {
                    164:   int pane;
                    165:   int line;
                    166: };
                    167: 
                    168: Lisp_Object
                    169: XEmacsMenu(parent, startx, starty, line_list, pane_list, line_cnt,
                    170:                      pane_cnt, item_list, title, errorstr)
                    171:      Window parent;            
                    172:      int startx, starty;       /* upper left corner position BROKEN */
                    173:      char **line_list[];       /* list of strings for items */
                    174:      char *pane_list[];                /* list of pane titles */
                    175:      char *title;
                    176:      int pane_cnt;             /* total number of panes */
                    177:      Lisp_Object *item_list[]; /* All items */
                    178:      int line_cnt[];           /* Lines in each pane */
                    179:      char **errorstr;          /* Error returned */
                    180: {
                    181:   XMenu *GXMenu;
                    182:   int panes, sel, lpane, status;
                    183:   Lisp_Object entry;
                    184:   /* struct indices *datap, *datap_save; */
                    185:   char *datap;
                    186:   
                    187:   *errorstr = (char *) 0;              /* Initialize errorstr pointer to null */
                    188:   if ((GXMenu = XMenuCreate(XXdisplay, parent, "emacs" )) == NUL )
                    189:     {
                    190:       *errorstr = "Can't create menu";
                    191:       /* error("Can't create menu"); */
                    192:       return(0);
                    193:     }
                    194:   
                    195:   for (panes=0; panes < pane_cnt; panes++ )
                    196:     ;
                    197:   /* datap = (struct indices *) xmalloc (lines * sizeof(struct indices)); */
                    198:   /*datap = (char *) xmalloc(lines * sizeof(char));
                    199:     datap_save = datap;*/
                    200:   
                    201:   for (panes = 0;panes < pane_cnt; panes++ )
                    202:     {
                    203:       /* create all the necessary panes */
                    204:       if ((lpane= XMenuAddPane(XXdisplay, GXMenu, pane_list[panes] , TRUE ))
                    205:          == XM_FAILURE)
                    206:        {
                    207:          XMenuDestroy(XXdisplay, GXMenu);
                    208:          *errorstr = "Can't create pane";
                    209:          /* error("Can't create pane"); */
                    210:          /* free(datap); */
                    211:          return(0);
                    212:        }
                    213:       for ( sel = 0; sel < line_cnt[panes] ; sel++ )
                    214:        {
                    215:          /* add the selection stuff to the menus */
                    216:          /* datap[sel+sofar].pane = panes;
                    217:             datap[sel+sofar].line = sel; */
                    218:          if (XMenuAddSelection(XXdisplay, GXMenu, lpane, 0, line_list[panes][sel], TRUE)
                    219:              == XM_FAILURE)
                    220:            {
                    221:              XMenuDestroy(XXdisplay, GXMenu);
                    222:              /* free(datap); */
                    223:              *errorstr = "Can't add selection to menu";
                    224:              /* error ("Can't add selection to menu"); */
                    225:              return(0);
                    226:            }
                    227:        }
                    228:     }
                    229:   /* all set and ready to fly */
                    230:   XMenuSetFreeze(GXMenu, TRUE);
                    231:   XMenuRecompute(XXdisplay,GXMenu);
                    232:   panes = sel = 0;
                    233:   
                    234:   status = XMenuActivate(XXdisplay, GXMenu, &panes, &sel, startx, starty,
                    235:                         ButtonReleaseMask, &datap);
                    236:   switch (status ) {
                    237:   case XM_SUCCESS:
                    238: #ifdef XDEBUG
                    239:     fprintf (stderr, "pane= %d line = %d\n", panes, sel);
                    240: #endif
                    241:     entry = item_list[panes][sel];
                    242:     break;
                    243:   case XM_FAILURE:
                    244:     /*free (datap_save); */
                    245:     /*XMenuDestroy(XXdisplay, GXMenu);*/
                    246:     *errorstr = "Can't activate menu";
                    247:     /* error("Can't activate menu"); */
                    248:   case XM_IA_SELECT:
                    249:   case XM_NO_SELECT:
                    250:     entry = Qnil;
                    251:     break;
                    252:   }
                    253:   XMenuDestroy(XXdisplay, GXMenu);
                    254:   XFlush(XXdisplay);
                    255:   if (XPending(XXdisplay))
                    256:          read_events_block();
                    257:   /*free(datap_save);*/
                    258:   return(entry);
                    259: }
                    260: 
                    261: syms_of_xmenu ()
                    262: {
                    263:   defsubr (&Sx_popup_menu);
                    264: }
                    265: 
                    266: list_of_panes (vector, panes, names, items, menu)
                    267:      Lisp_Object ***vector;    /* RETURN all menu objects */
                    268:      char ***panes;            /* RETURN pane names */
                    269:      char ****names;           /* RETURN all line names */
                    270:      int **items;              /* RETURN number of items per pane */
                    271:      Lisp_Object menu;
                    272: {
                    273:   Lisp_Object tail, item, item1;
                    274:   int i;
                    275:   
                    276:   if (XTYPE (menu) != Lisp_Cons) menu = wrong_type_argument(Qlistp, item);
                    277:   
                    278:   i= XFASTINT(Flength(menu,1));
                    279: 
                    280:   *vector = (Lisp_Object **) xmalloc(i * sizeof (Lisp_Object *));
                    281:   *panes = (char **) xmalloc(i * sizeof (char *));
                    282:   *items = (int *) xmalloc(i * sizeof (int));
                    283:   *names = (char ***) xmalloc(i * sizeof (char **));
                    284: 
                    285:   for (i=0,tail = menu; !NULL (tail); tail = Fcdr (tail), i++)
                    286:     {
                    287:        item = Fcdr(Fcar(tail));
                    288:        if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument(Qlistp, item);
                    289: #ifdef XDEBUG
                    290:        fprintf (stderr, "list_of_panes check tail, i=%d\n", i);
                    291: #endif
                    292:        item1 = Fcar(Fcar(tail));
                    293:        CHECK_STRING (item1, 1);
                    294: #ifdef XDEBUG
                    295:        fprintf (stderr, "list_of_panes check pane, i=%d%s\n", i,
                    296:                XSTRING(item1)->data);
                    297: #endif
                    298:        (*panes)[i] = (char *) XSTRING(item1)->data;
                    299:        (*items)[i] = list_of_items ((*vector)+i, (*names)+i, item);
                    300:        /* (*panes)[i] = (char *) xmalloc((XSTRING(item1)->size)+1);
                    301:          bcopy (XSTRING (item1)->data, (*panes)[i], XSTRING(item1)->size + 1)
                    302:          ; */
                    303:     }
                    304:   return i;
                    305: }
                    306:      
                    307: 
                    308: list_of_items (vector,names,pane)  /* get list from emacs and put to vector */
                    309:      Lisp_Object **vector;     /* RETURN menu "objects" */
                    310:      char ***names;            /* RETURN line names */
                    311:      Lisp_Object pane;
                    312: {
                    313:   Lisp_Object tail, item, item1;
                    314:   int i;
                    315: 
                    316:   if (XTYPE (pane) != Lisp_Cons) pane = wrong_type_argument(Qlistp, item);
                    317:   
                    318:   i= XFASTINT(Flength(pane,1));
                    319: 
                    320:   *vector = (Lisp_Object *) xmalloc(i * sizeof (Lisp_Object));
                    321:   *names = (char **) xmalloc(i * sizeof (char *));
                    322: 
                    323:   for (i=0,tail = pane; !NULL (tail); tail = Fcdr (tail), i++)
                    324:     {
                    325:        item = Fcar(tail);
                    326:        if (XTYPE (item) != Lisp_Cons) (void) wrong_type_argument(Qlistp, item);
                    327: #ifdef XDEBUG
                    328:        fprintf (stderr, "list_of_items check tail, i=%d\n", i);
                    329: #endif
                    330:        (*vector)[i] =  Fcdr (item);
                    331:        item1 = Fcar(item);
                    332:        CHECK_STRING (item1, 1);
                    333: #ifdef XDEBUG
                    334:        fprintf (stderr, "list_of_items check item, i=%d%s\n", i,
                    335:                XSTRING(item1)->data);
                    336: #endif
                    337:        (*names)[i] = (char *) XSTRING(item1)->data;
                    338:        /* (*names)[i] = (char *) xmalloc((XSTRING(item1)->size)+1);
                    339:        bcopy (XSTRING (item1)->data, (*names)[i], XSTRING(item1)->size + 1); */
                    340:     }
                    341:   return i;
                    342: }
                    343: 
                    344: #endif HAVE_X_MENU

unix.superglobalmegacorp.com

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