More rewriting imports. Also moved ui.h to out/.

This commit is contained in:
Pietro Gagliardi 2015-05-14 09:43:25 -04:00
parent b98de32786
commit 06cad86f55
12 changed files with 949 additions and 0 deletions

63
redo/GNUbase.mk Normal file
View File

@ -0,0 +1,63 @@
# 22 april 2015
OUTBASE = new
OUTDIR = out
OBJDIR = .obj
IDLFILES = \
ui.idl \
$(baseIDLFILES)
xHFILES = \
uipriv.h \
$(IDLFILES:%.idl=$(OUTDIR)/%.h) \
$(baseHFILES)
OFILES = \
$(baseCFILES:%.c=$(OBJDIR)/%.o) \
$(baseMFILES:%.m=$(OBJDIR)/%.o)
xCFLAGS = \
-g \
-Wall -Wextra \
-Wno-unused-parameter \
-Wno-switch \
--std=c99 \
$(CFLAGS) \
$(archmflag) \
$(baseCFLAGS)
xLDFLAGS = \
-g \
$(LDFLAGS) \
$(archmflag) \
$(baseLDFLAGS)
OUT = $(OUTDIR)/$(OUTBASE)$(baseSUFFIX)
$(OUT): $(OFILES) | $(OUTDIR)/.phony
@$(CC) -o $(OUT) $(OFILES) $(xLDFLAGS)
@echo ====== Linked $(OUT)
.SECONDEXPANSION:
$(OBJDIR)/%.o: %.c $(xHFILES) | $$(dir $$@).phony
@$(CC) -o $@ -c $< $(xCFLAGS)
@echo ====== Compiled $<
$(OBJDIR)/%.o: %.m $(xHFILES) | $$(dir $$@).phony
@$(CC) -o $@ -c $< $(xCFLAGS)
@echo ====== Compiled $<
# see http://www.cmcrossroads.com/article/making-directories-gnu-make
%/.phony:
@mkdir -p $(dir $@)
@touch $@
.PRECIOUS: %/.phony
$(OUTDIR)/%.h: %.idl tools/idl2h.go | $(OUTDIR)/.phony
@go run tools/idl2h.go -extern _UI_EXTERN -guard __UI_UI_H__ < $< > $@
@echo ====== Generated `basename $@`
clean:
rm -rf $(OUTDIR) $(OBJDIR) ui.h
.PHONY: clean

46
redo/GNUmakefile Normal file
View File

@ -0,0 +1,46 @@
# 22 april 2015
# MAME does this so :/
ifeq ($(OS),Windows_NT)
OS = windows
endif
ifndef OS
UNAME = $(shell uname -s)
ifeq ($(UNAME),Darwin)
OS = darwin
else
OS = unix
endif
endif
include $(OS)/GNUmakeinc.mk
#baseIDLFILES = \
# ui_$(OS).idl
baseHFILES = \
uipriv.h \
ui_$(OS).h \
$(osHFILES)
baseCFILES = \
box.c \
ptrarray.c \
shouldquit.c \
$(osCFILES)
baseMFILES = $(osMFILES)
baseCFLAGS = $(osCFLAGS)
baseLDFLAGS = \
-shared \
$(osLDWarnUndefinedFlags) \
$(osLDFLAGS)
baseSUFFIX = $(osLIBSUFFIX)
include GNUbase.mk
test: $(OUT)
@$(MAKE) -f GNUmaketest.mk osLIB=$(OUT) osEXESUFFIX=$(osEXESUFFIX) CC=$(CC) archmflag=$(archmflag)
.PHONY: test

16
redo/GNUmaketest.mk Normal file
View File

@ -0,0 +1,16 @@
# 22 april 2015
# should never be invoked directly, only ever from the main makefile
include test/GNUmakeinc.mk
baseHFILES = \
ui.h \
$(testHFILES)
baseCFILES = $(testCFILES)
baseCFLAGS = $(testCFLAGS)
baseLDFLAGS = $(osLIB) $(testLDFLAGS)
baseSUFFIX = $(osEXESUFFIX)
include GNUbase.mk

296
redo/box.c Normal file
View File

