1. SVN1260 WIN98 broken !

I just built SVN1260
The following binaries display a cursor in the correct place
for the prompt for file name but no text is visible on display.
backendc.exe
backendw.exe
ecw.exe
exw.exe
exwc.exe
The other binaries work ok.

The 1260 win98 binaries DO display on XP.

I went back and built SVN1212 and built win98 binaries with
the same setup and batch file that I am using and everything
works so it is not my setup.

new topic     » topic index » view message » categorize

2. Re: SVN1260 WIN98 broken !

bernie said...

I just built SVN1260
The following binaries display a cursor in the correct place
for the prompt for file name but no text is visible on display.
backendc.exe
backendw.exe
ecw.exe
exw.exe
exwc.exe
The other binaries work ok.

The 1260 win98 binaries DO display on XP.

I went back and built SVN1212 and built win98 binaries with
the same setup and batch file that I am using and everything
works so it is not my setup.

In other words, all the binaries built are broken...

Do the 1260 binaries work on 98 if you first do a:

set EUCONS=1

and then run the binary?

new topic     » goto parent     » topic index » view message » categorize

3. Re: SVN1260 WIN98 broken !

jimcbrown said...
bernie said...

I just built SVN1260
The following binaries display a cursor in the correct place
for the prompt for file name but no text is visible on display.
backendc.exe
backendw.exe
ecw.exe
exw.exe
exwc.exe
The other binaries work ok.

The 1260 win98 binaries DO display on XP.

I went back and built SVN1212 and built win98 binaries with
the same setup and batch file that I am using and everything
works so it is not my setup.

In other words, all the binaries built are broken...

Do the 1260 binaries work on 98 if you first do a:

set EUCONS=1

and then run the binary?

Yes 'set EUCONS=1' allows them to display.
What is the purpose of that ?
What ever EUCONS does should be done whenever the Win98 binaries
are compiled.
You are only adding one more confusion to new users.
Also when is something going to be added to the rev message to indicate
win98 binaries.

new topic     » goto parent     » topic index » view message » categorize

4. Re: SVN1260 WIN98 broken !

bernie said...

Yes 'set EUCONS=1' allows them to display.
What is the purpose of that ?

I was suprised to discover that some of the W32API Console API functions (such as WriteConsoleOutput) did not work on Windows 98. As in, they outputted blanks instead of text.

I was never able to discover the cause, and the only other W98 tester (ne1uno) stated that those functions worked fine for him.

So I quickly wrote some code to workaround the broken APIs (since I needed the output to work correctly to be able to test other issues on W98 at the time) and added it under the EUCONS option in case anyone else ever experienced the same issue as I did. You are the first besides myself to need it.

bernie said...

What ever EUCONS does should be done whenever the Win98 binaries
are compiled.

EUCONS is a run time setting. All binaries built for any version of windows support it.

We don't have a W98 binary option. The setting you are thinking about is probably MANAGED_MEM - which is purely a memory setting and has nothing to do with EUCONS.

bernie said...

You are only adding one more confusion to new users.
Also when is something going to be added to the rev message to indicate
win98 binaries.

Adding a banner to show the compile time options (such as MANAGED_MEM) is a good idea. Most C-based FOSS projects have them.

new topic     » goto parent     » topic index » view message » categorize

5. Re: SVN1260 WIN98 STILL BROKEN !

The set cons=1 only displays the prompt to enter a program name.
When you run a program all that displays is the console rectangle.
What was the last version before you made changes to be_w.c that worked.

new topic     » goto parent     » topic index » view message » categorize

6. Re: SVN1260 WIN98 STILL BROKEN !

bernie said...

The set cons=1 only displays the prompt to enter a program name.
When you run a program all that displays is the console rectangle.
What was the last version before you made changes to be_w.c that worked.

The EUCONS code has been in for a while, and is present in 1212. I haven't touched this code at all recently nor do I know of any changes that would have broke it.

new topic     » goto parent     » topic index » view message » categorize

7. Re: SVN1260 WIN98 STILL BROKEN !

jimcbrown said...
bernie said...

The set cons=1 only displays the prompt to enter a program name.
When you run a program all that displays is the console rectangle.
What was the last version before you made changes to be_w.c that worked.

The EUCONS code has been in for a while, and is present in 1212. I haven't touched this code at all recently nor do I know of any changes that would have broke it.

Hmm. I just tested 1260, and with EUCONS set both ed.ex and buzz.ex work with exwc and exw. Puzzling.

Without EUCONS, all I get are blanks.

new topic     » goto parent     » topic index » view message » categorize

8. Re: SVN1260 WIN98 STILL BROKEN !

jimcbrown said...
jimcbrown said...
bernie said...

The set cons=1 only displays the prompt to enter a program name.
When you run a program all that displays is the console rectangle.
What was the last version before you made changes to be_w.c that worked.

The EUCONS code has been in for a while, and is present in 1212. I haven't touched this code at all recently nor do I know of any changes that would have broke it.

Hmm. I just tested 1260, and with EUCONS set both ed.ex and buzz.ex work with exwc and exw. Puzzling.

Without EUCONS, all I get are blanks.

After further investigation and testing I found the following.

SVN 1250 was the last win98 version that worked.

