Category : Alternate Operating Systems - Quarterdeck DesqView, CP/M, etc
Archive   : DVGLUE17.ZIP
Filename : DEMO.C

 
Output of file : DEMO.C contained in archive : DVGLUE17.ZIP
/************************************************************************/
/* */
/* DV-GLUE DESQview and DESQview/X Function Library */
/* (c) Copyright 1993 Ralf Brown */
/* All Rights Reserved. */
/* */
/* File DEMO.C Demonstration Program */
/* */
/************************************************************************/
/* LastEdit: 1/3/93 */

#include
#include
#include
#include
#include
#include

#include "dvglue.h" /* types and function prototypes */
#include "dvstream.h"
#include "dvp.h"
#include "dvgui.h"

#if __TURBOC__ > 0x0100
unsigned _heaplen = 10240 ; /* only need 10K heap */
#endif

/*===============================================================*/

#define STDWIN_HEIGHT 14
#define STDWIN_WIDTH 68

/*===============================================================*/
/* global variables */
/*===============================================================*/

char old_title[32] ;
int old_frattr ;
int orig_rows,orig_cols ;
int orig_row,orig_col ;
int org_row, org_col ;
int orig_lrows,orig_lcols ;

/*===============================================================*/
/* wait for a keystroke, ensuring that the physical cursor pos */
/* is updated first (the logical cursor may move without */
/* necessarily moving the physical cursor) */
/*===============================================================*/

int get_key(void)
{
DVwin_hcur(NIL) ;
return bioskey(0) ;
}

/*===============================================================*/
/*===============================================================*/

void key_to_continue(void)
{
DVprintf(NIL,"Press a key to continue....") ;
get_key() ;
}

/*===============================================================*/
/* remove any trailing carriage returns and line feeds from the */
/* specified string. */
/*===============================================================*/

void stripCRLF(char *buf)
{
char *s = buf + strlen(buf) -1 ;

while (s >= buf && (*s == '\r' || *s == '\n'))
s-- ;
s[1] = '\0' ;
}

/*===============================================================*/
/* save as much of the current state as we can, to restore later */
/*===============================================================*/

void save_state(DVMENU *menu)
{
(void)menu ;
DVqry_origin(NIL,&org_row,&org_col) ;
DVqry_position(NIL,&orig_row,&orig_col) ;
DVqry_size(NIL,&orig_rows,&orig_cols) ;
DVqry_lsize(NIL,&orig_lrows,&orig_lcols) ;
DVqry_title(NIL,old_title,sizeof(old_title)) ;
old_frattr = DVqry_frattr(NIL) ;
}

/*===============================================================*/
/* restore as much of the old state as we've been able to save */
/*===============================================================*/

void restore_state(DVMENU *menu)
{
(void)menu ;
DVwin_lsize(NIL,orig_lrows,orig_lcols) ;
DVwin_title(NIL,old_title) ;
DVwin_frattr(NIL,old_frattr) ;
DVwin_move(NIL,orig_row,orig_col) ;
DVwin_resize(NIL,orig_rows,orig_cols) ;
DVwin_origin(NIL,org_row,org_col) ;
DVwin_redraw(NIL) ; /* make sure screen is updated */
}

/*===============================================================*/

void standard_window(char *title)
{
DVwin_resize(NIL,STDWIN_HEIGHT,STDWIN_WIDTH) ;
DVwin_move(NIL,7,5) ;
DVwin_cursor(NIL,0,0) ;
DVwin_origin(NIL,0,0) ;
DVwin_clear(NIL) ;
if (title)
DVwin_title(NIL,title) ;
}

/*===============================================================*/

int pascal help(OBJECT window,int status,char *results,long arg)
{
OBJECT helpwin ;

(void)window ; (void)status ; (void)results ; (void)arg ;
if ((helpwin = DVwin_create(NIL,"Help for DV-GLUE Demo",5,30,-1)) == NIL)
DVsound(1000,4) ; /* error beep */
else
{
DVprintf(helpwin,"Help selected.\n") ;
DVprintf(helpwin,"Press a key to continue....") ;
DVwin_unhide(helpwin) ;
DVwin_top(helpwin) ;
DVwin_redraw(helpwin) ;
get_key() ;
DVwin_free(helpwin) ;
}
return MA_DONE ;
}

/*===============================================================*/

int pascal stream_test(OBJECT window,int status,char *results,long arg)
{
int row, col ;
char buffer[10] ;
int i ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("DV-GLUE v" DVGLUE_versionSTR) ;
DVwin_frattr(NIL,9) ;
DVwin_redraw(NIL) ;
DVprintf(NIL,"Window #%d, old name was %s, origin (%d,%d)\n", DVappnum(), old_title, org_row,org_col) ;
DVqry_cursor(NIL,&row,&col) ;
DVprintf(NIL,"Cursor position is (%d,%d)\n",row,col) ;
DVqry_position(NIL,&row,&col) ;
DVprintf(NIL,"Window is at (%d,%d) ",row,col) ;
DVqry_size(NIL,&row,&col) ;
DVprintf(NIL,"and is %dx%d",row,col) ;
DVqry_lsize(NIL,&row,&col) ;
DVprintf(NIL,"/%dx%d in physical/logical size\n",row,col) ;
DVprintf(NIL,"The current output attribute is %d\n",DVqry_attr(NIL)) ;
DVprintf(NIL,"The old frame attribute was %d\n",old_frattr) ;
DVprintf(NIL,"Control code processing is %s",DVqry_ctrl(NIL)?"on":"off") ;
DVprintf(NIL," and we are\n %s when writing\n",
DVqry_leave(NIL)?"leaving attributes untouched":"changing attributes") ;
DVprintf(NIL,"Using %s attributes\n",DVqry_logattr(NIL)?"logical":"physical") ;
DVwin_hcur(NIL) ;
DVwin_atread(NIL,FALSE) ;
DVqry_cursor(NIL,&row,&col) ;
DVwin_cursor(NIL,0,0) ;
DVwin_readn(NIL,(void *)buffer,sizeof(buffer)) ;
DVwin_cursor(NIL,row,col) ;
DVprintf(NIL,"First method read '%s' from screen\n",buffer) ;
DVwin_cursor(NIL,0,0) ;
DVwin_read(NIL,(void *)buffer,sizeof(buffer)) ;
DVwin_gotoxy(NIL,col,row+1) ;
DVprintf(NIL,"Second method read '%s' from screen\n",buffer) ;

DVwin_swrite(NIL,"\r\nPress a key to hide window, then another to unhide it....\r\n");
get_key() ;
DVwin_hide(NIL) ;
get_key() ;
DVwin_unhide(NIL) ;
key_to_continue() ;

/* now scroll the visible portion of the virtual screen left until it is clear */
DVqry_size(NIL,&row,&col) ;
for (i = 0 ; i < col ; i++)
{
DVsleep(5) ;
DVwin_scroll(NIL,0,0,row,col,SCRL_LEFT) ;
}
return MA_DONE ;
}

/*===============================================================*/

int pascal timer_test(OBJECT window, int status, char *results, long arg)
{
OBJECT k, t, w ;
int left, elapsed ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window(NULL) ;
w = DVwin_new(NIL,5,46) ;
DVwin_clear(w) ;
DVposwin(w,NIL,PW_HCENTER|PW_VCENTER,0,0) ;
DVwin_cursor(w,0,0) ;
DVwin_origin(w,0,0) ;
DVwin_top(w) ;
DVprintf(w,"Press a few keys during the next ten seconds:"
"\n(this doesn't work as expected)") ;
k = DVkbd_new() ;
DVkbd_write(k,"a",1,0) ; /* make sure we allocate a buffer */
DVkbd_open(k,w) ; /* before connecting to window */
/* (to force one buffer per keystroke) */
DVkbd_setflags(k,KBD_ACTIVE) ;
t = DVtimer_new() ;
DVtimer_begin(t,1000) ; /* 10 seconds */
while ((left = (int) DVtimer_len(t)) > 0)
{
elapsed = (int) DVtimer_elapsed(t) ;
DVwin_cursor(w,3,0) ;
DVprintf(w,"Time left: %2d.%02d Buffers used: %d\n Elapsed: %2d.%02d",
left/100, left%100, DVkbd_messages(k), elapsed/100,
elapsed%100) ;
}
DVtimer_free(t) ;
DVkbd_clear(k) ; /* get rid of typeahead */
DVkbd_clear(NIL) ; /* just in case any typeahead leaked through to main kbd */
DVwin_cursor(w,0,0) ;
DVprintf(w,"%5d buffers used after clearing typeahead \n",DVkbd_messages(k));
while (bioskey(1)) /* brute-force keyboard clear */
bioskey(0) ;
DVsleep(100) ;
DVkbd_free(k) ;
DVwin_free(w) ;
DVkbd_setflags(NIL,KBD_ACTIVE) ; /* open and make active again */
DVkbd_clear(NIL) ; /* just in case any typeahead leaked through to main kbd */
return MA_DONE ;
}

/*===============================================================*/

void pascal notify_clear_line(void)
{
DVwin_swrite(NIL,"\r\n \r") ;
}

void pascal notify_move(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)arg ;
notify_clear_line() ;
DVprintf(NIL,"Hey, don't move me! Now at %d,%d",
msg->msg.movement.row,msg->msg.movement.col) ;
}

