Annotation of 43BSDReno/contrib/emacs-18.55/src/sunfns.c, revision 1.1

1.1     ! root        1: /* Functions for Sun Windows menus and selection buffer.
        !             2:    Copyright (C) 1987 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.
        !            11: 
        !            12: Everyone is granted permission to copy, modify and redistribute
        !            13: GNU Emacs, but only under the conditions described in the
        !            14: document "GNU Emacs copying permission notice".   An exact copy
        !            15: of the document is supposed to have been given to you along with
        !            16: GNU Emacs so that you can know how you may redistribute it all.
        !            17: It should be in a file named COPYING.  Among other things, the
        !            18: copyright notice and this notice must be preserved on all copies.
        !            19: 
        !            20: Author: Jeff Peck, Sun Microsystems, Inc. <[email protected]>
        !            21: Original ideas by David Kastan and Eric Negaard, SRI International
        !            22: Major help from: Steve Greenbaum, Reasoning Systems, Inc.
        !            23:                    <[email protected]>
        !            24: who first discovered the Menu_Base_Kludge.
        !            25:  */
        !            26: 
        !            27: /*
        !            28:  *     Emacs Lisp-Callable functions for sunwindows
        !            29:  */
        !            30: #include "config.h"
        !            31: 
        !            32: #include <stdio.h>
        !            33: #include <errno.h>
        !            34: #include <signal.h>
        !            35: #include <sunwindow/window_hs.h>
        !            36: #include <suntool/selection.h>
        !            37: #include <suntool/menu.h>
        !            38: #include <suntool/walkmenu.h>
        !            39: #include <suntool/frame.h>
        !            40: #include <suntool/window.h>
        !            41: 
        !            42: #include <fcntl.h>
        !            43: #undef NULL /* We don't need sunview's idea of NULL */
        !            44: #include "lisp.h"
        !            45: #include "window.h"
        !            46: #include "buffer.h"
        !            47: #include "termhooks.h"
        !            48: 
        !            49: /* conversion to/from character & screen coordinates */
        !            50: /* From Gosling Emacs SunWindow driver by Chris Torek */
        !            51: 
        !            52: /* Chars to screen coords.  Note that we speak in zero origin. */
        !            53: #define CtoSX(cx) ((cx) * Sun_Font_Xsize)
        !            54: #define CtoSY(cy) ((cy) * Sun_Font_Ysize)
        !            55: 
        !            56: /* Screen coords to chars */
        !            57: #define StoCX(sx) ((sx) / Sun_Font_Xsize)
        !            58: #define StoCY(sy) ((sy) / Sun_Font_Ysize)
        !            59: 
        !            60: #define CHECK_GFX(x) if((win_fd<0)&&(Fsun_window_init(),(win_fd<0)))return(x)
        !            61: int win_fd = -1;
        !            62: struct pixfont *Sun_Font;      /* The font */
        !            63: int Sun_Font_Xsize;            /* Width of font  */
        !            64: int Sun_Font_Ysize;            /* Height of font */
        !            65: 
        !            66: #define Menu_Base_Kludge       /* until menu_show_using_fd gets fixed */
        !            67: #ifdef  Menu_Base_Kludge
        !            68: static Frame Menu_Base_Frame;
        !            69: static int Menu_Base_fd;
        !            70: static Lisp_Object sm_kludge_string;
        !            71: #endif
        !            72: struct cursor CurrentCursor;   /* The current cursor */
        !            73: 
        !            74: static short CursorData[16];   /* Build cursor here */
        !            75: static mpr_static(CursorMpr, 16, 16, 1, CursorData);
        !            76: static struct cursor NewCursor = {0, 0, PIX_SRC ^ PIX_DST, &CursorMpr};
        !            77: 
        !            78: #define RIGHT_ARROW_CURSOR     /* if you want the right arrow */
        !            79: #ifdef RIGHT_ARROW_CURSOR
        !            80: /* The default right-arrow cursor, with XOR drawing. */
        !            81: static short ArrowCursorData[16] = {
        !            82:   0x0001,0x0003,0x0007,0x000F,0x001F,0x003F,0x007F,0x000F,
        !            83:   0x001B,0x0019,0x0030,0x0030,0x0060,0x0060,0x00C0,0x00C0};
        !            84: static mpr_static(ArrowCursorMpr, 16, 16, 1, ArrowCursorData);
        !            85: struct cursor DefaultCursor = {15, 0, PIX_SRC ^ PIX_DST, &ArrowCursorMpr};
        !            86: 
        !            87: #else
        !            88: /* The default left-arror cursor, with XOR drawing. */
        !            89: static short ArrowCursorData[16] = {
        !            90:        0x8000,0xC000,0xE000,0xF000,0xF800,0xFC00,0xFE00,0xF000,
        !            91:        0xD800,0x9800,0x0C00,0x0C00,0x0600,0x0600,0x0300,0x0300};
        !            92: static mpr_static(ArrowCursorMpr, 16, 16, 1, ArrowCursorData);
        !            93: struct cursor DefaultCursor = {0, 0, PIX_SRC ^ PIX_DST, &ArrowCursorMpr};
        !            94: #endif
        !            95: 
        !            96: /*
        !            97:  *     Initialize window
        !            98:  */
        !            99: DEFUN ("sun-window-init", Fsun_window_init, Ssun_window_init, 0, 1, 0,
        !           100:        "One time setup for using Sun Windows with mouse.\n\
        !           101: Unless optional argument FORCE is non-nil, is a noop after its first call.\n\
        !           102: Returns a number representing the file descriptor of the open Sun Window,\n\
        !           103: or -1 if can not open it.")
        !           104:       (force)
        !           105:       Lisp_Object force;
        !           106: {
        !           107:   char *cp;
        !           108:   static int already_initialized = 0;
        !           109: 
        !           110:   if ((! already_initialized) || (!NULL(force))) {
        !           111:     cp = getenv("WINDOW_GFX");
        !           112:     if (cp != 0) win_fd = open(cp, 2);
        !           113:     if (win_fd > 0)
        !           114:       {
        !           115:        Sun_Font = pf_default();
        !           116:        Sun_Font_Xsize = Sun_Font->pf_defaultsize.x;
        !           117:        Sun_Font_Ysize = Sun_Font->pf_defaultsize.y;
        !           118:        Fsun_change_cursor_icon (Qnil); /* set up the default cursor */
        !           119:        already_initialized = 1;
        !           120: #ifdef  Menu_Base_Kludge
        !           121: 
        !           122:        /* Make a frame to use for putting the menu on, and get its fd. */
        !           123:        Menu_Base_Frame = window_create(0, FRAME,
        !           124:                                        WIN_X, 0, WIN_Y, 0,
        !           125:                                        WIN_ROWS, 1, WIN_COLUMNS, 1,
        !           126:                                        WIN_SHOW, FALSE,
        !           127:                                        FRAME_NO_CONFIRM, 1,
        !           128:                                        0);
        !           129:        Menu_Base_fd = (int) window_get(Menu_Base_Frame, WIN_FD);
        !           130: #endif
        !           131:       }
        !           132:   }
        !           133:   return(make_number(win_fd));
        !           134: }
        !           135: 
        !           136: /*
        !           137:  *     Mouse sit-for (allows a shorter interval than the regular sit-for
        !           138:  *     and can be interrupted by the mouse)
        !           139:  */
        !           140: DEFUN ("sit-for-millisecs", Fsit_for_millisecs, Ssit_for_millisecs, 1, 1, 0,
        !           141:    "Like sit-for, but ARG is milliseconds. \n\
        !           142: Perform redisplay, then wait for ARG milliseconds or until\n\
        !           143: input is available.  Returns t if wait completed with no input.\n\
        !           144: Redisplay does not happen if input is available before it starts.")
        !           145:        (n)
        !           146:        Lisp_Object n;
        !           147: {
        !           148:   struct timeval Timeout;
        !           149:   int waitmask = 1;
        !           150:   
        !           151:   CHECK_NUMBER (n, 0);
        !           152:   Timeout.tv_sec = XINT(n) / 1000;
        !           153:   Timeout.tv_usec = (XINT(n) - (Timeout.tv_sec * 1000)) * 1000;
        !           154: 
        !           155:   if (detect_input_pending()) return(Qnil);
        !           156:   DoDsp(1);
        !           157:   /*
        !           158:    *   Check for queued keyboard input/mouse hits again
        !           159:    *   (A bit screen update can take some time!)
        !           160:    */
        !           161:   if (detect_input_pending()) return(Qnil);
        !           162:   select(1,&waitmask,0,0,&Timeout);
        !           163:   if (detect_input_pending()) return(Qnil);
        !           164:   return(Qt);
        !           165: }
        !           166: 
        !           167: /*
        !           168:  *   Sun sleep-for (allows a shorter interval than the regular sleep-for)
        !           169:  */
        !           170: DEFUN ("sleep-for-millisecs", 
        !           171:        Fsleep_for_millisecs,
        !           172:        Ssleep_for_millisecs, 1, 1, 0,
        !           173:    "Pause, without updating display, for ARG milliseconds.")
        !           174:        (n)
        !           175:        Lisp_Object n;
        !           176: {
        !           177:   unsigned useconds;
        !           178: 
        !           179:   CHECK_NUMBER (n, 0);
        !           180:   useconds = XINT(n) * 1000;
        !           181:   usleep(useconds);
        !           182:   return(Qt);
        !           183: }
        !           184: 
        !           185: DEFUN ("update-display", Fupdate_display, Supdate_display, 0, 0, 0,
        !           186:        "Perform redisplay.")
        !           187:      ()
        !           188: {
        !           189:   DoDsp(1);
        !           190:   return(Qt);
        !           191: }
        !           192: 
        !           193: 
        !           194: /*
        !           195:  *     Change the Sun mouse icon
        !           196:  */
        !           197: DEFUN ("sun-change-cursor-icon",
        !           198:        Fsun_change_cursor_icon,
        !           199:        Ssun_change_cursor_icon, 1, 1, 0,
        !           200:   "Change the Sun mouse cursor icon.  ICON is a lisp vector whose 1st element\n\
        !           201: is the X offset of the cursor hot-point, whose 2nd element is the Y offset\n\
        !           202: of the cursor hot-point and whose 3rd element is the cursor pixel data\n\
        !           203: expressed as a string.  If ICON is nil then the original arrow cursor is used")
        !           204:      (Icon)
        !           205:      Lisp_Object Icon;
        !           206: {
        !           207:   register unsigned char *cp;
        !           208:   register short *p;
        !           209:   register int i;
        !           210:   Lisp_Object X_Hot, Y_Hot, Data;
        !           211:   
        !           212:   CHECK_GFX (Qnil);
        !           213:   /*
        !           214:    *   If the icon is null, we just restore the DefaultCursor
        !           215:    */
        !           216:   if (NULL(Icon)) 
        !           217:     CurrentCursor = DefaultCursor;
        !           218:   else {
        !           219:     /*
        !           220:      * extract the data from the vector
        !           221:      */
        !           222:     CHECK_VECTOR (Icon, 0);
        !           223:     if (XVECTOR(Icon)->size < 3) return(Qnil);
        !           224:     X_Hot = XVECTOR(Icon)->contents[0];
        !           225:     Y_Hot = XVECTOR(Icon)->contents[1];
        !           226:     Data = XVECTOR(Icon)->contents[2];
        !           227:     
        !           228:     CHECK_NUMBER (X_Hot, 0);
        !           229:     CHECK_NUMBER (Y_Hot, 0);
        !           230:     CHECK_STRING (Data, 0);
        !           231:     if (XSTRING(Data)->size != 32) return(Qnil);
        !           232:     /*
        !           233:      * Setup the new cursor
        !           234:      */
        !           235:     NewCursor.cur_xhot = X_Hot;
        !           236:     NewCursor.cur_yhot = Y_Hot;
        !           237:     cp = XSTRING(Data)->data;
        !           238:     p = CursorData;
        !           239:     i = 16;
        !           240:     while(--i >= 0)
        !           241:       *p++ = (cp[0] << 8) | cp[1], cp += 2;
        !           242:     CurrentCursor = NewCursor;
        !           243:   }
        !           244:   win_setcursor(win_fd, &CurrentCursor);
        !           245:   return(Qt);
        !           246: }
        !           247: 
        !           248: /*
        !           249:  *     Interface for sunwindows selection
        !           250:  */
        !           251: static Lisp_Object Current_Selection;
        !           252: 
        !           253: static
        !           254: sel_write (sel, file)
        !           255:      struct selection *sel;
        !           256:      FILE *file;
        !           257: {
        !           258:   fwrite (XSTRING (Current_Selection)->data, sizeof (char), 
        !           259:          sel->sel_items, file);
        !           260: }
        !           261: 
        !           262: static
        !           263: sel_clear (sel, windowfd)
        !           264:      struct selection *sel;
        !           265:      int windowfd;
        !           266: {
        !           267: }
        !           268: 
        !           269: static
        !           270: sel_read (sel, file)
        !           271:      struct selection *sel;
        !           272:      FILE *file;
        !           273: {
        !           274:   register int i, n;
        !           275:   register char *cp;
        !           276:   
        !           277:   Current_Selection = make_string ("", 0);
        !           278:   if (sel->sel_items <= 0)
        !           279:     return (0);
        !           280:   cp = (char *) malloc(sel->sel_items);
        !           281:   if (cp == (char *)0) {
        !           282:     error("malloc failed in sel_read");
        !           283:     return(-1);
        !           284:   }
        !           285:   n = fread(cp, sizeof(char), sel->sel_items, file);
        !           286:   if (n > sel->sel_items) {
        !           287:     error("fread botch in sel_read");
        !           288:     return(-1);
        !           289:   } else if (n < 0) {
        !           290:     error("Error reading selection.");
        !           291:     return(-1);
        !           292:   }
        !           293:   /*
        !           294:    * The shelltool select saves newlines as carrige returns,
        !           295:    * but emacs wants newlines.
        !           296:    */
        !           297:   for (i = 0; i < n; i++) 
        !           298:     if (cp[i] == '\r') cp[i] = '\n';
        !           299: 
        !           300:   Current_Selection = make_string (cp, n);
        !           301:   free (cp);
        !           302:   return (0);
        !           303: }
        !           304: 
        !           305: /*
        !           306:  *     Set the window system "selection" to be the arg STRING
        !           307:  */
        !           308: DEFUN ("sun-set-selection", Fsun_set_selection, Ssun_set_selection, 1, 1,
        !           309:        "sSet selection to: ",
        !           310:   "Set the current sunwindow selection to STRING.")
        !           311:      (str)
        !           312:      Lisp_Object str;
        !           313: {
        !           314:   struct selection selection;
        !           315: 
        !           316:   CHECK_STRING (str, 0);
        !           317:   Current_Selection = str;
        !           318: 
        !           319:   CHECK_GFX (Qnil);
        !           320:   selection.sel_type = SELTYPE_CHAR;
        !           321:   selection.sel_items = XSTRING (str)->size;
        !           322:   selection.sel_itembytes = 1;
        !           323:   selection.sel_pubflags = 1;
        !           324:   selection_set(&selection, sel_write, sel_clear, win_fd);
        !           325:   return (Qt);
        !           326: }
        !           327: /*
        !           328:  *     Stuff the current window system selection into the current buffer
        !           329:  */
        !           330: DEFUN ("sun-get-selection", Fsun_get_selection, Ssun_get_selection, 0, 0, 0,
        !           331:        "Return the current sunwindows selection as a string.")
        !           332:      ()
        !           333: {
        !           334:   CHECK_GFX (Current_Selection);
        !           335:   selection_get (sel_read, win_fd);
        !           336:   return (Current_Selection);
        !           337: }
        !           338: 
        !           339: Menu sun_menu_create();
        !           340: 
        !           341: Menu_item
        !           342: sun_item_create (Pair)
        !           343:      Lisp_Object Pair;
        !           344: {
        !           345:   /* In here, we depend on Lisp supplying zero terminated strings in the data*/
        !           346:   /* so we can just pass the pointers, and not recopy anything */
        !           347: 
        !           348:   Menu_item menu_item;
        !           349:   Menu submenu;
        !           350:   Lisp_Object String;
        !           351:   Lisp_Object Value;
        !           352: 
        !           353:   if (!CONSP(Pair)) wrong_type_argument(Qlistp, Pair);
        !           354:   String = Fcar(Pair);
        !           355:   CHECK_STRING(String, 0);
        !           356:   Value = Fcdr(Pair);
        !           357:   if(XTYPE(Value) == Lisp_Symbol)
        !           358:     Value = XSYMBOL(Value)->value;
        !           359:   if(XTYPE(Value) == Lisp_Vector) {
        !           360:     submenu = sun_menu_create (Value);
        !           361:     menu_item = menu_create_item
        !           362:       (MENU_RELEASE, MENU_PULLRIGHT_ITEM, XSTRING(String)->data, submenu, 0);
        !           363:   } else {
        !           364:     menu_item = menu_create_item
        !           365:       (MENU_RELEASE, MENU_STRING_ITEM, XSTRING(String)->data, Value, 0);
        !           366:   }
        !           367:   return menu_item;
        !           368: }
        !           369: 
        !           370: Menu 
        !           371: sun_menu_create (Vector)
        !           372:      Lisp_Object Vector;
        !           373: {
        !           374:   Menu menu;
        !           375:   int i;
        !           376:   CHECK_VECTOR(Vector,0);
        !           377:   menu=menu_create(0)        !           378:   for(i = 0; i < XVECTOR(Vector)->size; i++) {
        !           379:     menu_set (menu, MENU_APPEND_ITEM, 
        !           380:              sun_item_create(XVECTOR(Vector)->contents[i]), 0);
        !           381:   }
        !           382:   return menu;
        !           383: }
        !           384: 
        !           385: /*
        !           386:  *  If the first item of the menu has nil as its value, then make the
        !           387:  *  item look like a label by inverting it and making it unselectable.
        !           388:  *  Returns 1 if the label was made, 0 otherwise.
        !           389:  */
        !           390: int
        !           391: make_menu_label (menu)
        !           392:      Menu menu;
        !           393: {
        !           394:   int made_label_p = 0;
        !           395: 
        !           396:   if (( menu_get(menu, MENU_NITEMS) > 0 ) && /* At least one item */
        !           397:       ((Lisp_Object) menu_get(menu_get(menu, MENU_NTH_ITEM, 1),
        !           398:                              MENU_VALUE) == Qnil )) {
        !           399:       menu_set(menu_get(menu, MENU_NTH_ITEM, 1),
        !           400:               MENU_INVERT, TRUE,
        !           401:               MENU_FEEDBACK, FALSE,
        !           402:               0);
        !           403:       made_label_p = 1;
        !           404:     }
        !           405:   return made_label_p;
        !           406: }
        !           407: 
        !           408: /*
        !           409:  *     Do a pop-up menu and return the selected value
        !           410:  */
        !           411: DEFUN ("sun-menu-internal",
        !           412:        Fsun_menu_internal,
        !           413:        Ssun_menu_internal, 5, 5, 0,
        !           414:        "Set up a SunView pop-up menu and return the user's choice.\n\
        !           415: Arguments WINDOW, X, Y, BUTTON, and MENU.\n\
        !           416: *** User code should generally use sun-menu-evaluate ***\n\
        !           417: \n\
        !           418: Arguments WINDOW, X, Y, BUTTON, and MENU.\n\
        !           419: Put MENU up in WINDOW at position X, Y.\n\
        !           420: The BUTTON argument specifies the button to be released that selects an item:\n\
        !           421:    1 = LEFT BUTTON\n\
        !           422:    2 = MIDDLE BUTTON\n\
        !           423:    4 = RIGHT BUTTON\n\
        !           424: The MENU argument is a vector containing (STRING . VALUE) pairs.\n\
        !           425: The VALUE of the selected item is returned.\n\
        !           426: If the VALUE of the first pair is nil, then the first STRING will be used\n\
        !           427: as a menu label.")
        !           428:       (window, X_Position, Y_Position, Button, MEnu)
        !           429:       Lisp_Object window, X_Position, Y_Position, Button, MEnu;
        !           430: {
        !           431:   Menu menu;
        !           432:   int button, xpos, ypos;
        !           433:   Event event0;
        !           434:   Event *event = &event0;
        !           435:   Lisp_Object Value, Pair;
        !           436:   
        !           437:   CHECK_NUMBER(X_Position, 0);
        !           438:   CHECK_NUMBER(Y_Position, 1);
        !           439:   CHECK_WINDOW(window, 2);
        !           440:   CHECK_NUMBER(Button, 3);
        !           441:   CHECK_VECTOR(MEnu, 4);
        !           442: 
        !           443:   CHECK_GFX (Qnil);
        !           444: 
        !           445:   xpos = CtoSX (XWINDOW(window)->left + XINT(X_Position));
        !           446:   ypos = CtoSY (XWINDOW(window)->top  + XINT(Y_Position));
        !           447: #ifdef  Menu_Base_Kludge
        !           448:   {static Lisp_Object symbol[2];
        !           449:    symbol[0] = Fintern (sm_kludge_string, Qnil);
        !           450:    Pair = Ffuncall (1, symbol);
        !           451:    xpos += XINT (XCONS (Pair)->cdr);
        !           452:    ypos += XINT (XCONS (Pair)->car);
        !           453:  }
        !           454: #endif
        !           455: 
        !           456:   button = XINT(Button);
        !           457:   if(button == 4) button = 3;
        !           458:   event_set_id   (event, BUT(button));
        !           459:   event_set_down (event);
        !           460:   event_set_x    (event, xpos);
        !           461:   event_set_y    (event, ypos);
        !           462: 
        !           463:   menu = sun_menu_create(MEnu);
        !           464:   make_menu_label(menu);
        !           465: 
        !           466: #ifdef  Menu_Base_Kludge
        !           467:   Value = (Lisp_Object) menu_show(menu, Menu_Base_Frame, event, 0);
        !           468: #else
        !           469: /* This confuses the notifier or something: */
        !           470:   Value = (Lisp_Object) menu_show_using_fd(menu, win_fd, event, 0);
        !           471: /*
        !           472:  * Right button gets lost, and event sequencing or delivery gets mixed up
        !           473:  * So, until that gets fixed, we use this <Menu_Base_Frame> kludge:
        !           474:  */
        !           475: #endif
        !           476:   menu_destroy (menu);
        !           477: 
        !           478:   return ((int)Value ? Value : Qnil);
        !           479: }
        !           480: 
        !           481: 
        !           482: /*
        !           483:  *     Define everything
        !           484:  */
        !           485: syms_of_sunfns()
        !           486: {
        !           487: #ifdef  Menu_Base_Kludge
        !           488:   /* i'm just too lazy to re-write this into C code */
        !           489:   /* so we will call this elisp function from C */
        !           490:   sm_kludge_string = make_pure_string ("sm::menu-kludge", 15);
        !           491: #endif /* Menu_Base_Kludge */
        !           492: 
        !           493:   defsubr(&Ssun_window_init);
        !           494:   defsubr(&Ssit_for_millisecs);
        !           495:   defsubr(&Ssleep_for_millisecs);
        !           496:   defsubr(&Supdate_display);
        !           497:   defsubr(&Ssun_change_cursor_icon);
        !           498:   defsubr(&Ssun_set_selection);
        !           499:   defsubr(&Ssun_get_selection);
        !           500:   defsubr(&Ssun_menu_internal);
        !           501: }

unix.superglobalmegacorp.com

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