SVN 1256 built the xp/vista binaries ok; but building win98 binaries
caused the following error: (derek's name was on be_w.c)

be_w.c(428): Error! E1011: Symbol 'default_heap' has not been declared

I then tried to update to 1258 the update just changed be_w.c & be_machine.c but not the SVN version number. (Matt's name was on be_w.c )
I built the win98 binaries with no error:
When I ran win98 binaries the prompt message for file is a blank display
with just a cursor. Running a program I just get a blank console rectangle.

I also built SVN1261 but it has the same problem.


To sum up the problem:

SVN 1250 was the last version of win98 binaries that worked.
SVN 1256 is when all the problems started and none of the versions
of Win98 binaries after that worked.
The Win98 binaries DO NOT have the blank display problem
If you run them on XP\WIN2000 (don't know about VISTA)

new topic     » goto parent     » topic index » view message » categorize

9. Re: SVN1260 WIN98 STILL BROKEN !

bernie said...

To sum up the problem:

SVN 1250 was the last version of win98 binaries that worked.
SVN 1256 is when all the problems started and none of the versions
of Win98 binaries after that worked.
The Win98 binaries DO NOT have the blank display problem
If you run them on XP\WIN2000 (don't know about VISTA)

This is all related to the changes to how we deal with console output. Basically, it used to only work for 80 character width consoles. We made it better at detecting wider consoles, and to dynamically increase the buffer size as needed. It seems that when we dynamically allocate the buffer, something breaks in win98. The other issues, related to unwanted console windows is probably an issue of how we're initializing the data structures.

I believe that Derek is working on the initialization issue. I don't know how to fix the 9X issue. It doesn't make sense why a statically initialized buffer works, but a dynamically allocated structure doesn't. We probably need to research the windows API to see if there were any changes.

Matt

new topic     » goto parent     » topic index » view message » categorize

10. Re: SVN1260 WIN98 STILL BROKEN !

[/quote]

bernie said...

After further investigation and testing I found the following.

SVN 1250 was the last win98 version that worked.

You've lost me there. No changes in the console code occurred between 1250 and 1251 - I have no idea why the bug fixes for the builtin sequence ops would have make the console break.

bernie said...

SVN 1256 built the xp/vista binaries ok; but building win98 binaries
caused the following error: (derek's name was on be_w.c)

be_w.c(428): Error! E1011: Symbol 'default_heap' has not been declared

This issue was related to the use of MANAGED_MEM, not the console code. Argubly a legitimate w98 bug, but as you noted already fixed.

The code changed here IS part of the console code.

bernie said...

I then tried to update to 1258 the update just changed be_w.c & be_machine.c but not the SVN version number. (Matt's name was on be_w.c )
I built the win98 binaries with no error:
When I ran win98 binaries the prompt message for file is a blank display
with just a cursor. Running a program I just get a blank console rectangle.

I also built SVN1261 but it has the same problem.

We have a few more changes to the console code here, mostly bug fixes to 1256.

bernie said...


To sum up the problem:

SVN 1250 was the last version of win98 binaries that worked.
SVN 1256 is when all the problems started and none of the versions
of Win98 binaries after that worked.
The Win98 binaries DO NOT have the blank display problem
If you run them on XP\WIN2000 (don't know about VISTA)

I'm confused when you say that 1250 is the last version that worked, but that 1256 is when the problem started. What happens with 1251, 1252, 1253, 1254, and 1255?

Note that 1251 predates any recent changes to the console code, so if the issue started in there then the fixes that went in at 1256 can not be the cause.

Also, you are stating that even with EUCONS set, the latest revision does not show any output from buzz.ex with exwc or exw? The file prompt works ok but the actual application is still blank?

new topic     » goto parent     » topic index » view message » categorize

11. Re: SVN1260 WIN98 STILL BROKEN !

mattlewis said...
bernie said...

To sum up the problem:

SVN 1250 was the last version of win98 binaries that worked.
SVN 1256 is when all the problems started and none of the versions
of Win98 binaries after that worked.
The Win98 binaries DO NOT have the blank display problem
If you run them on XP\WIN2000 (don't know about VISTA)

This is all related to the changes to how we deal with console output. Basically, it used to only work for 80 character width consoles. We made it better at detecting wider consoles, and to dynamically increase the buffer size as needed. It seems that when we dynamically allocate the buffer, something breaks in win98. The other issues, related to unwanted console windows is probably an issue of how we're initializing the data structures.

I believe that Derek is working on the initialization issue. I don't know how to fix the 9X issue. It doesn't make sense why a statically initialized buffer works, but a dynamically allocated structure doesn't. We probably need to research the windows API to see if there were any changes.

Matt

I wonder if they are related. Looking at expand_tabs() of be_w.c (which is called whenever anything is output to the screen) it looks like if col_max is not initialized properly (if it was set to zero) then nothing would be output.

OTOH, ne1uno reported that printing to stderror works, which would contradict this.

new topic     » goto parent     » topic index » view message » categorize

12. Re: SVN1260 WIN98 STILL BROKEN !

[quote jimcbrown]

said...

I'm confused when you say that 1250 is the last version that worked, but that 1256 is when the problem started. What happens with 1251, 1252, 1253, 1254, and 1255?

Jim:
I didn't have time to try everything before.

SVN 1251 1252 1253 all worked

Could not even build ANY BINARIES SVN 1254 due to these errors:

be_w.c(366): Error! E1009: Expecting ';' but found 'src'
be_w.c(366): Error! E1063: Missing operand
be_w.c(450): Error! E1011: Symbol 'default_heap' has not been declared

SVN 1255 default_heap error.

be_w.c(450): Error! E1011: Symbol 'default_heap' has not been declared

SVN 1253 was last working WIN98 binaries.

new topic     » goto parent     » topic index » view message » categorize

13. Re: SVN1260 WIN98 STILL BROKEN !

jimcbrown said...
mattlewis said...
bernie said...

To sum up the problem:

This is all related to the changes to how we deal with console output.

OTOH, ne1uno reported that printing to stderror works,

neither stderr nor stdout work on win98 w/o EUCONS since the late 1250's. I was running a program that was connected to a dll which was outputting on stderr is where my confusion came from. I've since made a test program that writes to stderr & stdout directly (print 1 or 2) and it's blanks. false alarm.

new topic     » goto parent     » topic index » view message » categorize

14. Re: SVN1260 WIN98 STILL BROKEN !

ne1uno said...

neither stderr nor stdout work on win98 w/o EUCONS since the late 1250's. I was running a program that was connected to a dll which was outputting on stderr is where my confusion came from. I've since made a test program that writes to stderr & stdout directly (print 1 or 2) and it's blanks. false alarm.

Ok, in that case its possible col_max is being set incorrectly on 98 (due to API bugs?) which is causing the blanks to show up.

new topic     » goto parent     » topic index » view message » categorize

15. Re: SVN1260 WIN98 STILL BROKEN !

jimcbrown said...
ne1uno said...

neither stderr nor stdout work on win98 w/o EUCONS since the late 1250's. I was running a program that was connected to a dll which was outputting on stderr is where my confusion came from. I've since made a test program that writes to stderr & stdout directly (print 1 or 2) and it's blanks. false alarm.

Ok, in that case its possible col_max is being set incorrectly on 98 (due to API bugs?) which is causing the blanks to show up.

But not confirmed.

new topic     » goto parent     » topic index » view message » categorize

16. Re: SVN1260 WIN98 STILL BROKEN !

bernie said...

SVN 1253 was last working WIN98 binaries.

Ok, the difference between 1253 and 1254 is the new width/height code AND the new dynamic buffer (as opposed to the old static one).

new topic     » goto parent     » topic index » view message » categorize

17. Re: SVN1260 WIN98 STILL BROKEN !

jimcbrown said...

Ok, in that case its possible col_max is being set incorrectly on 98 (due to API bugs?) which is causing the blanks to show up.

Jim:
According to MSDN WriteConsoleOutput :
If the rectangle specified by lpWriteRegion lies completely outside the
boundaries of the screen buffer, or if the corresponding rectangle is
positioned completely outside the boundaries of the source buffer, no data is
written.
So maybe the offset is outside the boundaries on Win98.

new topic     » goto parent     » topic index » view message » categorize

18. Re: SVN1260 WIN98 STILL BROKEN !

jimcbrown said...
jimcbrown said...
ne1uno said...

neither stderr nor stdout work on win98 w/o EUCONS since the late 1250's. I was running a program that was connected to a dll which was outputting on stderr is where my confusion came from. I've since made a test program that writes to stderr & stdout directly (print 1 or 2) and it's blanks. false alarm.

Ok, in that case its possible col_max is being set incorrectly on 98 (due to API bugs?) which is causing the blanks to show up.

But not confirmed.

Ok, my tests show that dwMaximumWindowSize is being set to 80x24, which is correct.

new topic     » goto parent     » topic index » view message » categorize

19. Re: SVN1260 WIN98 STILL BROKEN !

bernie said...
jimcbrown said...

Ok, in that case its possible col_max is being set incorrectly on 98 (due to API bugs?) which is causing the blanks to show up.

Jim:
According to MSDN WriteConsoleOutput :
If the rectangle specified by lpWriteRegion lies completely outside the
boundaries of the screen buffer, or if the corresponding rectangle is
positioned completely outside the boundaries of the source buffer, no data is
written.
So maybe the offset is outside the boundaries on Win98.

Why doesn't this affect SetCursorPosition or WriteConsole ?

new topic     » goto parent     » topic index » view message » categorize

20. Re: SVN1260 WIN98 STILL BROKEN !

jimcbrown said...
bernie said...
jimcbrown said...

Ok, in that case its possible col_max is being set incorrectly on 98 (due to API bugs?) which is causing the blanks to show up.

Jim:
According to MSDN WriteConsoleOutput :
If the rectangle specified by lpWriteRegion lies completely outside the
boundaries of the screen buffer, or if the corresponding rectangle is
positioned completely outside the boundaries of the source buffer, no data is
written.
So maybe the offset is outside the boundaries on Win98.

Why doesn't this affect SetCursorPosition or WriteConsole ?

Jim:
MSDN says WriteConsoleOutput has no effect on the cursor position.
Here's the link to console functions

http://msdn.microsoft.com/en-us/library/ms687404.aspx

new topic     » goto parent     » topic index » view message » categorize

21. Re: SVN1260 WIN98 STILL BROKEN !

bernie said...

Jim:
MSDN says WriteConsoleOutput has no effect on the cursor position.
Here's the link to console functions

http://msdn.microsoft.com/en-us/library/ms687404.aspx

I've already ruled this out, as my tests show 80x24 which is correct.

Since WriteConsoleOutput never worked for me, I'm not the best person to test changes to it anyways. I'm still waiting to hear about ne1uno's test results.

For now, when you aren't actively debugging this issue, just set EUCONS and everything should work the way it used to.

new topic     » goto parent     » topic index » view message » categorize

22. Re: SVN1260 WIN98 STILL BROKEN !

jimcbrown said...

Since WriteConsoleOutput never worked for me, I'm not the best person to test changes to it anyways. I'm still waiting to hear about ne1uno's test results.

I see that WriteConsoleOutput is not supported on Windows98 (actually anything before Win2000).

new topic     » goto parent     » topic index » view message » categorize

23. Re: SVN1260 WIN98 STILL BROKEN !

DerekParnell said...
jimcbrown said...

Since WriteConsoleOutput never worked for me, I'm not the best person to test changes to it anyways.

I see that WriteConsoleOutput is not supported on Windows98 (actually anything before Win2000).

win98 is no longer officially supported so newer help doesn't always mention it. I could find no KB# (knowledgebase) mentioning writeconsoleoutput as a problem on 98.

using an older MSDN help cd from 99: Requirements Windows NT/2000: Requires Windows NT 3.1 or later. Windows 95/98: Requires Windows 95 or later. Header: Declared in Wincon.h; include Windows.h. Library: Use Kernel32.lib. Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000

is it possibly that a wrong font or character type is selected? I'm guessing the default of unicode shouldn't be a problem on exwc compiled on 98.

new topic     » goto parent     » topic index » view message » categorize

24. Re: SVN1260 WIN98 STILL BROKEN !

SVN 1253 WIN98 binaries worked as they have in the past.

SVN 1254 WIN98 binaries DO NOT work properly on WIN98.

I moved SVN 1253 be_w.c and be_machine.c and
placed them into SVN 1254 source and recompiled.

The recompiled SVN 1254 then worked properly on WIN98.

I moved SVN 1253 be_w.c and be_machine.c and
placed them into SVN 1261 source and recompiled.

The recompiled SVN 1261 then worked properly on WIN98.


Therefore the problem is in the code of be_w.c, be_machine.c or both.

new topic     » goto parent     » topic index » view message » categorize

25. Re: SVN1260 WIN98 STILL BROKEN !

Bernie,

Try the modified be_w.c below with 1262. Does this fix the problem?

bernie said...

SVN 1253 WIN98 binaries worked as they have in the past.

SVN 1254 WIN98 binaries DO NOT work properly on WIN98.

I moved SVN 1253 be_w.c and be_machine.c and
placed them into SVN 1254 source and recompiled.

The recompiled SVN 1254 then worked properly on WIN98.

I moved SVN 1253 be_w.c and be_machine.c and
placed them into SVN 1261 source and recompiled.

The recompiled SVN 1261 then worked properly on WIN98.


Therefore the problem is in the code of be_w.c, be_machine.c or both.

/*****************************************************************************/ 
/*      (c) Copyright 2007 Rapid Deployment Software - See License.txt       */ 
/*****************************************************************************/ 
/*                                                                           */ 
/*                       SCREEN OUTPUT HANDLER                               */ 
/*                                                                           */ 
/*****************************************************************************/ 
 
/******************/ 
/* Included files */ 
/******************/ 
#include <stdio.h> 
#include <time.h> 
#ifdef EUNIX 
#include <sys/stat.h> 
#include <unistd.h> 
#else 
#ifdef EMINGW 
#include <sys/types.h> 
#include <sys/stat.h> 
#else 
#include <sys\types.h> 
#include <sys\stat.h> 
#endif 
#ifdef EDJGPP 
#include <pc.h> 
#include <sys/farptr.h> 
#include <dpmi.h> 
#include <go32.h> 
#include <allegro.h> 
#else 
#if !defined(ELCC) && !defined(EBORLAND) && !defined(EMINGW) 
#include <graph.h> 
#endif 
#endif 
#endif 
#include <string.h> 
#ifdef EWINDOWS 
#include <windows.h> 
#endif 
#include "alldefs.h" 
#ifdef EWATCOM 
#ifdef EDOS 
#include <i86.h> 
#endif 
#endif 
 
/******************/ 
/* Local defines  */ 
/******************/ 
#define MAX_SCREEN_WIDTH 200 /* what if resolutions get really high? >1280 */ 
#define TAB_WIDTH 8    /* power of 2 assumed */ 
 
/**********************/ 
/* Imported variables */ 
/**********************/ 
extern int current_screen; 
extern int line_max, col_max; 
extern int con_was_opened; 
extern struct videoconfig config; 
extern int low_on_space; 
extern unsigned current_bg_color; 
extern unsigned current_fg_color; 
 
/**********************/ 
/* Exported variables */ 
/**********************/ 
int screen_line = 1;     /* only used by ANSI code Linux */ 
int screen_col = 1;      /* column on screen, needed by expand_tabs below 

                         initialized in InitGraphics, then again in InitOutput */ 
int wrap_around = 1; 
int in_from_keyb;        /* stdin appears to be from keyboard */ 
char *collect = NULL;    /* to collect sprintf/sprint output */ 
int have_console = FALSE;  // is there a console window yet? 
int already_had_console = -1; /* were we created with a console window or did we have to allocate our own? */ 
#ifdef EWINDOWS 
HANDLE console_input;  // HANDLE for WIN32 console input 
HANDLE console_output; // HANDLE for WIN32 console output 
HANDLE console_trace;  // HANDLE for WIN32 output to trace-screen 
HANDLE console_var_display; // HANDLE for WIN32 output to large sequence display 
HANDLE console_save;   // place to save console_output while in trace screen 
#endif 
 
 
/*******************/ 
/* Local variables */ 
/*******************/ 
static int out_to_screen;  /* stdout is going to screen */ 
static int err_to_screen;  /* stderr is going to screen (always TRUE) */ 
#ifdef EWINDOWS 
static CHAR_INFO line_buffer[1024]; 
static int line_buffer_size = 0; 
 
static COORD buff_size; 
static COORD buff_start; 
static SMALL_RECT screen_loc; 
#endif 
static char expanded_string[MAX_SCREEN_WIDTH]; 
static char *expanded_ptr = expanded_string; 
static int must_flush = TRUE; /* flush output to screen or not */ 
static int collect_next;   /* place to store next collect output */ 
static int collect_free;   /* number of chars of empty space remaining */ 
#ifdef EUNIX 
// we need to record everything written to the screen 
struct char_cell screen_image[MAX_LINES][MAX_COLS]; 
// plus have two alternate screens for interactive trace 
struct char_cell alt_image_main[MAX_LINES][MAX_COLS]; 
struct char_cell alt_image_debug[MAX_LINES][MAX_COLS]; 
#endif 
 
/**********************/ 
/* Declared functions */ 
/**********************/ 
#ifndef ESIMPLE_MALLOC 
char *EMalloc(); 
char *ERealloc(); 
#else 
#include "alloc.h" 
#ifdef EWINDOWS 
extern unsigned default_heap; 
#endif 
#endif 
static void expand_tabs(); 
void SetPosition(); 
void RTInternal(); 
 
/*********************/ 
/* Defined functions */ 
/*********************/ 
struct rccoord GetTextPositionP() 
{ 
#if defined(EDOS) && !defined(EDJGPP) 
if (getenv("EUVISTA")!=NULL && atoi(getenv("EUVISTA"))==1) 
{ 
#endif 
        struct rccoord p; 
 
        p.row = screen_line; 
        p.col = screen_col; 
        return p; 
#if defined(EDOS) && !defined(EDJGPP) 
} else { 
        return _gettextposition(); 
} //endif EUVISTA 
#endif 
} 
void OutTextP(const char * c) 
{ 
#if defined(EDOS) && !defined(EDJGPP) 
if (getenv("EUVISTA")!=NULL && atoi(getenv("EUVISTA"))==1) 
{ 
#endif 
    printf(c); 
    fflush(stdout); 
#if defined(EDOS) && !defined(EDJGPP) 
} else { 
    _outtext(c); 
} //endif EUVISTA 
#endif 
} 
 
#ifdef EUNIX 
void screen_copy(struct char_cell a[MAX_LINES][MAX_COLS], 
                 struct char_cell b[MAX_LINES][MAX_COLS]) 
// copy a screen to another area 
{ 
    int i, j; 
 
    for (i = 0; i < line_max; i++) { 
        for (j = 0; j < col_max; j++) { 
            b[i][j] = a[i][j];  // structure copy 
        } 
    } 
} 
 
void screen_show() 
// display a screen 
{ 
    int i, j; 
 
    for (i = 0; i < line_max; i++) { 
        SetPosition(i+1, 1); 
        for (j = 0; j < col_max; j++) { 
            SetTColor(screen_image[i][j].fg_color); 
            SetBColor(screen_image[i][j].bg_color); 
            iputc(screen_image[i][j].ascii, stdout); 
        } 
    } 
    iflush(stdout); 
} 
#endif 
 
void InitInOut() 
/* Set up stdout and stderr. In EWINDOWS some stuff 

   is initialized right away. The rest is done later if necesssary on first 
   use of the console - see show_console() below. */ 
{ 
    struct rccoord position; 
    int i, j; 
#ifdef EDOS 
    struct stat buf; 
    int rc; 
#endif 
 
#ifdef EWINDOWS 
    position.col = 1;   // should do these 2 properly 
    position.row = 1; 
    screen_line = position.row; 
    screen_col = position.col; 
 
    buff_size.Y = 1; 
    buff_start.X = 0; 
    buff_start.Y = 0; 
#else 
#if defined(EUNIX) || defined(EDJGPP) 
    position.col = 1; 
    position.row = 1; 
    in_from_keyb  = isatty(0); 
    out_to_screen = isatty(1); 
    err_to_screen = isatty(2); 
    screen_line = position.row; 
    screen_col = position.col; 
#ifdef EUNIX 
    for (i = 0; i < line_max; i++) { 
        for (j = 0; j < col_max; j++) { 
            screen_image[i][j].ascii = ' '; 
            screen_image[i][j].fg_color = 15; 
            screen_image[i][j].bg_color = 0; 
        } 
    } 
#endif 
 
#else 
    //DOS 
    position = GetTextPositionP();  // causes OpenWatcom 1.4 to go full-screen 
 
    screen_col = position.col; 
    err_to_screen = TRUE;  /* stderr always goes to screen in DOS & WIN32 */ 
    rc = fstat(1, &buf); 
    if (rc == -1 || ((buf.st_atime == 0 || buf.st_mtime == 0) 
                     && (buf.st_dev < 0 || buf.st_dev > 9))) 
        out_to_screen = TRUE; /* what about printer ? */ 
    else 
        out_to_screen = FALSE; 
 
    rc = fstat(0, &buf); 
    if (rc == -1 || ((buf.st_atime == 0 || buf.st_mtime == 0) 
                     && (buf.st_dev < 0 || buf.st_dev > 9))) 
        in_from_keyb = TRUE; 
    else 
        in_from_keyb = FALSE; 
#endif 
#endif 
} 
 
#if defined(EWINDOWS) 
void show_console() 
/* set up a console window if not done yet */ 
{ 
    CONSOLE_SCREEN_BUFFER_INFO info; 
    CONSOLE_CURSOR_INFO c; 
    INPUT_RECORD pbuffer; 
    DWORD junk; 
    int alloc_ret; 
 
    if (have_console) 
        return; 
 
    have_console = TRUE; 
    alloc_ret = !AllocConsole(); 
    if (already_had_console < 0) { 
        // this effectively tells us if we were started as a GUI app or a CONSOLE app (exw.exe or exwc.exe) 
        already_had_console = alloc_ret; 
    } 
 
    console_output = GetStdHandle(STD_OUTPUT_HANDLE); 
 
    console_trace = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 
                                      FILE_SHARE_READ | FILE_SHARE_WRITE, 
                                      NULL, 
                                      CONSOLE_TEXTMODE_BUFFER, 
                                      NULL); 
 
    console_var_display = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 
                                      FILE_SHARE_READ | FILE_SHARE_WRITE, 
                                      NULL, 
                                      CONSOLE_TEXTMODE_BUFFER, 
                                      NULL); 
 
    c.dwSize = 12; 
    c.bVisible = FALSE; 
    SetConsoleCursorInfo(console_trace, &c); 
 
    out_to_screen = GetConsoleScreenBufferInfo(console_output, &info); 
 
    if (!out_to_screen) { 
        console_output = CreateFile("CONOUT$", 
                                GENERIC_READ | GENERIC_WRITE, 
                                FILE_SHARE_WRITE, 
                                NULL, 
                                OPEN_EXISTING, 
                                0, 
                                NULL); 
    } 
 
    console_input = GetStdHandle(STD_INPUT_HANDLE); 
 
    in_from_keyb = PeekConsoleInput(console_input, &pbuffer, 1, &junk); 
 
    // This stops the mouse cursor from appearing in full screen 
    SetConsoleMode(console_input, ENABLE_LINE_INPUT | 
                            ENABLE_ECHO_INPUT | 
                            ENABLE_PROCESSED_INPUT);  // no mouse please 
 
    NewConfig(TRUE); // update line_max and col_max 
} 
#endif 
 
#ifdef EWINDOWS 
static void end_of_line(int c) 
// handle \n or \r in Windows console 
{ 
    CONSOLE_SCREEN_BUFFER_INFO console_info; 
 
    GetConsoleScreenBufferInfo(console_output, &console_info); // not always necessary? 
    console_info.dwCursorPosition.X = 0; 
    if (c == '\n') { 
        if (console_info.dwCursorPosition.Y < console_info.dwMaximumWindowSize.Y - 1) 
            console_info.dwCursorPosition.Y++; 
        else { 
            // scroll screen up one line 
            SMALL_RECT src, clip; 
            COORD dest; 
            COORD pos; 
            CHAR_INFO fill_char; 
 
            if (getenv("EUCONS")!=NULL&&atoi(getenv("EUCONS"))==1){ 
                pos.X = 0; 
                pos.Y = console_info.dwSize.Y-1; 
                SetConsoleCursorPosition(console_output, pos); 
            } 
 
            src.Left = 0; 
            src.Right = console_info.dwMaximumWindowSize.X; 
            src.Top = 0; 
            src.Bottom = console_info.dwSize.Y-1; // -1 ??? 
            clip = src; 
            dest.X = 0; 
            dest.Y = src.Top - 1; // for now - ok??? 
            fill_char.Char.AsciiChar = ' '; 
            fill_char.Attributes = console_info.wAttributes; 
            ScrollConsoleScreenBuffer(console_output, 
                                      &src, 
                                      &clip, 
                                      dest, 
                                      &fill_char); 
        } 
    } 
    SetConsoleCursorPosition(console_output, console_info.dwCursorPosition); 
} 
 
#if defined(ELCC) || defined(EBORLAND) || defined(EMINGW) 
int MyReadConsoleChar() 
// Read the next character typed by the user on the console 
{ 
    DWORD nread; 
    char buff[4]; 
 
    ReadConsole(console_input, buff, 1, &nread, NULL); 
    return buff[0]; 
} 
#endif 
 
static void MyWriteConsole(char *string, int nchars) 
// write a string of plain characters to the console and 
// update the cursor position 
{ 
    int i; 
    static int first = 0; 
    CONSOLE_SCREEN_BUFFER_INFO console_info; 
    char old_string[82]; 
    COORD ch; 
 
    show_console(); 
    /* hack - if we are exwc, output something to avoid data appearing on the last line of the console which we later on will not be able to see */ 
    GetConsoleScreenBufferInfo(console_output, &console_info); // not always necessary? 
    if ( (getenv("EUCONS")!=NULL&&atoi(getenv("EUCONS"))==1) && 
    (already_had_console==1) && !first) { 
        if (!(console_info.dwCursorPosition.Y < console_info.dwSize.Y - 1)) 
        { 
            //WriteConsole(console_output, "\n", 1, &i, NULL); 
            end_of_line('\n'); 
        } 
        first = 1; 
    } 
 
    buff_size.X = nchars; 
 
    screen_loc.Top = console_info.dwCursorPosition.Y; 
    screen_loc.Bottom = screen_loc.Top; 
    screen_loc.Left = console_info.dwCursorPosition.X; //screen_col-1; 
    screen_loc.Right = console_info.dwMaximumWindowSize.X; 
 
    if (getenv("EUCONS")!=NULL&&atoi(getenv("EUCONS"))==1){ 
 
    ch.X = screen_loc.Left; 
    ch.Y = screen_loc.Top; 
 
    strncpy(old_string, string, 80); 
    old_string[81] = '\0'; 
 
    for (i = 0; i < nchars; i++) 
    { 
        if (old_string[i] == '\n') 
            old_string[i] = ' '; 
        if (old_string[i] == '\r') 
            old_string[i] = ' '; 
    } 
 
    SetConsoleCursorPosition(console_output, ch); 
    WriteConsole(console_output, string, nchars, &i, NULL); 
    SetConsoleCursorPosition(console_output, ch); 
 
    } else { 
 
    i = 0; 
    if( line_buffer_size < console_info.dwMaximumWindowSize.X ){ 
        line_buffer_size = console_info.dwMaximumWindowSize.X; 
    } 
 
    while (*string != '\0') { 
        line_buffer[i].Char.AsciiChar = *string; 
        line_buffer[i].Attributes = console_info.wAttributes; 
        string++; 
        i++; 
    } 
    WriteConsoleOutput(console_output, 
                       line_buffer, // was:  &line_buffer ? 
                       buff_size, 
                       buff_start, 
                       &screen_loc); 
    } // EUCONS 
 
    console_info.dwCursorPosition.X += nchars; // what if becomes 80? (i.e 1 too big) 
    SetConsoleCursorPosition(console_output, console_info.dwCursorPosition); 
    //screen_col += nchars; 
} 
#endif 
 
void buffer_screen() 
/* start buffering the screen output on each line */ 
{ 
    must_flush = FALSE; 
} 
 
void flush_screen() 
/* flush any left over characters */ 
{ 
    must_flush = TRUE; 
    expand_tabs(""); 
} 
 
 
#ifdef EDJGPP 
 
#define COLOR_TEXT_MEMORY 0x000B8000 
#define MONO_TEXT_MEMORY 0x000B0000 
 
static void graphic_puts(char *text) 
// use Allegro to write text in graphics modes 
{ 
    int n, last; 
 
    n = strlen(text); 
    if (n == 0) 
        return; 
    last = text[n-1]; 
    textout(screen, font, text, config.x, config.y, current_fg_color); 
    config.x += text_length(font, text); 
    if (last == '\n') { 
        config.x = 0; 
        config.y += text_height(font); 
    } 
    else if (last == '\r') { 
        config.x = 0; 
    } 
} 
 
static char *DOS_scr_addr(int line, int col) 
// calculate address in DOS screen memory for a given line, column 
{ 
    char *screen_memory; 
    int page_size; 
 
    if (config.mode == 7) 
        screen_memory = (char *)MONO_TEXT_MEMORY; 
    else 
        screen_memory = (char *)COLOR_TEXT_MEMORY; 
    // take out until we support pages: 
    // page_size = config.numtextrows * config.numtextcols * 2; 
    // page_size = 1024 * ((page_size + 1023) / 1024); 
    // screen_memory = screen_memory + get_active_page() * page_size; 
    return screen_memory + (line * config.numtextcols + col) * 2; 
} 
 
mem_cputs(char *text) 
/* write a string directly to screen memory */ 
{ 
    char *screen_memory; 
    int line, col, c; 
 
    if (TEXT_MODE) { 
        if (wrap_around) { 
            cputs(text); 
        } 
        else { 
            /* do it this way to avoid the scroll when the 

               last line is written */ 
            ScreenGetCursor(&line, &col); 
            while ((c = *text++) != 0) { 
                if (c == '\n') { 
                    if (line < config.numtextrows-1) 
                        line++; 
                    else { 
                        ScreenSetCursor(line, col); 
                        cputs("\n"); // only time we want to scroll 
                    } 
                    col = 0; 
                } 
                else if (c == '\r') { 
                    col = 0; 
                } 
                else if (col < config.numtextcols) { 
                    screen_memory = DOS_scr_addr(line, col); 
                    _farpokeb(_go32_info_block.selector_for_linear_memory, 
                            (unsigned)screen_memory++, 
                            c); 
                    _farpokeb(_go32_info_block.selector_for_linear_memory, 
                            (unsigned)screen_memory, 
                            ScreenAttrib); 
                    col++; 
                } 
            } 
            ScreenSetCursor(line, col); 
        } 
    } 
    else { 
        graphic_puts(text); // graphics modes 
    } 
} 
#endif 
 
#ifdef EUNIX 
void update_screen_string(char *s) 
// record that a string of characters was written to the screen 
{ 
    int i, col, line; 
    char buff[60]; 
 
    i = 0; 
    line = screen_line - 1; 
    col = screen_col - 1; 
    if (line < 0 || line >= line_max) { 
        sprintf(buff, "line corrupted (%d), s is %s, col is %d", 
        line, s, col); 
        debug_msg(buff); 
    } 
    // we shouldn't get any \n's or \r's, but just in case: 
    while (s[i] != 0 && s[i] != '\n' && s[i] != '\r' && col < col_max) { 
        screen_image[line][col].ascii = s[i]; 
        screen_image[line][col].fg_color = current_fg_color; 
        screen_image[line][col].bg_color = current_bg_color; 
        col += 1; 
        if (col < 0 || col > col_max) { 
            sprintf(buff, "col corrupted (%d)", col); 
            debug_msg(buff); 
        } 
        i += 1; 
    } 
} 
#endif 
 
static void expand_tabs(char *raw_string) 
/* Expand tabs and truncate long lines. 

 * Still needed to avoid a WATCOM bug that misprints lines that 
 * are too long for the screen width. Debug/Trace screen still uses 
 * tab expansion feature. Flush feature is used for better performance. 
 * Note: screen_col is the column based on what we have actually written 
 * to the screen so far, not what we have buffered. 
 */ 
{ 
    int c, i, nblanks, true_screen_col; 
 
    while ((c = *raw_string++) != 0) { 
 
        if (screen_col + (expanded_ptr - expanded_string) > col_max) { 
            // going past right margin 
            if (wrap_around) { 
                /* what if 0 chars to write? */ 
                *expanded_ptr = '\0'; 
#ifdef EWINDOWS 
                MyWriteConsole(expanded_string, 
                               expanded_ptr - expanded_string); 
                end_of_line('\n'); 
#else 
#ifdef EUNIX 
                iputs(expanded_string, stdout); 
                iflush(stdout); 
                update_screen_string(expanded_string); 
#else 
//DOS 
#ifdef EDJGPP 
                mem_cputs(expanded_string); //critical function 
#else 
                OutTextP(expanded_string); //critical function 
#endif 
#endif // EUNIX 
 
#endif // EWINDOWS 
                screen_col = 1; 
                expanded_ptr = expanded_string; // make it empty 
            } 
            else { 
                if (c != '\n' && c != '\r') 
                    continue; // ignore stuff past right margin 
            } 
        } 
 
        if (c == '\t') { 
            true_screen_col = screen_col + expanded_ptr - expanded_string; 
            /* expand with blanks */ 
            nblanks = ((true_screen_col - 1) & ~(TAB_WIDTH - 1)) + 
                      (TAB_WIDTH + 1) - true_screen_col; 
            if (true_screen_col + nblanks > col_max) 
                nblanks = col_max - true_screen_col + 1; 
            for (i = 1; i <= nblanks; i++) { 
                *expanded_ptr++ = ' '; 
            } 
        } 
 
        else if (c == '\n' || c == '\r') { 
#ifdef EWINDOWS 
            MyWriteConsole(expanded_string, expanded_ptr - expanded_string); 
            end_of_line(c); 
#endif 
 
#ifdef EUNIX 
            // curses advances to next line if given \r or \n beyond 80 
            *expanded_ptr = '\0'; 
            iputs(expanded_string, stdout); 
            iflush(stdout); 
            update_screen_string(expanded_string); 
            iputc(c, stdout); 
            iflush(stdout); 
#endif 
 
#ifdef EDOS 
#ifdef EDJGPP 
            if (c == '\n') 
                *expanded_ptr++ = '\r'; 
            *expanded_ptr++ = c; 
            *expanded_ptr = '\0'; 
            mem_cputs(expanded_string); 
#else 
            *expanded_ptr++ = c; 
            *expanded_ptr = '\0'; 
            OutTextP(expanded_string); 
#endif 
#endif 
            screen_col = 1; 
            if (c == '\n' && screen_line < config.numtextrows-1) 
                screen_line += 1; 
 
            expanded_ptr = expanded_string; 
        } 
 
        else if (screen_col <= col_max) { 
            // normal characters 
            *expanded_ptr++ = c; 
        } 
    } // end while 
 
    /* left over characters - flush? */ 
    if (expanded_ptr != expanded_string && must_flush) { 
 
        *expanded_ptr = '\0'; 
#ifdef EWINDOWS 
        MyWriteConsole(expanded_string, expanded_ptr - expanded_string); 
#else 
#ifdef EUNIX 
        iputs(expanded_string, stdout); 
        iflush(stdout); 
        update_screen_string(expanded_string); 
#else 
// DOS 
#ifdef EDJGPP 
        mem_cputs(expanded_string); 
#else 
        OutTextP(expanded_string); 
#endif 
#endif 
#endif 
        screen_col += expanded_ptr - expanded_string; 
        expanded_ptr = expanded_string; 
    } 
} 
 
void screen_output(IFILE f, char *out_string) 
/* All output from the compiler, interpreter or user program 

   comes here (except for some EPuts() output). It is then directed to the 
   appropriate window or passed to a file. */ 
/* f is output file, or NULL if debug screen, or DOING_SPRINTF */ 
/* out_string is null-terminated string of characters to write out */ 
{ 
    int len; 
 
    if ((int)f == DOING_SPRINTF) { 
        /* save characters as a C string in memory */ 
        len = strlen(out_string); 
        if (collect == NULL) { 
            collect_free = 80; 
            collect = EMalloc(len+1+collect_free); 
            strcpy(collect, out_string); 
            collect_next = len; 
        } 
        else { 
            if (len > collect_free) { 
                collect_free = len + 200; 
                collect = ERealloc(collect, collect_next + 1 + collect_free); 
            } 
            strcpy(collect+collect_next, out_string); 
            collect_free -= len; 
            collect_next += len; 
        } 
    } 
 
    else if (f == NULL) { 
        /* send to debug screen */ 
        expand_tabs(out_string); 
    } 
 
    else { 
#ifdef EUNIX 
        if ((f == stdout && out_to_screen) || 
            (f == stderr && err_to_screen && (!low_on_space || have_console))) { 
            if (current_screen != MAIN_SCREEN) 
                MainScreen(); 
            expand_tabs(out_string); 
            return; 
        } 
#else 
        if (f == stdout || f == stderr) { 
#ifdef EWINDOWS 
            show_console();  // needed to initialize out_to_screen in WIN32 
#endif 
            if (current_screen != MAIN_SCREEN) 
                MainScreen(); 
            if (out_to_screen || f == stderr) {  //stderr always goes to screen 
                expand_tabs(out_string); 
                return; 
            } 
        } 
#endif 
        else { 
            /* file/device output - should flush some devices ? */ 
            if (current_screen != MAIN_SCREEN && con_was_opened) 
                MainScreen(); 
        } 
 
        iputs(out_string, f); 
    } 
} 
 
#ifdef EWINDOWS 
void EClearLines(int first_line, int last_line, int len, WORD attributes) 
{ 
    int i, n; 
    COORD origin; 
 
    origin.X = 0; 
    for (i = first_line; i <= last_line; i++) { 
         origin.Y = i - 1; 
         FillConsoleOutputCharacter(console_output, ' ', len, origin, (LPDWORD)&n); 
         FillConsoleOutputAttribute(console_output, attributes, len, origin, (LPDWORD)&n); 
    } 
} 
#endif 
 
#ifdef EDOS 
#ifdef EWATCOM 
void SetPosInt(char x, char y) 
{ 
/* Perform a DOS software interrupt. */ 
    int int_no; 
    object_ptr obj_ptr; 
 
#ifdef EDJGPP 
    __dpmi_regs reglist; 
#else 
    // register list for Causeway IntXX 
    struct xx { 
        unsigned int edi; 
        unsigned int esi; 
        unsigned int ebp; 
        unsigned int z0; 
        unsigned int ebx; 
        unsigned int edx; 
        unsigned int ecx; 
        unsigned int eax; 
        unsigned short flags; 
        unsigned short es; 
        unsigned short ds; 
        unsigned short fs; 
        unsigned short gs; 
        unsigned short z1; 
        unsigned short z2; 
        unsigned short z3; 
        unsigned short z4; 
    } reglist; 
    union REGS regs; 
    struct SREGS seg_regs; 
#endif 
 
    int_no =       0x10; 
 
    // fill up reglist 
#ifdef EDJGPP 
    reglist.x.di = 0; 
    reglist.x.si = 0; 
    reglist.x.bp = 0; 
    reglist.x.bx = 0; 
    reglist.x.dx = y*256+x; 
    reglist.x.cx = 0; 
    reglist.x.ax = 0x0200; 
    reglist.x.flags = 0; 
    reglist.x.es = 0; 
    reglist.x.ds = 0; 
 
    __dpmi_int(int_no, &reglist); 
 
#else 
    reglist.edi = 0; 
    reglist.esi = 0; 
    reglist.ebp = 0; 
    reglist.z0 = 0; 
    reglist.ebx = 0; 
    reglist.edx = y*256+x; 
    reglist.ecx = 0; 
    reglist.eax = 0x0200; 
    reglist.flags = 0; 
    reglist.es = 0; 
    reglist.ds = 0; 
 
    reglist.fs = 0; 
    reglist.gs = 0; 
    reglist.z1 = 0; 
    reglist.z2 = 0; 
    reglist.z3 = 0; 
    reglist.z4 = 0; 
 
    segread(&seg_regs); 
    memset(&regs, 0, sizeof(regs)); 
    regs.x.edi = (unsigned int)&reglist; 
    regs.x.ebx = (unsigned int)int_no; // The user's interrupt number 
    regs.x.eax = 0x0ff01; // Causeway Simulate real mode interrupt 
 
    int386x(0x31, &regs, &regs, &seg_regs); 
#endif 
} 
#endif // EWATCOM 
#endif // EDOS 
 
void ClearScreen() 
{ 
#ifdef EWINDOWS 
    CONSOLE_SCREEN_BUFFER_INFO info; 
 
    show_console(); 
    GetConsoleScreenBufferInfo(console_output, &info); 
    EClearLines(1, info.dwSize.Y, info.dwSize.X, info.wAttributes); 
    SetPosition(1,1); 
#endif 
 
#ifdef EUNIX 
    // ANSI code 
    iputs("\033[2J", stdout);  // clear screen 
    SetPosition(1,1); 
#endif 
 
#ifdef EDOS 
#ifdef EDJGPP 
    if (TEXT_MODE) 
        ScreenClear(); // text modes 
    else 
        clear_to_color(screen, current_bg_color); 
    SetPosition(1,1); 
#else 
if (getenv("EUVISTA")!=NULL && atoi(getenv("EUVISTA"))==1) 
{ 
    system("CLS"); 
    SetPosInt(0,0); 
} else { 
    _clearscreen(_GCLEARSCREEN); 
} //endif EUVISTA 
#endif 
#endif 
    screen_line = 1; 
    screen_col = 1; 
} 
 
void SetPosition(int line, int col) 
{ 
#ifdef EUNIX 
    char lbuff[20]; 
    char cbuff[20]; 
#endif 
 
#ifdef EDOS 
#ifdef EDJGPP 
    if (TEXT_MODE) 
        ScreenSetCursor(line-1, col-1); 
    else { 
        config.x = (col-1) * text_length(font, "m"); 
        config.y = (line-1) * text_height(font); 
    } 
 
#else 
if (getenv("EUVISTA")!=NULL && atoi(getenv("EUVISTA"))==1) 
{ 
    SetPosInt((char)(line-1), (char)(col-1)); 
} else { 
    _settextposition(line, col); 
} //endif EUVISTA 
#endif 
#endif 
 
#ifdef EUNIX 
    sprintf(lbuff, "%d", line); 
    sprintf(cbuff, "%d", col); 
    // ANSI code 
    iputs("\033[", stdout); 
    iputs(lbuff, stdout); 
    iputc(';', stdout); 
    iputs(cbuff, stdout); 
    iputc('H', stdout); 
    iflush(stdout); 
#endif 
 
#ifdef EWINDOWS 
    COORD pos; 
 
    pos.X = col-1; 
    pos.Y = line-1; 
    show_console(); 
    SetConsoleCursorPosition(console_output, pos); 
#endif 
    screen_col = col; 
    screen_line = line; 
} 
 
#ifdef EWINDOWS 
 
void ReadInto(WORD * buf, LPTSTR * str, int size, int * n, int * m, WORD * saved, struct rccoord * pos) 
{ 
    COORD ch; 
 
    CONSOLE_SCREEN_BUFFER_INFO console_info; 
    GetConsoleScreenBufferInfo(console_output, &console_info); 
 
    *saved = console_info.wAttributes; 
    *pos = GetTextPositionP(); 
 
    ch.X = 0; 
    ch.Y = 0; 
    ReadConsoleOutputCharacter(console_output, str, size, ch, n); 
    ReadConsoleOutputAttribute(console_output, buf, size, ch, m); 
} 
 
void WriteOutFrom(WORD * buf, LPTSTR * str, int n, int m, WORD * saved, struct rccoord * pos) 
{ 
    int size1, size2; 
    COORD ch; 
    ch.X = 0; 
    ch.Y = 0; 
    WriteConsoleOutputCharacter(console_output, str, n, ch, &size1); 
    WriteConsoleOutputAttribute(console_output, buf, m, ch, &size2); 
 
    if (*saved != (WORD)-1) 
    { 
        SetConsoleTextAttribute(console_output, *saved); 
        *saved = (WORD)-1; 
    } 
    SetPosition(pos->row, pos->col); 
} 
 
TCHAR console_save_str[65536]; 
int console_save_str_n = 0; 
WORD console_save_buf[65536]; 
int console_save_buf_n = 0; 
WORD console_save_saved = (WORD)-1; 
struct rccoord console_save_pos; 
 
TCHAR console_trace_str[65536]; 
int console_trace_str_n = 0; 
WORD console_trace_buf[65536]; 
int console_trace_buf_n = 0; 
WORD console_trace_saved = (WORD)-1; 
struct rccoord console_trace_pos; 
 
void SaveNormal() 
{ 
    int size = 65536; 
    if (getenv("EUCONS")!=NULL&&atoi(getenv("EUCONS"))==1){ 
        ReadInto(console_save_buf, console_save_str, size, &console_save_buf_n, &console_save_str_n, &console_save_saved, &console_save_pos); 
    } else { 
        console_save = console_output; 
    } // EUCONS 
} 
 
void SaveTrace() 
{ 
    int size = 65536; 
    if (getenv("EUCONS")!=NULL&&atoi(getenv("EUCONS"))==1){ 
        ReadInto(console_trace_buf, console_trace_str, size, &console_save_buf_n, &console_save_str_n, &console_trace_saved, &console_trace_pos); 
    } else { 
        SetConsoleActiveScreenBuffer(console_var_display); 
        console_output = console_var_display; 
    } // EUCONS 
} 
 
void RestoreTrace() 
{ 
    if (getenv("EUCONS")!=NULL&&atoi(getenv("EUCONS"))==1){ 
        WriteOutFrom(console_trace_buf, console_trace_str, console_save_buf_n, console_save_str_n, &console_trace_saved, &console_trace_pos); 
    } else { 
        SetConsoleActiveScreenBuffer(console_trace); 
        console_output = console_trace; 
    } // EUCONS 
} 
 
void RestoreNormal() 
{ 
    if (getenv("EUCONS")!=NULL&&atoi(getenv("EUCONS"))==1){ 
        WriteOutFrom(console_save_buf, console_save_str, console_save_buf_n, console_save_str_n, &console_save_saved, &console_save_pos); 
    } else { 
        console_output = console_save; 
        SetConsoleActiveScreenBuffer(console_output); 
    } // EUCONS 
} 
 
#endif 
new topic     » goto parent     » topic index » view message » categorize

26. Re: SVN1260 WIN98 STILL BROKEN !

jimcbrown said...

Bernie,

Try the modified be_w.c below with 1262. Does this fix the problem?

no change here.

what is interesting, is you can redirect stdout to a file and the output is there.
exwc some.ex >t.txt
is probably some missing or extra default text attribute. trace(1) output is also blank but some of the lines are still colorized ok. rather than blanks, output may just be invisible.

new topic     » goto parent     » topic index » view message » categorize

27. Re: SVN1260 WIN98 STILL BROKEN !

jimcbrown said...

Bernie,

Try the modified be_w.c below with 1262. Does this fix the problem?

Is there a maximum (or even a reasonable upper limit) to the width? It seems like the dynamically allocated buffer was the problem. The structure isn't that big (is it?). Would it really make any difference to allocate 200 or so instead of 80 (the previous size)?

Matt

new topic     » goto parent     » topic index » view message » categorize

28. Re: SVN1260 WIN98 STILL BROKEN !

ne1uno said...
jimcbrown said...

Bernie,

Try the modified be_w.c below with 1262. Does this fix the problem?

no change here.

what is interesting, is you can redirect stdout to a file and the output is there.
exwc some.ex >t.txt
is probably some missing or extra default text attribute. trace(1) output is also blank but some of the lines are still colorized ok. rather than blanks, output may just be invisible.

Curious. That behavior was always the case for me.

Anyways, I was just checking to see if the use of the dynamic array was the cause or not. I guess it's not. So this is without a doubt related to the new console width/height code. Or else the earlier initialization... (I wonder if there is a difference between 80x24 and 80x25)

Looking at the code diff, I see

-       src.Right = 79; // assume for now !!! 
+       src.Right = info.dwMaximumWindowSize.X; 

but info.dwMaximumWindowSize.X is set to 80, not 79. I wonder if that makes a difference?
(Line 344 of be_w.c and 1856 and 1866 of be_machine.c)

new topic     » goto parent     » topic index » view message » categorize

29. Re: SVN1260 WIN98 STILL BROKEN !

mattlewis said...
jimcbrown said...

Bernie,

Try the modified be_w.c below with 1262. Does this fix the problem?

Is there a maximum (or even a reasonable upper limit) to the width? It seems like the dynamically allocated buffer was the problem. The structure isn't that big (is it?). Would it really make any difference to allocate 200 or so instead of 80 (the previous size)?

Matt

I don't think you'll see a console width larger than 160.

Why do you think it is the dynamically allocated buffer that is the problem? ne1uno reports that a static buffer doesn't make a difference. (As I've stated before I'm not able to test this aspect on my own w98 machine.)

new topic     » goto parent     » topic index » view message » categorize

30. Re: SVN1260 WIN98 STILL BROKEN !

bernie said...

Therefore the problem is in the code of be_w.c, be_machine.c or both.

The problem was in both. There were places in the code that used dwMaximumWindowSize.X but should have used dwMaximumWindowSize.X - 1 and it seems being out of bounds by one character caused WriteConsoleOutput() to send nothing at all on W98 (but 2K and XP's implementation probably tries to write as much as it can, hence the error isn't so obvious there).

This explains why WriteConsoleOutput() never worked for me - the original hardcoded size was 80x25 but I have a console of 80x24, so I was seeing this bug long before anyone else did.

This is now fixed in 1263.

bernie said...

Jim:
According to MSDN WriteConsoleOutput :
If the rectangle specified by lpWriteRegion lies completely outside the
boundaries of the screen buffer, or if the corresponding rectangle is
positioned completely outside the boundaries of the source buffer, no data is
written.
So maybe the offset is outside the boundaries on Win98.

You are correct. Thanks for putting us in the right direction.

new topic     » goto parent     » topic index » view message » categorize

31. Re: SVN1260 WIN98 STILL BROKEN !

I did a complete checkout of SVN1264 and built the WIN98 binaries.
Everything seems to now be working on WIN98.

Thanks to Jim, Derek, Matt, ne1uno and anyone else I've forgotten
for all your help and hard work.
Bernie

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu