/****************************************************************************** * * tweak.c * * Windows 95 style interface tweaks. * Copyright (c) 1997 Dave Cuthbert. * * FIXME: This file is, unfortunately, aptly named: the method of * displaying Win95 style windows is a tweak. Lots of stuff does not yet * work -- and probably never will unless some of this code is * incorporated into the mainstream Wine code. * * DEVELOPERS, PLEASE NOTE: Before delving into the mainstream code and * altering it, consider how your changes will affect the Win3.1 interface * (which has taken a major effort to create!). After you make any sort of * non-trivial change, *test* the Wine code running in Win3.1 mode! The * object here is to make it so that the person who tests the latest version * of Wine without adding the tweaks into wine.conf notices nothing out of * the ordinary. * * Revision history * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) * Original implementation. * *****************************************************************************/ #include #include #include #include #include "dc.h" #include "debug.h" #include "graphics.h" #include "options.h" #include "stackframe.h" #include "syscolor.h" #include "tweak.h" #include "windows.h" /* Parameters for windows/nonclient.c */ extern int NC_CaptionLeftNudge; extern int NC_CaptionTopNudge; extern int NC_SysControlNudge; extern int NC_MaxControlNudge; extern int NC_MinControlNudge; extern UINT32 NC_CaptionTextFlags; extern HBRUSH32 NC_WinHighlight95; extern HBRUSH32 NC_WinShadow95; /* Parameters for controls/menu.c */ extern UINT32 MENU_BarItemTopNudge; extern UINT32 MENU_BarItemLeftNudge; extern UINT32 MENU_ItemTopNudge; extern UINT32 MENU_ItemLeftNudge; extern UINT32 MENU_HighlightTopNudge; extern UINT32 MENU_HighlightLeftNudge; extern UINT32 MENU_HighlightBottomNudge; extern UINT32 MENU_HighlightRightNudge; /* General options */ HPEN32 TWEAK_PenFF95; HPEN32 TWEAK_PenE095; HPEN32 TWEAK_PenC095; HPEN32 TWEAK_Pen8095; HPEN32 TWEAK_Pen0095; #if defined(WIN_95_LOOK) int TWEAK_Win95Look = 1; #else int TWEAK_Win95Look = 0; #endif int TWEAK_WineInitialized = 0; /****************************************************************************** * * int TWEAK_MenuInit() * * Initializes the Win95 tweaks to the menu code. See controls/menu.c. * Return value indicates success (non-zero) or failure. * * Revision history * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) * Original implementation. * *****************************************************************************/ static int TWEAK_MenuInit() { MENU_BarItemTopNudge = PROFILE_GetWineIniInt("Tweak.Layout", "MenuBarItemTopNudge", 0); MENU_BarItemLeftNudge = PROFILE_GetWineIniInt("Tweak.Layout", "MenuBarItemLeftNudge", 0); MENU_ItemTopNudge = PROFILE_GetWineIniInt("Tweak.Layout", "MenuItemTopNudge", 0); MENU_ItemLeftNudge = PROFILE_GetWineIniInt("Tweak.Layout", "MenuItemLeftNudge", 0); MENU_HighlightTopNudge = PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightTopNudge", 0); MENU_HighlightLeftNudge = PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightLeftNudge", 0); MENU_HighlightBottomNudge = PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightBottomNudge", 0); MENU_HighlightRightNudge = PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightRightNudge", 0); return 1; } /****************************************************************************** * * int TWEAK_NonClientInit() * * Initializes the Win95 tweaks to the non-client drawing functions. See * windows/nonclient.c. Return value indicates success (non-zero) or * failure. * * Revision history * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) * Original implementation. * *****************************************************************************/ static int TWEAK_NonClientInit() { char key_value[2]; NC_CaptionLeftNudge = PROFILE_GetWineIniInt("Tweak.Layout", "CaptionLeftNudge", 0); NC_CaptionTopNudge = PROFILE_GetWineIniInt("Tweak.Layout", "CaptionTopNudge", 0); NC_SysControlNudge = PROFILE_GetWineIniInt("Tweak.Layout", "SysControlNudge", 0); NC_MaxControlNudge = PROFILE_GetWineIniInt("Tweak.Layout", "MaxControlNudge", 0); NC_MinControlNudge = PROFILE_GetWineIniInt("Tweak.Layout", "MinControlNudge", 0); NC_WinHighlight95 = CreateSolidBrush32(RGB(0xc0, 0xc0, 0xc0)); NC_WinShadow95 = CreateSolidBrush32(RGB(0x00, 0x00, 0x00)); NC_CaptionTextFlags = DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX; PROFILE_GetWineIniString("Tweak.Layout", "CaptionAlignment", TWEAK_Win95Look ? "l" : "c", key_value, 2); switch(key_value[0]) { case 'l': case 'L': NC_CaptionTextFlags |= DT_LEFT; break; case 'r': case 'R': NC_CaptionTextFlags |= DT_RIGHT; break; default: NC_CaptionTextFlags |= DT_CENTER; } return 1; } /****************************************************************************** * * int TWEAK_VarInit() * * Initializes the miscellaneous variables which are used in the tweak * routines. Return value is non-zero on success. * * Revision history * 07-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) * Original implementation. * *****************************************************************************/ static int TWEAK_VarInit() { TWEAK_Win95Look = PROFILE_GetWineIniBool("Tweak.Layout", "Win95Look", 0); /* FIXME: Each color should really occupy a single entry in the wine.conf file, but I couldn't settle on a good (intuitive!) format. */ TWEAK_PenFF95 = CreatePen32( PS_SOLID, 1, RGB(PROFILE_GetWineIniInt("Tweak.Colors", "PenFF95.Red", 0xff), PROFILE_GetWineIniInt("Tweak.Colors", "PenFF95.Grn", 0xff), PROFILE_GetWineIniInt("Tweak.Colors", "PenFF95.Blu", 0xff))); TWEAK_PenE095 = CreatePen32( PS_SOLID, 1, RGB(PROFILE_GetWineIniInt("Tweak.Colors", "PenE095.Red", 0xe0), PROFILE_GetWineIniInt("Tweak.Colors", "PenE095.Grn", 0xe0), PROFILE_GetWineIniInt("Tweak.Colors", "PenE095.Blu", 0xe0))); TWEAK_PenC095 = CreatePen32( PS_SOLID, 1, RGB(PROFILE_GetWineIniInt("Tweak.Colors", "PenC095.Red", 0xc0), PROFILE_GetWineIniInt("Tweak.Colors", "PenC095.Grn", 0xc0), PROFILE_GetWineIniInt("Tweak.Colors", "PenC095.Blu", 0xc0))); TWEAK_Pen8095 = CreatePen32( PS_SOLID, 1, RGB(PROFILE_GetWineIniInt("Tweak.Colors", "Pen8095.Red", 0x80), PROFILE_GetWineIniInt("Tweak.Colors", "Pen8095.Grn", 0x80), PROFILE_GetWineIniInt("Tweak.Colors", "Pen8095.Blu", 0x80))); TWEAK_Pen0095 = CreatePen32( PS_SOLID, 1, RGB(PROFILE_GetWineIniInt("Tweak.Colors", "Pen0095.Red", 0x00), PROFILE_GetWineIniInt("Tweak.Colors", "Pen0095.Grn", 0x00), PROFILE_GetWineIniInt("Tweak.Colors", "Pen0095.Blu", 0x00))); dprintf_tweak(stddeb, "TWEAK_VarInit: Using %s look and feel.\n", TWEAK_Win95Look ? "Win95" : "Win3.1"); return 1; } /****************************************************************************** * * int TWEAK_Init() * * Does the full initialization of the Win95 tweak subsystem. Return value * indicates success. Called by loader/main.c's MAIN_Init(). * * Revision history * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) * Original implementation. * *****************************************************************************/ int TWEAK_Init() { TWEAK_VarInit(); TWEAK_NonClientInit(); TWEAK_MenuInit(); return 1; } /****************************************************************************** * * int TWEAK_CheckOldFonts() * * Examines wine.conf for old/invalid font entries and recommend changes to * the user. * * Revision history * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) * Original implementation. * *****************************************************************************/ static void TWEAK_CheckOldFontsCallback(char const *, char const *, void *); static char const *fontmsgprologue = "Wine warning:\n" " The following entries in the [fonts] section of the wine.conf file are\n" " obsolete or invalid:\n"; static char const *fontmsgepilogue = " These entries should be eliminated or updated.\n" " See the documentation/fonts file for more information.\n"; static int TWEAK_CheckOldFonts() { int found = 0; PROFILE_EnumerateWineIniSection("Fonts", &TWEAK_CheckOldFontsCallback, (void *)&found); if(found) fprintf(stderr, fontmsgepilogue); return 1; } static void TWEAK_CheckOldFontsCallback( char const *key, char const *value, void *found) { /* Ignore any keys that start with potential comment characters "'", '#', or ';'. */ if(key[0] == '\'' || key[0] == '#' || key[0] == ';' || key[0] == '\0') return; /* Make sure this is a valid key */ if(strncasecmp(key, "Alias", 5) == 0 || strcasecmp(key, "Default") == 0) { /* Valid key; make sure the value doesn't contain a wildcard */ if(strchr(value, '*')) { if(*(int *)found == 0) { fprintf(stderr, fontmsgprologue); ++*(int *)found; } fprintf(stderr, " %s=%s [no wildcards allowed]\n", key, value); } } else { /* Not a valid key */ if(*(int *)found == 0) { fprintf(stderr, fontmsgprologue); ++*(int *)found; } fprintf(stderr, " %s=%s [obsolete]\n", key, value); } return; } /****************************************************************************** * * int TWEAK_CheckConfiguration() * * Examines wine.conf for old/bad entries and recommends changes to the user. * * Revision history * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) * Original implementation. * *****************************************************************************/ int TWEAK_CheckConfiguration() { TWEAK_CheckOldFonts(); return 1; } /****************************************************************************** * * Tweak graphic subsystem. * *****************************************************************************/ /****************************************************************************** * * void TWEAK_DrawReliefRect95( * HDC32 hdc, // Device context on which to draw * RECT32 const *rect ) // Rectangle to use * * Draws the double-bordered Win95-style relief rectangle. * * Bugs * There are some checks missing from this function. Perhaps the * SelectObject32 calls should be examined? Hasn't failed on me (yet). * * Should I really be calling X functions directly from here? It is * an optimization, but should I be optimizing alpha code? Probably * not. * * Revision history * 08-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) * Original implementation. * *****************************************************************************/ void TWEAK_DrawReliefRect95( HDC32 hdc, RECT32 const *rect ) { DC *dc; HPEN32 prevpen; if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) { /* Draw the top/left lines first */ prevpen = SelectObject32(hdc, TWEAK_PenE095); DC_SetupGCForPen(dc); XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top, rect->right - 1, rect->top); XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top, rect->left, rect->bottom - 1); SelectObject32(hdc, TWEAK_PenFF95); DC_SetupGCForPen(dc); XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1, rect->top + 1, rect->right - 2, rect->top + 1); XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1, rect->top + 1, rect->left + 1, rect->bottom - 2); /* Now the bottom/right lines */ SelectObject32(hdc, TWEAK_Pen0095); DC_SetupGCForPen(dc); XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->bottom - 1, rect->right - 1, rect->bottom - 1); XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 1, rect->top, rect->right - 1, rect->bottom - 1); SelectObject32(hdc, TWEAK_Pen8095); DC_SetupGCForPen(dc); XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1, rect->bottom - 2, rect->right - 2, rect->bottom - 2); XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 2, rect->top + 1, rect->right - 2, rect->bottom - 2); SelectObject32(hdc, prevpen); } return; } /****************************************************************************** * * void TWEAK_DrawMenuSeparator95( * HDC32 hdc, // Device context on which to draw * UINT32 xc1, // Left x-coordinate * UINT32 yc, // Y-coordinate of the LOWER line * UINT32 xc2 ) // Right x-coordinate * * Draws the menu separator bar Win 95 style. * * Bugs * Same as those for DrawReliefRect95. * * Revision history * 08-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) * Original implementation. * *****************************************************************************/ void TWEAK_DrawMenuSeparator95( HDC32 hdc, UINT32 xc1, UINT32 yc, UINT32 xc2 ) { DC *dc; HPEN32 prevpen; if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) { /* Draw the top line */ prevpen = SelectObject32(hdc, TWEAK_Pen8095); DC_SetupGCForPen(dc); XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc1, yc - 1, xc2, yc - 1); /* And the bottom line */ SelectObject32(hdc, TWEAK_PenFF95); DC_SetupGCForPen(dc); XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc1, yc, xc2, yc); SelectObject32(hdc, prevpen); } return; }