Release 950122
Sun Jan 22 18:55:33 1995 Alexandre Julliard (julliard@lamisun.epfl.ch) * [loader/resource.c] [objects/dib.c] Fixed icon loading and drawing, now that BitBlt() works correctly. * [objects/clipping.c] [objects/region.c] Implemented elliptic regions with a set of rectangle. This greatly simplifies the region code and should boost clipping performance. * [objects/color.c] Fixed bug that caused seg-fault on 24bpp displays. * [objects/bitblt.c] Fixed bug when shrinking a bitmap to more than half its size. * [windows/graphics.c] Fixed bugs in PaintRgn() and Polyline(). * [windows/nonclient.c] [windows/painting.c] [windows/winpos.c] Fixed some problems with window background painting. Thu Jan 12 12:20:25 PST 1995 Ross Biro (biro@yggdrasil.com) * [tools/build.c] * [tools/newbuild.c] * [Imakefile] * [include/wine.h] * [loader/call.S] * [loader/selector.c] * [include/segmem.h] * [misc/main.c] Changed selector code and 16/32 bit xfer code so that wine no longer has to be loaded low in memory. Changed wine to work with ELF binary formats under Linux. Sat Sep 17 11:08:49 1994 Eric Youngdale (eric@esp22) * [debugger/db_disasm.c] New instruction disassembler - borrowed from Mach kernel. Has a BSD style of license as opposed to the gdb code we were previously using which was under the GPL. Mon Jan 9 18:27:11 1995 Alexandre Julliard (julliard@lamisun.epfl.ch) * [Imakefile] Compiling with -Wall flag. * [*/*] Fixes to minimize the number of compilation warnings. * [objects/bitblt.c] Fixed BitBlt() and used the same code to rewrite PatBlt() and StretchBlt(). The three *Blt() functions should now be correct in every case (famous last words). * [objects/brush.c] [objects/dither.c] Merged the two files into brush.c * [objects/dc.c] Fixed bug when the Windows programs forget to re-select the original bitmap in a memory DC. * [objects/font.c] Tty to use 'fixed' font when the system font can't be found. * [windows/dialog.c] Tentative fix to make dialogs look better when using fixed-width fonts. * [windows/graphics.c] Partially implemented the PS_INSIDEFRAME pen style. * [windows/nonclient.c] Fix for windows that have the WS_EX_DLGMODALFRAME style bit without the WS_DLGFRAME style.
This commit is contained in:
parent
7cbe65725a
commit
18506558a7
21
ANNOUNCE
21
ANNOUNCE
|
@ -1,13 +1,14 @@
|
|||
This is release 950109 of Wine the MS Windows emulator. This is still a
|
||||
This is release 950122 of Wine the MS Windows emulator. This is still a
|
||||
developer's only release. There are many bugs and many unimplemented API
|
||||
features. Most applications still do not work.
|
||||
|
||||
Patches should be submitted to "wine-new@amscons.com". Please don't forget
|
||||
to include a ChangeLog entry. I'll try to make a new release every Sunday.
|
||||
to include a ChangeLog entry. I'll make a new release every other Sunday.
|
||||
|
||||
WHAT'S NEW with Wine-950109: (see ChangeLog for details)
|
||||
- Compiling with -Wall. Don't panic if you get many warnings...
|
||||
- Better StretchBlt()
|
||||
WHAT'S NEW with Wine-950122: (see ChangeLog for details)
|
||||
- ELF format support
|
||||
- New disassembler based on Mach code, replacing the gdb code
|
||||
- Faster regions
|
||||
- Lots of bug fixes
|
||||
|
||||
See the README file in the distribution for installation instructions.
|
||||
|
@ -16,11 +17,11 @@ Because of lags created by using mirror, this message may reach you before
|
|||
the release is available at the ftp sites. The sources will be available
|
||||
from the following locations:
|
||||
|
||||
sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950109.tar.gz
|
||||
aris.com:/pub/linux/ALPHA/Wine/development/Wine-950109.tar.gz
|
||||
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950109.tar.gz
|
||||
ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950109.tar.gz
|
||||
ftp.wonderland.org:/Wine/Wine-950109.tar.gz
|
||||
sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950122.tar.gz
|
||||
aris.com:/pub/linux/ALPHA/Wine/development/Wine-950122.tar.gz
|
||||
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950122.tar.gz
|
||||
ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950122.tar.gz
|
||||
ftp.wonderland.org:/Wine/Wine-950122.tar.gz
|
||||
|
||||
If you submitted a patch, please check to make sure it has been
|
||||
included in the new release.
|
||||
|
|
88
ChangeLog
88
ChangeLog
|
@ -1,3 +1,81 @@
|
|||
----------------------------------------------------------------------
|
||||
Sun Jan 22 18:55:33 1995 Alexandre Julliard (julliard@lamisun.epfl.ch)
|
||||
|
||||
* [loader/resource.c] [objects/dib.c]
|
||||
Fixed icon loading and drawing, now that BitBlt() works correctly.
|
||||
|
||||
* [objects/clipping.c] [objects/region.c]
|
||||
Implemented elliptic regions with a set of rectangle. This greatly
|
||||
simplifies the region code and should boost clipping performance.
|
||||
|
||||
* [objects/color.c]
|
||||
Fixed bug that caused seg-fault on 24bpp displays.
|
||||
|
||||
* [objects/bitblt.c]
|
||||
Fixed bug when shrinking a bitmap to more than half its size.
|
||||
|
||||
* [windows/graphics.c]
|
||||
Fixed bugs in PaintRgn() and Polyline().
|
||||
|
||||
* [windows/nonclient.c] [windows/painting.c] [windows/winpos.c]
|
||||
Fixed some problems with window background painting.
|
||||
|
||||
Thu Jan 12 12:20:25 PST 1995 Ross Biro (biro@yggdrasil.com)
|
||||
|
||||
* [tools/build.c]
|
||||
* [tools/newbuild.c]
|
||||
* [Imakefile]
|
||||
* [include/wine.h]
|
||||
* [loader/call.S]
|
||||
* [loader/selector.c]
|
||||
* [include/segmem.h]
|
||||
* [misc/main.c]
|
||||
Changed selector code and 16/32 bit xfer code so that wine
|
||||
no longer has to be loaded low in memory. Changed wine
|
||||
to work with ELF binary formats under Linux.
|
||||
|
||||
Sat Sep 17 11:08:49 1994 Eric Youngdale (eric@esp22)
|
||||
|
||||
* [debugger/db_disasm.c]
|
||||
New instruction disassembler - borrowed from Mach kernel. Has a
|
||||
BSD style of license as opposed to the gdb code we were previously
|
||||
using which was under the GPL.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Mon Jan 9 18:27:11 1995 Alexandre Julliard (julliard@lamisun.epfl.ch)
|
||||
|
||||
* [Imakefile]
|
||||
Compiling with -Wall flag.
|
||||
|
||||
* [*/*]
|
||||
Fixes to minimize the number of compilation warnings.
|
||||
|
||||
* [objects/bitblt.c]
|
||||
Fixed BitBlt() and used the same code to rewrite PatBlt() and
|
||||
StretchBlt(). The three *Blt() functions should now be correct in
|
||||
every case (famous last words).
|
||||
|
||||
* [objects/brush.c] [objects/dither.c]
|
||||
Merged the two files into brush.c
|
||||
|
||||
* [objects/dc.c]
|
||||
Fixed bug when the Windows programs forget to re-select the
|
||||
original bitmap in a memory DC.
|
||||
|
||||
* [objects/font.c]
|
||||
Tty to use 'fixed' font when the system font can't be found.
|
||||
|
||||
* [windows/dialog.c]
|
||||
Tentative fix to make dialogs look better when using fixed-width
|
||||
fonts.
|
||||
|
||||
* [windows/graphics.c]
|
||||
Partially implemented the PS_INSIDEFRAME pen style.
|
||||
|
||||
* [windows/nonclient.c]
|
||||
Fix for windows that have the WS_EX_DLGMODALFRAME style bit
|
||||
without the WS_DLGFRAME style.
|
||||
|
||||
Thu Jan 5 13:37:42 1995 Cameron Heide (heide@ee.ualberta.ca)
|
||||
|
||||
* [memory/global.c]
|
||||
|
@ -10,11 +88,13 @@ Thu Jan 5 13:37:42 1995 Cameron Heide (heide@ee.ualberta.ca)
|
|||
|
||||
Sun Jan 1 23:30:25 1995 Fons Botman <botman@rabo.nl>
|
||||
|
||||
* objects/font.c (GetTextExtentPoint):
|
||||
Fixed debug output, str is counted string, not zero terminated.
|
||||
* [objects/font.c]
|
||||
GetTextExtentPoint: fixed debug output, str is counted string, not
|
||||
zero terminated.
|
||||
|
||||
* if1632/relay.c (DLLRelay):
|
||||
When debugging_stack got segv, added upper bound for stack dump.
|
||||
* [if1632/relay.c]
|
||||
DLLRelay: when debugging_stack got segv, added upper bound for
|
||||
stack dump.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Tue Dec 27 13:35:16 1994 Alexandre Julliard (julliard@lamisun.epfl.ch)
|
||||
|
|
|
@ -7,7 +7,11 @@ CC = gcc -D__FreeBSD__
|
|||
#endif
|
||||
|
||||
DEFINES = AutoDefines -DUSE_READLINE -DWINESTAT
|
||||
#ifdef __ELF__
|
||||
CDEBUGFLAGS = -O2 -Wall -static
|
||||
#else
|
||||
CDEBUGFLAGS = -O2 -Wall
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the second try at using Imakefiles. There are probably many
|
||||
|
|
5
README
5
README
|
@ -8,11 +8,6 @@ API calls to their Unix/X11 equivalent.
|
|||
Wine is free software. See the file LICENSE for the details.
|
||||
Basically, you can do anything with it, except claim that you wrote it.
|
||||
|
||||
Important note: current versions of Wine include a built-in debugger
|
||||
for 16-bit code, that is based on code from gdb. This means that if
|
||||
you redistribute a version of Wine that includes this debugger, you
|
||||
must follow the terms of the GNU General Public License.
|
||||
|
||||
|
||||
2. COMPILATION
|
||||
|
||||
|
|
|
@ -1357,6 +1357,7 @@ void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt )
|
|||
void MENU_TrackKbdMenuBar( HWND hwnd, WORD wParam )
|
||||
{
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
if (!wndPtr->wIDmenu) return;
|
||||
SendMessage( hwnd, WM_ENTERMENULOOP, 0, 0 );
|
||||
/* Select first selectable item */
|
||||
MENU_SelectItem( wndPtr->wIDmenu, NO_SELECTED_ITEM );
|
||||
|
|
|
@ -134,7 +134,11 @@ LONG StaticWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
|
|||
break;
|
||||
|
||||
case WM_SETTEXT:
|
||||
DEFWND_SetText( hWnd, (LPSTR)lParam );
|
||||
if (style == SS_ICON)
|
||||
STATIC_SetIcon( hWnd, LoadIcon( wndPtr->hInstance,
|
||||
(LPSTR)lParam ) );
|
||||
else
|
||||
DEFWND_SetText( hWnd, (LPSTR)lParam );
|
||||
InvalidateRect( hWnd, NULL, FALSE );
|
||||
UpdateWindow( hWnd );
|
||||
break;
|
||||
|
|
|
@ -6,20 +6,19 @@
|
|||
|
||||
MODULE = debugger
|
||||
|
||||
SUBDIRS = opcodes readline
|
||||
SUBDIRS = readline
|
||||
|
||||
DEFINES = -DUSE_READLINE -Iopcodes
|
||||
DEFINES = -DUSE_READLINE
|
||||
|
||||
SRCS = \
|
||||
dbg.tab.c \
|
||||
break.c \
|
||||
db_disasm.c \
|
||||
dbg.tab.c \
|
||||
hash.c \
|
||||
lex.yy.c \
|
||||
info.c
|
||||
info.c \
|
||||
lex.yy.c
|
||||
|
||||
SUBDIRS_OBJS = \
|
||||
opcodes/opcodes.o \
|
||||
readline/readline.o
|
||||
SUBDIRS_OBJS = readline/readline.o
|
||||
|
||||
OBJS = $(SRCS:.c=.o) $(SUBDIRS_OBJS)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
|||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
typedef unsigned char boolean_t;
|
||||
typedef unsigned long db_addr_t;
|
||||
|
||||
extern db_addr_t db_disasm(db_addr_t loc, boolean_t altfmt, boolean_t flag16);
|
|
@ -57,8 +57,8 @@ void mode_command(int);
|
|||
| QUIT '\n' { exit(0); }
|
||||
| 'q' '\n' { exit(0); }
|
||||
| HELP '\n' { dbg_help(); }
|
||||
| CONT '\n' { return; }
|
||||
| 'c' '\n' { return; }
|
||||
| CONT '\n' { return 0; }
|
||||
| 'c' '\n' { return 0; }
|
||||
| ABORT '\n' { kill(getpid(), SIGABRT); }
|
||||
| SYMBOLFILE IDENTIFIER '\n' { read_symboltable($2); }
|
||||
| DEFINE IDENTIFIER expr '\n' { add_hash($2, $3); }
|
||||
|
@ -150,7 +150,6 @@ void
|
|||
wine_debug(int signal, int * regs)
|
||||
{
|
||||
static int dummy_regs[32];
|
||||
int i;
|
||||
#ifdef YYDEBUG
|
||||
yydebug = 0;
|
||||
#endif
|
||||
|
@ -223,7 +222,9 @@ wine_debug(int signal, int * regs)
|
|||
}
|
||||
|
||||
|
||||
yyerror(char * s){
|
||||
int yyerror(char * s)
|
||||
{
|
||||
fprintf(stderr,"%s\n", s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,25 @@ int yywrap(void) { return 1; }
|
|||
#include "readline/chardefs.h"
|
||||
#endif
|
||||
|
||||
/* Strip whitespace from the start and end of STRING. */
|
||||
static void stripwhite (char *string)
|
||||
{
|
||||
register int i = 0;
|
||||
|
||||
while (whitespace (string[i]))
|
||||
i++;
|
||||
|
||||
if (i)
|
||||
strcpy (string, string + i);
|
||||
|
||||
i = strlen (string) - 1;
|
||||
|
||||
while (i > 0 && whitespace (string[i]))
|
||||
i--;
|
||||
|
||||
string[++i] = '\0';
|
||||
}
|
||||
|
||||
dbg_read(char * buf, int size){
|
||||
char * line;
|
||||
int len;
|
||||
|
@ -180,25 +199,6 @@ dbg_read(char * buf, int size){
|
|||
} while (1==1);
|
||||
}
|
||||
|
||||
/* Strip whitespace from the start and end of STRING. */
|
||||
void stripwhite (char *string)
|
||||
{
|
||||
register int i = 0;
|
||||
|
||||
while (whitespace (string[i]))
|
||||
i++;
|
||||
|
||||
if (i)
|
||||
strcpy (string, string + i);
|
||||
|
||||
i = strlen (string) - 1;
|
||||
|
||||
while (i > 0 && whitespace (string[i]))
|
||||
i--;
|
||||
|
||||
string[++i] = '\0';
|
||||
}
|
||||
|
||||
static char *local_symbols[10];
|
||||
static int next_symbol;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "opcodes/dis-asm.h"
|
||||
#include "db_disasm.h"
|
||||
#include "regpos.h"
|
||||
|
||||
extern int * regval;
|
||||
|
@ -30,6 +30,7 @@ void print_address(unsigned int addr, FILE * outfile){
|
|||
|
||||
}
|
||||
|
||||
#ifdef GNU_DISASM
|
||||
void print_address_info(bfd_vma addr, disassemble_info * info){
|
||||
print_address((unsigned int) addr, info->stream);
|
||||
}
|
||||
|
@ -54,6 +55,23 @@ int print_insn(char *realmemaddr, char *memaddr, FILE *stream, int addrlen){
|
|||
fprintf(stderr, "invalid address length %d.\n", addrlen);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
void db_task_printsym(unsigned int addr){
|
||||
print_address(addr, stderr);
|
||||
}
|
||||
|
||||
int print_insn(char *realmemaddr, char *memaddr, FILE *stream, int addrlen)
|
||||
{
|
||||
if (addrlen == 16)
|
||||
return db_disasm((unsigned int) realmemaddr, 0, 1) -
|
||||
((unsigned int) realmemaddr);
|
||||
if (addrlen == 32)
|
||||
return db_disasm((unsigned int) realmemaddr, 0, 0) -
|
||||
((unsigned int) realmemaddr);
|
||||
fprintf(stderr, "invalid address length %d.\n", addrlen);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void info_reg(){
|
||||
|
||||
|
@ -191,7 +209,7 @@ void examine_memory(int addr, int count, char format){
|
|||
fprintf(stderr," %c", *pnt++);
|
||||
if ((i % 32) == 7) {
|
||||
fprintf(stderr,"\n");
|
||||
print_address((unsigned int) dump, stderr);
|
||||
print_address((unsigned int) pnt, stderr);
|
||||
fprintf(stderr,": ");
|
||||
};
|
||||
}
|
||||
|
@ -222,21 +240,14 @@ char * helptext[] = {
|
|||
"The commands accepted by the Wine debugger are a small subset",
|
||||
"of the commands that gdb would accept. The commands currently",
|
||||
"are:\n",
|
||||
" info [reg,stack,break]",
|
||||
" break *<addr>",
|
||||
" enable bpnum",
|
||||
" disable bpnum",
|
||||
" help",
|
||||
" quit",
|
||||
" print <expr>",
|
||||
" bt",
|
||||
" mode [16,32]",
|
||||
" symbolfile <filename>",
|
||||
" break *<addr> bt",
|
||||
" disable bpnum enable bpnum",
|
||||
" help quit",
|
||||
" x <expr> cont",
|
||||
" mode [16,32] print <expr>",
|
||||
" set <reg> = <expr> set *<expr> = <expr>",
|
||||
" info [reg,stack,break,segments] symbolfile <filename>",
|
||||
" define <identifier> <expr>",
|
||||
" x <expr>",
|
||||
" cont",
|
||||
" set <reg> = <expr>",
|
||||
" set *<expr> = <expr>",
|
||||
"",
|
||||
"The 'x' command accepts repeat counts and formats (including 'i') in the",
|
||||
"same way that gdb does.",
|
||||
|
@ -282,19 +293,19 @@ void dbg_bt(){
|
|||
return;
|
||||
}
|
||||
|
||||
frame = (struct frame *) ((SC_EBP(dbg_mask) & ~1) | (SC_SS << 16));
|
||||
|
||||
fprintf(stderr,"Backtrace:\n");
|
||||
fprintf(stderr,"%d ",frameno);
|
||||
print_address(frame->u.win32.saved_ip,stderr);
|
||||
cs = SC_CS;
|
||||
|
||||
frame = (struct frame *) ((SC_EBP(dbg_mask) & ~1) | (SC_SS << 16));
|
||||
while((cs & 3) == 3) {
|
||||
/* See if in 32 bit mode or not. Assume GDT means 32 bit. */
|
||||
if ((cs & 7) != 7) {
|
||||
void CallTo32();
|
||||
fprintf(stderr,"\n%d ",frameno++);
|
||||
print_address(frame->u.win32.saved_ip,stderr);
|
||||
if(frame->u.win32.saved_ip<((char*)CallTo32+1000))break;
|
||||
if(frame->u.win32.saved_ip<((unsigned long)CallTo32+1000))break;
|
||||
frame = (struct frame *) frame->u.win32.saved_bp;
|
||||
} else {
|
||||
cs = frame->u.win16.saved_cs;
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
#include "../../Wine.tmpl"
|
||||
|
||||
MODULE = opcodes
|
||||
|
||||
#ifdef i386
|
||||
#define xi386 1
|
||||
#undef i386
|
||||
#endif
|
||||
|
||||
SRCS = \
|
||||
dis-buf.c \
|
||||
i386-dis.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
#ifdef xi386
|
||||
#define i386 1
|
||||
#undef xi386
|
||||
#endif
|
||||
|
||||
WineRelocatableTarget($(MODULE),,$(OBJS))
|
||||
DependTarget()
|
||||
|
||||
includes::
|
||||
|
||||
install::
|
|
@ -1,141 +0,0 @@
|
|||
/* ANSI and traditional C compatability macros
|
||||
Copyright 1991, 1992 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* ANSI and traditional C compatibility macros
|
||||
|
||||
ANSI C is assumed if __STDC__ is #defined.
|
||||
|
||||
Macro ANSI C definition Traditional C definition
|
||||
----- ---- - ---------- ----------- - ----------
|
||||
PTR `void *' `char *'
|
||||
LONG_DOUBLE `long double' `double'
|
||||
VOLATILE `volatile' `'
|
||||
SIGNED `signed' `'
|
||||
PTRCONST `void *const' `char *'
|
||||
ANSI_PROTOTYPES 1 not defined
|
||||
|
||||
CONST is also defined, but is obsolete. Just use const.
|
||||
|
||||
DEFUN (name, arglist, args)
|
||||
|
||||
Defines function NAME.
|
||||
|
||||
ARGLIST lists the arguments, separated by commas and enclosed in
|
||||
parentheses. ARGLIST becomes the argument list in traditional C.
|
||||
|
||||
ARGS list the arguments with their types. It becomes a prototype in
|
||||
ANSI C, and the type declarations in traditional C. Arguments should
|
||||
be separated with `AND'. For functions with a variable number of
|
||||
arguments, the last thing listed should be `DOTS'.
|
||||
|
||||
DEFUN_VOID (name)
|
||||
|
||||
Defines a function NAME, which takes no arguments.
|
||||
|
||||
obsolete -- EXFUN (name, (prototype)) -- obsolete.
|
||||
|
||||
Replaced by PARAMS. Do not use; will disappear someday soon.
|
||||
Was used in external function declarations.
|
||||
In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
|
||||
parentheses). In traditional C it is `NAME()'.
|
||||
For a function that takes no arguments, PROTOTYPE should be `(void)'.
|
||||
|
||||
PARAMS ((args))
|
||||
|
||||
We could use the EXFUN macro to handle prototype declarations, but
|
||||
the name is misleading and the result is ugly. So we just define a
|
||||
simple macro to handle the parameter lists, as in:
|
||||
|
||||
static int foo PARAMS ((int, char));
|
||||
|
||||
This produces: `static int foo();' or `static int foo (int, char);'
|
||||
|
||||
EXFUN would have done it like this:
|
||||
|
||||
static int EXFUN (foo, (int, char));
|
||||
|
||||
but the function is not external...and it's hard to visually parse
|
||||
the function name out of the mess. EXFUN should be considered
|
||||
obsolete; new code should be written to use PARAMS.
|
||||
|
||||
For example:
|
||||
extern int printf PARAMS ((CONST char *format DOTS));
|
||||
int DEFUN(fprintf, (stream, format),
|
||||
FILE *stream AND CONST char *format DOTS) { ... }
|
||||
void DEFUN_VOID(abort) { ... }
|
||||
*/
|
||||
|
||||
#ifndef _ANSIDECL_H
|
||||
|
||||
#define _ANSIDECL_H 1
|
||||
|
||||
|
||||
/* Every source file includes this file,
|
||||
so they will all get the switch for lint. */
|
||||
/* LINTLIBRARY */
|
||||
|
||||
|
||||
#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4))
|
||||
/* All known AIX compilers implement these things (but don't always
|
||||
define __STDC__). The RISC/OS MIPS compiler defines these things
|
||||
in SVR4 mode, but does not define __STDC__. */
|
||||
|
||||
#define PTR void *
|
||||
#define PTRCONST void *CONST
|
||||
#define LONG_DOUBLE long double
|
||||
|
||||
#define AND ,
|
||||
#define NOARGS void
|
||||
#define CONST const
|
||||
#define VOLATILE volatile
|
||||
#define SIGNED signed
|
||||
#define DOTS , ...
|
||||
|
||||
#define EXFUN(name, proto) name proto
|
||||
#define DEFUN(name, arglist, args) name(args)
|
||||
#define DEFUN_VOID(name) name(void)
|
||||
|
||||
#define PROTO(type, name, arglist) type name arglist
|
||||
#define PARAMS(paramlist) paramlist
|
||||
#define ANSI_PROTOTYPES 1
|
||||
|
||||
#else /* Not ANSI C. */
|
||||
|
||||
#define PTR char *
|
||||
#define PTRCONST PTR
|
||||
#define LONG_DOUBLE double
|
||||
|
||||
#define AND ;
|
||||
#define NOARGS
|
||||
#define CONST
|
||||
#ifndef const /* some systems define it in header files for non-ansi mode */
|
||||
#define const
|
||||
#endif
|
||||
#define VOLATILE
|
||||
#define SIGNED
|
||||
#define DOTS
|
||||
|
||||
#define EXFUN(name, proto) name()
|
||||
#define DEFUN(name, arglist, args) name arglist args;
|
||||
#define DEFUN_VOID(name) name()
|
||||
#define PROTO(type, name, arglist) type name ()
|
||||
#define PARAMS(paramlist) ()
|
||||
|
||||
#endif /* ANSI C. */
|
||||
|
||||
#endif /* ansidecl.h */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,179 +0,0 @@
|
|||
/* Interface between the opcode library and its callers.
|
||||
Written by Cygnus Support, 1993.
|
||||
|
||||
The opcode library (libopcodes.a) provides instruction decoders for
|
||||
a large variety of instruction sets, callable with an identical
|
||||
interface, for making instruction-processing programs more independent
|
||||
of the instruction set being processed. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "bfd.h"
|
||||
|
||||
typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...));
|
||||
|
||||
enum dis_insn_type {
|
||||
dis_noninsn, /* Not a valid instruction */
|
||||
dis_nonbranch, /* Not a branch instruction */
|
||||
dis_branch, /* Unconditional branch */
|
||||
dis_condbranch, /* Conditional branch */
|
||||
dis_jsr, /* Jump to subroutine */
|
||||
dis_condjsr, /* Conditional jump to subroutine */
|
||||
dis_dref, /* Data reference instruction */
|
||||
dis_dref2 /* Two data references in instruction */
|
||||
};
|
||||
|
||||
/* This struct is passed into the instruction decoding routine,
|
||||
and is passed back out into each callback. The various fields are used
|
||||
for conveying information from your main routine into your callbacks,
|
||||
for passing information into the instruction decoders (such as the
|
||||
addresses of the callback functions), or for passing information
|
||||
back from the instruction decoders to their callers.
|
||||
|
||||
It must be initialized before it is first passed; this can be done
|
||||
by hand, or using one of the initialization macros below. */
|
||||
|
||||
typedef struct disassemble_info {
|
||||
fprintf_ftype fprintf_func;
|
||||
FILE *stream;
|
||||
PTR application_data;
|
||||
|
||||
/* For use by the disassembler. */
|
||||
int flags;
|
||||
PTR private_data;
|
||||
|
||||
/* Function used to get bytes to disassemble. MEMADDR is the
|
||||
address of the stuff to be disassembled, MYADDR is the address to
|
||||
put the bytes in, and LENGTH is the number of bytes to read.
|
||||
INFO is a pointer to this struct.
|
||||
Returns an errno value or 0 for success. */
|
||||
int (*read_memory_func)
|
||||
PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int length,
|
||||
struct disassemble_info *info));
|
||||
|
||||
/* Function which should be called if we get an error that we can't
|
||||
recover from. STATUS is the errno value from read_memory_func and
|
||||
MEMADDR is the address that we were trying to read. INFO is a
|
||||
pointer to this struct. */
|
||||
void (*memory_error_func)
|
||||
PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info));
|
||||
|
||||
/* Function called to print ADDR. */
|
||||
void (*print_address_func)
|
||||
PARAMS ((bfd_vma addr, struct disassemble_info *info));
|
||||
|
||||
/* These are for buffer_read_memory. */
|
||||
bfd_byte *buffer;
|
||||
bfd_vma buffer_vma;
|
||||
int buffer_length;
|
||||
|
||||
/* Results from instruction decoders. Not all decoders yet support
|
||||
this information. This info is set each time an instruction is
|
||||
decoded, and is only valid for the last such instruction.
|
||||
|
||||
To determine whether this decoder supports this information, set
|
||||
insn_info_valid to 0, decode an instruction, then check it. */
|
||||
|
||||
char insn_info_valid; /* Branch info has been set. */
|
||||
char branch_delay_insns; /* How many sequential insn's will run before
|
||||
a branch takes effect. (0 = normal) */
|
||||
char data_size; /* Size of data reference in insn, in bytes */
|
||||
enum dis_insn_type insn_type; /* Type of instruction */
|
||||
bfd_vma target; /* Target address of branch or dref, if known;
|
||||
zero if unknown. */
|
||||
bfd_vma target2; /* Second target address for dref2 */
|
||||
|
||||
} disassemble_info;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Standard disassemblers. Disassemble one instruction at the given
|
||||
target address. Return number of bytes processed. */
|
||||
typedef int (*disassembler_ftype)
|
||||
PARAMS((bfd_vma, disassemble_info *));
|
||||
|
||||
extern int print_insn_big_mips PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_little_mips PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_i286 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_i386 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_m68k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_z8001 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_z8002 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_h8300 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_h8300h PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_h8500 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_sparc PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_big_a29k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_m88k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_rs6000 PARAMS ((bfd_vma, disassemble_info*));
|
||||
|
||||
/* Fetch the disassembler for a given BFD, if that support is available. */
|
||||
extern disassembler_ftype disassembler PARAMS ((bfd *));
|
||||
|
||||
|
||||
/* This block of definitions is for particular callers who read instructions
|
||||
into a buffer before calling the instruction decoder. */
|
||||
|
||||
/* Here is a function which callers may wish to use for read_memory_func.
|
||||
It gets bytes from a buffer. */
|
||||
extern int buffer_read_memory
|
||||
PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *));
|
||||
|
||||
/* This function goes with buffer_read_memory.
|
||||
It prints a message using info->fprintf_func and info->stream. */
|
||||
extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *));
|
||||
|
||||
|
||||
/* Just print the address is hex. This is included for completeness even
|
||||
though both GDB and objdump provide their own (to print symbolic
|
||||
addresses). */
|
||||
extern void generic_print_address
|
||||
PARAMS ((bfd_vma, struct disassemble_info *));
|
||||
|
||||
#define INIT_DISASSEMBLE_INFO(INFO, STREAM) \
|
||||
(INFO).fprintf_func = (fprintf_ftype)fprintf, \
|
||||
(INFO).stream = (STREAM), \
|
||||
(INFO).buffer = NULL, \
|
||||
(INFO).buffer_vma = 0, \
|
||||
(INFO).buffer_length = 0, \
|
||||
(INFO).read_memory_func = buffer_read_memory, \
|
||||
(INFO).memory_error_func = perror_memory, \
|
||||
(INFO).print_address_func = generic_print_address, \
|
||||
(INFO).insn_info_valid = 0
|
||||
|
||||
|
||||
|
||||
|
||||
/* This block of definitions is for calling the instruction decoders
|
||||
from GDB. */
|
||||
|
||||
/* GDB--Like target_read_memory, but slightly different parameters. */
|
||||
extern int
|
||||
dis_asm_read_memory PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int len,
|
||||
disassemble_info *info));
|
||||
|
||||
/* GDB--Like memory_error with slightly different parameters. */
|
||||
extern void
|
||||
dis_asm_memory_error
|
||||
PARAMS ((int status, bfd_vma memaddr, disassemble_info *info));
|
||||
|
||||
/* GDB--Like print_address with slightly different parameters. */
|
||||
extern void
|
||||
dis_asm_print_address PARAMS ((bfd_vma addr, disassemble_info *info));
|
||||
|
||||
#define GDB_INIT_DISASSEMBLE_INFO(INFO, STREAM) \
|
||||
(INFO).fprintf_func = (fprintf_ftype)fprintf_filtered, \
|
||||
(INFO).stream = (STREAM), \
|
||||
(INFO).read_memory_func = dis_asm_read_memory, \
|
||||
(INFO).memory_error_func = dis_asm_memory_error, \
|
||||
(INFO).print_address_func = dis_asm_print_address, \
|
||||
(INFO).insn_info_valid = 0
|
|
@ -1,178 +0,0 @@
|
|||
/* Interface between the opcode library and its callers.
|
||||
Written by Cygnus Support, 1993.
|
||||
|
||||
The opcode library (libopcodes.a) provides instruction decoders for
|
||||
a large variety of instruction sets, callable with an identical
|
||||
interface, for making instruction-processing programs more independent
|
||||
of the instruction set being processed. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "bfd.h"
|
||||
|
||||
typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...));
|
||||
|
||||
enum dis_insn_type {
|
||||
dis_noninsn, /* Not a valid instruction */
|
||||
dis_nonbranch, /* Not a branch instruction */
|
||||
dis_branch, /* Unconditional branch */
|
||||
dis_condbranch, /* Conditional branch */
|
||||
dis_jsr, /* Jump to subroutine */
|
||||
dis_condjsr, /* Conditional jump to subroutine */
|
||||
dis_dref, /* Data reference instruction */
|
||||
dis_dref2 /* Two data references in instruction */
|
||||
};
|
||||
|
||||
/* This struct is passed into the instruction decoding routine,
|
||||
and is passed back out into each callback. The various fields are used
|
||||
for conveying information from your main routine into your callbacks,
|
||||
for passing information into the instruction decoders (such as the
|
||||
addresses of the callback functions), or for passing information
|
||||
back from the instruction decoders to their callers.
|
||||
|
||||
It must be initialized before it is first passed; this can be done
|
||||
by hand, or using one of the initialization macros below. */
|
||||
|
||||
typedef struct disassemble_info {
|
||||
fprintf_ftype fprintf_func;
|
||||
FILE *stream;
|
||||
PTR application_data;
|
||||
|
||||
/* For use by the disassembler. */
|
||||
int flags;
|
||||
PTR private_data;
|
||||
|
||||
/* Function used to get bytes to disassemble. MEMADDR is the
|
||||
address of the stuff to be disassembled, MYADDR is the address to
|
||||
put the bytes in, and LENGTH is the number of bytes to read.
|
||||
INFO is a pointer to this struct.
|
||||
Returns an errno value or 0 for success. */
|
||||
int (*read_memory_func)
|
||||
PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int length,
|
||||
struct disassemble_info *info));
|
||||
|
||||
/* Function which should be called if we get an error that we can't
|
||||
recover from. STATUS is the errno value from read_memory_func and
|
||||
MEMADDR is the address that we were trying to read. INFO is a
|
||||
pointer to this struct. */
|
||||
void (*memory_error_func)
|
||||
PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info));
|
||||
|
||||
/* Function called to print ADDR. */
|
||||
void (*print_address_func)
|
||||
PARAMS ((bfd_vma addr, struct disassemble_info *info));
|
||||
|
||||
/* These are for buffer_read_memory. */
|
||||
bfd_byte *buffer;
|
||||
bfd_vma buffer_vma;
|
||||
int buffer_length;
|
||||
|
||||
/* Results from instruction decoders. Not all decoders yet support
|
||||
this information. This info is set each time an instruction is
|
||||
decoded, and is only valid for the last such instruction.
|
||||
|
||||
To determine whether this decoder supports this information, set
|
||||
insn_info_valid to 0, decode an instruction, then check it. */
|
||||
|
||||
char insn_info_valid; /* Branch info has been set. */
|
||||
char branch_delay_insns; /* How many sequential insn's will run before
|
||||
a branch takes effect. (0 = normal) */
|
||||
char data_size; /* Size of data reference in insn, in bytes */
|
||||
enum dis_insn_type insn_type; /* Type of instruction */
|
||||
bfd_vma target; /* Target address of branch or dref, if known;
|
||||
zero if unknown. */
|
||||
bfd_vma target2; /* Second target address for dref2 */
|
||||
|
||||
} disassemble_info;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Standard disassemblers. Disassemble one instruction at the given
|
||||
target address. Return number of bytes processed. */
|
||||
typedef int (*disassembler_ftype)
|
||||
PARAMS((bfd_vma, disassemble_info *));
|
||||
|
||||
extern int print_insn_big_mips PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_little_mips PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_i386 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_m68k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_z8001 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_z8002 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_h8300 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_h8300h PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_h8500 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_sparc PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_big_a29k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_m88k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_rs6000 PARAMS ((bfd_vma, disassemble_info*));
|
||||
|
||||
/* Fetch the disassembler for a given BFD, if that support is available. */
|
||||
extern disassembler_ftype disassembler PARAMS ((bfd *));
|
||||
|
||||
|
||||
/* This block of definitions is for particular callers who read instructions
|
||||
into a buffer before calling the instruction decoder. */
|
||||
|
||||
/* Here is a function which callers may wish to use for read_memory_func.
|
||||
It gets bytes from a buffer. */
|
||||
extern int buffer_read_memory
|
||||
PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *));
|
||||
|
||||
/* This function goes with buffer_read_memory.
|
||||
It prints a message using info->fprintf_func and info->stream. */
|
||||
extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *));
|
||||
|
||||
|
||||
/* Just print the address is hex. This is included for completeness even
|
||||
though both GDB and objdump provide their own (to print symbolic
|
||||
addresses). */
|
||||
extern void generic_print_address
|
||||
PARAMS ((bfd_vma, struct disassemble_info *));
|
||||
|
||||
#define INIT_DISASSEMBLE_INFO(INFO, STREAM) \
|
||||
(INFO).fprintf_func = (fprintf_ftype)fprintf, \
|
||||
(INFO).stream = (STREAM), \
|
||||
(INFO).buffer = NULL, \
|
||||
(INFO).buffer_vma = 0, \
|
||||
(INFO).buffer_length = 0, \
|
||||
(INFO).read_memory_func = buffer_read_memory, \
|
||||
(INFO).memory_error_func = perror_memory, \
|
||||
(INFO).print_address_func = generic_print_address, \
|
||||
(INFO).insn_info_valid = 0
|
||||
|
||||
|
||||
|
||||
|
||||
/* This block of definitions is for calling the instruction decoders
|
||||
from GDB. */
|
||||
|
||||
/* GDB--Like target_read_memory, but slightly different parameters. */
|
||||
extern int
|
||||
dis_asm_read_memory PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int len,
|
||||
disassemble_info *info));
|
||||
|
||||
/* GDB--Like memory_error with slightly different parameters. */
|
||||
extern void
|
||||
dis_asm_memory_error
|
||||
PARAMS ((int status, bfd_vma memaddr, disassemble_info *info));
|
||||
|
||||
/* GDB--Like print_address with slightly different parameters. */
|
||||
extern void
|
||||
dis_asm_print_address PARAMS ((bfd_vma addr, disassemble_info *info));
|
||||
|
||||
#define GDB_INIT_DISASSEMBLE_INFO(INFO, STREAM) \
|
||||
(INFO).fprintf_func = (fprintf_ftype)fprintf_filtered, \
|
||||
(INFO).stream = (STREAM), \
|
||||
(INFO).read_memory_func = dis_asm_read_memory, \
|
||||
(INFO).memory_error_func = dis_asm_memory_error, \
|
||||
(INFO).print_address_func = dis_asm_print_address, \
|
||||
(INFO).insn_info_valid = 0
|
|
@ -1,70 +0,0 @@
|
|||
/* Disassemble from a buffer, for GNU.
|
||||
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "dis-asm.h"
|
||||
#include "sysdep.h"
|
||||
#include <errno.h>
|
||||
|
||||
/* Get LENGTH bytes from info's buffer, at target address memaddr.
|
||||
Transfer them to myaddr. */
|
||||
int
|
||||
buffer_read_memory (memaddr, myaddr, length, info)
|
||||
bfd_vma memaddr;
|
||||
bfd_byte *myaddr;
|
||||
int length;
|
||||
struct disassemble_info *info;
|
||||
{
|
||||
if (memaddr < info->buffer_vma
|
||||
|| memaddr + length > info->buffer_vma + info->buffer_length)
|
||||
/* Out of bounds. Use EIO because GDB uses it. */
|
||||
return EIO;
|
||||
memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Print an error message. We can assume that this is in response to
|
||||
an error return from buffer_read_memory. */
|
||||
void
|
||||
perror_memory (status, memaddr, info)
|
||||
int status;
|
||||
bfd_vma memaddr;
|
||||
struct disassemble_info *info;
|
||||
{
|
||||
if (status != EIO)
|
||||
/* Can't happen. */
|
||||
(*info->fprintf_func) (info->stream, "Unknown error %d\n", status);
|
||||
else
|
||||
/* Actually, address between memaddr and memaddr + len was
|
||||
out of bounds. */
|
||||
(*info->fprintf_func) (info->stream,
|
||||
"Address 0x%x is out of bounds.\n", memaddr);
|
||||
}
|
||||
|
||||
/* This could be in a separate file, to save miniscule amounts of space
|
||||
in statically linked executables. */
|
||||
|
||||
/* Just print the address is hex. This is included for completeness even
|
||||
though both GDB and objdump provide their own (to print symbolic
|
||||
addresses). */
|
||||
|
||||
void
|
||||
generic_print_address (addr, info)
|
||||
bfd_vma addr;
|
||||
struct disassemble_info *info;
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "0x%x", addr);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,513 +0,0 @@
|
|||
/* obstack.h - object stack macros
|
||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Summary:
|
||||
|
||||
All the apparent functions defined here are macros. The idea
|
||||
is that you would use these pre-tested macros to solve a
|
||||
very specific set of problems, and they would run fast.
|
||||
Caution: no side-effects in arguments please!! They may be
|
||||
evaluated MANY times!!
|
||||
|
||||
These macros operate a stack of objects. Each object starts life
|
||||
small, and may grow to maturity. (Consider building a word syllable
|
||||
by syllable.) An object can move while it is growing. Once it has
|
||||
been "finished" it never changes address again. So the "top of the
|
||||
stack" is typically an immature growing object, while the rest of the
|
||||
stack is of mature, fixed size and fixed address objects.
|
||||
|
||||
These routines grab large chunks of memory, using a function you
|
||||
supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
|
||||
by calling `obstack_chunk_free'. You must define them and declare
|
||||
them before using any obstack macros.
|
||||
|
||||
Each independent stack is represented by a `struct obstack'.
|
||||
Each of the obstack macros expects a pointer to such a structure
|
||||
as the first argument.
|
||||
|
||||
One motivation for this package is the problem of growing char strings
|
||||
in symbol tables. Unless you are "fascist pig with a read-only mind"
|
||||
--Gosper's immortal quote from HAKMEM item 154, out of context--you
|
||||
would not like to put any arbitrary upper limit on the length of your
|
||||
symbols.
|
||||
|
||||
In practice this often means you will build many short symbols and a
|
||||
few long symbols. At the time you are reading a symbol you don't know
|
||||
how long it is. One traditional method is to read a symbol into a
|
||||
buffer, realloc()ating the buffer every time you try to read a symbol
|
||||
that is longer than the buffer. This is beaut, but you still will
|
||||
want to copy the symbol from the buffer to a more permanent
|
||||
symbol-table entry say about half the time.
|
||||
|
||||
With obstacks, you can work differently. Use one obstack for all symbol
|
||||
names. As you read a symbol, grow the name in the obstack gradually.
|
||||
When the name is complete, finalize it. Then, if the symbol exists already,
|
||||
free the newly read name.
|
||||
|
||||
The way we do this is to take a large chunk, allocating memory from
|
||||
low addresses. When you want to build a symbol in the chunk you just
|
||||
add chars above the current "high water mark" in the chunk. When you
|
||||
have finished adding chars, because you got to the end of the symbol,
|
||||
you know how long the chars are, and you can create a new object.
|
||||
Mostly the chars will not burst over the highest address of the chunk,
|
||||
because you would typically expect a chunk to be (say) 100 times as
|
||||
long as an average object.
|
||||
|
||||
In case that isn't clear, when we have enough chars to make up
|
||||
the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
|
||||
so we just point to it where it lies. No moving of chars is
|
||||
needed and this is the second win: potentially long strings need
|
||||
never be explicitly shuffled. Once an object is formed, it does not
|
||||
change its address during its lifetime.
|
||||
|
||||
When the chars burst over a chunk boundary, we allocate a larger
|
||||
chunk, and then copy the partly formed object from the end of the old
|
||||
chunk to the beginning of the new larger chunk. We then carry on
|
||||
accreting characters to the end of the object as we normally would.
|
||||
|
||||
A special macro is provided to add a single char at a time to a
|
||||
growing object. This allows the use of register variables, which
|
||||
break the ordinary 'growth' macro.
|
||||
|
||||
Summary:
|
||||
We allocate large chunks.
|
||||
We carve out one object at a time from the current chunk.
|
||||
Once carved, an object never moves.
|
||||
We are free to append data of any size to the currently
|
||||
growing object.
|
||||
Exactly one object is growing in an obstack at any one time.
|
||||
You can run one obstack per control block.
|
||||
You may have as many control blocks as you dare.
|
||||
Because of the way we do it, you can `unwind' an obstack
|
||||
back to a previous state. (You may remove objects much
|
||||
as you would with a stack.)
|
||||
*/
|
||||
|
||||
|
||||
/* Don't do the contents of this file more than once. */
|
||||
|
||||
#ifndef __OBSTACK_H__
|
||||
#define __OBSTACK_H__
|
||||
|
||||
/* We use subtraction of (char *)0 instead of casting to int
|
||||
because on word-addressable machines a simple cast to int
|
||||
may ignore the byte-within-word field of the pointer. */
|
||||
|
||||
#ifndef __PTR_TO_INT
|
||||
#define __PTR_TO_INT(P) ((P) - (char *)0)
|
||||
#endif
|
||||
|
||||
#ifndef __INT_TO_PTR
|
||||
#define __INT_TO_PTR(P) ((P) + (char *)0)
|
||||
#endif
|
||||
|
||||
/* We need the type of the resulting object. In ANSI C it is ptrdiff_t
|
||||
but in traditional C it is usually long. If we are in ANSI C and
|
||||
don't already have ptrdiff_t get it. */
|
||||
|
||||
#if defined (__STDC__) && ! defined (offsetof)
|
||||
#if defined (__GNUC__) && defined (IN_GCC)
|
||||
/* On Next machine, the system's stddef.h screws up if included
|
||||
after we have defined just ptrdiff_t, so include all of stddef.h.
|
||||
Otherwise, define just ptrdiff_t, which is all we need. */
|
||||
#ifndef __NeXT__
|
||||
#define __need_ptrdiff_t
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
#define PTR_INT_TYPE ptrdiff_t
|
||||
#else
|
||||
#define PTR_INT_TYPE long
|
||||
#endif
|
||||
|
||||
struct _obstack_chunk /* Lives at front of each chunk. */
|
||||
{
|
||||
char *limit; /* 1 past end of this chunk */
|
||||
struct _obstack_chunk *prev; /* address of prior chunk or NULL */
|
||||
char contents[4]; /* objects begin here */
|
||||
};
|
||||
|
||||
struct obstack /* control current object in current chunk */
|
||||
{
|
||||
long chunk_size; /* preferred size to allocate chunks in */
|
||||
struct _obstack_chunk* chunk; /* address of current struct obstack_chunk */
|
||||
char *object_base; /* address of object we are building */
|
||||
char *next_free; /* where to add next char to current object */
|
||||
char *chunk_limit; /* address of char after current chunk */
|
||||
PTR_INT_TYPE temp; /* Temporary for some macros. */
|
||||
int alignment_mask; /* Mask of alignment for each object. */
|
||||
struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */
|
||||
void (*freefun) (); /* User's function to free a chunk. */
|
||||
char *extra_arg; /* first arg for chunk alloc/dealloc funcs */
|
||||
unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
|
||||
unsigned maybe_empty_object:1;/* There is a possibility that the current
|
||||
chunk contains a zero-length object. This
|
||||
prevents freeing the chunk if we allocate
|
||||
a bigger chunk to replace it. */
|
||||
unsigned alloc_failed:1; /* chunk alloc func returned 0 */
|
||||
};
|
||||
|
||||
/* Declare the external functions we use; they are in obstack.c. */
|
||||
|
||||
#ifdef __STDC__
|
||||
extern void _obstack_newchunk (struct obstack *, int);
|
||||
extern void _obstack_free (struct obstack *, void *);
|
||||
extern int _obstack_begin (struct obstack *, int, int,
|
||||
void *(*) (), void (*) ());
|
||||
extern int _obstack_begin_1 (struct obstack *, int, int,
|
||||
void *(*) (), void (*) (), void *);
|
||||
#else
|
||||
extern void _obstack_newchunk ();
|
||||
extern void _obstack_free ();
|
||||
extern int _obstack_begin ();
|
||||
extern int _obstack_begin_1 ();
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
|
||||
/* Do the function-declarations after the structs
|
||||
but before defining the macros. */
|
||||
|
||||
void obstack_init (struct obstack *obstack);
|
||||
|
||||
void * obstack_alloc (struct obstack *obstack, int size);
|
||||
|
||||
void * obstack_copy (struct obstack *obstack, void *address, int size);
|
||||
void * obstack_copy0 (struct obstack *obstack, void *address, int size);
|
||||
|
||||
void obstack_free (struct obstack *obstack, void *block);
|
||||
|
||||
void obstack_blank (struct obstack *obstack, int size);
|
||||
|
||||
void obstack_grow (struct obstack *obstack, void *data, int size);
|
||||
void obstack_grow0 (struct obstack *obstack, void *data, int size);
|
||||
|
||||
void obstack_1grow (struct obstack *obstack, int data_char);
|
||||
void obstack_ptr_grow (struct obstack *obstack, void *data);
|
||||
void obstack_int_grow (struct obstack *obstack, int data);
|
||||
|
||||
void * obstack_finish (struct obstack *obstack);
|
||||
|
||||
int obstack_object_size (struct obstack *obstack);
|
||||
|
||||
int obstack_room (struct obstack *obstack);
|
||||
void obstack_1grow_fast (struct obstack *obstack, int data_char);
|
||||
void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
|
||||
void obstack_int_grow_fast (struct obstack *obstack, int data);
|
||||
void obstack_blank_fast (struct obstack *obstack, int size);
|
||||
|
||||
void * obstack_base (struct obstack *obstack);
|
||||
void * obstack_next_free (struct obstack *obstack);
|
||||
int obstack_alignment_mask (struct obstack *obstack);
|
||||
int obstack_chunk_size (struct obstack *obstack);
|
||||
|
||||
#endif /* __STDC__ */
|
||||
|
||||
/* Non-ANSI C cannot really support alternative functions for these macros,
|
||||
so we do not declare them. */
|
||||
|
||||
/* Pointer to beginning of object being allocated or to be allocated next.
|
||||
Note that this might not be the final address of the object
|
||||
because a new chunk might be needed to hold the final size. */
|
||||
|
||||
#define obstack_base(h) ((h)->alloc_failed ? 0 : (h)->object_base)
|
||||
|
||||
/* Size for allocating ordinary chunks. */
|
||||
|
||||
#define obstack_chunk_size(h) ((h)->chunk_size)
|
||||
|
||||
/* Pointer to next byte not yet allocated in current chunk. */
|
||||
|
||||
#define obstack_next_free(h) ((h)->alloc_failed ? 0 : (h)->next_free)
|
||||
|
||||
/* Mask specifying low bits that should be clear in address of an object. */
|
||||
|
||||
#define obstack_alignment_mask(h) ((h)->alignment_mask)
|
||||
|
||||
#define obstack_init(h) \
|
||||
_obstack_begin ((h), 0, 0, \
|
||||
(void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
|
||||
|
||||
#define obstack_begin(h, size) \
|
||||
_obstack_begin ((h), (size), 0, \
|
||||
(void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
|
||||
|
||||
#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
|
||||
_obstack_begin ((h), (size), (alignment), \
|
||||
(void *(*) ()) (chunkfun), (void (*) ()) (freefun))
|
||||
|
||||
#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
|
||||
_obstack_begin_1 ((h), (size), (alignment), \
|
||||
(void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg))
|
||||
|
||||
#define obstack_chunkfun(h, newchunkfun) \
|
||||
((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun))
|
||||
|
||||
#define obstack_freefun(h, newfreefun) \
|
||||
((h) -> freefun = (void (*)()) (newfreefun))
|
||||
|
||||
#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
|
||||
|
||||
#define obstack_blank_fast(h,n) ((h)->next_free += (n))
|
||||
|
||||
#if defined (__GNUC__) && defined (__STDC__)
|
||||
#if __GNUC__ < 2
|
||||
#define __extension__
|
||||
#endif
|
||||
|
||||
/* For GNU C, if not -traditional,
|
||||
we can define these macros to compute all args only once
|
||||
without using a global variable.
|
||||
Also, we can avoid using the `temp' slot, to make faster code. */
|
||||
|
||||
#define obstack_object_size(OBSTACK) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
__o->alloc_failed ? 0 : \
|
||||
(unsigned) (__o->next_free - __o->object_base); })
|
||||
|
||||
#define obstack_room(OBSTACK) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
(unsigned) (__o->chunk_limit - __o->next_free); })
|
||||
|
||||
#define obstack_grow(OBSTACK,where,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
int __len = (length); \
|
||||
if (__o->next_free + __len > __o->chunk_limit) \
|
||||
_obstack_newchunk (__o, __len); \
|
||||
if (!__o->alloc_failed) \
|
||||
{ \
|
||||
bcopy (where, __o->next_free, __len); \
|
||||
__o->next_free += __len; \
|
||||
} \
|
||||
(void) 0; })
|
||||
|
||||
#define obstack_grow0(OBSTACK,where,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
int __len = (length); \
|
||||
if (__o->next_free + __len + 1 > __o->chunk_limit) \
|
||||
_obstack_newchunk (__o, __len + 1); \
|
||||
if (!__o->alloc_failed) \
|
||||
{ \
|
||||
bcopy (where, __o->next_free, __len); \
|
||||
__o->next_free += __len; \
|
||||
*(__o->next_free)++ = 0; \
|
||||
} \
|
||||
(void) 0; })
|
||||
|
||||
#define obstack_1grow(OBSTACK,datum) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
if (__o->next_free + 1 > __o->chunk_limit) \
|
||||
_obstack_newchunk (__o, 1); \
|
||||
if (!__o->alloc_failed) \
|
||||
*(__o->next_free)++ = (datum); \
|
||||
(void) 0; })
|
||||
|
||||
/* These assume that the obstack alignment is good enough for pointers or ints,
|
||||
and that the data added so far to the current object
|
||||
shares that much alignment. */
|
||||
|
||||
#define obstack_ptr_grow(OBSTACK,datum) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
|
||||
_obstack_newchunk (__o, sizeof (void *)); \
|
||||
if (!__o->alloc_failed) \
|
||||
*((void **)__o->next_free)++ = ((void *)datum); \
|
||||
(void) 0; })
|
||||
|
||||
#define obstack_int_grow(OBSTACK,datum) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
if (__o->next_free + sizeof (int) > __o->chunk_limit) \
|
||||
_obstack_newchunk (__o, sizeof (int)); \
|
||||
if (!__o->alloc_failed) \
|
||||
*((int *)__o->next_free)++ = ((int)datum); \
|
||||
(void) 0; })
|
||||
|
||||
#define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr)
|
||||
#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
|
||||
|
||||
#define obstack_blank(OBSTACK,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
int __len = (length); \
|
||||
if (__o->chunk_limit - __o->next_free < __len) \
|
||||
_obstack_newchunk (__o, __len); \
|
||||
if (!__o->alloc_failed) \
|
||||
__o->next_free += __len; \
|
||||
(void) 0; })
|
||||
|
||||
#define obstack_alloc(OBSTACK,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__h = (OBSTACK); \
|
||||
obstack_blank (__h, (length)); \
|
||||
obstack_finish (__h); })
|
||||
|
||||
#define obstack_copy(OBSTACK,where,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__h = (OBSTACK); \
|
||||
obstack_grow (__h, (where), (length)); \
|
||||
obstack_finish (__h); })
|
||||
|
||||
#define obstack_copy0(OBSTACK,where,length) \
|
||||
__extension__ \
|
||||
({ struct obstack *__h = (OBSTACK); \
|
||||
obstack_grow0 (__h, (where), (length)); \
|
||||
obstack_finish (__h); })
|
||||
|
||||
/* The local variable is named __o1 to avoid a name conflict
|
||||
when obstack_blank is called. */
|
||||
#define obstack_finish(OBSTACK) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o1 = (OBSTACK); \
|
||||
void *value; \
|
||||
if (__o1->alloc_failed) \
|
||||
value = 0; \
|
||||
else \
|
||||
{ \
|
||||
value = (void *) __o1->object_base; \
|
||||
if (__o1->next_free == value) \
|
||||
__o1->maybe_empty_object = 1; \
|
||||
__o1->next_free \
|
||||
= __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
|
||||
& ~ (__o1->alignment_mask)); \
|
||||
if (__o1->next_free - (char *)__o1->chunk \
|
||||
> __o1->chunk_limit - (char *)__o1->chunk) \
|
||||
__o1->next_free = __o1->chunk_limit; \
|
||||
__o1->object_base = __o1->next_free; \
|
||||
} \
|
||||
value; })
|
||||
|
||||
#define obstack_free(OBSTACK, OBJ) \
|
||||
__extension__ \
|
||||
({ struct obstack *__o = (OBSTACK); \
|
||||
void *__obj = (OBJ); \
|
||||
if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
|
||||
__o->next_free = __o->object_base = __obj; \
|
||||
else (obstack_free) (__o, __obj); })
|
||||
|
||||
#else /* not __GNUC__ or not __STDC__ */
|
||||
|
||||
#define obstack_object_size(h) \
|
||||
(unsigned) ((h)->alloc_failed ? 0 : (h)->next_free - (h)->object_base)
|
||||
|
||||
#define obstack_room(h) \
|
||||
(unsigned) ((h)->chunk_limit - (h)->next_free)
|
||||
|
||||
/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
|
||||
so that we can avoid having void expressions
|
||||
in the arms of the conditional expression.
|
||||
Casting the third operand to void was tried before,
|
||||
but some compilers won't accept it. */
|
||||
|
||||
#define obstack_grow(h,where,length) \
|
||||
( (h)->temp = (length), \
|
||||
(((h)->next_free + (h)->temp > (h)->chunk_limit) \
|
||||
? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
|
||||
((h)->alloc_failed ? 0 : \
|
||||
(bcopy (where, (h)->next_free, (h)->temp), \
|
||||
(h)->next_free += (h)->temp)))
|
||||
|
||||
#define obstack_grow0(h,where,length) \
|
||||
( (h)->temp = (length), \
|
||||
(((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \
|
||||
? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \
|
||||
((h)->alloc_failed ? 0 : \
|
||||
(bcopy (where, (h)->next_free, (h)->temp), \
|
||||
(h)->next_free += (h)->temp, \
|
||||
*((h)->next_free)++ = 0)))
|
||||
|
||||
#define obstack_1grow(h,datum) \
|
||||
( (((h)->next_free + 1 > (h)->chunk_limit) \
|
||||
? (_obstack_newchunk ((h), 1), 0) : 0), \
|
||||
((h)->alloc_failed ? 0 : \
|
||||
(*((h)->next_free)++ = (datum))))
|
||||
|
||||
#define obstack_ptr_grow(h,datum) \
|
||||
( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
|
||||
? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
|
||||
((h)->alloc_failed ? 0 : \
|
||||
(*((char **)(((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *)datum))))
|
||||
|
||||
#define obstack_int_grow(h,datum) \
|
||||
( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
|
||||
? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
|
||||
((h)->alloc_failed ? 0 : \
|
||||
(*((int *)(((h)->next_free+=sizeof(int))-sizeof(int))) = ((int)datum))))
|
||||
|
||||
#define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr)
|
||||
#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
|
||||
|
||||
#define obstack_blank(h,length) \
|
||||
( (h)->temp = (length), \
|
||||
(((h)->chunk_limit - (h)->next_free < (h)->temp) \
|
||||
? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
|
||||
((h)->alloc_failed ? 0 : \
|
||||
((h)->next_free += (h)->temp)))
|
||||
|
||||
#define obstack_alloc(h,length) \
|
||||
(obstack_blank ((h), (length)), obstack_finish ((h)))
|
||||
|
||||
#define obstack_copy(h,where,length) \
|
||||
(obstack_grow ((h), (where), (length)), obstack_finish ((h)))
|
||||
|
||||
#define obstack_copy0(h,where,length) \
|
||||
(obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
|
||||
|
||||
#define obstack_finish(h) \
|
||||
( (h)->alloc_failed ? 0 : \
|
||||
(((h)->next_free == (h)->object_base \
|
||||
? (((h)->maybe_empty_object = 1), 0) \
|
||||
: 0), \
|
||||
(h)->temp = __PTR_TO_INT ((h)->object_base), \
|
||||
(h)->next_free \
|
||||
= __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \
|
||||
& ~ ((h)->alignment_mask)), \
|
||||
(((h)->next_free - (char *)(h)->chunk \
|
||||
> (h)->chunk_limit - (char *)(h)->chunk) \
|
||||
? ((h)->next_free = (h)->chunk_limit) : 0), \
|
||||
(h)->object_base = (h)->next_free, \
|
||||
__INT_TO_PTR ((h)->temp)))
|
||||
|
||||
#ifdef __STDC__
|
||||
#define obstack_free(h,obj) \
|
||||
( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \
|
||||
(((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
|
||||
? (int) ((h)->next_free = (h)->object_base \
|
||||
= (h)->temp + (char *) (h)->chunk) \
|
||||
: (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0)))
|
||||
#else
|
||||
#define obstack_free(h,obj) \
|
||||
( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \
|
||||
(((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
|
||||
? (int) ((h)->next_free = (h)->object_base \
|
||||
= (h)->temp + (char *) (h)->chunk) \
|
||||
: (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0)))
|
||||
#endif
|
||||
|
||||
#endif /* not __GNUC__ or not __STDC__ */
|
||||
|
||||
#endif /* not __OBSTACK_H__ */
|
|
@ -27,6 +27,11 @@ A(IF1632_Saved32_ebp:)
|
|||
.long 0
|
||||
A(IF1632_Saved32_ss:)
|
||||
.word 0
|
||||
#ifdef __ELF__
|
||||
A(IF1632_ELF_KLUDGE:)
|
||||
.long 0
|
||||
.word 0x0f
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
* Places to keep info about the current 16-bit stack frame.
|
||||
|
@ -74,6 +79,16 @@ A(CallToInit16:)
|
|||
pushl A(IF1632_Saved32_ebp)
|
||||
pushw A(IF1632_Saved32_ss)
|
||||
|
||||
#ifdef __ELF__
|
||||
/* change to the other code segment */
|
||||
movw $0x0f, %ax
|
||||
movw %ax, A(IF1632_ELF_KLUDGE)+4
|
||||
movl $L4, %eax
|
||||
andl $0x0000ffff, %eax
|
||||
movl %eax,A(IF1632_ELF_KLUDGE)
|
||||
ljmp A(IF1632_ELF_KLUDGE)
|
||||
L4:
|
||||
#endif
|
||||
/*
|
||||
* Get target address.
|
||||
*/
|
||||
|
@ -147,6 +162,15 @@ A(CallToInit16:)
|
|||
popl A(IF1632_Saved32_ebp)
|
||||
popl A(IF1632_Saved32_esp)
|
||||
movl %eax,return_value
|
||||
#ifdef __ELF__
|
||||
/* change back */
|
||||
movw $0x23, %ax
|
||||
movw %ax, A(IF1632_ELF_KLUDGE)+4
|
||||
movl $L5, %eax
|
||||
movl %eax,A(IF1632_ELF_KLUDGE)
|
||||
ljmp A(IF1632_ELF_KLUDGE)
|
||||
L5:
|
||||
#endif
|
||||
popal
|
||||
movl return_value,%eax
|
||||
.align 2,0x90
|
||||
|
@ -182,7 +206,19 @@ A(CallTo16cx:)
|
|||
/*
|
||||
* Get target address and new ds
|
||||
*/
|
||||
L1: movl 8(%ebp),%eax
|
||||
L1:
|
||||
#ifdef __ELF__
|
||||
/* change code segments */
|
||||
movw $0x0f, %ax
|
||||
movw %ax, A(IF1632_ELF_KLUDGE)+4
|
||||
movl $L2, %eax
|
||||
andl $0x0000ffff, %eax
|
||||
movl %eax,A(IF1632_ELF_KLUDGE)
|
||||
ljmp A(IF1632_ELF_KLUDGE)
|
||||
L2:
|
||||
#endif
|
||||
/* At this point we have changed segments. */
|
||||
movl 8(%ebp),%eax
|
||||
movl %eax,jump_target
|
||||
lea jump_target,%edx
|
||||
movw 12(%ebp),%ax
|
||||
|
@ -244,6 +280,18 @@ L1: movl 8(%ebp),%eax
|
|||
|
||||
movl %eax,return_value
|
||||
movw return_value+2,%dx
|
||||
/* switch segments */
|
||||
#ifdef __ELF__
|
||||
movw $0x23, %ax
|
||||
movw %ax, A(IF1632_ELF_KLUDGE)+4
|
||||
movl $L3, %eax
|
||||
movl %eax,A(IF1632_ELF_KLUDGE)
|
||||
ljmp A(IF1632_ELF_KLUDGE)
|
||||
L3:
|
||||
/* back in the regular segment set up. */
|
||||
/* restore eax */
|
||||
movl return_value, %eax
|
||||
#endif
|
||||
.align 2,0x90
|
||||
leave
|
||||
ret
|
||||
|
|
|
@ -174,15 +174,15 @@ LONG CallWindowProc( WNDPROC func, HWND hwnd, WORD message,
|
|||
user_tab = FindDLLTable("USER");
|
||||
|
||||
/* DefWindowProc */
|
||||
if (user_tab[107].address == address)
|
||||
if (((LONG)user_tab[107].address &0xffff) == (LONG) address)
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
|
||||
/* DefDlgProc */
|
||||
else if (user_tab[308].address == address)
|
||||
else if (((LONG)user_tab[308].address &0xffff) == (LONG)address)
|
||||
return DefDlgProc(hwnd, message, wParam, lParam);
|
||||
|
||||
/* DefMDIChildProc */
|
||||
else if (user_tab[447].address == address)
|
||||
else if (((LONG)user_tab[447].address &0xffff) == (LONG)address)
|
||||
return DefMDIChildProc(hwnd, message, wParam, lParam);
|
||||
|
||||
/* default */
|
||||
|
|
|
@ -1,7 +1,17 @@
|
|||
/*
|
||||
* Window non-client functions definitions
|
||||
*
|
||||
* Copyright 1995 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#ifndef __WINE_NONCLIENT_H
|
||||
#define __WINE_NONCLIENT_H
|
||||
|
||||
extern LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn );
|
||||
#include "windows.h"
|
||||
|
||||
extern void NC_GetInsideRect( HWND hwnd, RECT *rect );
|
||||
extern void NC_DoNCPaint( HWND hwnd, BOOL active, BOOL suppress_menupaint );
|
||||
extern LONG NC_HandleNCPaint( HWND hwnd );
|
||||
extern LONG NC_HandleNCActivate( HWND hwnd, WORD wParam );
|
||||
extern LONG NC_HandleNCCalcSize( HWND hwnd, NCCALCSIZE_PARAMS *params );
|
||||
extern LONG NC_HandleNCHitTest( HWND hwnd, POINT pt );
|
||||
|
|
|
@ -9,23 +9,14 @@
|
|||
|
||||
#include "gdi.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD type;
|
||||
RECT box;
|
||||
Pixmap pixmap;
|
||||
Region xrgn;
|
||||
} REGION;
|
||||
|
||||
/* GDI logical region object */
|
||||
typedef struct
|
||||
{
|
||||
GDIOBJHDR header;
|
||||
REGION region;
|
||||
Region xrgn;
|
||||
} RGNOBJ;
|
||||
|
||||
|
||||
extern BOOL REGION_Init(void);
|
||||
extern BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj );
|
||||
|
||||
#endif /* __WINE_REGION_H */
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
*/
|
||||
#define MAX_SELECTORS 512
|
||||
#define SELECTOR_ISFREE 0x8000
|
||||
#define SELECTOR_IS32BIT 0x4000
|
||||
#define SELECTOR_INDEXMASK 0x0fff
|
||||
|
||||
extern unsigned short SelectorMap[MAX_SELECTORS];
|
||||
|
@ -75,10 +76,16 @@ extern int IPCCopySelector(int i_old, unsigned long new, int swap_type);
|
|||
#define GLOBAL_FLAGS_EXECUTEONLY 0x00020000
|
||||
#define GLOBAL_FLAGS_READONLY 0x00020000
|
||||
|
||||
#ifdef __ELF__
|
||||
#define FIRST_SELECTOR 2
|
||||
#define IS_16_BIT_ADDRESS(addr) \
|
||||
(!(SelectorMap[(unsigned int)(addr)>>19]& SELECTOR_IS32BIT))
|
||||
#else
|
||||
#define FIRST_SELECTOR 8
|
||||
|
||||
#define IS_16_BIT_ADDRESS(addr) \
|
||||
((unsigned int)(addr) >= (((FIRST_SELECTOR << 3) | 0x0007) << 16))
|
||||
#endif
|
||||
|
||||
|
||||
extern SEGDESC Segments[];
|
||||
|
||||
|
|
|
@ -23,5 +23,6 @@ extern unsigned int GetEntryDLLOrdinal(char *dll_name, int ordinal, int *sel,
|
|||
int *addr);
|
||||
extern unsigned int GetEntryPointFromOrdinal(struct w_files * wpnt,
|
||||
int ordinal);
|
||||
extern void InitSelectors(void);
|
||||
|
||||
#endif /* __WINE_SELECTORS_H */
|
||||
|
|
|
@ -56,12 +56,13 @@ typedef struct tagWND
|
|||
} WND;
|
||||
|
||||
/* WND flags values */
|
||||
#define WIN_ERASE_UPDATERGN 0x01 /* Update region needs erasing */
|
||||
#define WIN_NEEDS_BEGINPAINT 0x02 /* WM_PAINT sent to window */
|
||||
#define WIN_GOT_SIZEMSG 0x04 /* WM_SIZE has been sent to the window */
|
||||
#define WIN_NEEDS_BEGINPAINT 0x01 /* WM_PAINT sent to window */
|
||||
#define WIN_NEEDS_ERASEBKGND 0x02 /* WM_ERASEBKGND must be sent to window*/
|
||||
#define WIN_NEEDS_NCPAINT 0x04 /* WM_NCPAINT must be sent to window */
|
||||
#define WIN_RESTORE_MAX 0x08 /* Maximize when restoring */
|
||||
#define WIN_INTERNAL_PAINT 0x10 /* Internal WM_PAINT message pending */
|
||||
#define WIN_NO_REDRAW 0x20 /* WM_SETREDRAW called for this window */
|
||||
#define WIN_GOT_SIZEMSG 0x40 /* WM_SIZE has been sent to the window */
|
||||
|
||||
#define WIN_CLASS_INFO(wndPtr) (CLASS_FindClassPtr((wndPtr)->hClass)->wc)
|
||||
#define WIN_CLASS_STYLE(wndPtr) (WIN_CLASS_INFO(wndPtr).style)
|
||||
|
|
|
@ -1468,9 +1468,6 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE
|
|||
#define SW_SHOWMINNOACTIVE 7
|
||||
#define SW_SHOWNA 8
|
||||
#define SW_RESTORE 9
|
||||
#define SW_INTERNAL_HIDE 20
|
||||
#define SW_INTERNAL_RESTORE 21
|
||||
|
||||
|
||||
/* WM_SIZE message wParam values */
|
||||
#define SIZE_RESTORED 0
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#ifndef WINE_H
|
||||
#define WINE_H
|
||||
#if 0
|
||||
#define __ELF__
|
||||
#endif
|
||||
|
||||
extern char *WineIniFileName(void);
|
||||
extern char *WinIniFileName(void);
|
||||
|
@ -33,8 +36,12 @@ struct sigcontext_struct {
|
|||
unsigned long cr2;
|
||||
};
|
||||
#define WINE_DATA_SELECTOR 0x2b
|
||||
#ifdef __ELF__
|
||||
#define WINE_CODE_SELECTOR 0x0f
|
||||
#else
|
||||
#define WINE_CODE_SELECTOR 0x23
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
||||
#include <signal.h>
|
||||
|
|
|
@ -355,11 +355,8 @@ HICON LoadIcon(HANDLE instance, LPSTR icon_name)
|
|||
BITMAPINFO *bmi;
|
||||
BITMAPINFOHEADER *bih;
|
||||
RGBQUAD *rgbq;
|
||||
HDC hMemDC;
|
||||
HDC hMemDC2;
|
||||
HDC hdc;
|
||||
int image_size;
|
||||
HBITMAP hbmpOld1, hbmpOld2;
|
||||
|
||||
if(debugging_resource){
|
||||
printf("LoadIcon(%04X", instance);
|
||||
|
@ -422,14 +419,9 @@ HICON LoadIcon(HANDLE instance, LPSTR icon_name)
|
|||
lpico->hBitmap = 0;
|
||||
bih->biBitCount = 1;
|
||||
bih->biClrUsed = bih->biClrImportant = 2;
|
||||
rgbq[0].rgbBlue = 0xFF;
|
||||
rgbq[0].rgbGreen = 0xFF;
|
||||
rgbq[0].rgbRed = 0xFF;
|
||||
rgbq[0].rgbReserved = 0x00;
|
||||
rgbq[1].rgbBlue = 0x00;
|
||||
rgbq[1].rgbGreen = 0x00;
|
||||
rgbq[1].rgbRed = 0x00;
|
||||
rgbq[1].rgbReserved = 0x00;
|
||||
rgbq[0].rgbBlue = rgbq[0].rgbGreen = rgbq[0].rgbRed = 0x00;
|
||||
rgbq[1].rgbBlue = rgbq[1].rgbGreen = rgbq[1].rgbRed = 0xff;
|
||||
rgbq[0].rgbReserved = rgbq[1].rgbReserved = 0;
|
||||
if (bih->biSizeImage == 0) {
|
||||
if (bih->biCompression != BI_RGB) {
|
||||
fprintf(stderr,"Unknown size for compressed Icon bitmap.\n");
|
||||
|
@ -445,15 +437,6 @@ HICON LoadIcon(HANDLE instance, LPSTR icon_name)
|
|||
(BITMAPINFO *)bih, DIB_RGB_COLORS );
|
||||
GlobalUnlock(rsc_mem);
|
||||
GlobalFree(rsc_mem);
|
||||
hMemDC = CreateCompatibleDC(hdc);
|
||||
hMemDC2 = CreateCompatibleDC(hdc);
|
||||
hbmpOld1 = SelectObject(hMemDC, lpico->hBitmap);
|
||||
hbmpOld2 = SelectObject(hMemDC2, lpico->hBitMask);
|
||||
BitBlt(hMemDC, 0, 0, bih->biWidth, bih->biHeight, hMemDC2, 0, 0,SRCINVERT);
|
||||
SelectObject( hMemDC, hbmpOld1 );
|
||||
SelectObject( hMemDC2, hbmpOld2 );
|
||||
DeleteDC(hMemDC);
|
||||
DeleteDC(hMemDC2);
|
||||
ReleaseDC(GetDesktopWindow(), hdc);
|
||||
GlobalUnlock(hIcon);
|
||||
dprintf_resource(stddeb,"LoadIcon Alloc hIcon=%X\n", hIcon);
|
||||
|
|
|
@ -37,8 +37,12 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
|
|||
|
||||
#ifdef linux
|
||||
#define DEV_ZERO
|
||||
#ifdef __ELF__
|
||||
#define UTEXTSEL 0x0f
|
||||
#else
|
||||
#define UTEXTSEL 0x23
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
||||
#define PAGE_SIZE getpagesize()
|
||||
|
@ -72,6 +76,35 @@ extern char **environ;
|
|||
|
||||
unsigned int
|
||||
GetEntryPointFromOrdinal(struct w_files * wpnt, int ordinal);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* InitSelectors
|
||||
*/
|
||||
void
|
||||
InitSelectors(void) {
|
||||
int i;
|
||||
for (i = 0; i < MAX_SELECTORS; i++) {
|
||||
if (i < FIRST_SELECTOR) {
|
||||
SelectorMap[i] = SELECTOR_IS32BIT;
|
||||
#ifdef __ELF__
|
||||
/* quick hack, just reserves 4 meg for wine. */
|
||||
} else if ((i << 19) >= 0x8000000 &&
|
||||
(i << 19) <= 0x8400000) {
|
||||
SelectorMap[i]= SELECTOR_IS32BIT;
|
||||
#endif
|
||||
} else {
|
||||
SelectorMap[i]=0;
|
||||
}
|
||||
}
|
||||
#ifdef __ELF__
|
||||
/* create an ldt. */
|
||||
if (set_ldt_entry(1, 0x8000000, 65535, 1,0x1a ,1,0)) {
|
||||
perror ("set_ldt_entry");
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* FindUnusedSelectors
|
||||
|
@ -90,6 +123,8 @@ FindUnusedSelectors(int n_selectors)
|
|||
n_found = 0;
|
||||
i = FIRST_SELECTOR;
|
||||
}
|
||||
|
||||
if (SelectorMap[i] && n_found) n_found=0;
|
||||
|
||||
if (!SelectorMap[i] && ++n_found == n_selectors)
|
||||
break;
|
||||
|
@ -364,13 +399,13 @@ unsigned int PrestoChangoSelector(unsigned src_selector, unsigned dst_selector)
|
|||
if (zfile == NULL)
|
||||
zfile = fopen("/dev/zero","r");
|
||||
p = (void *) mmap((char *) dst_s->base_addr,
|
||||
((dst_s->length + PAGE_SIZE)
|
||||
((dst_s->length + PAGE_SIZE-1)
|
||||
& ~(PAGE_SIZE - 1)),
|
||||
PROT_EXEC | PROT_READ | PROT_WRITE,
|
||||
MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0);
|
||||
#else
|
||||
p = (void *) mmap((char *) dst_s->base_addr,
|
||||
((dst_s->length + PAGE_SIZE)
|
||||
((dst_s->length + PAGE_SIZE-1)
|
||||
& ~(PAGE_SIZE - 1)),
|
||||
PROT_EXEC | PROT_READ | PROT_WRITE,
|
||||
MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
|
|
|
@ -13,12 +13,6 @@
|
|||
#else
|
||||
#include <syscall.h>
|
||||
#endif
|
||||
#ifdef linux
|
||||
#define inline __inline__ /* So we can compile with -ansi */
|
||||
#include <linux/sched.h>
|
||||
#include <asm/system.h>
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
#include "wine.h"
|
||||
#include "dos_fs.h"
|
||||
|
|
|
@ -25,6 +25,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994";
|
|||
#include "desktop.h"
|
||||
#include "prototypes.h"
|
||||
#include "texts.h"
|
||||
#include "selectors.h" /* for InitSelectors prototype */
|
||||
#define DEBUG_DEFINE_VARIABLES
|
||||
#include "stddebug.h"
|
||||
#include "debug.h"
|
||||
|
@ -488,6 +489,7 @@ int main( int argc, char *argv[] )
|
|||
if (Options.desktopGeometry) MAIN_CreateDesktop( argc, argv );
|
||||
else rootWindow = DefaultRootWindow( display );
|
||||
|
||||
InitSelectors();
|
||||
MAIN_SaveSetup();
|
||||
DOS_InitFS();
|
||||
Comm_Init();
|
||||
|
|
|
@ -18,7 +18,7 @@ static char Copyright[] = "Copyright Martin Ayotte, 1994";
|
|||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "win.h"
|
||||
#include "windows.h"
|
||||
#include "user.h"
|
||||
#include "driver.h"
|
||||
#include "mmsystem.h"
|
||||
|
|
|
@ -17,7 +17,7 @@ static char Copyright[] = "Copyright Martin Ayotte, 1994";
|
|||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "win.h"
|
||||
#include "windows.h"
|
||||
#include "user.h"
|
||||
#include "driver.h"
|
||||
#include "mmsystem.h"
|
||||
|
|
|
@ -17,7 +17,7 @@ static char Copyright[] = "Copyright Martin Ayotte, 1994";
|
|||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "win.h"
|
||||
#include "windows.h"
|
||||
#include "user.h"
|
||||
#include "driver.h"
|
||||
#include "mmsystem.h"
|
||||
|
|
|
@ -16,7 +16,7 @@ static char Copyright[] = "Copyright Martin Ayotte, 1994";
|
|||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "win.h"
|
||||
#include "windows.h"
|
||||
#include "user.h"
|
||||
#include "driver.h"
|
||||
#include "mmsystem.h"
|
||||
|
|
|
@ -18,7 +18,7 @@ static char Copyright[] = "Copyright Martin Ayotte, 1994";
|
|||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "win.h"
|
||||
#include "windows.h"
|
||||
#include "user.h"
|
||||
#include "driver.h"
|
||||
#include "mmsystem.h"
|
||||
|
|
|
@ -547,7 +547,7 @@ static void BITBLT_StretchRow( int *rowSrc, int *rowDst,
|
|||
*/
|
||||
static void BITBLT_ShrinkRow( int *rowSrc, int *rowDst,
|
||||
short startSrc, short widthSrc,
|
||||
short xinc, WORD mode )
|
||||
int xinc, WORD mode )
|
||||
{
|
||||
register int xdst = xinc * startSrc;
|
||||
rowSrc += startSrc;
|
||||
|
@ -643,6 +643,10 @@ static void BITBLT_StretchImage( XImage *srcImage, XImage *dstImage,
|
|||
if ((widthSrc < widthDst) && (heightSrc < heightDst))
|
||||
mode = STRETCH_DELETESCANS;
|
||||
|
||||
if (mode != STRETCH_DELETESCANS)
|
||||
memset( rowDst, (mode == STRETCH_ANDSCANS) ? 0xff : 0x00,
|
||||
widthDst*sizeof(int) );
|
||||
|
||||
hstretch = ((widthSrc < widthDst) || (mode == STRETCH_DELETESCANS));
|
||||
vstretch = ((heightSrc < heightDst) || (mode == STRETCH_DELETESCANS));
|
||||
xinc = hstretch ? ((int)widthSrc << 16) / widthDst :
|
||||
|
@ -1225,7 +1229,8 @@ BOOL BitBlt( HDC hdcDst, short xDst, short yDst, short width, short height,
|
|||
"BitBlt: %04x %d,%d %d bpp -> %04x %d,%d %dx%dx%d rop=%06lx\n",
|
||||
hdcSrc, xSrc, ySrc, dcSrc ? dcSrc->w.bitsPerPixel : 0,
|
||||
hdcDst, xDst, yDst, width, height, dcDst->w.bitsPerPixel, rop);
|
||||
|
||||
dprintf_bitblt(stddeb," src org=%d,%d dst org=%d,%d\n",
|
||||
dcSrc->w.DCOrgX, dcSrc->w.DCOrgY, dcDst->w.DCOrgX, dcDst->w.DCOrgY );
|
||||
return BITBLT_InternalStretchBlt( dcDst, xDst, yDst, width, height,
|
||||
dcSrc, xSrc, ySrc, width, height, rop );
|
||||
}
|
||||
|
|
|
@ -24,18 +24,11 @@ static void CLIPPING_SetDeviceClipping( DC * dc )
|
|||
fprintf( stderr, "SetDeviceClipping: Rgn is 0. Please report this.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (obj->region.xrgn)
|
||||
if (obj->xrgn)
|
||||
{
|
||||
XSetRegion( display, dc->u.x.gc, obj->region.xrgn );
|
||||
XSetRegion( display, dc->u.x.gc, obj->xrgn );
|
||||
XSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY );
|
||||
}
|
||||
else if (obj->region.pixmap)
|
||||
{
|
||||
XSetClipMask( display, dc->u.x.gc, obj->region.pixmap );
|
||||
XSetClipOrigin( display, dc->u.x.gc,
|
||||
dc->w.DCOrgX + obj->region.box.left,
|
||||
dc->w.DCOrgY + obj->region.box.top );
|
||||
}
|
||||
else /* Clip everything */
|
||||
{
|
||||
XSetClipRectangles( display, dc->u.x.gc, 0, 0, NULL, 0, 0 );
|
||||
|
@ -74,7 +67,7 @@ int SelectClipRgn( HDC hdc, HRGN hrgn )
|
|||
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
|
||||
if (!dc) return ERROR;
|
||||
|
||||
dprintf_clipping(stddeb, "SelectClipRgn: %d %d\n", hdc, hrgn );
|
||||
dprintf_clipping(stddeb, "SelectClipRgn: %x %x\n", hdc, hrgn );
|
||||
|
||||
if (hrgn)
|
||||
{
|
||||
|
@ -101,7 +94,7 @@ int SelectVisRgn( HDC hdc, HRGN hrgn )
|
|||
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
|
||||
if (!dc || !hrgn) return ERROR;
|
||||
|
||||
dprintf_clipping(stddeb, "SelectVisRgn: %d %d\n", hdc, hrgn );
|
||||
dprintf_clipping(stddeb, "SelectVisRgn: %x %x\n", hdc, hrgn );
|
||||
|
||||
retval = CombineRgn( dc->w.hVisRgn, hrgn, 0, RGN_COPY );
|
||||
CLIPPING_UpdateGCRegion( dc );
|
||||
|
@ -123,7 +116,7 @@ int OffsetClipRgn( HDC hdc, short x, short y )
|
|||
return NULLREGION; /* ?? */
|
||||
}
|
||||
|
||||
dprintf_clipping(stddeb, "OffsetClipRgn: %d %d,%d\n", hdc, x, y );
|
||||
dprintf_clipping(stddeb, "OffsetClipRgn: %x %d,%d\n", hdc, x, y );
|
||||
|
||||
if (dc->w.hClipRgn)
|
||||
{
|
||||
|
@ -143,7 +136,7 @@ int OffsetVisRgn( HDC hdc, short x, short y )
|
|||
int retval;
|
||||
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
|
||||
if (!dc) return ERROR;
|
||||
dprintf_clipping(stddeb, "OffsetVisRgn: %d %d,%d\n", hdc, x, y );
|
||||
dprintf_clipping(stddeb, "OffsetVisRgn: %x %d,%d\n", hdc, x, y );
|
||||
retval = OffsetRgn( dc->w.hVisRgn, x, y );
|
||||
CLIPPING_UpdateGCRegion( dc );
|
||||
return retval;
|
||||
|
@ -202,7 +195,7 @@ int ExcludeClipRect( HDC hdc, short left, short top,
|
|||
return NULLREGION; /* ?? */
|
||||
}
|
||||
|
||||
dprintf_clipping(stddeb, "ExcludeClipRect: %d %dx%d,%dx%d\n",
|
||||
dprintf_clipping(stddeb, "ExcludeClipRect: %x %dx%d,%dx%d\n",
|
||||
hdc, left, top, right, bottom );
|
||||
return CLIPPING_IntersectClipRect( dc, left, top, right, bottom, TRUE );
|
||||
}
|
||||
|
@ -223,7 +216,7 @@ int IntersectClipRect( HDC hdc, short left, short top,
|
|||
return NULLREGION; /* ?? */
|
||||
}
|
||||
|
||||
dprintf_clipping(stddeb, "IntersectClipRect: %d %dx%d,%dx%d\n",
|
||||
dprintf_clipping(stddeb, "IntersectClipRect: %x %dx%d,%dx%d\n",
|
||||
hdc, left, top, right, bottom );
|
||||
return CLIPPING_IntersectClipRect( dc, left, top, right, bottom, FALSE );
|
||||
}
|
||||
|
@ -276,7 +269,7 @@ int ExcludeVisRect( HDC hdc, short left, short top, short right, short bottom )
|
|||
{
|
||||
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
|
||||
if (!dc) return ERROR;
|
||||
dprintf_clipping(stddeb, "ExcludeVisRect: %d %dx%d,%dx%d\n",
|
||||
dprintf_clipping(stddeb, "ExcludeVisRect: %x %dx%d,%dx%d\n",
|
||||
hdc, left, top, right, bottom );
|
||||
return CLIPPING_IntersectVisRect( dc, left, top, right, bottom, TRUE );
|
||||
}
|
||||
|
@ -290,7 +283,7 @@ int IntersectVisRect( HDC hdc, short left, short top,
|
|||
{
|
||||
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
|
||||
if (!dc) return ERROR;
|
||||
dprintf_clipping(stddeb, "IntersectVisRect: %d %dx%d,%dx%d\n",
|
||||
dprintf_clipping(stddeb, "IntersectVisRect: %x %dx%d,%dx%d\n",
|
||||
hdc, left, top, right, bottom );
|
||||
return CLIPPING_IntersectVisRect( dc, left, top, right, bottom, FALSE );
|
||||
}
|
||||
|
@ -304,7 +297,7 @@ BOOL PtVisible( HDC hdc, short x, short y )
|
|||
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
|
||||
if (!dc) return ERROR;
|
||||
|
||||
dprintf_clipping(stddeb, "PtVisible: %d %d,%d\n", hdc, x, y );
|
||||
dprintf_clipping(stddeb, "PtVisible: %x %d,%d\n", hdc, x, y );
|
||||
if (!dc->w.hGCClipRgn) return FALSE;
|
||||
return PtInRegion( dc->w.hGCClipRgn, XLPTODP(dc,x), YLPTODP(dc,y) );
|
||||
}
|
||||
|
@ -318,7 +311,8 @@ BOOL RectVisible( HDC hdc, LPRECT rect )
|
|||
RECT tmpRect;
|
||||
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
|
||||
if (!dc) return FALSE;
|
||||
dprintf_clipping(stddeb,"RectVisible: %d %p\n", hdc, rect );
|
||||
dprintf_clipping(stddeb,"RectVisible: %x %d,%dx%d,%d\n",
|
||||
hdc, rect->left, rect->top, rect->right, rect->bottom );
|
||||
if (!dc->w.hGCClipRgn) return FALSE;
|
||||
LPtoDP( hdc, (LPPOINT)rect, 2 );
|
||||
return RectInRegion( dc->w.hGCClipRgn, &tmpRect );
|
||||
|
@ -333,7 +327,7 @@ int GetClipBox( HDC hdc, LPRECT rect )
|
|||
int ret;
|
||||
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
|
||||
if (!dc) return ERROR;
|
||||
dprintf_clipping(stddeb, "GetClipBox: %d %p\n", hdc, rect );
|
||||
dprintf_clipping(stddeb, "GetClipBox: %x %p\n", hdc, rect );
|
||||
ret = GetRgnBox( dc->w.hGCClipRgn, rect );
|
||||
DPtoLP( hdc, (LPPOINT)rect, 2 );
|
||||
return ret;
|
||||
|
@ -349,7 +343,7 @@ HRGN SaveVisRgn( HDC hdc )
|
|||
RGNOBJ *obj, *copyObj;
|
||||
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
|
||||
if (!dc) return 0;
|
||||
dprintf_clipping(stddeb, "SaveVisRgn: %d\n", hdc );
|
||||
dprintf_clipping(stddeb, "SaveVisRgn: %x\n", hdc );
|
||||
if (!dc->w.hVisRgn)
|
||||
{
|
||||
fprintf( stderr, "SaveVisRgn: hVisRgn is zero. Please report this.\n" );
|
||||
|
@ -376,7 +370,7 @@ int RestoreVisRgn( HDC hdc )
|
|||
RGNOBJ *obj, *savedObj;
|
||||
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
|
||||
if (!dc || !dc->w.hVisRgn) return ERROR;
|
||||
dprintf_clipping(stddeb, "RestoreVisRgn: %d\n", hdc );
|
||||
dprintf_clipping(stddeb, "RestoreVisRgn: %x\n", hdc );
|
||||
if (!(obj = (RGNOBJ *) GDI_GetObjPtr( dc->w.hVisRgn, REGION_MAGIC )))
|
||||
return ERROR;
|
||||
if (!(saved = obj->header.hNext)) return ERROR;
|
||||
|
@ -385,5 +379,5 @@ int RestoreVisRgn( HDC hdc )
|
|||
DeleteObject( dc->w.hVisRgn );
|
||||
dc->w.hVisRgn = saved;
|
||||
CLIPPING_UpdateGCRegion( dc );
|
||||
return savedObj->region.type;
|
||||
return savedObj->xrgn ? COMPLEXREGION : NULLREGION;
|
||||
}
|
||||
|
|
|
@ -105,19 +105,25 @@ static HPALETTE COLOR_InitPalette(void)
|
|||
|
||||
size = DefaultVisual( display, DefaultScreen(display) )->map_entries;
|
||||
COLOR_ColormapSize = size;
|
||||
if (!(hSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
|
||||
sizeof(WORD)*NB_RESERVED_COLORS )))
|
||||
return FALSE;
|
||||
if (!(hRevSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
|
||||
sizeof(WORD)*size )))
|
||||
return FALSE;
|
||||
colorTranslation = (WORD *) GDI_HEAP_ADDR( hSysColorTranslation );
|
||||
revTranslation = (WORD *) GDI_HEAP_ADDR( hRevSysColorTranslation );
|
||||
if (screenDepth <= 8)
|
||||
{
|
||||
if (!(hSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
|
||||
sizeof(WORD)*NB_RESERVED_COLORS )))
|
||||
return FALSE;
|
||||
if (!(hRevSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
|
||||
sizeof(WORD)*size )))
|
||||
return FALSE;
|
||||
colorTranslation = (WORD *) GDI_HEAP_ADDR( hSysColorTranslation );
|
||||
revTranslation = (WORD *) GDI_HEAP_ADDR( hRevSysColorTranslation );
|
||||
}
|
||||
else colorTranslation = revTranslation = NULL;
|
||||
|
||||
if ((COLOR_WinColormap == DefaultColormapOfScreen(screen)) && (screenDepth <= 8))
|
||||
{
|
||||
COLOR_PaletteToPixel = (int *)malloc( sizeof(int) * size );
|
||||
COLOR_PixelToPalette = (int *)malloc( sizeof(int) * size );
|
||||
for (i = 0; i < size; i++) /* Set the default mapping */
|
||||
COLOR_PaletteToPixel[i] = COLOR_PixelToPalette[i] = i;
|
||||
}
|
||||
|
||||
for (i = 0; i < NB_RESERVED_COLORS; i++)
|
||||
|
@ -157,8 +163,8 @@ static HPALETTE COLOR_InitPalette(void)
|
|||
COLOR_PixelToPalette[color.pixel] = pixel;
|
||||
}
|
||||
}
|
||||
colorTranslation[i] = color.pixel;
|
||||
revTranslation[color.pixel] = i;
|
||||
if (colorTranslation) colorTranslation[i] = color.pixel;
|
||||
if (revTranslation) revTranslation[color.pixel] = i;
|
||||
/* Set EGA mapping if color in the first or last eight */
|
||||
if (i < 8)
|
||||
COLOR_mapEGAPixel[i] = color.pixel;
|
||||
|
|
|
@ -670,33 +670,14 @@ BOOL DrawIcon(HDC hDC, short x, short y, HICON hIcon)
|
|||
if (hIcon == (HICON)NULL) return FALSE;
|
||||
lpico = (ICONALLOC *)GlobalLock(hIcon);
|
||||
GetObject(lpico->hBitmap, sizeof(BITMAP), (LPSTR)&bm);
|
||||
dprintf_icon(stddeb,"DrawIcon / x=%d y=%d\n", x, y);
|
||||
dprintf_icon(stddeb,"DrawIcon / icon Width=%d\n",
|
||||
(int)lpico->descriptor.Width);
|
||||
dprintf_icon(stddeb,"DrawIcon / icon Height=%d\n",
|
||||
(int)lpico->descriptor.Height);
|
||||
dprintf_icon(stddeb,"DrawIcon / icon ColorCount=%d\n",
|
||||
(int)lpico->descriptor.ColorCount);
|
||||
dprintf_icon(stddeb,"DrawIcon / icon icoDIBSize=%lX\n",
|
||||
(DWORD)lpico->descriptor.icoDIBSize);
|
||||
dprintf_icon(stddeb,"DrawIcon / icon icoDIBOffset=%lX\n",
|
||||
(DWORD)lpico->descriptor.icoDIBOffset);
|
||||
dprintf_icon(stddeb,"DrawIcon / bitmap bmWidth=%d bmHeight=%d\n",
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
hMemDC = CreateCompatibleDC(hDC);
|
||||
if(debugging_icon){
|
||||
hBitTemp = SelectObject(hMemDC, lpico->hBitmap);
|
||||
BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
|
||||
SelectObject(hMemDC, lpico->hBitMask);
|
||||
BitBlt(hDC, x, y + bm.bmHeight, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
|
||||
}else{
|
||||
hBitTemp = SelectObject(hMemDC, lpico->hBitMask);
|
||||
BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCAND);
|
||||
SelectObject(hMemDC, lpico->hBitmap);
|
||||
BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCPAINT);
|
||||
}
|
||||
BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCINVERT);
|
||||
SelectObject( hMemDC, hBitTemp );
|
||||
DeleteDC(hMemDC);
|
||||
GlobalUnlock( hIcon );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -181,10 +181,6 @@ BOOL GDI_Init(void)
|
|||
|
||||
if (!BITMAP_Init()) return FALSE;
|
||||
|
||||
/* Initialise regions */
|
||||
|
||||
if (!REGION_Init()) return FALSE;
|
||||
|
||||
/* Initialise brush dithering */
|
||||
|
||||
if (!BRUSH_Init()) return FALSE;
|
||||
|
|
722
objects/region.c
722
objects/region.c
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* GDI region objects
|
||||
*
|
||||
* Copyright 1993, 1994 Alexandre Julliard
|
||||
* Copyright 1993, 1994, 1995 Alexandre Julliard
|
||||
*
|
||||
static char Copyright[] = "Copyright Alexandre Julliard, 1993, 1994";
|
||||
*/
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -13,109 +13,14 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993, 1994";
|
|||
/* #define DEBUG_REGION */
|
||||
#include "debug.h"
|
||||
|
||||
/* GC used for region operations */
|
||||
static GC regionGC = 0;
|
||||
|
||||
/***********************************************************************
|
||||
* REGION_Init
|
||||
*/
|
||||
BOOL REGION_Init(void)
|
||||
{
|
||||
Pixmap tmpPixmap;
|
||||
|
||||
/* CreateGC needs a drawable */
|
||||
tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 );
|
||||
if (tmpPixmap)
|
||||
{
|
||||
regionGC = XCreateGC( display, tmpPixmap, 0, NULL );
|
||||
XFreePixmap( display, tmpPixmap );
|
||||
if (!regionGC) return FALSE;
|
||||
XSetForeground( display, regionGC, 1 );
|
||||
XSetGraphicsExposures( display, regionGC, False );
|
||||
return TRUE;
|
||||
}
|
||||
else return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* REGION_MakePixmap
|
||||
*
|
||||
* Make a pixmap of an X region.
|
||||
*/
|
||||
static BOOL REGION_MakePixmap( REGION *region )
|
||||
{
|
||||
int width = region->box.right - region->box.left;
|
||||
int height = region->box.bottom - region->box.top;
|
||||
|
||||
if (!region->xrgn) return TRUE; /* Null region */
|
||||
region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 );
|
||||
if (!region->pixmap) return FALSE;
|
||||
XSetRegion( display, regionGC, region->xrgn );
|
||||
XSetClipOrigin( display, regionGC, -region->box.left, -region->box.top );
|
||||
XSetFunction( display, regionGC, GXset );
|
||||
XFillRectangle( display, region->pixmap, regionGC, 0, 0, width, height );
|
||||
XSetClipMask( display, regionGC, None ); /* Clear clip region */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* REGION_SetRect
|
||||
*
|
||||
* Set the bounding box of the region and create the pixmap (or the X rgn).
|
||||
* The hrgn must be valid.
|
||||
*/
|
||||
static BOOL REGION_SetRect( HRGN hrgn, LPRECT rect, BOOL createXrgn )
|
||||
{
|
||||
int width, height;
|
||||
|
||||
/* Fill region */
|
||||
|
||||
REGION * region = &((RGNOBJ *)GDI_HEAP_ADDR( hrgn ))->region;
|
||||
width = rect->right - rect->left;
|
||||
height = rect->bottom - rect->top;
|
||||
if ((width <= 0) || (height <= 0))
|
||||
{
|
||||
region->type = NULLREGION;
|
||||
region->box.left = 0;
|
||||
region->box.right = 0;
|
||||
region->box.top = 0;
|
||||
region->box.bottom = 0;
|
||||
region->pixmap = 0;
|
||||
region->xrgn = 0;
|
||||
return TRUE;
|
||||
}
|
||||
region->type = SIMPLEREGION;
|
||||
region->box = *rect;
|
||||
region->xrgn = 0;
|
||||
region->pixmap = 0;
|
||||
|
||||
if (createXrgn) /* Create and set the X region */
|
||||
{
|
||||
XRectangle xrect = { region->box.left, region->box.top, width, height};
|
||||
if (!(region->xrgn = XCreateRegion())) return FALSE;
|
||||
XUnionRectWithRegion( &xrect, region->xrgn, region->xrgn );
|
||||
}
|
||||
else /* Create the pixmap */
|
||||
{
|
||||
region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1);
|
||||
if (!region->pixmap) return FALSE;
|
||||
/* Fill the pixmap */
|
||||
XSetFunction( display, regionGC, GXclear );
|
||||
XFillRectangle(display, region->pixmap, regionGC, 0, 0, width, height);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* REGION_DeleteObject
|
||||
*/
|
||||
BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj )
|
||||
{
|
||||
if (obj->region.pixmap) XFreePixmap( display, obj->region.pixmap );
|
||||
if (obj->region.xrgn) XDestroyRegion( obj->region.xrgn );
|
||||
dprintf_region(stddeb, "DeleteRegion: %x\n", hrgn );
|
||||
if (obj->xrgn) XDestroyRegion( obj->xrgn );
|
||||
return GDI_FreeObject( hrgn );
|
||||
}
|
||||
|
||||
|
@ -128,9 +33,9 @@ int OffsetRgn( HRGN hrgn, short x, short y )
|
|||
RGNOBJ * obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
|
||||
if (!obj) return ERROR;
|
||||
dprintf_region(stddeb, "OffsetRgn: %d %d,%d\n", hrgn, x, y );
|
||||
OffsetRect( &obj->region.box, x, y );
|
||||
if (obj->region.xrgn) XOffsetRegion( obj->region.xrgn, x, y );
|
||||
return obj->region.type;
|
||||
if (!obj->xrgn) return NULLREGION;
|
||||
XOffsetRegion( obj->xrgn, x, y );
|
||||
return COMPLEXREGION;
|
||||
}
|
||||
|
||||
|
||||
|
@ -142,8 +47,19 @@ int GetRgnBox( HRGN hrgn, LPRECT rect )
|
|||
RGNOBJ * obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC );
|
||||
if (!obj) return ERROR;
|
||||
dprintf_region(stddeb, "GetRgnBox: %d\n", hrgn );
|
||||
*rect = obj->region.box;
|
||||
return obj->region.type;
|
||||
if (!obj->xrgn)
|
||||
{
|
||||
SetRectEmpty( rect );
|
||||
return NULLREGION;
|
||||
}
|
||||
else
|
||||
{
|
||||
XRectangle xrect;
|
||||
XClipBox( obj->xrgn, &xrect );
|
||||
SetRect( rect, xrect.x, xrect.y,
|
||||
xrect.x + xrect.width, xrect.y + xrect.height);
|
||||
return COMPLEXREGION;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -152,8 +68,25 @@ int GetRgnBox( HRGN hrgn, LPRECT rect )
|
|||
*/
|
||||
HRGN CreateRectRgn( short left, short top, short right, short bottom )
|
||||
{
|
||||
RECT rect = { left, top, right, bottom };
|
||||
return CreateRectRgnIndirect( &rect );
|
||||
HRGN hrgn;
|
||||
RGNOBJ *obj;
|
||||
|
||||
if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
|
||||
obj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
|
||||
if ((right > left) && (bottom > top))
|
||||
{
|
||||
XRectangle rect = { left, top, right - left, bottom - top };
|
||||
if (!(obj->xrgn = XCreateRegion()))
|
||||
{
|
||||
GDI_FreeObject( hrgn );
|
||||
return 0;
|
||||
}
|
||||
XUnionRectWithRegion( &rect, obj->xrgn, obj->xrgn );
|
||||
}
|
||||
else obj->xrgn = 0;
|
||||
dprintf_region( stddeb, "CreateRectRgn(%d,%d-%d,%d): returning %x\n",
|
||||
left, top, right, bottom, hrgn );
|
||||
return hrgn;
|
||||
}
|
||||
|
||||
|
||||
|
@ -162,20 +95,29 @@ HRGN CreateRectRgn( short left, short top, short right, short bottom )
|
|||
*/
|
||||
HRGN CreateRectRgnIndirect( LPRECT rect )
|
||||
{
|
||||
HRGN hrgn;
|
||||
return CreateRectRgn( rect->left, rect->top, rect->right, rect->bottom );
|
||||
}
|
||||
|
||||
dprintf_region(stddeb, "CreateRectRgnIndirect: %d,%d-%d,%d\n",
|
||||
rect->left, rect->top, rect->right, rect->bottom );
|
||||
|
||||
/***********************************************************************
|
||||
* SetRectRgn (GDI.172)
|
||||
*/
|
||||
void SetRectRgn( HRGN hrgn, short left, short top, short right, short bottom )
|
||||
{
|
||||
RGNOBJ * obj;
|
||||
|
||||
dprintf_region(stddeb, "SetRectRgn: %x %d,%d-%d,%d\n",
|
||||
hrgn, left, top, right, bottom );
|
||||
|
||||
/* Create region */
|
||||
|
||||
if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
|
||||
if (!REGION_SetRect( hrgn, rect, TRUE ))
|
||||
if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return;
|
||||
if (obj->xrgn) XDestroyRegion( obj->xrgn );
|
||||
if ((right > left) && (bottom > top))
|
||||
{
|
||||
GDI_FreeObject( hrgn );
|
||||
return 0;
|
||||
XRectangle rect = { left, top, right - left, bottom - top };
|
||||
if ((obj->xrgn = XCreateRegion()) != 0)
|
||||
XUnionRectWithRegion( &rect, obj->xrgn, obj->xrgn );
|
||||
}
|
||||
return hrgn;
|
||||
else obj->xrgn = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -185,81 +127,103 @@ HRGN CreateRectRgnIndirect( LPRECT rect )
|
|||
HRGN CreateRoundRectRgn( short left, short top, short right, short bottom,
|
||||
short ellipse_width, short ellipse_height )
|
||||
{
|
||||
RECT rect = { left, top, right, bottom };
|
||||
RGNOBJ * rgnObj;
|
||||
RGNOBJ * obj;
|
||||
HRGN hrgn;
|
||||
XRectangle rect;
|
||||
int asq, bsq, d, xd, yd;
|
||||
|
||||
/* Check if we can do a normal rectangle instead */
|
||||
|
||||
if ((right <= left) || (bottom <= top) ||
|
||||
(ellipse_width <= 0) || (ellipse_height <= 0))
|
||||
return CreateRectRgn( left, top, right, bottom );
|
||||
|
||||
dprintf_region(stddeb, "CreateRoundRectRgn: %d,%d-%d,%d %dx%d\n",
|
||||
left, top, right, bottom, ellipse_width, ellipse_height );
|
||||
|
||||
/* Create region */
|
||||
|
||||
if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
|
||||
if (!REGION_SetRect( hrgn, &rect, FALSE ))
|
||||
{
|
||||
GDI_FreeObject( hrgn );
|
||||
return 0;
|
||||
}
|
||||
rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
|
||||
obj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
|
||||
obj->xrgn = XCreateRegion();
|
||||
dprintf_region(stddeb,"CreateRoundRectRgn(%d,%d-%d,%d %dx%d): return=%x\n",
|
||||
left, top, right, bottom, ellipse_width, ellipse_height, hrgn );
|
||||
|
||||
/* Fill pixmap */
|
||||
|
||||
if (rgnObj->region.type != NULLREGION)
|
||||
/* Check parameters */
|
||||
|
||||
if (ellipse_width > right-left) ellipse_width = right-left;
|
||||
if (ellipse_height > bottom-top) ellipse_height = bottom-top;
|
||||
|
||||
/* Ellipse algorithm, based on an article by K. Porter */
|
||||
/* in DDJ Graphics Programming Column, 8/89 */
|
||||
|
||||
asq = ellipse_width * ellipse_width / 4; /* a^2 */
|
||||
bsq = ellipse_height * ellipse_height / 4; /* b^2 */
|
||||
d = bsq - asq * ellipse_height / 2 + asq / 4; /* b^2 - a^2b + a^2/4 */
|
||||
xd = 0;
|
||||
yd = asq * ellipse_height; /* 2a^2b */
|
||||
|
||||
rect.x = left + ellipse_width / 2;
|
||||
rect.width = right - left - ellipse_width;
|
||||
rect.height = 1;
|
||||
|
||||
/* Loop to draw first half of quadrant */
|
||||
|
||||
while (xd < yd)
|
||||
{
|
||||
int width = rgnObj->region.box.right - rgnObj->region.box.left;
|
||||
int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
|
||||
XSetFunction( display, regionGC, GXcopy );
|
||||
XFillRectangle( display, rgnObj->region.pixmap, regionGC,
|
||||
0, ellipse_height / 2,
|
||||
width, height - ellipse_height );
|
||||
XFillRectangle( display, rgnObj->region.pixmap, regionGC,
|
||||
ellipse_width / 2, 0,
|
||||
width - ellipse_width, height );
|
||||
XFillArc( display, rgnObj->region.pixmap, regionGC,
|
||||
0, 0,
|
||||
ellipse_width, ellipse_height, 0, 360*64 );
|
||||
XFillArc( display, rgnObj->region.pixmap, regionGC,
|
||||
width - ellipse_width, 0,
|
||||
ellipse_width, ellipse_height, 0, 360*64 );
|
||||
XFillArc( display, rgnObj->region.pixmap, regionGC,
|
||||
0, height - ellipse_height,
|
||||
ellipse_width, ellipse_height, 0, 360*64 );
|
||||
XFillArc( display, rgnObj->region.pixmap, regionGC,
|
||||
width - ellipse_width, height - ellipse_height,
|
||||
ellipse_width, ellipse_height, 0, 360*64 );
|
||||
if (d > 0) /* if nearest pixel is toward the center */
|
||||
{
|
||||
/* move toward center */
|
||||
rect.y = top++;
|
||||
XUnionRectWithRegion( &rect, obj->xrgn, obj->xrgn );
|
||||
rect.y = --bottom;
|
||||
XUnionRectWithRegion( &rect, obj->xrgn, obj->xrgn );
|
||||
yd -= 2*asq;
|
||||
d -= yd;
|
||||
}
|
||||
rect.x--; /* next horiz point */
|
||||
rect.width += 2;
|
||||
xd += 2*bsq;
|
||||
d += bsq + xd;
|
||||
}
|
||||
|
||||
/* Loop to draw second half of quadrant */
|
||||
|
||||
d += (3 * (asq-bsq) / 2 - (xd+yd)) / 2;
|
||||
while (yd >= 0)
|
||||
{
|
||||
/* next vertical point */
|
||||
rect.y = top++;
|
||||
XUnionRectWithRegion( &rect, obj->xrgn, obj->xrgn );
|
||||
rect.y = --bottom;
|
||||
XUnionRectWithRegion( &rect, obj->xrgn, obj->xrgn );
|
||||
if (d < 0) /* if nearest pixel is outside ellipse */
|
||||
{
|
||||
rect.x--; /* move away from center */
|
||||
rect.width += 2;
|
||||
xd += 2*bsq;
|
||||
d += xd;
|
||||
}
|
||||
yd -= 2*asq;
|
||||
d += asq - yd;
|
||||
}
|
||||
|
||||
/* Add the inside rectangle */
|
||||
|
||||
if (top <= bottom)
|
||||
{
|
||||
rect.y = top;
|
||||
rect.height = bottom - top + 1;
|
||||
XUnionRectWithRegion( &rect, obj->xrgn, obj->xrgn );
|
||||
}
|
||||
|
||||
return hrgn;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetRectRgn (GDI.172)
|
||||
*/
|
||||
void SetRectRgn( HRGN hrgn, short left, short top, short right, short bottom )
|
||||
{
|
||||
RECT rect = { left, top, right, bottom };
|
||||
RGNOBJ * rgnObj;
|
||||
|
||||
dprintf_region(stddeb, "SetRectRgn: %d %d,%d-%d,%d\n",
|
||||
hrgn, left, top, right, bottom );
|
||||
|
||||
/* Free previous pixmap */
|
||||
|
||||
if (!(rgnObj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return;
|
||||
if (rgnObj->region.pixmap) XFreePixmap( display, rgnObj->region.pixmap );
|
||||
if (rgnObj->region.xrgn) XDestroyRegion( rgnObj->region.xrgn );
|
||||
REGION_SetRect( hrgn, &rect, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateEllipticRgn (GDI.54)
|
||||
*/
|
||||
HRGN CreateEllipticRgn( short left, short top, short right, short bottom )
|
||||
{
|
||||
RECT rect = { left, top, right, bottom };
|
||||
return CreateEllipticRgnIndirect( &rect );
|
||||
return CreateRoundRectRgn( left, top, right, bottom,
|
||||
right-left, bottom-top );
|
||||
}
|
||||
|
||||
|
||||
|
@ -268,34 +232,8 @@ HRGN CreateEllipticRgn( short left, short top, short right, short bottom )
|
|||
*/
|
||||
HRGN CreateEllipticRgnIndirect( LPRECT rect )
|
||||
{
|
||||
RGNOBJ * rgnObj;
|
||||
HRGN hrgn;
|
||||
|
||||
dprintf_region(stddeb, "CreateEllipticRgnIndirect: %d,%d-%d,%d\n",
|
||||
rect->left, rect->top, rect->right, rect->bottom );
|
||||
|
||||
/* Create region */
|
||||
|
||||
if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
|
||||
if (!REGION_SetRect( hrgn, rect, FALSE ))
|
||||
{
|
||||
GDI_FreeObject( hrgn );
|
||||
return 0;
|
||||
}
|
||||
rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
|
||||
|
||||
/* Fill pixmap */
|
||||
|
||||
if (rgnObj->region.type != NULLREGION)
|
||||
{
|
||||
int width = rgnObj->region.box.right - rgnObj->region.box.left;
|
||||
int height = rgnObj->region.box.bottom - rgnObj->region.box.top;
|
||||
XSetFunction( display, regionGC, GXcopy );
|
||||
XFillArc( display, rgnObj->region.pixmap, regionGC,
|
||||
0, 0, width, height, 0, 360*64 );
|
||||
}
|
||||
|
||||
return hrgn;
|
||||
return CreateRoundRectRgn(rect->left, rect->top, rect->right, rect->bottom,
|
||||
rect->right-rect->left, rect->bottom-rect->top );
|
||||
}
|
||||
|
||||
|
||||
|
@ -314,15 +252,12 @@ HRGN CreatePolygonRgn( POINT * points, short count, short mode )
|
|||
HRGN CreatePolyPolygonRgn( POINT * points, short * count,
|
||||
short nbpolygons, short mode )
|
||||
{
|
||||
RGNOBJ * rgnObj;
|
||||
RGNOBJ * obj;
|
||||
HRGN hrgn;
|
||||
int i, j, maxPoints;
|
||||
XPoint *xpoints, *pt;
|
||||
XRectangle rect;
|
||||
Region xrgn;
|
||||
|
||||
dprintf_region(stddeb, "CreatePolyPolygonRgn: %d polygons\n", nbpolygons );
|
||||
|
||||
/* Allocate points array */
|
||||
|
||||
if (!nbpolygons) return 0;
|
||||
|
@ -339,10 +274,10 @@ HRGN CreatePolyPolygonRgn( POINT * points, short * count,
|
|||
free( xpoints );
|
||||
return 0;
|
||||
}
|
||||
rgnObj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
|
||||
rgnObj->region.type = SIMPLEREGION;
|
||||
rgnObj->region.xrgn = 0;
|
||||
rgnObj->region.pixmap = 0;
|
||||
obj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
|
||||
obj->xrgn = 0;
|
||||
dprintf_region(stddeb, "CreatePolyPolygonRgn: %d polygons, returning %x\n",
|
||||
nbpolygons, hrgn );
|
||||
|
||||
/* Create X region */
|
||||
|
||||
|
@ -357,7 +292,7 @@ HRGN CreatePolyPolygonRgn( POINT * points, short * count,
|
|||
(mode == WINDING) ? WindingRule : EvenOddRule );
|
||||
if (!xrgn)
|
||||
{
|
||||
if (rgnObj->region.xrgn) XDestroyRegion( rgnObj->region.xrgn );
|
||||
if (obj->xrgn) XDestroyRegion( obj->xrgn );
|
||||
free( xpoints );
|
||||
GDI_FreeObject( hrgn );
|
||||
return 0;
|
||||
|
@ -365,18 +300,15 @@ HRGN CreatePolyPolygonRgn( POINT * points, short * count,
|
|||
if (i > 0)
|
||||
{
|
||||
Region tmprgn = XCreateRegion();
|
||||
if (mode == WINDING) XUnionRegion(xrgn,rgnObj->region.xrgn,tmprgn);
|
||||
else XXorRegion( xrgn, rgnObj->region.xrgn, tmprgn );
|
||||
XDestroyRegion( rgnObj->region.xrgn );
|
||||
rgnObj->region.xrgn = tmprgn;
|
||||
if (mode == WINDING) XUnionRegion( xrgn, obj->xrgn, tmprgn );
|
||||
else XXorRegion( xrgn, obj->xrgn, tmprgn );
|
||||
XDestroyRegion( obj->xrgn );
|
||||
obj->xrgn = tmprgn;
|
||||
}
|
||||
else rgnObj->region.xrgn = xrgn;
|
||||
else obj->xrgn = xrgn;
|
||||
}
|
||||
|
||||
free( xpoints );
|
||||
XClipBox( rgnObj->region.xrgn, &rect );
|
||||
SetRect( &rgnObj->region.box, rect.x, rect.y,
|
||||
rect.x + rect.width, rect.y + rect.height);
|
||||
return hrgn;
|
||||
}
|
||||
|
||||
|
@ -386,26 +318,11 @@ HRGN CreatePolyPolygonRgn( POINT * points, short * count,
|
|||
*/
|
||||
BOOL PtInRegion( HRGN hrgn, short x, short y )
|
||||
{
|
||||
BOOL res;
|
||||
RGNOBJ * obj;
|
||||
POINT pt = { x, y };
|
||||
|
||||
if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE;
|
||||
if (!PtInRect( &obj->region.box, pt )) return FALSE;
|
||||
if (obj->region.xrgn)
|
||||
{
|
||||
return XPointInRegion( obj->region.xrgn, x, y );
|
||||
}
|
||||
else
|
||||
{
|
||||
XImage *image = XGetImage( display, obj->region.pixmap,
|
||||
x - obj->region.box.left, y - obj->region.box.top,
|
||||
1, 1, AllPlanes, ZPixmap );
|
||||
if (!image) return FALSE;
|
||||
res = (XGetPixel( image, 0, 0 ) != 0);
|
||||
XDestroyImage( image );
|
||||
}
|
||||
return res;
|
||||
if (!obj->xrgn) return FALSE;
|
||||
return XPointInRegion( obj->xrgn, x, y );
|
||||
}
|
||||
|
||||
|
||||
|
@ -414,40 +331,13 @@ BOOL PtInRegion( HRGN hrgn, short x, short y )
|
|||
*/
|
||||
BOOL RectInRegion( HRGN hrgn, LPRECT rect )
|
||||
{
|
||||
XImage * image;
|
||||
RGNOBJ * obj;
|
||||
RECT intersect;
|
||||
int x, y;
|
||||
|
||||
if (!(obj = (RGNOBJ *) GDI_GetObjPtr( hrgn, REGION_MAGIC ))) return FALSE;
|
||||
if (obj->region.xrgn)
|
||||
{
|
||||
return (XRectInRegion( obj->region.xrgn, rect->left, rect->top,
|
||||
rect->right-rect->left,
|
||||
rect->bottom-rect->top ) != RectangleOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IntersectRect( &intersect, &obj->region.box, rect )) return FALSE;
|
||||
|
||||
image = XGetImage( display, obj->region.pixmap,
|
||||
intersect.left - obj->region.box.left,
|
||||
intersect.top - obj->region.box.top,
|
||||
intersect.right - intersect.left,
|
||||
intersect.bottom - intersect.top,
|
||||
AllPlanes, ZPixmap );
|
||||
if (!image) return FALSE;
|
||||
for (y = 0; y < image->height; y++)
|
||||
for (x = 0; x < image->width; x++)
|
||||
if (XGetPixel( image, x, y ) != 0)
|
||||
{
|
||||
XDestroyImage( image );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
XDestroyImage( image );
|
||||
}
|
||||
return FALSE;
|
||||
if (!obj->xrgn) return FALSE;
|
||||
return (XRectInRegion( obj->xrgn, rect->left, rect->top,
|
||||
rect->right-rect->left,
|
||||
rect->bottom-rect->top ) != RectangleOut);
|
||||
}
|
||||
|
||||
|
||||
|
@ -457,72 +347,10 @@ BOOL RectInRegion( HRGN hrgn, LPRECT rect )
|
|||
BOOL EqualRgn( HRGN rgn1, HRGN rgn2 )
|
||||
{
|
||||
RGNOBJ *obj1, *obj2;
|
||||
XImage *image1, *image2;
|
||||
Pixmap pixmap1, pixmap2;
|
||||
int width, height, x, y;
|
||||
|
||||
/* Compare bounding boxes */
|
||||
|
||||
if (!(obj1 = (RGNOBJ *) GDI_GetObjPtr( rgn1, REGION_MAGIC ))) return FALSE;
|
||||
if (!(obj2 = (RGNOBJ *) GDI_GetObjPtr( rgn2, REGION_MAGIC ))) return FALSE;
|
||||
if (obj1->region.type == NULLREGION)
|
||||
return (obj2->region.type == NULLREGION);
|
||||
else if (obj2->region.type == NULLREGION) return FALSE;
|
||||
if (!EqualRect( &obj1->region.box, &obj2->region.box )) return FALSE;
|
||||
if (obj1->region.xrgn && obj2->region.xrgn)
|
||||
{
|
||||
return XEqualRegion( obj1->region.xrgn, obj2->region.xrgn );
|
||||
}
|
||||
|
||||
/* Get pixmap contents */
|
||||
|
||||
if (!(pixmap1 = obj1->region.pixmap) &&
|
||||
!REGION_MakePixmap( &obj1->region )) return FALSE;
|
||||
if (!(pixmap2 = obj2->region.pixmap) &&
|
||||
!REGION_MakePixmap( &obj2->region )) return FALSE;
|
||||
width = obj1->region.box.right - obj1->region.box.left;
|
||||
height = obj1->region.box.bottom - obj1->region.box.top;
|
||||
image1 = XGetImage( display, obj1->region.pixmap,
|
||||
0, 0, width, height, AllPlanes, ZPixmap );
|
||||
image2 = XGetImage( display, obj2->region.pixmap,
|
||||
0, 0, width, height, AllPlanes, ZPixmap );
|
||||
if (!image1 || !image2)
|
||||
{
|
||||
if (image1) XDestroyImage( image1 );
|
||||
if (image2) XDestroyImage( image2 );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Compare pixmaps */
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = 0; x < width; x++)
|
||||
if (XGetPixel( image1, x, y ) != XGetPixel( image2, x, y))
|
||||
{
|
||||
XDestroyImage( image1 );
|
||||
XDestroyImage( image2 );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
XDestroyImage( image1 );
|
||||
XDestroyImage( image2 );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* REGION_CopyIntersection
|
||||
*
|
||||
* Copy to dest->pixmap the area of src->pixmap delimited by
|
||||
* the intersection of dest and src regions, using the current GC function.
|
||||
*/
|
||||
void REGION_CopyIntersection( REGION * dest, REGION * src )
|
||||
{
|
||||
RECT inter;
|
||||
if (!IntersectRect( &inter, &dest->box, &src->box )) return;
|
||||
XCopyArea( display, src->pixmap, dest->pixmap, regionGC,
|
||||
inter.left - src->box.left, inter.top - src->box.top,
|
||||
inter.right - inter.left, inter.bottom - inter.top,
|
||||
inter.left - dest->box.left, inter.top - dest->box.top );
|
||||
if (!obj1->xrgn || !obj2->xrgn) return (!obj1->xrgn && !obj2->xrgn);
|
||||
return XEqualRegion( obj1->xrgn, obj2->xrgn );
|
||||
}
|
||||
|
||||
|
||||
|
@ -533,37 +361,20 @@ void REGION_CopyIntersection( REGION * dest, REGION * src )
|
|||
*/
|
||||
static int REGION_CopyRegion( RGNOBJ *src, RGNOBJ *dest )
|
||||
{
|
||||
if (dest->region.pixmap) XFreePixmap( display, dest->region.pixmap );
|
||||
dest->region.type = src->region.type;
|
||||
dest->region.box = src->region.box;
|
||||
dest->region.pixmap = 0;
|
||||
if (src->region.xrgn) /* Copy only the X region */
|
||||
if (src->xrgn)
|
||||
{
|
||||
Region tmprgn = XCreateRegion();
|
||||
if (!dest->region.xrgn) dest->region.xrgn = XCreateRegion();
|
||||
XUnionRegion( tmprgn, src->region.xrgn, dest->region.xrgn );
|
||||
if (!dest->xrgn) dest->xrgn = XCreateRegion();
|
||||
XUnionRegion( tmprgn, src->xrgn, dest->xrgn );
|
||||
XDestroyRegion( tmprgn );
|
||||
return COMPLEXREGION;
|
||||
}
|
||||
else /* Copy the pixmap (if any) */
|
||||
else
|
||||
{
|
||||
if (dest->region.xrgn)
|
||||
{
|
||||
XDestroyRegion( dest->region.xrgn );
|
||||
dest->region.xrgn = 0;
|
||||
}
|
||||
if (src->region.pixmap)
|
||||
{
|
||||
int width = src->region.box.right - src->region.box.left;
|
||||
int height = src->region.box.bottom - src->region.box.top;
|
||||
|
||||
dest->region.pixmap = XCreatePixmap( display, rootWindow,
|
||||
width, height, 1 );
|
||||
XSetFunction( display, regionGC, GXcopy );
|
||||
XCopyArea( display, src->region.pixmap, dest->region.pixmap,
|
||||
regionGC, 0, 0, width, height, 0, 0 );
|
||||
}
|
||||
if (dest->xrgn) XDestroyRegion( dest->xrgn );
|
||||
dest->xrgn = 0;
|
||||
return NULLREGION;
|
||||
}
|
||||
return dest->region.type;
|
||||
}
|
||||
|
||||
|
||||
|
@ -573,12 +384,9 @@ static int REGION_CopyRegion( RGNOBJ *src, RGNOBJ *dest )
|
|||
int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode )
|
||||
{
|
||||
RGNOBJ *destObj, *src1Obj, *src2Obj;
|
||||
REGION * region;
|
||||
int width, height;
|
||||
BOOL res;
|
||||
|
||||
dprintf_region(stddeb, "CombineRgn: %d %d %d %d\n",
|
||||
hDest, hSrc1, hSrc2, mode );
|
||||
dprintf_region(stddeb, "CombineRgn: %x,%x -> %x mode=%x\n",
|
||||
hSrc1, hSrc2, hDest, mode );
|
||||
|
||||
if (!(destObj = (RGNOBJ *) GDI_GetObjPtr( hDest, REGION_MAGIC )))
|
||||
return ERROR;
|
||||
|
@ -588,183 +396,57 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode )
|
|||
|
||||
if (!(src2Obj = (RGNOBJ *) GDI_GetObjPtr( hSrc2, REGION_MAGIC )))
|
||||
return ERROR;
|
||||
region = &destObj->region;
|
||||
|
||||
/* Some optimizations for null regions */
|
||||
|
||||
if (src1Obj->region.type == NULLREGION)
|
||||
if (!src1Obj->xrgn || !src2Obj->xrgn)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case RGN_AND:
|
||||
case RGN_DIFF:
|
||||
if (region->xrgn) XDestroyRegion( region->xrgn );
|
||||
if (region->pixmap) XFreePixmap( display, region->pixmap );
|
||||
region->type = NULLREGION;
|
||||
region->xrgn = 0;
|
||||
if (src1Obj->xrgn)
|
||||
return REGION_CopyRegion( src1Obj, destObj );
|
||||
/* else fall through */
|
||||
case RGN_AND:
|
||||
if (destObj->xrgn) XDestroyRegion( destObj->xrgn );
|
||||
destObj->xrgn = 0;
|
||||
return NULLREGION;
|
||||
case RGN_OR:
|
||||
case RGN_XOR:
|
||||
return REGION_CopyRegion( src2Obj, destObj );
|
||||
default:
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else if (src2Obj->region.type == NULLREGION)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case RGN_AND:
|
||||
if (region->xrgn) XDestroyRegion( region->xrgn );
|
||||
if (region->pixmap) XFreePixmap( display, region->pixmap );
|
||||
region->type = NULLREGION;
|
||||
region->xrgn = 0;
|
||||
return NULLREGION;
|
||||
case RGN_OR:
|
||||
case RGN_XOR:
|
||||
case RGN_DIFF:
|
||||
return REGION_CopyRegion( src1Obj, destObj );
|
||||
if (src1Obj->xrgn)
|
||||
return REGION_CopyRegion( src1Obj, destObj );
|
||||
else
|
||||
return REGION_CopyRegion( src2Obj, destObj );
|
||||
default:
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (src1Obj->region.xrgn && src2Obj->region.xrgn)
|
||||
{
|
||||
/* Perform the operation with X regions */
|
||||
|
||||
if (region->pixmap) XFreePixmap( display, region->pixmap );
|
||||
region->pixmap = 0;
|
||||
if (!region->xrgn) region->xrgn = XCreateRegion();
|
||||
switch(mode)
|
||||
{
|
||||
case RGN_AND:
|
||||
XIntersectRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
|
||||
region->xrgn );
|
||||
break;
|
||||
case RGN_OR:
|
||||
XUnionRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
|
||||
region->xrgn );
|
||||
break;
|
||||
case RGN_XOR:
|
||||
XXorRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
|
||||
region->xrgn );
|
||||
break;
|
||||
case RGN_DIFF:
|
||||
XSubtractRegion( src1Obj->region.xrgn, src2Obj->region.xrgn,
|
||||
region->xrgn );
|
||||
break;
|
||||
default:
|
||||
return ERROR;
|
||||
}
|
||||
if (XEmptyRegion(region->xrgn))
|
||||
{
|
||||
XDestroyRegion( region->xrgn );
|
||||
region->type = NULLREGION;
|
||||
region->xrgn = 0;
|
||||
return NULLREGION;
|
||||
}
|
||||
else
|
||||
{
|
||||
XRectangle rect;
|
||||
XClipBox( region->xrgn, &rect );
|
||||
region->type = COMPLEXREGION;
|
||||
region->box.left = rect.x;
|
||||
region->box.top = rect.y;
|
||||
region->box.right = rect.x + rect.width;
|
||||
region->box.bottom = rect.y + rect.height;
|
||||
return COMPLEXREGION;
|
||||
}
|
||||
}
|
||||
else /* Create pixmaps if needed */
|
||||
{
|
||||
if (!src1Obj->region.pixmap)
|
||||
if (!REGION_MakePixmap( &src1Obj->region )) return ERROR;
|
||||
if (!src2Obj->region.pixmap)
|
||||
if (!REGION_MakePixmap( &src2Obj->region )) return ERROR;
|
||||
}
|
||||
|
||||
/* Perform the operation with the two X regions */
|
||||
|
||||
if (!destObj->xrgn) destObj->xrgn = XCreateRegion();
|
||||
switch(mode)
|
||||
{
|
||||
case RGN_AND:
|
||||
res = IntersectRect( ®ion->box, &src1Obj->region.box,
|
||||
&src2Obj->region.box );
|
||||
region->type = COMPLEXREGION;
|
||||
break;
|
||||
|
||||
case RGN_OR:
|
||||
case RGN_XOR:
|
||||
res = UnionRect( ®ion->box, &src1Obj->region.box,
|
||||
&src2Obj->region.box );
|
||||
region->type = COMPLEXREGION;
|
||||
break;
|
||||
|
||||
case RGN_DIFF:
|
||||
res = SubtractRect( ®ion->box, &src1Obj->region.box,
|
||||
&src2Obj->region.box );
|
||||
region->type = COMPLEXREGION;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR;
|
||||
case RGN_AND:
|
||||
XIntersectRegion( src1Obj->xrgn, src2Obj->xrgn, destObj->xrgn );
|
||||
break;
|
||||
case RGN_OR:
|
||||
XUnionRegion( src1Obj->xrgn, src2Obj->xrgn, destObj->xrgn );
|
||||
break;
|
||||
case RGN_XOR:
|
||||
XXorRegion( src1Obj->xrgn, src2Obj->xrgn, destObj->xrgn );
|
||||
break;
|
||||
case RGN_DIFF:
|
||||
XSubtractRegion( src1Obj->xrgn, src2Obj->xrgn, destObj->xrgn );
|
||||
break;
|
||||
default:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (region->pixmap) XFreePixmap( display, region->pixmap );
|
||||
if (region->xrgn) XDestroyRegion( region->xrgn );
|
||||
if (!res)
|
||||
if (XEmptyRegion(destObj->xrgn))
|
||||
{
|
||||
region->type = NULLREGION;
|
||||
region->pixmap = 0;
|
||||
region->xrgn = 0;
|
||||
return NULLREGION;
|
||||
XDestroyRegion( destObj->xrgn );
|
||||
destObj->xrgn = 0;
|
||||
return NULLREGION;
|
||||
}
|
||||
|
||||
width = region->box.right - region->box.left;
|
||||
height = region->box.bottom - region->box.top;
|
||||
if (!width || !height)
|
||||
{
|
||||
fprintf(stderr, "CombineRgn: width or height is 0. Please report this.\n" );
|
||||
fprintf(stderr, "src1=%d,%d-%d,%d src2=%d,%d-%d,%d dst=%d,%d-%d,%d op=%d\n",
|
||||
src1Obj->region.box.left, src1Obj->region.box.top,
|
||||
src1Obj->region.box.right, src1Obj->region.box.bottom,
|
||||
src2Obj->region.box.left, src2Obj->region.box.top,
|
||||
src2Obj->region.box.right, src2Obj->region.box.bottom,
|
||||
region->box.left, region->box.top,
|
||||
region->box.right, region->box.bottom, mode );
|
||||
exit(1);
|
||||
}
|
||||
region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 );
|
||||
region->xrgn = 0;
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case RGN_AND:
|
||||
XSetFunction( display, regionGC, GXcopy );
|
||||
REGION_CopyIntersection( region, &src1Obj->region );
|
||||
XSetFunction( display, regionGC, GXand );
|
||||
REGION_CopyIntersection( region, &src2Obj->region );
|
||||
break;
|
||||
|
||||
case RGN_OR:
|
||||
case RGN_XOR:
|
||||
XSetFunction( display, regionGC, GXclear );
|
||||
XFillRectangle( display, region->pixmap, regionGC,
|
||||
0, 0, width, height );
|
||||
XSetFunction( display, regionGC, (mode == RGN_OR) ? GXor : GXxor);
|
||||
REGION_CopyIntersection( region, &src1Obj->region );
|
||||
REGION_CopyIntersection( region, &src2Obj->region );
|
||||
break;
|
||||
|
||||
case RGN_DIFF:
|
||||
XSetFunction( display, regionGC, GXclear );
|
||||
XFillRectangle( display, region->pixmap, regionGC,
|
||||
0, 0, width, height );
|
||||
XSetFunction( display, regionGC, GXcopy );
|
||||
REGION_CopyIntersection( region, &src1Obj->region );
|
||||
XSetFunction( display, regionGC, GXandInverted );
|
||||
REGION_CopyIntersection( region, &src2Obj->region );
|
||||
break;
|
||||
}
|
||||
return region->type;
|
||||
else return COMPLEXREGION;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ $(RCOBJS): winerc $(TOP)/include/windows.h
|
|||
includes::
|
||||
|
||||
clean::
|
||||
$(RM) $(RCSRCS:.rc=.c)
|
||||
$(RM) $(RCSRCS:.rc=.c) $(RCSRCS:.rc=.h)
|
||||
|
||||
|
||||
XCOMM Rules to build the winerc program
|
||||
|
|
|
@ -7,8 +7,12 @@
|
|||
#include "wine.h"
|
||||
|
||||
#ifdef linux
|
||||
#ifdef __ELF__
|
||||
#define UTEXTSEL 0x0f
|
||||
#else
|
||||
#define UTEXTSEL 0x23
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
||||
#define UTEXTSEL 0x1f
|
||||
#endif
|
||||
|
@ -753,20 +757,29 @@ int main(int argc, char **argv)
|
|||
|
||||
sprintf(filename, "dll_%s.S", LowerDLLName);
|
||||
fp = fopen(filename, "w");
|
||||
|
||||
fprintf (fp, "#define __ASSEMBLY__\n");
|
||||
fprintf (fp, "#include <asm/segment.h>\n");
|
||||
fprintf(fp, "\t.globl " PREFIX "%s_Dispatch\n", UpperDLLName);
|
||||
fprintf(fp, PREFIX "%s_Dispatch:\n", UpperDLLName);
|
||||
fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
|
||||
fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
|
||||
fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
|
||||
fprintf(fp, "\tjmp\t" PREFIX "CallTo32\n\n");
|
||||
#ifdef __ELF__
|
||||
fprintf(fp, "\tljmp\t$USER_CS, $" PREFIX "CallTo32\n\n");
|
||||
#else
|
||||
fprintf(fp, "\tjmp\t_CallTo32\n\n");
|
||||
#endif
|
||||
|
||||
fprintf(fp, "\t.globl " PREFIX "%s_Dispatch_16\n", UpperDLLName);
|
||||
fprintf(fp, PREFIX "%s_Dispatch_16:\n", UpperDLLName);
|
||||
fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
|
||||
fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
|
||||
fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
|
||||
fprintf(fp, "\tjmp\t" PREFIX "CallTo32_16\n\n");
|
||||
#ifdef __ELF__
|
||||
fprintf(fp, "\tljmp\t$USER_CS, $" PREFIX "CallTo32_16\n\n");
|
||||
#else
|
||||
fprintf(fp, "\tjmp\t_CallTo32_16\n\n");
|
||||
#endif
|
||||
|
||||
odp = OrdinalDefinitions;
|
||||
for (i = 0; i <= Limit; i++, odp++)
|
||||
|
|
|
@ -7,7 +7,11 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
|
|||
#include <ctype.h>
|
||||
|
||||
#ifdef linux
|
||||
#ifdef __ELF__
|
||||
#define UTEXTSEL 0x0f
|
||||
#else
|
||||
#define UTEXTSEL 0x23
|
||||
#endif
|
||||
#define UDATASEL 0x2b
|
||||
#endif
|
||||
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
||||
|
|
|
@ -416,7 +416,8 @@ int ShowCursor(BOOL bShow)
|
|||
*/
|
||||
void ClipCursor(LPRECT lpNewClipRect)
|
||||
{
|
||||
CopyRect(&ClipCursorRect, lpNewClipRect);
|
||||
if (!lpNewClipRect) SetRectEmpty( &ClipCursorRect );
|
||||
else CopyRect( &ClipCursorRect, lpNewClipRect );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
|
|||
|
||||
case WM_PAINTICON:
|
||||
case WM_NCPAINT:
|
||||
return NC_HandleNCPaint( hwnd, (HRGN)wParam );
|
||||
return NC_HandleNCPaint( hwnd );
|
||||
|
||||
case WM_NCHITTEST:
|
||||
return NC_HandleNCHitTest( hwnd, MAKEPOINT(lParam) );
|
||||
|
@ -145,8 +145,8 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
|
|||
case WM_ERASEBKGND:
|
||||
case WM_ICONERASEBKGND:
|
||||
{
|
||||
if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 1;
|
||||
if (!classPtr->wc.hbrBackground) return 1;
|
||||
if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
|
||||
if (!classPtr->wc.hbrBackground) return 0;
|
||||
if (classPtr->wc.hbrBackground <= COLOR_MAX+1)
|
||||
{
|
||||
HBRUSH hbrush;
|
||||
|
@ -158,7 +158,7 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
|
|||
else
|
||||
FillWindow( GetParent(hwnd), hwnd, (HDC)wParam,
|
||||
classPtr->wc.hbrBackground );
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
case WM_GETDLGCODE:
|
||||
|
@ -211,7 +211,7 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
|
|||
|
||||
case WM_SETTEXT:
|
||||
DEFWND_SetText( hwnd, (LPSTR)lParam );
|
||||
NC_HandleNCPaint( hwnd, (HRGN)1 ); /* Repaint caption */
|
||||
NC_HandleNCPaint( hwnd ); /* Repaint caption */
|
||||
return 0;
|
||||
|
||||
case WM_SETCURSOR:
|
||||
|
|
|
@ -256,7 +256,6 @@ static WORD EVENT_XStateToKeyState( int state )
|
|||
static void EVENT_Expose( HWND hwnd, XExposeEvent *event )
|
||||
{
|
||||
RECT rect;
|
||||
UINT flags;
|
||||
WND * wndPtr = WIN_FindWndPtr( hwnd );
|
||||
if (!wndPtr) return;
|
||||
|
||||
|
@ -266,10 +265,9 @@ static void EVENT_Expose( HWND hwnd, XExposeEvent *event )
|
|||
rect.right = rect.left + event->width;
|
||||
rect.bottom = rect.top + event->height;
|
||||
|
||||
flags = RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN;
|
||||
/* Erase desktop background synchronously */
|
||||
/* if (event->window == rootWindow) flags |= RDW_ERASENOW | RDW_NOCHILDREN; */
|
||||
RedrawWindow( hwnd, &rect, 0, flags );
|
||||
RedrawWindow( hwnd, &rect, 0,
|
||||
RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
|
||||
(event->count ? 0 : RDW_ERASENOW) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -542,8 +542,6 @@ BOOL PaintRgn( HDC hdc, HRGN hrgn )
|
|||
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
|
||||
if (!dc) return FALSE;
|
||||
|
||||
/* FIXME: the region is supposed to be in logical coordinates */
|
||||
|
||||
/* Modify visible region */
|
||||
|
||||
if (!(prevVisRgn = SaveVisRgn( hdc ))) return FALSE;
|
||||
|
@ -558,7 +556,7 @@ BOOL PaintRgn( HDC hdc, HRGN hrgn )
|
|||
|
||||
/* Fill the region */
|
||||
|
||||
GetClipBox( hdc, &box );
|
||||
GetRgnBox( dc->w.hGCClipRgn, &box );
|
||||
if (DC_SetupGCForBrush( dc ))
|
||||
XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
|
||||
dc->w.DCOrgX + box.left, dc->w.DCOrgY + box.top,
|
||||
|
@ -717,21 +715,13 @@ BOOL Polyline (HDC hdc, LPPOINT pt, int count)
|
|||
}
|
||||
|
||||
if (DC_SetupGCForPen( dc ))
|
||||
{
|
||||
for (i = 0; i < count-1; i ++)
|
||||
XDrawLine (display, dc->u.x.drawable, dc->u.x.gc,
|
||||
dc->w.DCOrgX + XLPTODP(dc, pt [i].x),
|
||||
dc->w.DCOrgY + YLPTODP(dc, pt [i].y),
|
||||
dc->w.DCOrgX + XLPTODP(dc, pt [i+1].x),
|
||||
dc->w.DCOrgY + YLPTODP(dc, pt [i+1].y));
|
||||
XDrawLine (display, dc->u.x.drawable, dc->u.x.gc,
|
||||
dc->w.DCOrgX + XLPTODP(dc, pt [count-1].x),
|
||||
dc->w.DCOrgY + YLPTODP(dc, pt [count-1].y),
|
||||
dc->w.DCOrgX + XLPTODP(dc, pt [0].x),
|
||||
dc->w.DCOrgY + YLPTODP(dc, pt [0].y));
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -915,7 +905,7 @@ BOOL ExtFloodFill( HDC hdc, INT x, INT y, COLORREF color, WORD fillType )
|
|||
}
|
||||
|
||||
if (!PtVisible( hdc, x, y )) return FALSE;
|
||||
if (GetClipBox( hdc, &rect ) == ERROR) return FALSE;
|
||||
if (GetRgnBox( dc->w.hGCClipRgn, &rect ) == ERROR) return FALSE;
|
||||
pixel = COLOR_ToPhysical( dc, color );
|
||||
|
||||
if (!(image = XGetImage( display, dc->u.x.drawable,
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
*
|
||||
* Copyright 1993 Bob Amstadt
|
||||
*/
|
||||
|
||||
static char Copyright[] = "Copyright Bob Amstadt, 1993";
|
||||
|
||||
#include <string.h>
|
||||
#include "win.h"
|
||||
#include "windows.h"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <math.h>
|
||||
#include "windows.h"
|
||||
#include "win.h"
|
||||
#include "nonclient.h"
|
||||
#include "mdi.h"
|
||||
#include "user.h"
|
||||
#include "menu.h"
|
||||
|
@ -271,7 +272,7 @@ LONG MDIMaximizeChild(HWND parent, HWND child, MDICLIENTINFO *ci)
|
|||
SendMessage(child, WM_SIZE, SIZE_MAXIMIZED,
|
||||
MAKELONG(w->rectClient.right-w->rectClient.left,
|
||||
w->rectClient.bottom-w->rectClient.top));
|
||||
SendMessage(GetParent(parent), WM_NCPAINT, 1, 0);
|
||||
SendMessage(GetParent(parent), WM_NCPAINT, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -298,7 +299,7 @@ LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci)
|
|||
ci->flagChildMaximized = FALSE;
|
||||
|
||||
ShowWindow(child, SW_RESTORE); /* display the window */
|
||||
SendMessage(GetParent(parent), WM_NCPAINT, 1, 0);
|
||||
SendMessage(GetParent(parent), WM_NCPAINT, 0, 0);
|
||||
MDIBringChildToTop(parent, child, FALSE, FALSE);
|
||||
|
||||
return 0;
|
||||
|
@ -496,7 +497,6 @@ LONG MDIPaintMaximized(HWND hwndFrame, HWND hwndClient, WORD message,
|
|||
|
||||
MDICLIENTINFO *ci;
|
||||
WND *w;
|
||||
LONG rv;
|
||||
HDC hdc, hdcMem;
|
||||
RECT rect;
|
||||
WND *wndPtr = WIN_FindWndPtr(hwndFrame);
|
||||
|
@ -512,11 +512,10 @@ LONG MDIPaintMaximized(HWND hwndFrame, HWND hwndClient, WORD message,
|
|||
|
||||
if (ci->flagChildMaximized && wndPtr && wndPtr->wIDmenu != 0)
|
||||
{
|
||||
rv = NC_DoNCPaint( hwndFrame, (HRGN) 1, wParam, TRUE);
|
||||
|
||||
NC_DoNCPaint( hwndFrame, wParam, TRUE);
|
||||
|
||||
hdc = GetDCEx(hwndFrame, 0, DCX_CACHE | DCX_WINDOW);
|
||||
if (!hdc)
|
||||
return rv;
|
||||
if (!hdc) return 0;
|
||||
|
||||
hdcMem = CreateCompatibleDC(hdc);
|
||||
|
||||
|
@ -563,7 +562,7 @@ LONG MDIPaintMaximized(HWND hwndFrame, HWND hwndClient, WORD message,
|
|||
else
|
||||
DefWindowProc(hwndFrame, message, wParam, lParam);
|
||||
|
||||
return rv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -725,8 +724,8 @@ DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
|
|||
break;
|
||||
|
||||
case WM_NCPAINT:
|
||||
return NC_DoNCPaint(hwnd, (HRGN)1,
|
||||
hwnd == ci->hwndActiveChild);
|
||||
NC_DoNCPaint( hwnd, hwnd == ci->hwndActiveChild, FALSE );
|
||||
return 0;
|
||||
|
||||
case WM_SYSCOMMAND:
|
||||
switch (wParam)
|
||||
|
|
|
@ -209,7 +209,7 @@ static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos )
|
|||
static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove )
|
||||
{
|
||||
BOOL eatMsg = FALSE;
|
||||
LONG hittest_result;
|
||||
INT hittest_result;
|
||||
static DWORD lastClickTime = 0;
|
||||
static WORD lastClickMsg = 0;
|
||||
static POINT lastClickPos = { 0, 0 };
|
||||
|
@ -231,14 +231,14 @@ static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove )
|
|||
|
||||
/* Send the WM_NCHITTEST message */
|
||||
|
||||
hittest_result = SendMessage( msg->hwnd, WM_NCHITTEST, 0,
|
||||
MAKELONG( msg->pt.x, msg->pt.y ) );
|
||||
hittest_result = (INT)SendMessage( msg->hwnd, WM_NCHITTEST, 0,
|
||||
MAKELONG( msg->pt.x, msg->pt.y ) );
|
||||
while ((hittest_result == HTTRANSPARENT) && (msg->hwnd))
|
||||
{
|
||||
msg->hwnd = WINPOS_NextWindowFromPoint( msg->hwnd, msg->pt );
|
||||
if (msg->hwnd)
|
||||
hittest_result = SendMessage( msg->hwnd, WM_NCHITTEST, 0,
|
||||
MAKELONG( msg->pt.x, msg->pt.y ) );
|
||||
hittest_result = (INT)SendMessage( msg->hwnd, WM_NCHITTEST, 0,
|
||||
MAKELONG( msg->pt.x, msg->pt.y ));
|
||||
}
|
||||
if (!msg->hwnd) msg->hwnd = GetDesktopWindow();
|
||||
|
||||
|
|
|
@ -537,33 +537,18 @@ static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
|
|||
* NC_DoNCPaint
|
||||
*
|
||||
* Paint the non-client area.
|
||||
* 'hrgn' is the update rgn to use (in client coords) or 1 if no update rgn.
|
||||
*/
|
||||
void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active, BOOL suppress_menupaint )
|
||||
void NC_DoNCPaint( HWND hwnd, BOOL active, BOOL suppress_menupaint )
|
||||
{
|
||||
HDC hdc;
|
||||
RECT rect;
|
||||
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
|
||||
dprintf_nonclient(stddeb, "NC_DoNCPaint: %d %d\n", hwnd, hrgn );
|
||||
if (!wndPtr || !hrgn) return;
|
||||
if (!(wndPtr->dwStyle & WS_VISIBLE)) return; /* Nothing to do */
|
||||
if (!(wndPtr->dwStyle & (WS_BORDER | WS_DLGFRAME | WS_THICKFRAME)) &&
|
||||
!(wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)) return; /* Nothing to do */
|
||||
|
||||
if (hrgn == 1) hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW );
|
||||
else
|
||||
{
|
||||
/* Make region relative to window area */
|
||||
int xoffset = wndPtr->rectWindow.left - wndPtr->rectClient.left;
|
||||
int yoffset = wndPtr->rectWindow.top - wndPtr->rectClient.top;
|
||||
OffsetRgn( hrgn, -xoffset, -yoffset );
|
||||
hdc = GetDCEx( hwnd, hrgn, DCX_USESTYLE|DCX_WINDOW|DCX_INTERSECTRGN );
|
||||
OffsetRgn( hrgn, xoffset, yoffset ); /* Restore region */
|
||||
}
|
||||
if (!hdc) return;
|
||||
dprintf_nonclient(stddeb, "NC_DoNCPaint: %x %d\n", hwnd, active );
|
||||
if (!wndPtr || !(wndPtr->dwStyle & WS_VISIBLE)) return; /* Nothing to do */
|
||||
|
||||
if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
|
||||
|
||||
/*
|
||||
* If this is an icon, we don't want to do any more nonclient painting
|
||||
|
@ -654,9 +639,9 @@ void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active, BOOL suppress_menupaint )
|
|||
*
|
||||
* Handle a WM_NCPAINT message. Called from DefWindowProc().
|
||||
*/
|
||||
LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn )
|
||||
LONG NC_HandleNCPaint( HWND hwnd )
|
||||
{
|
||||
NC_DoNCPaint( hwnd, hrgn, hwnd == GetActiveWindow(), FALSE );
|
||||
NC_DoNCPaint( hwnd, hwnd == GetActiveWindow(), FALSE );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -668,7 +653,7 @@ LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn )
|
|||
*/
|
||||
LONG NC_HandleNCActivate( HWND hwnd, WORD wParam )
|
||||
{
|
||||
NC_DoNCPaint( hwnd, (HRGN)1, wParam, FALSE );
|
||||
NC_DoNCPaint( hwnd, wParam, FALSE );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#include "win.h"
|
||||
#include "message.h"
|
||||
#include "gdi.h"
|
||||
#include "stddebug.h"
|
||||
/* #define DEBUG_WIN */
|
||||
#include "debug.h"
|
||||
|
||||
/* Last CTLCOLOR id */
|
||||
#define CTLCOLOR_MAX CTLCOLOR_STATIC
|
||||
|
@ -34,21 +37,29 @@ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps )
|
|||
wndPtr->hrgnUpdate = 0;
|
||||
wndPtr->flags &= ~(WIN_NEEDS_BEGINPAINT | WIN_INTERNAL_PAINT);
|
||||
|
||||
if (!(lps->hdc = GetDCEx( hwnd, hrgnUpdate,
|
||||
DCX_INTERSECTRGN | DCX_USESTYLE )))
|
||||
if (wndPtr->flags & WIN_NEEDS_NCPAINT)
|
||||
{
|
||||
fprintf( stderr, "GetDCEx() failed in BeginPaint(), hwnd=%d\n", hwnd );
|
||||
DeleteObject( hrgnUpdate );
|
||||
SendMessage( hwnd, WM_NCPAINT, 0, 0 );
|
||||
wndPtr->flags &= ~WIN_NEEDS_NCPAINT;
|
||||
}
|
||||
|
||||
lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_USESTYLE );
|
||||
DeleteObject( hrgnUpdate );
|
||||
if (!lps->hdc)
|
||||
{
|
||||
fprintf( stderr, "GetDCEx() failed in BeginPaint(), hwnd=%x\n", hwnd );
|
||||
return 0;
|
||||
}
|
||||
|
||||
GetRgnBox( InquireVisRgn(lps->hdc), &lps->rcPaint );
|
||||
DPtoLP( lps->hdc, (LPPOINT)&lps->rcPaint, 2 );
|
||||
|
||||
SendMessage( hwnd, WM_NCPAINT, hrgnUpdate, 0 );
|
||||
DeleteObject( hrgnUpdate );
|
||||
|
||||
if (!(wndPtr->flags & WIN_ERASE_UPDATERGN)) lps->fErase = TRUE;
|
||||
else lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 );
|
||||
if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
|
||||
{
|
||||
lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 );
|
||||
wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
|
||||
}
|
||||
else lps->fErase = TRUE;
|
||||
|
||||
return lps->hdc;
|
||||
}
|
||||
|
@ -86,7 +97,7 @@ void PaintRect(HWND hwndParent, HWND hwnd, HDC hdc, HBRUSH hbrush, LPRECT rect)
|
|||
{
|
||||
if (!hwndParent) return;
|
||||
hbrush = (HBRUSH)SendMessage( hwndParent, WM_CTLCOLOR,
|
||||
hdc, hwnd | (hbrush << 16) );
|
||||
hdc, MAKELONG( hwnd, hbrush ) );
|
||||
}
|
||||
if (hbrush) FillRect( hdc, rect, hbrush );
|
||||
}
|
||||
|
@ -106,14 +117,23 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
|
|||
if (!(wndPtr->dwStyle & WS_VISIBLE) || (wndPtr->flags & WIN_NO_REDRAW))
|
||||
return TRUE; /* No redraw needed */
|
||||
|
||||
if (rectUpdate)
|
||||
{
|
||||
dprintf_win( stddeb, "RedrawWindow: %x %d,%d-%d,%d %x flags=%04x\n",
|
||||
hwnd, rectUpdate->left, rectUpdate->top,
|
||||
rectUpdate->right, rectUpdate->bottom, hrgnUpdate, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
dprintf_win( stddeb, "RedrawWindow: %x NULL %x flags=%04x\n",
|
||||
hwnd, hrgnUpdate, flags);
|
||||
}
|
||||
GetClientRect( hwnd, &rectClient );
|
||||
rectWindow = wndPtr->rectWindow;
|
||||
OffsetRect(&rectWindow, -wndPtr->rectClient.left, -wndPtr->rectClient.top);
|
||||
|
||||
if (flags & RDW_INVALIDATE) /* Invalidate */
|
||||
{
|
||||
if (flags & RDW_ERASE) wndPtr->flags |= WIN_ERASE_UPDATERGN;
|
||||
|
||||
if (hrgnUpdate) /* Invalidate a region */
|
||||
{
|
||||
if (flags & RDW_FRAME) tmpRgn = CreateRectRgnIndirect(&rectWindow);
|
||||
|
@ -162,11 +182,13 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
|
|||
wndPtr->hrgnUpdate = tmpRgn;
|
||||
}
|
||||
}
|
||||
if (flags & RDW_FRAME) wndPtr->flags |= WIN_NEEDS_NCPAINT;
|
||||
if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
|
||||
flags |= RDW_FRAME; /* Force invalidating the frame of children */
|
||||
}
|
||||
else if (flags & RDW_VALIDATE) /* Validate */
|
||||
{
|
||||
if (flags & RDW_NOERASE) wndPtr->flags &= ~WIN_ERASE_UPDATERGN;
|
||||
if (flags & RDW_NOERASE) wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
|
||||
if (!(hrgn = CreateRectRgn( 0, 0, 0, 0 ))) return FALSE;
|
||||
|
||||
/* Remove frame from update region */
|
||||
|
@ -231,22 +253,31 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
|
|||
|
||||
/* Erase/update window */
|
||||
|
||||
if (flags & RDW_UPDATENOW) UpdateWindow( hwnd );
|
||||
if (flags & RDW_UPDATENOW) SendMessage( hwnd, WM_PAINT, 0, 0 );
|
||||
else if (flags & RDW_ERASENOW)
|
||||
{
|
||||
HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
|
||||
DCX_INTERSECTRGN | DCX_USESTYLE );
|
||||
if (hdc)
|
||||
{
|
||||
SendMessage( hwnd, WM_NCPAINT, wndPtr->hrgnUpdate, 0 );
|
||||
|
||||
if (wndPtr->flags & WIN_NEEDS_NCPAINT)
|
||||
{
|
||||
SendMessage( hwnd, WM_NCPAINT, 0, 0 );
|
||||
wndPtr->flags &= ~WIN_NEEDS_NCPAINT;
|
||||
}
|
||||
if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
|
||||
{
|
||||
HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
|
||||
DCX_INTERSECTRGN | DCX_USESTYLE );
|
||||
if (hdc)
|
||||
{
|
||||
/* Don't send WM_ERASEBKGND to icons */
|
||||
/* (WM_ICONERASEBKGND is sent during processing of WM_NCPAINT) */
|
||||
if (!(wndPtr->dwStyle & WS_MINIMIZE)
|
||||
|| !WIN_CLASS_INFO(wndPtr).hIcon)
|
||||
SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 );
|
||||
ReleaseDC( hwnd, hdc );
|
||||
}
|
||||
if (!(wndPtr->dwStyle & WS_MINIMIZE)
|
||||
|| !WIN_CLASS_INFO(wndPtr).hIcon)
|
||||
{
|
||||
if (SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 ))
|
||||
wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
|
||||
}
|
||||
ReleaseDC( hwnd, hdc );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Recursively process children */
|
||||
|
@ -294,10 +325,7 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
|
|||
*/
|
||||
void UpdateWindow( HWND hwnd )
|
||||
{
|
||||
if (GetUpdateRect( hwnd, NULL, FALSE ))
|
||||
{
|
||||
if (IsWindowVisible( hwnd )) SendMessage( hwnd, WM_PAINT, 0, 0 );
|
||||
}
|
||||
RedrawWindow( hwnd, NULL, 0, RDW_UPDATENOW | RDW_NOCHILDREN );
|
||||
}
|
||||
|
||||
|
||||
|
@ -372,27 +400,15 @@ int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
|
|||
|
||||
if (!wndPtr->hrgnUpdate)
|
||||
{
|
||||
if (!(hrgnClip = CreateRectRgn( 0, 0, 0, 0 ))) return ERROR;
|
||||
retval = CombineRgn( hrgn, hrgnClip, 0, RGN_COPY );
|
||||
}
|
||||
else
|
||||
{
|
||||
hrgnClip = CreateRectRgn( 0, 0,
|
||||
wndPtr->rectClient.right-wndPtr->rectClient.left,
|
||||
wndPtr->rectClient.bottom-wndPtr->rectClient.top );
|
||||
if (!hrgnClip) return ERROR;
|
||||
retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, hrgnClip, RGN_AND );
|
||||
if (erase)
|
||||
{
|
||||
HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
|
||||
DCX_INTERSECTRGN | DCX_USESTYLE );
|
||||
if (hdc)
|
||||
{
|
||||
SendMessage( hwnd, WM_ERASEBKGND, hdc, 0 );
|
||||
ReleaseDC( hwnd, hdc );
|
||||
}
|
||||
}
|
||||
SetRectRgn( hrgn, 0, 0, 0, 0 );
|
||||
return NULLREGION;
|
||||
}
|
||||
hrgnClip = CreateRectRgn( 0, 0,
|
||||
wndPtr->rectClient.right-wndPtr->rectClient.left,
|
||||
wndPtr->rectClient.bottom-wndPtr->rectClient.top);
|
||||
if (!hrgnClip) return ERROR;
|
||||
retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, hrgnClip, RGN_AND );
|
||||
if (erase) RedrawWindow( hwnd, NULL, 0, RDW_ERASENOW | RDW_NOCHILDREN );
|
||||
DeleteObject( hrgnClip );
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -154,8 +154,8 @@ int ScrollWindowEx(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect,
|
|||
|
||||
if (flags | SW_INVALIDATE)
|
||||
{
|
||||
RedrawWindow(hwnd, NULL, hrgnUpdate,
|
||||
RDW_INVALIDATE | ((flags & SW_ERASE) ? RDW_ERASENOW : 0));
|
||||
RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
|
||||
((flags & SW_ERASE) ? RDW_ERASENOW : 0));
|
||||
}
|
||||
|
||||
ReleaseDC(hwnd, hdc);
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
*
|
||||
* Copyright 1993, 1994 Alexandre Julliard
|
||||
*/
|
||||
|
||||
static char Copyright[] = "Copyright Alexandre Julliard, 1993, 1994";
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "winpos.h"
|
||||
#include "stddebug.h"
|
||||
/* #define DEBUG_WIN */
|
||||
/* #undef DEBUG_WIN */
|
||||
#include "debug.h"
|
||||
|
||||
static HWND hwndActive = 0; /* Currently active window */
|
||||
|
@ -274,7 +273,7 @@ BOOL ShowWindow( HWND hwnd, int cmd )
|
|||
*/
|
||||
MoveWindow(hwnd, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
|
||||
SYSMETRICS_CXICON, SYSMETRICS_CYICON, FALSE);
|
||||
RedrawWindow( hwnd, NULL, 0, RDW_FRAME | RDW_ERASENOW );
|
||||
RedrawWindow( hwnd, NULL, 0, RDW_FRAME | RDW_ERASE | RDW_ERASENOW);
|
||||
break;
|
||||
|
||||
case SW_SHOWNA:
|
||||
|
@ -604,7 +603,7 @@ static void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter, BOOL erase )
|
|||
OffsetRect( &rect, -wndPtr->rectClient.left,
|
||||
-wndPtr->rectClient.top );
|
||||
RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
|
||||
RDW_FRAME | (erase ? RDW_ERASENOW : RDW_ERASE) );
|
||||
RDW_FRAME | RDW_ERASE | (erase ? RDW_ERASENOW : 0) );
|
||||
hwndCur = curPtr->hwndNext;
|
||||
}
|
||||
}
|
||||
|
@ -620,7 +619,7 @@ static void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter, BOOL erase )
|
|||
OffsetRect( &rect, -curPtr->rectClient.left,
|
||||
-curPtr->rectClient.top );
|
||||
RedrawWindow( hwndCur, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
|
||||
RDW_FRAME | (erase ? RDW_ERASENOW : RDW_ERASE) );
|
||||
RDW_FRAME | RDW_ERASE | (erase ? RDW_ERASENOW : 0) );
|
||||
hwndCur = curPtr->hwndNext;
|
||||
}
|
||||
}
|
||||
|
@ -775,12 +774,13 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
|
|||
HRGN hrgn3 = CreateRectRgn( 0, 0, 0, 0 );
|
||||
CombineRgn( hrgn3, hrgn1, hrgn2, RGN_DIFF );
|
||||
RedrawWindow( wndPtr->hwndParent, NULL, hrgn3,
|
||||
RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASENOW );
|
||||
RDW_INVALIDATE | RDW_ALLCHILDREN |
|
||||
RDW_ERASE | RDW_ERASENOW );
|
||||
if ((oldWindowRect.left != wndPtr->rectWindow.left) ||
|
||||
(oldWindowRect.top != wndPtr->rectWindow.top))
|
||||
{
|
||||
RedrawWindow( winpos->hwnd, NULL, 0, RDW_INVALIDATE |
|
||||
RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASENOW );
|
||||
RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW );
|
||||
}
|
||||
DeleteObject( hrgn1 );
|
||||
DeleteObject( hrgn2 );
|
||||
|
@ -794,9 +794,11 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
|
|||
if (wndPtr->window)
|
||||
{
|
||||
XMapWindow( display, wndPtr->window );
|
||||
MSG_Synchronize();
|
||||
if (flags & SWP_NOREDRAW) /* Validate the whole window */
|
||||
RedrawWindow( winpos->hwnd, NULL, 0, RDW_VALIDATE );
|
||||
}
|
||||
else
|
||||
{
|
||||
RedrawWindow( winpos->hwnd, NULL, 0,
|
||||
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE );
|
||||
}
|
||||
}
|
||||
else if (flags & SWP_HIDEWINDOW)
|
||||
|
@ -810,7 +812,7 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
|
|||
{
|
||||
RedrawWindow( wndPtr->hwndParent, &wndPtr->rectWindow, 0,
|
||||
RDW_INVALIDATE | RDW_FRAME |
|
||||
RDW_ALLCHILDREN | RDW_ERASENOW );
|
||||
RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW );
|
||||
}
|
||||
if ((winpos->hwnd == GetFocus()) || IsChild(winpos->hwnd, GetFocus()))
|
||||
SetFocus( GetParent(winpos->hwnd) ); /* Revert focus to parent */
|
||||
|
@ -835,23 +837,14 @@ static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
|
|||
WINPOS_ChangeActiveWindow( winpos->hwnd, FALSE );
|
||||
}
|
||||
|
||||
/* Send WM_NCPAINT message if needed */
|
||||
/* Repaint the window */
|
||||
|
||||
if (flags & SWP_SHOWWINDOW)
|
||||
{
|
||||
/* Repaint the window frame and background */
|
||||
RedrawWindow( winpos->hwnd, NULL, 0,
|
||||
RDW_INVALIDATE | RDW_FRAME | RDW_ERASENOW );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((flags & SWP_FRAMECHANGED) ||
|
||||
(!(flags & SWP_NOSIZE)) ||
|
||||
(!(flags & SWP_NOMOVE)) ||
|
||||
(!(flags & SWP_NOACTIVATE)) ||
|
||||
(!(flags & SWP_NOZORDER)))
|
||||
SendMessage( winpos->hwnd, WM_NCPAINT, 1, 0L );
|
||||
}
|
||||
if (wndPtr->window) MSG_Synchronize(); /* Wait for all expose events */
|
||||
if (flags & SWP_FRAMECHANGED)
|
||||
RedrawWindow( winpos->hwnd, NULL, 0,
|
||||
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE );
|
||||
RedrawWindow( winpos->hwnd, NULL, 0,
|
||||
(flags & SWP_NOREDRAW) ? RDW_VALIDATE : RDW_ERASENOW );
|
||||
|
||||
/* And last, send the WM_WINDOWPOSCHANGED message */
|
||||
|
||||
|
|
Loading…
Reference in New Issue