1 /* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
2 Copyright (C) 2006 and later, Cockos, Inc.
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
21 This file provides basic win32 GDI--> null translation.
25 #ifndef SWELL_PROVIDED_BY_APP
28 #include "swell-internal.h"
29 #include "../wdlcstring.h"
31 const char *g_swell_deffont_face
= "Arial";
33 swell_colortheme g_swell_ctheme
= {
34 #define __def_theme_ent(x,c) (c),
35 #define __def_theme_ent_fb(x,c,fb) (c),
36 SWELL_GENERIC_THEMEDEFS(__def_theme_ent
,__def_theme_ent_fb
)
37 #undef __def_theme_ent
38 #undef __def_theme_ent_fb
41 int GetSysColor(int idx
)
47 case COLOR_BTNFACE
: return g_swell_ctheme
._3dface
;
48 case COLOR_3DSHADOW
: return g_swell_ctheme
._3dshadow
;
49 case COLOR_3DHILIGHT
: return g_swell_ctheme
._3dhilight
;
50 case COLOR_3DDKSHADOW
: return g_swell_ctheme
._3ddkshadow
;
51 case COLOR_BTNTEXT
: return g_swell_ctheme
.button_text
;
52 case COLOR_INFOBK
: return g_swell_ctheme
.info_bk
;
53 case COLOR_INFOTEXT
: return g_swell_ctheme
.info_text
;
54 case COLOR_SCROLLBAR
: return g_swell_ctheme
.scrollbar
;
59 int g_swell_ui_scale
= 256;
61 int SWELL_GetScaling256(void)
63 return g_swell_ui_scale
;
66 #ifndef SWELL_LICE_GDI
69 #include "../ptrlist.h"
71 #include "swell-gdi-internalpool.h"
73 HDC
SWELL_CreateGfxContext(void *c
)
75 HDC__
*ctx
=SWELL_GDP_CTX_NEW();
81 HDC
SWELL_CreateMemContext(HDC hdc
, int w
, int h
)
83 // we could use CGLayer here, but it's 10.4+ and seems to be slower than this
85 void *buf
=calloc(w
*4,h
);
88 HDC__
*ctx
=SWELL_GDP_CTX_NEW();
96 void SWELL_DeleteGfxContext(HDC ctx
)
98 HDC__
*ct
=(HDC__
*)ctx
;
105 SWELL_GDP_CTX_DELETE(ct
);
108 HPEN
CreatePen(int attr
, int wid
, int col
)
110 return CreatePenAlpha(attr
,wid
,col
,1.0f
);
113 HBRUSH
CreateSolidBrush(int col
)
115 return CreateSolidBrushAlpha(col
,1.0f
);
118 HPEN
CreatePenAlpha(int attr
, int wid
, int col
, float alpha
)
120 HGDIOBJ__
*pen
=GDP_OBJECT_NEW();
122 pen
->wid
=wid
<0?0:wid
;
123 // pen->color=CreateColor(col,alpha);
126 HBRUSH
CreateSolidBrushAlpha(int col
, float alpha
)
128 HGDIOBJ__
*brush
=GDP_OBJECT_NEW();
129 brush
->type
=TYPE_BRUSH
;
130 // brush->color=CreateColor(col,alpha);
135 #define FONTSCALE 0.9
136 HFONT
CreateFont(int lfHeight
, int lfWidth
, int lfEscapement
, int lfOrientation
, int lfWeight
, char lfItalic
,
137 char lfUnderline
, char lfStrikeOut
, char lfCharSet
, char lfOutPrecision
, char lfClipPrecision
,
138 char lfQuality
, char lfPitchAndFamily
, const char *lfFaceName
)
140 HGDIOBJ__
*font
=GDP_OBJECT_NEW();
141 font
->type
=TYPE_FONT
;
142 float fontwid
=lfHeight
;
145 if (!fontwid
) fontwid
=lfWidth
;
146 if (fontwid
<0)fontwid
=-fontwid
;
148 if (fontwid
< 2 || fontwid
> 8192) fontwid
=10;
154 HFONT
CreateFontIndirect(LOGFONT
*lf
)
156 return CreateFont(lf
->lfHeight
, lf
->lfWidth
,lf
->lfEscapement
, lf
->lfOrientation
, lf
->lfWeight
, lf
->lfItalic
,
157 lf
->lfUnderline
, lf
->lfStrikeOut
, lf
->lfCharSet
, lf
->lfOutPrecision
,lf
->lfClipPrecision
,
158 lf
->lfQuality
, lf
->lfPitchAndFamily
, lf
->lfFaceName
);
161 int GetTextFace(HDC ctx
, int nCount
, LPTSTR lpFaceName
)
163 if (lpFaceName
) lpFaceName
[0]=0;
167 void DeleteObject(HGDIOBJ pen
)
169 if (HGDIOBJ_VALID(pen
))
171 HGDIOBJ__
*p
=(HGDIOBJ__
*)pen
;
172 if (--p
->additional_refcnt
< 0)
174 if (p
->type
== TYPE_PEN
|| p
->type
== TYPE_BRUSH
|| p
->type
== TYPE_FONT
|| p
->type
== TYPE_BITMAP
)
176 if (p
->type
== TYPE_PEN
|| p
->type
== TYPE_BRUSH
)
177 if (p
->wid
<0) return;
179 GDP_OBJECT_DELETE(p
);
181 // JF> don't free unknown objects, this should never happen anyway: else free(p);
187 HGDIOBJ
SelectObject(HDC ctx
, HGDIOBJ pen
)
189 HDC__
*c
=(HDC__
*)ctx
;
190 HGDIOBJ__
*p
=(HGDIOBJ__
*) pen
;
192 if (!HDC_VALID(c
)||!p
) return 0;
194 if (p
== (HGDIOBJ__
*)TYPE_PEN
) mod
=&c
->curpen
;
195 else if (p
== (HGDIOBJ__
*)TYPE_BRUSH
) mod
=&c
->curbrush
;
196 else if (p
== (HGDIOBJ__
*)TYPE_FONT
) mod
=&c
->curfont
;
205 if (!HGDIOBJ_VALID(p
)) return 0;
207 if (p
->type
== TYPE_PEN
) mod
=&c
->curpen
;
208 else if (p
->type
== TYPE_BRUSH
) mod
=&c
->curbrush
;
209 else if (p
->type
== TYPE_FONT
) mod
=&c
->curfont
;
213 if (!op
) op
=(HGDIOBJ__
*)(INT_PTR
)p
->type
;
218 if (p
->type
== TYPE_FONT
)
227 void SWELL_FillRect(HDC ctx
, const RECT
*r
, HBRUSH br
)
229 HDC__
*c
=(HDC__
*)ctx
;
230 HGDIOBJ__
*b
=(HGDIOBJ__
*) br
;
231 if (!HDC_VALID(c
) || !HGDIOBJ_VALID(b
,TYPE_BRUSH
)) return;
233 if (b
->wid
<0) return;
238 void RoundRect(HDC ctx
, int x
, int y
, int x2
, int y2
, int xrnd
, int yrnd
)
242 POINT pts
[10]={ // todo: curves between edges
255 WDL_GDP_Polygon(ctx
,pts
,sizeof(pts
)/sizeof(pts
[0]));
258 void Ellipse(HDC ctx
, int l
, int t
, int r
, int b
)
260 HDC__
*c
=(HDC__
*)ctx
;
261 if (!HDC_VALID(c
)) return;
263 //CGRect rect=CGRectMake(l,t,r-l,b-t);
265 if (HGDIOBJ_VALID(c
->curbrush
,TYPE_BRUSH
) && c
->curbrush
->wid
>=0)
268 if (HGDIOBJ_VALID(c
->curpen
,TYPE_PEN
) && c
->curpen
->wid
>= 0)
273 void Rectangle(HDC ctx
, int l
, int t
, int r
, int b
)
275 HDC__
*c
=(HDC__
*)ctx
;
276 if (!HDC_VALID(c
)) return;
278 if (HGDIOBJ_VALID(c
->curbrush
,TYPE_BRUSH
) && c
->curbrush
->wid
>= 0)
281 if (HGDIOBJ_VALID(c
->curpen
,TYPE_PEN
) && c
->curpen
->wid
>= 0)
286 HGDIOBJ
GetStockObject(int wh
)
292 static HGDIOBJ__ br
={0,};
299 static HGDIOBJ__ pen
={0,};
308 void Polygon(HDC ctx
, POINT
*pts
, int npts
)
310 HDC__
*c
=(HDC__
*)ctx
;
311 if (!HDC_VALID(c
)) return;
312 if (((!HGDIOBJ_VALID(c
->curbrush
,TYPE_BRUSH
)||c
->curbrush
->wid
<0) &&
313 (!HGDIOBJ_VALID(c
->curpen
,TYPE_PEN
)||c
->curpen
->wid
<0)) || npts
<2) return;
317 void MoveToEx(HDC ctx
, int x
, int y
, POINT
*op
)
319 HDC__
*c
=(HDC__
*)ctx
;
320 if (!HDC_VALID(c
)) return;
323 op
->x
= (int) (c
->lastpos_x
);
324 op
->y
= (int) (c
->lastpos_y
);
326 c
->lastpos_x
=(float)x
;
327 c
->lastpos_y
=(float)y
;
330 void PolyBezierTo(HDC ctx
, POINT
*pts
, int np
)
332 HDC__
*c
=(HDC__
*)ctx
;
333 if (!HDC_VALID(c
)||!HGDIOBJ_VALID(c
->curpen
,TYPE_PEN
)||c
->curpen
->wid
<0||np
<3) return;
337 for (x
= 0; x
< np
-2; x
+= 3)
339 xp
=(float)pts
[x
+2].x
;
340 yp
=(float)pts
[x
+2].y
;
342 c
->lastpos_x
=(float)xp
;
343 c
->lastpos_y
=(float)yp
;
347 void SWELL_LineTo(HDC ctx
, int x
, int y
)
349 HDC__
*c
=(HDC__
*)ctx
;
350 if (!HDC_VALID(c
)||!HGDIOBJ_VALID(c
->curpen
,TYPE_PEN
)||c
->curpen
->wid
<0) return;
352 float fx
=(float)x
,fy
=(float)y
;
358 void PolyPolyline(HDC ctx
, POINT
*pts
, DWORD
*cnts
, int nseg
)
360 HDC__
*c
=(HDC__
*)ctx
;
361 if (!HDC_VALID(c
)||!HGDIOBJ_VALID(c
->curpen
,TYPE_PEN
)||c
->curpen
->wid
<0||nseg
<1) return;
367 if (!--cnt
) { pts
++; continue; }
377 void *SWELL_GetCtxGC(HDC ctx
)
379 HDC__
*ct
=(HDC__
*)ctx
;
380 if (!HDC_VALID(ct
)) return 0;
385 void SWELL_SetPixel(HDC ctx
, int x
, int y
, int c
)
387 HDC__
*ct
=(HDC__
*)ctx
;
388 if (!HDC_VALID(ct
)) return;
392 BOOL
GetTextMetrics(HDC ctx
, TEXTMETRIC
*tm
)
394 HDC__
*ct
=(HDC__
*)ctx
;
395 if (tm
) // give some sane defaults
397 tm
->tmInternalLeading
=3;
401 tm
->tmAveCharWidth
= 10;
403 if (!HDC_VALID(ct
)||!tm
) return 0;
409 int DrawText(HDC ctx
, const char *buf
, int buflen
, RECT
*r
, int align
)
411 HDC__
*ct
=(HDC__
*)ctx
;
412 if (!HDC_VALID(ct
)) return 0;
413 if (r
&& (align
&DT_CALCRECT
))
417 r
->right
= ( buflen
< 0 ? strlen(buf
) : buflen
) *8;
419 else printf("DrawText: %s\n",buf
);
423 void SetBkColor(HDC ctx
, int col
)
425 HDC__
*ct
=(HDC__
*)ctx
;
426 if (!HDC_VALID(ct
)) return;
430 void SetBkMode(HDC ctx
, int col
)
432 HDC__
*ct
=(HDC__
*)ctx
;
433 if (!HDC_VALID(ct
)) return;
436 int GetTextColor(HDC ctx
)
438 HDC__
*ct
=(HDC__
*)ctx
;
439 if (!HDC_VALID(ct
)) return -1;
440 return ct
->cur_text_color_int
;
443 void SetTextColor(HDC ctx
, int col
)
445 HDC__
*ct
=(HDC__
*)ctx
;
446 if (!HDC_VALID(ct
)) return;
447 ct
->cur_text_color_int
= col
;
451 HICON
LoadNamedImage(const char *name
, bool alphaFromMask
)
456 void DrawImageInRect(HDC ctx
, HICON img
, const RECT
*r
)
462 BOOL
GetObject(HICON icon
, int bmsz
, void *_bm
)
465 if (bmsz
!= sizeof(BITMAP
)) return false;
466 HGDIOBJ__
*i
= (HGDIOBJ__
*)icon
;
467 if (!HGDIOBJ_VALID(i
,TYPE_BITMAP
)) return false;
468 //BITMAP *bm=(BITMAP *)_bm;
473 void BitBltAlphaFromMem(HDC hdcOut
, int x
, int y
, int w
, int h
, void *inbufptr
, int inbuf_span
, int inbuf_h
, int xin
, int yin
, int mode
, bool useAlphaChannel
, float opacity
)
477 void BitBltAlpha(HDC hdcOut
, int x
, int y
, int w
, int h
, HDC hdcIn
, int xin
, int yin
, int mode
, bool useAlphaChannel
, float opacity
)
481 void BitBlt(HDC hdcOut
, int x
, int y
, int w
, int h
, HDC hdcIn
, int xin
, int yin
, int mode
)
485 void StretchBlt(HDC hdcOut
, int x
, int y
, int w
, int h
, HDC hdcIn
, int xin
, int yin
, int srcw
, int srch
, int mode
)
489 void StretchBltFromMem(HDC hdcOut
, int x
, int y
, int w
, int h
, const void *bits
, int srcw
, int srch
, int srcspan
)
493 void SWELL_PushClipRegion(HDC ctx
)
495 // HDC__ *ct=(HDC__ *)ctx;
498 void SWELL_SetClipRegion(HDC ctx
, const RECT
*r
)
500 // HDC__ *ct=(HDC__ *)ctx;
504 void SWELL_PopClipRegion(HDC ctx
)
506 // HDC__ *ct=(HDC__ *)ctx;
509 void *SWELL_GetCtxFrameBuffer(HDC ctx
)
511 HDC__
*ct
=(HDC__
*)ctx
;
512 if (HDC_VALID(ct
)) return ct
->ownedData
;
522 HDC
GetWindowDC(HWND h
)
527 void ReleaseDC(HWND h
, HDC hdc
)
531 void SWELL_FillDialogBackground(HDC hdc
, const RECT
*r
, int level
)
535 HGDIOBJ
SWELL_CloneGDIObject(HGDIOBJ a
)
537 if (HGDIOBJ_VALID(a
))
539 a
->additional_refcnt
++;
545 HDC
BeginPaint(HWND hwnd
, PAINTSTRUCT
*ps
)
548 memset(ps
,0,sizeof(PAINTSTRUCT
));
555 HBITMAP
CreateBitmap(int width
, int height
, int numplanes
, int bitsperpixel
, unsigned char* bits
)
560 HICON
CreateIconIndirect(ICONINFO
* iconinfo
)
564 HIMAGELIST
ImageList_CreateEx()
566 return (HIMAGELIST
)new WDL_PtrList
<HGDIOBJ__
>;
568 BOOL
ImageList_Remove(HIMAGELIST list
, int idx
)
570 WDL_PtrList
<HGDIOBJ__
>* imglist
=(WDL_PtrList
<HGDIOBJ__
>*)list
;
571 if (imglist
&& idx
< imglist
->GetSize())
575 int x
,n
=imglist
->GetSize();
578 HGDIOBJ__
*a
= imglist
->Get(x
);
579 if (a
) DeleteObject(a
);
585 HGDIOBJ__
*a
= imglist
->Get(idx
);
586 imglist
->Set(idx
, NULL
);
587 if (a
) DeleteObject(a
);
595 void ImageList_Destroy(HIMAGELIST list
)
598 WDL_PtrList
<HGDIOBJ__
> *p
=(WDL_PtrList
<HGDIOBJ__
>*)list
;
599 ImageList_Remove(list
,-1);
603 int ImageList_ReplaceIcon(HIMAGELIST list
, int offset
, HICON image
)
605 if (!image
|| !list
) return -1;
606 WDL_PtrList
<HGDIOBJ__
> *l
=(WDL_PtrList
<HGDIOBJ__
> *)list
;
608 HGDIOBJ__
*imgsrc
= (HGDIOBJ__
*)image
;
609 if (!HGDIOBJ_VALID(imgsrc
,TYPE_BITMAP
)) return -1;
611 HGDIOBJ__
* icon
=GDP_OBJECT_NEW();
612 icon
->type
=TYPE_BITMAP
;
614 // todo: copy underlying image
616 image
= (HICON
) icon
;
618 if (offset
<0||offset
>=l
->GetSize())
621 offset
=l
->GetSize()-1;
625 HICON old
=l
->Get(offset
);
626 l
->Set(offset
,image
);
627 if (old
) DeleteObject(old
);
632 int ImageList_Add(HIMAGELIST list
, HBITMAP image
, HBITMAP mask
)
634 if (!image
|| !list
) return -1;
635 WDL_PtrList
<HGDIOBJ__
> *l
=(WDL_PtrList
<HGDIOBJ__
> *)list
;
637 HGDIOBJ__
*imgsrc
= (HGDIOBJ__
*)image
;
638 if (!HGDIOBJ_VALID(imgsrc
,TYPE_BITMAP
)) return -1;
640 HGDIOBJ__
* icon
=GDP_OBJECT_NEW();
641 icon
->type
=TYPE_BITMAP
;
643 // todo: copy underlying image
645 image
= (HICON
) icon
;
652 int AddFontResourceEx(LPCTSTR str
, DWORD fl
, void *pdv
)
657 int GetGlyphIndicesW(HDC ctx
, wchar_t *buf
, int len
, unsigned short *indices
, int flags
)
660 for (i
=0; i
< len
; ++i
) indices
[i
]=(flags
== GGI_MARK_NONEXISTING_GLYPHS
? 0xFFFF : 0);
664 #endif // !SWELL_LICE_GDI
666 #ifdef SWELL__MAKE_THEME
667 void print_ent(const char *x
, int c
, const char *def
)
670 printf("; %s #%02x%02x%02x ; defaults to %s\n",x
,GetRValue(c
),GetGValue(c
),GetBValue(c
),def
);
673 if (strstr(x
,"_size") ||
674 strstr(x
,"_height") ||
676 printf("%s %d\n",x
,c
);
677 else printf("%s #%02x%02x%02x\n",x
,GetRValue(c
),GetGValue(c
),GetBValue(c
));
683 #define __def_theme_ent(x,c) print_ent(#x,c,NULL);
684 #define __def_theme_ent_fb(x,c,fb) print_ent(#x,c,#fb);
686 printf("default_font_face %s\n",g_swell_deffont_face
);
687 SWELL_GENERIC_THEMEDEFS(__def_theme_ent
,__def_theme_ent_fb
)
693 class swellColorThemeLoader
696 swellColorThemeLoader()
699 GetModuleFileName(NULL
,buf
,sizeof(buf
));
700 WDL_remove_filepart(buf
);
701 lstrcatn(buf
,"/libSwell.colortheme",sizeof(buf
));
702 FILE *fp
= fopen(buf
,"r");
705 swell_colortheme load
;
706 memset(&load
,-1,sizeof(load
));
710 if (!fgets(buf
,sizeof(buf
),fp
)) break;
712 while (*p
== ' ' || *p
== '\t') p
++;
714 while (*np
> 0 && (*np
== '_' || isalnum(*np
))) np
++;
715 if (!*np
|| np
== p
) continue;
717 while (*np
== ' ' || *np
== '\t') np
++;
719 if(!stricmp(p
,"default_font_face"))
721 if (*np
> 0 && !isspace(*np
))
723 char *b
= strdup(np
);
724 g_swell_deffont_face
= b
;
725 while (*b
>0 && !isspace(*b
)) b
++;
736 col
= strtol(np
,&next
,16);
739 if (next
!= np
+3) continue;
740 col
= ((col
&0xf)<<4) | ((col
&0xf0)<<8) | ((col
&0xf00)<<12);
743 else if (*np
>= '0' && *np
<= '9')
750 #define __def_theme_ent(x,c) else if (!stricmp(p,#x)) load.x = col;
751 #define __def_theme_ent_fb(x,c,fb) else if (!stricmp(p,#x)) load.x = col;
752 SWELL_GENERIC_THEMEDEFS(__def_theme_ent
,__def_theme_ent_fb
)
753 #undef __def_theme_ent
754 #undef __def_theme_ent_fb
756 #define __def_theme_ent(x,c) g_swell_ctheme.x = load.x == -1 ? c : load.x;
757 #define __def_theme_ent_fb(x,c,fb) g_swell_ctheme.x = load.x == -1 ? g_swell_ctheme.fb : load.x;
758 SWELL_GENERIC_THEMEDEFS(__def_theme_ent
,__def_theme_ent_fb
)
759 #undef __def_theme_ent
760 #undef __def_theme_ent_fb
765 swellColorThemeLoader g_swell_themeloader
;