physical.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Copyright (c) 1986 AT&T
* All Rights Reserved
*/
#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.25 */
#include <curses.h>
#include <fcntl.h>
#include "wish.h"
#include "token.h"
#include "message.h"
#include "vt.h"
#include "var_arrays.h"
#include "actrec.h"
#include "moremacros.h"
#include "vtdefs.h"
#ifdef TIME_IT
#include <sys/types.h>
#include <sys/times.h>
#endif /* TIME_IT */
extern time_t Cur_time; /* abs k15, EFT k16*/
extern char Semaphore[];
extern int Coproc_active;
extern int Vflag;
extern time_t time(); /* EFT abs k16 */
/* #ifdef i386 abs k18 */
/*
* redefine curses mouse position macros
*/
#define SCR_ROW MOUSE_Y_POS
#define SCR_COL MOUSE_X_POS
/*
* Given a screen offset (r, c), PTS_to() will determine whether r,c
* points to a given frame (excluding the frame border).
* (br, bc is the beginning offset of the frame on the screen and
* mr, mc is the maximum rows and columns of the frame)
*/
#define PTS_to(r, c, br, bc, mr, mc) \
((r > br) && (r < (br + mr - 1)) && \
(c > bc) && (c < (bc + mc - 1)))
/*
* ON_border() will evaluate to true if the mouse points to the
* frame border
*/
#define ON_border(r, c, br, bc, mr, mc) \
(((r == br || (r == (br + mr - 1))) && \
(c >= bc && (c <= (bc + mc - 1)))) || \
((c == bc || (c == (bc + mc - 1))) && \
(r >= br && (r <= (br + mr - 1)))))
/*
* Determine the mouse offset within the frame (0,0 based)
* (excluding the frame border).
*/
#define FRAME_ROW(r1, r2) (r1 - (r2 + 1))
#define FRAME_COL(c1, c2) (c1 - (c2 + 1))
static token page_tok();
static token do_mouse(), do_open_mouse();
/* #endif abs k18 */
int Mouse_row;
int Mouse_col;
int Open_mouse_mode = FALSE;
extern long Mail_check;
extern long Interupt_pending;
token
physical_stream(t)
register token t;
{
token wgetchar();
int fd;
#ifdef PHYSICAL /* i dont know what this does but since
* it was un-compilable until k17
* it must never have been used. abs */
struct tms tms1, tms2;
clock_t real1; /* EFT abs k16 */
int lcv1 = 10000;
real1 = times( &tms1 ); /* ; added. abs k17 */
while ( lcv1-- )
{
#endif /* PHYSICAL */
Cur_time = time((time_t)0);
ar_checkworld(FALSE);
working(FALSE);
if (Vflag)
showmail( FALSE );
(void) mess_flush(FALSE);
/* new les */
vt_flush();
alarm((int) Mail_check);
if (Coproc_active)
{
/*
* The call to open is to protect "vsig" from
* sending a signal to FACE when the screen
* is being painted ...
* Vsig will block on the semaphore until FACE
* is able to receive signals ..
* This code may be changed if a better solution
* is found ...
* Interupt_pending is definined in main.c and
* set in the interupt handler for a SIGUSR2
* once a signal is encountered ...
*/
fd = open(Semaphore, O_RDONLY|O_NDELAY);
if (Interupt_pending)
{
Interupt_pending = 0;
ar_checkworld(TRUE);
vt_flush(); /* abs k18.2 */
}
t = wgetchar();
close(fd);
}
else
t = wgetchar();
mess_unlock(); /* allow calls to mess_temp and mess_perm */
if (t < 0)
t = TOK_NOP;
else if (t >= TOK_F(1) && t <= TOK_F(8))
t = t - TOK_F(1) + TOK_SLK1;
/* #ifdef i386 abs k18*/
else if (t == KEY_MOUSE)
{
if (Open_mouse_mode)
t = do_open_mouse();
else
t = do_mouse();
}
/* #endif abs k18 */
(void) mess_flush(TRUE);
return t;
#ifdef PHYSICAL /* abs k17 */
} /* abs k17 */
#endif /* PHYSICAL */ /* abs k17 */
}
/* #ifdef i386 abs k18 */
static token
do_mouse()
{
register int brow, bcol, mrow, mcol;
struct vt *v, *savev, *curvt;
int num, onborder;
token t;
struct actrec *wdw_to_ar();
if (BUTTON_CHANGED(2) || BUTTON_CHANGED(3))
return(TOK_NOP); /* only concerned about button 1 events */
if (BUTTON_CHANGED(1) && (BUTTON_STATUS(1) == BUTTON_PRESSED ||
BUTTON_STATUS(1) == BUTTON_CLICKED)) {
/*
* First check to see which frame (if any) the
* the mouse points to ...
*/
t = TOK_NOP;
savev = curvt = &VT_array[VT_curid];
getbegyx(curvt->win, brow, bcol);
getmaxyx(curvt->win, mrow, mcol);
if (ON_border(SCR_ROW, SCR_COL, brow, bcol, mrow, mcol)) {
/*
* Mouse points to the current frame border
*/
onborder = TRUE;
t = TOK_BPRESSED;
}
else if (PTS_to(SCR_ROW, SCR_COL, brow, bcol, mrow, mcol)) {
/*
* Mouse points to the current frame
*/
onborder = FALSE;
t = TOK_BPRESSED;
}
else {
/*
* Scan the list of VT's to find one that the
* mouse points to ...
*/
v = VT_array;
savev = NULL;
for (num = array_len(VT_array); num > 0; v++, num--) {
if (v == curvt || !(v->flags & VT_USED) ||
(v->flags & VT_NOBORDER))
continue; /* don't bother */
getbegyx(v->win, brow, bcol);
getmaxyx(v->win, mrow, mcol);
if (ON_border(SCR_ROW, SCR_COL, brow, bcol, mrow, mcol)) {
if (on_top(v, savev)) {
savev = v;
onborder = TRUE;
}
t = TOK_BPRESSED;
}
else if (PTS_to(SCR_ROW, SCR_COL, brow, bcol, mrow, mcol)) {
if (on_top(v, savev)) {
savev = v;
onborder = FALSE;
}
t = TOK_BPRESSED;
}
}
}
/*
* If the mouse doesn't point to a frame (t != TOK_BPRESSED)
* then return TOK_NOP
*/
if (t != TOK_BPRESSED)
return(TOK_NOP);
v = savev;
if (v != curvt) {
/*
* frame is not current so make it current
*/
ar_current(wdw_to_ar(v->number), TRUE); /* abs k15 */
vt_flush();
curvt = &VT_array[VT_curid];
getbegyx(curvt->win, brow, bcol);
getmaxyx(curvt->win, mrow, mcol);
}
if (onborder == FALSE) {
/*
* If not on the frame border then
* do object specific action for
* BUTTON PRESS
*/
Mouse_row = FRAME_ROW(SCR_ROW, brow);
Mouse_col = FRAME_COL(SCR_COL, bcol);
(void) arf_odsh(ar_get_current(), TOK_BPRESSED);
wrefresh(curvt->win);
}
if (mess_flush(FALSE)) /* update message line */
wrefresh(VT_array[MESS_WIN].win);
if (BUTTON_STATUS(1) == BUTTON_PRESSED) {
/*
* Perform mouse tracking while the button is
* depressed ... (if the mouse was "clicked" there
* is no need to track)
*
* NOTE: Do not map button release events to SLKS while
* tracking.
*/
map_button(0);
for (; ;) {
/*
* No longer track on BUTTON_RELEASE
*/
if (BUTTON_STATUS(1) == BUTTON_RELEASED) {
Mouse_row = FRAME_ROW(SCR_ROW, brow);
Mouse_col = FRAME_COL(SCR_COL, bcol);
break;
}
if (request_mouse_pos() == ERR)
break;
if (MOUSE_MOVED && PTS_to(SCR_ROW, SCR_COL, brow, bcol, mrow, mcol)) {
Mouse_row = FRAME_ROW(SCR_ROW, brow);
Mouse_col = FRAME_COL(SCR_COL, bcol);
(void) arf_odsh(ar_get_current(), TOK_BPRESSED);
wrefresh(curvt->win);
if (mess_flush(FALSE))
wrefresh(VT_array[MESS_WIN].win);
}
}
map_button(BUTTON1_RELEASED);
}
}
if (BUTTON_CHANGED(1) && (BUTTON_STATUS(1) == BUTTON_RELEASED ||
BUTTON_STATUS(1) == BUTTON_CLICKED)) {
/*
* If XY points to the current frame return (TOK_BRELEASED)
* otherwise ignore the mouse event (TOK_NOP)
*/
flushinp();
curvt = &VT_array[VT_curid];
getbegyx(curvt->win, brow, bcol);
getmaxyx(curvt->win, mrow, mcol);
if ((SCR_COL - bcol + 1) == mcol) {
/*
* The mouse points to the right frame border ...
* check to see if it is inside the scroll box
*/
t = page_tok(SCR_ROW, brow, mrow);
}
else if (PTS_to(SCR_ROW, SCR_COL, brow, bcol, mrow, mcol)) {
/*
* The mouse points to the current frame ...
* Determine the frame offset
*/
Mouse_row = FRAME_ROW(SCR_ROW, brow);
Mouse_col = FRAME_COL(SCR_COL, bcol);
t = TOK_BRELEASED;
}
else
t = TOK_NOP;
}
return(t);
}
/*
* DO_OPEN_MOUSE is similar to DO_MOUSE except the mouse doesn't have
* to point inside a frame (e.g., frame management routines move and
* reshape)
*/
static token
do_open_mouse()
{
token t;
if (BUTTON_CHANGED(2) || BUTTON_CHANGED(3))
return(TOK_NOP); /* only concerned about button 1 events */
t = TOK_NOP;
if (BUTTON_CHANGED(1) && BUTTON_STATUS(1) == BUTTON_PRESSED) {
/*
* Perform mouse tracking while button is depressed
*/
map_button(0);
for (; ;) {
t = TOK_NOP;
/*
* No longer track on BUTTON_RELEASE
*/
if (BUTTON_STATUS(1) == BUTTON_RELEASED) {
Mouse_row = SCR_ROW;
Mouse_row = SCR_ROW;
t = TOK_BRELEASED;
break;
}
if (request_mouse_pos() == ERR)
break;
if (MOUSE_MOVED) {
Mouse_row = SCR_ROW;
Mouse_col = SCR_COL;
(void) arf_odsh(ar_get_current(), TOK_BPRESSED);
vt_flush();
}
}
map_button(BUTTON1_RELEASED);
}
else if (BUTTON_CHANGED(1) && BUTTON_STATUS(1) == BUTTON_CLICKED) {
/*
* Button was clicked so don't track ... interpret as
* Button press immediately followed by button release.
*/
Mouse_row = SCR_ROW;
Mouse_col = SCR_COL;
(void) arf_odsh(ar_get_current(), TOK_BPRESSED);
vt_flush();
t = TOK_BRELEASED;
}
return(t);
}
/*
* Given that the mouse points to the right frame border,
* PAGE_TOK() returns a page token if the mouse points to
* the up/down arrow in the scroll box
*/
static token
page_tok(mouserow, brow, mrow)
int mouserow, brow, mrow;
{
int uparrow, dnarrow, framerow;
token rettok;
uparrow = (mrow / 2) - 1; /* location of up arrow */
dnarrow = uparrow + 2; /* location of down arrow */
framerow = mouserow - brow; /* location of the mouse */
if (framerow == uparrow)
rettok = TOK_PPAGE;
else if (framerow == dnarrow)
rettok = TOK_NPAGE;
else
rettok = TOK_NOP;
return(rettok);
}
/*
* Given 2 frames ON_TOP will return TRUE if frame 1 (arg1) is
* "on top of" frame 2 (arg2)
*/
static int
on_top(f1, f2)
struct vt *f1, *f2;
{
struct actrec *wdw_to_ar();
struct actrec *ar1, *ar2;
if (f2 == (struct vt *)NULL)
return(TRUE);
ar1 = wdw_to_ar(f1->number);
ar2 = wdw_to_ar(f2->number);
if (ar_isfirst(ar1, ar2))
return(TRUE);
else
return(FALSE);
}
/* #endif abs k18 */