void pascal notify_size(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)arg ;
notify_clear_line() ;
DVprintf(NIL,"I liked my previous size! New size %d by %d",
msg->msg.resizing.rows,msg->msg.resizing.cols) ;
}

void pascal notify_hscroll(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)arg ;
notify_clear_line() ;
DVprintf(NIL,"You scrolled me %s",
(msg->msg.scrolling.amount>0)
? "right"
: ((msg->msg.scrolling.amount<0) ? "left" : "[done]")) ;
}

void pascal notify_vscroll(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)arg ;
notify_clear_line() ;
DVprintf(NIL,"You scrolled me %s",
(msg->msg.scrolling.amount>0)
? "down"
: ((msg->msg.scrolling.amount<0) ? "up" : "[done]")) ;
}

void pascal notify_close(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)msg ; (void)arg ;
notify_clear_line() ;
DVwin_swrite(NIL,"You can't close me yet! Next time WILL close me") ;
DVwin_cancel(NIL,DV_CLOSE,FALSE) ;
}

void pascal notify_hide(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)msg ; (void)arg ;
notify_clear_line() ;
DVwin_swrite(NIL,"You hid me!") ;
}

void pascal notify_help(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)arg ;
notify_clear_line() ;
DVprintf(NIL,"Sorry, no help available. Mouse at (%d,%d)",
msg->msg.help.mouse_row,msg->msg.help.mouse_col) ;
}

void pascal notify_colors(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)msg ; (void)arg ;
notify_clear_line() ;
DVwin_swrite(NIL,"Was the color changed?") ;
}

void pascal notify_raise(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)msg ; (void)arg ;
notify_clear_line() ;
DVwin_swrite(NIL,"Thanks for making me active.") ;
}

void pascal notify_lower(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)msg ; (void)arg ;
notify_clear_line() ;
DVwin_swrite(NIL,"Hey, I want to stay active!") ;
}

void pascal notify_videomode(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)arg ;
notify_clear_line() ;
DVprintf(NIL,"New video mode is %d",msg->msg.video_mode) ;
}

void pascal notify_cut(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)arg ;
notify_clear_line() ;
/* DVmbx_write(msg->msg.scissors.mailbox,0,0,"",0) ; /* keep DV happy */
DVprintf(NIL,"Sorry, don't know how to cut (%d,%d) to (%d,%d)",
msg->msg.scissors.up_left_row,
msg->msg.scissors.up_left_col,
msg->msg.scissors.up_left_row+msg->msg.scissors.height-1,
msg->msg.scissors.up_left_col+msg->msg.scissors.width-1) ;
}

void pascal notify_copy(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)arg ;
notify_clear_line() ;
/* DVmbx_write(msg->msg.scissors.mailbox,0,0,"",0) ; /* keep DV happy */
DVprintf(NIL,"Sorry, don't know how to copy (%d,%d) to (%d,%d)",
msg->msg.scissors.up_left_row,
msg->msg.scissors.up_left_col,
msg->msg.scissors.up_left_row+msg->msg.scissors.height-1,
msg->msg.scissors.up_left_col+msg->msg.scissors.width-1) ;
}

void pascal notify_paste(OBJECT win,NOTIFY_MSG *msg,long arg)
{
char mail[8] ;
int count ;

(void)win ; (void)arg ;
notify_clear_line() ;
count = DVmbx_size(msg->msg.scissors.mailbox) ;
DVprintf(NIL,"Pasting (%d,%d) to (%d,%d)--%d msgs\nPasted data: ",
msg->msg.scissors.up_left_row,
msg->msg.scissors.up_left_col,
msg->msg.scissors.up_left_row+msg->msg.scissors.height-1,
msg->msg.scissors.up_left_col+msg->msg.scissors.width-1,
count) ;
while (count > 0)
{
count -= DVreadmail(msg->msg.scissors.mailbox,mail,sizeof(mail)) ;
DVwin_swrite(NIL,mail) ;
}
DVmbx_clear(msg->msg.scissors.mailbox) ;
}

void pascal notify_mainmenu(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)msg ; (void)arg ;
notify_clear_line() ;
DVwin_swrite(NIL,"Main menu popped up") ;
}

void pascal notify_menu_end(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)win ; (void)msg ; (void)arg ;
notify_clear_line() ;
DVwin_swrite(NIL,"Main menu put away") ;
}

void pascal notify_other(OBJECT win,NOTIFY_MSG *msg,long arg)
{
(void)arg ;
notify_clear_line() ;
DVprintf(NIL,"Unknown event %d on %Fp! What happened?",msg->event,win) ;
}

SIGNAL_LIST notifications[] =
{ { DV_HMOVE, notify_move },
{ DV_VMOVE, notify_move },
{ DV_HSIZE, notify_size },
{ DV_VSIZE, notify_size },
{ DV_HSCROLL, notify_hscroll },
{ DV_VSCROLL, notify_vscroll },
{ DV_CLOSE, notify_close },
{ DV_HIDE, notify_hide },
{ DV_HELP, notify_help },
{ DV_COLORS, notify_colors },
{ DV_RAISE, notify_raise },
{ DV_LOWER, notify_lower },
{ DV_VIDEOMODE, notify_videomode },
{ DV_SCISSORS_CUT, notify_cut },
{ DV_SCISSORS_COPY, notify_copy },
{ DV_SCISSORS_PASTE, notify_paste },
{ DV_MAINMENU, notify_mainmenu },
{ DV_MENU_END, notify_menu_end },
{ DV_OTHER, notify_other }
} ;

int pascal notify_test(OBJECT window, int status, char *results, long arg)
{
char far *scrnbuf ;
int size, flag ;
int row, col ;
int sigID ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window(NULL) ;
DVwin_redraw(NIL) ;
if ((sigID = UIsignal(NIL,DVSIG_ADD,lengthof(notifications),notifications,0L,1000))
== DVSIG_ERROR)
{
DVprintf(NIL,"\a\nUnable to set handler for one or more signals\n") ;
DVsleep(200) ;

return MA_DONE ;
}
DVwin_disallow(NIL,DV_QUIT) ;
DVwin_swrite(NIL,"\r\nJust try to do something to me! (including closing me)\r\n") ;
DVwin_cursor(NIL,4,0) ;
DVwin_swrite(NIL,"Press a key when done....\r\n") ;
DVwin_hcur(NIL) ;
DVgetbuf(NIL,&scrnbuf,&size,&flag) ;
while (bioskey(1) == 0)
{
switch (scrnbuf[0])
{
case '|': scrnbuf[0] = '/' ;
break ;
case '/': scrnbuf[0] = '-' ;
break ;
case '-': scrnbuf[0] = '\\' ;
break ;
default: scrnbuf[0] = '|' ;
}
TVupdate(scrnbuf,2) ;
DVqry_cursor(NIL,&row,&col) ;
if (row > 20)
DVwin_cursor(NIL,5,0) ;
DVsleep(20) ;
}
bioskey(0) ;
UIsignal(NIL,DVSIG_REMOVE,lengthof(notifications),notifications,0L,sigID) ;
DVwin_allow(NIL,DV_QUIT) ;
DVwin_clear(NIL) ;
return MA_DONE ;
}

/*===============================================================*/

int pascal pointer_test(OBJECT window, int status, char *results, long arg)
{
OBJECT p ;
int i, rows, cols ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("Mouse Demo") ;
DVwin_move(NIL,6,1) ;
DVwin_top(NIL) ;
DVwin_redraw(NIL) ;
p = DVptr_new() ;
DVptr_open(p,NIL) ;
DVptr_icon(p,'+') ; /* this is actually ignored in DV, I assume it does work */
/* as advertised under TopView */
DVwin_disallow(NIL,DV_HSIZE) ;
DVwin_disallow(NIL,DV_VSIZE) ;
if (DVqry_kmouse()) /* if we are using a keyboard mouse */
DVapi_kmouse(TRUE) ; /* make sure it is on */
DVwin_swrite(NIL,"\r\nMoving mouse pointer to screen origin...") ;
DVsleep(50) ;
DVqry_position(NIL,&rows,&cols) ;
DVptr_goto(p,-rows,-cols) ;
DVsleep(150) ;
DVwin_swrite(NIL,"\r\nMoving mouse pointer to positions relative to window\r\n");
DVqry_size(NIL,&rows,&cols) ;
for (i = 0 ; i < rows ; i++)
{
DVptr_goto(p,i,i/2+1) ;
DVsleep(25) ;
}
DVwin_allow(NIL,DV_VSIZE) ;
DVwin_allow(NIL,DV_HSIZE) ;
DVptr_getscale(p,&rows,&cols) ;
DVprintf(NIL,"\nPointer scaling: %d rows and %d columns",rows,cols) ;
DVsleep(100) ;
DVptr_free(p) ;
if (DVqry_kmouse()) /* if we are using a keyboard mouse */
DVapi_kmouse(FALSE) ; /* make sure it is off */
DVwin_bottom(NIL) ;
return MA_DONE ;
}

