home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / new / util / edit / jade / src / windows.c < prev    next >
C/C++ Source or Header  |  1994-10-03  |  20KB  |  770 lines

  1. /* windows.c -- System-independant window handling
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4.    This file is part of Jade.
  5.  
  6.    Jade is free software; you can redistribute it and/or modify it
  7.    under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    Jade is distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with Jade; see the file COPYING.    If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22.  
  23. #include <stdarg.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26.  
  27. _PR void messagen(u_char *, int);
  28. _PR void message(u_char *);
  29. _PR void messagef(u_char *, ...);
  30. _PR void no_message(VW *);
  31. _PR void std_message(VW *);
  32. _PR void reset_message(VW *);
  33. _PR void refresh_message(VW *);
  34. _PR void windows_init(void);
  35. _PR void windows_kill(void);
  36. _PR void window_sweep(void);
  37. _PR void window_prin(VALUE, VALUE);
  38.  
  39. VALUE sym_make_window_hook, sym_destroy_window_hook;
  40.  
  41. /* This can contain `dead' windows, ie vw_Window==NULL, they have been
  42.    close'd but must hang around until we're sure all refs are dead.  */
  43. _PR   VW     *view_chain;
  44. /* curr_vw is the active window */
  45. _PR   VW     *curr_vw;
  46. _PR   int      window_count;
  47. _PR   bool  log_messages;
  48.  
  49. VW   *view_chain;
  50. VW   *curr_vw;
  51. int   window_count;
  52. bool  log_messages;
  53.  
  54. _PR short def_dims[4];
  55. short def_dims[4] = { 0, 0, 80, 24 };
  56.  
  57. static void
  58. copy_prefs(VW *dest, VW *src)
  59. {
  60.     if(src)
  61.     {
  62.     dest->vw_MaxScroll = src->vw_MaxScroll;
  63.     dest->vw_XStepRatio = src->vw_XStepRatio;
  64.     dest->vw_YStepRatio = src->vw_YStepRatio;
  65.     dest->vw_Flags = src->vw_Flags;
  66.     dest->vw_FontName = src->vw_FontName;
  67. #ifdef HAVE_AMIGA
  68.     dest->vw_WindowSys.ws_FontSize = src->vw_WindowSys.ws_FontSize;
  69.     dest->vw_WindowSys.ws_ScreenName = src->vw_WindowSys.ws_ScreenName;
  70. #endif
  71.     }
  72.     else
  73.     {
  74.     dest->vw_MaxScroll = 20;
  75.     dest->vw_XStepRatio = 4;
  76. #ifdef HAVE_AMIGA
  77.     dest->vw_YStepRatio = 0;
  78. #else
  79.     dest->vw_YStepRatio = 4;
  80. #endif
  81.     dest->vw_Flags = 0;
  82.     dest->vw_FontName = def_font_str;
  83. #ifdef HAVE_AMIGA
  84.     dest->vw_WindowSys.ws_FontSize = ami_def_font_size;
  85.     dest->vw_WindowSys.ws_ScreenName = ami_def_pub_screen;
  86. #endif
  87.     }
  88. }
  89.  
  90. _PR VALUE cmd_make_window(VALUE xv, VALUE yv, VALUE wv, VALUE hv);
  91. DEFUN("make-window", cmd_make_window, subr_make_window, (VALUE xv, VALUE yv, VALUE wv, VALUE hv), V_Subr4, DOC_make_window) /*
  92. ::doc:make_window::
  93. make-window [X] [Y] [WIDTH] [HEIGHT]
  94.  
  95. Return a new window, it will be displaying the same buffer as the currently
  96. active window.
  97. ::end:: */
  98. {
  99.     VW *vw;
  100.     TX *tx = curr_vw ? curr_vw->vw_Tx : NULL;
  101.     if(NUMBERP(xv))
  102.     def_dims[0] = VNUM(xv);
  103.     if(NUMBERP(yv))
  104.     def_dims[1] = VNUM(yv);
  105.     if(NUMBERP(wv))
  106.     def_dims[2] = VNUM(wv);
  107.     if(NUMBERP(hv))
  108.     def_dims[3] = VNUM(hv);
  109.     vw = mycalloc(sizeof(VW));
  110.     if(vw)
  111.     {
  112.     vw->vw_Type = V_Window;
  113.     vw->vw_Next = view_chain;
  114.     view_chain = vw;
  115.     copy_prefs(vw, curr_vw);
  116.     if(sys_set_font(vw))
  117.     {
  118.         vw->vw_Window = sys_new_window(curr_vw, vw, TRUE);
  119.         if(vw->vw_Window)
  120.         {
  121.         window_count++;
  122.         sys_new_vw(vw);
  123.         vw->vw_BlockStatus = -1;
  124.         vw->vw_BufferList = sym_nil;
  125.         sys_update_dimensions(vw);
  126.         if(tx)
  127.         {
  128.             vw->vw_Tx = tx;
  129.             vw->vw_CursorPos = tx->tx_SavedCPos;
  130.             vw->vw_StartLine = tx->tx_SavedWPos.pos_Line;
  131.             vw->vw_StartCol = tx->tx_SavedWPos.pos_Col;
  132.             std_message(vw);
  133.             cmd_eval_hook2(sym_make_window_hook, VAL(vw));
  134. #ifndef NOSCRLBAR
  135.             sys_update_scroller(vw);
  136. #endif
  137.         }
  138.         vw->vw_Flags |= VWFF_FORCE_REFRESH;
  139.         return(VAL(vw));
  140.         }
  141.         sys_unset_font(vw);
  142.     }
  143.     myfree(vw);
  144.     }
  145.     return(NULL);
  146. }
  147.  
  148. _PR VALUE cmd_destroy_window(VALUE win);
  149. DEFUN("destroy-window", cmd_destroy_window, subr_destroy_window, (VALUE win), V_Subr1, DOC_destroy_window) /*
  150. ::doc:destroy_window::
  151. destroy-window [WINDOW]
  152.  
  153. Close WINDOW (or the current window), if this was the last one all files in
  154. memory are flushed and jade will exit.
  155. ::end:: */
  156. {
  157.     VW *vw = WINDOWP(win) ? VWIN(win) : curr_vw;
  158.     cmd_eval_hook2(sym_destroy_window_hook, VAL(vw));
  159.     no_message(vw);
  160.     /* This function is to take care of OS-independant stuff:
  161.        releasing GCs etc...  */
  162.     sys_kill_vw(vw);
  163.     sys_kill_window(vw);
  164.     sys_unset_font(vw);
  165.     window_count--;
  166.     /* This flags that this window is dead.  */
  167.     vw->vw_Window = WINDOW_NIL;
  168.     vw->vw_Tx = NULL;
  169.     vw->vw_BufferList = sym_nil;
  170.     if(curr_vw == vw)
  171.     {
  172.     while((vw = vw->vw_Next))
  173.     {
  174.         if(vw->vw_Window)
  175.         {
  176.         curr_vw = vw;
  177.         return(VAL(vw));
  178.         }
  179.     }
  180.     vw = view_chain;
  181.     while(vw && (vw != curr_vw))
  182.     {
  183.         if(vw->vw_Window)
  184.         {
  185.         curr_vw = vw;
  186.         return(VAL(vw));
  187.         }
  188.         vw = vw->vw_Next;
  189.     }
  190.     /* No living windows left :-( we'll die soon :-(  */
  191.     curr_vw = NULL;
  192.     throw_value = cmd_cons(sym_quit, make_number(0)); /* experimental. */
  193.     return(NULL);
  194.     }
  195.     return(VAL(curr_vw));
  196. }
  197.  
  198. _PR VALUE cmd_sleep_window(VALUE vw);
  199. DEFUN_INT("sleep-window", cmd_sleep_window, subr_sleep_window, (VALUE vw), V_Subr1, DOC_sleep_window, "") /*
  200. ::doc:sleep_window::
  201. sleep-window [WINDOW]
  202.  
  203. Iconifies the current window.
  204. ::end:: */
  205. {
  206.     if(!WINDOWP(vw))
  207.     vw = VAL(curr_vw);
  208.     if(((VWIN(vw)->vw_Flags & VWFF_SLEEPING) == 0)
  209.        && sys_sleep_vw(VWIN(vw)))
  210.     return(vw);
  211.     return(sym_nil);
  212. }
  213.  
  214. _PR VALUE cmd_unsleep_window(VALUE vw);
  215. DEFUN_INT("unsleep-window", cmd_unsleep_window, subr_unsleep_window, (VALUE vw), V_Subr1, DOC_unsleep_window, "") /*
  216. ::doc:unsleep_window::
  217. unsleep-window [WINDOW]
  218.  
  219. Uniconifies the current window.
  220. ::end:: */
  221. {
  222.     if(!WINDOWP(vw))
  223.     vw = VAL(curr_vw);
  224.     if((VWIN(vw)->vw_Flags & VWFF_SLEEPING) && sys_unsleep_vw(VWIN(vw)))
  225.     return(vw);
  226.     return(sym_nil);
  227. }
  228.  
  229. _PR VALUE cmd_next_window(VALUE vw, VALUE activ);
  230. DEFUN_INT("next-window", cmd_next_window, subr_next_window, (VALUE vw, VALUE activ), V_Subr2, DOC_next_window, "!\np") /*
  231. ::doc:next_window::
  232. next-window [WINDOW] [ACTIVATE]
  233.  
  234. Cycles through the open windows forwards.
  235. ::end:: */
  236. {
  237.     if(!WINDOWP(vw))
  238.     vw = VAL(curr_vw->vw_Next);
  239.     while(VWIN(vw) != curr_vw)
  240.     {
  241.     if(!vw)
  242.         vw = VAL(view_chain);
  243.     if(VWIN(vw)->vw_Window)
  244.     {
  245.         if(!NILP(activ))
  246.         {
  247.         curr_vw = VWIN(vw);
  248.         sys_activate_win(VWIN(vw));
  249.         }
  250.         return(vw);
  251.     }
  252.     vw = VAL(VWIN(vw)->vw_Next);
  253.     }
  254.     return(VAL(curr_vw));
  255. }
  256.  
  257. void
  258. messagen(u_char *title, int length)
  259. {
  260.     VW *vw = curr_vw;
  261.     if(log_messages)
  262.     {
  263.     fwrite(title, 1, length, stderr);
  264.     fputc('\n', stderr);
  265.     }
  266.     if((vw->vw_Flags & VWFF_SLEEPING) == 0)
  267.     {
  268.     str_free(vw->vw_Message);
  269.     vw->vw_Message = str_dupn(title, length);
  270.     vw->vw_MessageLen = length;
  271.     vw->vw_Flags |= VWFF_REFRESH_STATUS | VWFF_MESSAGE;
  272.     }
  273. }
  274.  
  275. void
  276. message(u_char *msg)
  277. {
  278.     messagen(msg, strlen(msg));
  279. }
  280.  
  281. void
  282. messagef(u_char *fmt, ...)
  283. {
  284.     VW *vw = curr_vw;
  285.     va_list args;
  286.     if((vw->vw_Flags & VWFF_SLEEPING) == 0)
  287.     {
  288.     u_char fmtbuff[256];
  289.     u_long len;
  290.     va_start(args, fmt);
  291.     vsprintf(fmtbuff, fmt, args);
  292.     va_end(args);
  293.     if(log_messages)
  294.        fprintf(stderr, "%s\n", fmtbuff);
  295.     str_free(vw->vw_Message);
  296.     len = strlen(fmtbuff);
  297.     vw->vw_Message = str_dupn(fmtbuff, len);
  298.     vw->vw_MessageLen = len;
  299.     vw->vw_Flags |= VWFF_REFRESH_STATUS | VWFF_MESSAGE;
  300.     }
  301. }
  302.  
  303. void
  304. no_message(VW *vw)
  305. {
  306.     if(((vw->vw_Flags & VWFF_SLEEPING) == 0) && vw->vw_Message)
  307.     {
  308.     str_free(vw->vw_Message);
  309.     vw->vw_Message = NULL;
  310.     vw->vw_MessageLen = 0;
  311.     vw->vw_Flags &= ~VWFF_MESSAGE;
  312.     vw->vw_Flags |= VWFF_REFRESH_STATUS;
  313.     }
  314. }
  315.  
  316. void
  317. std_message(VW *vw)
  318. {
  319.     if(((vw->vw_Flags & VWFF_MESSAGE) == 0)
  320.        && ((vw->vw_Flags & VWFF_SLEEPING) == 0))
  321.     {
  322.     TX *tx = vw->vw_Tx;
  323.     u_char *blk;
  324.     u_char fmtbuff[100];
  325.     u_long len;
  326.     if(vw->vw_BlockStatus >= 0)
  327.     {
  328.         if(vw->vw_BlockStatus == 0)
  329.         blk = "B";
  330.         else
  331.         blk = "b";
  332.     }
  333.     else
  334.         blk = "";
  335.     str_free(vw->vw_Message);
  336.     calc_cursor_offset(vw);
  337.     sprintf(fmtbuff, "%s%s %c%s%s%c (%ld,%ld) %ld line(s) %s",
  338.         VSTR(tx->tx_BufferName),
  339.         ((tx->tx_Changes != t