home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
new
/
util
/
edit
/
jade
/
src
/
windows.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-03
|
20KB
|
770 lines
/* windows.c -- System-independant window handling
Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
This file is part of Jade.
Jade is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Jade is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jade; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "jade.h"
#include "jade_protos.h"
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
_PR void messagen(u_char *, int);
_PR void message(u_char *);
_PR void messagef(u_char *, ...);
_PR void no_message(VW *);
_PR void std_message(VW *);
_PR void reset_message(VW *);
_PR void refresh_message(VW *);
_PR void windows_init(void);
_PR void windows_kill(void);
_PR void window_sweep(void);
_PR void window_prin(VALUE, VALUE);
VALUE sym_make_window_hook, sym_destroy_window_hook;
/* This can contain `dead' windows, ie vw_Window==NULL, they have been
close'd but must hang around until we're sure all refs are dead. */
_PR VW *view_chain;
/* curr_vw is the active window */
_PR VW *curr_vw;
_PR int window_count;
_PR bool log_messages;
VW *view_chain;
VW *curr_vw;
int window_count;
bool log_messages;
_PR short def_dims[4];
short def_dims[4] = { 0, 0, 80, 24 };
static void
copy_prefs(VW *dest, VW *src)
{
if(src)
{
dest->vw_MaxScroll = src->vw_MaxScroll;
dest->vw_XStepRatio = src->vw_XStepRatio;
dest->vw_YStepRatio = src->vw_YStepRatio;
dest->vw_Flags = src->vw_Flags;
dest->vw_FontName = src->vw_FontName;
#ifdef HAVE_AMIGA
dest->vw_WindowSys.ws_FontSize = src->vw_WindowSys.ws_FontSize;
dest->vw_WindowSys.ws_ScreenName = src->vw_WindowSys.ws_ScreenName;
#endif
}
else
{
dest->vw_MaxScroll = 20;
dest->vw_XStepRatio = 4;
#ifdef HAVE_AMIGA
dest->vw_YStepRatio = 0;
#else
dest->vw_YStepRatio = 4;
#endif
dest->vw_Flags = 0;
dest->vw_FontName = def_font_str;
#ifdef HAVE_AMIGA
dest->vw_WindowSys.ws_FontSize = ami_def_font_size;
dest->vw_WindowSys.ws_ScreenName = ami_def_pub_screen;
#endif
}
}
_PR VALUE cmd_make_window(VALUE xv, VALUE yv, VALUE wv, VALUE hv);
DEFUN("make-window", cmd_make_window, subr_make_window, (VALUE xv, VALUE yv, VALUE wv, VALUE hv), V_Subr4, DOC_make_window) /*
::doc:make_window::
make-window [X] [Y] [WIDTH] [HEIGHT]
Return a new window, it will be displaying the same buffer as the currently
active window.
::end:: */
{
VW *vw;
TX *tx = curr_vw ? curr_vw->vw_Tx : NULL;
if(NUMBERP(xv))
def_dims[0] = VNUM(xv);
if(NUMBERP(yv))
def_dims[1] = VNUM(yv);
if(NUMBERP(wv))
def_dims[2] = VNUM(wv);
if(NUMBERP(hv))
def_dims[3] = VNUM(hv);
vw = mycalloc(sizeof(VW));
if(vw)
{
vw->vw_Type = V_Window;
vw->vw_Next = view_chain;
view_chain = vw;
copy_prefs(vw, curr_vw);
if(sys_set_font(vw))
{
vw->vw_Window = sys_new_window(curr_vw, vw, TRUE);
if(vw->vw_Window)
{
window_count++;
sys_new_vw(vw);
vw->vw_BlockStatus = -1;
vw->vw_BufferList = sym_nil;
sys_update_dimensions(vw);
if(tx)
{
vw->vw_Tx = tx;
vw->vw_CursorPos = tx->tx_SavedCPos;
vw->vw_StartLine = tx->tx_SavedWPos.pos_Line;
vw->vw_StartCol = tx->tx_SavedWPos.pos_Col;
std_message(vw);
cmd_eval_hook2(sym_make_window_hook, VAL(vw));
#ifndef NOSCRLBAR
sys_update_scroller(vw);
#endif
}
vw->vw_Flags |= VWFF_FORCE_REFRESH;
return(VAL(vw));
}
sys_unset_font(vw);
}
myfree(vw);
}
return(NULL);
}
_PR VALUE cmd_destroy_window(VALUE win);
DEFUN("destroy-window", cmd_destroy_window, subr_destroy_window, (VALUE win), V_Subr1, DOC_destroy_window) /*
::doc:destroy_window::
destroy-window [WINDOW]
Close WINDOW (or the current window), if this was the last one all files in
memory are flushed and jade will exit.
::end:: */
{
VW *vw = WINDOWP(win) ? VWIN(win) : curr_vw;
cmd_eval_hook2(sym_destroy_window_hook, VAL(vw));
no_message(vw);
/* This function is to take care of OS-independant stuff:
releasing GCs etc... */
sys_kill_vw(vw);
sys_kill_window(vw);
sys_unset_font(vw);
window_count--;
/* This flags that this window is dead. */
vw->vw_Window = WINDOW_NIL;
vw->vw_Tx = NULL;
vw->vw_BufferList = sym_nil;
if(curr_vw == vw)
{
while((vw = vw->vw_Next))
{
if(vw->vw_Window)
{
curr_vw = vw;
return(VAL(vw));
}
}
vw = view_chain;
while(vw && (vw != curr_vw))
{
if(vw->vw_Window)
{
curr_vw = vw;
return(VAL(vw));
}
vw = vw->vw_Next;
}
/* No living windows left :-( we'll die soon :-( */
curr_vw = NULL;
throw_value = cmd_cons(sym_quit, make_number(0)); /* experimental. */
return(NULL);
}
return(VAL(curr_vw));
}
_PR VALUE cmd_sleep_window(VALUE vw);
DEFUN_INT("sleep-window", cmd_sleep_window, subr_sleep_window, (VALUE vw), V_Subr1, DOC_sleep_window, "") /*
::doc:sleep_window::
sleep-window [WINDOW]
Iconifies the current window.
::end:: */
{
if(!WINDOWP(vw))
vw = VAL(curr_vw);
if(((VWIN(vw)->vw_Flags & VWFF_SLEEPING) == 0)
&& sys_sleep_vw(VWIN(vw)))
return(vw);
return(sym_nil);
}
_PR VALUE cmd_unsleep_window(VALUE vw);
DEFUN_INT("unsleep-window", cmd_unsleep_window, subr_unsleep_window, (VALUE vw), V_Subr1, DOC_unsleep_window, "") /*
::doc:unsleep_window::
unsleep-window [WINDOW]
Uniconifies the current window.
::end:: */
{
if(!WINDOWP(vw))
vw = VAL(curr_vw);
if((VWIN(vw)->vw_Flags & VWFF_SLEEPING) && sys_unsleep_vw(VWIN(vw)))
return(vw);
return(sym_nil);
}
_PR VALUE cmd_next_window(VALUE vw, VALUE activ);
DEFUN_INT("next-window", cmd_next_window, subr_next_window, (VALUE vw, VALUE activ), V_Subr2, DOC_next_window, "!\np") /*
::doc:next_window::
next-window [WINDOW] [ACTIVATE]
Cycles through the open windows forwards.
::end:: */
{
if(!WINDOWP(vw))
vw = VAL(curr_vw->vw_Next);
while(VWIN(vw) != curr_vw)
{
if(!vw)
vw = VAL(view_chain);
if(VWIN(vw)->vw_Window)
{
if(!NILP(activ))
{
curr_vw = VWIN(vw);
sys_activate_win(VWIN(vw));
}
return(vw);
}
vw = VAL(VWIN(vw)->vw_Next);
}
return(VAL(curr_vw));
}
void
messagen(u_char *title, int length)
{
VW *vw = curr_vw;
if(log_messages)
{
fwrite(title, 1, length, stderr);
fputc('\n', stderr);
}
if((vw->vw_Flags & VWFF_SLEEPING) == 0)
{
str_free(vw->vw_Message);
vw->vw_Message = str_dupn(title, length);
vw->vw_MessageLen = length;
vw->vw_Flags |= VWFF_REFRESH_STATUS | VWFF_MESSAGE;
}
}
void
message(u_char *msg)
{
messagen(msg, strlen(msg));
}
void
messagef(u_char *fmt, ...)
{
VW *vw = curr_vw;
va_list args;
if((vw->vw_Flags & VWFF_SLEEPING) == 0)
{
u_char fmtbuff[256];
u_long len;
va_start(args, fmt);
vsprintf(fmtbuff, fmt, args);
va_end(args);
if(log_messages)
fprintf(stderr, "%s\n", fmtbuff);
str_free(vw->vw_Message);
len = strlen(fmtbuff);
vw->vw_Message = str_dupn(fmtbuff, len);
vw->vw_MessageLen = len;
vw->vw_Flags |= VWFF_REFRESH_STATUS | VWFF_MESSAGE;
}
}
void
no_message(VW *vw)
{
if(((vw->vw_Flags & VWFF_SLEEPING) == 0) && vw->vw_Message)
{
str_free(vw->vw_Message);
vw->vw_Message = NULL;
vw->vw_MessageLen = 0;
vw->vw_Flags &= ~VWFF_MESSAGE;
vw->vw_Flags |= VWFF_REFRESH_STATUS;
}
}
void
std_message(VW *vw)
{
if(((vw->vw_Flags & VWFF_MESSAGE) == 0)
&& ((vw->vw_Flags & VWFF_SLEEPING) == 0))
{
TX *tx = vw->vw_Tx;
u_char *blk;
u_char fmtbuff[100];
u_long len;
if(vw->vw_BlockStatus >= 0)
{
if(vw->vw_BlockStatus == 0)
blk = "B";
else
blk = "b";
}
else
blk = "";
str_free(vw->vw_Message);
calc_cursor_offset(vw);
sprintf(fmtbuff, "%s%s %c%s%s%c (%ld,%ld) %ld line(s) %s",
VSTR(tx->tx_BufferName),
((tx->tx_Changes != t