int pascal mouse_drawing_program(OBJECT window,int status,char *results,long arg)
{
OBJECT p ;
POINTER_MSG msg ;
int left_button = FALSE ;
int right_button = FALSE ;

(void)window ; (void)status ; (void)results ; (void)arg ;
DVwin_clear(NIL) ;
DVwin_cursor(NIL,0,0) ;
DVwin_top(NIL) ;
DVwin_resize(NIL,23,47) ;
DVwin_move(NIL,1,10) ;
DVwin_swrite(NIL,"Drawing Program. Press key to quit\r\n"
" Left button sets block, right button erases\r\n"
" Row: 4 Col: 0 Buttons: \r\n"
"----------------------------------------------\r\n") ;
DVwin_redraw(NIL) ;
p = DVptr_new() ;
DVptr_open(p,NIL) ;
DVptr_setflags(p,PTR_RELEASE|PTR_NOTTOP) ;
if (DVqry_kmouse()) /* if we are using a keyboard mouse */
DVapi_kmouse(TRUE) ; /* make sure it is on */
DVptr_goto(p,4,0) ;
msg.row = 4 ; msg.column = 0 ; msg.button_state = 0 ;
while (bioskey(1) == 0)
{
while (DVptr_messages(p)) /* only read pointer if there is input */
{
DVptr_read(p,&msg) ;
if (msg.button_state & 1)
{
if (msg.button_state & 0x80)
left_button = TRUE ;
else if (msg.button_state & 0x40)
left_button = FALSE ;
}
else if (msg.button_state & 2)
if (msg.button_state & 0x80)
right_button = TRUE ;
else if (msg.button_state & 0x40)
right_button = FALSE ;
if (msg.row >= 4 && msg.row < 23 && msg.column >= 0 && msg.column < 46)
{
DVwin_cursor(NIL,msg.row,msg.column) ;
if (left_button)
DVputchar(NIL,'Û',7) ;
else if (right_button)
DVputchar(NIL,' ',7) ;
}
else if (msg.row < 4)
{
DVptr_goto(p,4,msg.column) ;
msg.row = 4 ;
}
}
DVwin_cursor(NIL,2,7) ;
DVprintf(NIL,"Row: %4d Col: %4d Buttons: %c%c", msg.row, msg.column,
left_button ? 'L' : ' ',right_button ? 'R' : ' ') ;
}
bioskey(0) ; /* swallow the keystroke */
DVptr_close(p) ;
DVptr_free(p) ;
if (DVisobj(p))
DVerrormsg(0,"Error--Pointer wasn't freed!",1,0,0,0) ;
else
{
DVwin_cursor(NIL,22,0) ;
key_to_continue() ;
}
if (DVqry_kmouse()) /* if we are using a keyboard mouse */
DVapi_kmouse(FALSE) ; /* make sure it is off */
DVwin_bottom(NIL) ;
return MA_DONE ;
}

/*===============================================================*/

static BYTE panel_data[] = {
PAN_HEADER(2),
'P','a','n','e','l','1',' ',' ',0x1F,0,0,0,0x26,0,
'P','a','n','e','l','2',' ',' ',0x45,0,0,0,0x2B,0,
S_WINDOW(0x22),
0xE5,0x40, /* panel command, uses existing window */
0xC0,2,0,
0x77,'T','h','i','s',' ','i','s',' ','t','h','e',' ','f','i','r','s','t',
' ','p','a','n','e','l',
0xC0,4,0,
0xD4,0xE4,

S_WINDOW(0x27),
0xE5,0xC0, /* panel command, creates new window */
0xE6,0x05,0x20,
0xC2,1,1,
0xC0,10,0,
0x78,'T','h','i','s',' ','i','s',' ','t','h','e',' ','s','e','c','o','n','d',
' ','p','a','n','e','l',
0xC0,12,0
} ;

int pascal panel_test(OBJECT window, int status, char *results, long arg)
{
OBJECT pan ;
OBJECT retwin, retkbd ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("Panel Test") ;
DVwin_redraw(NIL) ;
pan = DVpanel_new() ;
DVpanel_data(pan,panel_data,sizeof(panel_data)) ;
DVprintf(NIL,"Status = %d, #panels = %d\n",(int)DVpanel_status(pan),
(int)DVpanel_size(pan)) ;
DVsleep(100) ;
DVpanel_apply(pan,"Panel1 ",DVmywindow(),&retwin,&retkbd) ;
if (retwin && retwin != DVmywindow())
{
DVwin_top(retwin) ;
DVwin_move(retwin,1,1) ;
DVwin_redraw(retwin) ;
DVsleep(150) ;
DVwin_free(retwin) ;
}
else
DVsleep(100) ;
DVprintf(NIL,"Status = %d\nreturned kbd = %Fp\nreturned win = %Fp\n",
(int)DVpanel_status(pan),retkbd,retwin) ;
DVsleep(100) ;
DVpanel_apply(pan,"Panel2 ",DVmywindow(),&retwin,&retkbd) ;
if (retwin && retwin != DVmywindow())
{
DVwin_top(retwin) ;
DVwin_move(retwin,1,1) ;
DVwin_redraw(retwin) ;
DVsleep(150) ;
DVwin_free(retwin) ;
}
DVprintf(NIL,"Status = %d\nreturned kbd = %Fp\nreturned win = %Fp\n",
(int)DVpanel_status(pan),retkbd,retwin) ;
key_to_continue() ;
DVpanel_close(pan) ;
DVpanel_free(pan) ;
return MA_DONE ;
}

/*===============================================================*/

int pascal multiwindow_test(OBJECT window, int status, char *results, long arg)
{
OBJECT win1 = DVwin_new(NIL,10,15) ;
OBJECT win2 = DVwin_new(NIL,5,20) ;
OBJECT win3 = DVwin_new(NIL,8,30) ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("Multiwindow Demo") ;
DVwin_redraw(NIL) ;
DVwin_move(win1,6,60) ;
DVwin_title(win1,"Window 1") ;
DVwin_top(win1) ;
DVwin_redraw(win1) ;
DVwin_move(win2,1,52) ;
DVwin_title(win2,"Window 2") ;
DVwin_top(win2) ;
DVwin_redraw(win2) ;
DVwin_move(win3,4,40) ;
DVwin_title(win3,"Window 3") ;
DVwin_top(win3) ;
DVwin_redraw(win3) ;
DVwin_redraw(NIL) ;
DVsleep(150) ;
DVwin_reorder(win1,OBJSEG(win3),OBJSEG(win2),OBJSEG(DVmywindow()),OBJSEG(win1),0);
DVwin_swrite(win1,"Window 1 on top") ;
DVsleep(150) ;
DVwin_reorder(win3,OBJSEG(win2),OBJSEG(win1),OBJSEG(DVmywindow()),OBJSEG(win3),0);
DVwin_swrite(win3,"Window 3 on top") ;
DVsleep(150) ;
DVwin_reorder(win2,OBJSEG(win3),OBJSEG(DVmywindow()),OBJSEG(win1),OBJSEG(win2),0);
DVwin_swrite(win2,"Window 2 on top") ;
DVsleep(150) ;
DVwin_reorder(NIL,OBJSEG(win2),OBJSEG(win3),OBJSEG(win1),OBJSEG(DVmywindow()),0);
DVwin_swrite(NIL,"\r\nWindow 0 on top") ;
DVsleep(100) ;
DVwin_top(win3) ;
DVwin_swrite(win3,"\r\nWindow 3 on top again") ;
DVsleep(100) ;
DVwin_topsys(win2) ;
DVwin_swrite(win2,"\r\nWindow 2 now topmost" ) ;
DVsleep(100) ;
DVwin_top(NIL) ;
DVwin_swrite(NIL,"\r\nBack to window 0" ) ;
DVsleep(100) ;
DVwin_swrite(NIL,"\r\nPlease open another window, then press a key....") ;
DVwin_top(NIL) ; /* need to be topmost to have keyboard attached */
get_key() ;
DVwin_swrite(NIL,"\r\nAbout to hide and then unhide all my windows....") ;
DVsleep(150) ;
DVforeonly(NIL,FALSE) ; /* allow running in background */
DVapp_hide(NIL) ; /* this also puts us in background */
DVsleep(100) ;
DVapp_show(NIL) ;
DVsleep(10) ;
DVapp_gofore(NIL) ; /* so have to force ourself into foreground */
DVwin_swrite(NIL,"\r\nDone!") ;
DVwin_redraw(NIL) ;
DVsleep(50) ;
DVwin_swrite(NIL,"\r\n\nI am about to put myself in the background, and"
"\r\nthen back into the foreground") ;
DVsleep(200) ;
DVapp_goback(NIL) ;
DVsleep(100) ;
DVapp_gofore(NIL) ;
DVwin_swrite(NIL,"\r\nDone!\r\n") ;
DVsleep(50) ;
DVwin_free(win3) ;
DVsleep(50) ;
DVwin_free(win2) ;
DVsleep(50) ;
DVwin_free(win1) ;
DVsleep(50) ;
DVwin_frattr(NIL,0x70) ; /* reverse video */
DVwin_top(NIL) ; /* make window active */
DVwin_redraw(NIL) ; /* make sure physical screen is updated */
DVkbd_setflags(NIL,KBD_ACTIVE) ; /* make sure we get kbd input */
key_to_continue() ;
return MA_DONE ;
}

/*===============================================================*/

char prog[40], arg1[40] ;

