Commit 0b83d4cb authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

New console code based on Win32 windows.

parent 6b6596a1
...@@ -28,7 +28,8 @@ PROGRAMS = \ ...@@ -28,7 +28,8 @@ PROGRAMS = \
# Programs that link with libwine # Programs that link with libwine
LIBPROGRAMS = \ LIBPROGRAMS = \
debugger/winedbg debugger/winedbg \
programs/wineconsole/wineconsole
# Libraries (not dlls) to build # Libraries (not dlls) to build
LIBRARIES = \ LIBRARIES = \
...@@ -59,6 +60,7 @@ INSTALLSUBDIRS = \ ...@@ -59,6 +60,7 @@ INSTALLSUBDIRS = \
include \ include \
library \ library \
ole \ ole \
programs/wineconsole \
server \ server \
tools \ tools \
tsx11 \ tsx11 \
......
...@@ -7166,6 +7166,7 @@ programs/regtest/Makefile ...@@ -7166,6 +7166,7 @@ programs/regtest/Makefile
programs/uninstaller/Makefile programs/uninstaller/Makefile
programs/view/Makefile programs/view/Makefile
programs/wcmd/Makefile programs/wcmd/Makefile
programs/wineconsole/Makefile
programs/winemine/Makefile programs/winemine/Makefile
programs/winetest/Makefile programs/winetest/Makefile
programs/winhelp/Makefile programs/winhelp/Makefile
...@@ -7426,6 +7427,7 @@ programs/regtest/Makefile ...@@ -7426,6 +7427,7 @@ programs/regtest/Makefile
programs/uninstaller/Makefile programs/uninstaller/Makefile
programs/view/Makefile programs/view/Makefile
programs/wcmd/Makefile programs/wcmd/Makefile
programs/wineconsole/Makefile
programs/winemine/Makefile programs/winemine/Makefile
programs/winetest/Makefile programs/winetest/Makefile
programs/winhelp/Makefile programs/winhelp/Makefile
......
...@@ -1336,6 +1336,7 @@ programs/regtest/Makefile ...@@ -1336,6 +1336,7 @@ programs/regtest/Makefile
programs/uninstaller/Makefile programs/uninstaller/Makefile
programs/view/Makefile programs/view/Makefile
programs/wcmd/Makefile programs/wcmd/Makefile
programs/wineconsole/Makefile
programs/winemine/Makefile programs/winemine/Makefile
programs/winetest/Makefile programs/winetest/Makefile
programs/winhelp/Makefile programs/winhelp/Makefile
......
...@@ -444,7 +444,7 @@ struct x11drv_thread_data *x11drv_init_thread_data(void) ...@@ -444,7 +444,7 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
if (synchronous) XSynchronize( data->display, True ); if (synchronous) XSynchronize( data->display, True );
wine_tsx11_unlock(); wine_tsx11_unlock();
data->display_fd = FILE_DupUnixHandle( ConnectionNumber(data->display), data->display_fd = FILE_DupUnixHandle( ConnectionNumber(data->display),
GENERIC_READ | SYNCHRONIZE ); GENERIC_READ | SYNCHRONIZE, FALSE );
data->process_event_count = 0; data->process_event_count = 0;
NtCurrentTeb()->driver_data = data; NtCurrentTeb()->driver_data = data;
return data; return data;
......
...@@ -93,6 +93,17 @@ Options: ...@@ -93,6 +93,17 @@ Options:
options that affect the Windows program should come options that affect the Windows program should come
<emphasis>after</emphasis> it. <emphasis>after</emphasis> it.
</para> </para>
<para>
If you want to run a console program (aka a CUI executable), use
<command>wineconsole</command> instead of <command>wine</command>
to start it. It will display the program in a separate Window
(this requires X11 to be run). If you don't, you'll still be able
to run able your program, in the Unix console were you're started
your program, but with very limited capacities (so, your program
might work, but your mileage may vary). This shall be improved
in the future.
</para>
</sect1> </sect1>
<sect1 id="command-line-options"> <sect1 id="command-line-options">
......
.\" -*- nroff -*- .\" -*- nroff -*-
.TH WINE 1 "Aug 5, 2001" "Version 20010731" "Windows On Unix" .TH WINE 1 "Oct 13, 2001" "Version 20011004" "Windows On Unix"
.SH NAME .SH NAME
wine \- run Windows programs on Unix wine \- run Windows programs on Unix
.SH SYNOPSIS .SH SYNOPSIS
...@@ -20,6 +20,16 @@ For debugging wine, use ...@@ -20,6 +20,16 @@ For debugging wine, use
.I program .I program
instead. instead.
.PP .PP
For running CUI executables (Windows console programs), use
.B wineconsole
instead of
.B wine
. This will display all the output in a separate windows (this requires X11 to
run). Not using
.B wineconsole
for CUI programs will only provide very limited console support, and your
program might not function properly.
.PP
.B wine .B wine
currently runs a growing list of applications written for all kinds of currently runs a growing list of applications written for all kinds of
Windows versions >= Win2.0, e.g. Win3.1, Win95/98, NT. Windows versions >= Win2.0, e.g. Win3.1, Win95/98, NT.
...@@ -350,6 +360,11 @@ The ...@@ -350,6 +360,11 @@ The
.B wine .B wine
program loader. program loader.
.TP .TP
.I @prefix@/bin/wineconsole
The
.B wine
program loader for CUI (console) applications.
.TP
.I @prefix@/bin/dosmod .I @prefix@/bin/dosmod
The DOS program loader. The DOS program loader.
.TP .TP
......
...@@ -182,7 +182,7 @@ void FILE_SetDosError(void) ...@@ -182,7 +182,7 @@ void FILE_SetDosError(void)
* Duplicate a Unix handle into a task handle. * Duplicate a Unix handle into a task handle.
* Returns 0 on failure. * Returns 0 on failure.
*/ */
HANDLE FILE_DupUnixHandle( int fd, DWORD access ) HANDLE FILE_DupUnixHandle( int fd, DWORD access, BOOL inherit )
{ {
HANDLE ret; HANDLE ret;
...@@ -191,6 +191,7 @@ HANDLE FILE_DupUnixHandle( int fd, DWORD access ) ...@@ -191,6 +191,7 @@ HANDLE FILE_DupUnixHandle( int fd, DWORD access )
SERVER_START_REQ( alloc_file_handle ) SERVER_START_REQ( alloc_file_handle )
{ {
req->access = access; req->access = access;
req->inherit = inherit;
req->fd = fd; req->fd = fd;
SERVER_CALL(); SERVER_CALL();
ret = req->handle; ret = req->handle;
...@@ -255,14 +256,15 @@ int FILE_GetUnixHandle( HANDLE handle, DWORD access ) ...@@ -255,14 +256,15 @@ int FILE_GetUnixHandle( HANDLE handle, DWORD access )
* Open a handle to the current process console. * Open a handle to the current process console.
* Returns 0 on failure. * Returns 0 on failure.
*/ */
static HANDLE FILE_OpenConsole( BOOL output, DWORD access, LPSECURITY_ATTRIBUTES sa ) static HANDLE FILE_OpenConsole( BOOL output, DWORD access, DWORD sharing, LPSECURITY_ATTRIBUTES sa )
{ {
HANDLE ret; HANDLE ret;
SERVER_START_REQ( open_console ) SERVER_START_REQ( open_console )
{ {
req->output = output; req->from = output;
req->access = access; req->access = access;
req->share = sharing;
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
SetLastError(0); SetLastError(0);
SERVER_CALL_ERR(); SERVER_CALL_ERR();
...@@ -477,12 +479,12 @@ HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing, ...@@ -477,12 +479,12 @@ HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing,
/* Open a console for CONIN$ or CONOUT$ */ /* Open a console for CONIN$ or CONOUT$ */
if (!strcasecmp(filename, "CONIN$")) if (!strcasecmp(filename, "CONIN$"))
{ {
ret = FILE_OpenConsole( FALSE, access, sa ); ret = FILE_OpenConsole( FALSE, access, sharing, sa );
goto done; goto done;
} }
if (!strcasecmp(filename, "CONOUT$")) if (!strcasecmp(filename, "CONOUT$"))
{ {
ret = FILE_OpenConsole( TRUE, access, sa ); ret = FILE_OpenConsole( TRUE, access, sharing, sa );
goto done; goto done;
} }
...@@ -1452,13 +1454,12 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, ...@@ -1452,13 +1454,12 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
if (!bytesToRead) return TRUE; if (!bytesToRead) return TRUE;
unix_handle = FILE_GetUnixHandleType( hFile, GENERIC_READ, &type ); unix_handle = FILE_GetUnixHandleType( hFile, GENERIC_READ, &type );
if (unix_handle == -1)
return FALSE;
switch(type) switch (type)
{ {
case FD_TYPE_OVERLAPPED: case FD_TYPE_OVERLAPPED:
if(!overlapped) if (unix_handle == -1) return FALSE;
if (!overlapped)
{ {
close(unix_handle); close(unix_handle);
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
...@@ -1493,8 +1494,13 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead, ...@@ -1493,8 +1494,13 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
SetLastError(ERROR_IO_PENDING); SetLastError(ERROR_IO_PENDING);
return FALSE; return FALSE;
case FD_TYPE_CONSOLE:
return ReadConsoleA(hFile, buffer, bytesToRead, bytesRead, NULL);
default: default:
if(overlapped) /* normal unix files */
if (unix_handle == -1)
return FALSE;
if (overlapped)
{ {
close(unix_handle); close(unix_handle);
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
...@@ -1648,6 +1654,7 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite, ...@@ -1648,6 +1654,7 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
LPDWORD bytesWritten, LPOVERLAPPED overlapped ) LPDWORD bytesWritten, LPOVERLAPPED overlapped )
{ {
int unix_handle, result; int unix_handle, result;
DWORD type;
TRACE("%d %p %ld %p %p\n", hFile, buffer, bytesToWrite, TRACE("%d %p %ld %p %p\n", hFile, buffer, bytesToWrite,
bytesWritten, overlapped ); bytesWritten, overlapped );
...@@ -1659,8 +1666,18 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite, ...@@ -1659,8 +1666,18 @@ BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
if ( overlapped ) if ( overlapped )
return WriteFileEx(hFile, buffer, bytesToWrite, overlapped, NULL); return WriteFileEx(hFile, buffer, bytesToWrite, overlapped, NULL);
unix_handle = FILE_GetUnixHandle( hFile, GENERIC_WRITE ); unix_handle = FILE_GetUnixHandleType( hFile, GENERIC_WRITE, &type );
if (unix_handle == -1) return FALSE;
switch (type)
{
case FD_TYPE_CONSOLE:
TRACE("%d %s %ld %p %p\n", hFile, debugstr_an(buffer, bytesToWrite), bytesToWrite,
bytesWritten, overlapped );
return WriteConsoleA(hFile, buffer, bytesToWrite, bytesWritten, NULL);
default:
if (unix_handle == -1)
return FALSE;
}
/* synchronous file write */ /* synchronous file write */
while ((result = write( unix_handle, buffer, bytesToWrite )) == -1) while ((result = write( unix_handle, buffer, bytesToWrite )) == -1)
......
...@@ -71,7 +71,7 @@ inline static int FILE_contains_path (LPCSTR name) ...@@ -71,7 +71,7 @@ inline static int FILE_contains_path (LPCSTR name)
extern int FILE_strcasecmp( const char *str1, const char *str2 ); extern int FILE_strcasecmp( const char *str1, const char *str2 );
extern int FILE_strncasecmp( const char *str1, const char *str2, int len ); extern int FILE_strncasecmp( const char *str1, const char *str2, int len );
extern void FILE_SetDosError(void); extern void FILE_SetDosError(void);
extern HANDLE FILE_DupUnixHandle( int fd, DWORD access ); extern HANDLE FILE_DupUnixHandle( int fd, DWORD access, BOOL inherit );
extern int FILE_GetUnixHandle( HANDLE handle, DWORD access ); extern int FILE_GetUnixHandle( HANDLE handle, DWORD access );
extern BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info ); extern BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info );
extern HFILE16 FILE_Dup2( HFILE16 hFile1, HFILE16 hFile2 ); extern HFILE16 FILE_Dup2( HFILE16 hFile1, HFILE16 hFile2 );
......
...@@ -17,6 +17,8 @@ extern "C" { ...@@ -17,6 +17,8 @@ extern "C" {
#define ENABLE_ECHO_INPUT 0x04 #define ENABLE_ECHO_INPUT 0x04
#define ENABLE_WINDOW_INPUT 0x08 #define ENABLE_WINDOW_INPUT 0x08
#define ENABLE_MOUSE_INPUT 0x10 #define ENABLE_MOUSE_INPUT 0x10
/* Wine only code (extension) */
#define WINE_ENABLE_LINE_INPUT_EMACS 0x80
#define ENABLE_PROCESSED_OUTPUT 0x01 #define ENABLE_PROCESSED_OUTPUT 0x01
#define ENABLE_WRAP_AT_EOL_OUTPUT 0x02 #define ENABLE_WRAP_AT_EOL_OUTPUT 0x02
......
...@@ -577,6 +577,7 @@ struct alloc_file_handle_request ...@@ -577,6 +577,7 @@ struct alloc_file_handle_request
{ {
struct request_header __header; struct request_header __header;
unsigned int access; unsigned int access;
int inherit;
int fd; int fd;
handle_t handle; handle_t handle;
}; };
...@@ -755,8 +756,9 @@ struct alloc_console_request ...@@ -755,8 +756,9 @@ struct alloc_console_request
struct request_header __header; struct request_header __header;
unsigned int access; unsigned int access;
int inherit; int inherit;
void* pid;
handle_t handle_in; handle_t handle_in;
handle_t handle_out; handle_t event;
}; };
...@@ -767,25 +769,69 @@ struct free_console_request ...@@ -767,25 +769,69 @@ struct free_console_request
}; };
#define CONSOLE_RENDERER_NONE_EVENT 0x00
struct open_console_request #define CONSOLE_RENDERER_TITLE_EVENT 0x01
#define CONSOLE_RENDERER_ACTIVE_SB_EVENT 0x02
#define CONSOLE_RENDERER_SB_RESIZE_EVENT 0x03
#define CONSOLE_RENDERER_UPDATE_EVENT 0x04
#define CONSOLE_RENDERER_CURSOR_POS_EVENT 0x05
#define CONSOLE_RENDERER_CURSOR_GEOM_EVENT 0x06
#define CONSOLE_RENDERER_DISPLAY_EVENT 0x07
#define CONSOLE_RENDERER_EXIT_EVENT 0x08
struct console_renderer_event
{
short event;
union
{
struct update
{
short top;
short bottom;
} update;
struct resize
{
short width;
short height;
} resize;
struct cursor_pos
{
short x;
short y;
} cursor_pos;
struct cursor_geom
{
short visible;
short size;
} cursor_geom;
struct display
{
short left;
short top;
short width;
short height;
} display;
} u;
};
struct get_console_renderer_events_request
{ {
struct request_header __header; struct request_header __header;
int output;
unsigned int access;
int inherit;
handle_t handle; handle_t handle;
/* VARARG(data,bytes); */
}; };
struct set_console_fd_request struct open_console_request
{ {
struct request_header __header; struct request_header __header;
int from;
unsigned int access;
int inherit;
int share;
handle_t handle; handle_t handle;
int fd_in;
int fd_out;
int pid;
}; };
...@@ -808,30 +854,113 @@ struct set_console_mode_request ...@@ -808,30 +854,113 @@ struct set_console_mode_request
struct set_console_info_request struct set_console_input_info_request
{ {
struct request_header __header; struct request_header __header;
handle_t handle; handle_t handle;
int mask; int mask;
int cursor_size; handle_t active_sb;
int cursor_visible; int history_mode;
/* VARARG(title,string); */ int history_size;
/* VARARG(title,unicode_str); */
};
#define SET_CONSOLE_INPUT_INFO_ACTIVE_SB 0x01
#define SET_CONSOLE_INPUT_INFO_TITLE 0x02
#define SET_CONSOLE_INPUT_INFO_HISTORY_MODE 0x04
#define SET_CONSOLE_INPUT_INFO_HISTORY_SIZE 0x08
struct get_console_input_info_request
{
struct request_header __header;
handle_t handle;
int history_mode;
int history_size;
int history_index;
/* VARARG(title,unicode_str); */
};
struct append_console_input_history_request
{
struct request_header __header;
handle_t handle;
/* VARARG(line,unicode_str); */
};
struct get_console_input_history_request
{
struct request_header __header;
handle_t handle;
int index;
/* VARARG(line,unicode_str); */
};
struct create_console_output_request
{
struct request_header __header;
handle_t handle_in;
int access;
int share;
int inherit;
handle_t handle_out;
}; };
#define SET_CONSOLE_INFO_CURSOR 0x01
#define SET_CONSOLE_INFO_TITLE 0x02
struct get_console_info_request
struct set_console_output_info_request
{ {
struct request_header __header; struct request_header __header;
handle_t handle; handle_t handle;
int cursor_size; int mask;
int cursor_visible; short int cursor_size;
int pid; short int cursor_visible;
/* VARARG(title,string); */ short int cursor_x;
short int cursor_y;
short int width;
short int height;
short int attr;
short int win_left;
short int win_top;
short int win_right;
short int win_bottom;
short int max_width;
short int max_height;
}; };
#define SET_CONSOLE_OUTPUT_INFO_CURSOR_GEOM 0x01
#define SET_CONSOLE_OUTPUT_INFO_CURSOR_POS 0x02
#define SET_CONSOLE_OUTPUT_INFO_SIZE 0x04
#define SET_CONSOLE_OUTPUT_INFO_ATTR 0x08
#define SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW 0x10
#define SET_CONSOLE_OUTPUT_INFO_MAX_SIZE 0x20
struct get_console_output_info_request
{
struct request_header __header;
handle_t handle;
short int cursor_size;
short int cursor_visible;
short int cursor_x;
short int cursor_y;
short int width;
short int height;
short int attr;
short int win_left;
short int win_top;
short int win_right;
short int win_bottom;
short int max_width;
short int max_height;
};
struct write_console_input_request struct write_console_input_request
{ {
...@@ -842,6 +971,7 @@ struct write_console_input_request ...@@ -842,6 +971,7 @@ struct write_console_input_request
}; };
struct read_console_input_request struct read_console_input_request
{ {
struct request_header __header; struct request_header __header;
...@@ -853,6 +983,53 @@ struct read_console_input_request ...@@ -853,6 +983,53 @@ struct read_console_input_request
struct write_console_output_request
{
struct request_header __header;
handle_t handle;
int mode;
short int x;
short int y;
/* VARARG(data,bytes); */
int written;
};
#define WRITE_CONSOLE_MODE_TEXT 0x00
#define WRITE_CONSOLE_MODE_ATTR 0x01
#define WRITE_CONSOLE_MODE_TEXTATTR 0x02
#define WRITE_CONSOLE_MODE_TEXTSTDATTR 0x03
#define WRITE_CONSOLE_MODE_UNIFORM 0x04
struct read_console_output_request
{
struct request_header __header;
handle_t handle;
short int x;
short int y;
short int w;
short int h;
short int eff_w;
short int eff_h;
/* VARARG(data,bytes); */
};
struct move_console_output_request
{
struct request_header __header;
handle_t handle;
short int x_src;
short int y_src;
short int x_dst;
short int y_dst;
short int w;
short int h;
};
struct create_change_notification_request struct create_change_notification_request
{ {
struct request_header __header; struct request_header __header;
...@@ -1843,14 +2020,22 @@ enum request ...@@ -1843,14 +2020,22 @@ enum request
REQ_enable_socket_event, REQ_enable_socket_event,
REQ_alloc_console, REQ_alloc_console,
REQ_free_console, REQ_free_console,
REQ_get_console_renderer_events,
REQ_open_console, REQ_open_console,
REQ_set_console_fd,
REQ_get_console_mode, REQ_get_console_mode,
REQ_set_console_mode, REQ_set_console_mode,
REQ_set_console_info, REQ_set_console_input_info,
REQ_get_console_info, REQ_get_console_input_info,
REQ_append_console_input_history,
REQ_get_console_input_history,
REQ_create_console_output,
REQ_set_console_output_info,
REQ_get_console_output_info,
REQ_write_console_input, REQ_write_console_input,
REQ_read_console_input, REQ_read_console_input,
REQ_write_console_output,
REQ_read_console_output,
REQ_move_console_output,
REQ_create_change_notification, REQ_create_change_notification,
REQ_create_mapping, REQ_create_mapping,
REQ_open_mapping, REQ_open_mapping,
...@@ -1990,14 +2175,22 @@ union generic_request ...@@ -1990,14 +2175,22 @@ union generic_request
struct enable_socket_event_request enable_socket_event; struct enable_socket_event_request enable_socket_event;
struct alloc_console_request alloc_console; struct alloc_console_request alloc_console;
struct free_console_request free_console; struct free_console_request free_console;
struct get_console_renderer_events_request get_console_renderer_events;
struct open_console_request open_console; struct open_console_request open_console;
struct set_console_fd_request set_console_fd;
struct get_console_mode_request get_console_mode; struct get_console_mode_request get_console_mode;
struct set_console_mode_request set_console_mode; struct set_console_mode_request set_console_mode;
struct set_console_info_request set_console_info; struct set_console_input_info_request set_console_input_info;
struct get_console_info_request get_console_info; struct get_console_input_info_request get_console_input_info;
struct append_console_input_history_request append_console_input_history;
struct get_console_input_history_request get_console_input_history;
struct create_console_output_request create_console_output;
struct set_console_output_info_request set_console_output_info;
struct get_console_output_info_request get_console_output_info;
struct write_console_input_request write_console_input; struct write_console_input_request write_console_input;
struct read_console_input_request read_console_input; struct read_console_input_request read_console_input;
struct write_console_output_request write_console_output;
struct read_console_output_request read_console_output;
struct move_console_output_request move_console_output;
struct create_change_notification_request create_change_notification; struct create_change_notification_request create_change_notification;
struct create_mapping_request create_mapping; struct create_mapping_request create_mapping;
struct open_mapping_request open_mapping; struct open_mapping_request open_mapping;
...@@ -2080,6 +2273,6 @@ union generic_request ...@@ -2080,6 +2273,6 @@ union generic_request
struct get_window_properties_request get_window_properties; struct get_window_properties_request get_window_properties;
}; };
#define SERVER_PROTOCOL_VERSION 64 #define SERVER_PROTOCOL_VERSION 65
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -1052,10 +1052,6 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine, ...@@ -1052,10 +1052,6 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine,
/* Warn if unsupported features are used */ /* Warn if unsupported features are used */
if (dwCreationFlags & DETACHED_PROCESS)
FIXME("(%s,...): DETACHED_PROCESS ignored\n", name);
if (dwCreationFlags & CREATE_NEW_CONSOLE)
FIXME("(%s,...): CREATE_NEW_CONSOLE ignored\n", name);
if (dwCreationFlags & NORMAL_PRIORITY_CLASS) if (dwCreationFlags & NORMAL_PRIORITY_CLASS)
FIXME("(%s,...): NORMAL_PRIORITY_CLASS ignored\n", name); FIXME("(%s,...): NORMAL_PRIORITY_CLASS ignored\n", name);
if (dwCreationFlags & IDLE_PRIORITY_CLASS) if (dwCreationFlags & IDLE_PRIORITY_CLASS)
......
...@@ -17,6 +17,7 @@ SUBDIRS = \ ...@@ -17,6 +17,7 @@ SUBDIRS = \
uninstaller \ uninstaller \
view \ view \
wcmd \ wcmd \
wineconsole \
winemine \ winemine \
winetest \ winetest \
winhelp \ winhelp \
......
Makefile
wineconsole.spec.c
wineconsole_res.res
EXTRADEFS = -DSTRICT -DUNICODE
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = wineconsole
C_SRCS = \
dialog.c \
user.c \
wineconsole.c
RC_SRCS = \
wineconsole_res.rc
@MAKE_PROG_RULES@
### Dependencies:
#include <winbase.h>
#include <wingdi.h>
#include <winuser.h>
#include <wincon.h>
#include "wineconsole_res.h"
struct inner_data {
unsigned sb_width; /* active screen buffer width */
unsigned sb_height; /* active screen buffer height */
CHAR_INFO* cells; /* local copy of cells (sb_width * sb_height) */
COORD win_pos; /* position (in cells) of visible part of screen buffer in window */
unsigned win_width; /* size (in cells) of visible part of window (width & height) */
unsigned win_height;
COORD cursor; /* position in cells of cursor */
int cursor_visible;
int cursor_size; /* in % of cell height */
HANDLE hConIn; /* console input handle */
HANDLE hConOut; /* screen buffer handle: has to be changed when active sb changes */
HANDLE hSynchro; /* waitable handle signalled by server when something in server has been modified */
int (*fnMainLoop)(struct inner_data* data);
void (*fnPosCursor)(const struct inner_data* data);
void (*fnShapeCursor)(struct inner_data* data, int size, int vis, BOOL force);
void (*fnComputePositions)(struct inner_data* data);
void (*fnRefresh)(const struct inner_data* data, int tp, int bm);
void (*fnResizeScreenBuffer)(struct inner_data* data);
void (*fnSetTitle)(const struct inner_data* data);
void (*fnScroll)(struct inner_data* data, int pos, BOOL horz);
void (*fnDeleteBackend)(struct inner_data* data);
/* the following fields are only user by the USER backend (should be hidden in user) */
HWND hWnd; /* handle to windows for rendering */
HFONT hFont; /* font used for rendering, usually fixed */
LOGFONT logFont; /* logFont dscription for used hFont */
unsigned cell_width; /* width in pixels of a character */
unsigned cell_height; /* height in pixels of a character */
HDC hMemDC; /* memory DC holding the bitmap below */
HBITMAP hBitmap; /* bitmap of display window content */
HBITMAP cursor_bitmap; /* bitmap used for the caret */
BOOL hasSelection; /* a rectangular mouse selection has taken place */
COORD selectPt1; /* start (and end) point of a mouse selection */
COORD selectPt2;
};
# ifdef __GNUC__
extern void XTracer(int level, const char* format, ...) __attribute__((format (printf,2,3)));
# else
extern void XTracer(int level, const char* format, ...);
# endif
#if 0
/* Trace mode */
# define Trace XTracer
#else
/* non trace mode */
# define Trace (1) ? (void)0 : XTracer
#endif
extern void WINECON_NotifyWindowChange(struct inner_data* data);
extern int WINECON_GetHistorySize(HANDLE hConIn);
extern BOOL WINECON_SetHistorySize(HANDLE hConIn, int size);
extern int WINECON_GetHistoryMode(HANDLE hConIn);
extern BOOL WINECON_SetHistoryMode(HANDLE hConIn, int mode);
extern BOOL WINECON_GetConsoleTitle(HANDLE hConIn, WCHAR* buffer, size_t len);
extern void WINECON_FetchCells(struct inner_data* data, int upd_tp, int upd_bm);
extern int WINECON_GrabChanges(struct inner_data* data);
extern BOOL WCUSER_GetProperties(struct inner_data*);
extern BOOL WCUSER_SetFont(struct inner_data* data, const LOGFONT* font, const TEXTMETRIC* tm);
extern BOOL WCUSER_ValidateFont(const struct inner_data* data, const LOGFONT* lf);
extern BOOL WCUSER_ValidateFontMetric(const struct inner_data* data, const TEXTMETRIC* tm);
extern BOOL WCUSER_InitBackend(struct inner_data* data);
name wineconsole
mode guiexe
type win32
init WINECON_WinMain
rsrc wineconsole_res.res
import -delay comctl32
import gdi32.dll
import user32.dll
#import advapi32.dll
import kernel32.dll
import ntdll.dll
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
STRINGTABLE LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
BEGIN
IDS_EDIT, "&Edit"
IDS_DEFAULT, "&Default"
IDS_PROPERTY, "&Property"
IDS_MARK, "&Mark"
IDS_COPY, "&Copy"
IDS_PASTE, "&Paste"
IDS_SELECTALL, "&Select all"
IDS_SCROLL, "Sc&roll"
IDS_SEARCH, "S&earch"
IDS_FNT_DISPLAY, "Each character is %ld pixels wide on %ld pixels high"
IDS_FNT_PREVIEW_1, "This is a test"
IDS_FNT_PREVIEW_2, ""
END
IDD_OPTION DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 140, 105 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION " Options "
FONT 8, "Helv"
{
GROUPBOX "Cursor size", -1, 10, 11, 120, 44, BS_GROUPBOX
AUTORADIOBUTTON "&Small", IDC_OPT_CURSOR_SMALL, 14, 23, 84, 10, WS_TABSTOP
AUTORADIOBUTTON "&Medium", IDC_OPT_CURSOR_MEDIUM, 14, 33, 84, 10, WS_TABSTOP
AUTORADIOBUTTON "&Large", IDC_OPT_CURSOR_LARGE, 14, 43, 84, 10, WS_TABSTOP
GROUPBOX "Command history", -1, 10, 57, 180, 35, BS_GROUPBOX
LTEXT "&Numbers of recalled commands :", -1, 14, 67, 78, 18
EDITTEXT IDC_OPT_HIST_SIZE, 92, 69, 31, 12, WS_TABSTOP|WS_BORDER|ES_NUMBER
CONTROL "", IDC_OPT_HIST_SIZE_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
AUTOCHECKBOX "&Remove doubles", IDC_OPT_HIST_DOUBLE, 130, 67, 50, 18, WS_TABSTOP|BS_MULTILINE
}
IDD_FONT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 140, 105 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION " Font "
FONT 8, "Helv"
{
LTEXT "&Font", -1, 5, 5, 24, 8
LISTBOX IDC_FNT_LIST_FONT, 5,18,109,42, LBS_SORT|WS_VSCROLL
LTEXT "&Size", -1, 128, 5, 60, 8
LISTBOX IDC_FNT_LIST_SIZE, 128, 18, 50, 60, WS_VSCROLL
CONTROL "", IDC_FNT_PREVIEW, "WineConFontPreview", 0L, 5,60,109,40
LTEXT "", IDC_FNT_FONT_INFO, 128, 76, 80, 18
}
IDD_CONFIG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 140, 105 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION " Configuration "
FONT 8, "Helv"
{
GROUPBOX "Buffer zone", -1, 10, 11, 110, 42, BS_GROUPBOX
LTEXT "&Width :", -1, 14, 25, 54, 9
EDITTEXT IDC_CNF_SB_WIDTH, 78, 23, 36, 12, WS_TABSTOP|WS_BORDER|ES_NUMBER
CONTROL "", IDC_CNF_SB_WIDTH_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
LTEXT "&Height :", -1, 14, 39, 54, 9
EDITTEXT IDC_CNF_SB_HEIGHT, 78, 37, 36, 12, WS_TABSTOP|WS_BORDER|ES_NUMBER
CONTROL "", IDC_CNF_SB_HEIGHT_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
GROUPBOX "Window size", -1, 10, 55, 110, 42
LTEXT "W&idth :", -1, 14, 69, 54, 9
EDITTEXT IDC_CNF_WIN_WIDTH, 78, 67, 36, 12, WS_TABSTOP|WS_BORDER|ES_NUMBER
CONTROL "", IDC_CNF_WIN_WIDTH_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
LTEXT "H&eight :", -1, 14, 83, 54, 9
EDITTEXT IDC_CNF_WIN_HEIGHT, 78, 81, 36, 12, WS_TABSTOP|WS_BORDER|ES_NUMBER
CONTROL "", IDC_CNF_WIN_HEIGHT_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
}
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
STRINGTABLE LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
BEGIN
IDS_EDIT, "&Editer"
IDS_DEFAULT, "Par &dfaut"
IDS_PROPERTY, "&Proprits"
IDS_MARK, "&Marquer"
IDS_COPY, "&Copier"
IDS_PASTE, "C&oller"
IDS_SELECTALL, "&Slectionner tout"
IDS_SCROLL, "&Dfiler"
IDS_SEARCH, "C&hercher"
IDS_FNT_DISPLAY, "Chaque caractre a %ld points en largeur et %ld points en hauteur"
IDS_FNT_PREVIEW_1, "Ceci est un test"
IDS_FNT_PREVIEW_2, ""
END
IDD_OPTION DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 140, 105 LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION " Options "
FONT 8, "Helv"
{
GROUPBOX "Taille du curseur", -1, 10, 11, 120, 44, BS_GROUPBOX
AUTORADIOBUTTON "&Petit", IDC_OPT_CURSOR_SMALL, 14, 23, 84, 10, WS_TABSTOP
AUTORADIOBUTTON "&Moyen", IDC_OPT_CURSOR_MEDIUM, 14, 33, 84, 10, WS_TABSTOP
AUTORADIOBUTTON "&Grand", IDC_OPT_CURSOR_LARGE, 14, 43, 84, 10, WS_TABSTOP
GROUPBOX "Historique des commandes", -1, 10, 57, 180, 35, BS_GROUPBOX
LTEXT "&Taille de la mmoire tampon :", -1, 14, 67, 78, 18
EDITTEXT IDC_OPT_HIST_SIZE, 92, 69, 31, 12, WS_TABSTOP|WS_BORDER|ES_NUMBER
CONTROL "", IDC_OPT_HIST_SIZE_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
AUTOCHECKBOX "&Supprimer les doublons", IDC_OPT_HIST_DOUBLE, 130, 67, 50, 18, WS_TABSTOP|BS_MULTILINE
}
IDD_FONT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 140, 105 LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION " Police "
FONT 8, "Helv"
{
LTEXT "&Police", -1, 5, 5, 24, 8
LISTBOX IDC_FNT_LIST_FONT, 5, 18, 109, 42, LBS_SORT|WS_VSCROLL
LTEXT "&Taille", -1, 128, 5, 60, 8
LISTBOX IDC_FNT_LIST_SIZE, 128, 18, 50, 60, WS_VSCROLL
CONTROL "", IDC_FNT_PREVIEW, "WineConFontPreview", 0L, 5, 60, 109, 40
LTEXT "", IDC_FNT_FONT_INFO, 128, 76, 80, 18
}
IDD_CONFIG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 140, 105 LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION " Configuration "
FONT 8, "Helv"
{
GROUPBOX "Taille mmoire tampon cran", -1, 10, 11, 110, 42, BS_GROUPBOX
LTEXT "&Largeur :", -1, 14, 25, 54, 9
EDITTEXT IDC_CNF_SB_WIDTH, 78, 23, 36, 12, WS_TABSTOP|WS_BORDER|ES_NUMBER
CONTROL "", IDC_CNF_SB_WIDTH_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
LTEXT "Ha&uteur :", -1, 14, 39, 54, 9
EDITTEXT IDC_CNF_SB_HEIGHT, 78, 37, 36, 12, WS_TABSTOP|WS_BORDER|ES_NUMBER
CONTROL "", IDC_CNF_SB_HEIGHT_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
GROUPBOX "Taille de la fentre", -1, 10, 55, 110, 42
LTEXT "La&rgeur :", -1, 14, 69, 54, 9
EDITTEXT IDC_CNF_WIN_WIDTH, 78, 67, 36, 12, WS_TABSTOP|WS_BORDER|ES_NUMBER
CONTROL "", IDC_CNF_WIN_WIDTH_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
LTEXT "Hau&teur :", -1, 14, 83, 54, 9
EDITTEXT IDC_CNF_WIN_HEIGHT, 78, 81, 36, 12, WS_TABSTOP|WS_BORDER|ES_NUMBER
CONTROL "", IDC_CNF_WIN_HEIGHT_UD, "msctls_updown32", UDS_SETBUDDYINT|UDS_ALIGNRIGHT|UDS_AUTOBUDDY|UDS_ARROWKEYS|UDS_NOTHOUSANDS, 0, 0, 0, 0
}
/* wineconsole resource definitions */
/* strings */
#define IDS_EDIT 0x100
#define IDS_DEFAULT 0x101
#define IDS_PROPERTY 0x102
#define IDS_MARK 0x110
#define IDS_COPY 0x111
#define IDS_PASTE 0x112
#define IDS_SELECTALL 0x113
#define IDS_SCROLL 0x114
#define IDS_SEARCH 0x115
#define IDS_FNT_DISPLAY 0x200
#define IDS_FNT_PREVIEW_1 0x201
#define IDS_FNT_PREVIEW_2 0x202
#define IDD_OPTION 0x0100
#define IDD_FONT 0x0200
#define IDD_CONFIG 0x0300
/* dialog boxes */
#define IDC_OPT_CURSOR_SMALL 0x0101
#define IDC_OPT_CURSOR_MEDIUM 0x0102
#define IDC_OPT_CURSOR_LARGE 0x0103
#define IDC_OPT_HIST_SIZE 0x0104
#define IDC_OPT_HIST_SIZE_UD 0x0105
#define IDC_OPT_HIST_DOUBLE 0x0106
#define IDC_FNT_LIST_FONT 0x0201
#define IDC_FNT_LIST_SIZE 0x0202
#define IDC_FNT_FONT_INFO 0x0203
#define IDC_FNT_PREVIEW 0x0204
#define IDC_CNF_SB_WIDTH 0x0301
#define IDC_CNF_SB_WIDTH_UD 0x0302
#define IDC_CNF_SB_HEIGHT 0x0303
#define IDC_CNF_SB_HEIGHT_UD 0x0304
#define IDC_CNF_WIN_WIDTH 0x0305
#define IDC_CNF_WIN_WIDTH_UD 0x0306
#define IDC_CNF_WIN_HEIGHT 0x0307
#define IDC_CNF_WIN_HEIGHT_UD 0x0308
#include "windef.h"
#include "winuser.h"
#include "winnls.h"
#include "commctrl.h"
#include "wineconsole_res.h"
#include "wineconsole_En.rc"
#include "wineconsole_Fr.rc"
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "file.h" #include "file.h"
#include "thread.h" #include "thread.h"
#include "winerror.h" #include "winerror.h"
#include "wincon.h"
#include "wine/server.h" #include "wine/server.h"
#include "options.h" #include "options.h"
#include "callback.h" #include "callback.h"
...@@ -216,29 +217,6 @@ void PROCESS_CallUserSignalProc( UINT uCode, HMODULE16 hModule ) ...@@ -216,29 +217,6 @@ void PROCESS_CallUserSignalProc( UINT uCode, HMODULE16 hModule )
Callout.UserSignalProc( uCode, GetCurrentProcessId(), dwFlags, hModule ); Callout.UserSignalProc( uCode, GetCurrentProcessId(), dwFlags, hModule );
} }
/***********************************************************************
* set_console_handles
*
* Set the console handles to use stdin/stdout.
*/
static void set_console_handles( HANDLE console )
{
wine_server_send_fd( 0 );
wine_server_send_fd( 1 );
SERVER_START_REQ( set_console_fd )
{
req->handle = console;
req->fd_in = 0;
req->fd_out = 1;
req->pid = 0;
SERVER_CALL();
}
SERVER_END_REQ;
}
/*********************************************************************** /***********************************************************************
* process_init * process_init
* *
...@@ -287,14 +265,27 @@ static BOOL process_init( char *argv[] ) ...@@ -287,14 +265,27 @@ static BOOL process_init( char *argv[] )
SERVER_END_VAR_REQ; SERVER_END_VAR_REQ;
if (!ret) return FALSE; if (!ret) return FALSE;
/* Create the process heap */
current_process.heap = HeapCreate( HEAP_GROWABLE, 0, 0 );
if (create_flags == 0 &&
current_startupinfo.hStdInput == 0 &&
current_startupinfo.hStdOutput == 0 &&
current_startupinfo.hStdError == 0)
{
/* no parent, and no new console requested, create a simple console with bare handles to
* unix stdio input & output streams (aka simple console)
*/
SetStdHandle( STD_INPUT_HANDLE, FILE_DupUnixHandle( 0, GENERIC_READ, TRUE ));
SetStdHandle( STD_OUTPUT_HANDLE, FILE_DupUnixHandle( 1, GENERIC_WRITE, TRUE ));
SetStdHandle( STD_ERROR_HANDLE, FILE_DupUnixHandle( 1, GENERIC_WRITE, TRUE ));
}
else if (!(create_flags & (DETACHED_PROCESS|CREATE_NEW_CONSOLE)))
{
SetStdHandle( STD_INPUT_HANDLE, current_startupinfo.hStdInput ); SetStdHandle( STD_INPUT_HANDLE, current_startupinfo.hStdInput );
SetStdHandle( STD_OUTPUT_HANDLE, current_startupinfo.hStdOutput ); SetStdHandle( STD_OUTPUT_HANDLE, current_startupinfo.hStdOutput );
SetStdHandle( STD_ERROR_HANDLE, current_startupinfo.hStdError ); SetStdHandle( STD_ERROR_HANDLE, current_startupinfo.hStdError );
if (create_flags & CREATE_NEW_CONSOLE) }
set_console_handles( current_startupinfo.hStdOutput );
/* Create the process heap */
current_process.heap = HeapCreate( HEAP_GROWABLE, 0, 0 );
/* Now we can use the pthreads routines */ /* Now we can use the pthreads routines */
PTHREAD_init_done(); PTHREAD_init_done();
...@@ -305,7 +296,11 @@ static BOOL process_init( char *argv[] ) ...@@ -305,7 +296,11 @@ static BOOL process_init( char *argv[] )
/* Parse command line arguments */ /* Parse command line arguments */
OPTIONS_ParseOptions( argv ); OPTIONS_ParseOptions( argv );
return MAIN_MainInit(); ret = MAIN_MainInit();
if (create_flags & CREATE_NEW_CONSOLE)
AllocConsole();
return ret;
} }
......
/*
* Wine server consoles
*
* Copyright (C) 2001 Eric Pouech
*/
#ifndef __WINE_SERVER_CONSOLE_H
#define __WINE_SERVER_CONSOLE_H
struct screen_buffer;
struct console_input_events;
struct console_input
{
struct object obj; /* object header */
int num_proc; /* number of processes attached to this console */
struct process *renderer; /* console renderer thread */
int mode; /* input mode */
struct screen_buffer *active; /* active screen buffer */
int recnum; /* number of input records */
void *records; /* input records */
struct console_input_events *evt; /* synchronization event with renderer */
WCHAR *title; /* console title */
WCHAR **history; /* lines history */
int history_size; /* number of entries in history array */
int history_index; /* number of used entries in history array */
int history_mode; /* mode of history (non zero means remove doubled strings */
};
/* console functions */
extern void inherit_console(struct process *parent, struct process *process, handle_t hconin);
extern int free_console( struct process *process );
#endif /* __WINE_SERVER_CONSOLE_H */
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "process.h" #include "process.h"
#include "thread.h" #include "thread.h"
#include "request.h" #include "request.h"
#include "console.h"
enum debug_event_state { EVENT_QUEUED, EVENT_SENT, EVENT_CONTINUED }; enum debug_event_state { EVENT_QUEUED, EVENT_SENT, EVENT_CONTINUED };
...@@ -411,6 +412,11 @@ static int debugger_attach( struct process *process, struct thread *debugger ) ...@@ -411,6 +412,11 @@ static int debugger_attach( struct process *process, struct thread *debugger )
for (thread = debugger; thread; thread = thread->process->debugger) for (thread = debugger; thread; thread = thread->process->debugger)
if (thread->process == process) goto error; if (thread->process == process) goto error;
/* don't let a debugger debug its console... won't work */
if (debugger->process->console &&
debugger->process->console->renderer == process &&
process->console) goto error;
suspend_process( process ); suspend_process( process );
/* we must have been able to attach all threads */ /* we must have been able to attach all threads */
......
...@@ -494,7 +494,7 @@ DECL_HANDLER(alloc_file_handle) ...@@ -494,7 +494,7 @@ DECL_HANDLER(alloc_file_handle)
if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE, if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE,
0, DRIVE_UNKNOWN ))) 0, DRIVE_UNKNOWN )))
{ {
req->handle = alloc_handle( current->process, file, req->access, 0 ); req->handle = alloc_handle( current->process, file, req->access, req->inherit );
release_object( file ); release_object( file );
} }
} }
......
...@@ -355,6 +355,7 @@ struct object *get_handle_obj( struct process *process, handle_t handle, ...@@ -355,6 +355,7 @@ struct object *get_handle_obj( struct process *process, handle_t handle,
if (!(entry = get_handle( process, handle ))) return NULL; if (!(entry = get_handle( process, handle ))) return NULL;
if ((entry->access & access) != access) if ((entry->access & access) != access)
{ {
fprintf( stderr, "handle %d access %08x denied (%08x)\n", handle, access, entry->access );
set_error( STATUS_ACCESS_DENIED ); set_error( STATUS_ACCESS_DENIED );
return NULL; return NULL;
} }
...@@ -376,6 +377,7 @@ int get_handle_fd( struct process *process, handle_t handle, unsigned int access ...@@ -376,6 +377,7 @@ int get_handle_fd( struct process *process, handle_t handle, unsigned int access
if (!(entry = get_handle( process, handle ))) return -1; if (!(entry = get_handle( process, handle ))) return -1;
if ((entry->access & access) != access) if ((entry->access & access) != access)
{ {
fprintf( stderr, "handle %d access %08x denied (%08x)\n", handle, access, entry->access );
set_error( STATUS_ACCESS_DENIED ); set_error( STATUS_ACCESS_DENIED );
return -1; return -1;
} }
......
...@@ -155,11 +155,6 @@ extern void file_set_error(void); ...@@ -155,11 +155,6 @@ extern void file_set_error(void);
int get_serial_async_timeout(struct object *obj, int type, int count); int get_serial_async_timeout(struct object *obj, int type, int count);
/* console functions */
extern int alloc_console( struct process *process );
extern int free_console( struct process *process );
/* debugger functions */ /* debugger functions */
extern int set_process_debugger( struct process *process, struct thread *debugger ); extern int set_process_debugger( struct process *process, struct thread *debugger );
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "process.h" #include "process.h"
#include "thread.h" #include "thread.h"
#include "request.h" #include "request.h"
#include "console.h"
/* process structure */ /* process structure */
...@@ -101,12 +102,18 @@ static int set_process_console( struct process *process, struct process *parent, ...@@ -101,12 +102,18 @@ static int set_process_console( struct process *process, struct process *parent,
{ {
if (process->create_flags & CREATE_NEW_CONSOLE) if (process->create_flags & CREATE_NEW_CONSOLE)
{ {
if (!alloc_console( process )) return 0; /* let the process init do the allocation */
return 1;
} }
else if (parent && !(process->create_flags & DETACHED_PROCESS)) else if (parent && !(process->create_flags & DETACHED_PROCESS))
{ {
if (parent->console_in) process->console_in = grab_object( parent->console_in ); /* FIXME: some better error checking should be done...
if (parent->console_out) process->console_out = grab_object( parent->console_out ); * like if hConOut and hConIn are console handles, then they should be on the same
* physical console
*/
inherit_console( parent, process,
(info->inherit_all || (info->start_flags & STARTF_USESTDHANDLES)) ?
info->hstdin : 0 );
} }
if (parent) if (parent)
{ {
...@@ -129,13 +136,20 @@ static int set_process_console( struct process *process, struct process *parent, ...@@ -129,13 +136,20 @@ static int set_process_console( struct process *process, struct process *parent,
} }
else else
{ {
/* no parent, use handles to the console for stdio */ if (process->console)
req->hstdin = alloc_handle( process, process->console_in, {
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 ); req->hstdin = alloc_handle( process, process->console,
req->hstdout = alloc_handle( process, process->console_out,
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
req->hstderr = alloc_handle( process, process->console_out,
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 ); GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
req->hstdout = alloc_handle( process, process->console->active,
GENERIC_READ | GENERIC_WRITE, 1 );
req->hstderr = alloc_handle( process, process->console->active,
GENERIC_READ | GENERIC_WRITE, 1 );
}
else
{
/* no parent, let the caller decide what to do */
req->hstdin = req->hstdout = req->hstderr = 0;
}
} }
/* some handles above may have been invalid; this is not an error */ /* some handles above may have been invalid; this is not an error */
if (get_error() == STATUS_INVALID_HANDLE) clear_error(); if (get_error() == STATUS_INVALID_HANDLE) clear_error();
...@@ -152,6 +166,7 @@ struct thread *create_process( int fd ) ...@@ -152,6 +166,7 @@ struct thread *create_process( int fd )
if (!(process = alloc_object( &process_ops, fd ))) return NULL; if (!(process = alloc_object( &process_ops, fd ))) return NULL;
process->next = NULL; process->next = NULL;
process->prev = NULL; process->prev = NULL;
process->parent = NULL;
process->thread_list = NULL; process->thread_list = NULL;
process->debugger = NULL; process->debugger = NULL;
process->handles = NULL; process->handles = NULL;
...@@ -161,8 +176,7 @@ struct thread *create_process( int fd ) ...@@ -161,8 +176,7 @@ struct thread *create_process( int fd )
process->affinity = 1; process->affinity = 1;
process->suspend = 0; process->suspend = 0;
process->create_flags = 0; process->create_flags = 0;
process->console_in = NULL; process->console = NULL;
process->console_out = NULL;
process->init_event = NULL; process->init_event = NULL;
process->idle_event = NULL; process->idle_event = NULL;
process->queue = NULL; process->queue = NULL;
...@@ -173,6 +187,7 @@ struct thread *create_process( int fd ) ...@@ -173,6 +187,7 @@ struct thread *create_process( int fd )
process->exe.file = NULL; process->exe.file = NULL;
process->exe.dbg_offset = 0; process->exe.dbg_offset = 0;
process->exe.dbg_size = 0; process->exe.dbg_size = 0;
gettimeofday( &process->start_time, NULL ); gettimeofday( &process->start_time, NULL );
if ((process->next = first_process) != NULL) process->next->prev = process; if ((process->next = first_process) != NULL) process->next->prev = process;
first_process = process; first_process = process;
...@@ -222,10 +237,11 @@ static void init_process( int ppid, struct init_process_request *req ) ...@@ -222,10 +237,11 @@ static void init_process( int ppid, struct init_process_request *req )
fatal_protocol_error( current, "init_process: called twice?\n" ); fatal_protocol_error( current, "init_process: called twice?\n" );
return; return;
} }
process->parent = (struct process *)grab_object( parent );
} }
/* set the process flags */ /* set the process flags */
process->create_flags = info ? info->create_flags : CREATE_NEW_CONSOLE; process->create_flags = info ? info->create_flags : 0;
/* create the handle table */ /* create the handle table */
if (parent && info->inherit_all) if (parent && info->inherit_all)
...@@ -288,6 +304,8 @@ static void process_destroy( struct object *obj ) ...@@ -288,6 +304,8 @@ static void process_destroy( struct object *obj )
/* we can't have a thread remaining */ /* we can't have a thread remaining */
assert( !process->thread_list ); assert( !process->thread_list );
if (process->console) release_object( process->console );
if (process->parent) release_object( process->parent );
if (process->next) process->next->prev = process->prev; if (process->next) process->next->prev = process->prev;
if (process->prev) process->prev->next = process->next; if (process->prev) process->prev->next = process->next;
else first_process = process->next; else first_process = process->next;
...@@ -304,9 +322,8 @@ static void process_dump( struct object *obj, int verbose ) ...@@ -304,9 +322,8 @@ static void process_dump( struct object *obj, int verbose )
struct process *process = (struct process *)obj; struct process *process = (struct process *)obj;
assert( obj->ops == &process_ops ); assert( obj->ops == &process_ops );
fprintf( stderr, "Process next=%p prev=%p console=%p/%p handles=%p\n", fprintf( stderr, "Process next=%p prev=%p handles=%p\n",
process->next, process->prev, process->console_in, process->console_out, process->next, process->prev, process->handles );
process->handles );
} }
static int process_signaled( struct object *obj, struct thread *thread ) static int process_signaled( struct object *obj, struct thread *thread )
...@@ -418,6 +435,25 @@ static void process_unload_dll( struct process *process, void *base ) ...@@ -418,6 +435,25 @@ static void process_unload_dll( struct process *process, void *base )
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
} }
/* kill all processes being attached to a console renderer */
static void kill_console_processes( struct process *renderer, int exit_code )
{
for (;;) /* restart from the beginning of the list every time */
{
struct process *process = first_process;
/* find the first process being attached to 'renderer' and still running */
while (process &&
(process == renderer || !process->console ||
process->console->renderer != renderer || !process->running_threads))
{
process = process->next;
}
if (!process) break;
kill_process( process, NULL, exit_code );
}
}
/* a process has been killed (i.e. its last thread died) */ /* a process has been killed (i.e. its last thread died) */
static void process_killed( struct process *process ) static void process_killed( struct process *process )
{ {
...@@ -425,7 +461,13 @@ static void process_killed( struct process *process ) ...@@ -425,7 +461,13 @@ static void process_killed( struct process *process )
gettimeofday( &process->end_time, NULL ); gettimeofday( &process->end_time, NULL );
if (process->handles) release_object( process->handles ); if (process->handles) release_object( process->handles );
process->handles = NULL; process->handles = NULL;
/* close the console attached to this process, if any */
free_console( process ); free_console( process );
/* close the processes using process as renderer, if any */
kill_console_processes( process, 0 );
while (process->exe.next) while (process->exe.next)
{ {
struct process_dll *dll = process->exe.next; struct process_dll *dll = process->exe.next;
...@@ -508,6 +550,7 @@ void resume_process( struct process *process ) ...@@ -508,6 +550,7 @@ void resume_process( struct process *process )
void kill_process( struct process *process, struct thread *skip, int exit_code ) void kill_process( struct process *process, struct thread *skip, int exit_code )
{ {
struct thread *thread = process->thread_list; struct thread *thread = process->thread_list;
while (thread) while (thread)
{ {
struct thread *next = thread->proc_next; struct thread *next = thread->proc_next;
...@@ -532,6 +575,7 @@ void kill_debugged_processes( struct thread *debugger, int exit_code ) ...@@ -532,6 +575,7 @@ void kill_debugged_processes( struct thread *debugger, int exit_code )
} }
} }
/* get all information about a process */ /* get all information about a process */
static void get_process_info( struct process *process, struct get_process_info_request *req ) static void get_process_info( struct process *process, struct get_process_info_request *req )
{ {
......
...@@ -30,6 +30,7 @@ struct process ...@@ -30,6 +30,7 @@ struct process
struct object obj; /* object header */ struct object obj; /* object header */
struct process *next; /* system-wide process list */ struct process *next; /* system-wide process list */
struct process *prev; struct process *prev;
struct process *parent; /* parent process */
struct thread *thread_list; /* head of the thread list */ struct thread *thread_list; /* head of the thread list */
struct thread *debugger; /* thread debugging this process */ struct thread *debugger; /* thread debugging this process */
struct object *handles; /* handle entries */ struct object *handles; /* handle entries */
...@@ -41,8 +42,7 @@ struct process ...@@ -41,8 +42,7 @@ struct process
int affinity; /* process affinity mask */ int affinity; /* process affinity mask */
int suspend; /* global process suspend count */ int suspend; /* global process suspend count */
int create_flags; /* process creation flags */ int create_flags; /* process creation flags */
struct object *console_in; /* console input */ struct console_input*console; /* console input */
struct object *console_out; /* console output */
struct event *init_event; /* event for init done */ struct event *init_event; /* event for init done */
struct event *idle_event; /* event for input idle */ struct event *idle_event; /* event for input idle */
struct msg_queue *queue; /* main message queue */ struct msg_queue *queue; /* main message queue */
...@@ -55,7 +55,6 @@ struct process ...@@ -55,7 +55,6 @@ struct process
struct process_snapshot struct process_snapshot
{ {
struct process *process; /* process ptr */ struct process *process; /* process ptr */
struct process *parent; /* process parent */
int count; /* process refcount */ int count; /* process refcount */
int threads; /* number of threads */ int threads; /* number of threads */
int priority; /* priority class */ int priority; /* priority class */
......
...@@ -118,14 +118,22 @@ DECL_HANDLER(get_socket_event); ...@@ -118,14 +118,22 @@ DECL_HANDLER(get_socket_event);
DECL_HANDLER(enable_socket_event); DECL_HANDLER(enable_socket_event);
DECL_HANDLER(alloc_console); DECL_HANDLER(alloc_console);
DECL_HANDLER(free_console); DECL_HANDLER(free_console);
DECL_HANDLER(get_console_renderer_events);
DECL_HANDLER(open_console); DECL_HANDLER(open_console);
DECL_HANDLER(set_console_fd);
DECL_HANDLER(get_console_mode); DECL_HANDLER(get_console_mode);
DECL_HANDLER(set_console_mode); DECL_HANDLER(set_console_mode);
DECL_HANDLER(set_console_info); DECL_HANDLER(set_console_input_info);
DECL_HANDLER(get_console_info); DECL_HANDLER(get_console_input_info);
DECL_HANDLER(append_console_input_history);
DECL_HANDLER(get_console_input_history);
DECL_HANDLER(create_console_output);
DECL_HANDLER(set_console_output_info);
DECL_HANDLER(get_console_output_info);
DECL_HANDLER(write_console_input); DECL_HANDLER(write_console_input);
DECL_HANDLER(read_console_input); DECL_HANDLER(read_console_input);
DECL_HANDLER(write_console_output);
DECL_HANDLER(read_console_output);
DECL_HANDLER(move_console_output);
DECL_HANDLER(create_change_notification); DECL_HANDLER(create_change_notification);
DECL_HANDLER(create_mapping); DECL_HANDLER(create_mapping);
DECL_HANDLER(open_mapping); DECL_HANDLER(open_mapping);
...@@ -264,14 +272,22 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -264,14 +272,22 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_enable_socket_event, (req_handler)req_enable_socket_event,
(req_handler)req_alloc_console, (req_handler)req_alloc_console,
(req_handler)req_free_console, (req_handler)req_free_console,
(req_handler)req_get_console_renderer_events,
(req_handler)req_open_console, (req_handler)req_open_console,
(req_handler)req_set_console_fd,
(req_handler)req_get_console_mode, (req_handler)req_get_console_mode,
(req_handler)req_set_console_mode, (req_handler)req_set_console_mode,
(req_handler)req_set_console_info, (req_handler)req_set_console_input_info,
(req_handler)req_get_console_info, (req_handler)req_get_console_input_info,
(req_handler)req_append_console_input_history,
(req_handler)req_get_console_input_history,
(req_handler)req_create_console_output,
(req_handler)req_set_console_output_info,
(req_handler)req_get_console_output_info,
(req_handler)req_write_console_input, (req_handler)req_write_console_input,
(req_handler)req_read_console_input, (req_handler)req_read_console_input,
(req_handler)req_write_console_output,
(req_handler)req_read_console_output,
(req_handler)req_move_console_output,
(req_handler)req_create_change_notification, (req_handler)req_create_change_notification,
(req_handler)req_create_mapping, (req_handler)req_create_mapping,
(req_handler)req_open_mapping, (req_handler)req_open_mapping,
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
%formats = %formats =
( (
"int" => "%d", "int" => "%d",
"short int" => "%d",
"char" => "%c", "char" => "%c",
"unsigned char" => "%02x", "unsigned char" => "%02x",
"unsigned short"=> "%04x", "unsigned short"=> "%04x",
......
DEFS = @DLLFLAGS@ -D__WINE__ DEFS = @DLLFLAGS@ -D__WINE__ -DBINDIR="\"$(bindir)\""
TOPSRCDIR = @top_srcdir@ TOPSRCDIR = @top_srcdir@
TOPOBJDIR = .. TOPOBJDIR = ..
SRCDIR = @srcdir@ SRCDIR = @srcdir@
...@@ -8,6 +8,7 @@ MODULE = win32 ...@@ -8,6 +8,7 @@ MODULE = win32
C_SRCS = \ C_SRCS = \
console.c \ console.c \
device.c \ device.c \
editline.c \
except.c \ except.c \
file.c \ file.c \
init.c \ init.c \
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment