home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / emacs-18.59-src.tgz / emacs-18.59-src.tar / fsf / emacs18 / src / amiga_screen.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  38KB  |  1,397 lines

  1. #include "config.h"
  2. #undef NULL
  3. #include "lisp.h"
  4. #include "termchar.h"
  5. #include "dispextern.h"
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stddef.h>
  10. #include <internal/devices.h>
  11. #include <internal/vars.h>
  12.  
  13. #define min(x,y) ((x) > (y) ? (y) : (x))
  14. #define max(x,y) ((x) < (y) ? (y) : (x))
  15.  
  16. #undef LONGBITS
  17.  
  18. #include <exec/types.h>
  19. #include <exec/interrupts.h>
  20. #include <devices/input.h>
  21. #include <devices/inputevent.h>
  22. #include <intuition/intuitionbase.h>
  23. #include <intuition/intuition.h>
  24. #include <devices/conunit.h>
  25. #include <devices/inputevent.h>
  26. #include <graphics/gfxbase.h>
  27. #include <graphics/gfxmacros.h>
  28. #include <utility/hooks.h>
  29. #include <workbench/startup.h>
  30. #include <workbench/workbench.h>
  31.  
  32. #include <proto/exec.h>
  33. #include <proto/dos.h>
  34. #include <proto/intuition.h>
  35. #include <proto/graphics.h>
  36. #include <proto/console.h>
  37. #include <proto/diskfont.h>
  38. #include <proto/wb.h>
  39.  
  40. /* this is defined for those unlucky enough
  41.  * not to have the 3.0 headers  -ch3/16/93. */
  42. #ifndef WA_NewLookMenus
  43. #define WA_NewLookMenus (WA_Dummy + 0x30)
  44. #endif
  45.  
  46. #include "amiga.h"
  47.  
  48. #define SHIFT_MASK (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)
  49. #define CONTROL_MASK IEQUALIFIER_CONTROL
  50. #define META_MASK IEQUALIFIER_LALT
  51.  
  52. struct GfxBase *GfxBase;
  53. struct IntuitionBase *IntuitionBase;
  54. struct Library *DiskfontBase, *KeymapBase, *WorkbenchBase;
  55.  
  56. static char intkey_code, intkey_qualifier;
  57. static struct IOStdReq *input_req;
  58. static struct Interrupt int_handler_hook;
  59. static int hooked;
  60.  
  61. static struct MsgPort *wbport;
  62. static struct AppWindow *emacs_app_win;
  63. static struct AppIcon *emacs_icon;
  64.  
  65. struct Library *ConsoleDevice;
  66. static struct TextFont *font;
  67. static int font_opened;
  68. /* The reset string resets the console, turns off scrolling and sets up
  69.    the foreground & background colors. */
  70. #define CONSOLE_RESET "\x1b""c\x9b>1l\x9b""3%d;4%d;>%dm"
  71. static char reset_string[20]; /* Must be big enough for
  72.               printf(CONSOLE_RESET, foreground, background, background);
  73.               (0 <= foreground, background <= 7) */
  74.  
  75. /* These are the pen numbers for emacs window's base colors */
  76. int foreground = 1, background = 0;
  77.  
  78. /* Current window, and its main characteristics */
  79. struct Window *emacs_win;
  80. WORD emacs_x = 0, emacs_y = 0, emacs_w = 640, emacs_h = 200;
  81. char *emacs_screen_name;
  82. char emacs_screen_name_storage[MAXPUBSCREENNAME+1];
  83. int emacs_backdrop = 0;        /* Use backdrop window ? */
  84.  
  85. /* Current window size: */
  86. #define EMACS_X() (emacs_win ? emacs_win->LeftEdge : emacs_x)
  87. #define EMACS_Y() (emacs_win ? emacs_win->TopEdge : emacs_y)
  88. #define EMACS_W() (emacs_win ? emacs_win->Width : emacs_w)
  89. #define EMACS_H() (emacs_win ? emacs_win->Height : emacs_h)
  90.  
  91. /* used for setting the color of standout text  -ch3/16/93. */
  92. int inverse_fill_pen = 8, inverse_text_pen = 8;
  93.  
  94. /* IO request for all console io. */
  95. static struct IOStdReq *emacs_console;
  96.  
  97. /* a storage area for the name of the screen last opened on */
  98.  
  99. #define emacs_icon_width 57
  100. #define emacs_icon_height 55
  101. #define emacs_icon_num_planes 1
  102. #define emacs_icon_words_per_plane 220
  103.  
  104. UWORD chip emacs_icon_data[1][55][4] = {
  105.   {
  106.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  107.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  108.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x6000,
  109.     0x0000,0x0000,0x0060,0x6000,0x0000,0x0000,0x0fff,0xe000,
  110.     0x0000,0x0000,0x1800,0x2000,0x0000,0x0000,0x13ff,0xa000,
  111.     0x0000,0x0000,0x1400,0xa000,0x0000,0x0000,0x3600,0xa000,
  112.     0x0000,0x0000,0x0000,0xa000,0x0000,0x0000,0x0c00,0xa000,
  113.     0x0000,0x0000,0x1e00,0xa000,0x0000,0x0000,0x0c00,0xa000,
  114.     0x0000,0x0000,0x0000,0xa000,0x0000,0x0000,0x2100,0xa000,
  115.     0x0000,0x0000,0x3300,0xa000,0x0000,0x0000,0x0c00,0xa000,
  116.     0x003f,0xffff,0xffff,0xb000,0x001f,0xffff,0xffff,0x8000,
  117.     0x004e,0x0000,0x0001,0xf000,0x00c6,0x00f0,0x0001,0x8000,
  118.     0x00c6,0x0100,0x0001,0x8000,0x0006,0x0103,0x9201,0x8000,
  119.     0x0006,0x013a,0x5201,0x8000,0x00c6,0x010a,0x5201,0x8000,
  120.     0x00c6,0x010a,0x5601,0x8000,0x0086,0x00f2,0x4a01,0x8000,
  121.     0x0006,0x0000,0x0001,0x8000,0x0046,0x0000,0x0001,0x8000,
  122.     0x00c6,0x7c00,0x0001,0x8000,0x00c6,0x4000,0x0001,0x8000,
  123.     0x0006,0x41d8,0xc319,0x8000,0x0006,0x7925,0x24a1,0x8000,
  124.     0x00c6,0x4125,0x2419,0x8000,0x01c6,0x4125,0x2485,0x8000,
  125.     0x0086,0x7d24,0xd319,0x8000,0x0007,0x0000,0x0003,0x8000,
  126.     0x0003,0xffe3,0xffff,0x0000,0x0081,0xfff7,0xfffe,0x0000,
  127.     0x01c0,0x0036,0x0000,0x0000,0x0180,0x0014,0x0f80,0x0000,
  128.     0x0000,0x0014,0x1040,0x0000,0x0000,0x0014,0x2720,0x0000,
  129.     0x0000,0x0012,0x28a0,0x0000,0x0080,0x000a,0x48a0,0x0000,
  130.     0x01c0,0x0009,0x90a0,0x0000,0x0180,0x0004,0x20a0,0x0000,
  131.     0x0000,0x0003,0xc0a0,0x0000,0x0000,0x0000,0x00a0,0x0000,
  132.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  133.     0x0000,0x0000,0x0000,0x0000
  134.   },
  135. };
  136.  
  137. struct Image far emacs_icon_image = {
  138.   0, 0,
  139.   emacs_icon_width, emacs_icon_height, emacs_icon_num_planes,
  140.   (UWORD *)emacs_icon_data,
  141.   3, 0,
  142.   0
  143. };
  144.  
  145. static struct DiskObject far emacs_icon_object = {
  146.   0, 0,
  147.   { 0, 0, 0, emacs_icon_width, emacs_icon_height, 0, 0, 0, (APTR)&emacs_icon_image },
  148.   0, 0, 0,
  149.   NO_ICON_POSITION, NO_ICON_POSITION
  150. };
  151.  
  152. static struct Hook background_hook;
  153.  
  154. #define EVENTSIZE 32
  155.  
  156. static struct event {
  157.   ULONG class;
  158.   UWORD code, qual;
  159.   WORD x, y;
  160. } events[EVENTSIZE];
  161. static int event_num, event_in, event_out;
  162.  
  163. static struct wbevent {
  164.   struct wbevent *next;
  165.   char file[1];
  166. } *wbevents;
  167.  
  168. Lisp_Object Vamiga_mouse_pos;
  169. Lisp_Object Vamiga_mouse_item;
  170. extern Lisp_Object MouseMap;
  171. int amiga_remap_bsdel;
  172. int amiga_remap_numeric_keypad;
  173. int amiga_mouse_initialized;
  174. int amiga_wb_initialized;
  175. int emacs_iconified;
  176.  
  177. static int amiga_pos_x(int x)
  178. {
  179.   return (x - emacs_win->BorderLeft) / emacs_win->RPort->Font->tf_XSize;
  180. }
  181.  
  182. static int amiga_pos_y(int y)
  183. {
  184.   return (y - emacs_win->BorderTop) / emacs_win->RPort->Font->tf_YSize;
  185. }
  186.  
  187. static void amiga_change_size(void)
  188. {
  189.   int new_height = amiga_pos_y(emacs_win->Height - emacs_win->BorderBottom);
  190.   int new_width = amiga_pos_x(emacs_win->Width - emacs_win->BorderRight);
  191.  
  192.   /* Hack to force redisplay */
  193.   if (screen_height == new_height) screen_height--;
  194.   /* I consider that refreshes are possible during a select, which is
  195.      true for the current state of emacs */
  196.   change_screen_size(new_height, new_width, 0, !selecting && !waiting_for_input, 1);
  197. }
  198.  
  199. /* Get terminal size from system.
  200.    Store number of lines into *heightp and width into *widthp.
  201.    If zero or a negative number is stored, the value is not valid.  */
  202.  
  203. void get_window_size (widthp, heightp)
  204.      int *widthp, *heightp;
  205. {
  206.   if (emacs_win)
  207.     {
  208.       *heightp = amiga_pos_y(emacs_win->Height - emacs_win->BorderBottom);
  209.       *widthp = amiga_pos_x(emacs_win->Width - emacs_win->BorderRight);
  210.     }
  211.   else
  212.     {
  213.       *heightp = 0;
  214.       *widthp = 0;
  215.     }
  216. }
  217.  
  218. static int set_min_size(struct Window *win, struct TextFont *font,
  219.             WORD *minw, WORD *minh)
  220. {
  221.   *minw = 11 * font->tf_XSize + win->BorderLeft + win->BorderRight;
  222.   *minh = 4 * font->tf_YSize + win->BorderTop + win->BorderBottom;
  223.  
  224.   return (int)WindowLimits(win, *minw, *minh, 0, 0);
  225. }
  226.  
  227. struct fill
  228. {
  229.   struct Layer *layer;
  230.   struct Rectangle bounds;
  231.   WORD offsetx, offsety;
  232. };
  233.  
  234. /* __interrupt disables stack checking.   -ch3/19/93. */
  235. static ULONG __asm __saveds __interrupt
  236. fill_background(register __a2 struct RastPort *obj,
  237.         register __a1 struct fill *msg)
  238. {
  239.   struct Layer *l;
  240.  
  241.   SetAPen(obj, background);
  242.   SetDrMd(obj, JAM1);
  243.   SetAfPt(obj, 0, 0);
  244.   SetWrMsk(obj, 0xff);
  245.   /* Gross hack starts here */
  246.   l = obj->Layer;
  247.   obj->Layer = 0;
  248.   /* Stops */
  249.   RectFill(obj, msg->bounds.MinX, msg->bounds.MinY,
  250.        msg->bounds.MaxX, msg->bounds.MaxY);
  251.   /* Starts again */
  252.   obj->Layer = l;
  253.   /* And finally dies */
  254.  
  255.   return 0;
  256. }
  257.  
  258. static void clear_window(void)
  259. {
  260.   SetAPen(emacs_win->RPort, background);
  261.   RectFill(emacs_win->RPort, emacs_win->BorderLeft, emacs_win->BorderTop,
  262.        emacs_win->Width - emacs_win->BorderRight - 1,
  263.        emacs_win->Height - emacs_win->BorderBottom - 1);
  264. }
  265.  
  266. static int make_reset_string(void)
  267. {
  268.   sprintf(reset_string, CONSOLE_RESET, foreground, background, background);
  269. }
  270.  
  271. void reset_window(void)
  272. {
  273.   make_reset_string();
  274.   if (emacs_win)
  275.     {
  276.       screen_puts (reset_string, strlen(reset_string));
  277.       clear_window();
  278.       amiga_change_size ();
  279.     }
  280. }
  281.  
  282. static void close_app_win(void)
  283. {
  284.   if (emacs_app_win)
  285.     {
  286.       struct AppMessage *msg;
  287.  
  288.       RemoveAppWindow(emacs_app_win); /* What can I do if it fails ?! */
  289.       while (msg = (struct AppMessage *)GetMsg(wbport)) ReplyMsg(msg);
  290.     }
  291. }
  292.  
  293. static int close_emacs_window(void)
  294. {
  295.   close_app_win();
  296.   inputsig &= ~(1L << emacs_win->UserPort->mp_SigBit);
  297.   _device_close(emacs_console);
  298.   if(emacs_win)
  299.     {
  300.       /* put title back the way it should be   -ch3/19/93. */
  301.       ShowTitle(emacs_win->WScreen, !emacs_backdrop);
  302.     }
  303.   CloseWindow(emacs_win);
  304.   emacs_console = 0;
  305.   emacs_win = 0;
  306.   ConsoleDevice = 0;
  307. }
  308.  
  309. /* We need this function becuase we do not always have the string
  310.  * for the screen we opened on. for example LockPubScreen(NULL);
  311.  * This function will get the name by looping through all public
  312.  * screens looking for the one that matches ours. -ch3/20/93 */
  313.  
  314. char *get_screen_name(struct Screen *this, char *namebuf)
  315. {
  316.   struct PubScreenNode *pubscreens =
  317.     (struct PubScreenNode *)LockPubScreenList()->lh_Head;
  318.  
  319.   while (pubscreens->psn_Node.ln_Succ)
  320.     {
  321.       if (pubscreens->psn_Screen == this)
  322.     {
  323.       strcpy(namebuf, pubscreens->psn_Node.ln_Name);
  324.       UnlockPubScreenList();
  325.       return namebuf;
  326.     }
  327.       pubscreens = (struct PubScreenNode *)pubscreens->psn_Node.ln_Succ;
  328.     }
  329.   /* Failed to find screen */
  330.   namebuf[0] = '\0';
  331.   UnlockPubScreenList();
  332.  
  333.   return 0;
  334. }
  335.  
  336. /* added two parameters to eliminate the need for the global
  337.  * which was causing some unwanted effect (bugs). -ch3/19/93 */
  338.  
  339. static enum { ok, no_screen, no_window }
  340. open_emacs_window(UWORD x, UWORD y, UWORD w, UWORD h, int backdrop,
  341.           char *pubscreen_name)
  342.      /* Open or reopen emacs window */
  343. {
  344.   WORD minw, minh;
  345.   struct Screen *new_screen;
  346.   struct Window *new_win;
  347.   struct IOStdReq *new_console;
  348.   int no_backdrop = !backdrop;
  349.  
  350.   new_screen = LockPubScreen(pubscreen_name);
  351.  
  352.   if (!new_screen)
  353.     return no_screen;
  354.  
  355.   /* removed newwindow structure, and added as tag
  356.    * items so that we can change them easier. -ch3/16/93. */
  357.  
  358.   new_win = OpenWindowTags(0, WA_Left, x, WA_Top, y,
  359.                   WA_Width, w, WA_Height, h,    /* Static items */
  360.                   WA_AutoAdjust, 1, WA_NewLookMenus, 1,
  361.                   WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY |
  362.                             IDCMP_MOUSEBUTTONS| IDCMP_NEWSIZE |
  363.                             IDCMP_MENUPICK | IDCMP_MENUHELP,
  364.                   WA_PubScreen, new_screen,
  365.                   WA_BackFill, &background_hook,
  366.                   WA_MenuHelp, 1, WA_Activate, 1,
  367.                   WA_SimpleRefresh, 1,
  368.                   WA_MaxWidth, -1, WA_MaxHeight, -1,
  369.                   WA_Backdrop, backdrop,    /* changing items */
  370.                   WA_Borderless, backdrop,
  371.                   WA_CloseGadget, no_backdrop,
  372.                   WA_SizeGadget, no_backdrop,
  373.                   WA_DragBar, no_backdrop,
  374.                   WA_DepthGadget, no_backdrop,
  375.                   WA_Title, no_backdrop ?
  376.                    "GNU Emacs 18.59, Amiga port "VERS : 0,
  377.                               TAG_END);
  378.  
  379.   UnlockPubScreen(0L, new_screen);
  380.  
  381.   if (new_win)
  382.     {
  383.       /* if emacs_backdrop then the screen title will show BEHIND the window
  384.      -ch3/16/93. */
  385.       ShowTitle(new_screen, !emacs_backdrop);
  386.       SetFont(new_win->RPort, font);
  387.  
  388.       if (set_min_size(new_win, font, &minw, &minh) &&
  389.       (new_console = (struct IOStdReq *)
  390.        _device_open("console.device", CONU_CHARMAP, CONFLAG_NODRAW_ON_NEWSIZE,
  391.             (APTR)new_win, sizeof(*new_win),
  392.             sizeof(struct IOStdReq))))
  393.     {
  394.       inputsig |= 1L << new_win->UserPort->mp_SigBit;
  395.       ConsoleDevice = (struct Library *)new_console->io_Device;
  396.       emacs_app_win = AddAppWindowA(0, 0, new_win, wbport, 0);
  397.  
  398.       /* Copy the info into permanent storage */
  399.       emacs_win = new_win;
  400.       emacs_console = new_console;
  401.  
  402.       /* fetch the name of the current screen -ch3/19/93 */
  403.       emacs_screen_name = get_screen_name(emacs_win->WScreen,
  404.                           emacs_screen_name_storage);
  405.  
  406.       emacs_backdrop = backdrop;
  407.  
  408.       reset_window();
  409.  
  410.       return ok;
  411.     }
  412.       CloseWindow(new_win);
  413.     }
  414.   return no_window;
  415. }
  416.  
  417. void force_window(void)
  418. {
  419.   if (!emacs_win && !emacs_iconified)
  420.     {
  421.       if (open_emacs_window(emacs_x, emacs_y, emacs_w, emacs_h, emacs_backdrop,
  422.                 emacs_screen_name) != ok)
  423.     {
  424.       /* Try to return to defaults (Workbench, etc) */
  425.       if (open_emacs_window(0, 0, 640, 200, 0, 0) != ok)
  426.           _fail("I've lost my window ! Exiting.");
  427.     }
  428.       resume_menus();
  429.     }
  430. }
  431.  
  432. /* returns:
  433.  *    -2 if msg is not class RAWKEY
  434.  *    same as RawKeyConvert otherwise:
  435.  *    buffer length if <= kbsize
  436.  *    -1 else
  437.  */
  438. static DeadKeyConvert(struct IntuiMessage *msg, UBYTE *kbuffer, int kbsize,
  439.               struct KeyMap *kmap)
  440. {
  441.   static struct InputEvent ievent = {0, IECLASS_RAWKEY, 0, 0, 0};
  442.   int extra = 0, res;
  443.  
  444.   if (msg->Class != RAWKEY) return (-2);
  445.  
  446.   /* Do some keymapping ourselves to make emacs users happy */
  447.  
  448.   /* Ctrl-space becomes Ctrl-@ */
  449.   if (msg->Code == 0x40 && msg->Qualifier & CONTROL_MASK)
  450.     {
  451.       *kbuffer = 0;
  452.       return 1;
  453.     }
  454.   /* Backspace becomes DEL */
  455.   if (msg->Code == 0x41 && amiga_remap_bsdel)
  456.     {
  457.       *kbuffer = 0177;
  458.       return 1;
  459.     }
  460.   /* And DEL becomes CTRL-D */
  461.   if (msg->Code == 0x46 && amiga_remap_bsdel)
  462.     {
  463.       *kbuffer = 04;
  464.       return 1;
  465.     }
  466.   /* Stick numeric pad prefix in front of numeric keypad chars */
  467.   if (msg->Qualifier & IEQUALIFIER_NUMERICPAD && amiga_remap_numeric_keypad)
  468.     {
  469.       *kbuffer++ = 'x' & 037;
  470.       *kbuffer++ = '^' & 037;
  471.       *kbuffer++ = 'K';
  472.       kbsize -= 3;
  473.       extra = 3;
  474.     }
  475.  
  476.   /* pack input event */
  477.   ievent.ie_Code = msg->Code;
  478.  
  479.   /* Ignore meta in decoding keys */
  480.   ievent.ie_Qualifier = msg->Qualifier & ~META_MASK;
  481.  
  482.   /* get previous codes from location pointed to by IAddress
  483.    *  this pointer is valid until IntuiMessage is replied.
  484.    */
  485.   ievent.ie_position.ie_addr = *((APTR *)msg->IAddress);
  486.   ievent.ie_position.ie_dead.ie_prev1DownQual &= ~META_MASK;
  487.   ievent.ie_position.ie_dead.ie_prev2DownQual &= ~META_MASK;
  488.  
  489.   res = RawKeyConvert(&ievent, kbuffer, kbsize, kmap);
  490.   return res ? res + extra : 0;
  491. }
  492.  
  493. void add_wbevent(struct WBArg *wbarg)
  494. {
  495.   char filename[256];
  496.  
  497.   if (wbarg->wa_Lock && NameFromLock(wbarg->wa_Lock, filename, 256))
  498.     {
  499.       struct wbevent *event;
  500.  
  501.       if (wbarg->wa_Name) AddPart(filename, wbarg->wa_Name, 256);
  502.       if (event = (struct wbevent *)malloc(offsetof(struct wbevent, file) +
  503.                        strlen(filename) + 1))
  504.     {
  505.       event->next = wbevents;
  506.       strcpy(event->file, filename);
  507.       wbevents = event;
  508.     }
  509.     }
  510. }
  511.  
  512. void check_window(int force)
  513. {
  514.   ULONG class;
  515.   USHORT code, qualifier;
  516.   UWORD mx, my;
  517.   unsigned char buf[32];
  518.   int buflen, deiconify, i;
  519.   struct IntuiMessage *msg;
  520.   int mouse_event = FALSE, wb_event = FALSE;
  521.   struct AppMessage *amsg;
  522.  
  523.   force_window();
  524.  
  525.   if (emacs_win)
  526.     while (msg = (struct IntuiMessage *)GetMsg(emacs_win->UserPort))
  527.       {
  528.     class = msg->Class;
  529.     code = msg->Code;
  530.     qualifier = msg->Qualifier;
  531.     mx = msg->MouseX; my = msg->MouseY;
  532.     buflen = DeadKeyConvert(msg, buf, 32, 0);
  533.     ReplyMsg(msg);
  534.  
  535.     switch (class)
  536.       {
  537.       case IDCMP_CLOSEWINDOW: {
  538.         enque(030, FALSE); enque(03, FALSE); /* ^X^C */
  539.         break;
  540.       }
  541.       case IDCMP_RAWKEY: {
  542.         if (buflen > 0)
  543.           {
  544.         unsigned char *sbuf = buf;
  545.         int meta = qualifier & META_MASK;
  546.  
  547.         /* Don't set META on CSI */
  548.         do enque(*sbuf++, meta); while (--buflen);
  549.           }
  550.         break;
  551.       }
  552.       case IDCMP_NEWSIZE: amiga_change_size(); break;
  553.       case IDCMP_MENUPICK: case IDCMP_MENUHELP:
  554.         if (code == MENUNULL) break; /* else fall through */
  555.       case IDCMP_MOUSEBUTTONS: {
  556.         mouse_event = TRUE;
  557.         if (event_num == EVENTSIZE) break;
  558.  
  559.         events[event_in].class = class;
  560.         events[event_in].code = code;
  561.         events[event_in].qual = qualifier;
  562.         events[event_in].x = mx;
  563.         events[event_in].y = my;
  564.         event_num++;
  565.         event_in = (event_in + 1) % EVENTSIZE;
  566.  
  567.         break;
  568.       }
  569.       }
  570.       }
  571.   /* Handle App requests */
  572.   while (amsg = (struct AppMessage *)GetMsg(wbport))
  573.       switch (amsg->am_Type)
  574.     {
  575.     case MTYPE_APPICON: case MTYPE_APPWINDOW:
  576.       /* Add an event for all these files */
  577.       for (i = 0; i < amsg->am_NumArgs; i++) add_wbevent(amsg->am_ArgList + i);
  578.       wb_event = TRUE;
  579.       /* Reply to the message, and deiconify if was icon */
  580.       deiconify = amsg->am_Type == MTYPE_APPICON;
  581.       ReplyMsg(amsg);
  582.       if (deiconify && emacs_icon)
  583.         /* Reopen window */
  584.         if (open_emacs_window(emacs_x, emacs_y, emacs_w, emacs_h, emacs_backdrop,
  585.                   emacs_screen_name) == ok)
  586.           {
  587.         resume_menus();
  588.         RemoveAppIcon(emacs_icon);
  589.         emacs_icon = 0;
  590.         emacs_iconified = 0;
  591.           }
  592.       break;
  593.     default: ReplyMsg(amsg); break;
  594.     }
  595.  
  596.   if (amiga_mouse_initialized && (force && event_num > 0 || mouse_event))
  597.     {
  598.       enque(AMIGASEQ, FALSE); enque('M', FALSE);
  599.     }
  600.   if (amiga_wb_initialized && (force && wbevents || wb_event))
  601.     {
  602.       enque(AMIGASEQ, FALSE); enque('W', FALSE);
  603.     }
  604. }
  605.  
  606. void setup_intchar(char intchar)
  607. {
  608.   char cqbuf[2];
  609.  
  610.   if (MapANSI(&intchar, 1, cqbuf, 1, 0) == 1)
  611.     {
  612.       intkey_code = cqbuf[0];
  613.       intkey_qualifier = cqbuf[1];
  614.     }
  615.   else
  616.     {
  617.       /* Default is CTRL-G in usa0 keymap */
  618.       intkey_code = 0x24;
  619.       intkey_qualifier = IEQUALIFIER_CONTROL;
  620.     }
  621. }
  622.  
  623. /* Hack to detect interrupt char as soon as it is pressed */
  624. /* __interrupt disables stack checking.  -ch3/19/93.*/
  625. static long __saveds __interrupt __asm
  626. int_handler(register __a0 struct InputEvent *ev)
  627. {
  628.   struct InputEvent *ep, *laste;
  629.   static struct InputEvent retkey;
  630.   ULONG lock = LockIBase(0);
  631.  
  632.   if (emacs_win && IntuitionBase->ActiveWindow == emacs_win)
  633.     {
  634.       laste = 0;
  635.  
  636.       /* run down the list of events to see if they pressed the magic key */
  637.       for (ep = ev; ep; laste = ep, ep = ep->ie_NextEvent)
  638.     if (ep->ie_Class == IECLASS_RAWKEY &&
  639.         (ep->ie_Qualifier & 0xff) == intkey_qualifier &&
  640.         ep->ie_Code == intkey_code)
  641.       {
  642.         /* Remove this key from input sequence */
  643.         if (laste) laste->ie_NextEvent = ep->ie_NextEvent;
  644.         else ev = ep->ie_NextEvent;
  645.  
  646.         Vquit_flag = Qt;
  647.         Signal(_us, SIGBREAKF_CTRL_C);
  648.       }
  649.     }
  650.   UnlockIBase(lock);
  651.  
  652.   /* pass on the pointer to the event */
  653.   return (long)ev;
  654. }
  655.  
  656. DEFUN ("amiga-mouse-events", Famiga_mouse_events, Samiga_mouse_events, 0, 0, 0,
  657.        "Return number of pending mouse events from Intuition.")
  658.      ()
  659. {
  660.   register Lisp_Object tem;
  661.  
  662.   check_intuition ();
  663.  
  664.   XSET (tem, Lisp_Int, event_num);
  665.  
  666.   return tem;
  667. }
  668.  
  669. DEFUN ("amiga-proc-mouse-event", Famiga_proc_mouse_event, Samiga_proc_mouse_event,
  670.        0, 0, 0,
  671.        "Pulls a mouse event out of the mouse event buffer and dispatches\n\
  672. the appropriate function to act upon this event.")
  673. ()
  674. {
  675.   register Lisp_Object mouse_cmd;
  676.   register char com_letter;
  677.   register char key_mask;
  678.   register Lisp_Object tempx;
  679.   register Lisp_Object tempy;
  680.   extern Lisp_Object get_keyelt ();
  681.   extern int meta_prefix_char;
  682.   struct event *ev;
  683.   int posx, posy;
  684.  
  685.   check_intuition ();
  686.  
  687.   if (event_num) {
  688.     ev = &events[event_out];
  689.     event_out = (event_out + 1) % EVENTSIZE;
  690.     event_num--;
  691.     if (ev->class == MOUSEBUTTONS)
  692.       {
  693.     switch (ev->code)
  694.       {
  695.       case SELECTDOWN: com_letter = 2; break;
  696.       case SELECTUP: com_letter = 6; break;
  697.       case MIDDLEDOWN: com_letter = 1; break;
  698.       case MIDDLEUP: com_letter = 5; break;
  699.       case MENUDOWN: com_letter = 0; break;
  700.       case MENUUP: com_letter = 4; break;
  701.       default: com_letter = 3; break;
  702.       }
  703.     posx = amiga_pos_x(ev->x);
  704.     posy = amiga_pos_y(ev->y);
  705.     XSET (tempx, Lisp_Int, min (screen_width-1, max (0, posx)));
  706.     XSET (tempy, Lisp_Int, min (screen_height-1, max (0, posy)));
  707.       }
  708.     else
  709.       {
  710.     /* Must be Menu Pick or Help */
  711.     com_letter = ev->class == IDCMP_MENUPICK ? 3 : 7;
  712.  
  713.     /* The parameters passed describe the selected item */
  714.     XSET (tempx, Lisp_Int, MENUNUM(ev->code));
  715.     XSET (tempy, Lisp_Int, ITEMNUM(ev->code));
  716.       }
  717.     if (ev->qual & META_MASK) com_letter |= 0x20;
  718.     if (ev->qual & SHIFT_MASK) com_letter |= 0x10;
  719.     if (ev->qual & CONTROL_MASK) com_letter |= 0x40;
  720.  
  721.     Vamiga_mouse_pos = Fcons (tempx, Fcons (tempy, Qnil));
  722.     Vamiga_mouse_item = make_number (com_letter);
  723.     mouse_cmd = get_keyelt (access_keymap (MouseMap, com_letter));
  724.     if (NULL (mouse_cmd)) {
  725.       bell ();
  726.       Vamiga_mouse_pos = Qnil;
  727.     }
  728.     else return call1 (mouse_cmd, Vamiga_mouse_pos);
  729.   }
  730.   return Qnil;
  731. }
  732.  
  733. DEFUN ("amiga-get-mouse-event", Famiga_get_mouse_event, Samiga_get_mouse_event,
  734.        1, 1, 0,
  735.        "Get next mouse event out of mouse event buffer (com-letter (x y)).\n\
  736. ARG non-nil means return nil immediately if no pending event;\n\
  737. otherwise, wait for an event.")
  738. (arg)
  739. Lisp_Object arg;
  740. {
  741.   register char com_letter;
  742.   register char key_mask;
  743.  
  744.   register Lisp_Object tempx;
  745.   register Lisp_Object tempy;
  746.   struct event *ev;
  747.   int posx, posy;
  748.  
  749.   check_intuition ();
  750.  
  751.   if (NULL (arg))
  752.     {
  753.       amiga_consume_input();
  754.       while (!event_num)
  755.     {
  756.       int rfds = 1;
  757.  
  758.       select(1, &rfds, 0, 0, 0);
  759.       amiga_consume_input();
  760.     }
  761.     }
  762.   /*** ??? Surely you don't mean to busy wait??? */
  763.  
  764.   if (event_num) {
  765.     ev = &events[event_out];
  766.     event_out = (event_out + 1) % EVENTSIZE;
  767.     event_num--;
  768.     switch (ev->code)
  769.       {
  770.       case SELECTDOWN: com_letter = 2; break;
  771.       case SELECTUP: com_letter = 6; break;
  772.       case MIDDLEDOWN: com_letter = 1; break;
  773.       case MIDDLEUP: com_letter = 5; break;
  774.       case MENUDOWN: com_letter = 0; break;
  775.       case MENUUP: com_letter = 4; break;
  776.       default: com_letter = 3; break;
  777.       }
  778.     if (ev->qual & META_MASK) com_letter |= 0x20;
  779.     if (ev->qual & SHIFT_MASK) com_letter |= 0x10;
  780.     if (ev->qual & CONTROL_MASK) com_letter |= 0x40;
  781.  
  782.     posx = amiga_pos_x(ev->x);
  783.     posy = amiga_pos_y(ev->y);
  784.     XSET (tempx, Lisp_Int, min (screen_width-1, max (0, posx)));
  785.     XSET (tempy, Lisp_Int, min (screen_height-1, max (0, posy)));
  786.  
  787.     Vamiga_mouse_pos = Fcons (tempx, Fcons (tempy, Qnil));
  788.     Vamiga_mouse_item = make_number (com_letter);
  789.     return Fcons (com_letter, Fcons (Vamiga_mouse_pos, Qnil));
  790.   }
  791.   return Qnil;
  792. }
  793.  
  794. DEFUN ("amiga-get-wb-event", Famiga_get_wb_event, Samiga_get_wb_event,
  795.        1, 1, 0,
  796.        "Get next Workbench event out of workbench event buffer (a file name).\n\
  797. ARG non-nil means return nil immediately if no pending event;\n\
  798. otherwise, wait for an event.")
  799. (arg)
  800. Lisp_Object arg;
  801. {
  802.   Lisp_Object file;
  803.   struct wbevent *ev;
  804.  
  805.   check_intuition ();
  806.  
  807.   if (NULL (arg))
  808.     {
  809.       amiga_consume_input();
  810.       while (!wbevents)
  811.     {
  812.       int rfds = 1;
  813.  
  814.       select(1, &rfds, 0, 0, 0);
  815.       amiga_consume_input();
  816.     }
  817.     }
  818.   /*** ??? Surely you don't mean to busy wait??? */
  819.  
  820.   if (wbevents) {
  821.     file = build_string(wbevents->file);
  822.     ev = wbevents;
  823.     wbevents = wbevents->next;
  824.     free(ev);
  825.     return file;
  826.   }
  827.   return Qnil;
  828. }
  829.  
  830. DEFUN("amiga-set-foreground-color", Famiga_set_foreground_color,
  831.       Samiga_set_foreground_color, 1, 1, "nPen number: ",
  832.       "Use PEN as foreground color")
  833.      (pen)
  834. {
  835.   int fg;
  836.  
  837.   check_intuition();
  838.   CHECK_NUMBER(pen, 0);
  839.  
  840.   fg = XUINT (pen);
  841.   if (pen > 7) error("Pen colors must be between 0 & 7");
  842.   foreground = fg;
  843.   reset_window();
  844.   return Qnil;
  845. }
  846.  
  847. DEFUN("amiga-set-background-color", Famiga_set_background_color,
  848.       Samiga_set_background_color, 1, 1, "nPen number: ",
  849.       "Use PEN as background color")
  850.      (pen)
  851. {
  852.   int bg;
  853.  
  854.   check_intuition();
  855.   CHECK_NUMBER(pen, 0);
  856.  
  857.   bg = XUINT (pen);
  858.   if (pen > 7) error("Pen colors must be between 0 & 7");
  859.   background = bg;
  860.   reset_window();
  861.   return Qnil;
  862. }
  863.  
  864. DEFUN("amiga-set-inverse-fill-pen", Famiga_set_inverse_fill_pen,
  865.       Samiga_set_inverse_fill_pen, 1, 1, "nPen number: ",
  866.       "Use PEN's color for inverse fills (0-7 or 8 for reverse)")
  867.      (pen)
  868. {
  869.   int ifp = 8;
  870.  
  871.   check_intuition();
  872.   CHECK_NUMBER(pen, 0);
  873.  
  874.   ifp = XUINT (pen);
  875.   if (pen > 8)
  876.     error("choices are from 0 to 8");
  877.   inverse_fill_pen = ifp;
  878.   reset_window();
  879.   return Qnil;
  880. }
  881.  
  882. DEFUN("amiga-set-inverse-text-pen", Famiga_set_inverse_text_pen,
  883.       Samiga_set_inverse_text_pen, 1, 1, "nPen number: ",
  884.       "Use PEN's color for inverse fills (0-7 or 8 for reverse)")
  885.      (pen)
  886. {
  887.   int itp = 8;
  888.  
  889.   check_intuition();
  890.   CHECK_NUMBER(pen, 0);
  891.  
  892.   itp = XUINT (pen);
  893.   if (pen > 8)
  894.     error("choices are from 0 to 8");
  895.   inverse_text_pen = itp;
  896.   reset_window();
  897.   return Qnil;
  898. }
  899.  
  900. DEFUN("amiga-set-font", Famiga_set_font, Samiga_set_font, 2, 2,
  901.       "sFont: \n\
  902. nSize: ",
  903.       "Set font used for window to FONT with given HEIGHT.\n\
  904. The font used must be non-proportional.")
  905. (wfont, height)
  906. {
  907.   struct TextAttr attr;
  908.   struct TextFont *newfont;
  909.   char *fname;
  910.   struct Lisp_String *fstr;
  911.   WORD minw, minh, oldmw, oldmh;
  912.  
  913.   CHECK_STRING (wfont, 0);
  914.   CHECK_NUMBER (height, 0);
  915.  
  916.   check_intuition();
  917.  
  918.   fstr = XSTRING (wfont);
  919.   fname = (char *)alloca (fstr->size + 6);
  920.   strcpy (fname, fstr->data);
  921.   strcat (fname, ".font");
  922.   attr.ta_Name = fname;
  923.   attr.ta_YSize = XFASTINT (height);
  924.   attr.ta_Style = 0;
  925.   attr.ta_Flags = 0;
  926.   newfont = OpenDiskFont (&attr);
  927.  
  928.   if (!newfont)
  929.     error ("Font %s %d not found", fstr->data, XFASTINT (height));
  930.   if (newfont->tf_Flags & FPF_PROPORTIONAL)
  931.     {
  932.       CloseFont(newfont);
  933.       error ("Font %s %d is proportional", fstr->data, XFASTINT (height));
  934.     }
  935.  
  936.   if (emacs_win)
  937.     {
  938.       if (!set_min_size(emacs_win, newfont, &minw, &minh))
  939.     {
  940.       CloseFont(newfont);
  941.       if (!set_min_size(emacs_win, font, &oldmw, &oldmh))
  942.         _fail("Failed to restore old font, exiting.");
  943.       error("Window is too small for this font, need at least %d(w) by %d(h)",
  944.         minw, minh);
  945.     }
  946.       SetFont(emacs_win->RPort, newfont);
  947.     }
  948.   if (font_opened) CloseFont(font);
  949.   font_opened = TRUE;
  950.   font = newfont;
  951.   reset_window();
  952.   return Qnil;
  953. }
  954.  
  955. DEFUN("amiga-set-geometry", Famiga_set_geometry, Samiga_set_geometry, 4, MANY, 0,
  956.       "Set Emacs window geometry and screen.\n\
  957. First 4 parameters are the (X,Y) position of the top-left corner of the window\n\
  958. and its WIDTH and HEIGHT. These must be big enough for an 11x4 characters window.\n\
  959. If nil is given for any of these, that means to keep the same value as before.\n\
  960. The optional argument SCREEN specifies which screen to use, nil stands for the\n\
  961. same screen as the window is on, t stands for the default public screen (normally\n\
  962. the Workbench), a string specifies a given public screen.\n\
  963. If optional argument BACKDROP is t, a backdrop window is used.")
  964.   (nargs, args)
  965.     int nargs;
  966.     Lisp_Object *args;
  967. {
  968.   Lisp_Object x, y, w, h, scr = Qnil, backdrop = Qnil;
  969.   int opened;
  970.   WORD tempx, tempy, tempw, temph;
  971.   char *screen_name;
  972.   int use_backdrop;
  973.  
  974.   if (nargs > 6) error("Too many arguments to amiga-set-geometry");
  975.   x = args[0]; y = args[1]; w = args[2]; h = args[3];
  976.   if (nargs > 4)
  977.     {
  978.       scr = args[4];
  979.       if (nargs > 5) backdrop = args[5];
  980.     }
  981.  
  982.   check_intuition();
  983.  
  984.   if (!NULL (x))
  985.     {
  986.       CHECK_NUMBER(x, 0);
  987.       tempx = XUINT(x);
  988.     }
  989.   else tempx = EMACS_X();
  990.   if (!NULL (y))
  991.     {
  992.       CHECK_NUMBER(y, 0);
  993.       tempy = XUINT(y);
  994.     }
  995.   else tempy = EMACS_Y();
  996.   if (!NULL (w))
  997.     {
  998.       CHECK_NUMBER(w, 0);
  999.       tempw = XUINT(w);
  1000.     }
  1001.   else tempw = EMACS_W();
  1002.   if (!NULL (h))
  1003.     {
  1004.       CHECK_NUMBER(h, 0);
  1005.       temph = XUINT(h);
  1006.     }
  1007.   else temph = EMACS_H();
  1008.  
  1009.   use_backdrop = !NULL(backdrop);
  1010.  
  1011.   if (scr == Qt) screen_name = 0; /* set to zero for def. */
  1012.   else if (!NULL (scr))
  1013.     {
  1014.       CHECK_STRING (scr, 0);
  1015.       screen_name = XSTRING (scr)->data;
  1016.     }
  1017.   else screen_name = emacs_screen_name;
  1018.  
  1019.   if (emacs_win)
  1020.     {
  1021.       struct Window *old_win = emacs_win;
  1022.       struct IOStdReq *old_console = emacs_console;
  1023.  
  1024.       suspend_menus();
  1025.       opened = open_emacs_window(tempx, tempy, tempw, temph, use_backdrop,
  1026.                  screen_name);
  1027.       if (opened != ok)
  1028.     {
  1029.       resume_menus();
  1030.  
  1031.       if (opened == no_window) error("Failed to open desired window");
  1032.       else if (screen_name)
  1033.         error("Unknown public screen %s", screen_name);
  1034.       else error("The default screen wasn't found !?");
  1035.     }
  1036.  
  1037.       _device_close(old_console);
  1038.       CloseWindow(old_win);
  1039.       if (!resume_menus()) error("Failed to recover menus (No memory?)");
  1040.     }
  1041.   else /* No window, set defaults */
  1042.     {
  1043.       emacs_screen_name = screen_name;
  1044.       if (screen_name)
  1045.     {
  1046.       emacs_screen_name_storage[MAXPUBSCREENNAME] = '\0';
  1047.       strncpy(emacs_screen_name_storage, screen_name, MAXPUBSCREENNAME);
  1048.     }
  1049.       emacs_x = tempx;
  1050.       emacs_y = tempy;
  1051.       emacs_w = tempw;
  1052.       emacs_h = temph;
  1053.       emacs_backdrop = use_backdrop;
  1054.     }
  1055.   return Qnil;
  1056. }
  1057.  
  1058.  
  1059. /* The next 2 functions are very usefull for writing
  1060.  * arexx/lisp functions that interact with other programs
  1061.  * that will be sharing the same screen.  -ch3/19/93. */
  1062.  
  1063. DEFUN("amiga-get-window-geometry",
  1064.       Famiga_get_window_geometry, Samiga_get_window_geometry, 0, 0, 0,
  1065.       "Get Emacs window geometry.\n\
  1066. a list returned is of the form:  (iconified x y width height backdrop)\n\
  1067. where x, y, width, height are integers, backdrop is t or nil and iconified\n\
  1068. is t if the window is iconified and nil otherwise")
  1069. ()
  1070. {
  1071.   Lisp_Object x, y, w, h, b, i;
  1072.  
  1073.   XSET(x, Lisp_Int, EMACS_X());
  1074.   XSET(y, Lisp_Int, EMACS_Y());
  1075.   XSET(w, Lisp_Int, EMACS_W());
  1076.   XSET(h, Lisp_Int, EMACS_H());
  1077.   b = emacs_backdrop ? Qt : Qnil;
  1078.   i = emacs_iconified ? Qt : Qnil;
  1079.  
  1080.   return Fcons(i, Fcons(x, Fcons(y, Fcons(w, Fcons(h, Fcons(b, Qnil))))));
  1081. }
  1082.  
  1083. DEFUN("amiga-get-screen-geometry",
  1084.       Famiga_get_screen_geometry, Samiga_get_screen_geometry, 0, 0, 0,
  1085.       "Get geometry of the screen emacs window resides on.\n\
  1086. a list returned is of the form:  (name x y width height)\n\
  1087. where name is a string, x, y, width, height are integers.\n\
  1088. Only the public screen name is returned if the window is not currently open.\n\
  1089. In this last case, the name may be nil if the window will be opened on the\n\
  1090. default public screen.")
  1091. ()
  1092. {
  1093.   Lisp_Object name;
  1094.  
  1095.   if (emacs_screen_name) name = Qnil;
  1096.   else name = build_string(emacs_screen_name);
  1097.  
  1098.   if(emacs_win)
  1099.     {
  1100.       struct Screen *s = emacs_win->WScreen;
  1101.       Lisp_Object x, y, w, h;
  1102.  
  1103.       XSET(x, Lisp_Int, s->LeftEdge);
  1104.       XSET(y, Lisp_Int, s->TopEdge);
  1105.       XSET(w, Lisp_Int, s->Width);
  1106.       XSET(h, Lisp_Int, s->Height);
  1107.  
  1108.       return Fcons(name, Fcons(x, Fcons(y, Fcons(w, Fcons(h, Qnil)))));
  1109.     }
  1110.   return Fcons(name, Qnil);
  1111. }
  1112.  
  1113. DEFUN("amiga-iconify", Famiga_iconify, Samiga_iconify, 0, 0, "",
  1114.       "Toggle the emacs iconification state.")
  1115. ()
  1116. {
  1117.   check_intuition();
  1118.  
  1119.   if (emacs_iconified)
  1120.     {
  1121.       /* Deiconify */
  1122.  
  1123.       /* Reopen window */
  1124.       if (open_emacs_window(emacs_x, emacs_y, emacs_w, emacs_h, emacs_backdrop,
  1125.                 emacs_screen_name) != ok)
  1126.     error("Failed to deiconify (No memory?)");
  1127.       resume_menus();
  1128.  
  1129.       RemoveAppIcon(emacs_icon);
  1130.       emacs_icon = 0;
  1131.       emacs_iconified = 0;
  1132.     }
  1133.   else
  1134.     if (emacs_icon = AddAppIconA(0, 0, "Emacs", wbport, 0, &emacs_icon_object, 0))
  1135.       {
  1136.     if (emacs_win)
  1137.       {
  1138.         /* Close window */
  1139.         emacs_x = EMACS_X(); emacs_y = EMACS_Y();
  1140.         emacs_w = EMACS_W(); emacs_h = EMACS_H();
  1141.         suspend_menus();
  1142.         close_emacs_window();
  1143.       }
  1144.     emacs_iconified = 1;
  1145.       }
  1146.     else error("Iconify attempt failed\n");
  1147.  
  1148.   return Qnil;
  1149. }
  1150.  
  1151. DEFUN("amiga-set-icon-pos", Famiga_set_icon_pos, Samiga_set_icon_pos, 2, 2,
  1152. "nX position: \n\
  1153. nY position: ",
  1154.       "Set the X Y position of the icon for emacs when iconified.")
  1155.   (Lisp_Object x, Lisp_Object y)
  1156. {
  1157.   long xpos, ypos;
  1158.  
  1159.   if (NULL (x)) emacs_icon_object.do_CurrentX = NO_ICON_POSITION;
  1160.   else
  1161.     {
  1162.       CHECK_NUMBER (x, 0);
  1163.       emacs_icon_object.do_CurrentX = XINT(x);
  1164.     }
  1165.   if (NULL (y)) emacs_icon_object.do_CurrentY = NO_ICON_POSITION;
  1166.   else
  1167.     {
  1168.       CHECK_NUMBER (y, 0);
  1169.       emacs_icon_object.do_CurrentY = XINT(y);
  1170.     }
  1171.  
  1172.   return Qnil;
  1173. }
  1174.  
  1175. struct EClockVal scount[16], ecount[16];
  1176. long total[16], counting[16], nb[16], susp[16];
  1177.  
  1178. void start_count(int n)
  1179. {
  1180.   nb[n]++;
  1181.   if (counting[n]) printf("Restarted %d\n", n);
  1182.   counting[n] = 1;
  1183.   /*ReadEClock(&scount[n]);*/
  1184. }
  1185.  
  1186. void stop_count(int n)
  1187. {
  1188.   if (counting[n])
  1189.     {
  1190.       /*ReadEClock(&ecount[n]);*/
  1191.       counting[n] = 0;
  1192.  
  1193.       total[n] += ecount[n].ev_lo - scount[n].ev_lo;
  1194.     }
  1195. }
  1196.  
  1197. void suspend_count(int n)
  1198. {
  1199.   if (counting[n] && susp[n]++ == 0)
  1200.     {
  1201.       /*ReadEClock(&ecount[n]);*/
  1202.       total[n] += ecount[n].ev_lo - scount[n].ev_lo;
  1203.     }
  1204. }
  1205.  
  1206. void resume_count(int n)
  1207. {
  1208.   if (counting[n] && --susp[n] == 0) /*ReadEClock(&scount[n])*/;
  1209. }
  1210.  
  1211. disp_counts(void)
  1212. {
  1213.   int i;
  1214.  
  1215.   for (i = 0; i < 16; i++)
  1216.     {
  1217.       printf("%d(%d) ", total[i], nb[i]);
  1218.       total[i] = nb[i] = 0;
  1219.     }
  1220.   printf("\n");
  1221. }
  1222.  
  1223. void screen_puts(char *str, unsigned int len)
  1224. {
  1225.   if (emacs_win)
  1226.     {
  1227.       int i;
  1228.  
  1229.       emacs_console->io_Command = CMD_WRITE;
  1230.       emacs_console->io_Data    = (APTR)str;
  1231.       emacs_console->io_Length  = len;
  1232.  
  1233.       /*    start_count(0);
  1234.         for (i = 1; i <= 6; i++) suspend_count(i);*/
  1235.       DoIO(emacs_console);
  1236.       /*    for (i = 1; i <= 6; i++) resume_count(i);
  1237.         stop_count(0);*/
  1238.     }
  1239. }
  1240.  
  1241. DEFUN ("amiga-activate-window", Famiga_activate_window, Samiga_activate_window, 0, 0, 0,
  1242.        "Makes emacs window the currently active one.")
  1243.      ()
  1244. {
  1245.   if(emacs_win) {
  1246.     ActivateWindow(emacs_win);
  1247.     return Qnil;
  1248.   }
  1249.   error("No window to make active.");
  1250.   return Qnil;
  1251. }
  1252.  
  1253. DEFUN ("amiga-window-to-front", Famiga_window_to_front, Samiga_window_to_front, 0, 0, 0,
  1254.        "Pulls the emacs window to the front (including screen)")
  1255.      ()
  1256. {
  1257.   if(emacs_win) {
  1258.     WindowToFront(emacs_win);
  1259.     ScreenToFront(emacs_win->WScreen);
  1260.     return Qnil;
  1261.   }
  1262.   error("No window to pull to the front.");
  1263.   return Qnil;
  1264. }
  1265.  
  1266. DEFUN ("amiga-window-to-back", Famiga_window_to_back, Samiga_window_to_back, 0, 0, 0,
  1267.        "Pushes the emacs window to the back (including screen)")
  1268.      ()
  1269. {
  1270.   if(emacs_win) {
  1271.     WindowToBack(emacs_win);
  1272.     ScreenToBack(emacs_win->WScreen);
  1273.     return Qnil;
  1274.   }
  1275.   error("No window to push back.");
  1276.   return Qnil;
  1277. }
  1278.  
  1279.  
  1280. void syms_of_amiga_screen(void)
  1281. {
  1282.   DEFVAR_LISP ("amiga-mouse-item", &Vamiga_mouse_item,
  1283.            "Encoded representation of last mouse click, corresponding to\n\
  1284. numerical entries in amiga-mouse-map.");
  1285.   Vamiga_mouse_item = Qnil;
  1286.   DEFVAR_LISP ("amiga-mouse-pos", &Vamiga_mouse_pos,
  1287.            "Current x-y position of mouse by row, column as specified by font.");
  1288.   Vamiga_mouse_pos = Qnil;
  1289.  
  1290.   DEFVAR_BOOL ("amiga-remap-bsdel", &amiga_remap_bsdel,
  1291.            "*If true, map DEL to Ctrl-D and Backspace to DEL. \n\
  1292. This is the most convenient (and default) setting. If nil, don't remap.");
  1293.   amiga_remap_bsdel = 1;
  1294.  
  1295.   DEFVAR_BOOL ("amiga-remap-numeric-keypad", &amiga_remap_numeric_keypad,
  1296.            "*If true, numeric keypad keys are prefixed with C-x C-^ K.\n\
  1297. This enables you to remap them, but causes problems with functions like\n\
  1298. isearch-forward-regexp on some keyboards. Default to true.");
  1299.   amiga_remap_numeric_keypad = 1;
  1300.  
  1301.   DEFVAR_BOOL ("amiga-mouse-initialized", &amiga_mouse_initialized,
  1302.            "Set to true once lisp has been setup to process mouse commands.\n\
  1303. No mouse processing request (C-X C-^ M) will be queued while this is nil.");
  1304.   amiga_mouse_initialized = 0;
  1305.  
  1306.   DEFVAR_BOOL ("amiga-wb-initialized", &amiga_wb_initialized,
  1307.            "Set to true once lisp has been setup to process workbench commands.\n\
  1308. No workbench processing request (C-X C-^ W) will be queued while this is nil.");
  1309.   amiga_mouse_initialized = 0;
  1310.  
  1311.   defsubr (&Samiga_mouse_events);
  1312.   defsubr (&Samiga_proc_mouse_event);
  1313.   defsubr (&Samiga_get_mouse_event);
  1314.   defsubr (&Samiga_get_wb_event);
  1315.   defsubr (&Samiga_set_font);
  1316.   defsubr (&Samiga_set_geometry);
  1317.   defsubr (&Samiga_set_background_color);
  1318.   defsubr (&Samiga_set_foreground_color);
  1319.   defsubr (&Samiga_iconify);
  1320.   defsubr (&Samiga_set_icon_pos);
  1321.  
  1322.   /* New functions  -ch3/19/93. */
  1323.   defsubr (&Samiga_set_inverse_text_pen);
  1324.   defsubr (&Samiga_set_inverse_fill_pen);
  1325.   defsubr (&Samiga_window_to_front);
  1326.   defsubr (&Samiga_window_to_back);
  1327.   defsubr (&Samiga_activate_window);
  1328.   defsubr (&Samiga_get_window_geometry);
  1329.   defsubr (&Samiga_get_screen_geometry);
  1330.  
  1331. }
  1332.  
  1333. void init_amiga_screen(void)
  1334. {
  1335.   event_num = event_in = event_out = 0;
  1336.  
  1337.   if (!((IntuitionBase = (struct IntuitionBase *)
  1338.      OpenLibrary("intuition.library", 37L)) &&
  1339.     (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L)) &&
  1340.     (DiskfontBase = OpenLibrary("diskfont.library", 0L)) &&
  1341.     (WorkbenchBase = OpenLibrary("workbench.library", 37)) &&
  1342.     (KeymapBase = OpenLibrary("keymap.library", 36)) &&
  1343.     (input_req = (struct IOStdReq *)_device_open("input.device", 0, 0, 0, 0,
  1344.                              sizeof(struct IOStdReq)))))
  1345.     _fail("Need version 2.04 and diskfont.library!");
  1346.  
  1347.   if (!(wbport = CreateMsgPort())) no_memory();
  1348.  
  1349.   /* Add Ctrl-G detector */
  1350.   int_handler_hook.is_Data = 0;
  1351.   int_handler_hook.is_Code = (void *)int_handler;
  1352.   int_handler_hook.is_Node.ln_Pri = 100; /* 100 not 127 is the standard value
  1353.                       * for input stream handlers.  -ch3/19/93. */
  1354.   /* it is standard for interrupts to have names  -ch3/19/93.*/
  1355.   int_handler_hook.is_Node.ln_Name = "GNU Emacs CTRL-G handler";
  1356.   input_req->io_Command = IND_ADDHANDLER;
  1357.   input_req->io_Data = (APTR)&int_handler_hook;
  1358.  
  1359.   /* wasn't checking for error. -ch3/19/93. */
  1360.   if(0 == DoIO(input_req))
  1361.     hooked = TRUE;
  1362.   else
  1363.     {
  1364.       hooked = FALSE;
  1365.       _fail("couldn't get input handler hook for CTRL-G");
  1366.     }
  1367.  
  1368.   inputsig |= 1L << wbport->mp_SigBit;
  1369.  
  1370.   background_hook.h_Entry = (ULONG (*)()) fill_background; /* added cast. */
  1371.   font = GfxBase->DefaultFont;
  1372.  
  1373.   init_amiga_menu();
  1374. }
  1375.  
  1376. void cleanup_amiga_screen(void)
  1377. {
  1378.   if (hooked)
  1379.     {
  1380.       input_req->io_Command = IND_REMHANDLER;
  1381.       input_req->io_Data = (APTR)&int_handler_hook;
  1382.       DoIO(input_req);
  1383.     }
  1384.   close_app_win();
  1385.   if (wbport) DeleteMsgPort(wbport);
  1386.   cleanup_amiga_menu();
  1387.   _device_close(emacs_console);
  1388.   if (emacs_win) CloseWindow(emacs_win);
  1389.   if (font_opened) CloseFont(font);
  1390.   if (IntuitionBase) CloseLibrary(IntuitionBase);
  1391.   if (GfxBase) CloseLibrary(GfxBase);
  1392.   if (DiskfontBase) CloseLibrary(DiskfontBase);
  1393.   if (WorkbenchBase) CloseLibrary(WorkbenchBase);
  1394.   if (KeymapBase) CloseLibrary(KeymapBase);
  1395.   _device_close(input_req);
  1396. }
  1397.