void subtask1(int parent)
{
char kbd_input[16] ;
char mbx_input[32] ;
int mbx_status ;
OBJECT mbx ;

do {
DVkbd_read(NIL,kbd_input,sizeof(kbd_input)) ;
if (kbd_input[0] != 0x1B)
DVwin_swrite(NIL,kbd_input) ;
} while (kbd_input[0] != 0x1B) ;
DVwin_clear(NIL) ;
do {
DVreadmail(NIL,mbx_input, sizeof(mbx_input)) ;
mbx_status = (int) DVmbx_status(NIL) ;
if (mbx_input[0] == '\0')
DVwin_swrite(NIL,"\r\nThat's all, folks!" ) ;
else
DVprintf(NIL, "\nRead: '%s' with status %d from %s",
mbx_input,mbx_status,
(OBJSEG(DVmbx_sender(NIL))==parent)?"parent":"a stranger") ;
} while (mbx_input[0] != '\0') ;
DVsleep(250) ;
DVwin_clear(NIL) ;
DVwin_swrite(NIL,"Test of named mailboxes:\r\n") ;
mbx = DVmbx_new() ;
DVmbx_open(mbx);
DVmbx_name(mbx,"Test Mailbox") ;
DVmbx_clear(mbx) ;
DVmbx_write(DVmbx_of(MK_OBJ(parent)),FALSE,0,"Ready",5) ;
DVreadmail(mbx,mbx_input,sizeof(mbx_input)) ;
DVprintf(NIL,"Got '%s'",mbx_input) ;
DVsleep(150) ; /* don't ACK right away */
DVmbx_write(DVmbx_of(MK_OBJ(parent)),FALSE,0,"Done",4) ;
DVreadmail(NIL,mbx_input,sizeof(mbx_input)) ;
DVprintf(NIL,"got 'Quit' command\n") ;
DVmbx_close(mbx) ;
DVprintf(NIL,"mailbox closed") ;
DVmbx_free(mbx) ;
DVprintf(NIL," and freed. Bye...\n") ;
}

void subtask2(int parent)
{
int row = 0, col = 0 ;
int drow, dcol ;
int rows, cols ;
int rep ;

(void) parent ; /* get rid of TurboC's warning about unused parameters */
DVwin_cursor(NIL,0,0) ;
DVwin_hcur(NIL) ;
drow = 1 ;
dcol = 1 ;
for (rep = 0 ; rep < 30 ; rep++)
do {
if (DVmbx_size(NIL) != 0)
{
DVmbx_clear(NIL) ; /* discard messages, only used to notify us */
DVtask_stop(NIL) ; /* and suspend ourselves */
}
DVwin_cursor(NIL,row,col) ;
DVwin_swrite(NIL," ") ;
DVqry_size(NIL, &rows, &cols) ;
if (row < 0 || row >= rows-1)
drow = -drow ;
if (col < 0 || col >= cols-1)
dcol = -dcol ;
row += drow ;
col += dcol ;
DVwin_cursor(NIL,row,col) ;
DVwin_swrite(NIL,"+") ;
DVsleep(10) ;
} while (row != 0 || col != 0) ;
}

int pascal fork_test(OBJECT window, int status, char *results, long arg)
{
char key, keys[2] ;
OBJECT task1, task2 ;
int count = 0 ;
char mail[10] ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window(NULL) ;
DVwin_resize(NIL,8,66) ;
DVwin_move(NIL,5,11) ;
DVwin_redraw(NIL) ;
task1 = DVtask_new(NIL,"Echo keys",1,39,3,40,NULL,1000,subtask1,FALSE) ;
if (task1 == NIL)
{
DVerrormsg(0,"Insufficient memory or other error--Press ESC",1,0,0,0);
return MA_DONE ;
}
task2 = DVtask_new(NIL,"Another task",14,1,10,78,NULL,1000,subtask2,FALSE) ;
if (task2 == NIL)
{
DVerrormsg(0,"Insufficient memory or other error--Press ESC",1,0,0,0) ;
DVtask_free(task1) ;
return MA_DONE ;
}
DVwin_top(NIL) ; /* put the cursor back in our window */
DVwin_swrite(NIL,"Type characters to echo in other window, ESC to quit") ;
do {
key = get_key() ;
keys[0] = key ;
DVkbd_write(DVkbd_of(task1),keys,1,0) ;
} while (key != 0x1B) ;
DVsleep(25) ; /* allow time for other window to clear */
DVwin_swrite(NIL,"\r\nType strings to echo in other window, press just RETURN to quit\r\n") ;
DVwin_hcur(NIL) ;
do {
fgets(arg1, sizeof(arg1), stdin) ;
stripCRLF(arg1) ;
DVmbx_write(DVmbx_of(task1),FALSE,count++,arg1, strlen(arg1)) ;
} while (strlen(arg1) > 0) ;

DVmbx_clear(NIL) ;
DVwin_swrite(NIL,"\r\nTesting named mailboxes\r\n") ;
DVreadmail(NIL,mail,sizeof(mail)) ; /* wait for other task to set up mbx */
DVwin_swrite(NIL,"sending... " ) ;
DVmbx_write(DVmbx_find("Test Mailbox"),FALSE,0,"Test successful",15) ;
DVreadmail(NIL,mail,sizeof(mail)) ; /* wait for ACK */
DVprintf(NIL,"got ACK: '%s'\n",mail) ;
DVmbx_write(DVmbx_of(task1),FALSE,0,"Quit",4) ;
DVsleep(100) ; /* allow time for other window to close */
key_to_continue() ;
DVwin_move(NIL,1,1) ;
DVwin_resize(NIL,9,66) ;
DVwin_redraw(NIL) ; /* update window's size and position on the screen */
DVsendmail(DVmbx_of(task2),"",0) ; /* would like to do DVtask_stop(task2) */
/* but DV 2.00 only allows suspending */
/* the current process, not others */
DVwin_clear(NIL) ;
DVwin_origin(NIL,0,0) ;
DVwin_cursor(NIL,0,0) ;
DVwin_swrite(NIL,"\r\nThe 'bouncing' plus sign in the other window should"
"\r\nhave stopped moving. Press a key....") ;
get_key() ;
DVtask_start(task2) ;
DVwin_swrite(NIL,"\r\nIt should have started moving again. Press a key....") ;
get_key() ;
DVtask_free(task1) ;
DVtask_free(task2) ; /* make sure the subtasks are both terminated */
DVwin_clear(NIL) ;
return MA_DONE ;
}

/*===============================================================*/

DVP_file DVPbuffer ;

void app_new_test(void)
{
char *progname ;
OBJECT new_task ;

DVwin_clear(NIL) ;
DVwin_cursor(NIL,0,0) ;
DVwin_swrite(NIL,"\r\nOK, now let's load a user program.\r\nProgram's name, including extension: ");
DVwin_hcur(NIL) ;
fgets(prog,sizeof(prog),stdin) ;
stripCRLF(prog) ;
DVwin_swrite(NIL,"\r\nThe program's argument: " ) ;
DVwin_hcur(NIL) ;
fgets(arg1,sizeof(arg1),stdin) ;
stripCRLF(arg1) ;
progname = searchpath(prog) ;
if (progname)
{
DVprintf(NIL,"\nInvoking '%s %s'\n",progname,arg1) ;
new_task = DVapp_new(NIL,10,1,13,78,TRUE,progname,progname,arg1,NULL) ;
if (new_task != NIL)
{
DVwin_swrite(NIL,"\r\nExperiment with switching between this program and "
"\r\nthe one you just invoked. Press a key when done") ;
get_key() ;
DVapp_free(new_task) ;
}
else
{
DVprintf(NIL,"Program not loaded, error code %d\n"
"Press a key....",_doserrno) ;
get_key() ;
}
}
else
{
DVprintf(NIL,"\n\n\nCouldn't find %s!\n", prog ) ;
DVsleep(150) ;
}
}

void app_start_test(void)
{
int size ;
FILE *fp ;

standard_window("Create New Window") ;
if (DVver() >= 0x214) /* is this v2.20? */
DVwin_swrite(NIL,"Congratulations, you have a version for which this\r\n"
"test actually works right! (it didn't in v2.0x)\r\n") ;
else
DVwin_swrite(NIL,"This next test may cause your system to lock up.\r\n"
"It is known to cause a lockup the next time you\r\n"
"try to open a window under DV 2.00 (6-16-87)\r\n"
"With DV 2.01 (10-16-87) it merely does nothing\r\n") ;
DVwin_swrite(NIL,"\r\n"
"Type the keys from the open menu, or just Return to\r\n"
"skip this test\r\n"
"\r\n"
"Keys on open menu: ") ;
DVwin_redraw(NIL) ;
fgets(arg1,sizeof(arg1),stdin) ;
if (arg1[0] && arg1[0] != '\n')
{
arg1[2] = '\0' ;
DVwin_swrite(NIL,"DV directory (i.e. C:\\DV): ") ;
DVwin_hcur(NIL) ;
fflush(stdin) ;
fgets(prog,sizeof(prog)-11,stdin) ;
if (prog[strlen(prog)-1] == '\n')
prog[strlen(prog)-1] = '\0' ;
strcat(prog,"\\") ;
strcat(prog,arg1) ;
strcat(prog,"-PIF.DVP") ;
if ((fp = fopen(prog,"rb")) == NULL)
DVprintf(NIL,"\nUnable to open %s!\n",prog) ;
else
{
size = fread(&DVPbuffer,1,sizeof(DVPbuffer),fp) ;
if (DVapp_start(&DVPbuffer,size) == 0)
DVwin_swrite(NIL,"Unable to open!\r\n") ;
fclose(fp) ;
}
key_to_continue() ;
}
}

int pascal app_test(OBJECT window, int status, char *results, long arg)
{
(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("Starting Applications") ;
DVwin_redraw(NIL) ;
app_start_test() ;
app_new_test() ;
DVwin_clear(NIL) ;
return MA_DONE ;
}

/*===============================================================*/

void far second_level_interrupt(void)
{
/* note that in this routine, DS/ES/SS are unknown */
DVsound(1000,10) ;
}

int pascal interrupt_test(OBJECT window, int status, char *results, long arg)
{
WORD bit = DVgetbit(second_level_interrupt) ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window(NULL) ;
DVwin_swrite(NIL,"\r\n\r\nPress a key to test second level interrupts") ;
DVwin_redraw(NIL) ;
get_key() ;
DVwin_swrite(NIL,"\r\n\r\nBeeping....") ;
DVsetbit(bit) ;
DVsleep(100) ;
DVfreebit(bit) ;
DVwin_swrite(NIL,"Done!\r\n") ;
return MA_DONE ;
}

/*===============================================================*/

int pascal objectq_test(OBJECT window, int status, char *results, long arg)
{
OBJECT p = DVptr_new() ;
OBJECT obj ;
char buffer[100] ;
int i, count ;
POINTER_MSG msg ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("OBJECTQ Demo") ;
DVwin_swrite(NIL,"Waiting for input from either the keyboard or a mouse\r\n\r\n") ;
DVwin_hcur(NIL) ;
DVwin_redraw(NIL) ;
DVobq_open(NIL) ;
DVptr_open(p,NIL) ;
DVptr_setflags(p,PTR_NOTFORE|PTR_NOTTOP|PTR_RELEASE) ;
DVptr_erase(p) ;
DVkbd_clear(NIL) ;
DVkbd_setflags(NIL,KBD_ACTIVE) ;
DVobq_add(NIL,p) ;
DVobq_add(NIL,DVmykbd()) ;
DVobq_close(NIL) ; /* need to close it so that all objects can be used */
obj = DVobq_read(NIL) ;
if (obj == p)
{
DVptr_read(obj,&msg) ;
DVprintf(NIL,"Got row: %d col: %d buttons: %02.2x\n",msg.row,
msg.column,msg.button_state) ;
}
else
{
count = DVkbd_read(obj,buffer,sizeof(buffer)) ;
DVwin_swrite(NIL,"\r\nGot: ") ;
for (i = 0 ; i < count ; i++)
DVprintf(NIL,"%02x ",buffer[i]) ;
}
DVobq_remove(NIL,p) ; /* don't take input from mouse anymore */
DVptr_close(p) ; /* don't need the object, so free it */
DVptr_free(p) ;
DVsleep(100) ;
DVobq_close(NIL) ;
return MA_DONE ;
}

/*===============================================================*/

extern WORD _restore_DS(void) ;

void far kbd_filter(void)
{
WORD ax = _AX ; /* store the parameters which were passed in registers */
WORD bx = _BX ;
WORD cx = _CX ;
WORD dx = _DX ;
WORD ds = _DS ; /* and DS, which we will be clobbering */

_restore_DS() ; /* get back TurboC's data segment (not necessary in this */
/* trivial filter function, though) */
/* tell DESQview to ignore non-numeric characters in numeric fields */
if ((dx & F_NUMBER) != 0 && ax >= ' ' && ax <= 0xFF)
ax = (ax >= '0' && ax <= '9') ? 0 : 0x100 ;
else if (ax > 0xFF)
ax = 0 ; /* we want to use the extended-ASCII keystrokes */
_DX = dx ;
_CX = cx ;
_BX = bx ;
_DS = ds ;
_AX = ax ;
}

/*===============================================================*/

static char *field_status_names[] =
{ "Enter pressed",
"item selected",
"right button pressed",
"validation [cursor left modified field]",
"auto-Enter on field"
} ;

int pascal field_test(OBJECT window,int call_status,char *results,long arg)
{
char buffer[50] ;
char *status_name ;
BYTE *fields ;
int status, len ;

(void)window ; (void)call_status ; (void)results ; (void)arg ;
standard_window("Low-Level Fields") ;
DVprintf(NIL,"About to display a simple form using direct field\n") ;
DVprintf(NIL,"table manipulations. This method makes forms rather\n") ;
DVprintf(NIL,"difficult to change; for anything more than is shown\n") ;
DVprintf(NIL,"here, you should use UIform() instead.\n") ;
DVwin_redraw(NIL) ;
key_to_continue() ;
DVwin_clear(NIL) ;
DVwin_swrite(NIL,"Field-mode test\r\n"
"Cursor should be \031 there\r\n"
"Enter a number: Enter a string:\r\n"
"Forced uppercase string: With value: \r\n"
"Validated entry: \r\n"
"Press RETURN when done, or click here: ") ;
fields = DVfld_build_header(6,F_ALLOWKBD|F_READARRAY,0x70,0x0F) ;
DVfld_build_entry(fields,1,2,16,2,18,F_FILLIN,F_NEXT|F_NUMBER|F_CLEAR,1,0) ;
DVfld_build_entry(fields,2,2,35,2,50,F_FILLIN,F_NEXT|F_CLEAR,1,0) ;
DVfld_build_entry(fields,3,3,25,3,30,F_FILLIN,F_NEXT|F_UPPER|F_CLEAR,1,0) ;
DVfld_build_entry(fields,4,3,44,3,57,F_FILLIN,F_NEXT|F_CLEAR,1,0) ;
DVfld_build_entry(fields,5,4,17,4,25,F_FILLIN,F_NEXT|F_CLEAR|F_VALIDATE,1,0) ;
DVfld_build_entry(fields,6,5,39,5,42,F_MENU,'\r',0x70,0) ;
DVwin_stream(NIL,fields) ;
DVfld_swrite(NIL,4,"default") ;
DVfld_attr(NIL,4,0x70) ;
DVfld_cursor(NIL,1) ; /* position cursor in first field */
DVwin_redraw(NIL) ;
DVfld_altmode(NIL,TRUE) ;
DVkbd_setflags(NIL,KBD_FILTERALL) ;
DVkbd_setesc(NIL,kbd_filter) ;
len = DVkbd_read(NIL,buffer,sizeof(buffer)) ;
status = (int) DVkbd_status(NIL) ;
DVfld_altmode(NIL,FALSE) ;
free(fields) ; /* now we can finally free the stream */
switch (status)
{
case 27:
status_name = "Esc pressed" ;
break ;
case 70:
status_name = "Ctrl-Break pressed" ;
break ;
case 73:
status_name = "cancelled with PgUp" ;
break ;
default:
if (status < lengthof(field_status_names))
status_name = field_status_names[status] ;
else
status_name = "extended key pressed" ;
break ;
}
DVwin_gotoxy(NIL,0,7) ;
DVprintf(NIL,"Got '%.*s'\nStatus was %d (%s)\nPress a key....",
len,buffer,status,status_name) ;
get_key() ;
return MA_DONE ;
}

/*===============================================================*/
/*===============================================================*/

int pascal uifield_test(OBJECT window,int status,char *results,long arg)
{
(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("High-Level Fields") ;
DVprintf(NIL,"This test not yet available; UIform() not implemented.\n") ;
DVwin_redraw(NIL) ;
key_to_continue() ;
DVwin_clear(NIL) ;
return MA_DONE ;
}

/*===============================================================*/
/*===============================================================*/

int pascal open_window(OBJECT window, int status, char *results, long arg)
{
OBJECT w ;
int row, col, rows, cols ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("UIwin_open() test") ;
DVwin_swrite(NIL,"About to ask you to select a window's size and position" ) ;
DVwin_redraw(NIL) ;
DVsleep(100) ;
w = UIwin_open(NIL,3,18,25,70,6,25) ;
DVwin_clear(NIL) ;
DVwin_cursor(NIL,0,0) ;
if (w)
{
DVqry_position(w,&row,&col) ;
DVqry_size(w,&rows,&cols) ;
DVwin_cursor(w,0,0) ;
DVwin_top(w) ;
DVprintf(w,"Window %Fp\n%dx%d at (%d,%d)\nPress a key...",
w,rows,cols,row,col) ;
DVwin_redraw(w) ;
get_key() ;
DVwin_free(w) ;
}
else
{
DVwin_swrite(NIL,"Cancelled! ") ;
key_to_continue() ;
}
return MA_DONE ;
}

/*===============================================================*/
/*===============================================================*/

static void task_list_header(OBJECT window)
{
DVwin_clear(window) ;
DVwin_cursor(window,0,0) ;
DVprintf(window," Handle LogSize PhySize Posit'n Type Status ## Name\n") ;
}

static char *status_names[] =
{ "Waiting", "Idle", "(unknwn)", "Idle", "Pausing", "ModeChg", "ModeNtf",
"MoniChg", "StartPgm", "MgrCan", "Slicing", "Exit DOS", "EnterDOS",
"Terminat", "BrkNext", "MgrCol", "PgmInt", "BldOpen"
} ;

static void task_list_entry(OBJECT window,OBJECT curwin)
{
DVWININFO info ;
char title[30] ;
char *type ;
char *status ;

DVwin_info(curwin,&info) ;
if (info.tskflag == 0)
type = "Wndw" ;
else
type = (info.tskflag == 1) ? "Task" : "Unkn" ;
if (info.tskflag == 1 && info.tskstatus < lengthof(status_names))
status = status_names[info.tskstatus] ;
else
status = "" ;
if (info.procnumber == 1)
strcpy(title,"(DESQview System Task)") ;
else
DVqry_title(curwin,title,sizeof(title)) ;
DVprintf(window,"%Fp %3dx%-3d %3dx%-3d %3d,%-3d %4.4s %-8.8s %2d %-26.26s\n",
curwin,info.logcols,info.logrows,info.physcols,info.physrows,
info.poscol,info.posrow,type,status,info.procnumber,title
) ;
}

int pascal task_list(OBJECT window, int status, char *results, long arg)
{
OBJECT curwin ;
int count ;

(void)status ; (void)results ; (void)arg ;
DVwin_resize(NIL,STDWIN_HEIGHT,78) ;
DVwin_move(NIL,7,1) ;
DVwin_cursor(NIL,0,0) ;
DVwin_origin(NIL,0,0) ;
DVwin_clear(NIL) ;
DVwin_title(NIL,"Task/Window List") ;
task_list_header(NIL) ;
DVwin_redraw(NIL) ;
task_list_entry(NIL,window) ;
count = 1 ;
for (curwin = DVobjnext(window) ; curwin != window ; curwin = DVobjnext(curwin))
{
task_list_entry(NIL,curwin) ;
count++ ;
if (count > STDWIN_HEIGHT-3)
{
key_to_continue() ;
count = 0 ;
task_list_header(NIL) ;
}
}
DVprintf(NIL,"End of list. Press a key....") ;
get_key() ;
return MA_DONE ;
}

/*===============================================================*/
/*===============================================================*/

static void object_list_header(OBJECT window)
{
DVwin_clear(window) ;
DVwin_cursor(window,0,0) ;
DVprintf(window," Handle Type Owner\n") ;
}

static char* type_names[] = { "Invalid", "(error)", "(error)", "(error)",
"(error)", "(error)", "(error)", "(error)",
"Wndw/Task", "Mailbox", "Keyboard",
"Timer", "ObjectQ", "(error)", "(error)",
"Pointer", "Panel"
} ;

static void object_list_entry(OBJECT window,OBJECT obj)
{
unsigned int type = DVobjtype(obj) ;
OBJECT owner ;
char *typename ;
char title[30] ;

if (type < lengthof(type_names))
typename = type_names[type] ;
else
typename = "(error)" ;
owner = DVowner_of(obj) ;
if (owner)
DVqry_title(owner,title,sizeof(title)) ;
else
title[0] = '\0' ;
DVprintf(window,"%Fp %-10.10s %Fp (%s)\n",obj,typename,owner,title) ;
}

int pascal object_list(OBJECT window, int status, char *results, long arg)
{
OBJECT mykbd, curobj ;
int count ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("Other Object List") ;
object_list_header(NIL) ;
DVwin_redraw(NIL) ;
mykbd = DVkbd_of(NIL) ;
object_list_entry(NIL,mykbd) ;
count = 1 ;
for (curobj = DVobjnext(mykbd) ; curobj != mykbd ; curobj = DVobjnext(curobj))
{
object_list_entry(NIL,curobj) ;
count++ ;
if (count > STDWIN_HEIGHT-3)
{
key_to_continue() ;
count = 0 ;
object_list_header(NIL) ;
}
}
DVprintf(NIL,"End of list. Press a key....") ;
get_key() ;
return MA_DONE ;
}

/*===============================================================*/
/*===============================================================*/

int pascal XDI_test(OBJECT window, int status, char *results, long arg)
{
int version, last ;
long time, total ;

(void)window ; (void)status ; (void)results ; (void)arg ;
if (_dvversion < 0x021A)
{
DVerrormsg(0,"XDI functions require DV 2.26 or higher",1,0,0,0) ;
return MA_DONE ;
}
XDIinit() ;
standard_window("XDI Functions") ;
DVwin_redraw(NIL) ;
DVprintf(NIL,"XDI is using Multiplex number %02.2Xh\n",XDI_multiplex_number) ;
if ((version = DVeop_installed()) == 0)
DVprintf(NIL,"DVeop is not installed.\n") ;
else
DVprintf(NIL,"DVeop version %d.%02d is installed.\n",version/256,version%256) ;
DVprintf(NIL,"QDPMI is %sinstalled.\n",QDPMI_installed()?"":"not ") ;
DVprintf(NIL,"DVTXDI is %sinstalled.\n",DVTXDI_installed()?"":"not ") ;
if ((version = DVSI_installed()) == 0)
DVprintf(NIL,"DVSI XDI driver is not installed.\n") ;
else
{
DVprintf(NIL,"DVSI XDI driver version %d.%02d is installed.\n",
version/256,version%256) ;
if (version >= 0x010A) /* v1.10+ ? */
{
time = DVSI_runtime() ;
DVprintf(NIL,"Time since DESQview started: %ld.%02d seconds\n",
time/100,(int)time%100) ;
DVSI_taskswitches(&total,&last) ;
DVprintf(NIL,"Task switches: %ld total, %d in last interval\n",
total,last) ;
}
}


key_to_continue() ;
DVwin_clear(NIL) ;
XDIexit() ;
return MA_DONE ;
}

/*===============================================================*/

int pascal v220_test(OBJECT window,int status,char *results,long arg)
{
(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("DV 2.20+ Functions") ;
DVwin_redraw(NIL) ;
DVprintf(NIL,"There are %d nested critical sections in effect.\n",DVgetcrit()) ;
DVprintf(NIL,"The current error state is %d.\n",DVgeterror()) ;
DVprintf(NIL,"The current mapping context is %04.4X.\n",DVassertmap(0)) ;
DVprintf(NIL,"The keyboard's priority is %d\n",DVkbd_getpri(NIL)) ;
DVprintf(NIL,"The mailbox's priority is %d\n",DVmbx_getpri(NIL)) ;
DVprintf(NIL,"The keyboard's flags are %08.8X\n",DVkbd_getflags(NIL)) ;
DVprintf(NIL,"The mailbox's flags are %08.8X\n",DVmbx_getflags(NIL)) ;
key_to_continue() ;
DVwin_clear(NIL) ;
return MA_DONE ;
}

/*===============================================================*/

int pascal v223_test(OBJECT window,int status,char *results,long arg)
{
int rows, cols, mode ;
OBJECT user ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("DV 2.23+ Functions") ;
DVwin_redraw(NIL) ;
DVprintf(NIL,"Physical screen information:\n") ;
mode = DVscrninfo(&rows,&cols) ;
DVprintf(NIL," %d rows by %d columns in mode %02X.\n",rows,cols,mode) ;
user = DVDOSuser() ;
if (user)
DVprintf(NIL,"DOS user = %Fp.\n",user) ;
else
DVprintf(NIL,"No one is using DOS.\n") ;
key_to_continue() ;
DVwin_clear(NIL) ;
return MA_DONE ;
}

/*===============================================================*/

int pascal v226_test(OBJECT window,int status,char *results,long arg)
{
unsigned total, sysmem, maxblock ;
int flags ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("DV 2.26+ Functions") ;
DVwin_redraw(NIL) ;
flags = DVprocessmem(NIL,&total,&sysmem,&maxblock) ;
DVprintf(NIL,"Process memory: Flags = %04.4X\n",flags) ;
DVprintf(NIL," Total = %lu, System = %lu, MaxBlock = %lu\n",(long)total<<4,
(long)sysmem<<4,(long)maxblock<<4) ;
if (flags & PM_SYSMEM_SWAPPED)
DVprintf(NIL,"System memory is swapped out (ignore above values).\n") ;
if (flags & PM_SYSMEM_SHARED)
DVprintf(NIL,"System memory is shared.\n") ;
if (flags & PM_PROCMEM_SWAPPED)
DVprintf(NIL,"Process memory is swapped out.\n") ;
key_to_continue() ;
DVwin_clear(NIL) ;
return MA_DONE ;
}

/*===============================================================*/

int pascal v240_test(OBJECT window,int status,char *results,long arg)
{
char path[70] ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("DV 2.40+ Functions") ;
DVwin_redraw(NIL) ;
memset(path,0,sizeof(path)) ;
DVgetDVpath(path) ;
DVprintf(NIL,"Path from which DV was started:\n %s\n",path) ;
DVprintf(NIL,"Process %04.4X:0000 has the keyboard focus\n",DVgetforeground()) ;
key_to_continue() ;
DVwin_clear(NIL) ;
return MA_DONE ;
}

/*===============================================================*/

int pascal v250_test(OBJECT window,int status,char *results,long arg)
{
unsigned char name[60] ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("DV 2.50+ Functions") ;
DVwin_redraw(NIL) ;
DVwin_getname(NIL,name,sizeof(name)) ;
DVprintf(NIL,"The current window's name is\n %s\n",name) ;
DVprintf(NIL,"These functions have not been fully implemented yet.\n") ;
key_to_continue() ;
DVwin_clear(NIL) ;
return MA_DONE ;
}

/*===============================================================*/

int pascal DVX100_test(OBJECT window,int status,char *results,long arg)
{
char name[128] ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("DV/X 1.00+ Functions") ;
DVwin_redraw(NIL) ;
if (DVXqry_displayname(NIL,name,sizeof name))
DVprintf(NIL,"The display name is %s\n",name) ;
else
DVprintf(NIL,"Unable to get X display name.\n") ;
key_to_continue() ;
DVwin_clear(NIL) ;
return MA_DONE ;
}

/*===============================================================*/

void gray_out_newfuncs(DVMENU *menu)
{
DVMENU_ITEM *item ;

for (item = menu->items ; item->type != M_END ; item++)
{
if (item->type == M_FUNC && item->arg > 0 && _dvversion < item->arg)
item->type = M_TEXT ;
}
return ;
}

/*===============================================================*/

int pascal QEMM_test(OBJECT window,int status,char *results,long arg)
{
int qemm_ver, hiram, state, i, j ;
unsigned int totmem, availmem ;
DEBUGREGS debug_regs ;
char mapbuf[256] ;
QEMM_USAGE usage ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("QEMM Interface") ;
DVwin_redraw(NIL) ;
qemm_ver = QEMMinit() ;
if (!qemm_ver)
DVprintf(NIL,"QEMM-386 is not installed on this system.") ;
else
{
DVprintf(NIL,"QEMM-386 version %d.%02d\n",qemm_ver/256,qemm_ver%256) ;
state = QEMMget_state() ;
if (state == -1)
DVprintf(NIL,"[Error getting QEMM state]\n") ;
else
DVprintf(NIL,"Current state: %s%s\n",(state&QEMM_AUTO)?"AUTO ":"",
(state&QEMM_OFF)?"OFF":"ON") ;
if (QEMMmem_avail(&totmem,&availmem))
DVprintf(NIL,"There are a total of %u 4K pages, of which %u are free\n",
totmem,availmem) ;
else
DVprintf(NIL,"[Error getting 4K page counts]\n") ;
hiram = QEMMhiram() ;
if (hiram)
DVprintf(NIL,"The high memory chain starts at segment %04.4X\n",hiram) ;
else
DVprintf(NIL,"There is no high memory chain.\n") ;
DVprintf(NIL,"The maximum physical memory address is %08.8lX\n",QEMMmax_physmem()) ;
DVprintf(NIL,"The CPU's CR0 register is %08.8lX\n",QEMMget_CR0()) ;
QEMMget_debug(&debug_regs) ;
DVprintf(NIL,"The CPU's debugging registers are:\n"
" DR0: %08.8lX DR1: %08.8lX DR2: %08.8lX\n"
" DR3: %08.8lX DR6: %08.8lX DR7: %08.8lX\n",
debug_regs.DR0,debug_regs.DR1,debug_regs.DR2,
debug_regs.DR3,debug_regs.DR6,debug_regs.DR7) ;
key_to_continue() ;
DVwin_resize(NIL,19,42) ;
DVwin_move(NIL,4,5) ;
DVwin_clear(NIL) ;
DVwin_redraw(NIL) ;
DVprintf(NIL,"QEMM memory type map Accessed memory map\n") ;
DVprintf(NIL,"-------------------- -------------------\n") ;
if (QEMMmemory_type(mapbuf) != -1)
for (i = 0 ; i < 16 ; i++)
{
for (j = 0 ; j < 16 ; j++)
{
if ((j%8) == 0)
DVputchar(NIL,' ',7) ;
DVputchar(NIL,".?MHXVRA/FrC"[mapbuf[16*i+j] & 15],7) ;
}
DVwin_swrite(NIL,"\r\n") ;
}
else
DVprintf(NIL,"Error retrieving\ninformation\n") ;
if (QEMMget_accessed(mapbuf))
for (i = 0 ; i < 16 ; i++)
{
for (j = 0 ; j < 16 ; j++)
{
if ((j%8) == 0)
DVwin_cursor(NIL,i+2,j?32:23) ;
DVputchar(NIL,".RwW"[mapbuf[16*i+j] & 3],7) ;
}
DVwin_swrite(NIL,"\r\n") ;
}
else
{
DVprintf(NIL,"Error retrieving") ;
DVwin_cursor(NIL,3,23) ;
DVprintf(NIL,"information") ;
}
DVwin_cursor(NIL,18,0) ;
key_to_continue() ;
standard_window(NULL) ;
DVprintf(NIL,"QEMM Memory Usage\n"
"-----------------\n") ;
DVwin_redraw(NIL) ;
QEMMget_memusage(&usage) ;
DVprintf(NIL,"QEMM is using %lu bytes for its code and\n"
" %lu bytes for its data segment.\n",usage.QEMMcode,
usage.QEMMdata) ;
}
key_to_continue() ;
return MA_DONE ;
}

/*===============================================================*/

int pascal VIDRAM_test(OBJECT window,int status,char *results,long arg)
{
int state, BL, flags, monitor ;
unsigned memtop, hiram ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("VIDRAM") ;
DVwin_redraw(NIL) ;
if (!VIDRAM_installed())
DVprintf(NIL,"VIDRAM is not installed.\n") ;
else
{
state = VIDRAM_status(&BL,&flags,&monitor,&memtop,&hiram) ;
DVprintf(NIL,"VIDRAM is installed, and is %s.\n",
(state==0)?"turned off":
((state==1)?"disabling EGA graphics":
"disabling all graphics")) ;
DVprintf(NIL,"The current monitor is %s.\n",(monitor==1)?"mono":"color");
DVprintf(NIL,"Top of memory is set at %04.4X\n",memtop) ;
if (hiram)
DVprintf(NIL,"HighRAM starts at %04.4X\n",hiram) ;
else
DVprintf(NIL,"There is no high memory available.\n") ;
}
key_to_continue() ;
return MA_DONE ;
}

/*===============================================================*/

int pascal QOS_other_test(OBJECT window,int status,char *results,long arg)
{
WORD hiram ;

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("Other QOS Programs") ;
DVwin_redraw(NIL) ;
hiram = QOShiram() ;
if (hiram)
DVprintf(NIL,"Quarterdeck HiRAM chain starts at segment %04.4X\n",hiram) ;
else
DVprintf(NIL,"No Quarterdeck HiRAM\n") ;
DVprintf(NIL,"Manifest is %sinstalled resident.\n",
MANIFEST_installed()?"":"not ") ;

key_to_continue() ;
return MA_DONE ;
}

/*===============================================================*/

static void pascal error_test_end(void); /* forward declaration */

int pascal error_test(OBJECT window,int status,char *results,long arg)
{

(void)window ; (void)status ; (void)results ; (void)arg ;
standard_window("Error Handling") ;
DVwin_redraw(NIL) ;
DVprintf(NIL,"This menu selection will show various error reporting\n") ;
DVprintf(NIL,"features of DVGLUE. First, press a key to show an\n") ;
DVprintf(NIL,"error message requested by the program....\n") ;
get_key() ;
DVerrormsg(0,"TEST ERROR MESSAGE - press ESC",1,0,0,0);
DVprintf(NIL,"\nAbout to check DVGLUE's detection of invalid handles.\n") ;
key_to_continue() ;
DVkbd_of((OBJECT)1) ;
DVprintf(NIL,"\nYou should have received an error popup similar to the\n") ;
DVprintf(NIL,"first test error message. The offset of the error address\n") ;
DVprintf(NIL,"should have been between %04.4X and %04.4X\n",(WORD)error_test,
(WORD)error_test_end) ;
key_to_continue() ;
DVwin_clear(NIL) ;
return MA_DONE ;
}

static void pascal error_test_end(void) {}

/*===============================================================*/

int pascal do_all(OBJECT window,int status,char *results,long arg)
{
(void)window ; (void)status ; (void)results ; (void)arg ;
stream_test(NIL,0,NULL,0) ;
field_test(NIL,0,NULL,0) ;
uifield_test(NIL,0,NULL,0) ;
objectq_test(NIL,0,NULL,0) ;
panel_test(NIL,0,NULL,0) ;
pointer_test(NIL,0,NULL,0);
mouse_drawing_program(NIL,0,NULL,0) ;
timer_test(NIL,0,NULL,0) ;
multiwindow_test(NIL,0,NULL,0) ;
notify_test(NIL,0,NULL,0) ;
fork_test(NIL,0,NULL,0) ;
app_test(NIL,0,NULL,0) ;
interrupt_test(NIL,0,NULL,0) ;
open_window(NIL,0,NULL,0) ;
DVsound(200,5) ;
DVsound(350,5) ;
DVsound(600,5) ;
DVsound(800,5) ;
task_list(NIL,0,NULL,0) ;
object_list(NIL,0,NULL,0) ;
XDI_test(NIL,0,NULL,0) ;
if (_dvversion >= 0x0214) /* v2.20+ ? */
{
v220_test(NIL,0,NULL,0) ;
if (_dvversion >= 0x217) /* v2.23+ ? */
{
v223_test(NIL,0,NULL,0) ;
if (_dvversion >= 0x021A) /* v2.26+ ? */
{
v226_test(NIL,0,NULL,0) ;
if (_dvversion >= 0x0228) /* v2.40+ ? */
{
v240_test(NIL,0,NULL,0) ;
if (_dvversion >= 0x0232) /* v2.50+ ? */
{
v250_test(NIL,0,NULL,0);
if (DVXver() >= 0x0100) /* DV/X 1.00+ ? */
DVX100_test(NIL,0,NULL,0) ;
}
}
}
}
}
QEMM_test(NIL,0,NULL,0) ;
VIDRAM_test(NIL,0,NULL,0) ;
QOS_other_test(NIL,0,NULL,0) ;
error_test(NIL,0,NULL,0) ;
return MA_DONE ;
}

/*===============================================================*/

int menu_test(OBJECT window,int status,char *results)
{
(void) window ;
(void) results ;
if (status == 2 || status == 27) /* right mouse button or ESC */
return MA_REDO | MA_RESET ;
else
return MA_DONE ;
}

/*===============================================================*/

int menu_cancel(OBJECT window,int status,char *results)
{
(void) window ;
(void) results ;
if (status == 2 || status == 27) /* right mouse button or ESC */
return MA_REDO | MA_RESET ;
else
return MA_DONE ;
}

/*===============================================================*/

int pascal sound_test(OBJECT window, int status, char *results, long freq)
{
(void)window ; (void)status ; (void)results ;
DVsound((int)freq,4) ;
return MA_DONE ;
}

/*===============================================================*/

int sound_cancel(OBJECT window,int status,char *results)
{
int i ;

(void)window ; (void)status ; (void)results ;
for (i = 0 ; i < 30 ; i++)
DVsound(300+100*i,3) ;
DVnosound() ; /* test cancellation of enqueued notes */
return MA_DONE ;
}

/*===============================================================*/

int menu_error(DVMENU *menu,OBJECT window,int errcode)
{
(void) menu ; (void) window ;
if (errcode == ME_TOOBIG)
{
DVprintf(NIL, "Menu too big!\n" ) ;
if (menu->allow_oversize)
return MA_ABORT ;
else
{
menu->allow_oversize = TRUE ; /* try again, letting menu go over screen */
return MA_REDO ;
}
}
else if (errcode == ME_NOMEM)
DVprintf(NIL, "Not enough memory for menu!\n" ) ;
else if (errcode == ME_RESOURCE)
DVprintf(NIL, "Out of resources!\n") ;
else if (errcode == ME_BADITEM)
DVprintf(NIL, "Error in menu item! You probably forgot the M_END\n" ) ;
return MA_ABORT ;
}

/*===============================================================*/

DVMENU_ITEM field_menu_items[] = {
{ "Low-level functions", M_FUNC, 'L',0, FALSE, field_test },
{ "High-level functions", M_FUNC|M_EXIT, 'H',0, FALSE, uifield_test },
{ 0, M_END, 0,0, FALSE }
} ;

DVMENU field_menu = { "Fields", field_menu_items,
7, -25,
0, 0, 0, menu_error,
TRUE, FALSE, FALSE, TRUE,
' ', 0, 0 } ;

DVMENU_ITEM pointer_menu_items[] = {
{ "Pointer movement", M_FUNC|M_EXIT, 'P', 0, FALSE, pointer_test },
{ "Drawing program", M_FUNC|M_EXIT, 'D', 0, FALSE, mouse_drawing_program },
{ 0, M_END, 0, 0, FALSE }
} ;

DVMENU pointer_menu = { " Pointer Menu ", pointer_menu_items,
10, -22,
0, 0, 0, menu_error,
TRUE, FALSE, FALSE, TRUE,
' ', 0, 0 } ;

DVMENU_ITEM mtask_menu_items[] = {
{ "multiple Threads", M_FUNC|M_EXIT, 'T', 0, FALSE, fork_test },
{ "Applications", M_FUNC|M_EXIT, 'A', 0, FALSE, app_test },
{ 0, M_END, 0, 0, FALSE }
} ;

DVMENU mtask_menu = { " Multitasking ", mtask_menu_items,
14, -22,
0, 0, 0, menu_error,
TRUE, FALSE, FALSE, TRUE,
' ', 0, 0 } ;

DVMENU_ITEM sound_menu_items[] = {
{ "200 Hz tone", M_FUNCMENU|M_EXIT, '2', 0, FALSE, sound_test, 200 },
{ "350 Hz tone", M_FUNCMENU|M_EXIT, '3', '5', FALSE, sound_test, 350 },
{ "600 Hz tone", M_FUNCMENU|M_EXIT, '6', 0, FALSE, sound_test, 600 },
{ "800 Hz tone", M_FUNCMENU|M_EXIT, '8', '0', FALSE, sound_test, 800 },
{ 0, M_END, 0, 0, FALSE }
} ;

DVMENU sound_menu = { " Sound Menu ", sound_menu_items,
17, -18,
0, 0, sound_cancel, menu_error,
TRUE, FALSE, FALSE, TRUE,
' ', 0, 0 } ;

DVMENU_ITEM newfunc_menu_items[] = {
{ "v2.20", M_FUNC, 'A',0, FALSE, v220_test, 0x0214 },
{ "v2.23", M_FUNC, 'B',0, FALSE, v223_test, 0x0217 },
{ "v2.26", M_FUNC, 'C',0, FALSE, v226_test, 0x021A },
{ "v2.40", M_FUNC, 'D',0, FALSE, v240_test, 0x0228 },
{ "v2.50", M_FUNC, 'E',0, FALSE, v250_test, 0x0232 },
{ "DV/X 1.0", M_FUNC, 'F',0, FALSE, DVX100_test, 0x0232 },
{ 0, M_END, 0, 0, FALSE }
} ;

DVMENU newfunc_menu = { " Newer Functions ", newfunc_menu_items,
3, -15,
gray_out_newfuncs, 0, 0, menu_error,
TRUE, FALSE, FALSE, TRUE,
' ', 0, 0 } ;

DVMENU_ITEM QOS_menu_items[] = {
{ "QEMM-386", M_FUNC, 'Q', 0, FALSE, QEMM_test },
{ "VIDRAM", M_FUNC, 'V', 0, FALSE, VIDRAM_test },
{ "Other programs",M_FUNC, 'O', 0, FALSE, QOS_other_test },
{ 0, M_END, 0, 0, FALSE }
} ;

DVMENU QOS_menu = { " QOS Programs ", QOS_menu_items,
7, -20,
0, 0, 0, menu_error,
TRUE, FALSE, FALSE, TRUE,
' ', 0, 0 } ;

DVMENU_ITEM more_menu_items[] = {
{ "Newer functions", M_SUBMENU, 'N', 0, FALSE, 0, (long)&newfunc_menu },
{ "Task/window list",M_FUNC, 'T', 0, FALSE, task_list },
{ "Other objects", M_FUNC, 'O', 0, FALSE, object_list },
{ "XDI functions", M_FUNC, 'X', 0, FALSE, XDI_test },
{ "QOS programs", M_SUBMENU, 'Q', 0, FALSE, 0, (long)&QOS_menu },
{ "Error handling", M_FUNC, 'E', 0, FALSE, error_test },
{ 0, M_SEP, 205, 0, FALSE },
{ "Cancel Esc", M_QUIT|M_KEY, 27, 0, FALSE },
{ 0, M_END, 0, 0, FALSE }
} ;

DVMENU more_menu = { " More DV-GLUE ", more_menu_items,
0, -1,
0, 0, 0, menu_error,
TRUE, FALSE, FALSE, TRUE,
' ', 0, 0 } ;

DVMENU_ITEM main_menu_items[] = {
{ "Do everything \021ÄÙ",M_FUNC|M_KEY, '\r',0, FALSE, do_all },
{ 0, M_SEP, 205, 0, FALSE },
{ "Single Tests", M_CENTER|M_HI, 0, 0, FALSE },
{ "Streams", M_FUNC, 'S', 0, FALSE, stream_test },
{ "Fields", M_SUBMENU, 'F', 0, FALSE, 0, (long)&field_menu },
{ "objectQ", M_FUNC, 'Q', 0, FALSE, objectq_test },
{ "pAnels", M_FUNC, 'A', 0, FALSE, panel_test },
{ "Pointers...", M_SUBMENU, 'P', 0, FALSE, 0, (long)&pointer_menu },
{ "Timers", M_FUNC, 'T', 0, FALSE, timer_test },
{ "Windows", M_FUNC, 'W', 0, FALSE, multiwindow_test },
{ "Notification", M_FUNC, 'N', 0, FALSE, notify_test },
{ "Multitasking", M_SUBMENU, 'M', 0, FALSE, 0, (long)&mtask_menu },
{ "Interrupts", M_FUNC, 'I', 0, FALSE, interrupt_test },
{ "Open window", M_FUNC, 'O', 0, FALSE, open_window },
{ "soUnd...", M_SUBMENU, 'U', 0, FALSE, 0, (long)&sound_menu },
{ "more... PgDn", M_SUBMENUR|M_KEY,0,81,FALSE, 0, (long)&more_menu },
{ 0, M_SEP, 205, 0, FALSE },
{ "eXit", M_QUIT, 'X', 0, FALSE },
{ 0, M_FUNCMENU|M_HOT,0,59, FALSE, help }, /* F1 */
{ 0, M_END, 0, 0, FALSE }
} ;

DVMENU main_menu = { " DV-GLUE Demo ", main_menu_items,
0, -1,
save_state, restore_state, menu_cancel, menu_error,
TRUE, FALSE, TRUE, TRUE,
' ', 0, 0 } ;

/*===============================================================*/

void main()
{
/* initialize everything, aborting if wrong DESQview version */

DVinit(0x0200) ; /* although we call functions requiring > 2.00, all such */
/* calls are carefully version-checked */
do {
} while (UImenu(&main_menu) == 2) ; /* until exited with 'X' instead */
/* of Esc/PgUp/But2 */
DVwin_clear(NIL) ;
/* quit DESQview API */
DVexit() ;
}

/* End of DEMO.C */


  3 Responses to “Category : Alternate Operating Systems - Quarterdeck DesqView, CP/M, etc
Archive   : DVGLUE17.ZIP
Filename : DEMO.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/