2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis and Cameron Heide
5 * Copyright 1997 Karl Garrison
6 * Copyright 1998 John Richardson
7 * Copyright 1998 Marcus Meissner
11 * - Completely lacks SCREENBUFFER interface.
12 * - No abstraction for something other than xterm.
13 * - Key input translation shouldn't use VkKeyScan and MapVirtualKey, since
14 * they are window (USER) driver dependend.
15 * - Output sometimes is buffered (We switched off buffering by ~ICANON ?)
17 /* Reference applications:
18 * - IDA (interactive disassembler) full version 3.75. Works.
19 * - LYNX/W32. Works mostly, some keys crash it.
26 #include <sys/ioctl.h>
27 #include <sys/types.h>
32 #include <sys/errno.h>
47 /* The CONSOLE kernel32 Object */
48 typedef struct _CONSOLE
{
51 CONSOLE_CURSOR_INFO cinfo
;
53 int master
; /* xterm side of pty */
55 int pid
; /* xterm's pid, -1 if no xterm */
56 LPSTR title
; /* title of console */
57 INPUT_RECORD
*irs
; /* buffered input records */
58 int nrofirs
;/* nr of buffered input records */
59 THREAD_QUEUE wait_queue
;
62 static void CONSOLE_AddWait(K32OBJ
*ptr
, DWORD thread_id
);
63 static void CONSOLE_RemoveWait(K32OBJ
*ptr
, DWORD thread_id
);
64 static BOOL32
CONSOLE_Satisfied(K32OBJ
*ptr
, DWORD thread_id
);
65 static BOOL32
CONSOLE_Signaled(K32OBJ
*ptr
, DWORD thread_id
);
66 static void CONSOLE_Destroy( K32OBJ
*obj
);
67 static BOOL32
CONSOLE_Write(K32OBJ
*ptr
, LPCVOID lpBuffer
,
68 DWORD nNumberOfChars
, LPDWORD lpNumberOfChars
,
69 LPOVERLAPPED lpOverlapped
);
70 static BOOL32
CONSOLE_Read(K32OBJ
*ptr
, LPVOID lpBuffer
,
71 DWORD nNumberOfChars
, LPDWORD lpNumberOfChars
,
72 LPOVERLAPPED lpOverlapped
);
74 const K32OBJ_OPS CONSOLE_Ops
=
76 CONSOLE_Signaled
, /* signaled */
77 CONSOLE_Satisfied
, /* satisfied */
78 CONSOLE_AddWait
, /* add_wait */
79 CONSOLE_RemoveWait
, /* remove_wait */
80 CONSOLE_Read
, /* read */
81 CONSOLE_Write
, /* write */
82 CONSOLE_Destroy
/* destroy */
85 /***********************************************************************
88 static void CONSOLE_Destroy(K32OBJ
*obj
)
90 CONSOLE
*console
= (CONSOLE
*)obj
;
91 assert(obj
->type
== K32OBJ_CONSOLE
);
93 obj
->type
= K32OBJ_UNKNOWN
;
96 HeapFree( SystemHeap
, 0, console
->title
);
97 console
->title
= NULL
;
98 /* if there is a xterm, kill it. */
99 if (console
->pid
!= -1)
100 kill(console
->pid
, SIGTERM
);
101 HeapFree(SystemHeap
, 0, console
);
105 /***********************************************************************
109 * lpOverlapped is ignored
111 static BOOL32
CONSOLE_Read(K32OBJ
*ptr
, LPVOID lpBuffer
, DWORD nNumberOfChars
,
112 LPDWORD lpNumberOfChars
, LPOVERLAPPED lpOverlapped
)
114 CONSOLE
*console
= (CONSOLE
*)ptr
;
117 TRACE(console
, "%p %p %ld\n", ptr
, lpBuffer
, nNumberOfChars
);
118 *lpNumberOfChars
= 0;
119 if ((result
= read(console
->infd
, lpBuffer
, nNumberOfChars
)) == -1) {
123 *lpNumberOfChars
= result
;
128 /***********************************************************************
132 * lpOverlapped is ignored
134 static BOOL32
CONSOLE_Write(K32OBJ
*ptr
, LPCVOID lpBuffer
,
135 DWORD nNumberOfChars
,
136 LPDWORD lpNumberOfChars
, LPOVERLAPPED lpOverlapped
)
138 CONSOLE
*console
= (CONSOLE
*)ptr
;
141 TRACE(console
, "%p %p %ld\n", ptr
, lpBuffer
, nNumberOfChars
);
142 *lpNumberOfChars
= 0;
144 * I assume this loop around EAGAIN is here because
145 * win32 doesn't have interrupted system calls
150 result
= write(console
->outfd
, lpBuffer
, nNumberOfChars
);
152 *lpNumberOfChars
= result
;
155 if (errno
!= EINTR
) {
162 /****************************************************************************
163 * CONSOLE_add_input_record [internal]
165 * Adds an INPUT_RECORD to the CONSOLEs input queue.
168 CONSOLE_add_input_record(CONSOLE
*console
,INPUT_RECORD
*inp
) {
169 console
->irs
= HeapReAlloc(GetProcessHeap(),0,console
->irs
,sizeof(INPUT_RECORD
)*(console
->nrofirs
+1));
170 console
->irs
[console
->nrofirs
++]=*inp
;
173 /****************************************************************************
174 * XTERM_string_to_IR [internal]
176 * Transfers a string read from XTERM to INPUT_RECORDs and adds them to the
177 * queue. Does translation of vt100 style function keys and xterm-mouse clicks.
180 CONSOLE_string_to_IR(CONSOLE
*console
,unsigned char *buf
,int len
) {
184 for (j
=0;j
<len
;j
++) {
185 unsigned char inchar
= buf
[j
];
187 if (inchar
!=27) { /* no escape -> 'normal' keyboard event */
188 ir
.EventType
= 1; /* Key_event */
190 ir
.Event
.KeyEvent
.bKeyDown
= 1;
191 ir
.Event
.KeyEvent
.wRepeatCount
= 0;
193 ir
.Event
.KeyEvent
.dwControlKeyState
= 0;
195 ir
.Event
.KeyEvent
.dwControlKeyState
|=LEFT_ALT_PRESSED
;
198 ir
.Event
.KeyEvent
.wVirtualKeyCode
= VkKeyScan16(inchar
);
199 if (ir
.Event
.KeyEvent
.wVirtualKeyCode
& 0x0100)
200 ir
.Event
.KeyEvent
.dwControlKeyState
|=SHIFT_PRESSED
;
201 if (ir
.Event
.KeyEvent
.wVirtualKeyCode
& 0x0200)
202 ir
.Event
.KeyEvent
.dwControlKeyState
|=LEFT_CTRL_PRESSED
;
203 if (ir
.Event
.KeyEvent
.wVirtualKeyCode
& 0x0400)
204 ir
.Event
.KeyEvent
.dwControlKeyState
|=LEFT_ALT_PRESSED
;
205 ir
.Event
.KeyEvent
.wVirtualScanCode
= MapVirtualKey16(
206 ir
.Event
.KeyEvent
.wVirtualKeyCode
& 0x00ff,
207 0 /* VirtualKeyCodes to ScanCode */
210 ir
.Event
.KeyEvent
.uChar
.AsciiChar
= '\r';
211 ir
.Event
.KeyEvent
.wVirtualKeyCode
= 0x0d;
212 ir
.Event
.KeyEvent
.wVirtualScanCode
= 0x1c;
214 ir
.Event
.KeyEvent
.uChar
.AsciiChar
= inchar
;
216 /* FIXME: find good values for ^X */
217 ir
.Event
.KeyEvent
.wVirtualKeyCode
= 0xdead;
218 ir
.Event
.KeyEvent
.wVirtualScanCode
= 0xbeef;
222 CONSOLE_add_input_record(console
,&ir
);
223 ir
.Event
.KeyEvent
.bKeyDown
= 0;
224 CONSOLE_add_input_record(console
,&ir
);
228 if ((j
==len
-1) || (buf
[j
+1]!='[')) {/* add ESCape on its own */
229 ir
.EventType
= 1; /* Key_event */
230 ir
.Event
.KeyEvent
.bKeyDown
= 1;
231 ir
.Event
.KeyEvent
.wRepeatCount
= 0;
233 ir
.Event
.KeyEvent
.wVirtualKeyCode
= VkKeyScan16(27);
234 ir
.Event
.KeyEvent
.wVirtualScanCode
= MapVirtualKey16(
235 ir
.Event
.KeyEvent
.wVirtualKeyCode
,0
237 ir
.Event
.KeyEvent
.dwControlKeyState
= 0;
238 ir
.Event
.KeyEvent
.uChar
.AsciiChar
= 27;
239 CONSOLE_add_input_record(console
,&ir
);
240 ir
.Event
.KeyEvent
.bKeyDown
= 0;
241 CONSOLE_add_input_record(console
,&ir
);
244 for (k
=j
;k
<len
;k
++) {
245 if (((buf
[k
]>='A') && (buf
[k
]<='Z')) ||
246 ((buf
[k
]>='a') && (buf
[k
]<='z')) ||
252 int subid
,scancode
=0;
254 ir
.EventType
= 1; /* Key_event */
255 ir
.Event
.KeyEvent
.bKeyDown
= 1;
256 ir
.Event
.KeyEvent
.wRepeatCount
= 0;
257 ir
.Event
.KeyEvent
.dwControlKeyState
= 0;
259 ir
.Event
.KeyEvent
.wVirtualKeyCode
= 0xad; /* FIXME */
260 ir
.Event
.KeyEvent
.wVirtualScanCode
= 0xad; /* FIXME */
261 ir
.Event
.KeyEvent
.uChar
.AsciiChar
= 0;
265 sscanf(&buf
[j
+2],"%d",&subid
);
267 case 2:/*INS */scancode
= 0xe052;break;
268 case 3:/*DEL */scancode
= 0xe053;break;
269 case 6:/*PGDW*/scancode
= 0xe051;break;
270 case 5:/*PGUP*/scancode
= 0xe049;break;
271 case 11:/*F1 */scancode
= 0x003b;break;
272 case 12:/*F2 */scancode
= 0x003c;break;
273 case 13:/*F3 */scancode
= 0x003d;break;
274 case 14:/*F4 */scancode
= 0x003e;break;
275 case 15:/*F5 */scancode
= 0x003f;break;
276 case 17:/*F6 */scancode
= 0x0040;break;
277 case 18:/*F7 */scancode
= 0x0041;break;
278 case 19:/*F8 */scancode
= 0x0042;break;
279 case 20:/*F9 */scancode
= 0x0043;break;
280 case 21:/*F10 */scancode
= 0x0044;break;
281 case 23:/*F11 */scancode
= 0x00d9;break;
282 case 24:/*F12 */scancode
= 0x00da;break;
283 /* FIXME: Shift-Fx */
285 FIXME(console
,"parse ESC[%d~\n",subid
);
289 case 'A': /* Cursor Up */scancode
= 0xe048;break;
290 case 'B': /* Cursor Down */scancode
= 0xe050;break;
291 case 'D': /* Cursor Left */scancode
= 0xe04b;break;
292 case 'C': /* Cursor Right */scancode
= 0xe04d;break;
293 case 'F': /* End */scancode
= 0xe04f;break;
294 case 'H': /* Home */scancode
= 0xe047;break;
296 /* Mouse Button Press (ESCM<button+'!'><x+'!'><y+'!'>) or
297 * Release (ESCM#<x+'!'><y+'!'>
300 ir
.EventType
= MOUSE_EVENT
;
301 ir
.Event
.MouseEvent
.dwMousePosition
.x
= buf
[k
+2]-'!';
302 ir
.Event
.MouseEvent
.dwMousePosition
.y
= buf
[k
+3]-'!';
304 ir
.Event
.MouseEvent
.dwButtonState
= 0;
306 ir
.Event
.MouseEvent
.dwButtonState
= 1<<(buf
[k
+1]-' ');
307 ir
.Event
.MouseEvent
.dwEventFlags
= 0; /* FIXME */
308 CONSOLE_add_input_record(console
,&ir
);
315 ir
.Event
.KeyEvent
.wVirtualScanCode
= scancode
;
316 ir
.Event
.KeyEvent
.wVirtualKeyCode
= MapVirtualKey16(scancode
,1);
317 CONSOLE_add_input_record(console
,&ir
);
318 ir
.Event
.KeyEvent
.bKeyDown
= 0;
319 CONSOLE_add_input_record(console
,&ir
);
326 /****************************************************************************
327 * CONSOLE_get_input (internal)
329 * Reads (nonblocking) as much input events as possible and stores them
330 * in an internal queue.
331 * (not necessarily XTERM dependend, but UNIX filedescriptor...)
334 CONSOLE_get_input(CONSOLE
*console
) {
335 char *buf
= HeapAlloc(GetProcessHeap(),0,1);
345 FD_SET(console
->infd
,&infds
);
346 memset(&tv
,0,sizeof(tv
));
347 if (select(console
->infd
+1,&infds
,NULL
,NULL
,&tv
)<1)
348 break; /* no input there */
350 if (!FD_ISSET(console
->infd
,&infds
))
352 if (!CONSOLE_Read((K32OBJ
*)console
,&inchar
,1,&res
,NULL
))
354 buf
= HeapReAlloc(GetProcessHeap(),0,buf
,len
+1);
357 CONSOLE_string_to_IR(console
,buf
,len
);
358 HeapFree(GetProcessHeap(),0,buf
);
361 /****************************************************************************
362 * CONSOLE_drain_input (internal)
364 * Drains 'n' console input events from the queue.
367 CONSOLE_drain_input(CONSOLE
*console
,int n
) {
368 assert(n
<=console
->nrofirs
);
371 memcpy( &console
->irs
[0],
373 console
->nrofirs
*sizeof(INPUT_RECORD
)
375 console
->irs
= HeapReAlloc(
379 console
->nrofirs
*sizeof(INPUT_RECORD
)
384 /***********************************************************************
385 * CONSOLE_async_handler [internal]
388 CONSOLE_async_handler(int unixfd
,void *private) {
389 CONSOLE
*console
= (CONSOLE
*)private;
391 SYNC_WakeUp(&console
->wait_queue
,INFINITE32
);
394 /***********************************************************************
395 * CONSOLE_Signaled [internal]
397 * Checks if we can read something. (Hmm, what about writing ?)
400 CONSOLE_Signaled(K32OBJ
*ptr
,DWORD tid
) {
401 CONSOLE
*console
=(CONSOLE
*)ptr
;
403 if (ptr
->type
!= K32OBJ_CONSOLE
)
405 CONSOLE_get_input(console
);
406 if (console
->nrofirs
!=0)
412 /***********************************************************************
413 * CONSOLE_AddWait [internal]
415 * Add thread to our waitqueue (so we can signal it if we have input).
417 static void CONSOLE_AddWait(K32OBJ
*ptr
, DWORD thread_id
)
419 CONSOLE
*console
= (CONSOLE
*)ptr
;
421 /* register our unix filedescriptors for async IO */
422 if (!console
->wait_queue
)
423 ASYNC_RegisterFD(console
->infd
,CONSOLE_async_handler
,console
);
424 THREAD_AddQueue( &console
->wait_queue
, THREAD_ID_TO_THDB(thread_id
) );
427 /***********************************************************************
428 * CONSOLE_RemoveWait [internal]
430 * Remove thread from our waitqueue.
432 static void CONSOLE_RemoveWait(K32OBJ
*ptr
, DWORD thread_id
)
434 CONSOLE
*console
= (CONSOLE
*)ptr
;
436 THREAD_RemoveQueue( &console
->wait_queue
, THREAD_ID_TO_THDB(thread_id
) );
437 if (!console
->wait_queue
)
438 ASYNC_UnregisterFD(console
->infd
,CONSOLE_async_handler
);
441 /***********************************************************************
442 * CONSOLE_Satisfied [internal]
444 * Condition from last Signaled is satisfied and will be used now.
446 static BOOL32
CONSOLE_Satisfied(K32OBJ
*ptr
, DWORD thread_id
)
452 /******************************************************************************
453 * SetConsoleCtrlHandler [KERNEL32.459] Adds function to calling process list
456 * func [I] Address of handler function
457 * add [I] Handler to add or remove
464 * James Sutherland (JamesSutherland@gmx.de)
465 * Added global variables console_ignore_ctrl_c and handlers[]
466 * Does not yet do any error checking, or set LastError if failed.
467 * This doesn't yet matter, since these handlers are not yet called...!
469 static unsigned int console_ignore_ctrl_c
= 0;
470 static HANDLER_ROUTINE
*handlers
[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
471 BOOL32 WINAPI
SetConsoleCtrlHandler( HANDLER_ROUTINE
*func
, BOOL32 add
)
473 unsigned int alloc_loop
= sizeof(handlers
)/sizeof(HANDLER_ROUTINE
*);
474 unsigned int done
= 0;
475 FIXME(console
, "(%p,%i) - no error checking or testing yet\n", func
, add
);
478 console_ignore_ctrl_c
= add
;
484 if (!handlers
[alloc_loop
] && !done
)
486 handlers
[alloc_loop
] = func
;
490 FIXME(console
, "Out of space on CtrlHandler table\n");
496 if (handlers
[alloc_loop
] == func
&& !done
)
498 handlers
[alloc_loop
] = 0;
502 WARN(console
, "Attempt to remove non-installed CtrlHandler %p\n",
510 /******************************************************************************
511 * GenerateConsoleCtrlEvent [KERNEL32.275] Simulate a CTRL-C or CTRL-BREAK
514 * dwCtrlEvent [I] Type of event
515 * dwProcessGroupID [I] Process group ID to send event to
518 * Doesn't yet work...!
522 * Failure: False (and *should* [but doesn't] set LastError)
524 BOOL32 WINAPI
GenerateConsoleCtrlEvent( DWORD dwCtrlEvent
,
525 DWORD dwProcessGroupID
)
527 if (dwCtrlEvent
!= CTRL_C_EVENT
&& dwCtrlEvent
!= CTRL_BREAK_EVENT
)
529 ERR( console
, "invalid event %d for PGID %ld\n",
530 (unsigned short)dwCtrlEvent
, dwProcessGroupID
);
533 if (dwProcessGroupID
== GetCurrentProcessId() )
535 FIXME( console
, "Attempt to send event %d to self - stub\n",
536 (unsigned short)dwCtrlEvent
);
539 FIXME( console
,"event %d to external PGID %ld - not implemented yet\n",
540 (unsigned short)dwCtrlEvent
, dwProcessGroupID
);
545 /******************************************************************************
546 * CreateConsoleScreenBuffer [KERNEL32.151] Creates a console screen buffer
549 * dwDesiredAccess [I] Access flag
550 * dwShareMode [I] Buffer share mode
551 * sa [I] Security attributes
552 * dwFlags [I] Type of buffer to create
553 * lpScreenBufferData [I] Reserved
556 * Should call SetLastError
559 * Success: Handle to new console screen buffer
560 * Failure: INVALID_HANDLE_VALUE
562 HANDLE32 WINAPI
CreateConsoleScreenBuffer( DWORD dwDesiredAccess
,
563 DWORD dwShareMode
, LPSECURITY_ATTRIBUTES sa
,
564 DWORD dwFlags
, LPVOID lpScreenBufferData
)
566 FIXME(console
, "(%ld,%ld,%p,%ld,%p): stub\n",dwDesiredAccess
,
567 dwShareMode
, sa
, dwFlags
, lpScreenBufferData
);
568 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
569 return INVALID_HANDLE_VALUE32
;
573 /***********************************************************************
574 * GetConsoleScreenBufferInfo (KERNEL32.190)
576 BOOL32 WINAPI
GetConsoleScreenBufferInfo( HANDLE32 hConsoleOutput
,
577 LPCONSOLE_SCREEN_BUFFER_INFO csbi
)
581 csbi
->dwCursorPosition
.x
= 0;
582 csbi
->dwCursorPosition
.y
= 0;
583 csbi
->wAttributes
= 0;
584 csbi
->srWindow
.Left
= 0;
585 csbi
->srWindow
.Right
= 79;
586 csbi
->srWindow
.Top
= 0;
587 csbi
->srWindow
.Bottom
= 23;
588 csbi
->dwMaximumWindowSize
.x
= 80;
589 csbi
->dwMaximumWindowSize
.y
= 24;
594 /******************************************************************************
595 * SetConsoleActiveScreenBuffer [KERNEL32.623] Sets buffer to current console
601 BOOL32 WINAPI
SetConsoleActiveScreenBuffer(
602 HANDLE32 hConsoleOutput
) /* [in] Handle to console screen buffer */
604 FIXME(console
, "(%x): stub\n", hConsoleOutput
);
609 /***********************************************************************
610 * GetLargestConsoleWindowSize (KERNEL32.226)
612 DWORD WINAPI
GetLargestConsoleWindowSize( HANDLE32 hConsoleOutput
)
614 return (DWORD
)MAKELONG(80,24);
617 /***********************************************************************
618 * FreeConsole (KERNEL32.267)
620 BOOL32 WINAPI
FreeConsole(VOID
)
623 PDB32
*pdb
= PROCESS_Current();
628 console
= (CONSOLE
*)pdb
->console
;
630 if (console
== NULL
) {
631 SetLastError(ERROR_INVALID_PARAMETER
);
635 HANDLE_CloseAll( pdb
, &console
->header
);
637 K32OBJ_DecCount( &console
->header
);
645 * It looks like the openpty that comes with glibc in RedHat 5.0
646 * is buggy (second call returns what looks like a dup of 0 and 1
647 * instead of a new pty), this is a generic replacement.
649 static int CONSOLE_openpty(CONSOLE
*console
, char *name
,
650 struct termios
*term
, struct winsize
*winsize
)
656 strcpy (pts_name
, "/dev/ptyXY");
658 for (ptr1
= "pqrstuvwxyzPQRST"; *ptr1
!= 0; ptr1
++) {
660 for (ptr2
= "0123456789abcdef"; *ptr2
!= 0; ptr2
++) {
663 if ((fdm
= open(pts_name
, O_RDWR
)) < 0) {
670 if ((fds
= open(pts_name
, O_RDWR
)) < 0) {
674 console
->master
= fdm
;
675 console
->infd
= console
->outfd
= fds
;
678 tcsetattr(console
->infd
, TCSANOW
, term
);
680 ioctl(console
->outfd
, TIOCSWINSZ
, winsize
);
682 strcpy(name
, pts_name
);
689 /*************************************************************************
690 * CONSOLE_make_complex [internal]
692 * Turns a CONSOLE kernel object into a complex one.
693 * (switches from output/input using the terminal where WINE was started to
696 * This makes simple commandline tools pipeable, while complex commandline
697 * tools work without getting messed up by debugoutput.
699 * All other functions should work indedependend from this call.
701 * To test for complex console: pid == -1 -> simple, otherwise complex.
703 static BOOL32
CONSOLE_make_complex(CONSOLE
*console
)
712 if (console
->pid
!= -1)
713 return TRUE
; /* already complex */
715 MSG("Console: Making console complex (creating an xterm)...\n");
717 if (tcgetattr(0, &term
) < 0) return FALSE
;
718 term
.c_lflag
= ~(ECHO
|ICANON
);
719 if (CONSOLE_openpty(console
, NULL
, &term
, NULL
) < 0) return FALSE
;
721 if ((xpid
=fork()) == 0) {
722 tcsetattr(console
->infd
, TCSADRAIN
, &term
);
723 sprintf(buf
, "-Sxx%d", console
->master
);
724 /* "-fn vga" for VGA font. Harmless if vga is not present:
725 * xterm: unable to open font "vga", trying "fixed"....
727 execlp("xterm", "xterm", buf
, "-fn","vga",NULL
);
728 ERR(console
, "error creating AllocConsole xterm\n");
733 /* most xterms like to print their window ID when used with -S;
734 * read it and continue before the user has a chance...
736 for (i
=0; c
!='\n'; (status
=read(console
->infd
, &c
, 1)), i
++) {
737 if (status
== -1 && c
== '\0') {
738 /* wait for xterm to be created */
742 ERR(console
, "can't read xterm WID\n");
743 kill(console
->pid
, SIGKILL
);
747 /* enable mouseclicks */
748 sprintf(buf
,"%c[?1001s%c[?1000h",27,27);
749 CONSOLE_Write(&console
->header
,buf
,strlen(buf
),&xlen
,NULL
);
754 /***********************************************************************
755 * CONSOLE_GetConsoleHandle
756 * returns a 16-bit style console handle
757 * note: only called from _lopen
759 HFILE32
CONSOLE_GetConsoleHandle(VOID
)
761 PDB32
*pdb
= PROCESS_Current();
762 HFILE32 handle
= HFILE_ERROR32
;
765 if (pdb
->console
!= NULL
) {
766 CONSOLE
*console
= (CONSOLE
*)pdb
->console
;
767 handle
= (HFILE32
)HANDLE_Alloc(pdb
, &console
->header
, 0, TRUE
, -1);
773 /***********************************************************************
774 * AllocConsole (KERNEL32.103)
776 * creates an xterm with a pty to our program
778 BOOL32 WINAPI
AllocConsole(VOID
)
781 PDB32
*pdb
= PROCESS_Current();
783 HANDLE32 hIn
, hOut
, hErr
;
785 SYSTEM_LOCK(); /* FIXME: really only need to lock the process */
787 SetLastError(ERROR_CANNOT_MAKE
); /* this might not be the right
788 error, but it's a good guess :) */
790 console
= (CONSOLE
*)pdb
->console
;
792 /* don't create a console if we already have one */
793 if (console
!= NULL
) {
794 SetLastError(ERROR_ACCESS_DENIED
);
799 if (!(console
= (CONSOLE
*)HeapAlloc( SystemHeap
, 0, sizeof(*console
))))
805 console
->header
.type
= K32OBJ_CONSOLE
;
806 console
->header
.refcount
= 1;
808 console
->title
= NULL
;
809 console
->nrofirs
= 0;
810 console
->wait_queue
= NULL
;
811 console
->irs
= HeapAlloc(GetProcessHeap(),0,1);;
812 console
->mode
= ENABLE_PROCESSED_INPUT
815 /* FIXME: we shouldn't probably use hardcoded UNIX values here. */
819 if ((hIn
= HANDLE_Alloc(pdb
,&console
->header
, 0, TRUE
,-1)) == INVALID_HANDLE_VALUE32
)
821 K32OBJ_DecCount(&console
->header
);
826 if ((hOut
= HANDLE_Alloc(pdb
,&console
->header
, 0, TRUE
,-1)) == INVALID_HANDLE_VALUE32
)
829 K32OBJ_DecCount(&console
->header
);
835 if ((hErr
= HANDLE_Alloc(pdb
,&console
->header
, 0, TRUE
,-1)) == INVALID_HANDLE_VALUE32
)
839 K32OBJ_DecCount(&console
->header
);
844 if (pdb
->console
) K32OBJ_DecCount( pdb
->console
);
845 pdb
->console
= (K32OBJ
*)console
;
846 K32OBJ_IncCount( pdb
->console
);
848 /* NT resets the STD_*_HANDLEs on console alloc */
849 SetStdHandle(STD_INPUT_HANDLE
, hIn
);
850 SetStdHandle(STD_OUTPUT_HANDLE
, hOut
);
851 SetStdHandle(STD_ERROR_HANDLE
, hErr
);
853 SetLastError(ERROR_SUCCESS
);
855 SetConsoleTitle32A("Wine Console");
860 /******************************************************************************
861 * GetConsoleCP [KERNEL32.295] Returns the OEM code page for the console
866 UINT32 WINAPI
GetConsoleCP(VOID
)
872 /***********************************************************************
873 * GetConsoleOutputCP (KERNEL32.189)
875 UINT32 WINAPI
GetConsoleOutputCP(VOID
)
877 return GetConsoleCP();
880 /***********************************************************************
881 * GetConsoleMode (KERNEL32.188)
883 BOOL32 WINAPI
GetConsoleMode(HANDLE32 hcon
,LPDWORD mode
)
885 CONSOLE
*console
= (CONSOLE
*)HANDLE_GetObjPtr( PROCESS_Current(), hcon
, K32OBJ_CONSOLE
, 0, NULL
);
888 FIXME(console
,"(%d,%p), no console handle passed!\n",hcon
,mode
);
891 *mode
= console
->mode
;
892 K32OBJ_DecCount(&console
->header
);
897 /******************************************************************************
898 * SetConsoleMode [KERNEL32.628] Sets input mode of console's input buffer
901 * hcon [I] Handle to console input or screen buffer
902 * mode [I] Input or output mode to set
908 BOOL32 WINAPI
SetConsoleMode( HANDLE32 hcon
, DWORD mode
)
910 CONSOLE
*console
= (CONSOLE
*)HANDLE_GetObjPtr( PROCESS_Current(), hcon
, K32OBJ_CONSOLE
, 0, NULL
);
913 FIXME(console
,"(%d,%ld), no console handle passed!\n",hcon
,mode
);
916 FIXME(console
,"(0x%08x,0x%08lx): stub\n",hcon
,mode
);
917 console
->mode
= mode
;
918 K32OBJ_DecCount(&console
->header
);
923 /***********************************************************************
924 * GetConsoleTitleA (KERNEL32.191)
926 DWORD WINAPI
GetConsoleTitle32A(LPSTR title
,DWORD size
)
928 PDB32
*pdb
= PROCESS_Current();
929 CONSOLE
*console
= (CONSOLE
*)pdb
->console
;
931 if(console
&& console
->title
) {
932 lstrcpyn32A(title
,console
->title
,size
);
933 return strlen(title
);
939 /******************************************************************************
940 * GetConsoleTitle32W [KERNEL32.192] Retrieves title string for console
943 * title [O] Address of buffer for title
944 * size [I] Size of buffer
947 * Success: Length of string copied
950 DWORD WINAPI
GetConsoleTitle32W( LPWSTR title
, DWORD size
)
952 PDB32
*pdb
= PROCESS_Current();
953 CONSOLE
*console
= (CONSOLE
*)pdb
->console
;
954 if(console
&& console
->title
)
956 lstrcpynAtoW(title
,console
->title
,size
);
957 return (lstrlen32W(title
));
963 /***********************************************************************
964 * WriteConsoleA (KERNEL32.729)
966 BOOL32 WINAPI
WriteConsole32A( HANDLE32 hConsoleOutput
,
968 DWORD nNumberOfCharsToWrite
,
969 LPDWORD lpNumberOfCharsWritten
,
972 /* FIXME: should I check if this is a console handle? */
973 return WriteFile(hConsoleOutput
, lpBuffer
, nNumberOfCharsToWrite
,
974 lpNumberOfCharsWritten
, NULL
);
979 if (bufused==curbufsize-1) \
980 buffer = HeapReAlloc(GetProcessHeap(),0,buffer,(curbufsize+=100));\
982 #define SADD(s) { char *x=s;while (*x) {CADD(*x);x++;}}
984 /***********************************************************************
985 * WriteConsoleOutputA (KERNEL32.732)
987 BOOL32 WINAPI
WriteConsoleOutput32A( HANDLE32 hConsoleOutput
,
988 LPCHAR_INFO lpBuffer
,
991 LPSMALL_RECT lpWriteRegion
)
993 int i
,j
,off
=0,lastattr
=-1;
994 char sbuf
[20],*buffer
=NULL
;
995 int bufused
=0,curbufsize
= 100;
997 const int colormap
[8] = {
1001 CONSOLE
*console
= (CONSOLE
*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleOutput
, K32OBJ_CONSOLE
, 0, NULL
);
1004 FIXME(console
,"(%d,...): no console handle!\n",hConsoleOutput
);
1007 CONSOLE_make_complex(console
);
1008 buffer
= HeapAlloc(GetProcessHeap(),0,100);;
1011 TRACE(console
,"wr: top = %d, bottom=%d, left=%d,right=%d\n",
1013 lpWriteRegion
->Bottom
,
1014 lpWriteRegion
->Left
,
1015 lpWriteRegion
->Right
1018 for (i
=lpWriteRegion
->Top
;i
<=lpWriteRegion
->Bottom
;i
++) {
1019 sprintf(sbuf
,"%c[%d;%dH",27,i
+1,lpWriteRegion
->Left
+1);
1021 for (j
=lpWriteRegion
->Left
;j
<=lpWriteRegion
->Right
;j
++) {
1022 if (lastattr
!=lpBuffer
[off
].Attributes
) {
1023 lastattr
= lpBuffer
[off
].Attributes
;
1024 sprintf(sbuf
,"%c[0;%s3%d;4%dm",
1026 (lastattr
& FOREGROUND_INTENSITY
)?"1;":"",
1027 colormap
[lastattr
&7],
1028 colormap
[(lastattr
&0x70)>>4]
1030 /* FIXME: BACKGROUND_INTENSITY */
1033 CADD(lpBuffer
[off
].Char
.AsciiChar
);
1037 sprintf(sbuf
,"%c[0m",27);SADD(sbuf
);
1038 WriteFile(hConsoleOutput
,buffer
,bufused
,&res
,NULL
);
1039 HeapFree(GetProcessHeap(),0,buffer
);
1040 K32OBJ_DecCount(&console
->header
);
1044 /***********************************************************************
1045 * WriteConsoleW (KERNEL32.577)
1047 BOOL32 WINAPI
WriteConsole32W( HANDLE32 hConsoleOutput
,
1049 DWORD nNumberOfCharsToWrite
,
1050 LPDWORD lpNumberOfCharsWritten
,
1054 LPSTR xstring
=HeapAlloc( GetProcessHeap(), 0, nNumberOfCharsToWrite
);
1056 lstrcpynWtoA( xstring
, lpBuffer
,nNumberOfCharsToWrite
);
1058 /* FIXME: should I check if this is a console handle? */
1059 ret
= WriteFile(hConsoleOutput
, xstring
, nNumberOfCharsToWrite
,
1060 lpNumberOfCharsWritten
, NULL
);
1061 HeapFree( GetProcessHeap(), 0, xstring
);
1066 /***********************************************************************
1067 * ReadConsoleA (KERNEL32.419)
1069 BOOL32 WINAPI
ReadConsole32A( HANDLE32 hConsoleInput
,
1071 DWORD nNumberOfCharsToRead
,
1072 LPDWORD lpNumberOfCharsRead
,
1075 CONSOLE
*console
= (CONSOLE
*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleInput
, K32OBJ_CONSOLE
, 0, NULL
);
1076 int i
,charsread
= 0;
1077 LPSTR xbuf
= (LPSTR
)lpBuffer
;
1080 SetLastError(ERROR_INVALID_HANDLE
);
1081 FIXME(console
,"(%d,...), no console handle!\n",hConsoleInput
);
1084 TRACE(console
,"(%d,%p,%ld,%p,%p)\n",
1085 hConsoleInput
,lpBuffer
,nNumberOfCharsToRead
,
1086 lpNumberOfCharsRead
,lpReserved
1088 CONSOLE_get_input(console
);
1090 /* FIXME: should this drain everything from the input queue and just
1091 * put the keypresses in the buffer? Needs further thought.
1093 for (i
=0;(i
<console
->nrofirs
)&&(charsread
<nNumberOfCharsToRead
);i
++) {
1094 if (console
->irs
[i
].EventType
!= KEY_EVENT
)
1096 if (!console
->irs
[i
].Event
.KeyEvent
.bKeyDown
)
1098 *xbuf
++ = console
->irs
[i
].Event
.KeyEvent
.uChar
.AsciiChar
;
1101 CONSOLE_drain_input(console
,i
);
1102 if (lpNumberOfCharsRead
)
1103 *lpNumberOfCharsRead
= charsread
;
1104 K32OBJ_DecCount(&console
->header
);
1108 /***********************************************************************
1109 * ReadConsoleW (KERNEL32.427)
1111 BOOL32 WINAPI
ReadConsole32W( HANDLE32 hConsoleInput
,
1113 DWORD nNumberOfCharsToRead
,
1114 LPDWORD lpNumberOfCharsRead
,
1118 LPSTR buf
= (LPSTR
)HeapAlloc(GetProcessHeap(), 0, nNumberOfCharsToRead
);
1120 ret
= ReadConsole32A(
1123 nNumberOfCharsToRead
,
1124 lpNumberOfCharsRead
,
1128 lstrcpynAtoW(lpBuffer
,buf
,nNumberOfCharsToRead
);
1129 HeapFree( GetProcessHeap(), 0, buf
);
1134 /******************************************************************************
1135 * ReadConsoleInput32A [KERNEL32.569] Reads data from a console
1138 * hConsoleInput [I] Handle to console input buffer
1139 * lpBuffer [O] Address of buffer for read data
1140 * nLength [I] Number of records to read
1141 * lpNumberOfEventsRead [O] Address of number of records read
1147 BOOL32 WINAPI
ReadConsoleInput32A(HANDLE32 hConsoleInput
,
1148 LPINPUT_RECORD lpBuffer
,
1149 DWORD nLength
, LPDWORD lpNumberOfEventsRead
)
1151 CONSOLE
*console
= (CONSOLE
*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleInput
, K32OBJ_CONSOLE
, 0, NULL
);
1153 TRACE(console
, "(%d,%p,%ld,%p)\n",hConsoleInput
, lpBuffer
, nLength
,
1154 lpNumberOfEventsRead
);
1156 FIXME(console
, "(%d,%p,%ld,%p), No console handle!\n",hConsoleInput
,
1157 lpBuffer
, nLength
, lpNumberOfEventsRead
);
1160 CONSOLE_get_input(console
);
1161 if (nLength
>console
->nrofirs
)
1162 nLength
= console
->nrofirs
;
1163 memcpy(lpBuffer
,console
->irs
,sizeof(INPUT_RECORD
)*nLength
);
1164 if (lpNumberOfEventsRead
)
1165 *lpNumberOfEventsRead
= nLength
;
1166 CONSOLE_drain_input(console
,nLength
);
1167 K32OBJ_DecCount(&console
->header
);
1171 /***********************************************************************
1172 * SetConsoleTitle32A (KERNEL32.476)
1174 * Sets the console title.
1176 * We do not necessarily need to create a complex console for that,
1177 * but should remember the title and set it on creation of the latter.
1178 * (not fixed at this time).
1180 BOOL32 WINAPI
SetConsoleTitle32A(LPCSTR title
)
1182 PDB32
*pdb
= PROCESS_Current();
1185 char titleformat
[]="\033]2;%s\a"; /*this should work for xterms*/
1189 TRACE(console
,"(%s)\n",title
);
1191 console
= (CONSOLE
*)pdb
->console
;
1194 if(console
->title
) /* Free old title, if there is one */
1195 HeapFree( SystemHeap
, 0, console
->title
);
1196 console
->title
= (LPSTR
)HeapAlloc(SystemHeap
, 0,strlen(title
)+1);
1197 if(console
->title
) strcpy(console
->title
,title
);
1198 titlestring
= HeapAlloc(GetProcessHeap(), 0,strlen(title
)+strlen(titleformat
)+1);
1200 K32OBJ_DecCount(&console
->header
);
1204 sprintf(titlestring
,titleformat
,title
);
1205 /* FIXME: hmm, should use WriteFile probably... */
1206 CONSOLE_Write(&console
->header
,titlestring
,strlen(titlestring
),&written
,NULL
);
1207 if (written
== strlen(titlestring
))
1209 HeapFree( GetProcessHeap(), 0, titlestring
);
1210 K32OBJ_DecCount(&console
->header
);
1215 /******************************************************************************
1216 * SetConsoleTitle32W [KERNEL32.477] Sets title bar string for console
1219 * title [I] Address of new title
1222 * This should not be calling the A version
1228 BOOL32 WINAPI
SetConsoleTitle32W( LPCWSTR title
)
1232 LPSTR titleA
= HEAP_strdupWtoA( GetProcessHeap(), 0, title
);
1233 ret
= SetConsoleTitle32A(titleA
);
1234 HeapFree( GetProcessHeap(), 0, titleA
);
1238 /***********************************************************************
1239 * ReadConsoleInput32W (KERNEL32.570)
1241 BOOL32 WINAPI
ReadConsoleInput32W(HANDLE32 hConsoleInput
,
1242 LPINPUT_RECORD lpBuffer
,
1243 DWORD nLength
, LPDWORD lpNumberOfEventsRead
)
1245 FIXME(console
, "(%d,%p,%ld,%p): stub\n",hConsoleInput
, lpBuffer
, nLength
,
1246 lpNumberOfEventsRead
);
1250 /***********************************************************************
1251 * FlushConsoleInputBuffer (KERNEL32.132)
1253 BOOL32 WINAPI
FlushConsoleInputBuffer(HANDLE32 hConsoleInput
)
1255 CONSOLE
*console
= (CONSOLE
*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleInput
, K32OBJ_CONSOLE
, 0, NULL
);
1259 CONSOLE_drain_input(console
,console
->nrofirs
);
1260 K32OBJ_DecCount(&console
->header
);
1265 /******************************************************************************
1266 * SetConsoleCursorPosition [KERNEL32.627]
1267 * Sets the cursor position in console
1270 * hConsoleOutput [I] Handle of console screen buffer
1271 * dwCursorPosition [I] New cursor position coordinates
1275 BOOL32 WINAPI
SetConsoleCursorPosition( HANDLE32 hcon
, COORD pos
)
1279 CONSOLE
*console
= (CONSOLE
*)HANDLE_GetObjPtr( PROCESS_Current(), hcon
, K32OBJ_CONSOLE
, 0, NULL
);
1282 FIXME(console
,"(%d,...), no console handle!\n",hcon
);
1285 CONSOLE_make_complex(console
);
1286 TRACE(console
, "%d (%dx%d)\n", hcon
, pos
.x
, pos
.y
);
1287 /* x are columns, y rows */
1288 sprintf(xbuf
,"%c[%d;%dH", 0x1B, pos
.y
+1, pos
.x
+1);
1289 /* FIXME: store internal if we start using own console buffers */
1290 WriteFile(hcon
,xbuf
,strlen(xbuf
),&xlen
,NULL
);
1291 K32OBJ_DecCount(&console
->header
);
1295 /***********************************************************************
1296 * GetNumberOfConsoleInputEvents (KERNEL32.246)
1298 BOOL32 WINAPI
GetNumberOfConsoleInputEvents(HANDLE32 hcon
,LPDWORD nrofevents
)
1300 CONSOLE
*console
= (CONSOLE
*)HANDLE_GetObjPtr( PROCESS_Current(), hcon
, K32OBJ_CONSOLE
, 0, NULL
);
1303 FIXME(console
,"(%d,%p), no console handle!\n",hcon
,nrofevents
);
1306 CONSOLE_get_input(console
);
1307 *nrofevents
= console
->nrofirs
;
1308 K32OBJ_DecCount(&console
->header
);
1312 /***********************************************************************
1313 * GetNumberOfConsoleMouseButtons (KERNEL32.358)
1315 BOOL32 WINAPI
GetNumberOfConsoleMouseButtons(LPDWORD nrofbuttons
)
1317 FIXME(console
,"(%p): stub\n", nrofbuttons
);
1322 /***********************************************************************
1323 * PeekConsoleInputA (KERNEL32.550)
1325 * Gets 'cInRecords' first events (or less) from input queue.
1327 * Does not need a complex console.
1329 BOOL32 WINAPI
PeekConsoleInput32A(HANDLE32 hConsoleInput
,
1330 LPINPUT_RECORD pirBuffer
,
1334 CONSOLE
*console
= (CONSOLE
*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleInput
, K32OBJ_CONSOLE
, 0, NULL
);
1337 FIXME(console
,"(%d,%p,%ld,%p), No console handle passed!\n",hConsoleInput
, pirBuffer
, cInRecords
, lpcRead
);
1340 TRACE(console
,"(%d,%p,%ld,%p)\n",hConsoleInput
, pirBuffer
, cInRecords
, lpcRead
);
1341 CONSOLE_get_input(console
);
1342 if (cInRecords
>console
->nrofirs
)
1343 cInRecords
= console
->nrofirs
;
1345 memcpy(pirBuffer
,console
->irs
,cInRecords
*sizeof(INPUT_RECORD
));
1347 *lpcRead
= cInRecords
;
1348 K32OBJ_DecCount(&console
->header
);
1352 /***********************************************************************
1353 * PeekConsoleInputW (KERNEL32.551)
1355 BOOL32 WINAPI
PeekConsoleInput32W(HANDLE32 hConsoleInput
,
1356 LPINPUT_RECORD pirBuffer
,
1360 /* FIXME: Hmm. Fix this if we get UNICODE input. */
1361 return PeekConsoleInput32A(hConsoleInput
,pirBuffer
,cInRecords
,lpcRead
);
1365 /******************************************************************************
1366 * GetConsoleCursorInfo32 [KERNEL32.296] Gets size and visibility of console
1369 * hcon [I] Handle to console screen buffer
1370 * cinfo [O] Address of cursor information
1376 BOOL32 WINAPI
GetConsoleCursorInfo32( HANDLE32 hcon
,
1377 LPCONSOLE_CURSOR_INFO cinfo
)
1379 CONSOLE
*console
= (CONSOLE
*)HANDLE_GetObjPtr( PROCESS_Current(), hcon
, K32OBJ_CONSOLE
, 0, NULL
);
1382 FIXME(console
, "(%x,%p), no console handle!\n", hcon
, cinfo
);
1385 TRACE(console
, "(%x,%p)\n", hcon
, cinfo
);
1388 *cinfo
= console
->cinfo
;
1389 K32OBJ_DecCount(&console
->header
);
1394 /******************************************************************************
1395 * SetConsoleCursorInfo32 [KERNEL32.626] Sets size and visibility of cursor
1401 BOOL32 WINAPI
SetConsoleCursorInfo32(
1402 HANDLE32 hcon
, /* [in] Handle to console screen buffer */
1403 LPCONSOLE_CURSOR_INFO cinfo
) /* [in] Address of cursor information */
1407 CONSOLE
*console
= (CONSOLE
*)HANDLE_GetObjPtr( PROCESS_Current(), hcon
, K32OBJ_CONSOLE
, 0, NULL
);
1409 TRACE(console
, "(%x,%ld,%i): stub\n", hcon
,cinfo
->dwSize
,cinfo
->bVisible
);
1412 CONSOLE_make_complex(console
);
1413 sprintf(buf
,"%c[?25%c",27,cinfo
->bVisible
?'h':'l');
1414 WriteFile(hcon
,buf
,strlen(buf
),&xlen
,NULL
);
1415 console
->cinfo
= *cinfo
;
1416 K32OBJ_DecCount(&console
->header
);
1421 /******************************************************************************
1422 * SetConsoleWindowInfo [KERNEL32.634] Sets size and position of console
1428 BOOL32 WINAPI
SetConsoleWindowInfo(
1429 HANDLE32 hcon
, /* [in] Handle to console screen buffer */
1430 BOOL32 bAbsolute
, /* [in] Coordinate type flag */
1431 LPSMALL_RECT window
) /* [in] Address of new window rectangle */
1433 FIXME(console
, "(%x,%d,%p): stub\n", hcon
, bAbsolute
, window
);
1438 /******************************************************************************
1439 * SetConsoleTextAttribute32 [KERNEL32.631] Sets colors for text
1441 * Sets the foreground and background color attributes of characters
1442 * written to the screen buffer.
1448 BOOL32 WINAPI
SetConsoleTextAttribute32(HANDLE32 hConsoleOutput
,WORD wAttr
)
1450 const int colormap
[8] = {
1457 TRACE(console
,"(%d,%d)\n",hConsoleOutput
,wAttr
);
1458 sprintf(buffer
,"%c[0;%s3%d;4%dm",
1460 (wAttr
& FOREGROUND_INTENSITY
)?"1;":"",
1462 colormap
[(wAttr
&0x70)>>4]
1464 WriteFile(hConsoleOutput
,buffer
,strlen(buffer
),&xlen
,NULL
);
1469 /******************************************************************************
1470 * SetConsoleScreenBufferSize [KERNEL32.630] Changes size of console
1473 * hConsoleOutput [I] Handle to console screen buffer
1474 * dwSize [I] New size in character rows and cols
1480 BOOL32 WINAPI
SetConsoleScreenBufferSize( HANDLE32 hConsoleOutput
,
1483 FIXME(console
, "(%d,%dx%d): stub\n",hConsoleOutput
,dwSize
.x
,dwSize
.y
);
1488 /******************************************************************************
1489 * FillConsoleOutputCharacterA [KERNEL32.242]
1492 * hConsoleOutput [I] Handle to screen buffer
1493 * cCharacter [I] Character to write
1494 * nLength [I] Number of cells to write to
1495 * dwCoord [I] Coords of first cell
1496 * lpNumCharsWritten [O] Pointer to number of cells written
1502 BOOL32 WINAPI
FillConsoleOutputCharacterA(
1503 HANDLE32 hConsoleOutput
,
1507 LPDWORD lpNumCharsWritten
)
1512 SetConsoleCursorPosition(hConsoleOutput
,dwCoord
);
1513 for(count
=0;count
<nLength
;count
++)
1514 WriteFile(hConsoleOutput
,&cCharacter
,1,&xlen
,NULL
);
1515 *lpNumCharsWritten
= nLength
;
1520 /******************************************************************************
1521 * FillConsoleOutputCharacterW [KERNEL32.243] Writes characters to console
1524 * hConsoleOutput [I] Handle to screen buffer
1525 * cCharacter [I] Character to write
1526 * nLength [I] Number of cells to write to
1527 * dwCoord [I] Coords of first cell
1528 * lpNumCharsWritten [O] Pointer to number of cells written
1534 BOOL32 WINAPI
FillConsoleOutputCharacterW(HANDLE32 hConsoleOutput
,
1538 LPDWORD lpNumCharsWritten
)
1543 SetConsoleCursorPosition(hConsoleOutput
,dwCoord
);
1544 /* FIXME: not quite correct ... but the lower part of UNICODE char comes
1547 for(count
=0;count
<nLength
;count
++)
1548 WriteFile(hConsoleOutput
,&cCharacter
,1,&xlen
,NULL
);
1549 *lpNumCharsWritten
= nLength
;
1554 /******************************************************************************
1555 * FillConsoleOutputAttribute [KERNEL32.241] Sets attributes for console
1558 * hConsoleOutput [I] Handle to screen buffer
1559 * wAttribute [I] Color attribute to write
1560 * nLength [I] Number of cells to write to
1561 * dwCoord [I] Coords of first cell
1562 * lpNumAttrsWritten [O] Pointer to number of cells written
1568 BOOL32 WINAPI
FillConsoleOutputAttribute( HANDLE32 hConsoleOutput
,
1569 WORD wAttribute
, DWORD nLength
, COORD dwCoord
,
1570 LPDWORD lpNumAttrsWritten
)
1572 FIXME(console
, "(%d,%d,%ld,%dx%d,%p): stub\n", hConsoleOutput
,
1573 wAttribute
,nLength
,dwCoord
.x
,dwCoord
.y
,lpNumAttrsWritten
);
1574 *lpNumAttrsWritten
= nLength
;
1578 /******************************************************************************
1579 * ReadConsoleOutputCharacter32A [KERNEL32.573]
1584 BOOL32 WINAPI
ReadConsoleOutputCharacter32A(HANDLE32 hConsoleOutput
,
1585 LPSTR lpstr
, DWORD dword
, COORD coord
, LPDWORD lpdword
)
1587 FIXME(console
, "(%d,%p,%ld,%dx%d,%p): stub\n", hConsoleOutput
,lpstr
,
1588 dword
,coord
.x
,coord
.y
,lpdword
);
1589 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1594 /******************************************************************************
1595 * ScrollConsoleScreenBuffer [KERNEL32.612]
1600 BOOL32 WINAPI
ScrollConsoleScreenBuffer( HANDLE32 hConsoleOutput
,
1601 LPSMALL_RECT lpScrollRect
, LPSMALL_RECT lpClipRect
,
1602 COORD dwDestOrigin
, LPCHAR_INFO lpFill
)
1604 FIXME(console
, "(%d,%p,%p,%dx%d,%p): stub\n", hConsoleOutput
,lpScrollRect
,
1605 lpClipRect
,dwDestOrigin
.x
,dwDestOrigin
.y
,lpFill
);
1606 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);