@ -0,0 +1,296 @@
// 7 april 2015
#include "out/ui.h"
#include "uipriv.h"
struct box {
uiBox b;
void (*baseDestroy)(uiControl *);
struct ptrArray *controls;
int vertical;
void (*baseSetParent)(uiControl *, uiContainer *);
uiContainer *parent;
int padded;
};
struct boxControl {
uiControl *c;
int stretchy;
intmax_t width; // both used by resize(); preallocated to save time and reduce risk of failure
intmax_t height;
};
static void boxDestroy(uiControl *c)
{
struct box *b = (struct box *) c;
struct boxControl *bc;
if (b->parent != NULL)
complain("attempt to destroy uiBox %p while it has a parent", b);
// don't chain up to base here; we need to destroy children ourselves first
while (b->controls->len != 0) {
bc = ptrArrayIndex(b->controls, struct boxControl *, 0);
uiControlSetParent(bc->c, NULL);
uiControlDestroy(bc->c);
ptrArrayDelete(b->controls, 0);
uiFree(bc);
}
ptrArrayDestroy(b->controls);
// NOW we can chain up to base
(*(b->baseDestroy))(uiControl(b));
uiFree(b);
}
static void boxSetParent(uiControl *c, uiContainer *parent)
{
struct box *b = (struct box *) c;
// this does all the actual work
(*(b->baseSetParent))(uiControl(b), parent);
// we just need to have a copy of the parent ourselves for boxSetPadded()
b->parent = parent;
}
static void boxPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
{
struct box *b = (struct box *) c;
struct boxControl *bc;
int xpadding, ypadding;
uintmax_t nStretchy;
// these two contain the largest preferred width and height of all stretchy controls in the box
// all stretchy controls will use this value to determine the final preferred size
intmax_t maxStretchyWidth, maxStretchyHeight;
uintmax_t i;
intmax_t preferredWidth, preferredHeight;
*width = 0;
*height = 0;
if (b->controls->len == 0)
return;
// 0) get this Box's padding
xpadding = 0;
ypadding = 0;
if (b->padded) {
xpadding = d->XPadding;
ypadding = d->YPadding;
}
// 1) initialize the desired rect with the needed padding
// TODO this is wrong if any controls are hidden
if (b->vertical)
*height = (b->controls->len - 1) * ypadding;
else
*width = (b->controls->len - 1) * xpadding;
// 2) add in the size of non-stretchy controls and get (but not add in) the largest widths and heights of stretchy controls
// we still add in like direction of stretchy controls
nStretchy = 0;
maxStretchyWidth = 0;
maxStretchyHeight = 0;
for (i = 0; i < b->controls->len; i++) {
bc = ptrArrayIndex(b->controls, struct boxControl *, i);
if (!uiControlVisible(bc->c))
continue;
uiControlPreferredSize(bc->c, d, &preferredWidth, &preferredHeight);
if (bc->stretchy) {
nStretchy++;
if (maxStretchyWidth < preferredWidth)
maxStretchyWidth = preferredWidth;
if (maxStretchyHeight < preferredHeight)
maxStretchyHeight = preferredHeight;
}
if (b->vertical) {
if (*width < preferredWidth)
*width = preferredWidth;
if (!bc->stretchy)
*height += preferredHeight;
} else {
if (!bc->stretchy)
*width += preferredWidth;
if (*height < preferredHeight)
*height = preferredHeight;
}
}
// 3) and now we can add in stretchy controls
if (b->vertical)
*height += nStretchy * maxStretchyHeight;
else
*width += nStretchy * maxStretchyWidth;
}
static void boxSysFunc(uiControl *c, uiControlSysFuncParams *p)
{
struct box *b = (struct box *) c;
struct boxControl *bc;
uintmax_t i;
for (i = 0; i < b->controls->len; i++) {
bc = ptrArrayIndex(b->controls, struct boxControl *, i);
uiControlSysFunc(bc->c, p);
}
}
static void boxResizeChildren(uiContainer *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
{
struct box *b = (struct box *) c;
struct boxControl *bc;
int xpadding, ypadding;
uintmax_t nStretchy;
intmax_t stretchywid, stretchyht;
uintmax_t i;
intmax_t preferredWidth, preferredHeight;
if (b->controls->len == 0)
return;
// -1) get this Box's padding
xpadding = 0;
ypadding = 0;
if (b->padded) {
xpadding = d->XPadding;
ypadding = d->YPadding;
}
// 0) inset the available rect by the needed padding
// TODO this is incorrect if any controls are hidden
if (b->vertical)
height -= (b->controls->len - 1) * ypadding;
else
width -= (b->controls->len - 1) * xpadding;
// 1) get width and height of non-stretchy controls
// this will tell us how much space will be left for stretchy controls
stretchywid = width;
stretchyht = height;
nStretchy = 0;
for (i = 0; i < b->controls->len; i++) {
bc = ptrArrayIndex(b->controls, struct boxControl *, i);
if (!uiControlVisible(bc->c))
continue;
if (bc->stretchy) {
nStretchy++;
continue;
}
uiControlPreferredSize(bc->c, d, &preferredWidth, &preferredHeight);
if (b->vertical) { // all controls have same width
bc->width = width;
bc->height = preferredHeight;
stretchyht -= preferredHeight;
} else { // all controls have same height
bc->width = preferredWidth;
bc->height = height;
stretchywid -= preferredWidth;
}
}
// 2) now get the size of stretchy controls
if (nStretchy != 0)
if (b->vertical)
stretchyht /= nStretchy;
else
stretchywid /= nStretchy;
for (i = 0; i < b->controls->len; i++) {
bc = ptrArrayIndex(b->controls, struct boxControl *, i);
if (!uiControlVisible(bc->c))
continue;
if (bc->stretchy) {
bc->width = stretchywid;
bc->height = stretchyht;
}
}
// 3) now we can position controls
for (i = 0; i < b->controls->len; i++) {
bc = ptrArrayIndex(b->controls, struct boxControl *, i);
if (!uiControlVisible(bc->c))
continue;
uiControlResize(bc->c, x, y, bc->width, bc->height, d);
if (b->vertical)
y += bc->height + ypadding;
else
x += bc->width + xpadding;
}
}
static void boxAppend(uiBox *ss, uiControl *c, int stretchy)
{
struct box *b = (struct box *) ss;
struct boxControl *bc;
bc = uiNew(struct boxControl);
bc->c = c;
bc->stretchy = stretchy;
uiControlSetParent(bc->c, uiContainer(b));
ptrArrayAppend(b->controls, bc);
uiContainerUpdate(uiContainer(b));
}
static void boxDelete(uiBox *ss, uintmax_t index)
{
struct box *b = (struct box *) ss;
struct boxControl *bc;
uiControl *removed;
// TODO rearrange this
// TODO sync call order with that of Destroy()
bc = ptrArrayIndex(b->controls, struct boxControl *, index);
removed = bc->c;
ptrArrayDelete(b->controls, index);
uiControlSetParent(removed, NULL);
uiFree(bc);
uiContainerUpdate(uiContainer(b));
}
static int boxPadded(uiBox *ss)
{
struct box *b = (struct box *) ss;
return b->padded;
}
static void boxSetPadded(uiBox *ss, int padded)
{
struct box *b = (struct box *) ss;
b->padded = padded;
uiContainerUpdate(uiContainer(b));
}
uiBox *uiNewHorizontalBox(void)
{
struct box *b;
b = uiNew(struct box);
uiMakeContainer(uiContainer(b));
b->controls = newPtrArray();
b->baseDestroy = uiControl(b)->Destroy;
uiControl(b)->Destroy = boxDestroy;
b->baseSetParent = uiControl(b)->SetParent;
uiControl(b)->SetParent = boxSetParent;
uiControl(b)->PreferredSize = boxPreferredSize;
uiControl(b)->SysFunc = boxSysFunc;
uiContainer(b)->ResizeChildren = boxResizeChildren;
uiBox(b)->Append = boxAppend;
uiBox(b)->Delete = boxDelete;
uiBox(b)->Padded = boxPadded;
uiBox(b)->SetPadded = boxSetPadded;
return uiBox(b);
}
uiBox *uiNewVerticalBox(void)
{
uiBox *bb;
struct box *b;
bb = uiNewHorizontalBox();
b = (struct box *) bb;
b->vertical = 1;
return bb;
}

54
redo/ptrarray.c Normal file
View File

@ -0,0 +1,54 @@
// 5 may 2015
#include <string.h>
#include "out/ui.h"
#include "uipriv.h"
struct ptrArray *newPtrArray(void)
{
return uiNew(struct ptrArray);
}
void ptrArrayDestroy(struct ptrArray *p)
{
if (p->len != 0)
complain("attempt to destroy ptrarray %p while it still has pointers inside", p);
if (p->ptrs != NULL) // array was created but nothing was ever put inside
uiFree(p->ptrs);
uiFree(p);
}
#define grow 32
void ptrArrayAppend(struct ptrArray *p, void *d)
{
if (p->len >= p->cap) {
p->cap += grow;
p->ptrs = (void **) uiRealloc(p->ptrs, p->cap * sizeof (void *), "void *[]");
}
p->ptrs[p->len] = d;
p->len++;
}
void ptrArrayInsertBefore(struct ptrArray *p, uintmax_t i, void *d)
{
if (i >= p->len)
complain("index out of range in ptrArrayInsertBefore()");
if (p->len >= p->cap) {
p->cap += grow;
p->ptrs = (void **) uiRealloc(p->ptrs, p->cap * sizeof (void *), "void *[]");
}
// thanks to ValleyBell
memmove(&(p->ptrs[i + 1]), &(p->ptrs[i]), (p->len - i) * sizeof (void *));
p->ptrs[i] = d;
p->len++;
}
void ptrArrayDelete(struct ptrArray *p, uintmax_t i)
{
if (i >= p->len)
complain("index out of range in ptrArrayRemove()");
// thanks to ValleyBell
memmove(&(p->ptrs[i]), &(p->ptrs[i + 1]), (p->len - i - 1) * sizeof (void *));
p->ptrs[p->len - 1] = NULL;
p->len--;
}

22
redo/shouldquit.c Normal file
View File

@ -0,0 +1,22 @@
// 9 may 2015
#include "out/ui.h"
#include "uipriv.h"
static int defaultOnShouldQuit(void *data)
{
return 0;
}
static int (*onShouldQuit)(void *) = defaultOnShouldQuit;
static void *onShouldQuitData;
void uiOnShouldQuit(int (*f)(void *), void *data)
{
onShouldQuit = f;
onShouldQuitData = data;
}
int shouldQuit(void)
{
return (*onShouldQuit)(onShouldQuitData);
}

188
redo/tools/idl2h.go Normal file
View File

@ -0,0 +1,188 @@
// 15 april 2015
package main
import (
"fmt"
"os"
"flag"
"github.com/andlabs/pgidl"
)
var extern = flag.String("extern", "extern", "name for extern")
var guard = flag.String("guard", "", "#define name for include guards")
var pkgtypes = map[string]string{}
func typedecl(t *pgidl.Type, name string) string {
if t == nil {
return "void " + name
}
if t.IsFuncPtr {
return cfuncptrdecl(t.FuncType, name)
}
s := t.Name + " "
if pkgtypes[t.Name] != "" {
s = pkgtypes[t.Name] + " "
}
for i := uint(0); i < t.NumPtrs; i++ {
s += "*"
}
return s + name
}
func arglist(a []*pgidl.Arg) string {
if len(a) == 0 {
return "void"
}
s := typedecl(a[0].Type, a[0].Name)
for i := 1; i < len(a); i++ {
s += ", " + typedecl(a[i].Type, a[i].Name)
}
return s
}
func cfuncdecl(f *pgidl.Func, name string) string {
fd := name + "(" + arglist(f.Args) + ")"
return *extern + " " + typedecl(f.Ret, fd) + ";"
}
func cfuncptrdecl(f *pgidl.Func, name string) string {
name = "(*" + name + ")"
fd := name + "(" + arglist(f.Args) + ")"
return typedecl(f.Ret, fd)
}
func cmethodmacro(f *pgidl.Func, typename string) string {
s := "#define " + typename + f.Name + "("
first := true
for _, a := range f.Args {
if !first {
s += ", "
}
s += a.Name
first = false
}
s += ") ("
s += "(*((this)->" + f.Name + "))"
s += "("
first = true
for _, a := range f.Args {
if !first {
s += ", "
}
s += "(" + a.Name + ")"
first = false
}
s += ")"
s += ")"
return s
}
func genpkgfunc(f *pgidl.Func, prefix string) {
fmt.Printf("%s\n", cfuncdecl(f, prefix + f.Name))
}
func genstruct(s *pgidl.Struct, prefix string) {
fmt.Printf("struct %s%s {\n", prefix, s.Name)
for _, f := range s.Fields {
fmt.Printf("\t%s;\n", typedecl(f.Type, f.Name))
}
fmt.Printf("};\n")
}
func geniface(i *pgidl.Interface, prefix string) {
fmt.Printf("struct %s%s {\n", prefix, i.Name)
if i.From != "" {
fmt.Printf("\t%s%s base;\n", prefix, i.From)
}
for _, f := range i.Fields {
fmt.Printf("\t%s;\n", typedecl(f.Type, f.Name))
}
for _, m := range i.Methods {
// hack our this pointer in
m.Args = append([]*pgidl.Arg{
&pgidl.Arg{
Name: "this",
Type: &pgidl.Type{
Name: prefix + i.Name,
NumPtrs: 1,
},
},
}, m.Args...)
fmt.Printf("\t%s;\n", cfuncptrdecl(m, m.Name))
fmt.Printf("%s\n", cmethodmacro(m, prefix + i.Name))
}
fmt.Printf("};\n")
fmt.Printf("#define %s%s(this) ((%s%s *) (this))\n",
prefix, i.Name,
prefix, i.Name)
}
func genenum(e *pgidl.Enum, prefix string) {
fmt.Printf("enum %s%s {\n", prefix, e.Name)
for _, m := range e.Members {
fmt.Printf("\t%s%s%s,\n", prefix, e.Name, m)
}
fmt.Printf("};\n")
}
func genpkg(p *pgidl.Package) {
for _, s := range p.Structs {
fmt.Printf("typedef struct %s%s %s%s;\n",
p.Name, s.Name,
p.Name, s.Name)
pkgtypes[s.Name] = p.Name + s.Name
}
for _, i := range p.Interfaces {
fmt.Printf("typedef struct %s%s %s%s;\n",
p.Name, i.Name,
p.Name, i.Name)
pkgtypes[i.Name] = p.Name + i.Name
}
for _, e := range p.Enums {
fmt.Printf("typedef enum %s%s %s%s;\n",
p.Name, e.Name,
p.Name, e.Name)
pkgtypes[e.Name] = p.Name + e.Name
}
// apparently we have to fully define C enumerations before we can use them...
for _, e := range p.Enums {
genenum(e, p.Name)
}
for _, o := range p.Order {
switch o.Which {
case pgidl.Funcs:
genpkgfunc(p.Funcs[o.Index], p.Name)
case pgidl.Structs:
genstruct(p.Structs[o.Index], p.Name)
case pgidl.Interfaces:
geniface(p.Interfaces[o.Index], p.Name)
case pgidl.Raws:
fmt.Printf("%s\n", p.Raws[o.Index])
case pgidl.Enums:
// we did them already; see above
}
}
}
func main() {
flag.Parse()
idl, errs := pgidl.Parse(os.Stdin, "<stdin>")
if len(errs) != 0 {
for _, e := range errs {
fmt.Fprintf(os.Stderr, "%s\n", e)
}
os.Exit(1)
}
fmt.Printf("// generated by idl2h; do not edit\n")
if *guard != "" {
fmt.Printf("#ifndef %s\n", *guard)
fmt.Printf("#define %s\n", *guard)
}
for _, p := range idl {
genpkg(p)
}
if *guard != "" {
fmt.Printf("#endif\n")
}
}

79
redo/ui_windows.h Normal file
View File

@ -0,0 +1,79 @@
// 7 april 2015
/*
This file assumes that you have included <windows.h> and "ui.h" beforehand. It provides API-specific functions for interfacing with foreign controls in Windows.
*/
#ifndef __UI_UI_WINDOWS_H__
#define __UI_UI_WINDOWS_H__
// uiWindowsMakeControl() initializes the given uiControl with the given Windows API control inside.
// You will need to provide the preferredSize() method yourself.
typedef struct uiWindowsMakeControlParams uiWindowsMakeControlParams;
struct uiWindowsMakeControlParams {
// These match the CreateWindowExW() function.
DWORD dwExStyle;
LPCWSTR lpClassName;
LPCWSTR lpWindowName;
DWORD dwStyle; // WS_CHILD and WS_VISIBLE are automatically applied.
HINSTANCE hInstance;
// Set this to non-FALSE to use the standard control font used by other ui controls.
BOOL useStandardControlFont;
// These are called when the control sends a WM_COMMAND or WM_NOTIFY (respectively) to its parent.
// ui redirects the message back and calls these functions.
// Store the result in *lResult and return any non-FALSE value (such as TRUE) to return the given result; return FALSE to pass the notification up to your window procedure.
// Note that these are only issued if they come from the uiControl itself; notifications from children of the uiControl (such as a header control) will be received normally.
BOOL (*onWM_COMMAND)(uiControl *c, WORD code, LRESULT *lResult);
BOOL (*onWM_NOTIFY)(uiControl *c, NMHDR *nm, LRESULT *lResult);
// This is called when the widget is ready to be destroyed.
void (*onDestroy)(void *data);
void *onDestroyData;
};
_UI_EXTERN void uiWindowsMakeControl(uiControl *c, uiWindowsMakeControlParams *p);
// This contains the Windows-specific parts of the uiSizing structure.
// BaseX and BaseY are the dialog base units.
// InternalLeading is the standard control font's internal leading; labels in uiForms use this for correct Y positioning.
struct uiSizingSys {
int BaseX;
int BaseY;
LONG InternalLeading;
// This is the window handle to pass to the hWndInsertAfter parameter of SetWindowPos().
// You should set this to your own window handle when done.
// Controls made with uiWindowsMakeControl() do this for you; you only need to do this if you are implementing uiControlResize() yourself.
HWND InsertAfter;
};
// Use these in your preferredSize() implementation with baseX and baseY.
#define uiWindowsDlgUnitsToX(dlg, baseX) MulDiv((dlg), baseX, 4)
#define uiWindowsDlgUnitsToY(dlg, baseY) MulDiv((dlg), baseY, 8)
// and use this if you need the text of the window width
_UI_EXTERN intmax_t uiWindowsWindowTextWidth(HWND hwnd);
// these functions get and set the window text for such a uiControl
// the value returned should be freed with uiFreeText()
_UI_EXTERN char *uiWindowsControlText(uiControl *);
_UI_EXTERN void uiWindowsControlSetText(uiControl *, const char *);
struct uiControlSysFuncParams {
int Func;
BOOL HasTabStops;
};
enum {
// These should enable and disable the uiControl while preserving the user enable/disable setting.
// These are needed because while disabling a parent window does cause children to stop receiving events, they are not shown as disabled, which is not what we want.
uiWindowsSysFuncContainerEnable,
uiWindowsSysFuncContainerDisable,
// This is interpreted by controls that are tab stops; the control should set HasTabStops to TRUE if so, and *LEAVE IT ALONE* if not.
// You only need this if implementing your own uiControl.
// Controls created with uiWindowsMakeControl() check for the window being enabled and the presence of WS_TABSTOP.
// The name is "has tab stops" because it is used by uiTabs to say "does the current tab page have tab stops?".
uiWindowsSysFuncHasTabStops,
};
#endif

34
redo/uipriv.h Normal file
View File

@ -0,0 +1,34 @@
// 6 april 2015
#include <stdlib.h>
extern uiInitOptions options;
extern void *uiAlloc(size_t, const char *);
#define uiNew(T) ((T *) uiAlloc(sizeof (T), #T))
extern void *uiRealloc(void *, size_t, const char *);
extern void uiFree(void *);
extern void complain(const char *, ...);
extern uiBin *newBin(void);
extern int binHasOSParent(uiBin *);
extern void binSetOSParent(uiBin *, uintptr_t);
extern void binRemoveOSParent(uiBin *);
extern void binResizeRootAndUpdate(uiBin *, intmax_t, intmax_t, intmax_t, intmax_t);
extern void binTranslateMargins(uiBin *, intmax_t *, intmax_t *, intmax_t *, intmax_t *, uiSizing *);
// array.c
struct ptrArray {
void **ptrs;
uintmax_t len;
uintmax_t cap;
};
struct ptrArray *newPtrArray(void);
void ptrArrayDestroy(struct ptrArray *);
void ptrArrayAppend(struct ptrArray *, void *);
void ptrArrayInsertBefore(struct ptrArray *, uintmax_t, void *);
void ptrArrayDelete(struct ptrArray *, uintmax_t);
#define ptrArrayIndex(p, T, i) ((T) ((p)->ptrs[(i)]))
// shouldquit.c
int shouldQuit(void);

View File

@ -0,0 +1,53 @@
# 22 april 2015
osCFILES = \
windows/alloc.c \
windows/bin.c \
windows/button.c \
windows/checkbox.c \
windows/comctl32.c \
windows/container.c \
windows/debug.c \
windows/entry.c \
windows/group.c \
windows/init.c \
windows/label.c \
windows/main.c \
windows/menu.c \
windows/newcontrol.c \
windows/tab.c \
windows/text.c \
windows/util.c \
windows/window.c
osHFILES = \
windows/uipriv_windows.h
# thanks ebassi in irc.gimp.net/#gtk+
osCFLAGS = \
-D_UI_EXTERN='__declspec(dllexport) extern'
osLDFLAGS = \
-static-libgcc \
-luser32 -lkernel32 -lgdi32 -luxtheme -lmsimg32 -lcomdlg32 -lole32 -loleaut32 -loleacc -luuid
osLDWarnUndefinedFlags = -Wl,--no-undefined -Wl,--no-allow-shlib-undefined
osLIBSUFFIX = .dll
osEXESUFFIX = .exe
ifeq ($(ARCH),amd64)
CC = x86_64-w64-mingw32-gcc
RC = x86_64-w64-mingw32-windres
archmflag = -m64
else
CC = i686-w64-mingw32-gcc
RC = i686-w64-mingw32-windres
archmflag = -m32
endif
ifeq ($(PROFILE),1)
osCFILES += windows/profiler.c
osCFLAGS += -finstrument-functions
osLDFLAGS += -finstrument-functions
endif

2
redo/windows/resize.c Normal file
View File

@ -0,0 +1,2 @@
// 14 may 2015
#include "uipriv_windows.h"

View File

@ -0,0 +1,96 @@
// 6 january 2015
#define UNICODE
#define _UNICODE
#define STRICT
#define STRICT_TYPED_ITEMIDS
#define CINTERFACE
#define COBJMACROS
// see https://github.com/golang/go/issues/9916#issuecomment-74812211
#define INITGUID
// get Windows version right; right now Windows XP
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
#define _WIN32_WINDOWS 0x0501 /* according to Microsoft's winperf.h */
#define _WIN32_IE 0x0600 /* according to Microsoft's sdkddkver.h */
#define NTDDI_VERSION 0x05010000 /* according to Microsoft's sdkddkver.h */
#include <windows.h>
#include <commctrl.h>
#include <stdint.h>
#include <uxtheme.h>
#include <string.h>
#include <wchar.h>
#include <windowsx.h>
#include <vsstyle.h>
#include <vssym32.h>
#include <stdarg.h>
#include <oleacc.h>
#include <stdio.h>
#include "../out/ui.h"
#include "../ui_windows.h"
#include "../uipriv.h"
// ui internal window messages
enum {
// redirected WM_COMMAND and WM_NOTIFY
msgCOMMAND = WM_APP + 0x40, // start offset just to be safe
msgNOTIFY,
msgUpdateChild, // fake because Windows seems to SWP_NOSIZE MoveWindow()s and SetWindowPos()s that don't change the window size (even if SWP_NOSIZE isn't specified)
msgHasTabStops,
msgConsoleEndSession,
};
// debug.c
extern HRESULT logLastError(const char *);
extern HRESULT logHRESULT(const char *, HRESULT);
extern HRESULT logMemoryExhausted(const char *);
// init.c
extern HINSTANCE hInstance;
extern int nCmdShow;
extern HFONT hMessageFont;
extern HBRUSH hollowBrush;
// util.c
extern int windowClassOf(HWND, ...);
extern void mapWindowRect(HWND, HWND, RECT *);
extern DWORD getStyle(HWND);
extern void setStyle(HWND, DWORD);
extern DWORD getExStyle(HWND);
extern void setExStyle(HWND, DWORD);
extern void moveWindow(HWND, intmax_t, intmax_t, intmax_t, intmax_t);
extern void moveAndReorderWindow(HWND, HWND, intmax_t, intmax_t, intmax_t, intmax_t);
// text.c
extern WCHAR *toUTF16(const char *);
extern char *toUTF8(const WCHAR *);
extern WCHAR *windowText(HWND);
// comctl32.c
extern BOOL (*WINAPI fv_SetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
extern BOOL (*WINAPI fv_RemoveWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR);
extern LRESULT (*WINAPI fv_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
extern const char *initCommonControls(void);
// window.c
extern ATOM registerWindowClass(HICON, HCURSOR);
extern void unregisterWindowClass(void);
// container.c
extern HWND initialParent;
extern const char *initContainer(HICON, HCURSOR);
extern void uninitContainer(void);
// menu.c
extern HMENU makeMenubar(void);
extern const uiMenuItem *menuIDToItem(UINT_PTR);
extern void runMenuEvent(WORD, uiWindow *);
extern void freeMenubar(HMENU);
extern void uninitMenus(void);
// alloc.c
extern int initAlloc(void);
extern void uninitAlloc(void);
// tab.c
extern void tabEnterTabNavigation(HWND);
extern void tabLeaveTabNavigation(HWND);