Release 970804
[wine/multimedia.git] / misc / tweak.c
blobe8f0095371a957047b03ed46b47d773fd119c67c
1 /******************************************************************************
3 * tweak.c
5 * Windows 95 style interface tweaks.
6 * Copyright (c) 1997 Dave Cuthbert.
8 * FIXME: This file is, unfortunately, aptly named: the method of
9 * displaying Win95 style windows is a tweak. Lots of stuff does not yet
10 * work -- and probably never will unless some of this code is
11 * incorporated into the mainstream Wine code.
13 * DEVELOPERS, PLEASE NOTE: Before delving into the mainstream code and
14 * altering it, consider how your changes will affect the Win3.1 interface
15 * (which has taken a major effort to create!). After you make any sort of
16 * non-trivial change, *test* the Wine code running in Win3.1 mode! The
17 * object here is to make it so that the person who tests the latest version
18 * of Wine without adding the tweaks into wine.conf notices nothing out of
19 * the ordinary.
21 * Revision history
22 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
23 * Original implementation.
25 *****************************************************************************/
27 #include <stdio.h>
28 #include <malloc.h>
29 #include <X11/Xlib.h>
30 #include <string.h>
31 #include "dc.h"
32 #include "debug.h"
33 #include "graphics.h"
34 #include "options.h"
35 #include "stackframe.h"
36 #include "syscolor.h"
37 #include "tweak.h"
38 #include "windows.h"
40 /* Parameters for windows/nonclient.c */
41 extern int NC_CaptionLeftNudge;
42 extern int NC_CaptionTopNudge;
43 extern int NC_SysControlNudge;
44 extern int NC_MaxControlNudge;
45 extern int NC_MinControlNudge;
46 extern UINT32 NC_CaptionTextFlags;
47 extern HBRUSH32 NC_WinHighlight95;
48 extern HBRUSH32 NC_WinShadow95;
50 /* Parameters for controls/menu.c */
51 extern UINT32 MENU_BarItemTopNudge;
52 extern UINT32 MENU_BarItemLeftNudge;
53 extern UINT32 MENU_ItemTopNudge;
54 extern UINT32 MENU_ItemLeftNudge;
55 extern UINT32 MENU_HighlightTopNudge;
56 extern UINT32 MENU_HighlightLeftNudge;
57 extern UINT32 MENU_HighlightBottomNudge;
58 extern UINT32 MENU_HighlightRightNudge;
60 /* General options */
61 HPEN32 TWEAK_PenFF95;
62 HPEN32 TWEAK_PenE095;
63 HPEN32 TWEAK_PenC095;
64 HPEN32 TWEAK_Pen8095;
65 HPEN32 TWEAK_Pen0095;
67 #if defined(WIN_95_LOOK)
68 int TWEAK_Win95Look = 1;
69 #else
70 int TWEAK_Win95Look = 0;
71 #endif
73 int TWEAK_WineInitialized = 0;
76 /******************************************************************************
78 * int TWEAK_MenuInit()
80 * Initializes the Win95 tweaks to the menu code. See controls/menu.c.
81 * Return value indicates success (non-zero) or failure.
83 * Revision history
84 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
85 * Original implementation.
87 *****************************************************************************/
89 static int TWEAK_MenuInit()
91 MENU_BarItemTopNudge =
92 PROFILE_GetWineIniInt("Tweak.Layout", "MenuBarItemTopNudge", 0);
93 MENU_BarItemLeftNudge =
94 PROFILE_GetWineIniInt("Tweak.Layout", "MenuBarItemLeftNudge", 0);
95 MENU_ItemTopNudge =
96 PROFILE_GetWineIniInt("Tweak.Layout", "MenuItemTopNudge", 0);
97 MENU_ItemLeftNudge =
98 PROFILE_GetWineIniInt("Tweak.Layout", "MenuItemLeftNudge", 0);
99 MENU_HighlightTopNudge =
100 PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightTopNudge", 0);
101 MENU_HighlightLeftNudge =
102 PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightLeftNudge", 0);
103 MENU_HighlightBottomNudge =
104 PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightBottomNudge", 0);
105 MENU_HighlightRightNudge =
106 PROFILE_GetWineIniInt("Tweak.Layout", "MenuHighlightRightNudge", 0);
108 return 1;
112 /******************************************************************************
114 * int TWEAK_NonClientInit()
116 * Initializes the Win95 tweaks to the non-client drawing functions. See
117 * windows/nonclient.c. Return value indicates success (non-zero) or
118 * failure.
120 * Revision history
121 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
122 * Original implementation.
124 *****************************************************************************/
126 static int TWEAK_NonClientInit()
128 char key_value[2];
130 NC_CaptionLeftNudge =
131 PROFILE_GetWineIniInt("Tweak.Layout", "CaptionLeftNudge", 0);
132 NC_CaptionTopNudge =
133 PROFILE_GetWineIniInt("Tweak.Layout", "CaptionTopNudge", 0);
134 NC_SysControlNudge =
135 PROFILE_GetWineIniInt("Tweak.Layout", "SysControlNudge", 0);
136 NC_MaxControlNudge =
137 PROFILE_GetWineIniInt("Tweak.Layout", "MaxControlNudge", 0);
138 NC_MinControlNudge =
139 PROFILE_GetWineIniInt("Tweak.Layout", "MinControlNudge", 0);
141 NC_WinHighlight95 = CreateSolidBrush32(RGB(0xc0, 0xc0, 0xc0));
142 NC_WinShadow95 = CreateSolidBrush32(RGB(0x00, 0x00, 0x00));
144 NC_CaptionTextFlags = DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX;
146 PROFILE_GetWineIniString("Tweak.Layout", "CaptionAlignment",
147 TWEAK_Win95Look ? "l" : "c", key_value, 2);
149 switch(key_value[0]) {
150 case 'l':
151 case 'L':
152 NC_CaptionTextFlags |= DT_LEFT;
153 break;
155 case 'r':
156 case 'R':
157 NC_CaptionTextFlags |= DT_RIGHT;
158 break;
160 default:
161 NC_CaptionTextFlags |= DT_CENTER;
164 return 1;
168 /******************************************************************************
170 * int TWEAK_VarInit()
172 * Initializes the miscellaneous variables which are used in the tweak
173 * routines. Return value is non-zero on success.
175 * Revision history
176 * 07-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
177 * Original implementation.
179 *****************************************************************************/
181 static int TWEAK_VarInit()
183 TWEAK_Win95Look = PROFILE_GetWineIniBool("Tweak.Layout", "Win95Look", 0);
185 /* FIXME: Each color should really occupy a single entry in the wine.conf
186 file, but I couldn't settle on a good (intuitive!) format. */
188 TWEAK_PenFF95 = CreatePen32(
189 PS_SOLID, 1,
190 RGB(PROFILE_GetWineIniInt("Tweak.Colors", "PenFF95.Red", 0xff),
191 PROFILE_GetWineIniInt("Tweak.Colors", "PenFF95.Grn", 0xff),
192 PROFILE_GetWineIniInt("Tweak.Colors", "PenFF95.Blu", 0xff)));
193 TWEAK_PenE095 = CreatePen32(
194 PS_SOLID, 1,
195 RGB(PROFILE_GetWineIniInt("Tweak.Colors", "PenE095.Red", 0xe0),
196 PROFILE_GetWineIniInt("Tweak.Colors", "PenE095.Grn", 0xe0),
197 PROFILE_GetWineIniInt("Tweak.Colors", "PenE095.Blu", 0xe0)));
198 TWEAK_PenC095 = CreatePen32(
199 PS_SOLID, 1,
200 RGB(PROFILE_GetWineIniInt("Tweak.Colors", "PenC095.Red", 0xc0),
201 PROFILE_GetWineIniInt("Tweak.Colors", "PenC095.Grn", 0xc0),
202 PROFILE_GetWineIniInt("Tweak.Colors", "PenC095.Blu", 0xc0)));
203 TWEAK_Pen8095 = CreatePen32(
204 PS_SOLID, 1,
205 RGB(PROFILE_GetWineIniInt("Tweak.Colors", "Pen8095.Red", 0x80),
206 PROFILE_GetWineIniInt("Tweak.Colors", "Pen8095.Grn", 0x80),
207 PROFILE_GetWineIniInt("Tweak.Colors", "Pen8095.Blu", 0x80)));
208 TWEAK_Pen0095 = CreatePen32(
209 PS_SOLID, 1,
210 RGB(PROFILE_GetWineIniInt("Tweak.Colors", "Pen0095.Red", 0x00),
211 PROFILE_GetWineIniInt("Tweak.Colors", "Pen0095.Grn", 0x00),
212 PROFILE_GetWineIniInt("Tweak.Colors", "Pen0095.Blu", 0x00)));
214 dprintf_tweak(stddeb, "TWEAK_VarInit: Using %s look and feel.\n",
215 TWEAK_Win95Look ? "Win95" : "Win3.1");
216 return 1;
220 /******************************************************************************
222 * int TWEAK_Init()
224 * Does the full initialization of the Win95 tweak subsystem. Return value
225 * indicates success. Called by loader/main.c's MAIN_Init().
227 * Revision history
228 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
229 * Original implementation.
231 *****************************************************************************/
233 int TWEAK_Init()
235 TWEAK_VarInit();
236 TWEAK_NonClientInit();
237 TWEAK_MenuInit();
238 return 1;
242 /******************************************************************************
244 * int TWEAK_CheckOldFonts()
246 * Examines wine.conf for old/invalid font entries and recommend changes to
247 * the user.
249 * Revision history
250 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
251 * Original implementation.
253 *****************************************************************************/
255 static void TWEAK_CheckOldFontsCallback(char const *, char const *, void *);
257 static char const *fontmsgprologue =
258 "Wine warning:\n"
259 " The following entries in the [fonts] section of the wine.conf file are\n"
260 " obsolete or invalid:\n";
262 static char const *fontmsgepilogue =
263 " These entries should be eliminated or updated.\n"
264 " See the documentation/fonts file for more information.\n";
266 static int TWEAK_CheckOldFonts()
268 int found = 0;
270 PROFILE_EnumerateWineIniSection("Fonts", &TWEAK_CheckOldFontsCallback,
271 (void *)&found);
272 if(found)
273 fprintf(stderr, fontmsgepilogue);
275 return 1;
278 static void TWEAK_CheckOldFontsCallback(
279 char const *key,
280 char const *value,
281 void *found)
283 /* Ignore any keys that start with potential comment characters "'", '#',
284 or ';'. */
285 if(key[0] == '\'' || key[0] == '#' || key[0] == ';' || key[0] == '\0')
286 return;
288 /* Make sure this is a valid key */
289 if(strncasecmp(key, "Alias", 5) == 0 ||
290 strcasecmp(key, "Default") == 0) {
292 /* Valid key; make sure the value doesn't contain a wildcard */
293 if(strchr(value, '*')) {
294 if(*(int *)found == 0) {
295 fprintf(stderr, fontmsgprologue);
296 ++*(int *)found;
299 fprintf(stderr, " %s=%s [no wildcards allowed]\n", key, value);
302 else {
303 /* Not a valid key */
304 if(*(int *)found == 0) {
305 fprintf(stderr, fontmsgprologue);
306 ++*(int *)found;
309 fprintf(stderr, " %s=%s [obsolete]\n", key, value);
312 return;
316 /******************************************************************************
318 * int TWEAK_CheckConfiguration()
320 * Examines wine.conf for old/bad entries and recommends changes to the user.
322 * Revision history
323 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
324 * Original implementation.
326 *****************************************************************************/
328 int TWEAK_CheckConfiguration()
330 TWEAK_CheckOldFonts();
331 return 1;
336 /******************************************************************************
338 * Tweak graphic subsystem.
340 *****************************************************************************/
342 /******************************************************************************
344 * void TWEAK_DrawReliefRect95(
345 * HDC32 hdc, // Device context on which to draw
346 * RECT32 const *rect ) // Rectangle to use
348 * Draws the double-bordered Win95-style relief rectangle.
350 * Bugs
351 * There are some checks missing from this function. Perhaps the
352 * SelectObject32 calls should be examined? Hasn't failed on me (yet).
354 * Should I really be calling X functions directly from here? It is
355 * an optimization, but should I be optimizing alpha code? Probably
356 * not.
358 * Revision history
359 * 08-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
360 * Original implementation.
362 *****************************************************************************/
364 void TWEAK_DrawReliefRect95(
365 HDC32 hdc,
366 RECT32 const *rect )
368 DC *dc;
369 HPEN32 prevpen;
371 if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) {
373 /* Draw the top/left lines first */
374 prevpen = SelectObject32(hdc, TWEAK_PenE095);
375 DC_SetupGCForPen(dc);
376 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
377 rect->right - 1, rect->top);
378 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
379 rect->left, rect->bottom - 1);
381 SelectObject32(hdc, TWEAK_PenFF95);
382 DC_SetupGCForPen(dc);
383 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
384 rect->top + 1, rect->right - 2, rect->top + 1);
385 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
386 rect->top + 1, rect->left + 1, rect->bottom - 2);
389 /* Now the bottom/right lines */
390 SelectObject32(hdc, TWEAK_Pen0095);
391 DC_SetupGCForPen(dc);
392 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left,
393 rect->bottom - 1, rect->right - 1, rect->bottom - 1);
394 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 1,
395 rect->top, rect->right - 1, rect->bottom - 1);
397 SelectObject32(hdc, TWEAK_Pen8095);
398 DC_SetupGCForPen(dc);
399 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
400 rect->bottom - 2, rect->right - 2, rect->bottom - 2);
401 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 2,
402 rect->top + 1, rect->right - 2, rect->bottom - 2);
404 SelectObject32(hdc, prevpen);
407 return;
411 /******************************************************************************
413 * void TWEAK_DrawRevReliefRect95(
414 * HDC32 hdc, // Device context on which to draw
415 * RECT32 const *rect ) // Rectangle to use
417 * Draws the double-bordered Win95-style relief rectangle.
419 * Bugs
420 * There are some checks missing from this function. Perhaps the
421 * SelectObject32 calls should be examined? Hasn't failed on me (yet).
423 * Should I really be calling X functions directly from here? It is
424 * an optimization, but should I be optimizing alpha code? Probably
425 * not.
427 * Revision history
428 * 08-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
429 * Original implementation.
431 *****************************************************************************/
433 void TWEAK_DrawRevReliefRect95(
434 HDC32 hdc,
435 RECT32 const *rect )
437 DC *dc;
438 HPEN32 prevpen;
440 if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) {
442 /* Draw the top/left lines first */
443 prevpen = SelectObject32(hdc, TWEAK_Pen8095);
444 DC_SetupGCForPen(dc);
445 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
446 rect->right - 1, rect->top);
447 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
448 rect->left, rect->bottom - 1);
450 SelectObject32(hdc, TWEAK_Pen0095);
451 DC_SetupGCForPen(dc);
452 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
453 rect->top + 1, rect->right - 2, rect->top + 1);
454 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
455 rect->top + 1, rect->left + 1, rect->bottom - 2);
458 /* Now the bottom/right lines */
459 SelectObject32(hdc, TWEAK_PenFF95);
460 DC_SetupGCForPen(dc);
461 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left,
462 rect->bottom - 1, rect->right - 1, rect->bottom - 1);
463 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 1,
464 rect->top, rect->right - 1, rect->bottom - 1);
466 SelectObject32(hdc, TWEAK_PenE095);
467 DC_SetupGCForPen(dc);
468 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
469 rect->bottom - 2, rect->right - 2, rect->bottom - 2);
470 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 2,
471 rect->top + 1, rect->right - 2, rect->bottom - 2);
473 SelectObject32(hdc, prevpen);
476 return;
481 /******************************************************************************
483 * void TWEAK_DrawMenuSeparatorHoriz95(
484 * HDC32 hdc, // Device context on which to draw
485 * UINT32 xc1, // Left x-coordinate
486 * UINT32 yc, // Y-coordinate of the LOWER line
487 * UINT32 xc2 ) // Right x-coordinate
489 * Draws a horizontal menu separator bar Win 95 style.
491 * Bugs
492 * Same as those for DrawReliefRect95.
494 * Revision history
495 * 08-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
496 * Original implementation.
497 * 11-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
498 * Changed name from DrawMenuSeparator95
500 *****************************************************************************/
502 void TWEAK_DrawMenuSeparatorHoriz95(
503 HDC32 hdc,
504 UINT32 xc1,
505 UINT32 yc,
506 UINT32 xc2 )
508 DC *dc;
509 HPEN32 prevpen;
511 if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) {
513 /* Draw the top line */
514 prevpen = SelectObject32(hdc, TWEAK_Pen8095);
515 DC_SetupGCForPen(dc);
516 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc1, yc - 1, xc2,
517 yc - 1);
519 /* And the bottom line */
520 SelectObject32(hdc, TWEAK_PenFF95);
521 DC_SetupGCForPen(dc);
522 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc1, yc, xc2, yc);
524 SelectObject32(hdc, prevpen);
527 return;
531 /******************************************************************************
533 * void TWEAK_DrawMenuSeparatorVert95(
534 * HDC32 hdc, // Device context on which to draw
535 * UINT32 xc, // X-coordinate of the RIGHT line
536 * UINT32 yc1, // top Y-coordinate
537 * UINT32 yc2 ) // bottom Y-coordinate
539 * Draws a vertical menu separator bar Win 95 style.
541 * Bugs
542 * Same as those for DrawReliefRect95.
544 * Revision history
545 * 11-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
546 * Original implementation.
548 *****************************************************************************/
550 void TWEAK_DrawMenuSeparatorVert95(
551 HDC32 hdc,
552 UINT32 xc,
553 UINT32 yc1,
554 UINT32 yc2 )
556 DC *dc;
557 HPEN32 prevpen;
559 if((dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC))) {
561 /* Draw the top line */
562 prevpen = SelectObject32(hdc, TWEAK_Pen8095);
563 DC_SetupGCForPen(dc);
564 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc, yc1, xc,
565 yc2);
567 /* And the bottom line */
568 SelectObject32(hdc, TWEAK_PenFF95);
569 DC_SetupGCForPen(dc);
570 XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc + 1, yc1, xc + 1,
571 yc2);
573 SelectObject32(hdc, prevpen);
576 return;