Move feedback stutter bug report to android folder
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
# use make
|
||||
# or make NOGDK=1
|
||||
# or make DEBUG=1
|
||||
# etc
|
||||
|
||||
ARCH := $(shell uname -m)
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
ifeq ($(ARCH), aarch64)
|
||||
ifeq ($(shell $(CC) -dumpmachine | cut -f 1 -d -), arm)
|
||||
# helper for armv7l userspace on aarch64 cpu
|
||||
ARCH := armv7l
|
||||
endif
|
||||
endif
|
||||
|
||||
PKG_CONFIG = pkg-config
|
||||
|
||||
COMPILER=GCC
|
||||
|
||||
CFLAGS = -pipe -fvisibility=hidden -fno-math-errno -fPIC -DPIC -Wall -Wshadow -Wno-unused-function -Wno-multichar -Wtype-limits -Wno-unused-value -fstrict-aliasing
|
||||
|
||||
CFLAGS += -DSWELL_MAKING_DYLIB
|
||||
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
CFLAGS += -Wno-unused-private-field -DSWELL_FORCE_GENERIC
|
||||
DLL_EXT=.dylib
|
||||
COMPILER=CLANG
|
||||
else
|
||||
DLL_EXT=.so
|
||||
CFLAGS += -D_FILE_OFFSET_BITS=64
|
||||
endif
|
||||
|
||||
ifeq ($(COMPILER),CLANG)
|
||||
CC = clang
|
||||
CXX = clang++
|
||||
endif
|
||||
|
||||
ifeq ($(COMPILER),ICC)
|
||||
CC = icc
|
||||
CXX = icpc
|
||||
CFLAGS += -D__PURE_SYS_C99_HEADERS__
|
||||
else
|
||||
CFLAGS += -Wno-unused-result
|
||||
endif
|
||||
|
||||
ifeq ($(COMPILER),GCC)
|
||||
GCC_VER := $(shell $(CXX) --version|head -n 1| sed 's/.* \([0-9][0-9]*\)[.].*/\1/' )
|
||||
GCC_GT_11 := $(shell [ "$(GCC_VER)" -gt 11 ] && echo true )
|
||||
ifeq ($(GCC_GT_11),true)
|
||||
# false positive in gcc 12/13
|
||||
CFLAGS += -Wno-dangling-pointer
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef DISALLOW_WARNINGS
|
||||
CFLAGS += -Werror
|
||||
endif
|
||||
ifndef DEPRECATED_WARNINGS
|
||||
CFLAGS += -Wno-deprecated-declarations
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),arm64)
|
||||
CFLAGS += -fsigned-char
|
||||
else
|
||||
ifneq ($(filter arm%,$(ARCH)),)
|
||||
CFLAGS += -fsigned-char -marm
|
||||
endif
|
||||
ifeq ($(ARCH),aarch64)
|
||||
CFLAGS += -fsigned-char
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(COMPILER),CLANG)
|
||||
CFLAGS += -Wbitwise-instead-of-logical
|
||||
endif
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS += -O0 -g -D_DEBUG
|
||||
else
|
||||
CFLAGS += -O2 -DNDEBUG
|
||||
ifdef DEBUG_INFO
|
||||
CFLAGS += -g
|
||||
else
|
||||
ifneq ($(COMPILER),CLANG)
|
||||
CFLAGS += -s
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
LINKEXTRA = -lpthread -ldl
|
||||
|
||||
|
||||
EXTRA_OBJS =
|
||||
|
||||
|
||||
|
||||
|
||||
vpath %.cpp .. ../lice
|
||||
|
||||
SWELL_OBJS = swell.o swell-ini.o swell-miscdlg-generic.o swell-wnd-generic.o \
|
||||
swell-menu-generic.o swell-kb-generic.o swell-dlg-generic.o \
|
||||
swell-gdi-generic.o swell-misc-generic.o swell-gdi-lice.o \
|
||||
swell-generic-headless.o swell-generic-gdk.o \
|
||||
swell-appstub-generic.o swell-modstub-generic.o
|
||||
|
||||
LICE_OBJS = lice.o lice_arc.o lice_colorspace.o lice_line.o lice_text.o \
|
||||
lice_textnew.o lice_ico.o lice_bmp.o
|
||||
|
||||
OBJS = $(SWELL_OBJS)
|
||||
|
||||
ifndef NOGDK
|
||||
ifdef GDK2
|
||||
CFLAGS += -DSWELL_TARGET_GDK=2 $(shell $(PKG_CONFIG) --cflags gdk-2.0)
|
||||
ifndef PRELOAD_GDK
|
||||
LINKEXTRA += $(shell $(PKG_CONFIG) --libs gdk-2.0)
|
||||
else
|
||||
LINKEXTRA += -lX11 -lXi
|
||||
CFLAGS += -DSWELL_PRELOAD="libgdk-x11-2.0.so.0"
|
||||
endif
|
||||
else
|
||||
ifdef SWELL_SUPPORT_GTK
|
||||
CFLAGS += -DSWELL_TARGET_GDK=3 $(shell $(PKG_CONFIG) --cflags gtk+-3.0) -DSWELL_SUPPORT_GTK
|
||||
else
|
||||
CFLAGS += -DSWELL_TARGET_GDK=3 $(shell $(PKG_CONFIG) --cflags gdk-3.0)
|
||||
endif
|
||||
ifndef PRELOAD_GDK
|
||||
ifdef SWELL_SUPPORT_GTK
|
||||
LINKEXTRA += $(shell $(PKG_CONFIG) --libs gtk+-3.0)
|
||||
else
|
||||
LINKEXTRA += $(shell $(PKG_CONFIG) --libs gdk-3.0)
|
||||
endif
|
||||
else
|
||||
LINKEXTRA += -lX11 -lXi
|
||||
ifdef SWELL_SUPPORT_GTK
|
||||
CFLAGS += -DSWELL_PRELOAD="libgtk+-3.so.0"
|
||||
else
|
||||
CFLAGS += -DSWELL_PRELOAD="libgdk-3.so.0"
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
CFLAGS += -DSWELL_LICE_GDI
|
||||
OBJS += $(LICE_OBJS)
|
||||
|
||||
ifndef NOFREETYPE
|
||||
CFLAGS += -DSWELL_FREETYPE $(shell $(PKG_CONFIG) --cflags freetype2)
|
||||
ifndef PRELOAD_GDK
|
||||
LINKEXTRA += $(shell $(PKG_CONFIG) --libs freetype2)
|
||||
endif
|
||||
ifndef NOFONTCONFIG
|
||||
CFLAGS += -DSWELL_FONTCONFIG
|
||||
LINKEXTRA += -lfontconfig
|
||||
endif
|
||||
endif
|
||||
LINKEXTRA += -lGL
|
||||
ifdef PRELOAD_GDK
|
||||
CFLAGS += -Wl,-z,lazy
|
||||
endif
|
||||
endif
|
||||
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
|
||||
default: libSwell$(DLL_EXT)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
SWELL_HEADERS=swell-dlggen.h swell-gdi-internalpool.h swell-menugen.h swell-types.h swell-functions.h swell-internal.h
|
||||
|
||||
swell.o: $(SWELL_HEADERS)
|
||||
swell-ini.o: $(SWELL_HEADERS)
|
||||
swell-wnd-generic.o: $(SWELL_HEADERS)
|
||||
swell-dlg-generic.o: $(SWELL_HEADERS)
|
||||
swell-menu-generic.o: $(SWELL_HEADERS)
|
||||
swell-misc-generic.o: $(SWELL_HEADERS)
|
||||
swell-gdi-generic.o: $(SWELL_HEADERS)
|
||||
swell-gdi-lice.o: $(SWELL_HEADERS)
|
||||
swell-kb-generic.o: $(SWELL_HEADERS)
|
||||
swell-miscdlg-generic.o: $(SWELL_HEADERS)
|
||||
swell-modstub-generic.o: $(SWELL_HEADERS)
|
||||
swell-appstub-generic.o: $(SWELL_HEADERS)
|
||||
|
||||
libSwell$(DLL_EXT): $(OBJS)
|
||||
$(CXX) -shared -o $@ $(CFLAGS) $(LFLAGS) $^ $(LINKEXTRA)
|
||||
|
||||
test: $(OBJS) test.o
|
||||
$(CXX) -o test $(CFLAGS) $(LFLAGS) $^ $(LINKEXTRA)
|
||||
|
||||
libSwell.colortheme: swell-gdi-generic.cpp $(SWELL_HEADERS)
|
||||
$(CXX) $(CFLAGS) -o make-theme -DSWELL__MAKE_THEME swell-gdi-generic.cpp -lpthread
|
||||
./make-theme > libSwell.colortheme
|
||||
|
||||
clean:
|
||||
-rm -f -- $(OBJS) libSwell$(DLL_EXT) make-theme libSwell.colortheme
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
Win32/Debug/
|
||||
Win32/Release/
|
||||
x64/Debug/
|
||||
x64/Release/
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.v12.suo
|
||||
+653
@@ -0,0 +1,653 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="SWELLApplication">
|
||||
<connections>
|
||||
<outlet property="delegate" destination="494" id="495"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="SWELLApplication"/>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="MyApp" id="56">
|
||||
<menu key="submenu" title="MyApp" systemMenu="apple" id="57">
|
||||
<items>
|
||||
<menuItem title="About MyApp" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="236">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="129"/>
|
||||
<menuItem isSeparatorItem="YES" id="143">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Services" id="131">
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="130"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="144">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hide MyApp" keyEquivalent="h" id="134">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="367"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="145">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="368"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150">
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="-1" id="370"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="149">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit MyApp" tag="40000" keyEquivalent="q" id="136">
|
||||
<connections>
|
||||
<action selector="onSysMenuCommand:" target="494" id="gT6-4H-hSd"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="83">
|
||||
<menu key="submenu" title="File" id="81">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="82">
|
||||
<connections>
|
||||
<action selector="newDocument:" target="-1" id="373"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72">
|
||||
<connections>
|
||||
<action selector="openDocument:" target="-1" id="374"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="124">
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="125">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="126">
|
||||
<connections>
|
||||
<action selector="clearRecentDocuments:" target="-1" id="127"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="79">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73">
|
||||
<connections>
|
||||
<action selector="performClose:" target="-1" id="193"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75">
|
||||
<connections>
|
||||
<action selector="saveDocument:" target="-1" id="362"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" id="112">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="364"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="74">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Page Setup..." keyEquivalent="P" id="77">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="runPageLayout:" target="-1" id="87"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78">
|
||||
<connections>
|
||||
<action selector="print:" target="-1" id="86"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="217">
|
||||
<menu key="submenu" title="Edit" id="205">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207">
|
||||
<connections>
|
||||
<action selector="undo:" target="-1" id="223"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="215">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="redo:" target="-1" id="231"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="206">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="228"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197">
|
||||
<connections>
|
||||
<action selector="copy:" target="-1" id="224"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203">
|
||||
<connections>
|
||||
<action selector="paste:" target="-1" id="226"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="485">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteAsPlainText:" target="-1" id="486"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202">
|
||||
<connections>
|
||||
<action selector="delete:" target="-1" id="235"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="-1" id="232"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="214">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Find" id="218">
|
||||
<menu key="submenu" title="Find" id="220">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="241"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="534">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="535"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="487"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="488"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="489"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="245"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="216">
|
||||
<menu key="submenu" title="Spelling and Grammar" id="200">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204">
|
||||
<connections>
|
||||
<action selector="showGuessPanel:" target="-1" id="230"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201">
|
||||
<connections>
|
||||
<action selector="checkSpelling:" target="-1" id="225"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="453"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219">
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="222"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="346">
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="347"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="454">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="456"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Substitutions" id="348">
|
||||
<menu key="submenu" title="Substitutions" id="349">
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="457">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="458"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="459"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350">
|
||||
<connections>
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="355"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351">
|
||||
<connections>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="356"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Dashes" id="460">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="461"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" tag="3" keyEquivalent="G" id="354">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="357"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="462">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="-1" id="463"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Transformations" id="450">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Transformations" id="451">
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="452">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="uppercaseWord:" target="-1" id="464"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="465">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowercaseWord:" target="-1" id="468"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="466">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="capitalizeWord:" target="-1" id="467"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Speech" id="211">
|
||||
<menu key="submenu" title="Speech" id="212">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="196">
|
||||
<connections>
|
||||
<action selector="startSpeaking:" target="-1" id="233"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="195">
|
||||
<connections>
|
||||
<action selector="stopSpeaking:" target="-1" id="227"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Format" id="375">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Format" id="376">
|
||||
<items>
|
||||
<menuItem title="Font" id="377">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="388">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389">
|
||||
<connections>
|
||||
<action selector="orderFrontFontPanel:" target="420" id="424"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="420" id="421"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="420" id="422"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392">
|
||||
<connections>
|
||||
<action selector="underline:" target="-1" id="432"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="393"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="420" id="425"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="420" id="423"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="396"/>
|
||||
<menuItem title="Kern" id="397">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Kern" id="415">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="416">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardKerning:" target="-1" id="438"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="417">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffKerning:" target="-1" id="441"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="418">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="tightenKerning:" target="-1" id="431"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="419">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="loosenKerning:" target="-1" id="435"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Ligatures" id="398">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Ligatures" id="411">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="412">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardLigatures:" target="-1" id="439"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="413">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffLigatures:" target="-1" id="440"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="414">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAllLigatures:" target="-1" id="434"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Baseline" id="399">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Baseline" id="405">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="406">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unscript:" target="-1" id="437"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="407">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="superscript:" target="-1" id="430"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="408">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="subscript:" target="-1" id="429"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="409">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="raiseBaseline:" target="-1" id="426"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="410">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowerBaseline:" target="-1" id="427"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="400"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401">
|
||||
<connections>
|
||||
<action selector="orderFrontColorPanel:" target="-1" id="433"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="402"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="403">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyFont:" target="-1" id="428"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="404">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteFont:" target="-1" id="436"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Text" id="496">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="497">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498">
|
||||
<connections>
|
||||
<action selector="alignLeft:" target="-1" id="524"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499">
|
||||
<connections>
|
||||
<action selector="alignCenter:" target="-1" id="518"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justify" id="500">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="alignJustified:" target="-1" id="523"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501">
|
||||
<connections>
|
||||
<action selector="alignRight:" target="-1" id="521"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="502"/>
|
||||
<menuItem title="Writing Direction" id="503">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Writing Direction" id="508">
|
||||
<items>
|
||||
<menuItem title="Paragraph" enabled="NO" id="509">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="510">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="525"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="511">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="526"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="512">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="527"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="513"/>
|
||||
<menuItem title="Selection" enabled="NO" id="514">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="515">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="-1" id="528"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="516">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="529"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="517">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="530"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="504"/>
|
||||
<menuItem title="Show Ruler" id="505">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleRuler:" target="-1" id="520"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="506">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyRuler:" target="-1" id="522"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="507">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteRuler:" target="-1" id="519"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="295">
|
||||
<menu key="submenu" title="View" id="296">
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="297">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="366"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298">
|
||||
<connections>
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="365"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="19">
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="24">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="-1" id="37"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="239">
|
||||
<connections>
|
||||
<action selector="performZoom:" target="-1" id="240"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="92">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Bring All to Front" id="5">
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="39"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Help" id="490">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="491">
|
||||
<items>
|
||||
<menuItem title="MyApp Help" keyEquivalent="?" id="492">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="493"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<customObject id="494" customClass="SWELLAppController"/>
|
||||
<customObject id="420" customClass="NSFontManager"/>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,102 @@
|
||||
APPNAME=myapp
|
||||
|
||||
WDL_PATH = ../WDL
|
||||
vpath swell%.cpp $(WDL_PATH)/swell
|
||||
vpath lice%.cpp $(WDL_PATH)/lice
|
||||
vpath %.c $(WDL_PATH)
|
||||
vpath %.cpp $(WDL_PATH) $(WDL_PATH)/wingui
|
||||
|
||||
###### Objects and resources (probably too many)
|
||||
SWELL_OBJS = swell.o swell-ini.o swell-miscdlg-generic.o swell-wnd-generic.o \
|
||||
swell-menu-generic.o swell-kb-generic.o swell-dlg-generic.o \
|
||||
swell-gdi-generic.o swell-misc-generic.o swell-gdi-lice.o \
|
||||
swell-generic-gdk.o swell-appstub-generic.o swell-modstub-generic.o
|
||||
|
||||
LICE_OBJS = lice_image.o lice_arc.o lice_line.o lice_text.o \
|
||||
lice_textnew.o lice.o lice_colorspace.o
|
||||
|
||||
OTHER_OBJS = wndsize.o
|
||||
|
||||
RESFILES = res.rc_mac_dlg res.rc_mac_menu
|
||||
|
||||
OBJS += myapp.o $(SWELL_OBJS) $(OTHER_OBJS)
|
||||
|
||||
|
||||
###### Compiler/Linker flags
|
||||
CFLAGS += -pipe -fvisibility=hidden -fno-math-errno -fPIC -DPIC -Wall -Wshadow -Wtype-limits \
|
||||
-Wno-unused-function -Wno-multichar -Wno-unused-result
|
||||
|
||||
CFLAGS += -D_FILE_OFFSET_BITS=64
|
||||
|
||||
ARCH := $(shell uname -m)
|
||||
PKG_CONFIG = pkg-config
|
||||
|
||||
ifndef ALLOW_WARNINGS
|
||||
CFLAGS += -Werror
|
||||
endif
|
||||
ifndef DEPRECATED_WARNINGS
|
||||
CFLAGS += -Wno-deprecated-declarations
|
||||
endif
|
||||
|
||||
ifneq ($(filter arm%,$(ARCH)),)
|
||||
CFLAGS += -fsigned-char -marm
|
||||
endif
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS += -O0 -g -D_DEBUG -DWDL_CHECK_FOR_NON_UTF8_FOPEN
|
||||
else
|
||||
CFLAGS += -O2 -DNDEBUG
|
||||
endif
|
||||
|
||||
LINKEXTRA = -lpthread -ldl
|
||||
|
||||
ifndef NOGDK
|
||||
ifdef GDK2
|
||||
CFLAGS += -DSWELL_TARGET_GDK=2 $(shell $(PKG_CONFIG) --cflags gdk-2.0)
|
||||
LINKEXTRA += $(shell $(PKG_CONFIG) --libs gdk-2.0)
|
||||
LINKEXTRA += -lX11 -lXi
|
||||
else
|
||||
ifdef SWELL_SUPPORT_GTK
|
||||
CFLAGS += -DSWELL_TARGET_GDK=3 $(shell $(PKG_CONFIG) --cflags gtk+-3.0) -DSWELL_SUPPORT_GTK
|
||||
else
|
||||
CFLAGS += -DSWELL_TARGET_GDK=3 $(shell $(PKG_CONFIG) --cflags gdk-3.0)
|
||||
endif
|
||||
LINKEXTRA += -lX11 -lXi -lGL
|
||||
ifdef SWELL_SUPPORT_GTK
|
||||
LINKEXTRA += $(shell $(PKG_CONFIG) --libs gtk+-3.0)
|
||||
else
|
||||
LINKEXTRA += $(shell $(PKG_CONFIG) --libs gdk-3.0)
|
||||
endif
|
||||
endif
|
||||
CFLAGS += -DSWELL_LICE_GDI
|
||||
OBJS += $(LICE_OBJS)
|
||||
|
||||
ifndef NOFREETYPE
|
||||
CFLAGS += -DSWELL_FREETYPE $(shell $(PKG_CONFIG) --cflags freetype2)
|
||||
LINKEXTRA += $(shell $(PKG_CONFIG) --libs freetype2)
|
||||
ifndef NOFONTCONFIG
|
||||
CFLAGS += -DSWELL_FONTCONFIG
|
||||
LINKEXTRA += -lfontconfig
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
|
||||
|
||||
default: $(APPNAME)
|
||||
|
||||
.PHONY: clean run
|
||||
|
||||
$(RESFILES): res.rc
|
||||
$(WDL_PATH)/swell/swell_resgen.pl $^
|
||||
|
||||
$(APPNAME): $(RESFILES) $(OBJS)
|
||||
$(CXX) -o $@ $(CFLAGS) $(OBJS) $(LINKEXTRA)
|
||||
|
||||
run: $(APPNAME)
|
||||
./$^
|
||||
|
||||
clean:
|
||||
-rm $(OBJS) $(APPNAME) $(RESFILES)
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>MyApp</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>nobody.swell.myapp</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.3</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2022</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>SWELLApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,9 @@
|
||||
//
|
||||
// Prefix header
|
||||
//
|
||||
// The contents of this file are implicitly included at the beginning of every source file.
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,28 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2013 for Windows Desktop
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyApp", "MyApp.vcxproj", "{DC8CCBA9-5214-48ED-96AE-C18B212FBE10}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{DC8CCBA9-5214-48ED-96AE-C18B212FBE10}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{DC8CCBA9-5214-48ED-96AE-C18B212FBE10}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{DC8CCBA9-5214-48ED-96AE-C18B212FBE10}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DC8CCBA9-5214-48ED-96AE-C18B212FBE10}.Debug|x64.Build.0 = Debug|x64
|
||||
{DC8CCBA9-5214-48ED-96AE-C18B212FBE10}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{DC8CCBA9-5214-48ED-96AE-C18B212FBE10}.Release|Win32.Build.0 = Release|Win32
|
||||
{DC8CCBA9-5214-48ED-96AE-C18B212FBE10}.Release|x64.ActiveCfg = Release|x64
|
||||
{DC8CCBA9-5214-48ED-96AE-C18B212FBE10}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{DC8CCBA9-5214-48ED-96AE-C18B212FBE10}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>MyApp</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;BUILD_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;BUILD_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;BUILD_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;BUILD_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\WDL\win32_utf8.c" />
|
||||
<ClCompile Include="..\WDL\wingui\wndsize.cpp" />
|
||||
<ClCompile Include="myapp.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="res.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\WDL">
|
||||
<UniqueIdentifier>{26d63633-dc60-4f96-afe7-14e5aa4ad154}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\WDL\wingui\wndsize.cpp">
|
||||
<Filter>Source Files\WDL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\WDL\win32_utf8.c">
|
||||
<Filter>Source Files\WDL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="myapp.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="res.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Vendored
+406
@@ -0,0 +1,406 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
338536692957A46300048720 /* myapp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 338536682957A46300048720 /* myapp.cpp */; };
|
||||
3385366B2957A4D300048720 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3385366A2957A4D300048720 /* main.m */; };
|
||||
338536702957A62F00048720 /* MyApp.icns in Resources */ = {isa = PBXBuildFile; fileRef = 3385366E2957A62F00048720 /* MyApp.icns */; };
|
||||
338536732957A6EB00048720 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 338536712957A6EB00048720 /* MainMenu.xib */; };
|
||||
3385932D185B555500FDFFEA /* wndsize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3385932C185B555500FDFFEA /* wndsize.cpp */; };
|
||||
33AA3116185A7E8D001D767E /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33AA3115185A7E8D001D767E /* Cocoa.framework */; };
|
||||
33AA3126185A7E8D001D767E /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 33AA3124185A7E8D001D767E /* Credits.rtf */; };
|
||||
33F96581185A7F79004C7070 /* swell-appstub.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33F96576185A7F79004C7070 /* swell-appstub.mm */; };
|
||||
33F96582185A7F79004C7070 /* swell-dlg.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33F96577185A7F79004C7070 /* swell-dlg.mm */; };
|
||||
33F96583185A7F79004C7070 /* swell-gdi.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33F96578185A7F79004C7070 /* swell-gdi.mm */; };
|
||||
33F96584185A7F79004C7070 /* swell-ini.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33F96579185A7F79004C7070 /* swell-ini.cpp */; };
|
||||
33F96585185A7F79004C7070 /* swell-kb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33F9657A185A7F79004C7070 /* swell-kb.mm */; };
|
||||
33F96586185A7F79004C7070 /* swell-menu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33F9657B185A7F79004C7070 /* swell-menu.mm */; };
|
||||
33F96587185A7F79004C7070 /* swell-misc.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33F9657C185A7F79004C7070 /* swell-misc.mm */; };
|
||||
33F96588185A7F79004C7070 /* swell-miscdlg.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33F9657D185A7F79004C7070 /* swell-miscdlg.mm */; };
|
||||
33F96589185A7F79004C7070 /* swell-wnd.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33F9657E185A7F79004C7070 /* swell-wnd.mm */; };
|
||||
33F9658A185A7F79004C7070 /* swell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33F9657F185A7F79004C7070 /* swell.cpp */; };
|
||||
33F9658B185A7F79004C7070 /* swellappmain.mm in Sources */ = {isa = PBXBuildFile; fileRef = 33F96580185A7F79004C7070 /* swellappmain.mm */; };
|
||||
33F9658D185A8228004C7070 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33F9658C185A8228004C7070 /* Carbon.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
338536682957A46300048720 /* myapp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = myapp.cpp; sourceTree = SOURCE_ROOT; };
|
||||
3385366A2957A4D300048720 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; };
|
||||
3385366C2957A62F00048720 /* MyApp-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "MyApp-Info.plist"; sourceTree = SOURCE_ROOT; };
|
||||
3385366D2957A62F00048720 /* MyApp-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MyApp-Prefix.pch"; sourceTree = SOURCE_ROOT; };
|
||||
3385366E2957A62F00048720 /* MyApp.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = MyApp.icns; sourceTree = SOURCE_ROOT; };
|
||||
338536722957A6EB00048720 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; };
|
||||
3385932C185B555500FDFFEA /* wndsize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = wndsize.cpp; path = ../WDL/wingui/wndsize.cpp; sourceTree = "<group>"; };
|
||||
33AA3112185A7E8D001D767E /* MyApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MyApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
33AA3115185A7E8D001D767E /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
33AA3118185A7E8D001D767E /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
33AA3119185A7E8D001D767E /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
33AA311A185A7E8D001D767E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
33AA311F185A7E8D001D767E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
33AA3125185A7E8D001D767E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
|
||||
33F96576185A7F79004C7070 /* swell-appstub.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-appstub.mm"; path = "../WDL/swell/swell-appstub.mm"; sourceTree = "<group>"; };
|
||||
33F96577185A7F79004C7070 /* swell-dlg.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-dlg.mm"; path = "../WDL/swell/swell-dlg.mm"; sourceTree = "<group>"; };
|
||||
33F96578185A7F79004C7070 /* swell-gdi.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-gdi.mm"; path = "../WDL/swell/swell-gdi.mm"; sourceTree = "<group>"; };
|
||||
33F96579185A7F79004C7070 /* swell-ini.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "swell-ini.cpp"; path = "../WDL/swell/swell-ini.cpp"; sourceTree = "<group>"; };
|
||||
33F9657A185A7F79004C7070 /* swell-kb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-kb.mm"; path = "../WDL/swell/swell-kb.mm"; sourceTree = "<group>"; };
|
||||
33F9657B185A7F79004C7070 /* swell-menu.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-menu.mm"; path = "../WDL/swell/swell-menu.mm"; sourceTree = "<group>"; };
|
||||
33F9657C185A7F79004C7070 /* swell-misc.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-misc.mm"; path = "../WDL/swell/swell-misc.mm"; sourceTree = "<group>"; };
|
||||
33F9657D185A7F79004C7070 /* swell-miscdlg.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-miscdlg.mm"; path = "../WDL/swell/swell-miscdlg.mm"; sourceTree = "<group>"; };
|
||||
33F9657E185A7F79004C7070 /* swell-wnd.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "swell-wnd.mm"; path = "../WDL/swell/swell-wnd.mm"; sourceTree = "<group>"; };
|
||||
33F9657F185A7F79004C7070 /* swell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = swell.cpp; path = ../WDL/swell/swell.cpp; sourceTree = "<group>"; };
|
||||
33F96580185A7F79004C7070 /* swellappmain.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = swellappmain.mm; path = ../WDL/swell/swellappmain.mm; sourceTree = "<group>"; };
|
||||
33F9658C185A8228004C7070 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
33AA310F185A7E8D001D767E /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
33F9658D185A8228004C7070 /* Carbon.framework in Frameworks */,
|
||||
33AA3116185A7E8D001D767E /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
33AA3109185A7E8D001D767E = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
338536712957A6EB00048720 /* MainMenu.xib */,
|
||||
338536682957A46300048720 /* myapp.cpp */,
|
||||
3385366C2957A62F00048720 /* MyApp-Info.plist */,
|
||||
3385366D2957A62F00048720 /* MyApp-Prefix.pch */,
|
||||
3385366E2957A62F00048720 /* MyApp.icns */,
|
||||
3385366A2957A4D300048720 /* main.m */,
|
||||
33AA3149185A7EEC001D767E /* WDL */,
|
||||
33AA311E185A7E8D001D767E /* InfoPlist.strings */,
|
||||
33AA3124185A7E8D001D767E /* Credits.rtf */,
|
||||
33AA3114185A7E8D001D767E /* Frameworks */,
|
||||
33AA3113185A7E8D001D767E /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
33AA3113185A7E8D001D767E /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
33AA3112185A7E8D001D767E /* MyApp.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
33AA3114185A7E8D001D767E /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
33F9658C185A8228004C7070 /* Carbon.framework */,
|
||||
33AA3115185A7E8D001D767E /* Cocoa.framework */,
|
||||
33AA3117185A7E8D001D767E /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
33AA3117185A7E8D001D767E /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
33AA3118185A7E8D001D767E /* AppKit.framework */,
|
||||
33AA3119185A7E8D001D767E /* CoreData.framework */,
|
||||
33AA311A185A7E8D001D767E /* Foundation.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
33AA3149185A7EEC001D767E /* WDL */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3385932C185B555500FDFFEA /* wndsize.cpp */,
|
||||
33AA314A185A7EF4001D767E /* swell */,
|
||||
);
|
||||
name = WDL;
|
||||
path = ../WDL;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
33AA314A185A7EF4001D767E /* swell */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
33F96576185A7F79004C7070 /* swell-appstub.mm */,
|
||||
33F96577185A7F79004C7070 /* swell-dlg.mm */,
|
||||
33F96578185A7F79004C7070 /* swell-gdi.mm */,
|
||||
33F96579185A7F79004C7070 /* swell-ini.cpp */,
|
||||
33F9657A185A7F79004C7070 /* swell-kb.mm */,
|
||||
33F9657B185A7F79004C7070 /* swell-menu.mm */,
|
||||
33F9657C185A7F79004C7070 /* swell-misc.mm */,
|
||||
33F9657D185A7F79004C7070 /* swell-miscdlg.mm */,
|
||||
33F9657E185A7F79004C7070 /* swell-wnd.mm */,
|
||||
33F9657F185A7F79004C7070 /* swell.cpp */,
|
||||
33F96580185A7F79004C7070 /* swellappmain.mm */,
|
||||
);
|
||||
name = swell;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
33AA3111185A7E8D001D767E /* MyApp */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 33AA3143185A7E8D001D767E /* Build configuration list for PBXNativeTarget "MyApp" */;
|
||||
buildPhases = (
|
||||
3304E16F1FC2253B00290319 /* ShellScript */,
|
||||
33AA310E185A7E8D001D767E /* Sources */,
|
||||
33AA310F185A7E8D001D767E /* Frameworks */,
|
||||
33AA3110185A7E8D001D767E /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = MyApp;
|
||||
productName = myapp;
|
||||
productReference = 33AA3112185A7E8D001D767E /* MyApp.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
33AA310A185A7E8D001D767E /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0500;
|
||||
ORGANIZATIONNAME = cockos;
|
||||
};
|
||||
buildConfigurationList = 33AA310D185A7E8D001D767E /* Build configuration list for PBXProject "MyApp" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 33AA3109185A7E8D001D767E;
|
||||
productRefGroup = 33AA3113185A7E8D001D767E /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
33AA3111185A7E8D001D767E /* MyApp */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
33AA3110185A7E8D001D767E /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
338536732957A6EB00048720 /* MainMenu.xib in Resources */,
|
||||
33AA3126185A7E8D001D767E /* Credits.rtf in Resources */,
|
||||
338536702957A62F00048720 /* MyApp.icns in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
3304E16F1FC2253B00290319 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/usr/bin/perl ../WDL/swell/swell_resgen.sh res.rc";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
33AA310E185A7E8D001D767E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
33F96581185A7F79004C7070 /* swell-appstub.mm in Sources */,
|
||||
33F9658B185A7F79004C7070 /* swellappmain.mm in Sources */,
|
||||
33F9658A185A7F79004C7070 /* swell.cpp in Sources */,
|
||||
33F96584185A7F79004C7070 /* swell-ini.cpp in Sources */,
|
||||
3385932D185B555500FDFFEA /* wndsize.cpp in Sources */,
|
||||
33F96589185A7F79004C7070 /* swell-wnd.mm in Sources */,
|
||||
33F96582185A7F79004C7070 /* swell-dlg.mm in Sources */,
|
||||
33F96585185A7F79004C7070 /* swell-kb.mm in Sources */,
|
||||
33F96586185A7F79004C7070 /* swell-menu.mm in Sources */,
|
||||
33F96583185A7F79004C7070 /* swell-gdi.mm in Sources */,
|
||||
338536692957A46300048720 /* myapp.cpp in Sources */,
|
||||
33F96587185A7F79004C7070 /* swell-misc.mm in Sources */,
|
||||
3385366B2957A4D300048720 /* main.m in Sources */,
|
||||
33F96588185A7F79004C7070 /* swell-miscdlg.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
338536712957A6EB00048720 /* MainMenu.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
338536722957A6EB00048720 /* Base */,
|
||||
);
|
||||
name = MainMenu.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
33AA311E185A7E8D001D767E /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
33AA311F185A7E8D001D767E /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
33AA3124185A7E8D001D767E /* Credits.rtf */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
33AA3125185A7E8D001D767E /* en */,
|
||||
);
|
||||
name = Credits.rtf;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
33AA3141185A7E8D001D767E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++98";
|
||||
CLANG_CXX_LIBRARY = "libstdc++";
|
||||
CLANG_ENABLE_OBJC_ARC = NO;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_STRICT_ALIASING = NO;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
33AA3142185A7E8D001D767E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++98";
|
||||
CLANG_CXX_LIBRARY = "libstdc++";
|
||||
CLANG_ENABLE_OBJC_ARC = NO;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_STRICT_ALIASING = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
33AA3144185A7E8D001D767E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "MyApp-Prefix.pch";
|
||||
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
|
||||
INFOPLIST_FILE = "MyApp-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = nobody.swell.myapp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
33AA3145185A7E8D001D767E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "MyApp-Prefix.pch";
|
||||
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
|
||||
INFOPLIST_FILE = "MyApp-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = nobody.swell.myapp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
33AA310D185A7E8D001D767E /* Build configuration list for PBXProject "MyApp" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
33AA3141185A7E8D001D767E /* Debug */,
|
||||
33AA3142185A7E8D001D767E /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
33AA3143185A7E8D001D767E /* Build configuration list for PBXNativeTarget "MyApp" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
33AA3144185A7E8D001D767E /* Debug */,
|
||||
33AA3145185A7E8D001D767E /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 33AA310A185A7E8D001D767E /* Project object */;
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
+7
@@ -0,0 +1,7 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf1265
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\vieww9600\viewh8400\viewkind0
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
|
||||
|
||||
\f0\b\fs24 \cf0 This is it, word.}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 766 B |
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// main.m
|
||||
// swell_myapp
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
extern const char **g_argv;
|
||||
extern int g_argc;
|
||||
g_argc=argc;
|
||||
g_argv=argv;
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
swell_myapp
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include "../WDL/win32_utf8.h"
|
||||
#endif
|
||||
|
||||
#include "../WDL/swell/swell.h"
|
||||
|
||||
#include "../WDL/wingui/wndsize.h"
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
bool g_quit;
|
||||
#endif
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
HWND g_hwnd;
|
||||
|
||||
WDL_DLGRET mainProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static WDL_WndSizer resize;
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
g_hwnd=hwndDlg;
|
||||
#ifdef _WIN32
|
||||
{
|
||||
HICON icon=LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON1));
|
||||
SetClassLongPtr(hwndDlg,GCLP_HICON,(LPARAM)icon);
|
||||
}
|
||||
#endif
|
||||
|
||||
resize.init(hwndDlg);
|
||||
resize.init_item(IDCANCEL,0,1,0,1);
|
||||
return 1;
|
||||
case WM_CLOSE:
|
||||
DestroyWindow(hwndDlg);
|
||||
return 1;
|
||||
case WM_DESTROY:
|
||||
g_hwnd=NULL;
|
||||
#ifdef __APPLE__
|
||||
SWELL_PostQuitMessage(0);
|
||||
#elif defined(_WIN32)
|
||||
PostQuitMessage(0);
|
||||
#else
|
||||
g_quit = true;
|
||||
#endif
|
||||
break;
|
||||
case WM_SIZE:
|
||||
if (wParam != SIZE_MINIMIZED)
|
||||
resize.onResize();
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case ID_QUIT:
|
||||
case IDCANCEL:
|
||||
DestroyWindow(hwndDlg);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case SWELLAPP_ONLOAD:
|
||||
{
|
||||
}
|
||||
break;
|
||||
case SWELLAPP_LOADED:
|
||||
{
|
||||
HWND h=CreateDialog(NULL,MAKEINTRESOURCE(IDD_DIALOG1),NULL,mainProc);
|
||||
ShowWindow(h,SW_SHOW);
|
||||
}
|
||||
break;
|
||||
case SWELLAPP_DESTROY:
|
||||
if (g_hwnd) DestroyWindow(g_hwnd);
|
||||
break;
|
||||
case SWELLAPP_ONCOMMAND:
|
||||
// this is to catch commands coming from the system menu etc
|
||||
if (g_hwnd && parm1) SendMessage(g_hwnd,WM_COMMAND,parm1,0);
|
||||
break;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
||||
{
|
||||
g_hInstance = hInstance;
|
||||
|
||||
SWELLAppMain(SWELLAPP_ONLOAD,0,0);
|
||||
SWELLAppMain(SWELLAPP_LOADED,0,0);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
MSG msg={0,};
|
||||
int vvv = GetMessage(&msg,NULL,0,0);
|
||||
if (!vvv) break;
|
||||
|
||||
if (vvv<0)
|
||||
{
|
||||
Sleep(10);
|
||||
continue;
|
||||
}
|
||||
if (!msg.hwnd)
|
||||
{
|
||||
DispatchMessage(&msg);
|
||||
continue;
|
||||
}
|
||||
if (SWELLAppMain(SWELLAPP_PROCESSMESSAGE, (INT_PTR) &msg, 0)) continue;
|
||||
|
||||
if (g_hwnd && IsDialogMessage(g_hwnd,&msg)) continue;
|
||||
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
SWELLAppMain(SWELLAPP_DESTROY,0,0);
|
||||
|
||||
ExitProcess(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/************** SWELL stuff ********** */
|
||||
|
||||
#ifdef __APPLE__
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const char **g_argv;
|
||||
int g_argc;
|
||||
|
||||
#ifdef __APPLE__
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __APPLE__
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
g_argc=argc;
|
||||
g_argv=argv;
|
||||
SWELL_initargs(&argc,(char***)&argv);
|
||||
SWELL_Internal_PostMessage_Init();
|
||||
SWELL_ExtendedAPI("APPNAME",(void*)"MyApp");
|
||||
SWELLAppMain(SWELLAPP_ONLOAD,0,0);
|
||||
SWELLAppMain(SWELLAPP_LOADED,0,0);
|
||||
while (!g_quit) {
|
||||
SWELL_RunMessageLoop();
|
||||
Sleep(10);
|
||||
}
|
||||
SWELLAppMain(SWELLAPP_DESTROY,0,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "../WDL/swell/swell-dlggen.h"
|
||||
#include "res.rc_mac_dlg"
|
||||
#undef BEGIN
|
||||
#undef END
|
||||
#include "../WDL/swell/swell-menugen.h"
|
||||
#include "res.rc_mac_menu"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
SWELL_MyApp
|
||||
Copyright (C) 2022 and onwards, Cockos Incorporated
|
||||
LICENSE:
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Minimal SWELL win32/linux/macOS GUI application starting point, feel free to base your applications on this.
|
||||
|
||||
NOTE: this project is not configured to be compiled in-place, you should move it to be alongside WDL, e.g.
|
||||
|
||||
cp -a ./WDL/swell/swell_myapp ./my_new_app
|
||||
|
||||
|
||||
------
|
||||
|
||||
Previous sample project xcode instructions:
|
||||
|
||||
How we created the xcode project that compiles this, too:
|
||||
|
||||
New Project -> Mac OS X -> Application -> Cocoa Application
|
||||
|
||||
Save as...
|
||||
|
||||
Add to "Other sources/SWELL": (from swell path) swell-dlg.mm swell-gdi.mm swell-ini.cpp swell-kb.mm swell-menu.mm swell-misc.mm swell-miscdlg.mm swell-wnd.mm swell.cpp swell-appstub.mm swellappmain.mm
|
||||
|
||||
Add app_main.cpp main_dialog.cpp to "Other sources"
|
||||
|
||||
Go to Frameworks -> Linked Frameworks, add existing framework, Carbon.Framework
|
||||
|
||||
go to terminal, to project dir, and run <pathtoswell>/swell_resgen.pl sample_project.rc
|
||||
|
||||
Open mainmenu.xib in Interface Builder (doubleclick it in XCode)
|
||||
|
||||
+ Delete the default "Window"
|
||||
+ File->Read class files, find and select "swellappmain.h"
|
||||
+ Go to Library, Objects, scroll to "Object" , drag to "MainMenu.xib", rename to "Controller", then open its
|
||||
properties (Cmd+Shift+I, go to class identity tab), choose for Class "SWELLAppController".
|
||||
+ Select "Application" in MainMenu.xib, go to (Cmd+Shift+I) application identity tab, select "SWELLApplication" for the class.
|
||||
|
||||
+ Customize the "NewApplication" menu.
|
||||
+ Properties on "About NewApplication":
|
||||
+ set the tag to 40002 (matching resource.h for about)
|
||||
+ on the connection tab, "Sent Actions", remove the default connection, then drag a new connection to controller (onSysMenuCommand).
|
||||
+ Properties on "Quit NewApplication":
|
||||
+ set the tag to 40001 (matching resource.h for quit)
|
||||
+ on the connection tab, "Sent Actions", remove the default connection, then drag a new connection to controller (onSysMenuCommand).
|
||||
+ Delete the file/edit/format/view/window/help menus, if you like (or keep some of them if you want)
|
||||
|
||||
+ Save and quit IB
|
||||
|
||||
Go to Targets->sample_project, hit cmd+I, go to "Properties", and change Principal class to "SWELLApplication"
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON1 ICON DISCARDABLE "icon1.ico"
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 377, 261
|
||||
STYLE DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
CAPTION "SWELL MyApp"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
PUSHBUTTON "Quit",IDCANCEL,4,244,50,14
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO DISCARDABLE
|
||||
BEGIN
|
||||
IDD_DIALOG1, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 4
|
||||
RIGHTMARGIN, 374
|
||||
TOPMARGIN, 3
|
||||
BOTTOMMARGIN, 258
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,0,0,1
|
||||
PRODUCTVERSION 0,0,0,1
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "unknown\0"
|
||||
VALUE "FileDescription", "swell_myapp\0"
|
||||
VALUE "FileVersion", "0, 0, 0, 1\0"
|
||||
VALUE "InternalName", "swell_myapp\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2022 and onwards\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "MyApp.exe\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "swell_myapp\0"
|
||||
VALUE "ProductVersion", "0, 0, l, 1\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by res.rc
|
||||
//
|
||||
#define IDI_ICON1 101
|
||||
#define IDD_DIALOG1 102
|
||||
#define IDC_EDIT1 1000
|
||||
#define IDC_BUTTON1 1001
|
||||
#define IDC_LASTMSG 1002
|
||||
#define IDC_CHECK1 1003
|
||||
#define ID_QUIT 40000
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 103
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1004
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "swell.h"
|
||||
|
||||
|
||||
#ifndef SWELL_PROVIDED_BY_APP
|
||||
|
||||
// only add this file to your project if you are an application that wishes to publish the SWELL API to its modules/plugins
|
||||
// the modules should be compiled using SWELL_PROVIDED_BY_APP and include swell-modstub-generic.cpp
|
||||
|
||||
#undef _WDL_SWELL_H_API_DEFINED_
|
||||
#undef SWELL_API_DEFINE
|
||||
#define SWELL_API_DEFINE(ret, func, parms) {#func, (void *)func },
|
||||
static struct api_ent
|
||||
{
|
||||
const char *name;
|
||||
void *func;
|
||||
}
|
||||
api_table[]=
|
||||
{
|
||||
#include "swell.h"
|
||||
};
|
||||
|
||||
static int compfunc(const void *a, const void *b)
|
||||
{
|
||||
return strcmp(((struct api_ent*)a)->name,((struct api_ent*)b)->name);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
__attribute__ ((visibility ("default"))) void *SWELLAPI_GetFunc(const char *name)
|
||||
{
|
||||
if (!name) return (void *)0x100; // version
|
||||
static int a;
|
||||
if (!a)
|
||||
{
|
||||
a=1;
|
||||
qsort(api_table,sizeof(api_table)/sizeof(api_table[0]),sizeof(api_table[0]),compfunc);
|
||||
}
|
||||
struct api_ent find={name,NULL};
|
||||
struct api_ent *res=(struct api_ent *)bsearch(&find,api_table,sizeof(api_table)/sizeof(api_table[0]),sizeof(api_table[0]),compfunc);
|
||||
if (res) return res->func;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#ifdef SWELL_MAKING_DYLIB
|
||||
static INT_PTR (*s_AppMain)(int msg, INT_PTR parm1, INT_PTR parm2);
|
||||
INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2)
|
||||
{
|
||||
if (s_AppMain) return s_AppMain(msg,parm1,parm2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
__attribute__ ((visibility ("default"))) void SWELL_set_app_main(INT_PTR (*AppMain)(int msg, INT_PTR parm1, INT_PTR parm2))
|
||||
{
|
||||
s_AppMain = AppMain;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "swell.h"
|
||||
|
||||
|
||||
#ifndef SWELL_PROVIDED_BY_APP
|
||||
|
||||
// only add this file to your project if you are an application that wishes to publish the SWELL API to its modules/plugins
|
||||
// the modules should be compiled using SWELL_PROVIDED_BY_APP and include swell-modstub.mm
|
||||
|
||||
#undef _WDL_SWELL_H_API_DEFINED_
|
||||
#undef SWELL_API_DEFINE
|
||||
#define SWELL_API_DEFINE(ret, func, parms) {#func, (void *)func },
|
||||
static struct api_ent
|
||||
{
|
||||
const char *name;
|
||||
void *func;
|
||||
}
|
||||
api_table[]=
|
||||
{
|
||||
#include "swell-functions.h"
|
||||
};
|
||||
|
||||
static int compfunc(const void *a, const void *b)
|
||||
{
|
||||
return strcmp(((struct api_ent*)a)->name,((struct api_ent*)b)->name);
|
||||
}
|
||||
|
||||
void *SWELLAPI_GetFunc(const char *name)
|
||||
{
|
||||
if (!name) return (void *)0x100; // version
|
||||
static int a;
|
||||
if (!a)
|
||||
{
|
||||
a=1;
|
||||
qsort(api_table,sizeof(api_table)/sizeof(api_table[0]),sizeof(api_table[0]),compfunc);
|
||||
}
|
||||
struct api_ent find={name,NULL};
|
||||
struct api_ent *res=(struct api_ent *)bsearch(&find,api_table,sizeof(api_table)/sizeof(api_table[0]),sizeof(api_table[0]),compfunc);
|
||||
if (res) return res->func;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,388 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SWELL_PROVIDED_BY_APP
|
||||
|
||||
#include "swell.h"
|
||||
#include "swell-dlggen.h"
|
||||
|
||||
#include "../ptrlist.h"
|
||||
|
||||
static HMENU g_swell_defaultmenu,g_swell_defaultmenumodal;
|
||||
|
||||
bool SWELL_owned_windows_levelincrease=false;
|
||||
|
||||
#include "swell-internal.h"
|
||||
|
||||
static SWELL_DialogResourceIndex *resById(SWELL_DialogResourceIndex *reshead, const char *resid)
|
||||
{
|
||||
SWELL_DialogResourceIndex *p=reshead;
|
||||
while (p)
|
||||
{
|
||||
if (p->resid == resid) return p;
|
||||
p=p->_next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// keep list of modal dialogs
|
||||
struct modalDlgRet {
|
||||
HWND hwnd;
|
||||
bool has_ret;
|
||||
int ret;
|
||||
};
|
||||
|
||||
|
||||
static WDL_PtrList<modalDlgRet> s_modalDialogs;
|
||||
|
||||
bool IsModalDialogBox(HWND hwnd)
|
||||
{
|
||||
if (WDL_NOT_NORMALLY(!hwnd)) return false;
|
||||
int a = s_modalDialogs.GetSize();
|
||||
while (a-- > 0)
|
||||
{
|
||||
modalDlgRet *r = s_modalDialogs.Get(a);
|
||||
if (r && r->hwnd == hwnd) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HWND DialogBoxIsActive()
|
||||
{
|
||||
int a = s_modalDialogs.GetSize();
|
||||
while (a-- > 0)
|
||||
{
|
||||
modalDlgRet *r = s_modalDialogs.Get(a);
|
||||
if (r && !r->has_ret && r->hwnd) return r->hwnd;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SWELL_OSWINDOW s_spare;
|
||||
static RECT s_spare_rect;
|
||||
static UINT_PTR s_spare_timer;
|
||||
static int s_spare_style;
|
||||
|
||||
void swell_dlg_destroyspare()
|
||||
{
|
||||
if (s_spare_timer)
|
||||
{
|
||||
KillTimer(NULL,s_spare_timer);
|
||||
s_spare_timer=0;
|
||||
}
|
||||
if (s_spare)
|
||||
{
|
||||
#ifdef SWELL_TARGET_GDK
|
||||
gdk_window_destroy(s_spare);
|
||||
#endif
|
||||
s_spare=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void spareTimer(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwtime)
|
||||
{
|
||||
swell_dlg_destroyspare();
|
||||
}
|
||||
|
||||
static int s_last_dlgret;
|
||||
|
||||
void EndDialog(HWND wnd, int ret)
|
||||
{
|
||||
if (WDL_NOT_NORMALLY(!wnd)) return;
|
||||
|
||||
int a = s_modalDialogs.GetSize();
|
||||
while (a-->0)
|
||||
{
|
||||
modalDlgRet *r = s_modalDialogs.Get(a);
|
||||
if (r && r->hwnd == wnd)
|
||||
{
|
||||
r->ret = ret;
|
||||
if (r->has_ret) return;
|
||||
|
||||
r->has_ret=true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wnd->m_hashaddestroy)
|
||||
{
|
||||
void RecurseDestroyWindow(HWND);
|
||||
SendMessage(wnd,WM_DESTROY,0,0);
|
||||
#ifndef SWELL_NO_SPARE_MODALDLG
|
||||
if (wnd->m_oswindow && wnd->m_visible)
|
||||
{
|
||||
swell_dlg_destroyspare();
|
||||
s_spare_rect = wnd->m_position;
|
||||
s_spare_style = wnd->m_style;
|
||||
s_spare = wnd->m_oswindow;
|
||||
wnd->m_oswindow = NULL;
|
||||
s_spare_timer = SetTimer(NULL,0,
|
||||
swell_is_app_inactive()>0 ? 500 : 100,
|
||||
spareTimer);
|
||||
}
|
||||
#endif
|
||||
RecurseDestroyWindow(wnd);
|
||||
}
|
||||
s_last_dlgret = ret;
|
||||
}
|
||||
|
||||
int SWELL_DialogBox(SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param)
|
||||
{
|
||||
SWELL_DialogResourceIndex *p=resById(reshead,resid);
|
||||
if (resid) // allow modal dialogs to be created without template
|
||||
{
|
||||
if (!p||(p->windowTypeFlags&SWELL_DLG_WS_CHILD)) return -1;
|
||||
}
|
||||
else if (parent)
|
||||
{
|
||||
resid = (const char *)(INT_PTR)(0x400002); // force non-child, force no minimize box
|
||||
}
|
||||
|
||||
|
||||
int ret=-1;
|
||||
s_last_dlgret = -1;
|
||||
HWND hwnd = SWELL_CreateDialog(reshead,resid,parent,dlgproc,param);
|
||||
// create dialog
|
||||
if (hwnd)
|
||||
{
|
||||
hwnd->Retain();
|
||||
|
||||
void SWELL_OnNavigationFocus(HWND ch);
|
||||
HWND SWELL_GetFocusedChild(HWND h);
|
||||
SWELL_OnNavigationFocus(SWELL_GetFocusedChild(hwnd));
|
||||
|
||||
ReleaseCapture(); // force end of any captures
|
||||
|
||||
WDL_PtrKeyedArray<int> restwnds;
|
||||
extern HWND__ *SWELL_topwindows;
|
||||
HWND a = SWELL_topwindows;
|
||||
while (a)
|
||||
{
|
||||
if (a!=hwnd)
|
||||
{
|
||||
int f=0;
|
||||
if (a->m_enabled) { EnableWindow(a,FALSE); f|=1; }
|
||||
if (a->m_israised) { SWELL_SetWindowLevel(a,0); f|=2; }
|
||||
if (f) restwnds.AddUnsorted((INT_PTR)a,f);
|
||||
}
|
||||
a = a->m_next;
|
||||
}
|
||||
restwnds.Resort();
|
||||
SWELL_SetWindowLevel(hwnd,1);
|
||||
|
||||
modalDlgRet r = { hwnd,false, -1 };
|
||||
s_modalDialogs.Add(&r);
|
||||
|
||||
if (s_spare && s_spare_style == hwnd->m_style)
|
||||
{
|
||||
if (s_spare_timer)
|
||||
{
|
||||
KillTimer(NULL,s_spare_timer);
|
||||
s_spare_timer = 0;
|
||||
}
|
||||
SWELL_OSWINDOW w = s_spare;
|
||||
s_spare = NULL;
|
||||
|
||||
int flags = 0;
|
||||
const int dw = (hwnd->m_position.right-hwnd->m_position.left) -
|
||||
(s_spare_rect.right - s_spare_rect.left);
|
||||
const int dh = (hwnd->m_position.bottom-hwnd->m_position.top) -
|
||||
(s_spare_rect.bottom - s_spare_rect.top);
|
||||
|
||||
if (hwnd->m_has_had_position) flags |= 1;
|
||||
if (dw || dh) flags |= 2;
|
||||
|
||||
if (flags == 2)
|
||||
{
|
||||
// center on the old window
|
||||
hwnd->m_position.right -= hwnd->m_position.left;
|
||||
hwnd->m_position.bottom -= hwnd->m_position.top;
|
||||
hwnd->m_position.left = s_spare_rect.left - dw/2;
|
||||
hwnd->m_position.top = s_spare_rect.top - dh/2;
|
||||
hwnd->m_position.right += hwnd->m_position.left;
|
||||
hwnd->m_position.bottom += hwnd->m_position.top;
|
||||
flags = 3;
|
||||
}
|
||||
|
||||
if (flags)
|
||||
{
|
||||
if (flags&2) swell_oswindow_begin_resize(w);
|
||||
swell_oswindow_resize(w, flags, hwnd->m_position);
|
||||
}
|
||||
hwnd->m_oswindow = w;
|
||||
|
||||
if (!flags)
|
||||
{
|
||||
hwnd->m_has_had_position = true;
|
||||
hwnd->m_position = s_spare_rect;
|
||||
if (!hwnd->m_hashaddestroy)
|
||||
{
|
||||
void swell_recalcMinMaxInfo(HWND hwnd);
|
||||
swell_recalcMinMaxInfo(hwnd);
|
||||
}
|
||||
}
|
||||
swell_oswindow_focus(hwnd);
|
||||
|
||||
ShowWindow(hwnd,SW_SHOWNA);
|
||||
InvalidateRect(hwnd,NULL,FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
swell_dlg_destroyspare();
|
||||
ShowWindow(hwnd,SW_SHOW);
|
||||
}
|
||||
|
||||
while (!r.has_ret && !hwnd->m_hashaddestroy)
|
||||
{
|
||||
void SWELL_RunMessageLoop();
|
||||
SWELL_RunMessageLoop();
|
||||
Sleep(10);
|
||||
}
|
||||
ret=r.ret;
|
||||
s_modalDialogs.DeletePtr(&r);
|
||||
|
||||
a = SWELL_topwindows;
|
||||
while (a)
|
||||
{
|
||||
if (a != hwnd)
|
||||
{
|
||||
int f = restwnds.Get((INT_PTR)a);
|
||||
if (!a->m_enabled && (f&1)) EnableWindow(a,TRUE);
|
||||
if (!a->m_israised && (f&2)) SWELL_SetWindowLevel(a,1);
|
||||
}
|
||||
a = a->m_next;
|
||||
}
|
||||
hwnd->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = s_last_dlgret; // SWELL_CreateDialog() failed, implies WM_INITDIALOG could have called EndDialog()
|
||||
}
|
||||
// while in list, do something
|
||||
return ret;
|
||||
}
|
||||
|
||||
HWND SWELL_CreateDialog(SWELL_DialogResourceIndex *reshead, const char *resid, HWND parent, DLGPROC dlgproc, LPARAM param)
|
||||
{
|
||||
int forceStyles=0; // 1=resizable, 2=no minimize, 4=no close
|
||||
bool forceNonChild=false;
|
||||
if ((((INT_PTR)resid)&~0xf)==0x400000)
|
||||
{
|
||||
forceStyles = (int) (((INT_PTR)resid)&0xf);
|
||||
if (forceStyles) forceNonChild=true;
|
||||
resid=0;
|
||||
}
|
||||
SWELL_DialogResourceIndex *p=resById(reshead,resid);
|
||||
if (!p&&resid) return 0;
|
||||
|
||||
// SWELL_DLG_WS_DEFAULT_SCALING is not used on -generic, because it is not needed (DPI-scaling instead)
|
||||
RECT r={0,0,SWELL_UI_SCALE(p ? p->width : 300), SWELL_UI_SCALE(p ? p->height : 200) };
|
||||
HWND owner=NULL;
|
||||
|
||||
if (!forceNonChild && parent && (!p || (p->windowTypeFlags&SWELL_DLG_WS_CHILD)))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
owner = parent;
|
||||
parent = NULL; // top level window
|
||||
}
|
||||
|
||||
HWND__ *h = new HWND__(parent,0,&r,NULL,false,NULL,NULL, owner);
|
||||
if (forceNonChild || (p && !(p->windowTypeFlags&SWELL_DLG_WS_CHILD)))
|
||||
{
|
||||
if ((forceStyles&1) || (p && (p->windowTypeFlags&SWELL_DLG_WS_RESIZABLE)))
|
||||
h->m_style |= WS_THICKFRAME|WS_CAPTION;
|
||||
else h->m_style |= WS_CAPTION;
|
||||
}
|
||||
else if (!p && !parent) h->m_style |= WS_CAPTION;
|
||||
else if (parent && (!p || (p->windowTypeFlags&SWELL_DLG_WS_CHILD))) h->m_style |= WS_CHILD;
|
||||
|
||||
if (p)
|
||||
{
|
||||
h->m_style |= p->windowTypeFlags & (WS_CLIPSIBLINGS);
|
||||
if (p->windowTypeFlags&SWELL_DLG_WS_DROPTARGET)
|
||||
h->m_exstyle|=WS_EX_ACCEPTFILES;
|
||||
}
|
||||
|
||||
h->Retain();
|
||||
|
||||
if (p)
|
||||
{
|
||||
p->createFunc(h,p->windowTypeFlags);
|
||||
if (p->title) SetWindowText(h,p->title);
|
||||
|
||||
h->m_dlgproc = dlgproc;
|
||||
h->m_wndproc = SwellDialogDefaultWindowProc;
|
||||
|
||||
HWND hFoc=h->m_children;
|
||||
while (hFoc)
|
||||
{
|
||||
if (hFoc->m_wantfocus && hFoc->m_visible && hFoc->m_enabled)
|
||||
{
|
||||
h->m_focused_child = hFoc; // default focus to hFoc, but set focus more aggressively after WM_INITDIALOG if the dlgproc returns 1
|
||||
break;
|
||||
}
|
||||
hFoc=hFoc->m_next;
|
||||
}
|
||||
|
||||
if (hFoc) hFoc->Retain();
|
||||
|
||||
if (h->m_dlgproc(h,WM_INITDIALOG,(WPARAM)hFoc,param))
|
||||
{
|
||||
if (hFoc && hFoc->m_wantfocus && hFoc->m_visible && hFoc->m_enabled)
|
||||
{
|
||||
if (!h->m_hashaddestroy && !hFoc->m_hashaddestroy)
|
||||
SetFocus(hFoc);
|
||||
}
|
||||
}
|
||||
|
||||
if (hFoc) hFoc->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
h->m_wndproc = (WNDPROC)dlgproc;
|
||||
h->m_wndproc(h,WM_CREATE,0,param);
|
||||
}
|
||||
|
||||
HWND rv = h->m_hashaddestroy ? NULL : h;
|
||||
h->Release();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
HMENU SWELL_GetDefaultWindowMenu() { return g_swell_defaultmenu; }
|
||||
void SWELL_SetDefaultWindowMenu(HMENU menu)
|
||||
{
|
||||
g_swell_defaultmenu=menu;
|
||||
}
|
||||
HMENU SWELL_GetDefaultModalWindowMenu()
|
||||
{
|
||||
return g_swell_defaultmenumodal;
|
||||
}
|
||||
void SWELL_SetDefaultModalWindowMenu(HMENU menu)
|
||||
{
|
||||
g_swell_defaultmenumodal=menu;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SWELL_DialogResourceIndex *SWELL_curmodule_dialogresource_head; // this eventually will go into a per-module stub file
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,256 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
This file provides functions to dynamically create controls in a view from a win32 resource script.
|
||||
|
||||
Use swell_resgen.pl or swell_resgen.php on the .rc file, which will produce .rc_mac_dlg, include that.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef _SWELL_DLGGEN_H_
|
||||
#define _SWELL_DLGGEN_H_
|
||||
|
||||
#ifdef BEGIN
|
||||
#undef BEGIN
|
||||
#endif
|
||||
|
||||
#ifdef END
|
||||
#undef END
|
||||
#endif
|
||||
|
||||
|
||||
struct SWELL_DlgResourceEntry
|
||||
{
|
||||
const char *str1;
|
||||
int flag1;
|
||||
const char *str2;
|
||||
|
||||
int p1; // often used for ID
|
||||
|
||||
// todo: see at runtime if some of these can be short instead of int (p2-p6 probably can, but not completely sure) -- i.e. do we use any
|
||||
// big values in flags. note: it can't be unsigned short, because we want negative values.
|
||||
int p2, p3, p4, p5, p6; // meaning is dependent on class
|
||||
};
|
||||
|
||||
|
||||
#define BEGIN {NULL,
|
||||
#define END },
|
||||
|
||||
#define PUSHBUTTON }, { "__SWELL_BUTTON", 0,
|
||||
#define DEFPUSHBUTTON }, { "__SWELL_BUTTON", 1,
|
||||
#define EDITTEXT }, { "__SWELL_EDIT", 0, "",
|
||||
#define CTEXT }, { "__SWELL_LABEL", 0,
|
||||
#define LTEXT }, { "__SWELL_LABEL", -1,
|
||||
#define RTEXT }, { "__SWELL_LABEL", 1,
|
||||
#define CONTROL }, {
|
||||
#define COMBOBOX }, { "__SWELL_COMBO", 0, "",
|
||||
#define GROUPBOX }, { "__SWELL_GROUP", 0,
|
||||
#define CHECKBOX }, { "__SWELL_CHECKBOX", 0,
|
||||
#define LISTBOX }, { "__SWELL_LISTBOX", 0, "",
|
||||
#define ICON }, { "__SWELL_ICON", 0, (const char*)(INT_PTR)
|
||||
|
||||
#define NOT
|
||||
|
||||
// flags we ignore
|
||||
#define LVS_SHOWSELALWAYS 0
|
||||
#define LVS_SHAREIMAGELISTS 0
|
||||
#define ES_AUTOVSCROLL 0
|
||||
#define GROUP 0
|
||||
#define PBS_SMOOTH 0
|
||||
#define CBS_AUTOHSCROLL 0
|
||||
#define TBS_NOTICKS 0
|
||||
#define TBS_TOP 0
|
||||
#define TBS_BOTH 0
|
||||
#define LBS_NOINTEGRALHEIGHT 0
|
||||
#define TVS_HASLINES 0
|
||||
#define TVS_LINESATROOT 0
|
||||
#define TVS_SHOWSELALWAYS 0
|
||||
#define TVS_HASBUTTONS 0
|
||||
#define TVS_TRACKSELECT 0
|
||||
#define TVS_NONEVENHEIGHT 0
|
||||
#define TVS_NOTOOLTIPS 0
|
||||
#define BS_FLAT 0
|
||||
#define SS_SUNKEN 0
|
||||
#define BS_RIGHT 0
|
||||
#define WS_EX_STATICEDGE 0
|
||||
#define WS_EX_RIGHT 0
|
||||
#define SS_CENTERIMAGE 0
|
||||
#define WS_CLIPCHILDREN 0
|
||||
|
||||
// more ignore flags for vc11+
|
||||
#define LVS_ALIGNLEFT 0 /* 0x0800 */
|
||||
|
||||
#ifndef IDC_STATIC
|
||||
#define IDC_STATIC 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#define SWELL_DLG_WS_CHILD 1
|
||||
#define SWELL_DLG_WS_RESIZABLE 2
|
||||
#define SWELL_DLG_WS_FLIPPED 4
|
||||
#define SWELL_DLG_WS_NOAUTOSIZE 8
|
||||
#define SWELL_DLG_WS_OPAQUE 16
|
||||
#define SWELL_DLG_WS_DROPTARGET 32
|
||||
#ifdef SWELL_TARGET_OSX
|
||||
#define SWELL_DLG_WS_DEFAULT_SCALING 128
|
||||
#endif
|
||||
|
||||
typedef struct SWELL_DialogResourceIndex
|
||||
{
|
||||
const char *resid;
|
||||
const char *title;
|
||||
int windowTypeFlags;
|
||||
void (*createFunc)(HWND, int);
|
||||
int width,height;
|
||||
struct SWELL_DialogResourceIndex *_next;
|
||||
} SWELL_DialogResourceIndex;
|
||||
|
||||
typedef struct SWELL_CursorResourceIndex
|
||||
{
|
||||
const char *resid;
|
||||
const char *resname;
|
||||
POINT hotspot;
|
||||
HCURSOR cachedCursor;
|
||||
struct SWELL_CursorResourceIndex *_next;
|
||||
} SWELL_CursorResourceIndex;
|
||||
|
||||
|
||||
class SWELL_DialogRegHelper {
|
||||
public:
|
||||
SWELL_DialogResourceIndex m_rec;
|
||||
SWELL_DialogRegHelper(SWELL_DialogResourceIndex **h, void (*cf)(HWND,int), int recid, int flags,
|
||||
const char *titlestr, int wid, int hei, double xscale, double yscale)
|
||||
{
|
||||
if (recid)
|
||||
{
|
||||
m_rec.resid=MAKEINTRESOURCE(recid);
|
||||
m_rec.title=titlestr;
|
||||
m_rec.windowTypeFlags=flags;
|
||||
m_rec.createFunc=cf;
|
||||
m_rec.width=(int)(wid*xscale);
|
||||
m_rec.height=(int)(hei*yscale);
|
||||
m_rec._next=*h;
|
||||
*h = &m_rec;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include "../assocarray.h"
|
||||
class SWELL_DialogRegValidator
|
||||
{
|
||||
public:
|
||||
SWELL_DialogRegValidator(const SWELL_DlgResourceEntry *recs, size_t recs_sz, int dlg_w, int dlg_h, int recid)
|
||||
{
|
||||
if (recs_sz>1)
|
||||
{
|
||||
// check for duplicate IDs
|
||||
// also check for multiple DEFPUSHBUTTON
|
||||
WDL_IntKeyedArray<bool> tmp;
|
||||
int defpushcnt = 0;
|
||||
for (size_t x = 0; x < recs_sz; x ++)
|
||||
{
|
||||
const SWELL_DlgResourceEntry *list = recs + x;
|
||||
const int idx = strncmp(list->str1,"__SWELL_",8) ? list->flag1 : list->p1;
|
||||
int parms[6] = { list->p1, list->p2, list->p3, list->p4, list->p5, list->p6 };
|
||||
const int coord_offs = 1; // all, I guess?
|
||||
const int xpos = parms[coord_offs], ypos = parms[coord_offs+1];
|
||||
WDL_ASSERT(xpos >= -1);
|
||||
WDL_ASSERT(ypos >= -1);
|
||||
if (list->flag1 && !strcmp(list->str1,"__SWELL_BUTTON"))
|
||||
{
|
||||
if (defpushcnt) wdl_log("resource %d has duplicate DEFPUSHBUTTON\n",recid);
|
||||
WDL_ASSERT(!defpushcnt);
|
||||
defpushcnt++;
|
||||
}
|
||||
|
||||
// far-bounds check; for old style pre-scaled coordinates this didn't work right (dlg_w/h were scaled)
|
||||
// and there are instances where out of bounds controls do make sense.
|
||||
|
||||
// const int w = parms[coord_offs+2];
|
||||
// const int h = strcmp(list->str1,"__SWELL_COMBO") ? parms[coord_offs+3] : 0;
|
||||
// WDL_ASSERT(xpos + w <= dlg_w);
|
||||
// WDL_ASSERT(ypos + h <= dlg_h);
|
||||
|
||||
if (idx != 0 && idx != -1)
|
||||
{
|
||||
if (tmp.Get(idx)) wdl_log("resource %d has duplicate item ID %d\n",recid, idx);
|
||||
WDL_ASSERT(!tmp.Get(idx));
|
||||
tmp.Insert(idx,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#define SWELL_VALIDATE_DIALOG_RESOURCE(v,r,w,h,recid) static SWELL_DialogRegValidator v(r+1, sizeof(r)/sizeof(r[0])-1,w,h,recid);
|
||||
#else
|
||||
#define SWELL_VALIDATE_DIALOG_RESOURCE(v,r,w,h,recid)
|
||||
#endif
|
||||
|
||||
|
||||
// per-resource scaling (deprecated), these have a bit more overhead (an extra float) and can't do
|
||||
// dynamic scaling on macOS
|
||||
#define SWELL_DEFINE_DIALOG_RESOURCE_BEGIN(recid, flags, titlestr, wid, hei, scale) \
|
||||
static void SWELL__dlg_cf__##recid(HWND view, int wflags); \
|
||||
const float __swell_dlg_scale__##recid = (float) (scale); \
|
||||
static SWELL_DialogRegHelper __swell_dlg_helper_##recid(&SWELL_curmodule_dialogresource_head, SWELL__dlg_cf__##recid, recid,(flags) & ~SWELL_DLG_WS_DEFAULT_SCALING,titlestr,wid,hei,scale,(scale)*(SWELL_DLG_SCALE_AUTOGEN_YADJ)); \
|
||||
static const SWELL_DlgResourceEntry __swell_dlg_list__##recid[]={
|
||||
|
||||
|
||||
#define SWELL_DEFINE_DIALOG_RESOURCE_END(recid ) }; \
|
||||
SWELL_VALIDATE_DIALOG_RESOURCE( __swell_dlg_validator__##recid, __swell_dlg_list__##recid, __swell_dlg_helper_##recid.m_rec.width, __swell_dlg_helper_##recid.m_rec.height, recid) \
|
||||
static void SWELL__dlg_cf__##recid(HWND view, int wflags) { \
|
||||
SWELL_MakeSetCurParms(__swell_dlg_scale__##recid,__swell_dlg_scale__##recid * (SWELL_DLG_SCALE_AUTOGEN_YADJ),0,0,view,false,!(wflags&SWELL_DLG_WS_NOAUTOSIZE)); \
|
||||
SWELL_GenerateDialogFromList(__swell_dlg_list__##recid+1,sizeof(__swell_dlg_list__##recid)/sizeof(__swell_dlg_list__##recid[0])-1); \
|
||||
}
|
||||
|
||||
#ifdef SWELL_TARGET_OSX
|
||||
// macOS uses dynamic dialog scaling if not overriden
|
||||
#define SWELL_DEF_DLGSCALE2 1.0
|
||||
#define SWELL_DEF_DLGFLAG2 SWELL_DLG_WS_DEFAULT_SCALING
|
||||
#else
|
||||
// -generic uses a fixed dialog scaling if not overridden
|
||||
#define SWELL_DEF_DLGSCALE2 1.9
|
||||
#define SWELL_DEF_DLGFLAG2 0
|
||||
#endif
|
||||
|
||||
// newer declaration, does not include scale (globally defined default is used)
|
||||
#define SWELL_DEFINE_DIALOG_RESOURCE_BEGIN2(recid, flags, titlestr, wid, hei) \
|
||||
static void SWELL__dlg_cf__##recid(HWND view, int wflags); \
|
||||
static SWELL_DialogRegHelper __swell_dlg_helper_##recid(&SWELL_curmodule_dialogresource_head, SWELL__dlg_cf__##recid, recid,(flags)|SWELL_DEF_DLGFLAG2,titlestr,wid,hei,SWELL_DEF_DLGSCALE2,SWELL_DEF_DLGSCALE2); \
|
||||
static const SWELL_DlgResourceEntry __swell_dlg_list__##recid[]={
|
||||
|
||||
#define SWELL_DEFINE_DIALOG_RESOURCE_END2(recid) }; \
|
||||
SWELL_VALIDATE_DIALOG_RESOURCE( __swell_dlg_validator__##recid, __swell_dlg_list__##recid, __swell_dlg_helper_##recid.m_rec.width, __swell_dlg_helper_##recid.m_rec.height, recid) \
|
||||
static void SWELL__dlg_cf__##recid(HWND view, int wflags) { \
|
||||
SWELL_MakeSetCurParms(0.0 /* use default */,0.0 /* use default */, \
|
||||
0,0,view,false,!(wflags&SWELL_DLG_WS_NOAUTOSIZE)); \
|
||||
SWELL_GenerateDialogFromList(__swell_dlg_list__##recid+1,sizeof(__swell_dlg_list__##recid)/sizeof(__swell_dlg_list__##recid[0])-1); \
|
||||
}
|
||||
|
||||
#ifndef SWELL_DLG_SCALE_AUTOGEN_YADJ
|
||||
#define SWELL_DLG_SCALE_AUTOGEN_YADJ 1.0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,786 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
This file provides basic win32 GDI--> null translation.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SWELL_PROVIDED_BY_APP
|
||||
|
||||
#include "swell.h"
|
||||
#include "swell-internal.h"
|
||||
#include "../wdlcstring.h"
|
||||
|
||||
const char *g_swell_deffont_face = "Arial";
|
||||
const char *swell_last_font_filename;
|
||||
|
||||
swell_colortheme g_swell_ctheme = {
|
||||
#define __def_theme_ent(x,c) (c),
|
||||
#define __def_theme_ent_fb(x,c,fb) (c),
|
||||
SWELL_GENERIC_THEMEDEFS(__def_theme_ent,__def_theme_ent_fb)
|
||||
#undef __def_theme_ent
|
||||
#undef __def_theme_ent_fb
|
||||
};
|
||||
|
||||
int GetSysColor(int idx)
|
||||
{
|
||||
switch (idx)
|
||||
{
|
||||
case COLOR_WINDOW:
|
||||
case COLOR_3DFACE:
|
||||
case COLOR_BTNFACE: return g_swell_ctheme._3dface;
|
||||
case COLOR_3DSHADOW: return g_swell_ctheme._3dshadow;
|
||||
case COLOR_3DHILIGHT: return g_swell_ctheme._3dhilight;
|
||||
case COLOR_3DDKSHADOW: return g_swell_ctheme._3ddkshadow;
|
||||
case COLOR_BTNTEXT: return g_swell_ctheme.button_text;
|
||||
case COLOR_INFOBK: return g_swell_ctheme.info_bk;
|
||||
case COLOR_INFOTEXT: return g_swell_ctheme.info_text;
|
||||
case COLOR_SCROLLBAR: return g_swell_ctheme.scrollbar;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int g_swell_ui_scale = 256;
|
||||
|
||||
int SWELL_GetScaling256(void)
|
||||
{
|
||||
return g_swell_ui_scale;
|
||||
}
|
||||
|
||||
#ifndef SWELL_LICE_GDI
|
||||
|
||||
#include "../mutex.h"
|
||||
#include "../ptrlist.h"
|
||||
|
||||
#include "swell-gdi-internalpool.h"
|
||||
|
||||
HDC SWELL_CreateGfxContext(void *c)
|
||||
{
|
||||
HDC__ *ctx=SWELL_GDP_CTX_NEW();
|
||||
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
HDC SWELL_CreateMemContext(HDC hdc, int w, int h)
|
||||
{
|
||||
// we could use CGLayer here, but it's 10.4+ and seems to be slower than this
|
||||
// if (w&1) w++;
|
||||
void *buf=calloc(w*4,h);
|
||||
if (!buf) return 0;
|
||||
|
||||
HDC__ *ctx=SWELL_GDP_CTX_NEW();
|
||||
ctx->ownedData=buf;
|
||||
|
||||
SetTextColor(ctx,0);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
void SWELL_DeleteGfxContext(HDC ctx)
|
||||
{
|
||||
HDC__ *ct=(HDC__ *)ctx;
|
||||
if (HDC_VALID(ct))
|
||||
{
|
||||
if (ct->ownedData)
|
||||
{
|
||||
free(ct->ownedData);
|
||||
}
|
||||
SWELL_GDP_CTX_DELETE(ct);
|
||||
}
|
||||
}
|
||||
HPEN CreatePen(int attr, int wid, int col)
|
||||
{
|
||||
return CreatePenAlpha(attr,wid,col,1.0f);
|
||||
}
|
||||
|
||||
HBRUSH CreateSolidBrush(int col)
|
||||
{
|
||||
return CreateSolidBrushAlpha(col,1.0f);
|
||||
}
|
||||
|
||||
HPEN CreatePenAlpha(int attr, int wid, int col, float alpha)
|
||||
{
|
||||
HGDIOBJ__ *pen=GDP_OBJECT_NEW();
|
||||
pen->type=TYPE_PEN;
|
||||
pen->wid=wid<0?0:wid;
|
||||
// pen->color=CreateColor(col,alpha);
|
||||
return pen;
|
||||
}
|
||||
HBRUSH CreateSolidBrushAlpha(int col, float alpha)
|
||||
{
|
||||
HGDIOBJ__ *brush=GDP_OBJECT_NEW();
|
||||
brush->type=TYPE_BRUSH;
|
||||
// brush->color=CreateColor(col,alpha);
|
||||
brush->wid=0;
|
||||
return brush;
|
||||
}
|
||||
|
||||
#define FONTSCALE 0.9
|
||||
HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic,
|
||||
char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision,
|
||||
char lfQuality, char lfPitchAndFamily, const char *lfFaceName)
|
||||
{
|
||||
HGDIOBJ__ *font=GDP_OBJECT_NEW();
|
||||
font->type=TYPE_FONT;
|
||||
float fontwid=lfHeight;
|
||||
|
||||
|
||||
if (!fontwid) fontwid=lfWidth;
|
||||
if (fontwid<0)fontwid=-fontwid;
|
||||
|
||||
if (fontwid < 2 || fontwid > 8192) fontwid=10;
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
HFONT SWELL_GetDefaultFont()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
HFONT CreateFontIndirect(const LOGFONT *lf)
|
||||
{
|
||||
return CreateFont(lf->lfHeight, lf->lfWidth,lf->lfEscapement, lf->lfOrientation, lf->lfWeight, lf->lfItalic,
|
||||
lf->lfUnderline, lf->lfStrikeOut, lf->lfCharSet, lf->lfOutPrecision,lf->lfClipPrecision,
|
||||
lf->lfQuality, lf->lfPitchAndFamily, lf->lfFaceName);
|
||||
}
|
||||
|
||||
int GetTextFace(HDC ctx, int nCount, LPTSTR lpFaceName)
|
||||
{
|
||||
if (lpFaceName) lpFaceName[0]=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DeleteObject(HGDIOBJ pen)
|
||||
{
|
||||
if (HGDIOBJ_VALID(pen))
|
||||
{
|
||||
HGDIOBJ__ *p=(HGDIOBJ__ *)pen;
|
||||
if (--p->additional_refcnt < 0)
|
||||
{
|
||||
if (p->type == TYPE_PEN || p->type == TYPE_BRUSH || p->type == TYPE_FONT || p->type == TYPE_BITMAP)
|
||||
{
|
||||
if (p->type == TYPE_PEN || p->type == TYPE_BRUSH)
|
||||
if (p->wid<0) return;
|
||||
|
||||
GDP_OBJECT_DELETE(p);
|
||||
}
|
||||
// JF> don't free unknown objects, this should never happen anyway: else free(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HGDIOBJ SelectObject(HDC ctx, HGDIOBJ pen)
|
||||
{
|
||||
HDC__ *c=(HDC__ *)ctx;
|
||||
HGDIOBJ__ *p=(HGDIOBJ__ *) pen;
|
||||
HGDIOBJ__ **mod=0;
|
||||
if (!HDC_VALID(c)||!p) return 0;
|
||||
|
||||
if (p == (HGDIOBJ__ *)TYPE_PEN) mod=&c->curpen;
|
||||
else if (p == (HGDIOBJ__ *)TYPE_BRUSH) mod=&c->curbrush;
|
||||
else if (p == (HGDIOBJ__ *)TYPE_FONT) mod=&c->curfont;
|
||||
|
||||
if (mod)
|
||||
{
|
||||
HGDIOBJ__ *np=*mod;
|
||||
*mod=0;
|
||||
return np?np:p;
|
||||
}
|
||||
|
||||
if (!HGDIOBJ_VALID(p)) return 0;
|
||||
|
||||
if (p->type == TYPE_PEN) mod=&c->curpen;
|
||||
else if (p->type == TYPE_BRUSH) mod=&c->curbrush;
|
||||
else if (p->type == TYPE_FONT) mod=&c->curfont;
|
||||
else return 0;
|
||||
|
||||
HGDIOBJ__ *op=*mod;
|
||||
if (!op) op=(HGDIOBJ__ *)(INT_PTR)p->type;
|
||||
if (op != p)
|
||||
{
|
||||
*mod=p;
|
||||
|
||||
if (p->type == TYPE_FONT)
|
||||
{
|
||||
}
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SWELL_FillRect(HDC ctx, const RECT *r, HBRUSH br)
|
||||
{
|
||||
HDC__ *c=(HDC__ *)ctx;
|
||||
HGDIOBJ__ *b=(HGDIOBJ__ *) br;
|
||||
if (!HDC_VALID(c) || !HGDIOBJ_VALID(b,TYPE_BRUSH)) return;
|
||||
|
||||
if (b->wid<0) return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void RoundRect(HDC ctx, int x, int y, int x2, int y2, int xrnd, int yrnd)
|
||||
{
|
||||
xrnd/=3;
|
||||
yrnd/=3;
|
||||
POINT pts[10]={ // todo: curves between edges
|
||||
{x,y+yrnd},
|
||||
{x+xrnd,y},
|
||||
{x2-xrnd,y},
|
||||
{x2,y+yrnd},
|
||||
{x2,y2-yrnd},
|
||||
{x2-xrnd,y2},
|
||||
{x+xrnd,y2},
|
||||
{x,y2-yrnd},
|
||||
{x,y+yrnd},
|
||||
{x+xrnd,y},
|
||||
};
|
||||
|
||||
WDL_GDP_Polygon(ctx,pts,sizeof(pts)/sizeof(pts[0]));
|
||||
}
|
||||
|
||||
void Ellipse(HDC ctx, int l, int t, int r, int b)
|
||||
{
|
||||
HDC__ *c=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(c)) return;
|
||||
|
||||
//CGRect rect=CGRectMake(l,t,r-l,b-t);
|
||||
|
||||
if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >=0)
|
||||
{
|
||||
}
|
||||
if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void Rectangle(HDC ctx, int l, int t, int r, int b)
|
||||
{
|
||||
HDC__ *c=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(c)) return;
|
||||
|
||||
if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0)
|
||||
{
|
||||
}
|
||||
if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
HGDIOBJ GetStockObject(int wh)
|
||||
{
|
||||
switch (wh)
|
||||
{
|
||||
case NULL_BRUSH:
|
||||
{
|
||||
static HGDIOBJ__ br={0,};
|
||||
br.type=TYPE_BRUSH;
|
||||
br.wid=-1;
|
||||
return &br;
|
||||
}
|
||||
case NULL_PEN:
|
||||
{
|
||||
static HGDIOBJ__ pen={0,};
|
||||
pen.type=TYPE_PEN;
|
||||
pen.wid=-1;
|
||||
return &pen;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Polygon(HDC ctx, POINT *pts, int npts)
|
||||
{
|
||||
HDC__ *c=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(c)) return;
|
||||
if (((!HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH)||c->curbrush->wid<0) &&
|
||||
(!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0)) || npts<2) return;
|
||||
|
||||
}
|
||||
|
||||
void MoveToEx(HDC ctx, int x, int y, POINT *op)
|
||||
{
|
||||
HDC__ *c=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(c)) return;
|
||||
if (op)
|
||||
{
|
||||
op->x = (int) (c->lastpos_x);
|
||||
op->y = (int) (c->lastpos_y);
|
||||
}
|
||||
c->lastpos_x=(float)x;
|
||||
c->lastpos_y=(float)y;
|
||||
}
|
||||
|
||||
void PolyBezierTo(HDC ctx, POINT *pts, int np)
|
||||
{
|
||||
HDC__ *c=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||np<3) return;
|
||||
|
||||
int x;
|
||||
float xp,yp;
|
||||
for (x = 0; x < np-2; x += 3)
|
||||
{
|
||||
xp=(float)pts[x+2].x;
|
||||
yp=(float)pts[x+2].y;
|
||||
}
|
||||
c->lastpos_x=(float)xp;
|
||||
c->lastpos_y=(float)yp;
|
||||
}
|
||||
|
||||
|
||||
void SWELL_LineTo(HDC ctx, int x, int y)
|
||||
{
|
||||
HDC__ *c=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0) return;
|
||||
|
||||
float fx=(float)x,fy=(float)y;
|
||||
|
||||
c->lastpos_x=fx;
|
||||
c->lastpos_y=fy;
|
||||
}
|
||||
|
||||
void PolyPolyline(HDC ctx, const POINT *pts, const DWORD *cnts, int nseg)
|
||||
{
|
||||
}
|
||||
|
||||
void *SWELL_GetCtxGC(HDC ctx)
|
||||
{
|
||||
HDC__ *ct=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(ct)) return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void SWELL_SetPixel(HDC ctx, int x, int y, int c)
|
||||
{
|
||||
HDC__ *ct=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(ct)) return;
|
||||
}
|
||||
|
||||
|
||||
BOOL GetTextMetrics(HDC ctx, TEXTMETRIC *tm)
|
||||
{
|
||||
HDC__ *ct=(HDC__ *)ctx;
|
||||
if (tm) // give some sane defaults
|
||||
{
|
||||
tm->tmInternalLeading=3;
|
||||
tm->tmAscent=12;
|
||||
tm->tmDescent=4;
|
||||
tm->tmHeight=16;
|
||||
tm->tmAveCharWidth = 10;
|
||||
}
|
||||
if (!HDC_VALID(ct)||!tm) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int DrawText(HDC ctx, const char *buf, int buflen, RECT *r, int align)
|
||||
{
|
||||
WDL_ASSERT((align & DT_SINGLELINE) || !(align & (DT_VCENTER | DT_BOTTOM)));
|
||||
// if DT_CALCRECT and DT_WORDBREAK, rect must be provided
|
||||
WDL_ASSERT((align&(DT_CALCRECT|DT_WORDBREAK)) != (DT_CALCRECT|DT_WORDBREAK) ||
|
||||
(r && r->right > r->left && r->bottom > r->top));
|
||||
|
||||
HDC__ *ct=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(ct)) return 0;
|
||||
if (r && (align&DT_CALCRECT))
|
||||
{
|
||||
r->top=r->left=0;
|
||||
r->bottom=10;
|
||||
r->right = ( buflen < 0 ? strlen(buf) : buflen ) *8;
|
||||
}
|
||||
else printf("DrawText: %s\n",buf);
|
||||
return 10;
|
||||
}
|
||||
|
||||
void SetBkColor(HDC ctx, int col)
|
||||
{
|
||||
HDC__ *ct=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(ct)) return;
|
||||
ct->curbkcol=col;
|
||||
}
|
||||
|
||||
void SetBkMode(HDC ctx, int col)
|
||||
{
|
||||
HDC__ *ct=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(ct)) return;
|
||||
ct->curbkmode=col;
|
||||
}
|
||||
int GetTextColor(HDC ctx)
|
||||
{
|
||||
HDC__ *ct=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(ct)) return -1;
|
||||
return ct->cur_text_color_int;
|
||||
}
|
||||
|
||||
void SetTextColor(HDC ctx, int col)
|
||||
{
|
||||
HDC__ *ct=(HDC__ *)ctx;
|
||||
if (!HDC_VALID(ct)) return;
|
||||
ct->cur_text_color_int = col;
|
||||
|
||||
}
|
||||
|
||||
HICON LoadNamedImage(const char *name, bool alphaFromMask)
|
||||
{
|
||||
return 0; // todo
|
||||
}
|
||||
|
||||
void DrawImageInRect(HDC ctx, HICON img, const RECT *r)
|
||||
{
|
||||
// todo
|
||||
}
|
||||
|
||||
void SWELL_SetViewGL(HWND h, char wantGL)
|
||||
{
|
||||
}
|
||||
bool SWELL_GetViewGL(HWND h)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool SWELL_SetGLContextToView(HWND h)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL GetObject(HICON icon, int bmsz, void *_bm)
|
||||
{
|
||||
memset(_bm,0,bmsz);
|
||||
if (bmsz != sizeof(BITMAP)) return false;
|
||||
HGDIOBJ__ *i = (HGDIOBJ__ *)icon;
|
||||
if (!HGDIOBJ_VALID(i,TYPE_BITMAP)) return false;
|
||||
//BITMAP *bm=(BITMAP *)_bm;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
void BitBltAlpha(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode, bool useAlphaChannel, float opacity)
|
||||
{
|
||||
}
|
||||
|
||||
void BitBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode)
|
||||
{
|
||||
}
|
||||
|
||||
void StretchBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int srcw, int srch, int mode)
|
||||
{
|
||||
}
|
||||
|
||||
void StretchBltFromMem(HDC hdcOut, int x, int y, int w, int h, const void *bits, int srcw, int srch, int srcspan)
|
||||
{
|
||||
}
|
||||
|
||||
void SWELL_PushClipRegion(HDC ctx)
|
||||
{
|
||||
// HDC__ *ct=(HDC__ *)ctx;
|
||||
}
|
||||
|
||||
void SWELL_SetClipRegion(HDC ctx, const RECT *r)
|
||||
{
|
||||
// HDC__ *ct=(HDC__ *)ctx;
|
||||
|
||||
}
|
||||
|
||||
void SWELL_PopClipRegion(HDC ctx)
|
||||
{
|
||||
// HDC__ *ct=(HDC__ *)ctx;
|
||||
}
|
||||
|
||||
void *SWELL_GetCtxFrameBuffer(HDC ctx)
|
||||
{
|
||||
HDC__ *ct=(HDC__ *)ctx;
|
||||
if (HDC_VALID(ct)) return ct->ownedData;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
HDC GetDC(HWND h)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HDC GetWindowDC(HWND h)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ReleaseDC(HWND h, HDC hdc)
|
||||
{
|
||||
}
|
||||
|
||||
void SWELL_FillDialogBackground(HDC hdc, const RECT *r, int level)
|
||||
{
|
||||
}
|
||||
|
||||
HGDIOBJ SWELL_CloneGDIObject(HGDIOBJ a)
|
||||
{
|
||||
if (HGDIOBJ_VALID(a))
|
||||
{
|
||||
a->additional_refcnt++;
|
||||
return a;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HDC BeginPaint(HWND hwnd, PAINTSTRUCT *ps)
|
||||
{
|
||||
if (!ps) return 0;
|
||||
memset(ps,0,sizeof(PAINTSTRUCT));
|
||||
if (!hwnd) return 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
HBITMAP CreateBitmap(int width, int height, int numplanes, int bitsperpixel, unsigned char* bits)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HICON CreateIconIndirect(const ICONINFO* iconinfo)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
HIMAGELIST ImageList_CreateEx()
|
||||
{
|
||||
return (HIMAGELIST)new WDL_PtrList<HGDIOBJ__>;
|
||||
}
|
||||
BOOL ImageList_Remove(HIMAGELIST list, int idx)
|
||||
{
|
||||
WDL_PtrList<HGDIOBJ__>* imglist=(WDL_PtrList<HGDIOBJ__>*)list;
|
||||
if (imglist && idx < imglist->GetSize())
|
||||
{
|
||||
if (idx < 0)
|
||||
{
|
||||
int x,n=imglist->GetSize();
|
||||
for (x=0;x<n;x++)
|
||||
{
|
||||
HGDIOBJ__ *a = imglist->Get(x);
|
||||
if (a) DeleteObject(a);
|
||||
}
|
||||
imglist->Empty();
|
||||
}
|
||||
else
|
||||
{
|
||||
HGDIOBJ__ *a = imglist->Get(idx);
|
||||
imglist->Set(idx, NULL);
|
||||
if (a) DeleteObject(a);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void ImageList_Destroy(HIMAGELIST list)
|
||||
{
|
||||
if (!list) return;
|
||||
WDL_PtrList<HGDIOBJ__> *p=(WDL_PtrList<HGDIOBJ__>*)list;
|
||||
ImageList_Remove(list,-1);
|
||||
delete p;
|
||||
}
|
||||
|
||||
int ImageList_ReplaceIcon(HIMAGELIST list, int offset, HICON image)
|
||||
{
|
||||
if (!image || !list) return -1;
|
||||
WDL_PtrList<HGDIOBJ__> *l=(WDL_PtrList<HGDIOBJ__> *)list;
|
||||
|
||||
HGDIOBJ__ *imgsrc = (HGDIOBJ__*)image;
|
||||
if (!HGDIOBJ_VALID(imgsrc,TYPE_BITMAP)) return -1;
|
||||
|
||||
HGDIOBJ__* icon=GDP_OBJECT_NEW();
|
||||
icon->type=TYPE_BITMAP;
|
||||
icon->wid=1;
|
||||
// todo: copy underlying image
|
||||
|
||||
image = (HICON) icon;
|
||||
|
||||
if (offset<0||offset>=l->GetSize())
|
||||
{
|
||||
l->Add(image);
|
||||
offset=l->GetSize()-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
HICON old=l->Get(offset);
|
||||
l->Set(offset,image);
|
||||
if (old) DeleteObject(old);
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
int ImageList_Add(HIMAGELIST list, HBITMAP image, HBITMAP mask)
|
||||
{
|
||||
if (!image || !list) return -1;
|
||||
WDL_PtrList<HGDIOBJ__> *l=(WDL_PtrList<HGDIOBJ__> *)list;
|
||||
|
||||
HGDIOBJ__ *imgsrc = (HGDIOBJ__*)image;
|
||||
if (!HGDIOBJ_VALID(imgsrc,TYPE_BITMAP)) return -1;
|
||||
|
||||
HGDIOBJ__* icon=GDP_OBJECT_NEW();
|
||||
icon->type=TYPE_BITMAP;
|
||||
icon->wid=1;
|
||||
// todo: copy underlying image
|
||||
|
||||
image = (HICON) icon;
|
||||
|
||||
l->Add(image);
|
||||
return l->GetSize();
|
||||
}
|
||||
|
||||
|
||||
int AddFontResourceEx(LPCTSTR str, DWORD fl, void *pdv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetGlyphIndicesW(HDC ctx, wchar_t *buf, int len, unsigned short *indices, int flags)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < len; ++i) indices[i]=(flags == GGI_MARK_NONEXISTING_GLYPHS ? 0xFFFF : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // !SWELL_LICE_GDI
|
||||
|
||||
#ifdef SWELL__MAKE_THEME
|
||||
void print_ent(const char *x, int c, const char *def)
|
||||
{
|
||||
if (def)
|
||||
printf("; %s #%02x%02x%02x ; defaults to %s\n",x,GetRValue(c),GetGValue(c),GetBValue(c),def);
|
||||
else
|
||||
{
|
||||
if (strstr(x,"_size") ||
|
||||
strstr(x,"_height") ||
|
||||
strstr(x,"_width"))
|
||||
printf("%s %d\n",x,c);
|
||||
else printf("%s #%02x%02x%02x\n",x,GetRValue(c),GetGValue(c),GetBValue(c));
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#define __def_theme_ent(x,c) print_ent(#x,c,NULL);
|
||||
#define __def_theme_ent_fb(x,c,fb) print_ent(#x,c,#fb);
|
||||
|
||||
printf("default_font_face %s\n",g_swell_deffont_face);
|
||||
SWELL_GENERIC_THEMEDEFS(__def_theme_ent,__def_theme_ent_fb)
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
void swell_load_color_theme(const char *fn)
|
||||
{
|
||||
FILE *fp = WDL_fopenA(fn,"r");
|
||||
if (fp)
|
||||
{
|
||||
swell_colortheme load;
|
||||
memset(&load,-1,sizeof(load));
|
||||
char buf[1024];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!fgets(buf,sizeof(buf),fp)) break;
|
||||
char *p = buf;
|
||||
while (*p == ' ' || *p == '\t') p++;
|
||||
char *np = p;
|
||||
while (*np > 0 && (*np == '_' || isalnum_safe(*np))) np++;
|
||||
if (!*np || np == p) continue;
|
||||
*np++ = 0;
|
||||
while (*np == ' ' || *np == '\t') np++;
|
||||
|
||||
if(!stricmp(p,"default_font_face"))
|
||||
{
|
||||
if (*np > 0 && !isspace_safe(*np))
|
||||
{
|
||||
char *b = strdup(np);
|
||||
g_swell_deffont_face = b;
|
||||
while (*b && *b != ';' && *b != '#') b++;
|
||||
while (b>g_swell_deffont_face && b[-1] > 0 && isspace_safe(b[-1])) b--;
|
||||
*b=0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
int col;
|
||||
if (*np == '#')
|
||||
{
|
||||
np++;
|
||||
char *next;
|
||||
col = strtol(np,&next,16);
|
||||
if (next != np+6)
|
||||
{
|
||||
if (next != np+3) continue;
|
||||
col = ((col&0xf)<<4) | ((col&0xf0)<<8) | ((col&0xf00)<<12);
|
||||
}
|
||||
}
|
||||
else if (*np >= '0' && *np <= '9')
|
||||
{
|
||||
col = atoi(np);
|
||||
}
|
||||
else continue;
|
||||
|
||||
if(0){}
|
||||
#define __def_theme_ent(x,c) else if (!stricmp(p,#x)) load.x = col;
|
||||
#define __def_theme_ent_fb(x,c,fb) else if (!stricmp(p,#x)) load.x = col;
|
||||
SWELL_GENERIC_THEMEDEFS(__def_theme_ent,__def_theme_ent_fb)
|
||||
#undef __def_theme_ent
|
||||
#undef __def_theme_ent_fb
|
||||
}
|
||||
#define __def_theme_ent(x,c) g_swell_ctheme.x = load.x == -1 ? c : load.x;
|
||||
#define __def_theme_ent_fb(x,c,fb) g_swell_ctheme.x = load.x == -1 ? g_swell_ctheme.fb : load.x;
|
||||
SWELL_GENERIC_THEMEDEFS(__def_theme_ent,__def_theme_ent_fb)
|
||||
#undef __def_theme_ent
|
||||
#undef __def_theme_ent_fb
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
// load color theme
|
||||
class swellColorThemeLoader
|
||||
{
|
||||
public:
|
||||
swellColorThemeLoader()
|
||||
{
|
||||
char buf[1024];
|
||||
GetModuleFileName(NULL,buf,sizeof(buf));
|
||||
WDL_remove_filepart(buf);
|
||||
lstrcatn(buf,"/libSwell.colortheme",sizeof(buf));
|
||||
swell_load_color_theme(buf);
|
||||
}
|
||||
};
|
||||
swellColorThemeLoader g_swell_themeloader;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,222 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
// used for HDC/HGDIOBJ pooling (to avoid excess heap use), used by swell-gdi.mm and swell-gdi-generic.cpp
|
||||
*/
|
||||
|
||||
#if defined(_DEBUG)
|
||||
#define SWELL_GDI_DEBUG
|
||||
#endif
|
||||
|
||||
static WDL_Mutex *m_ctxpool_mutex;
|
||||
#ifdef SWELL_GDI_DEBUG
|
||||
#include "../ptrlist.h"
|
||||
static WDL_PtrList<HDC__> *m_ctxpool_debug;
|
||||
static WDL_PtrList<HGDIOBJ__> *m_objpool_debug;
|
||||
#else
|
||||
static HDC__ *m_ctxpool;
|
||||
static int m_ctxpool_size;
|
||||
static HGDIOBJ__ *m_objpool;
|
||||
static int m_objpool_size;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
HDC__ *SWELL_GDP_CTX_NEW()
|
||||
{
|
||||
if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex;
|
||||
|
||||
HDC__ *p=NULL;
|
||||
#ifdef SWELL_GDI_DEBUG
|
||||
m_ctxpool_mutex->Enter();
|
||||
if (!m_ctxpool_debug) m_ctxpool_debug = new WDL_PtrList<HDC__>;
|
||||
if (m_ctxpool_debug->GetSize() > 8192)
|
||||
{
|
||||
p = m_ctxpool_debug->Get(0);
|
||||
m_ctxpool_debug->Delete(0);
|
||||
memset(p,0,sizeof(*p));
|
||||
}
|
||||
m_ctxpool_mutex->Leave();
|
||||
#else
|
||||
if (m_ctxpool)
|
||||
{
|
||||
m_ctxpool_mutex->Enter();
|
||||
if ((p=m_ctxpool))
|
||||
{
|
||||
m_ctxpool=p->_next;
|
||||
m_ctxpool_size--;
|
||||
memset(p,0,sizeof(*p));
|
||||
}
|
||||
m_ctxpool_mutex->Leave();
|
||||
}
|
||||
#endif
|
||||
if (!p)
|
||||
{
|
||||
// printf("alloc ctx\n");
|
||||
p=(HDC__ *)calloc(sizeof(HDC__)+128,1); // extra space in case things want to use it (i.e. swell-gdi-lice does)
|
||||
}
|
||||
return p;
|
||||
}
|
||||
static void SWELL_GDP_CTX_DELETE(HDC__ *p)
|
||||
{
|
||||
if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex;
|
||||
|
||||
if (WDL_NOT_NORMALLY(!p || p->_infreelist)) return;
|
||||
|
||||
memset(p,0,sizeof(*p));
|
||||
|
||||
#ifdef SWELL_GDI_DEBUG
|
||||
m_ctxpool_mutex->Enter();
|
||||
p->_infreelist=true;
|
||||
if (!m_ctxpool_debug) m_ctxpool_debug = new WDL_PtrList<HDC__>;
|
||||
m_ctxpool_debug->Add(p);
|
||||
m_ctxpool_mutex->Leave();
|
||||
#else
|
||||
if (m_ctxpool_size<100)
|
||||
{
|
||||
m_ctxpool_mutex->Enter();
|
||||
p->_infreelist=true;
|
||||
p->_next = m_ctxpool;
|
||||
m_ctxpool = p;
|
||||
m_ctxpool_size++;
|
||||
m_ctxpool_mutex->Leave();
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("free ctx\n");
|
||||
free(p);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
static HGDIOBJ__ *GDP_OBJECT_NEW()
|
||||
{
|
||||
if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex;
|
||||
HGDIOBJ__ *p=NULL;
|
||||
#ifdef SWELL_GDI_DEBUG
|
||||
m_ctxpool_mutex->Enter();
|
||||
if (!m_objpool_debug) m_objpool_debug = new WDL_PtrList<HGDIOBJ__>;
|
||||
if (m_objpool_debug->GetSize()>8192)
|
||||
{
|
||||
p = m_objpool_debug->Get(0);
|
||||
m_objpool_debug->Delete(0);
|
||||
memset(p,0,sizeof(*p));
|
||||
}
|
||||
m_ctxpool_mutex->Leave();
|
||||
#else
|
||||
if (m_objpool)
|
||||
{
|
||||
m_ctxpool_mutex->Enter();
|
||||
if ((p=m_objpool))
|
||||
{
|
||||
m_objpool = p->_next;
|
||||
m_objpool_size--;
|
||||
memset(p,0,sizeof(*p));
|
||||
}
|
||||
m_ctxpool_mutex->Leave();
|
||||
}
|
||||
#endif
|
||||
if (!p)
|
||||
{
|
||||
// printf("alloc obj\n");
|
||||
p=(HGDIOBJ__ *)calloc(sizeof(HGDIOBJ__),1);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static bool HGDIOBJ_VALID(HGDIOBJ__ *p, int reqType=0)
|
||||
{
|
||||
return p &&
|
||||
WDL_NORMALLY( p != (HGDIOBJ__*)TYPE_PEN && p != (HGDIOBJ__*)TYPE_BRUSH &&
|
||||
p != (HGDIOBJ__*)TYPE_FONT && p != (HGDIOBJ__*)TYPE_BITMAP) &&
|
||||
WDL_NORMALLY(!p->_infreelist) &&
|
||||
WDL_NORMALLY(!reqType || reqType == p->type);
|
||||
}
|
||||
|
||||
static void GDP_OBJECT_DELETE(HGDIOBJ__ *p)
|
||||
{
|
||||
if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex;
|
||||
if (WDL_NOT_NORMALLY(!p) || !HGDIOBJ_VALID(p)) return;
|
||||
|
||||
memset(p,0,sizeof(*p));
|
||||
#ifdef SWELL_GDI_DEBUG
|
||||
m_ctxpool_mutex->Enter();
|
||||
p->_infreelist = true;
|
||||
if (!m_objpool_debug) m_objpool_debug = new WDL_PtrList<HGDIOBJ__>;
|
||||
m_objpool_debug->Add(p);
|
||||
m_ctxpool_mutex->Leave();
|
||||
#else
|
||||
if (m_objpool_size<200)
|
||||
{
|
||||
m_ctxpool_mutex->Enter();
|
||||
p->_infreelist = true;
|
||||
p->_next = m_objpool;
|
||||
m_objpool = p;
|
||||
m_objpool_size++;
|
||||
m_ctxpool_mutex->Leave();
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("free obj\n");
|
||||
free(p);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool HDC_VALID(HDC__ *ct)
|
||||
{
|
||||
return ct && WDL_NORMALLY(!ct->_infreelist);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(SWELL_GDI_DEBUG) && defined(SWELL_CLEANUP_ON_UNLOAD)
|
||||
|
||||
class _swellGdiUnloader
|
||||
{
|
||||
public:
|
||||
_swellGdiUnloader() { }
|
||||
~_swellGdiUnloader()
|
||||
{
|
||||
{
|
||||
HDC__ *p = m_ctxpool;
|
||||
m_ctxpool = NULL;
|
||||
while (p)
|
||||
{
|
||||
HDC__ *t = p;
|
||||
p = p->_next;
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
{
|
||||
HGDIOBJ__ *p = m_objpool;
|
||||
m_objpool = NULL;
|
||||
while (p)
|
||||
{
|
||||
HGDIOBJ__ *t = p;
|
||||
p = p->_next;
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
|
||||
delete m_ctxpool_mutex;
|
||||
m_ctxpool_mutex=NULL;
|
||||
}
|
||||
};
|
||||
|
||||
_swellGdiUnloader __swell__swellGdiUnloader;
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,323 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SWELL_PROVIDED_BY_APP
|
||||
|
||||
#include "swell.h"
|
||||
|
||||
#ifndef SWELL_TARGET_GDK
|
||||
|
||||
#include "swell-internal.h"
|
||||
#include "swell-dlggen.h"
|
||||
#include "../wdlcstring.h"
|
||||
|
||||
void swell_oswindow_destroy(HWND hwnd)
|
||||
{
|
||||
if (hwnd && hwnd->m_oswindow)
|
||||
{
|
||||
if (SWELL_focused_oswindow == hwnd->m_oswindow) SWELL_focused_oswindow = NULL;
|
||||
hwnd->m_oswindow=NULL;
|
||||
#ifdef SWELL_LICE_GDI
|
||||
delete hwnd->m_backingstore;
|
||||
hwnd->m_backingstore=0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
void swell_oswindow_update_text(HWND hwnd)
|
||||
{
|
||||
if (hwnd) printf("SWELL: swt '%s'\n",hwnd->m_title.Get());
|
||||
|
||||
}
|
||||
|
||||
void swell_oswindow_maximize(HWND, bool wantmax)
|
||||
{
|
||||
}
|
||||
|
||||
void swell_oswindow_focus(HWND hwnd)
|
||||
{
|
||||
if (!hwnd)
|
||||
{
|
||||
SWELL_focused_oswindow = NULL;
|
||||
}
|
||||
while (hwnd && !hwnd->m_oswindow) hwnd=hwnd->m_parent;
|
||||
if (hwnd && hwnd->m_oswindow != SWELL_focused_oswindow)
|
||||
{
|
||||
SWELL_focused_oswindow = hwnd->m_oswindow;
|
||||
}
|
||||
}
|
||||
|
||||
void swell_recalcMinMaxInfo(HWND hwnd)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SWELL_initargs(int *argc, char ***argv)
|
||||
{
|
||||
}
|
||||
|
||||
void swell_oswindow_updatetoscreen(HWND hwnd, RECT *rect)
|
||||
{
|
||||
}
|
||||
|
||||
void swell_oswindow_manage(HWND hwnd, bool wantfocus)
|
||||
{
|
||||
if (!hwnd) return;
|
||||
|
||||
bool isVis = !!hwnd->m_oswindow;
|
||||
bool wantVis = !hwnd->m_parent && hwnd->m_visible;
|
||||
|
||||
if (isVis != wantVis)
|
||||
{
|
||||
if (!wantVis) swell_oswindow_destroy(hwnd);
|
||||
else
|
||||
{
|
||||
// generic implementation
|
||||
hwnd->m_oswindow = hwnd;
|
||||
if (wantfocus) swell_oswindow_focus(hwnd);
|
||||
}
|
||||
}
|
||||
if (wantVis) swell_oswindow_update_text(hwnd);
|
||||
}
|
||||
|
||||
void SWELL_RunEvents()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void swell_oswindow_update_style(HWND hwnd, LONG oldstyle)
|
||||
{
|
||||
}
|
||||
|
||||
void swell_oswindow_update_enable(HWND hwnd)
|
||||
{
|
||||
}
|
||||
|
||||
int SWELL_SetWindowLevel(HWND hwnd, int newlevel)
|
||||
{
|
||||
int rv=0;
|
||||
if (hwnd)
|
||||
{
|
||||
rv = hwnd->m_israised ? 1 : 0;
|
||||
hwnd->m_israised = newlevel>0;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void SWELL_GetViewPort(RECT *r, const RECT *sourcerect, bool wantWork)
|
||||
{
|
||||
r->left=r->top=0;
|
||||
r->right=1024;
|
||||
r->bottom=768;
|
||||
}
|
||||
|
||||
|
||||
bool GetWindowRect(HWND hwnd, RECT *r)
|
||||
{
|
||||
if (!hwnd) return false;
|
||||
if (hwnd->m_oswindow)
|
||||
{
|
||||
*r = hwnd->m_position;
|
||||
return true;
|
||||
}
|
||||
|
||||
r->left=r->top=0;
|
||||
ClientToScreen(hwnd,(LPPOINT)r);
|
||||
r->right = r->left + hwnd->m_position.right - hwnd->m_position.left;
|
||||
r->bottom = r->top + hwnd->m_position.bottom - hwnd->m_position.top;
|
||||
return true;
|
||||
}
|
||||
|
||||
void swell_oswindow_begin_resize(SWELL_OSWINDOW wnd) { }
|
||||
void swell_oswindow_resize(SWELL_OSWINDOW wnd, int reposflag, RECT f) { }
|
||||
void swell_oswindow_postresize(HWND hwnd, RECT f) { }
|
||||
void swell_oswindow_invalidate(HWND hwnd, const RECT *r) { }
|
||||
|
||||
void UpdateWindow(HWND hwnd) { }
|
||||
|
||||
static WDL_IntKeyedArray<HANDLE> m_clip_recs(GlobalFree);
|
||||
static WDL_PtrList<char> m_clip_curfmts;
|
||||
|
||||
bool OpenClipboard(HWND hwndDlg)
|
||||
{
|
||||
RegisterClipboardFormat(NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CloseClipboard() { }
|
||||
|
||||
UINT EnumClipboardFormats(UINT lastfmt)
|
||||
{
|
||||
int x=0;
|
||||
for (;;)
|
||||
{
|
||||
int fmt=0;
|
||||
if (!m_clip_recs.Enumerate(x++,&fmt)) return 0;
|
||||
if (lastfmt == 0) return fmt;
|
||||
|
||||
if ((UINT)fmt == lastfmt) return m_clip_recs.Enumerate(x++,&fmt) ? fmt : 0;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE GetClipboardData(UINT type)
|
||||
{
|
||||
return m_clip_recs.Get(type);
|
||||
}
|
||||
|
||||
|
||||
void EmptyClipboard()
|
||||
{
|
||||
m_clip_recs.DeleteAll();
|
||||
}
|
||||
|
||||
void SetClipboardData(UINT type, HANDLE h)
|
||||
{
|
||||
if (h) m_clip_recs.Insert(type,h);
|
||||
else m_clip_recs.Delete(type);
|
||||
}
|
||||
|
||||
UINT RegisterClipboardFormat(const char *desc)
|
||||
{
|
||||
if (!m_clip_curfmts.GetSize())
|
||||
{
|
||||
m_clip_curfmts.Add(strdup("SWELL__CF_TEXT"));
|
||||
m_clip_curfmts.Add(strdup("SWELL__CF_HDROP"));
|
||||
}
|
||||
if (!desc || !*desc) return 0;
|
||||
int x;
|
||||
const int n = m_clip_curfmts.GetSize();
|
||||
for(x=0;x<n;x++)
|
||||
if (!strcmp(m_clip_curfmts.Get(x),desc)) return x + 1;
|
||||
m_clip_curfmts.Add(strdup(desc));
|
||||
return n+1;
|
||||
}
|
||||
|
||||
|
||||
void GetCursorPos(POINT *pt)
|
||||
{
|
||||
pt->x=0;
|
||||
pt->y=0;
|
||||
}
|
||||
|
||||
|
||||
WORD GetAsyncKeyState(int key)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DWORD GetMessagePos()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
HWND SWELL_CreateXBridgeWindow(HWND viewpar, void **wref, const RECT *r)
|
||||
{
|
||||
*wref = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SWELL_InitiateDragDrop(HWND hwnd, RECT* srcrect, const char* srcfn, void (*callback)(const char* dropfn))
|
||||
{
|
||||
}
|
||||
|
||||
// owner owns srclist, make copies here etc
|
||||
void SWELL_InitiateDragDropOfFileList(HWND hwnd, RECT *srcrect, const char **srclist, int srccount, HICON icon)
|
||||
{
|
||||
}
|
||||
|
||||
void SWELL_FinishDragDrop() { }
|
||||
|
||||
static HCURSOR m_last_setcursor;
|
||||
|
||||
void SWELL_SetCursor(HCURSOR curs)
|
||||
{
|
||||
m_last_setcursor=curs;
|
||||
}
|
||||
|
||||
HCURSOR SWELL_GetCursor()
|
||||
{
|
||||
return m_last_setcursor;
|
||||
}
|
||||
HCURSOR SWELL_GetLastSetCursor()
|
||||
{
|
||||
return m_last_setcursor;
|
||||
}
|
||||
|
||||
static int m_curvis_cnt;
|
||||
bool SWELL_IsCursorVisible()
|
||||
{
|
||||
return m_curvis_cnt>=0;
|
||||
}
|
||||
|
||||
int SWELL_ShowCursor(BOOL bShow)
|
||||
{
|
||||
m_curvis_cnt += (bShow?1:-1);
|
||||
return m_curvis_cnt;
|
||||
}
|
||||
|
||||
BOOL SWELL_SetCursorPos(int X, int Y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HCURSOR SWELL_LoadCursorFromFile(const char *fn)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head;
|
||||
|
||||
HCURSOR SWELL_LoadCursor(const char *_idx)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SWELL_Register_Cursor_Resource(const char *idx, const char *name, int hotspot_x, int hotspot_y)
|
||||
{
|
||||
SWELL_CursorResourceIndex *ri = (SWELL_CursorResourceIndex*)malloc(sizeof(SWELL_CursorResourceIndex));
|
||||
ri->hotspot.x = hotspot_x;
|
||||
ri->hotspot.y = hotspot_y;
|
||||
ri->resname=name;
|
||||
ri->cachedCursor=0;
|
||||
ri->resid = idx;
|
||||
ri->_next = SWELL_curmodule_cursorresource_head;
|
||||
SWELL_curmodule_cursorresource_head = ri;
|
||||
}
|
||||
|
||||
int SWELL_KeyToASCII(int wParam, int lParam, int *newflags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int swell_is_app_inactive() { return 0; }
|
||||
|
||||
void *SWELL_GetOSWindow(HWND hwnd, const char *type) { return NULL; }
|
||||
void *SWELL_GetOSEvent(const char *type) { return NULL; }
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,632 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
This file implements basic win32 GetPrivateProfileString / etc support.
|
||||
It works by caching reads, but writing through on every write that is required (to ensure
|
||||
that updates take, especially when being updated from multiple modules who have their own
|
||||
cache of the .ini file).
|
||||
|
||||
It is threadsafe, but in theory if two processes are trying to access the same ini,
|
||||
results may go a bit unpredictable (but in general the file should NOT get corrupted,
|
||||
we hope).
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SWELL_PROVIDED_BY_APP
|
||||
|
||||
|
||||
#include "swell.h"
|
||||
#include "../assocarray.h"
|
||||
#include "../wdlcstring.h"
|
||||
#include "../mutex.h"
|
||||
#include "../queue.h"
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
struct iniFileContext
|
||||
{
|
||||
iniFileContext() : m_sections(false,wdl_deletefunc)
|
||||
{
|
||||
m_curfn=NULL;
|
||||
m_lastaccesscnt=0;
|
||||
m_curfn_time=0;
|
||||
m_curfn_sz=0;
|
||||
}
|
||||
~iniFileContext() { }
|
||||
|
||||
WDL_UINT64 m_lastaccesscnt;
|
||||
time_t m_curfn_time;
|
||||
int m_curfn_sz;
|
||||
char *m_curfn;
|
||||
|
||||
WDL_StringKeyedArray< WDL_StringKeyedArray<char *> * > m_sections;
|
||||
|
||||
};
|
||||
|
||||
#define NUM_OPEN_CONTEXTS 32
|
||||
static iniFileContext s_ctxs[NUM_OPEN_CONTEXTS];
|
||||
static WDL_Mutex m_mutex;
|
||||
|
||||
static time_t getfileupdtimesize(const char *fn, int *szOut)
|
||||
{
|
||||
struct stat st;
|
||||
*szOut = 0;
|
||||
if (!fn || !fn[0] || stat(fn,&st)) return 0;
|
||||
|
||||
if (S_ISLNK(st.st_mode))
|
||||
{
|
||||
char *linkpath = realpath(fn,NULL);
|
||||
if (linkpath)
|
||||
{
|
||||
const bool ok = !stat(linkpath,&st);
|
||||
free(linkpath);
|
||||
|
||||
if (!ok) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
*szOut = (int)st.st_size;
|
||||
return st.st_mtime;
|
||||
}
|
||||
|
||||
static bool fgets_to_typedbuf(WDL_TypedBuf<char> *buf, FILE *fp)
|
||||
{
|
||||
int rdpos=0;
|
||||
while (rdpos < 1024*1024*32)
|
||||
{
|
||||
if (buf->GetSize()<rdpos+8192) buf->Resize(rdpos+8192);
|
||||
if (buf->GetSize()<rdpos+4) break; // malloc fail, erg
|
||||
char *p = buf->Get()+rdpos;
|
||||
*p=0;
|
||||
if (!fgets(p,buf->GetSize()-rdpos,fp) || !*p) break;
|
||||
while (*p) p++;
|
||||
if (p[-1] == '\r' || p[-1] == '\n') break;
|
||||
|
||||
rdpos = (int) (p - buf->Get());
|
||||
}
|
||||
return buf->GetSize()>0 && buf->Get()[0];
|
||||
}
|
||||
|
||||
// return true on success
|
||||
static iniFileContext *GetFileContext(const char *name)
|
||||
{
|
||||
static WDL_UINT64 acc_cnt;
|
||||
int best_z = 0;
|
||||
char fntemp[512];
|
||||
if (!name || !strstr(name,"/"))
|
||||
{
|
||||
extern char *g_swell_defini;
|
||||
if (g_swell_defini)
|
||||
{
|
||||
lstrcpyn_safe(fntemp,g_swell_defini,sizeof(fntemp));
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *p = getenv("HOME");
|
||||
snprintf(fntemp,sizeof(fntemp),"%s/.libSwell.ini",
|
||||
p && *p ? p : "/tmp");
|
||||
}
|
||||
if (name && *name)
|
||||
{
|
||||
WDL_remove_fileext(fntemp);
|
||||
snprintf_append(fntemp,sizeof(fntemp),"_%s%s",name,
|
||||
stricmp(WDL_get_fileext(name),".ini")?".ini":"");
|
||||
}
|
||||
name = fntemp;
|
||||
}
|
||||
|
||||
{
|
||||
int w;
|
||||
WDL_UINT64 bestcnt = 0;
|
||||
bestcnt--;
|
||||
|
||||
for (w=0;w<NUM_OPEN_CONTEXTS;w++)
|
||||
{
|
||||
if (!s_ctxs[w].m_curfn || !stricmp(s_ctxs[w].m_curfn,name))
|
||||
{
|
||||
// we never clear m_curfn, so we'll always find an item in cache before an unused cache entry
|
||||
best_z=w;
|
||||
break;
|
||||
}
|
||||
|
||||
if (s_ctxs[w].m_lastaccesscnt < bestcnt) { best_z = w; bestcnt = s_ctxs[w].m_lastaccesscnt; }
|
||||
}
|
||||
}
|
||||
|
||||
iniFileContext *ctx = &s_ctxs[best_z];
|
||||
ctx->m_lastaccesscnt=++acc_cnt;
|
||||
|
||||
int sz=0;
|
||||
if (!ctx->m_curfn || stricmp(ctx->m_curfn,name) || ctx->m_curfn_time != getfileupdtimesize(ctx->m_curfn,&sz) || sz != ctx->m_curfn_sz)
|
||||
{
|
||||
ctx->m_sections.DeleteAll();
|
||||
// printf("reinitting to %s\n",name);
|
||||
if (!ctx->m_curfn || stricmp(ctx->m_curfn,name))
|
||||
{
|
||||
free(ctx->m_curfn);
|
||||
ctx->m_curfn=strdup(name);
|
||||
}
|
||||
FILE *fp = WDL_fopenA(name,"r");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
ctx->m_curfn_time=0;
|
||||
ctx->m_curfn_sz=0;
|
||||
return ctx; // allow to proceed (empty file)
|
||||
}
|
||||
|
||||
flock(fileno(fp),LOCK_SH);
|
||||
|
||||
// parse .ini file
|
||||
WDL_StringKeyedArray<char *> *cursec=NULL;
|
||||
|
||||
int lcnt=0;
|
||||
for (;;)
|
||||
{
|
||||
static WDL_TypedBuf<char> _buf;
|
||||
if (!fgets_to_typedbuf(&_buf,fp)) break;
|
||||
|
||||
char *buf = _buf.Get();
|
||||
if (!ctx->m_sections.GetSize())
|
||||
{
|
||||
lcnt += strlen(buf);
|
||||
if (lcnt > 256*1024) break; // dont bother reading more than 256kb if no section encountered
|
||||
}
|
||||
char *p=buf;
|
||||
|
||||
while (*p) p++;
|
||||
|
||||
if (p>buf)
|
||||
{
|
||||
p--;
|
||||
while (p >= buf && (*p==' ' || *p == '\r' || *p == '\n' || *p == '\t')) p--;
|
||||
p[1]=0;
|
||||
}
|
||||
p=buf;
|
||||
while (*p == ' ' || *p == '\t') p++;
|
||||
if (p[0] == '[')
|
||||
{
|
||||
char *p2=p;
|
||||
while (*p2 && *p2 != ']') p2++;
|
||||
if (*p2)
|
||||
{
|
||||
*p2=0;
|
||||
if (cursec) cursec->Resort();
|
||||
|
||||
if (p[1])
|
||||
{
|
||||
cursec = ctx->m_sections.Get(p+1);
|
||||
if (!cursec)
|
||||
{
|
||||
cursec = new WDL_StringKeyedArray<char *>(false,wdl_freefunc);
|
||||
ctx->m_sections.Insert(p+1,cursec);
|
||||
}
|
||||
else cursec->DeleteAll();
|
||||
}
|
||||
else cursec=0;
|
||||
}
|
||||
}
|
||||
else if (cursec)
|
||||
{
|
||||
char *t=strstr(p,"=");
|
||||
if (t)
|
||||
{
|
||||
*t++=0;
|
||||
// for maximum win32 compat, we should skip leading whitespace on t, and also trim quotes if any
|
||||
WDL_remove_trailing_whitespace(p);
|
||||
if (*p)
|
||||
cursec->AddUnsorted(p,strdup(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx->m_curfn_time = getfileupdtimesize(name,&ctx->m_curfn_sz);
|
||||
flock(fileno(fp),LOCK_UN);
|
||||
fclose(fp);
|
||||
|
||||
if (cursec) cursec->Resort();
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void WriteBackFile(iniFileContext *ctx)
|
||||
{
|
||||
if (!ctx||!ctx->m_curfn) return;
|
||||
char newfn[1024];
|
||||
|
||||
const char *curfn = ctx->m_curfn;
|
||||
|
||||
struct stat st;
|
||||
char *needfree = NULL;
|
||||
if (!stat(curfn,&st) && S_ISLNK(st.st_mode))
|
||||
{
|
||||
needfree = realpath(curfn,NULL);
|
||||
if (needfree) curfn = needfree;
|
||||
}
|
||||
|
||||
lstrcpyn_safe(newfn,curfn,sizeof(newfn)-8);
|
||||
{
|
||||
char *p=newfn;
|
||||
while (*p) p++;
|
||||
while (p>newfn && p[-1] != '/') p--;
|
||||
char lc = '.';
|
||||
while (*p)
|
||||
{
|
||||
char c = *p;
|
||||
*p++ = lc;
|
||||
lc = c;
|
||||
}
|
||||
*p++ = lc;
|
||||
strcpy(p,".new");
|
||||
}
|
||||
|
||||
FILE *fp = WDL_fopenA(newfn,"w");
|
||||
if (!fp)
|
||||
{
|
||||
free(needfree);
|
||||
return;
|
||||
}
|
||||
|
||||
flock(fileno(fp),LOCK_EX);
|
||||
|
||||
int x;
|
||||
for (x = 0; ; x ++)
|
||||
{
|
||||
const char *secname=NULL;
|
||||
WDL_StringKeyedArray<char *> * cursec = ctx->m_sections.Enumerate(x,&secname);
|
||||
if (!cursec || !secname) break;
|
||||
|
||||
fprintf(fp,"[%s]\n",secname);
|
||||
int y;
|
||||
for (y=0;;y++)
|
||||
{
|
||||
const char *keyname = NULL;
|
||||
const char *keyvalue = cursec->Enumerate(y,&keyname);
|
||||
if (!keyvalue || !keyname) break;
|
||||
if (*keyname) fprintf(fp,"%s=%s\n",keyname,keyvalue);
|
||||
}
|
||||
fprintf(fp,"\n");
|
||||
}
|
||||
|
||||
fflush(fp);
|
||||
flock(fileno(fp),LOCK_UN);
|
||||
fclose(fp);
|
||||
|
||||
if (!rename(newfn,curfn))
|
||||
{
|
||||
ctx->m_curfn_time = getfileupdtimesize(curfn,&ctx->m_curfn_sz);
|
||||
}
|
||||
else
|
||||
{
|
||||
// error updating, hmm how to handle this?
|
||||
}
|
||||
free(needfree);
|
||||
}
|
||||
|
||||
BOOL WritePrivateProfileSection(const char *appname, const char *strings, const char *fn)
|
||||
{
|
||||
if (!appname) return FALSE;
|
||||
WDL_MutexLock lock(&m_mutex);
|
||||
iniFileContext *ctx = GetFileContext(fn);
|
||||
if (!ctx) return FALSE;
|
||||
|
||||
WDL_StringKeyedArray<char *> * cursec = ctx->m_sections.Get(appname);
|
||||
if (!cursec)
|
||||
{
|
||||
if (!*strings) return TRUE;
|
||||
|
||||
cursec = new WDL_StringKeyedArray<char *>(false,wdl_freefunc);
|
||||
ctx->m_sections.Insert(appname,cursec);
|
||||
}
|
||||
else cursec->DeleteAll();
|
||||
|
||||
if (*strings)
|
||||
{
|
||||
while (*strings)
|
||||
{
|
||||
char buf[8192];
|
||||
lstrcpyn_safe(buf,strings,sizeof(buf));
|
||||
char *p = buf;
|
||||
while (*p && *p != '=') p++;
|
||||
if (*p)
|
||||
{
|
||||
*p++=0;
|
||||
cursec->Insert(buf,strdup(strings + (p-buf)));
|
||||
}
|
||||
|
||||
strings += strlen(strings)+1;
|
||||
}
|
||||
}
|
||||
WriteBackFile(ctx);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL WritePrivateProfileString(const char *appname, const char *keyname, const char *val, const char *fn)
|
||||
{
|
||||
if (!appname || (keyname && !*keyname)) return FALSE;
|
||||
// printf("writing %s %s %s %s\n",appname,keyname,val,fn);
|
||||
WDL_MutexLock lock(&m_mutex);
|
||||
|
||||
iniFileContext *ctx = GetFileContext(fn);
|
||||
if (!ctx) return FALSE;
|
||||
|
||||
if (!keyname)
|
||||
{
|
||||
if (ctx->m_sections.Get(appname))
|
||||
{
|
||||
ctx->m_sections.Delete(appname);
|
||||
WriteBackFile(ctx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WDL_StringKeyedArray<char *> * cursec = ctx->m_sections.Get(appname);
|
||||
if (!val)
|
||||
{
|
||||
if (cursec && cursec->Get(keyname))
|
||||
{
|
||||
cursec->Delete(keyname);
|
||||
WriteBackFile(ctx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *p;
|
||||
if (!cursec || !(p=cursec->Get(keyname)) || strcmp(p,val))
|
||||
{
|
||||
if (!cursec)
|
||||
{
|
||||
cursec = new WDL_StringKeyedArray<char *>(false,wdl_freefunc);
|
||||
ctx->m_sections.Insert(appname,cursec);
|
||||
}
|
||||
cursec->Insert(keyname,strdup(val));
|
||||
WriteBackFile(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void lstrcpyn_trimmed(char* dest, const char* src, int len)
|
||||
{
|
||||
if (len<1) return;
|
||||
// Mimic Win32 behavior of stripping quotes and whitespace
|
||||
while (*src==' ' || *src=='\t') ++src; // Strip beginning whitespace
|
||||
|
||||
const char *end = src;
|
||||
if (*end) while (end[1]) end++;
|
||||
|
||||
while (end >= src && (*end==' ' || *end=='\t')) --end; // Strip end whitespace
|
||||
|
||||
if (end > src && ((*src=='\"' && *end=='\"') || (*src=='\'' && *end=='\'')))
|
||||
{
|
||||
// Strip initial set of "" or ''
|
||||
++src;
|
||||
--end;
|
||||
}
|
||||
|
||||
int newlen = (int) (end-src+2);
|
||||
if (newlen < 1) newlen = 1;
|
||||
else if (newlen > len) newlen = len;
|
||||
|
||||
lstrcpyn_safe(dest, src, newlen);
|
||||
}
|
||||
|
||||
DWORD GetPrivateProfileSection(const char *appname, char *strout, DWORD strout_len, const char *fn)
|
||||
{
|
||||
WDL_MutexLock lock(&m_mutex);
|
||||
|
||||
if (!strout || strout_len<2)
|
||||
{
|
||||
if (strout && strout_len==1) *strout=0;
|
||||
return 0;
|
||||
}
|
||||
iniFileContext *ctx= GetFileContext(fn);
|
||||
int szOut=0;
|
||||
WDL_StringKeyedArray<char *> *cursec = ctx ? ctx->m_sections.Get(appname) : NULL;
|
||||
|
||||
if (ctx && cursec)
|
||||
{
|
||||
int x;
|
||||
for(x=0;x<cursec->GetSize();x++)
|
||||
{
|
||||
const char *kv = NULL;
|
||||
const char *val = cursec->Enumerate(x,&kv);
|
||||
if (val && kv)
|
||||
{
|
||||
int l;
|
||||
|
||||
#define WRSTR(v) \
|
||||
l = (int)strlen(v); \
|
||||
if (l > (int)strout_len - szOut - 2) l = (int)strout_len - 2 - szOut; \
|
||||
if (l>0) { memcpy(strout+szOut,v,l); szOut+=l; }
|
||||
|
||||
WRSTR(kv)
|
||||
WRSTR("=")
|
||||
#undef WRSTR
|
||||
|
||||
lstrcpyn_trimmed(strout+szOut, val, (int)strout_len - szOut - 2);
|
||||
szOut += strlen(strout+szOut);
|
||||
|
||||
l=1;
|
||||
if (l > (int)strout_len - szOut - 1) l = (int)strout_len - 1 - szOut;
|
||||
if (l>0) { memset(strout+szOut,0,l); szOut+=l; }
|
||||
if (szOut >= (int)strout_len-1)
|
||||
{
|
||||
strout[strout_len-1]=0;
|
||||
return strout_len-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
strout[szOut]=0;
|
||||
if (!szOut) strout[1]=0;
|
||||
return szOut;
|
||||
}
|
||||
|
||||
DWORD GetPrivateProfileString(const char *appname, const char *keyname, const char *def, char *ret, int retsize, const char *fn)
|
||||
{
|
||||
WDL_MutexLock lock(&m_mutex);
|
||||
|
||||
// printf("getprivateprofilestring: %s\n",fn);
|
||||
iniFileContext *ctx= GetFileContext(fn);
|
||||
|
||||
if (ctx)
|
||||
{
|
||||
if (!appname||!keyname)
|
||||
{
|
||||
WDL_Queue tmpbuf;
|
||||
if (!appname)
|
||||
{
|
||||
int x;
|
||||
for (x = 0;; x ++)
|
||||
{
|
||||
const char *secname=NULL;
|
||||
if (!ctx->m_sections.Enumerate(x,&secname) || !secname) break;
|
||||
if (*secname) tmpbuf.Add(secname,(int)strlen(secname)+1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WDL_StringKeyedArray<char *> *cursec = ctx->m_sections.Get(appname);
|
||||
if (cursec)
|
||||
{
|
||||
int y;
|
||||
for (y = 0; ; y ++)
|
||||
{
|
||||
const char *k=NULL;
|
||||
if (!cursec->Enumerate(y,&k)||!k) break;
|
||||
if (*k) tmpbuf.Add(k,(int)strlen(k)+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sz=tmpbuf.GetSize()-1;
|
||||
if (sz<0)
|
||||
{
|
||||
ret[0]=ret[1]=0;
|
||||
return 0;
|
||||
}
|
||||
if (sz > retsize-2) sz=retsize-2;
|
||||
memcpy(ret,tmpbuf.Get(),sz);
|
||||
ret[sz]=ret[sz+1]=0;
|
||||
|
||||
return (DWORD)sz;
|
||||
}
|
||||
|
||||
WDL_StringKeyedArray<char *> *cursec = ctx->m_sections.Get(appname);
|
||||
if (cursec)
|
||||
{
|
||||
const char *val = cursec->Get(keyname);
|
||||
if (val)
|
||||
{
|
||||
lstrcpyn_trimmed(ret,val,retsize);
|
||||
return (DWORD)strlen(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
// printf("def %s %s %s %s\n",appname,keyname,def,fn);
|
||||
lstrcpyn_safe(ret,def?def:"",retsize);
|
||||
return (DWORD)strlen(ret);
|
||||
}
|
||||
|
||||
int GetPrivateProfileInt(const char *appname, const char *keyname, int def, const char *fn)
|
||||
{
|
||||
char buf[512];
|
||||
GetPrivateProfileString(appname,keyname,"",buf,sizeof(buf),fn);
|
||||
if (buf[0])
|
||||
{
|
||||
int a=atoi(buf);
|
||||
if (a||buf[0]=='0') return a;
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
static bool __readbyte(char *src, unsigned char *out)
|
||||
{
|
||||
unsigned char cv=0;
|
||||
int s=4;
|
||||
while(s>=0)
|
||||
{
|
||||
if (*src >= '0' && *src <= '9') cv += (*src-'0')<<s;
|
||||
else if (*src >= 'a' && *src <= 'f') cv += (*src-'a' + 10)<<s;
|
||||
else if (*src >= 'A' && *src <= 'F') cv += (*src-'A' + 10)<<s;
|
||||
else return false;
|
||||
src++;
|
||||
s-=4;
|
||||
}
|
||||
|
||||
*out=cv;
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL GetPrivateProfileStruct(const char *appname, const char *keyname, void *buf, int bufsz, const char *fn)
|
||||
{
|
||||
if (!appname || !keyname || bufsz<0) return 0;
|
||||
char *tmp=(char *)malloc((bufsz+1)*2+16);
|
||||
if (!tmp) return 0;
|
||||
|
||||
BOOL ret=0;
|
||||
GetPrivateProfileString(appname,keyname,"",tmp,(bufsz+1)*2+15,fn);
|
||||
if (strlen(tmp) == (size_t) (bufsz+1)*2)
|
||||
{
|
||||
unsigned char sum=0;
|
||||
unsigned char *bufout=(unsigned char *)buf;
|
||||
char *src=tmp;
|
||||
unsigned char cv;
|
||||
while (bufsz-->0)
|
||||
{
|
||||
if (!__readbyte(src,&cv)) break;
|
||||
*bufout++ = cv;
|
||||
sum += cv;
|
||||
src+=2;
|
||||
}
|
||||
ret = bufsz<0 && WDL_NORMALLY(__readbyte(src,&cv) && cv==sum);
|
||||
}
|
||||
free(tmp);
|
||||
//printf("getprivateprofilestruct returning %d\n",ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WritePrivateProfileStruct(const char *appname, const char *keyname, const void *buf, int bufsz, const char *fn)
|
||||
{
|
||||
if (!keyname || !buf) return WritePrivateProfileString(appname,keyname,(const char *)buf,fn);
|
||||
char *tmp=(char *)malloc((bufsz+1)*2+1);
|
||||
if (!tmp) return 0;
|
||||
char *p = tmp;
|
||||
unsigned char sum=0;
|
||||
unsigned char *src=(unsigned char *)buf;
|
||||
while (bufsz-- > 0)
|
||||
{
|
||||
sprintf(p,"%02X",*src);
|
||||
sum+=*src++;
|
||||
p+=2;
|
||||
}
|
||||
sprintf(p,"%02X",sum);
|
||||
|
||||
BOOL ret=WritePrivateProfileString(appname,keyname,tmp,fn);
|
||||
free(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
This file provides basic key and mouse cursor querying, as well as a key to windows key translation function.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// everything has moved to swell-generic-*.cpp
|
||||
@@ -0,0 +1,698 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
This file provides basic key and mouse cursor querying, as well as a mac key to windows key translation function.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SWELL_PROVIDED_BY_APP
|
||||
|
||||
#include "swell.h"
|
||||
#include "swell-dlggen.h"
|
||||
#include "../wdltypes.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
|
||||
|
||||
static int MacKeyCodeToVK(int code, int *flag)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case 51: return VK_BACK;
|
||||
case 65: return VK_DECIMAL;
|
||||
case 67: return VK_MULTIPLY;
|
||||
case 69: return VK_ADD;
|
||||
case 71: return VK_NUMLOCK;
|
||||
case 75: return VK_DIVIDE;
|
||||
case 76: *flag |= 1<<24; return VK_RETURN;
|
||||
case 78: return VK_SUBTRACT;
|
||||
case 81: return VK_SEPARATOR;
|
||||
case 82: return VK_NUMPAD0;
|
||||
case 83: return VK_NUMPAD1;
|
||||
case 84: return VK_NUMPAD2;
|
||||
case 85: return VK_NUMPAD3;
|
||||
case 86: return VK_NUMPAD4;
|
||||
case 87: return VK_NUMPAD5;
|
||||
case 88: return VK_NUMPAD6;
|
||||
case 89: return VK_NUMPAD7;
|
||||
case 91: return VK_NUMPAD8;
|
||||
case 92: return VK_NUMPAD9;
|
||||
case 96: return VK_F5;
|
||||
case 97: return VK_F6;
|
||||
case 98: return VK_F7;
|
||||
case 99: return VK_F3;
|
||||
case 100: return VK_F8;
|
||||
case 101: return VK_F9;
|
||||
case 109: return VK_F10;
|
||||
case 103: return VK_F11;
|
||||
case 111: return VK_F12;
|
||||
case 114: *flag |= 1<<24; return VK_INSERT;
|
||||
case 115: *flag |= 1<<24; return VK_HOME;
|
||||
case 117: *flag |= 1<<24; return VK_DELETE;
|
||||
case 116: *flag |= 1<<24; return VK_PRIOR;
|
||||
case 118: return VK_F4;
|
||||
case 119: *flag |= 1<<24; return VK_END;
|
||||
case 120: return VK_F2;
|
||||
case 121: *flag |= 1<<24; return VK_NEXT;
|
||||
case 122: return VK_F1;
|
||||
case 123: *flag |= 1<<24; return VK_LEFT;
|
||||
case 124: *flag |= 1<<24; return VK_RIGHT;
|
||||
case 125: *flag |= 1<<24; return VK_DOWN;
|
||||
case 126: *flag |= 1<<24; return VK_UP;
|
||||
case 0x69: return VK_F13;
|
||||
case 0x6B: return VK_F14;
|
||||
case 0x71: return VK_F15;
|
||||
case 0x6A: return VK_F16;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsRightClickEmulateEnabled();
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_5
|
||||
|
||||
static int charFromVcode(int keyCode) // used for getting the root char (^, `) from dead keys on other keyboards,
|
||||
// only used when using MacKeyToWindowsKeyEx() with mode=1, for now
|
||||
{
|
||||
static char loaded;
|
||||
static TISInputSourceRef (*_TISCopyCurrentKeyboardInputSource)( void);
|
||||
static void* (*_TISGetInputSourceProperty) ( TISInputSourceRef inputSource, CFStringRef propertyKey);
|
||||
|
||||
if (!loaded)
|
||||
{
|
||||
loaded++;
|
||||
CFBundleRef b = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.Carbon"));
|
||||
if (b)
|
||||
{
|
||||
*(void **)&_TISGetInputSourceProperty = CFBundleGetFunctionPointerForName(b,CFSTR("TISGetInputSourceProperty"));
|
||||
*(void **)&_TISCopyCurrentKeyboardInputSource = CFBundleGetFunctionPointerForName(b,CFSTR("TISCopyCurrentKeyboardInputSource"));
|
||||
}
|
||||
}
|
||||
if (!_TISCopyCurrentKeyboardInputSource || !_TISGetInputSourceProperty) return 0;
|
||||
|
||||
TISInputSourceRef currentKeyboard = _TISCopyCurrentKeyboardInputSource();
|
||||
CFDataRef uchr = (CFDataRef)_TISGetInputSourceProperty(currentKeyboard, CFSTR("TISPropertyUnicodeKeyLayoutData"));
|
||||
const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr);
|
||||
|
||||
if(keyboardLayout)
|
||||
{
|
||||
UInt32 deadKeyState = 0;
|
||||
const UniCharCount maxStringLength = 255;
|
||||
UniCharCount actualStringLength = 0;
|
||||
UniChar unicodeString[maxStringLength];
|
||||
|
||||
OSStatus status = UCKeyTranslate(keyboardLayout,
|
||||
keyCode, kUCKeyActionDown, 0,
|
||||
LMGetKbdType(), 0,
|
||||
&deadKeyState,
|
||||
maxStringLength,
|
||||
&actualStringLength, unicodeString);
|
||||
|
||||
if (actualStringLength == 0 && deadKeyState)
|
||||
{
|
||||
status = UCKeyTranslate(keyboardLayout,
|
||||
kVK_Space, kUCKeyActionDown, 0,
|
||||
LMGetKbdType(), 0,
|
||||
&deadKeyState,
|
||||
maxStringLength,
|
||||
&actualStringLength, unicodeString);
|
||||
}
|
||||
if(actualStringLength > 0 && status == noErr) return unicodeString[0];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int SWELL_MacKeyToWindowsKeyEx(void *nsevent, int *flags, int mode)
|
||||
{
|
||||
NSEvent *theEvent = (NSEvent *)nsevent;
|
||||
if (!theEvent) theEvent = [NSApp currentEvent];
|
||||
|
||||
const NSInteger mod=[theEvent modifierFlags];
|
||||
|
||||
int flag=0;
|
||||
if (mod & NSShiftKeyMask) flag|=FSHIFT;
|
||||
if (mod & NSCommandKeyMask) flag|=FCONTROL; // todo: this should be command once we figure it out
|
||||
if (mod & NSAlternateKeyMask) flag|=FALT;
|
||||
if ((mod&NSControlKeyMask) && !IsRightClickEmulateEnabled()) flag|=FLWIN;
|
||||
|
||||
int rawcode=[theEvent keyCode];
|
||||
|
||||
int code=MacKeyCodeToVK(rawcode,&flag);
|
||||
if (!code)
|
||||
{
|
||||
NSString *str=NULL;
|
||||
if (mode == 1) str=[theEvent characters];
|
||||
|
||||
if (!str || ![str length]) str=[theEvent charactersIgnoringModifiers];
|
||||
|
||||
if (!str || ![str length])
|
||||
{
|
||||
#ifdef MAC_OS_X_VERSION_10_5
|
||||
if (mode==1) code=charFromVcode(rawcode);
|
||||
#endif
|
||||
if (!code)
|
||||
{
|
||||
code = 1024+rawcode; // raw code
|
||||
flag|=FVIRTKEY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
code=[str characterAtIndex:0];
|
||||
if (code >= NSF1FunctionKey && code <= NSF24FunctionKey)
|
||||
{
|
||||
flag|=FVIRTKEY;
|
||||
code += VK_F1 - NSF1FunctionKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (code == 25 && (flag&FSHIFT)) code=VK_TAB;
|
||||
if (code >= 'a' && code <= 'z') code+='A'-'a';
|
||||
if ((code >= '0' && code <= '9') ||
|
||||
(code >= 'A' && code <= 'Z') ||
|
||||
code==' ' || code == '\r' || code == '\n' || code ==27 || code == VK_TAB)
|
||||
{
|
||||
flag|=FVIRTKEY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flag|=FVIRTKEY;
|
||||
if (code==8) code='\b';
|
||||
}
|
||||
|
||||
if (!(flag&FVIRTKEY)) flag&=~FSHIFT;
|
||||
|
||||
if (flags) *flags=flag;
|
||||
return code;
|
||||
}
|
||||
|
||||
int SWELL_MacKeyToWindowsKey(void *nsevent, int *flags)
|
||||
{
|
||||
if (!nsevent) return 0;
|
||||
return SWELL_MacKeyToWindowsKeyEx(nsevent,flags,0);
|
||||
}
|
||||
|
||||
int SWELL_KeyToASCII(int wParam, int lParam, int *newflags)
|
||||
{
|
||||
if (wParam >= '0' && wParam <= '9' && lParam == (FSHIFT|FVIRTKEY))
|
||||
{
|
||||
*newflags = lParam&~(FSHIFT|FVIRTKEY);
|
||||
if (!(lParam & (FCONTROL|FLWIN))) switch (wParam)
|
||||
{
|
||||
case '1': return '!';
|
||||
case '2': return '@';
|
||||
case '3': return '#';
|
||||
case '4': return '$';
|
||||
case '5': return '%';
|
||||
case '6': return '^';
|
||||
case '7': return '&';
|
||||
case '8': return '*';
|
||||
case '9': return '(';
|
||||
case '0': return ')';
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WORD GetAsyncKeyState(int key)
|
||||
{
|
||||
CGEventFlags state=0;
|
||||
if (key == VK_LBUTTON || key == VK_RBUTTON || key == VK_MBUTTON)
|
||||
{
|
||||
state=GetCurrentEventButtonState();
|
||||
}
|
||||
else
|
||||
{
|
||||
state=CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState);
|
||||
}
|
||||
|
||||
if ((key == VK_LBUTTON && (state&1)) ||
|
||||
(key == VK_RBUTTON && (state&2)) ||
|
||||
(key == VK_MBUTTON && (state&4)) ||
|
||||
(key == VK_SHIFT && (state&kCGEventFlagMaskShift)) ||
|
||||
(key == VK_CONTROL && (state&kCGEventFlagMaskCommand)) ||
|
||||
(key == VK_MENU && (state&kCGEventFlagMaskAlternate)) ||
|
||||
(key == VK_LWIN && !IsRightClickEmulateEnabled() && (state&kCGEventFlagMaskControl)))
|
||||
{
|
||||
return 0x8000;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head;
|
||||
|
||||
static NSCursor* MakeCursorFromData(unsigned char* data, int hotspot_x, int hotspot_y)
|
||||
{
|
||||
NSCursor *c=NULL;
|
||||
NSBitmapImageRep* bmp = [[NSBitmapImageRep alloc]
|
||||
initWithBitmapDataPlanes:0
|
||||
pixelsWide:16
|
||||
pixelsHigh:16
|
||||
bitsPerSample:8
|
||||
samplesPerPixel:2
|
||||
hasAlpha:YES
|
||||
isPlanar:NO
|
||||
colorSpaceName:NSCalibratedWhiteColorSpace
|
||||
bytesPerRow:(16*2)
|
||||
bitsPerPixel:16];
|
||||
|
||||
if (bmp)
|
||||
{
|
||||
unsigned char* p = [bmp bitmapData];
|
||||
if (p)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 16*16; ++i)
|
||||
{
|
||||
// tried 4 bits per sample and memcpy, didn't work
|
||||
p[2*i] = (data[i]&0xF0) | data[i]>>4;
|
||||
p[2*i+1] = (data[i]<<4) | (data[i]&0xf);
|
||||
}
|
||||
|
||||
NSImage *img = [[NSImage alloc] init];
|
||||
if (img)
|
||||
{
|
||||
[img addRepresentation:bmp];
|
||||
NSPoint hs = NSMakePoint(hotspot_x, hotspot_y);
|
||||
c = [[NSCursor alloc] initWithImage:img hotSpot:hs];
|
||||
[img release];
|
||||
}
|
||||
}
|
||||
[bmp release];
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static NSCursor* MakeSWELLSystemCursor(const char *id)
|
||||
{
|
||||
// bytemaps are (white<<4)|(alpha)
|
||||
const unsigned char B = 0xF;
|
||||
const unsigned char W = 0xFF;
|
||||
const unsigned char G = 0xF8;
|
||||
|
||||
static NSCursor* carr[4] = { 0, 0, 0, 0 };
|
||||
|
||||
NSCursor** pc=0;
|
||||
if (id == IDC_SIZEALL) pc = &carr[0];
|
||||
else if (id == IDC_SIZENWSE) pc = &carr[1];
|
||||
else if (id == IDC_SIZENESW) pc = &carr[2];
|
||||
else if (id == IDC_NO) pc = &carr[3];
|
||||
else return 0;
|
||||
|
||||
if (!(*pc))
|
||||
{
|
||||
if (id == IDC_SIZEALL)
|
||||
{
|
||||
static unsigned char p[16*16] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, G, W, W, G, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, G, W, B, B, W, G, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, W, B, B, B, B, W, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, G, B, B, B, B, B, B, G, 0, 0, 0, 0,
|
||||
0, 0, 0, G, 0, 0, W, B, B, W, 0, 0, G, 0, 0, 0,
|
||||
0, G, W, B, 0, 0, W, B, B, W, 0, 0, B, W, G, 0,
|
||||
G, W, B, B, W, W, W, B, B, W, W, W, B, B, W, G,
|
||||
W, B, B, B, B, B, B, B, B, B, B, B, B, B, B, W,
|
||||
W, B, B, B, B, B, B, B, B, B, B, B, B, B, B, W,
|
||||
G, W, B, B, W, W, W, B, B, W, W, W, B, B, W, G,
|
||||
0, G, W, B, 0, 0, W, B, B, W, 0, 0, B, W, G, 0,
|
||||
0, 0, 0, G, 0, 0, W, B, B, W, 0, 0, G, 0, 0, 0,
|
||||
0, 0, 0, 0, G, B, B, B, B, B, B, G, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, W, B, B, B, B, W, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, G, W, B, B, W, G, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, G, W, W, G, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
*pc = MakeCursorFromData(p, 8, 8);
|
||||
}
|
||||
else if (id == IDC_SIZENWSE || id == IDC_SIZENESW)
|
||||
{
|
||||
static unsigned char p[16*16] =
|
||||
{
|
||||
W, W, W, W, W, W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
W, G, G, G, W, G, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
W, G, B, W, G, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
W, G, W, B, W, G, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
W, W, G, W, B, W, G, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
W, G, 0, G, W, B, W, G, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, G, W, B, W, G, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, G, W, B, W, G, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, G, W, B, W, G, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, G, W, B, W, G, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, G, W, B, W, G, 0, G, W,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, G, W, B, W, G, W, W,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, W, B, W, G, W,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, W, B, G, W,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, W, G, G, G, W,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W, W, W, W, W, W,
|
||||
};
|
||||
if (id == IDC_SIZENESW)
|
||||
{
|
||||
int x, y;
|
||||
for (y = 0; y < 16; ++y)
|
||||
{
|
||||
for (x = 0; x < 8; ++x)
|
||||
{
|
||||
unsigned char tmp = p[16*y+x];
|
||||
p[16*y+x] = p[16*y+16-x-1];
|
||||
p[16*y+16-x-1] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
*pc = MakeCursorFromData(p, 8, 8);
|
||||
if (id == IDC_SIZENESW) // swap back!
|
||||
{
|
||||
int x, y;
|
||||
for (y = 0; y < 16; ++y)
|
||||
{
|
||||
for (x = 0; x < 8; ++x)
|
||||
{
|
||||
unsigned char tmp = p[16*y+x];
|
||||
p[16*y+x] = p[16*y+16-x-1];
|
||||
p[16*y+16-x-1] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (id == IDC_NO)
|
||||
{
|
||||
static unsigned char p[16*16] =
|
||||
{
|
||||
0, 0, 0, 0, G, W, W, W, W, W, W, G, 0, 0, 0, 0,
|
||||
0, 0, G, W, W, B, B, B, B, B, B, W, W, G, 0, 0,
|
||||
0, G, W, B, B, B, W, W, W, W, B, B, B, W, G, 0,
|
||||
0, W, B, B, W, W, G, 0, 0, G, W, G, B, B, W, 0,
|
||||
G, W, B, W, G, 0, 0, 0, 0, G, W, B, G, B, W, G,
|
||||
W, B, B, W, 0, 0, 0, 0, G, W, B, W, W, B, B, W,
|
||||
W, B, W, G, 0, 0, 0, G, W, B, W, G, G, W, B, W,
|
||||
W, B, W, 0, 0, 0, G, W, B, W, G, 0, 0, W, B, W,
|
||||
W, B, W, 0, 0, G, W, B, W, G, 0, 0, 0, W, B, W,
|
||||
W, B, W, G, G, W, B, W, G, 0, 0, 0, G, W, B, W,
|
||||
W, B, B, W, W, B, W, G, 0, 0, 0, 0, W, B, B, W,
|
||||
G, W, B, G, B, W, G, 0, 0, 0, 0, G, W, B, W, G,
|
||||
0, W, B, B, G, W, G, 0, 0, G, W, W, B, B, W, 0,
|
||||
0, G, W, B, B, B, W, W, W, W, B, B, B, W, G, 0,
|
||||
0, 0, G, W, W, B, B, B, B, B, B, W, W, G, 0, 0,
|
||||
0, 0, 0, 0, G, W, W, W, W, W, W, G, 0, 0, 0, 0,
|
||||
};
|
||||
*pc = MakeCursorFromData(p, 8, 8);
|
||||
}
|
||||
}
|
||||
|
||||
return *pc;
|
||||
}
|
||||
|
||||
static NSImage *swell_imageFromCursorString(const char *name, POINT *hotSpot)
|
||||
{
|
||||
NSImage *img=NULL;
|
||||
FILE *fp = NULL;
|
||||
bool isFullFn=false;
|
||||
|
||||
if (!strstr(name,"/") && strlen(name)<1024)
|
||||
{
|
||||
char tmpn[4096];
|
||||
GetModuleFileName(NULL,tmpn,(DWORD)(sizeof(tmpn)-128-strlen(name)));
|
||||
strcat(tmpn,"/Contents/Resources/");
|
||||
strcat(tmpn,name);
|
||||
strcat(tmpn,".cur");
|
||||
fp = WDL_fopenA(tmpn,"rb");
|
||||
}
|
||||
else
|
||||
{
|
||||
isFullFn=true;
|
||||
if (strlen(name)>4 && !stricmp(name+strlen(name)-4,".cur")) fp = WDL_fopenA(name,"rb");
|
||||
}
|
||||
|
||||
if (fp)
|
||||
{
|
||||
unsigned char buf[4096];
|
||||
if (fread(buf,1,6,fp)==6 && !buf[0] && !buf[1] && buf[2] == 2 && buf[3] == 0 && buf[4] == 1 && buf[5] == 0)
|
||||
{
|
||||
static char tempfn[512];
|
||||
if (!tempfn[0])
|
||||
{
|
||||
GetTempPath(256,tempfn);
|
||||
snprintf(tempfn+strlen(tempfn),256,"swellcur%x%x.ico", timeGetTime(),(int)getpid());
|
||||
}
|
||||
|
||||
FILE *outfp = WDL_fopenA(tempfn,"wb");
|
||||
if (outfp)
|
||||
{
|
||||
bool wantLoad=false;
|
||||
buf[2]=1; // change to .ico
|
||||
fwrite(buf,1,6,outfp);
|
||||
|
||||
fread(buf,1,16,fp);
|
||||
int xHot = buf[4]|(buf[5]<<8);
|
||||
int yHot = buf[6]|(buf[7]<<8);
|
||||
|
||||
buf[4]=1; buf[5]=0; // 1 color plane
|
||||
buf[6]=0; buf[7]=0; // 0 for pixel depth means "auto"
|
||||
|
||||
if (!buf[3])
|
||||
{
|
||||
fwrite(buf,1,16,outfp);
|
||||
for (;;)
|
||||
{
|
||||
size_t a = fread(buf,1,sizeof(buf),fp);
|
||||
if (a<1) break;
|
||||
fwrite(buf,1,a,outfp);
|
||||
}
|
||||
wantLoad=true;
|
||||
}
|
||||
|
||||
fclose(outfp);
|
||||
if (wantLoad)
|
||||
{
|
||||
NSString *str = (NSString *)SWELL_CStringToCFString(tempfn);
|
||||
img = [[NSImage alloc] initWithContentsOfFile:str];
|
||||
[str release];
|
||||
if (img && hotSpot)
|
||||
{
|
||||
hotSpot->x = xHot;
|
||||
hotSpot->y = yHot;
|
||||
}
|
||||
// printf("loaded converted ico for %s %s %d\n",tempfn,name,!!img);
|
||||
}
|
||||
unlink(tempfn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
if (!img) // fall back
|
||||
{
|
||||
NSString *str = (NSString *)SWELL_CStringToCFString(name);
|
||||
|
||||
if (isFullFn) img = [[NSImage alloc] initWithContentsOfFile:str];
|
||||
else
|
||||
{
|
||||
img = [NSImage imageNamed:str];
|
||||
if (img) [img retain];
|
||||
}
|
||||
[str release];
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
|
||||
HCURSOR SWELL_LoadCursorFromFile(const char *fn)
|
||||
{
|
||||
POINT hotspot={0,};
|
||||
NSImage *img = swell_imageFromCursorString(fn,&hotspot);
|
||||
if (img)
|
||||
{
|
||||
HCURSOR ret=(HCURSOR)[[NSCursor alloc] initWithImage:img hotSpot:NSMakePoint(hotspot.x,hotspot.y)];
|
||||
[img release];
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// todo: support for loading from file
|
||||
HCURSOR SWELL_LoadCursor(const char *_idx)
|
||||
{
|
||||
if (_idx == IDC_NO||_idx==IDC_SIZENWSE || _idx == IDC_SIZENESW || _idx == IDC_SIZEALL) return (HCURSOR) MakeSWELLSystemCursor(_idx);
|
||||
if (_idx == IDC_SIZEWE) return (HCURSOR)[NSCursor resizeLeftRightCursor];
|
||||
if (_idx == IDC_SIZENS) return (HCURSOR)[NSCursor resizeUpDownCursor];
|
||||
if (_idx == IDC_ARROW) return (HCURSOR)[NSCursor arrowCursor];
|
||||
if (_idx == IDC_HAND) return (HCURSOR)[NSCursor openHandCursor];
|
||||
if (_idx == IDC_UPARROW) return (HCURSOR)[NSCursor resizeUpCursor];
|
||||
if (_idx == IDC_IBEAM) return (HCURSOR)[NSCursor IBeamCursor];
|
||||
|
||||
// search registered cursor list
|
||||
SWELL_CursorResourceIndex *p = SWELL_curmodule_cursorresource_head;
|
||||
while (p)
|
||||
{
|
||||
if (p->resid == _idx)
|
||||
{
|
||||
if (p->cachedCursor) return p->cachedCursor;
|
||||
|
||||
NSImage *img = swell_imageFromCursorString(p->resname,&p->hotspot);
|
||||
if (img)
|
||||
{
|
||||
p->cachedCursor=(HCURSOR)[[NSCursor alloc] initWithImage:img hotSpot:NSMakePoint(p->hotspot.x,p->hotspot.y)];
|
||||
[img release];
|
||||
return p->cachedCursor;
|
||||
}
|
||||
}
|
||||
p=p->_next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HCURSOR m_last_setcursor;
|
||||
|
||||
void SWELL_SetCursor(HCURSOR curs)
|
||||
{
|
||||
if (curs && [(id) curs isKindOfClass:[NSCursor class]])
|
||||
{
|
||||
m_last_setcursor=curs;
|
||||
[(NSCursor *)curs set];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_last_setcursor=NULL;
|
||||
[[NSCursor arrowCursor] set];
|
||||
}
|
||||
}
|
||||
|
||||
HCURSOR SWELL_GetCursor()
|
||||
{
|
||||
return (HCURSOR)[NSCursor currentCursor];
|
||||
}
|
||||
HCURSOR SWELL_GetLastSetCursor()
|
||||
{
|
||||
return m_last_setcursor;
|
||||
}
|
||||
|
||||
static POINT g_swell_mouse_relmode_curpos; // stored in osx-native coordinates (y=0=top of screen)
|
||||
static bool g_swell_mouse_relmode;
|
||||
|
||||
|
||||
|
||||
void GetCursorPos(POINT *pt)
|
||||
{
|
||||
if (g_swell_mouse_relmode)
|
||||
{
|
||||
*pt=g_swell_mouse_relmode_curpos;
|
||||
return;
|
||||
}
|
||||
NSPoint localpt=[NSEvent mouseLocation];
|
||||
pt->x=(int)floor(localpt.x + 0.5);
|
||||
pt->y=(int)floor(localpt.y + 0.5);
|
||||
}
|
||||
|
||||
DWORD GetMessagePos()
|
||||
{
|
||||
if (g_swell_mouse_relmode)
|
||||
{
|
||||
return MAKELONG((int)g_swell_mouse_relmode_curpos.x,(int)g_swell_mouse_relmode_curpos.y);
|
||||
}
|
||||
NSPoint localpt=[NSEvent mouseLocation];
|
||||
return MAKELONG((int)floor(localpt.x + 0.5), (int)floor(localpt.y + 0.5));
|
||||
}
|
||||
|
||||
|
||||
NSPoint swellProcessMouseEvent(int msg, NSView *view, NSEvent *event)
|
||||
{
|
||||
if (g_swell_mouse_relmode && msg==WM_MOUSEMOVE) // event will have relative coordinates
|
||||
{
|
||||
int idx=(int)[event deltaX];
|
||||
int idy=(int)[event deltaY];
|
||||
g_swell_mouse_relmode_curpos.x += idx;
|
||||
g_swell_mouse_relmode_curpos.y -= idy;
|
||||
}
|
||||
if (g_swell_mouse_relmode)
|
||||
{
|
||||
POINT p=g_swell_mouse_relmode_curpos;
|
||||
ScreenToClient((HWND)view,&p);
|
||||
return NSMakePoint(p.x,p.y);
|
||||
}
|
||||
NSPoint localpt=[event locationInWindow];
|
||||
return [view convertPoint:localpt fromView:nil];
|
||||
}
|
||||
|
||||
static int m_curvis_cnt;
|
||||
bool SWELL_IsCursorVisible()
|
||||
{
|
||||
return m_curvis_cnt>=0;
|
||||
}
|
||||
int SWELL_ShowCursor(BOOL bShow)
|
||||
{
|
||||
m_curvis_cnt += (bShow?1:-1);
|
||||
if (m_curvis_cnt==-1 && !bShow)
|
||||
{
|
||||
GetCursorPos(&g_swell_mouse_relmode_curpos);
|
||||
CGDisplayHideCursor(kCGDirectMainDisplay);
|
||||
CGAssociateMouseAndMouseCursorPosition(false);
|
||||
g_swell_mouse_relmode=true;
|
||||
}
|
||||
if (m_curvis_cnt==0 && bShow)
|
||||
{
|
||||
CGDisplayShowCursor(kCGDirectMainDisplay);
|
||||
CGAssociateMouseAndMouseCursorPosition(true);
|
||||
g_swell_mouse_relmode=false;
|
||||
SetCursorPos(g_swell_mouse_relmode_curpos.x,g_swell_mouse_relmode_curpos.y);
|
||||
}
|
||||
return m_curvis_cnt;
|
||||
}
|
||||
|
||||
|
||||
BOOL SWELL_SetCursorPos(int X, int Y)
|
||||
{
|
||||
if (g_swell_mouse_relmode)
|
||||
{
|
||||
g_swell_mouse_relmode_curpos.x=X;
|
||||
g_swell_mouse_relmode_curpos.y=Y;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const int h = (int)CGDisplayPixelsHigh(CGMainDisplayID());
|
||||
CGPoint pos=CGPointMake(X,h-Y);
|
||||
return CGWarpMouseCursorPosition(pos)==kCGErrorSuccess;
|
||||
}
|
||||
|
||||
void SWELL_Register_Cursor_Resource(const char *idx, const char *name, int hotspot_x, int hotspot_y)
|
||||
{
|
||||
SWELL_CursorResourceIndex *ri = (SWELL_CursorResourceIndex*)malloc(sizeof(SWELL_CursorResourceIndex));
|
||||
ri->hotspot.x = hotspot_x;
|
||||
ri->hotspot.y = hotspot_y;
|
||||
ri->resname=name;
|
||||
ri->cachedCursor=0;
|
||||
ri->resid = idx;
|
||||
ri->_next = SWELL_curmodule_cursorresource_head;
|
||||
SWELL_curmodule_cursorresource_head = ri;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,93 @@
|
||||
#ifndef _SWELL_MENUGEN_H_
|
||||
#define _SWELL_MENUGEN_H_
|
||||
|
||||
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Dynamic menu generation
|
||||
|
||||
Usage:
|
||||
|
||||
See: swell_resgen.pl etc
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "swell.h"
|
||||
|
||||
|
||||
#ifdef BEGIN
|
||||
#undef BEGIN
|
||||
#endif
|
||||
|
||||
#ifdef END
|
||||
#undef END
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct SWELL_MenuResourceIndex
|
||||
{
|
||||
const char *resid;
|
||||
void (*createFunc)(HMENU hMenu);
|
||||
struct SWELL_MenuResourceIndex *_next;
|
||||
} SWELL_MenuResourceIndex;
|
||||
extern SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head;
|
||||
|
||||
|
||||
#define SWELL_MENUGEN_POPUP_PREFIX "/.BO^O:"
|
||||
#define SWELL_MENUGEN_ENDPOPUP "EN%%%^:"
|
||||
struct SWELL_MenuGen_Entry
|
||||
{
|
||||
const char *name; // will begin with SWELL_MENUGEN_POPUP_PREFIX on submenus, and will be SWELL_MENUGEN_ENDPOPUP at the end of a submenu
|
||||
unsigned short idx;
|
||||
unsigned short flags;
|
||||
};
|
||||
|
||||
class SWELL_MenuGenHelper
|
||||
{
|
||||
public:
|
||||
SWELL_MenuResourceIndex m_rec;
|
||||
SWELL_MenuGenHelper(SWELL_MenuResourceIndex **h, void (*cf)(HMENU), int recid)
|
||||
{
|
||||
m_rec.resid=MAKEINTRESOURCE(recid);
|
||||
m_rec.createFunc=cf;
|
||||
m_rec._next=*h;
|
||||
*h = &m_rec;
|
||||
}
|
||||
};
|
||||
|
||||
#define SWELL_DEFINE_MENU_RESOURCE_BEGIN(recid) \
|
||||
static void __swell_menu_cf__##recid(HMENU hMenu); \
|
||||
static SWELL_MenuGenHelper __swell_menu_cf_helper__##recid(&SWELL_curmodule_menuresource_head, __swell_menu_cf__##recid, recid); \
|
||||
static void __swell_menu_cf__##recid(HMENU hMenu) { static const SWELL_MenuGen_Entry list[]={{NULL,0,0
|
||||
|
||||
#define SWELL_DEFINE_MENU_RESOURCE_END(recid) } }; SWELL_GenerateMenuFromList(hMenu,list+1,sizeof(list)/sizeof(list[0])-1); }
|
||||
|
||||
|
||||
#define GRAYED 1
|
||||
#define INACTIVE 2
|
||||
#define POPUP }, { SWELL_MENUGEN_POPUP_PREFIX
|
||||
#define MENUITEM }, {
|
||||
#define SEPARATOR NULL, 0xffff
|
||||
#define BEGIN
|
||||
#define END }, { SWELL_MENUGEN_ENDPOPUP
|
||||
|
||||
#endif//_SWELL_MENUGEN_H_
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SWELL_PROVIDED_BY_APP
|
||||
|
||||
#include "swell.h"
|
||||
#include "swell-internal.h"
|
||||
|
||||
#ifndef __APPLE__
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
bool IsRightClickEmulateEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void SWELL_EnableRightClickEmulate(BOOL enable)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HANDLE SWELL_CreateProcessFromPID(int pid)
|
||||
{
|
||||
SWELL_InternalObjectHeader_PID *buf = (SWELL_InternalObjectHeader_PID*)malloc(sizeof(SWELL_InternalObjectHeader_PID));
|
||||
buf->hdr.type = INTERNAL_OBJECT_PID;
|
||||
buf->hdr.count = 1;
|
||||
buf->pid = (int) pid;
|
||||
buf->done = buf->result = 0;
|
||||
return (HANDLE) buf;
|
||||
}
|
||||
|
||||
HANDLE SWELL_CreateProcess(const char *exe, int nparams, const char **params)
|
||||
{
|
||||
void swell_cleanupZombies();
|
||||
swell_cleanupZombies();
|
||||
|
||||
const pid_t pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
char **pp = (char **)calloc(nparams+2,sizeof(char*));
|
||||
pp[0] = strdup(exe);
|
||||
for (int x=0;x<nparams;x++) pp[x+1] = strdup(params[x]?params[x]:"");
|
||||
execvp(exe,pp);
|
||||
exit(0);
|
||||
}
|
||||
if (pid < 0) return NULL;
|
||||
|
||||
return SWELL_CreateProcessFromPID(pid);
|
||||
}
|
||||
|
||||
int SWELL_GetProcessExitCode(HANDLE hand)
|
||||
{
|
||||
SWELL_InternalObjectHeader_PID *hdr=(SWELL_InternalObjectHeader_PID*)hand;
|
||||
if (!hdr || hdr->hdr.type != INTERNAL_OBJECT_PID|| !hdr->pid) return -1;
|
||||
if (hdr->done) return hdr->result;
|
||||
|
||||
int wstatus=0;
|
||||
pid_t v = waitpid((pid_t)hdr->pid,&wstatus,WNOHANG);
|
||||
if (v <= 0) return -2;
|
||||
hdr->done = 1;
|
||||
return hdr->result = WEXITSTATUS(wstatus);
|
||||
}
|
||||
|
||||
|
||||
#ifndef SWELL_TARGET_GDK
|
||||
BOOL EnumDisplayMonitors(HDC hdc,const LPRECT r,MONITORENUMPROC proc,LPARAM lParam)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
BOOL GetMonitorInfo(HMONITOR hmon, void *inf)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,899 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SWELL_PROVIDED_BY_APP
|
||||
|
||||
//#import <Carbon/Carbon.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||
#include <sys/poll.h>
|
||||
#include "swell.h"
|
||||
#define SWELL_IMPLEMENT_GETOSXVERSION
|
||||
#include "swell-internal.h"
|
||||
#include "../wdlutf8.h"
|
||||
|
||||
#include "../mutex.h"
|
||||
|
||||
HWND g_swell_only_timerhwnd;
|
||||
|
||||
@implementation SWELL_TimerFuncTarget
|
||||
|
||||
-(id) initWithId:(UINT_PTR)tid hwnd:(HWND)h callback:(TIMERPROC)cb
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
m_hwnd=h;
|
||||
m_cb=cb;
|
||||
m_timerid = tid;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
-(void)SWELL_Timer:(id)sender
|
||||
{
|
||||
if (g_swell_only_timerhwnd && m_hwnd != g_swell_only_timerhwnd) return;
|
||||
|
||||
m_cb(m_hwnd,WM_TIMER,m_timerid,GetTickCount());
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation SWELL_DataHold
|
||||
-(id) initWithVal:(void *)val
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
m_data=val;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
-(void *) getValue
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
@end
|
||||
|
||||
void SWELL_CFStringToCString(const void *str, char *buf, int buflen)
|
||||
{
|
||||
NSString *s = (NSString *)str;
|
||||
if (buflen>0) *buf=0;
|
||||
if (buflen <= 1 || !s || [s getCString:buf maxLength:buflen encoding:NSUTF8StringEncoding]) return; // should always work, I'd hope (ambiguous documentation ugh)
|
||||
|
||||
NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
|
||||
if (!data)
|
||||
{
|
||||
[s getCString:buf maxLength:buflen encoding:NSASCIIStringEncoding];
|
||||
return;
|
||||
}
|
||||
int len = (int)[data length];
|
||||
if (len > buflen-1) len=buflen-1;
|
||||
[data getBytes:buf length:len];
|
||||
buf[len]=0;
|
||||
}
|
||||
|
||||
void *SWELL_CStringToCFString(const char *str)
|
||||
{
|
||||
if (!str) str="";
|
||||
void *ret;
|
||||
|
||||
ret=(void *)CFStringCreateWithCString(NULL,str,kCFStringEncodingUTF8);
|
||||
if (ret) return ret;
|
||||
|
||||
char tmp[2048];
|
||||
char *fixedstr = WDL_utf8_cleanup_bad_codepoints(str,tmp,sizeof(tmp),0);
|
||||
if (fixedstr)
|
||||
{
|
||||
ret=(void *)CFStringCreateWithCString(NULL,fixedstr,kCFStringEncodingUTF8);
|
||||
if (fixedstr != tmp) free(fixedstr);
|
||||
if (ret) return ret;
|
||||
}
|
||||
|
||||
ret=(void*)CFStringCreateWithCString(NULL,str,kCFStringEncodingASCII);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SWELL_MakeProcessFront(HANDLE h)
|
||||
{
|
||||
SWELL_InternalObjectHeader_NSTask *buf = (SWELL_InternalObjectHeader_NSTask*)h;
|
||||
if (buf && buf->hdr.type == INTERNAL_OBJECT_NSTASK && buf->task)
|
||||
{
|
||||
ProcessSerialNumber psn;
|
||||
|
||||
int pid=[(id)buf->task processIdentifier];
|
||||
// try for 1sec to get the PSN, if it fails
|
||||
int n = 20;
|
||||
while (GetProcessForPID(pid,&psn) != noErr && n-- > 0)
|
||||
{
|
||||
Sleep(50);
|
||||
}
|
||||
if (n>0) SetFrontProcess(&psn);
|
||||
}
|
||||
}
|
||||
|
||||
void SWELL_ReleaseNSTask(void *p)
|
||||
{
|
||||
NSTask *a =(NSTask*)p;
|
||||
if (a)
|
||||
{
|
||||
if (![a isRunning]) [a waitUntilExit]; // workaround for the system keeping a reference held on macOS 12+ at least
|
||||
[a release];
|
||||
}
|
||||
}
|
||||
DWORD SWELL_WaitForNSTask(void *p, DWORD msTO)
|
||||
{
|
||||
NSTask *a =(NSTask*)p;
|
||||
const DWORD t = GetTickCount();
|
||||
do
|
||||
{
|
||||
if (![a isRunning]) return WAIT_OBJECT_0;
|
||||
if (msTO) Sleep(1);
|
||||
}
|
||||
while (msTO && (GetTickCount()-t) < msTO);
|
||||
|
||||
return [a isRunning] ? WAIT_TIMEOUT : WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
HANDLE SWELL_CreateProcessIO(const char *exe, int nparams, const char **params, bool redirectIO)
|
||||
{
|
||||
NSString *ex = (NSString *)SWELL_CStringToCFString(exe);
|
||||
NSMutableArray *ar = [[NSMutableArray alloc] initWithCapacity:nparams];
|
||||
|
||||
int x;
|
||||
for (x=0;x <nparams;x++)
|
||||
{
|
||||
NSString *s = (NSString *)SWELL_CStringToCFString(params[x]?params[x]:"");
|
||||
[ar addObject:s];
|
||||
[s release];
|
||||
}
|
||||
|
||||
NSTask *tsk = NULL;
|
||||
|
||||
@try {
|
||||
tsk = [[NSTask alloc] init];
|
||||
[tsk setLaunchPath:ex];
|
||||
[tsk setArguments:ar];
|
||||
if (redirectIO)
|
||||
{
|
||||
[tsk setStandardInput:[NSPipe pipe]];
|
||||
[tsk setStandardOutput:[NSPipe pipe]];
|
||||
[tsk setStandardError:[NSPipe pipe]];
|
||||
}
|
||||
[tsk launch];
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
[tsk release];
|
||||
tsk=0;
|
||||
}
|
||||
@catch (id ex) {
|
||||
}
|
||||
|
||||
[ex release];
|
||||
[ar release];
|
||||
if (!tsk) return NULL;
|
||||
|
||||
SWELL_InternalObjectHeader_NSTask *buf = (SWELL_InternalObjectHeader_NSTask*)malloc(sizeof(SWELL_InternalObjectHeader_NSTask));
|
||||
buf->hdr.type = INTERNAL_OBJECT_NSTASK;
|
||||
buf->hdr.count=1;
|
||||
buf->task = tsk;
|
||||
return buf;
|
||||
}
|
||||
|
||||
HANDLE SWELL_CreateProcess(const char *exe, int nparams, const char **params)
|
||||
{
|
||||
return SWELL_CreateProcessIO(exe,nparams,params,false);
|
||||
}
|
||||
|
||||
|
||||
int SWELL_GetProcessExitCode(HANDLE hand)
|
||||
{
|
||||
int rv=0;
|
||||
SWELL_InternalObjectHeader_NSTask *hdr=(SWELL_InternalObjectHeader_NSTask*)hand;
|
||||
if (!hdr || hdr->hdr.type != INTERNAL_OBJECT_NSTASK || !hdr->task) return -1;
|
||||
@try {
|
||||
if ([(NSTask *)hdr->task isRunning]) rv=-3;
|
||||
else rv = [(NSTask *)hdr->task terminationStatus];
|
||||
}
|
||||
@catch (id ex) {
|
||||
rv=-2;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
int SWELL_TerminateProcess(HANDLE hand)
|
||||
{
|
||||
int rv=0;
|
||||
SWELL_InternalObjectHeader_NSTask *hdr=(SWELL_InternalObjectHeader_NSTask*)hand;
|
||||
if (!hdr || hdr->hdr.type != INTERNAL_OBJECT_NSTASK || !hdr->task) return -1;
|
||||
@try
|
||||
{
|
||||
[(NSTask *)hdr->task terminate];
|
||||
}
|
||||
@catch (id ex) {
|
||||
rv=-2;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
int SWELL_ReadWriteProcessIO(HANDLE hand, int w/*stdin,stdout,stderr*/, char *buf, int bufsz)
|
||||
{
|
||||
SWELL_InternalObjectHeader_NSTask *hdr=(SWELL_InternalObjectHeader_NSTask*)hand;
|
||||
if (!hdr || hdr->hdr.type != INTERNAL_OBJECT_NSTASK || !hdr->task) return 0;
|
||||
NSTask *tsk = (NSTask*)hdr->task;
|
||||
NSPipe *pipe = NULL;
|
||||
bool async_mode = false;
|
||||
if (w & (1<<24))
|
||||
{
|
||||
async_mode = true;
|
||||
w &= ~ (1<<24);
|
||||
}
|
||||
switch (w)
|
||||
{
|
||||
case 0: pipe = [tsk standardInput]; break;
|
||||
case 1: pipe = [tsk standardOutput]; break;
|
||||
case 2: pipe = [tsk standardError]; break;
|
||||
}
|
||||
if (!pipe || ![pipe isKindOfClass:[NSPipe class]]) return 0;
|
||||
|
||||
NSFileHandle *fh = w!=0 ? [pipe fileHandleForReading] : [pipe fileHandleForWriting];
|
||||
if (!fh) return 0;
|
||||
if (w==0)
|
||||
{
|
||||
if (bufsz>0)
|
||||
{
|
||||
NSData *d = [NSData dataWithBytes:buf length:bufsz];
|
||||
@try
|
||||
{
|
||||
if (d) [fh writeData:d];
|
||||
else bufsz=0;
|
||||
}
|
||||
@catch (id ex) { bufsz=0; }
|
||||
|
||||
return bufsz;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (async_mode)
|
||||
{
|
||||
int handle = [fh fileDescriptor];
|
||||
if (handle >= 0)
|
||||
{
|
||||
struct pollfd pl = { handle, POLLIN };
|
||||
if (poll(&pl,1,0)<1) return 0;
|
||||
|
||||
return (int)read(handle,buf,bufsz);
|
||||
}
|
||||
}
|
||||
NSData *d = NULL;
|
||||
@try
|
||||
{
|
||||
d = [fh readDataOfLength:(bufsz < 1 ? 32768 : bufsz)];
|
||||
}
|
||||
@catch (id ex) { }
|
||||
|
||||
if (!d || bufsz < 1) return d ? (int)[d length] : 0;
|
||||
int l = (int)[d length];
|
||||
if (l > bufsz) l = bufsz;
|
||||
[d getBytes:buf length:l];
|
||||
return l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@implementation SWELL_ThreadTmp
|
||||
-(void)bla:(id)obj
|
||||
{
|
||||
if (a)
|
||||
{
|
||||
DWORD (*func)(void *);
|
||||
*(void **)(&func) = a;
|
||||
func(b);
|
||||
}
|
||||
[NSThread exit];
|
||||
}
|
||||
@end
|
||||
|
||||
void SWELL_EnsureMultithreadedCocoa()
|
||||
{
|
||||
static int a;
|
||||
if (!a)
|
||||
{
|
||||
a++;
|
||||
if (![NSThread isMultiThreaded]) // force cocoa into multithreaded mode
|
||||
{
|
||||
SWELL_ThreadTmp *t=[[SWELL_ThreadTmp alloc] init];
|
||||
t->a=0;
|
||||
t->b=0;
|
||||
[NSThread detachNewThreadSelector:@selector(bla:) toTarget:t withObject:t];
|
||||
/// [t release];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CreateThreadNS(void *TA, DWORD stackSize, DWORD (*ThreadProc)(LPVOID), LPVOID parm, DWORD cf, DWORD *tidOut)
|
||||
{
|
||||
SWELL_ThreadTmp *t=[[SWELL_ThreadTmp alloc] init];
|
||||
t->a=(void*)ThreadProc;
|
||||
t->b=parm;
|
||||
return [NSThread detachNewThreadSelector:@selector(bla:) toTarget:t withObject:t];
|
||||
}
|
||||
|
||||
|
||||
// used by swell.cpp (lazy these should go elsewhere)
|
||||
void *SWELL_InitAutoRelease()
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
return (void *)pool;
|
||||
}
|
||||
void SWELL_QuitAutoRelease(void *p)
|
||||
{
|
||||
if (p)
|
||||
[(NSAutoreleasePool*)p release];
|
||||
}
|
||||
|
||||
void SWELL_RunEvents()
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
int x=100;
|
||||
while (x-- > 0)
|
||||
{
|
||||
NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate dateWithTimeIntervalSinceNow:0.001] inMode:NSDefaultRunLoopMode dequeue:YES];
|
||||
if (!event) break;
|
||||
[NSApp sendEvent:event];
|
||||
}
|
||||
[pool release];
|
||||
}
|
||||
|
||||
// timer stuff
|
||||
typedef struct TimerInfoRec
|
||||
{
|
||||
UINT_PTR timerid;
|
||||
HWND hwnd;
|
||||
NSTimer *timer;
|
||||
struct TimerInfoRec *_next;
|
||||
} TimerInfoRec;
|
||||
static TimerInfoRec *m_timer_list;
|
||||
static WDL_Mutex m_timermutex;
|
||||
#ifndef SWELL_NO_POSTMESSAGE
|
||||
static pthread_t m_pmq_mainthread;
|
||||
static void SWELL_pmq_settimer(HWND h, UINT_PTR timerid, UINT rate, TIMERPROC tProc);
|
||||
#endif
|
||||
|
||||
UINT_PTR SetTimer(HWND hwnd, UINT_PTR timerid, UINT rate, TIMERPROC tProc)
|
||||
{
|
||||
if (!hwnd && !tProc) return 0; // must have either callback or hwnd
|
||||
|
||||
if (hwnd && !timerid) return 0;
|
||||
|
||||
#ifndef SWELL_NO_POSTMESSAGE
|
||||
if (timerid != ~(UINT_PTR)0 && m_pmq_mainthread && pthread_self()!=m_pmq_mainthread)
|
||||
{
|
||||
SWELL_pmq_settimer(hwnd,timerid,(rate==(UINT)-1)?((UINT)-2):rate,tProc);
|
||||
return timerid;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (hwnd && ![(id)hwnd respondsToSelector:@selector(SWELL_Timer:)])
|
||||
{
|
||||
if (![(id)hwnd isKindOfClass:[NSWindow class]]) return 0;
|
||||
hwnd=(HWND)[(id)hwnd contentView];
|
||||
if (![(id)hwnd respondsToSelector:@selector(SWELL_Timer:)]) return 0;
|
||||
}
|
||||
|
||||
WDL_MutexLock lock(&m_timermutex);
|
||||
TimerInfoRec *rec=NULL;
|
||||
if (hwnd||timerid)
|
||||
{
|
||||
rec = m_timer_list;
|
||||
while (rec)
|
||||
{
|
||||
if (rec->timerid == timerid && rec->hwnd == hwnd) // works for both kinds
|
||||
break;
|
||||
rec=rec->_next;
|
||||
}
|
||||
}
|
||||
|
||||
bool recAdd=false;
|
||||
if (!rec)
|
||||
{
|
||||
rec=(TimerInfoRec*)malloc(sizeof(TimerInfoRec));
|
||||
recAdd=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
[rec->timer invalidate];
|
||||
rec->timer=0;
|
||||
}
|
||||
|
||||
rec->timerid=timerid;
|
||||
rec->hwnd=hwnd;
|
||||
|
||||
if (!hwnd || tProc)
|
||||
{
|
||||
// set timer to this unique ptr
|
||||
if (!hwnd) timerid = rec->timerid = (UINT_PTR)rec;
|
||||
|
||||
SWELL_TimerFuncTarget *t = [[SWELL_TimerFuncTarget alloc] initWithId:timerid hwnd:hwnd callback:tProc];
|
||||
rec->timer = [NSTimer scheduledTimerWithTimeInterval:(wdl_max(rate,1)*0.001) target:t selector:@selector(SWELL_Timer:)
|
||||
userInfo:t repeats:YES];
|
||||
[t release];
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
SWELL_DataHold *t=[[SWELL_DataHold alloc] initWithVal:(void *)timerid];
|
||||
rec->timer = [NSTimer scheduledTimerWithTimeInterval:(wdl_max(rate,1)*0.001) target:(id)hwnd selector:@selector(SWELL_Timer:)
|
||||
userInfo:t repeats:YES];
|
||||
|
||||
[t release];
|
||||
}
|
||||
[[NSRunLoop currentRunLoop] addTimer:rec->timer forMode:(NSString*)kCFRunLoopCommonModes];
|
||||
|
||||
if (recAdd)
|
||||
{
|
||||
rec->_next=m_timer_list;
|
||||
m_timer_list=rec;
|
||||
}
|
||||
|
||||
return timerid;
|
||||
}
|
||||
void SWELL_RunRunLoop(int ms)
|
||||
{
|
||||
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:ms*0.001]];
|
||||
}
|
||||
void SWELL_RunRunLoopEx(int ms, HWND hwndOnlyTimer)
|
||||
{
|
||||
HWND h=g_swell_only_timerhwnd;
|
||||
g_swell_only_timerhwnd = hwndOnlyTimer;
|
||||
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:ms*0.001]];
|
||||
if (g_swell_only_timerhwnd == hwndOnlyTimer) g_swell_only_timerhwnd = h;
|
||||
}
|
||||
|
||||
BOOL KillTimer(HWND hwnd, UINT_PTR timerid)
|
||||
{
|
||||
if (!hwnd && !timerid) return FALSE;
|
||||
|
||||
WDL_MutexLock lock(&m_timermutex);
|
||||
#ifndef SWELL_NO_POSTMESSAGE
|
||||
if (timerid != ~(UINT_PTR)0 && m_pmq_mainthread && pthread_self()!=m_pmq_mainthread)
|
||||
{
|
||||
SWELL_pmq_settimer(hwnd,timerid,~(UINT)0,NULL);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
BOOL rv=FALSE;
|
||||
|
||||
// don't allow removing all global timers
|
||||
if (timerid!=~(UINT_PTR)0 || hwnd)
|
||||
{
|
||||
TimerInfoRec *rec = m_timer_list, *lrec=NULL;
|
||||
while (rec)
|
||||
{
|
||||
|
||||
if (rec->hwnd == hwnd && (timerid==~(UINT_PTR)0 || rec->timerid == timerid))
|
||||
{
|
||||
TimerInfoRec *nrec = rec->_next;
|
||||
|
||||
// remove self from list
|
||||
if (lrec) lrec->_next = nrec;
|
||||
else m_timer_list = nrec;
|
||||
|
||||
[rec->timer invalidate];
|
||||
free(rec);
|
||||
|
||||
rv=TRUE;
|
||||
if (timerid!=~(UINT_PTR)0) break;
|
||||
|
||||
rec=nrec;
|
||||
}
|
||||
else
|
||||
{
|
||||
lrec=rec;
|
||||
rec=rec->_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
#ifndef SWELL_NO_POSTMESSAGE
|
||||
|
||||
///////// PostMessage emulation
|
||||
|
||||
// implementation of postmessage stuff
|
||||
|
||||
|
||||
|
||||
typedef struct PMQ_rec
|
||||
{
|
||||
HWND hwnd;
|
||||
UINT msg;
|
||||
WPARAM wParam;
|
||||
LPARAM lParam;
|
||||
|
||||
struct PMQ_rec *next;
|
||||
bool is_special_timer; // if set, then msg=interval(-1 for kill),wParam=timer id, lParam = timerproc
|
||||
} PMQ_rec;
|
||||
|
||||
static WDL_Mutex *m_pmq_mutex;
|
||||
static PMQ_rec *m_pmq, *m_pmq_empty, *m_pmq_tail;
|
||||
static int m_pmq_size;
|
||||
static id m_pmq_timer;
|
||||
#define MAX_POSTMESSAGE_SIZE 1024
|
||||
|
||||
void SWELL_Internal_PostMessage_Init()
|
||||
{
|
||||
if (m_pmq_mutex) return;
|
||||
id del = [NSApp delegate];
|
||||
if (!del || ![del respondsToSelector:@selector(swellPostMessageTick:)]) return;
|
||||
|
||||
m_pmq_mainthread=pthread_self();
|
||||
m_pmq_mutex = new WDL_Mutex;
|
||||
|
||||
m_pmq_timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:(id)del selector:@selector(swellPostMessageTick:) userInfo:nil repeats:YES];
|
||||
[[NSRunLoop currentRunLoop] addTimer:m_pmq_timer forMode:(NSString*)kCFRunLoopCommonModes];
|
||||
// [ release];
|
||||
// set a timer to the delegate
|
||||
}
|
||||
|
||||
|
||||
void SWELL_MessageQueue_Flush()
|
||||
{
|
||||
if (!m_pmq_mutex) return;
|
||||
|
||||
m_pmq_mutex->Enter();
|
||||
int max_amt = m_pmq_size;
|
||||
PMQ_rec *p=m_pmq;
|
||||
if (p)
|
||||
{
|
||||
m_pmq = p->next;
|
||||
if (m_pmq_tail == p) m_pmq_tail=NULL;
|
||||
m_pmq_size--;
|
||||
}
|
||||
m_pmq_mutex->Leave();
|
||||
|
||||
// process out queue
|
||||
while (p)
|
||||
{
|
||||
if (p->is_special_timer)
|
||||
{
|
||||
if (p->msg == ~(UINT)0) KillTimer(p->hwnd,p->wParam);
|
||||
else SetTimer(p->hwnd,p->wParam,p->msg,(TIMERPROC)p->lParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([(id)p->hwnd respondsToSelector:@selector(swellCanPostMessage)] && [(id)p->hwnd swellCanPostMessage])
|
||||
SendMessage(p->hwnd,p->msg,p->wParam,p->lParam);
|
||||
}
|
||||
|
||||
m_pmq_mutex->Enter();
|
||||
// move this message to empty list
|
||||
p->next=m_pmq_empty;
|
||||
m_pmq_empty = p;
|
||||
|
||||
// get next queued message (if within limits)
|
||||
p = (--max_amt > 0) ? m_pmq : NULL;
|
||||
if (p)
|
||||
{
|
||||
m_pmq = p->next;
|
||||
if (m_pmq_tail == p) m_pmq_tail=NULL;
|
||||
m_pmq_size--;
|
||||
}
|
||||
m_pmq_mutex->Leave();
|
||||
}
|
||||
}
|
||||
|
||||
void SWELL_Internal_PMQ_ClearAllMessages(HWND hwnd)
|
||||
{
|
||||
if (!m_pmq_mutex) return;
|
||||
|
||||
m_pmq_mutex->Enter();
|
||||
PMQ_rec *p=m_pmq;
|
||||
PMQ_rec *lastrec=NULL;
|
||||
while (p)
|
||||
{
|
||||
if (hwnd && p->hwnd != hwnd) { lastrec=p; p=p->next; }
|
||||
else
|
||||
{
|
||||
PMQ_rec *next=p->next;
|
||||
|
||||
p->next=m_pmq_empty; // add p to empty list
|
||||
m_pmq_empty=p;
|
||||
m_pmq_size--;
|
||||
|
||||
|
||||
if (p==m_pmq_tail) m_pmq_tail=lastrec; // update tail
|
||||
|
||||
if (lastrec) p = lastrec->next = next;
|
||||
else p = m_pmq = next;
|
||||
}
|
||||
}
|
||||
m_pmq_mutex->Leave();
|
||||
}
|
||||
|
||||
static void SWELL_pmq_settimer(HWND h, UINT_PTR timerid, UINT rate, TIMERPROC tProc)
|
||||
{
|
||||
if (!h||!m_pmq_mutex) return;
|
||||
WDL_MutexLock lock(m_pmq_mutex);
|
||||
|
||||
PMQ_rec *rec=m_pmq;
|
||||
while (rec)
|
||||
{
|
||||
if (rec->is_special_timer && rec->hwnd == h && rec->wParam == timerid)
|
||||
{
|
||||
rec->msg = rate; // adjust to new rate
|
||||
rec->lParam = (LPARAM)tProc;
|
||||
return;
|
||||
}
|
||||
rec=rec->next;
|
||||
}
|
||||
|
||||
rec=m_pmq_empty;
|
||||
if (rec) m_pmq_empty=rec->next;
|
||||
else rec=(PMQ_rec*)malloc(sizeof(PMQ_rec));
|
||||
rec->next=0;
|
||||
rec->hwnd=h;
|
||||
rec->msg=rate;
|
||||
rec->wParam=timerid;
|
||||
rec->lParam=(LPARAM)tProc;
|
||||
rec->is_special_timer=true;
|
||||
|
||||
if (m_pmq_tail) m_pmq_tail->next=rec;
|
||||
else
|
||||
{
|
||||
PMQ_rec *p=m_pmq;
|
||||
while (p && p->next) p=p->next; // shouldnt happen unless m_pmq is NULL As well but why not for safety
|
||||
if (p) p->next=rec;
|
||||
else m_pmq=rec;
|
||||
}
|
||||
m_pmq_tail=rec;
|
||||
m_pmq_size++;
|
||||
}
|
||||
|
||||
BOOL PostMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (WDL_NORMALLY(m_pmq_mutex != NULL))
|
||||
{
|
||||
return SWELL_Internal_PostMessage(hwnd,message,wParam,lParam);
|
||||
}
|
||||
|
||||
// legacy passthrough to delegate if caller is using its own swell impl, not threadsafe
|
||||
id del=[NSApp delegate];
|
||||
if (del && [del respondsToSelector:@selector(swellPostMessage:msg:wp:lp:)])
|
||||
return !![(SWELL_DelegateExtensions*)del swellPostMessage:hwnd msg:message wp:wParam lp:lParam];
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void SWELL_MessageQueue_Clear(HWND h)
|
||||
{
|
||||
if (WDL_NORMALLY(m_pmq_mutex != NULL))
|
||||
{
|
||||
SWELL_Internal_PMQ_ClearAllMessages(h);
|
||||
}
|
||||
else
|
||||
{
|
||||
id del=[NSApp delegate];
|
||||
if (del && [del respondsToSelector:@selector(swellPostMessageClearQ:)])
|
||||
[(SWELL_DelegateExtensions*)del swellPostMessageClearQ:h];
|
||||
}
|
||||
}
|
||||
|
||||
BOOL SWELL_Internal_PostMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (!hwnd||!m_pmq_mutex) return FALSE;
|
||||
|
||||
BOOL ret=FALSE;
|
||||
m_pmq_mutex->Enter();
|
||||
|
||||
if (m_pmq_empty||m_pmq_size<MAX_POSTMESSAGE_SIZE)
|
||||
{
|
||||
PMQ_rec *rec=m_pmq_empty;
|
||||
if (rec) m_pmq_empty=rec->next;
|
||||
else rec=(PMQ_rec*)malloc(sizeof(PMQ_rec));
|
||||
rec->next=0;
|
||||
rec->hwnd=hwnd;
|
||||
rec->msg=msg;
|
||||
rec->wParam=wParam;
|
||||
rec->lParam=lParam;
|
||||
rec->is_special_timer=false;
|
||||
|
||||
if (m_pmq_tail) m_pmq_tail->next=rec;
|
||||
else
|
||||
{
|
||||
PMQ_rec *p=m_pmq;
|
||||
while (p && p->next) p=p->next; // shouldnt happen unless m_pmq is NULL As well but why not for safety
|
||||
if (p) p->next=rec;
|
||||
else m_pmq=rec;
|
||||
}
|
||||
m_pmq_tail=rec;
|
||||
m_pmq_size++;
|
||||
|
||||
ret=TRUE;
|
||||
}
|
||||
|
||||
m_pmq_mutex->Leave();
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool s_rightclickemulate=true;
|
||||
|
||||
bool IsRightClickEmulateEnabled()
|
||||
{
|
||||
return s_rightclickemulate;
|
||||
}
|
||||
|
||||
void SWELL_EnableRightClickEmulate(BOOL enable)
|
||||
{
|
||||
s_rightclickemulate=enable;
|
||||
}
|
||||
|
||||
int g_swell_terminating;
|
||||
void SWELL_PostQuitMessage(void *sender)
|
||||
{
|
||||
g_swell_terminating=true;
|
||||
|
||||
[NSApp terminate:(id)sender];
|
||||
}
|
||||
|
||||
|
||||
#ifndef MAC_OS_X_VERSION_10_9
|
||||
typedef uint64_t NSActivityOptions;
|
||||
enum
|
||||
{
|
||||
NSActivityIdleDisplaySleepDisabled = (1ULL << 40),
|
||||
NSActivityIdleSystemSleepDisabled = (1ULL << 20),
|
||||
NSActivitySuddenTerminationDisabled = (1ULL << 14),
|
||||
NSActivityAutomaticTerminationDisabled = (1ULL << 15),
|
||||
NSActivityUserInitiated = (0x00FFFFFFULL | NSActivityIdleSystemSleepDisabled),
|
||||
NSActivityUserInitiatedAllowingIdleSystemSleep = (NSActivityUserInitiated & ~NSActivityIdleSystemSleepDisabled),
|
||||
NSActivityBackground = 0x000000FFULL,
|
||||
NSActivityLatencyCritical = 0xFF00000000ULL,
|
||||
};
|
||||
|
||||
|
||||
@interface NSProcessInfo (reaperhostadditions)
|
||||
- (id<NSObject>)beginActivityWithOptions:(NSActivityOptions)options reason:(NSString *)reason;
|
||||
- (void)endActivity:(id<NSObject>)activity;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
void SWELL_DisableAppNap(int disable) { SWELL_DisableAppNapEx(disable,0); }
|
||||
|
||||
void SWELL_DisableAppNapEx(int disable, int flags)
|
||||
{
|
||||
if (!g_swell_terminating && floor(NSFoundationVersionNumber) > 945.00) // 10.9+
|
||||
{
|
||||
static int s_cnt, s_lflags;
|
||||
static id s_obj;
|
||||
|
||||
s_cnt += disable;
|
||||
|
||||
bool force_del = false;
|
||||
@try
|
||||
{
|
||||
if ((flags & 1) && flags != s_lflags) { s_lflags = flags; force_del = true; }
|
||||
if (s_obj && (s_cnt <= 0 || force_del))
|
||||
{
|
||||
// in case we crash somehow, don't want obj sticking around pointing to a stale object
|
||||
id a = s_obj; s_obj = NULL;
|
||||
[[NSProcessInfo processInfo] endActivity:a];
|
||||
[a release]; // apparently releasing this is enough, without the endActivity call, but the docs are quite vague
|
||||
}
|
||||
if (s_cnt > 0 && !s_obj)
|
||||
{
|
||||
NSActivityOptions v = NSActivityLatencyCritical | NSActivityIdleSystemSleepDisabled;
|
||||
if (s_lflags & 2) v |= NSActivityIdleDisplaySleepDisabled;
|
||||
|
||||
// beginActivityWithOptions returns an autoreleased object
|
||||
s_obj = [[NSProcessInfo processInfo] beginActivityWithOptions:v reason:@"SWELL_DisableAppNap"];
|
||||
if (s_obj) [s_obj retain];
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
}
|
||||
@catch (id ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL EnumDisplayMonitors(HDC hdc, const LPRECT r, MONITORENUMPROC proc,LPARAM lParam)
|
||||
{
|
||||
// ignores hdc
|
||||
NSArray *screens = [NSScreen screens];
|
||||
const unsigned int ns = (unsigned int) [screens count];
|
||||
for (unsigned int x = 0; x < ns; x ++)
|
||||
{
|
||||
NSScreen *mon = [screens objectAtIndex:x];
|
||||
if (mon)
|
||||
{
|
||||
NSRect tr=[mon frame];
|
||||
RECT screen_rect,tmp;
|
||||
NSRECT_TO_RECT(&tmp,tr);
|
||||
if (r)
|
||||
{
|
||||
if (!IntersectRect(&screen_rect,r,&tmp))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
screen_rect = tmp;
|
||||
}
|
||||
if (!proc((HMONITOR)mon,hdc,&screen_rect,lParam)) break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL GetMonitorInfo(HMONITOR hmon, void *inf)
|
||||
{
|
||||
if (!hmon) return FALSE;
|
||||
MONITORINFOEX *a = (MONITORINFOEX*)inf;
|
||||
if (a->cbSize < sizeof(MONITORINFO)) return FALSE;
|
||||
|
||||
NSScreen *mon = (NSScreen *)hmon;
|
||||
NSRect tr=[mon frame];
|
||||
NSRECT_TO_RECT(&a->rcMonitor,tr);
|
||||
tr = [mon visibleFrame];
|
||||
NSRECT_TO_RECT(&a->rcWork,tr);
|
||||
a->dwFlags = 0;
|
||||
|
||||
if (a->cbSize > sizeof(MONITORINFO))
|
||||
{
|
||||
const int maxlen = (int) (a->cbSize - sizeof(MONITORINFO));
|
||||
const int displayID = [[[mon deviceDescription] valueForKey:@"NSScreenNumber"] intValue];
|
||||
snprintf(a->szDevice,maxlen,"DisplayID %d",displayID);
|
||||
|
||||
|
||||
static bool init;
|
||||
static CFDictionaryRef (*_IODisplayCreateInfoDictionary)(io_service_t framebuffer, IOOptionBits options);
|
||||
|
||||
if (!init)
|
||||
{
|
||||
init = true;
|
||||
void *lib = dlopen("/System/Library/Frameworks/IOKit.framework/Versions/Current/IOKit",RTLD_LAZY);
|
||||
if (lib)
|
||||
*(void **)&_IODisplayCreateInfoDictionary = dlsym(lib,"IODisplayCreateInfoDictionary");
|
||||
}
|
||||
|
||||
if (_IODisplayCreateInfoDictionary)
|
||||
{
|
||||
NSDictionary *deviceInfo = (NSDictionary *)_IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), kIODisplayOnlyPreferredName);
|
||||
NSDictionary *names = [deviceInfo objectForKey:@"DisplayProductName"];
|
||||
if ([names count] > 0)
|
||||
{
|
||||
NSString *s = [names objectForKey:[[names allKeys] objectAtIndex:0]];
|
||||
if (s) SWELL_CFStringToCString(s,a->szDevice,maxlen);
|
||||
}
|
||||
[deviceInfo release];
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,783 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
This file provides basic APIs for browsing for files, directories, and messageboxes.
|
||||
|
||||
These APIs don't all match the Windows equivelents, but are close enough to make it not too much trouble.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SWELL_PROVIDED_BY_APP
|
||||
|
||||
#include "swell.h"
|
||||
#include "swell-dlggen.h"
|
||||
#include "../wdlcstring.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include "swell-internal.h"
|
||||
|
||||
struct swell_autoarp {
|
||||
swell_autoarp() { pool = [[NSAutoreleasePool alloc] init]; }
|
||||
~swell_autoarp() { [pool release]; }
|
||||
NSAutoreleasePool *pool;
|
||||
};
|
||||
|
||||
static NSMutableArray *extensionsFromList(const char *extlist, const char *def_ext=NULL)
|
||||
{
|
||||
NSMutableArray *fileTypes = [[NSMutableArray alloc] initWithCapacity:30];
|
||||
while (*extlist)
|
||||
{
|
||||
extlist += strlen(extlist)+1;
|
||||
if (!*extlist) break;
|
||||
while (*extlist)
|
||||
{
|
||||
while (*extlist && *extlist != '.') extlist++;
|
||||
if (!*extlist) break;
|
||||
extlist++;
|
||||
char tmp[32];
|
||||
lstrcpyn_safe(tmp,extlist,sizeof(tmp));
|
||||
if (strstr(tmp,";")) strstr(tmp,";")[0]=0;
|
||||
if (tmp[0] && tmp[0]!='*')
|
||||
{
|
||||
NSString *s=(NSString *)SWELL_CStringToCFString(tmp);
|
||||
const size_t tmp_len = strlen(tmp);
|
||||
if (def_ext && *def_ext &&
|
||||
!strnicmp(def_ext,tmp,tmp_len) &&
|
||||
(!def_ext[tmp_len] || def_ext[tmp_len] == ';'))
|
||||
[fileTypes insertObject:s atIndex:0];
|
||||
else
|
||||
[fileTypes addObject:s];
|
||||
[s release];
|
||||
}
|
||||
while (*extlist && *extlist != ';') extlist++;
|
||||
if (*extlist == ';') extlist++;
|
||||
}
|
||||
extlist++;
|
||||
}
|
||||
|
||||
return fileTypes;
|
||||
}
|
||||
|
||||
static const char *BFSF_Templ_dlgid;
|
||||
static DLGPROC BFSF_Templ_dlgproc;
|
||||
static struct SWELL_DialogResourceIndex *BFSF_Templ_reshead;
|
||||
void BrowseFile_SetTemplate(const char *dlgid, DLGPROC dlgProc, struct SWELL_DialogResourceIndex *reshead)
|
||||
{
|
||||
BFSF_Templ_reshead=reshead;
|
||||
BFSF_Templ_dlgid=dlgid;
|
||||
BFSF_Templ_dlgproc=dlgProc;
|
||||
}
|
||||
static const char *s_browse_extsel;
|
||||
|
||||
static LRESULT fileTypeChooseProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
const int wndh = 22, lblw = 80, combow = 250, def_wid = lblw + 4 + combow + 4;
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
SetOpaque(hwnd,FALSE);
|
||||
SWELL_MakeSetCurParms(1,1,0,0,hwnd,true,false);
|
||||
SWELL_MakeLabel(1,"File type:",1001,0,2,lblw,wndh,0);
|
||||
SWELL_MakeCombo(1000, lblw + 4,0, combow, wndh,3/*CBS_DROPDOWNLIST*/);
|
||||
SWELL_MakeSetCurParms(1,1,0,0,NULL,false,false);
|
||||
SetWindowPos(hwnd,NULL,0,0,def_wid,wndh,SWP_NOMOVE|SWP_NOZORDER);
|
||||
{
|
||||
const char *extlist = ((const char **)lParam)[0];
|
||||
SetWindowLongPtr(hwnd,GWLP_USERDATA,(LPARAM)extlist);
|
||||
const char *initial_file = ((const char **)lParam)[1];
|
||||
|
||||
if (initial_file) initial_file=WDL_get_fileext(initial_file);
|
||||
const size_t initial_file_len = initial_file && *initial_file ? strlen(++initial_file) : 0;
|
||||
|
||||
int def_sel = -1;
|
||||
|
||||
HWND combo = GetDlgItem(hwnd,1000);
|
||||
while (*extlist)
|
||||
{
|
||||
const char *next = extlist + strlen(extlist)+1;
|
||||
if (!*next) break;
|
||||
|
||||
if (strcmp(next,"*.*"))
|
||||
{
|
||||
int a = (int)SendMessage(combo,CB_ADDSTRING,0,(LPARAM)extlist);
|
||||
|
||||
// userdata for each item is pointer to un-terminated extension.
|
||||
const char *p = next;
|
||||
while (*p && *p != '.') p++;
|
||||
if (*p) p++;
|
||||
const char *bestp = p;
|
||||
|
||||
// scan extension list for matching initial file, use that (and set default)
|
||||
if (def_sel < 0 && initial_file) while (*p)
|
||||
{
|
||||
if (!strnicmp(p,initial_file,initial_file_len) && (p[initial_file_len] == ';' || !p[initial_file_len]))
|
||||
{
|
||||
s_browse_extsel = p;
|
||||
bestp = p;
|
||||
def_sel = a;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*p && *p != '.') p++;
|
||||
if (*p) p++;
|
||||
}
|
||||
}
|
||||
SendMessage(combo,CB_SETITEMDATA,a,(LPARAM)bestp);
|
||||
}
|
||||
|
||||
extlist = next + strlen(next)+1;
|
||||
if (!*extlist) break;
|
||||
}
|
||||
SendMessage(combo,CB_SETCURSEL,def_sel>=0?def_sel:0,0);
|
||||
}
|
||||
return 0;
|
||||
case WM_SIZE:
|
||||
{
|
||||
RECT r;
|
||||
GetClientRect(hwnd,&r);
|
||||
const int xpos = r.right / 2 - def_wid/2;
|
||||
SetWindowPos(GetDlgItem(hwnd,1001),NULL, xpos,2,0,0,SWP_NOZORDER|SWP_NOSIZE);
|
||||
SetWindowPos(GetDlgItem(hwnd,1000),NULL, xpos + lblw + 4,0,0,0,SWP_NOZORDER|SWP_NOSIZE);
|
||||
|
||||
}
|
||||
return 0;
|
||||
case WM_COMMAND:
|
||||
if (LOWORD(wParam) == 1000 && HIWORD(wParam) == CBN_SELCHANGE)
|
||||
{
|
||||
int a = (int)SendDlgItemMessage(hwnd,1000,CB_GETCURSEL,0,0);
|
||||
if (a>=0)
|
||||
{
|
||||
const char *extlist = (const char *)GetWindowLongPtr(hwnd,GWLP_USERDATA);
|
||||
if (extlist)
|
||||
{
|
||||
NSArray *fileTypes = extensionsFromList(extlist,
|
||||
s_browse_extsel = (const char *)SendDlgItemMessage(hwnd,1000,CB_GETITEMDATA,a,0)
|
||||
);
|
||||
if ([fileTypes count]>0)
|
||||
{
|
||||
NSSavePanel *par = (NSSavePanel*)GetWindowLongPtr(hwnd,0);
|
||||
if (par && [par isKindOfClass:[NSSavePanel class]]) [(NSSavePanel *)par setAllowedFileTypes:fileTypes];
|
||||
}
|
||||
[fileTypes release];
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProc(hwnd,uMsg,wParam,lParam);
|
||||
}
|
||||
|
||||
static void restoreMenuForFocus()
|
||||
{
|
||||
HWND h = GetFocus();
|
||||
HMENU menu = h ? GetMenu(h) : NULL;
|
||||
if (!menu)
|
||||
menu = SWELL_GetDefaultWindowMenu();
|
||||
if (menu)
|
||||
SWELL_SetCurrentMenu(menu);
|
||||
}
|
||||
|
||||
// return true
|
||||
bool BrowseForSaveFile(const char *text, const char *initialdir, const char *initialfile, const char *extlist,
|
||||
char *fn, int fnsize)
|
||||
{
|
||||
swell_autoarp auto_arp;
|
||||
|
||||
NSSavePanel *panel = [NSSavePanel savePanel];
|
||||
NSMutableArray *fileTypes = extensionsFromList(extlist);
|
||||
NSString *title=(NSString *)SWELL_CStringToCFString(text);
|
||||
NSString *ifn=NULL, *idir = NULL;
|
||||
|
||||
[panel setTitle:title];
|
||||
[panel setAccessoryView:nil];
|
||||
HWND av_parent = (HWND)panel;
|
||||
|
||||
s_browse_extsel = NULL;
|
||||
|
||||
if ([fileTypes count]>1)
|
||||
{
|
||||
const char *ar[2]={extlist,initialfile};
|
||||
av_parent = SWELL_CreateDialog(NULL,0,NULL,fileTypeChooseProc,(LPARAM)ar);
|
||||
if (!av_parent) av_parent = (HWND)panel;
|
||||
else SetWindowLongPtr(av_parent, 0, (LPARAM)panel);
|
||||
}
|
||||
|
||||
HWND oh=NULL;
|
||||
if (BFSF_Templ_dlgproc && BFSF_Templ_dlgid) // create a child dialog and set it to the panel
|
||||
{
|
||||
oh=SWELL_CreateDialog(BFSF_Templ_reshead, BFSF_Templ_dlgid, av_parent, BFSF_Templ_dlgproc, 0);
|
||||
BFSF_Templ_dlgproc=0;
|
||||
BFSF_Templ_dlgid=0;
|
||||
}
|
||||
if (av_parent != (HWND)panel)
|
||||
{
|
||||
if (oh)
|
||||
{
|
||||
RECT r1,r2;
|
||||
GetClientRect(oh,&r1);
|
||||
GetClientRect(av_parent,&r2);
|
||||
|
||||
SetWindowPos(oh,NULL,0,r2.bottom,0,0,SWP_NOZORDER|SWP_NOSIZE);
|
||||
if (r2.right < r1.right) r2.right=r1.right;
|
||||
SetWindowPos(av_parent,NULL,0,0,r2.right,r2.bottom+r1.bottom,SWP_NOZORDER|SWP_NOMOVE);
|
||||
ShowWindow(oh,SW_SHOWNA);
|
||||
}
|
||||
oh = av_parent;
|
||||
|
||||
NSWindow *oldw = [(NSView *)av_parent window];
|
||||
[panel setAccessoryView:(NSView *)av_parent]; // we resized our accessory view
|
||||
SendMessage(av_parent,WM_COMMAND,(CBN_SELCHANGE<<16) | 1000,(LPARAM)GetDlgItem(av_parent,1000));
|
||||
[(NSView *)av_parent setHidden:NO];
|
||||
[oldw release];
|
||||
}
|
||||
else if ([fileTypes count]>0)
|
||||
{
|
||||
[panel setAllowedFileTypes:fileTypes];
|
||||
}
|
||||
|
||||
if (initialfile && *initialfile && *initialfile != '.')
|
||||
{
|
||||
char s[2048];
|
||||
lstrcpyn_safe(s,initialfile,sizeof(s));
|
||||
|
||||
if (ext_valid_for_extlist(WDL_get_fileext(initialfile),extlist)>=0)
|
||||
WDL_remove_fileext(s);
|
||||
|
||||
char *p=s;
|
||||
while (*p) p++;
|
||||
while (p >= s && *p != '/') p--;
|
||||
if (p>=s)
|
||||
{
|
||||
*p=0;
|
||||
ifn=(NSString *)SWELL_CStringToCFString(p+1);
|
||||
idir=(NSString *)SWELL_CStringToCFString(s[0]?s:"/");
|
||||
}
|
||||
else
|
||||
ifn=(NSString *)SWELL_CStringToCFString(s);
|
||||
}
|
||||
if (!idir && initialdir && *initialdir)
|
||||
{
|
||||
idir=(NSString *)SWELL_CStringToCFString(initialdir);
|
||||
}
|
||||
|
||||
HMENU hm=SWELL_GetDefaultModalWindowMenu();
|
||||
if (hm)
|
||||
{
|
||||
hm=SWELL_DuplicateMenu(hm);
|
||||
SWELL_SetCurrentMenu(hm);
|
||||
}
|
||||
|
||||
NSInteger result = [panel runModalForDirectory:idir file:ifn];
|
||||
restoreMenuForFocus();
|
||||
if (hm) DestroyMenu(hm);
|
||||
|
||||
if (oh) SendMessage(oh,WM_DESTROY,0,0);
|
||||
[panel setAccessoryView:nil];
|
||||
|
||||
bool rv = false;
|
||||
|
||||
NSString *str;
|
||||
if (result == NSOKButton && fn && fnsize > 0 && (str = [panel filename]))
|
||||
{
|
||||
SWELL_CFStringToCString(str,fn,fnsize);
|
||||
if (fn[0])
|
||||
{
|
||||
char tmp[256];
|
||||
|
||||
const NSUInteger nft = [fileTypes count];
|
||||
NSUInteger x = nft;
|
||||
|
||||
const char *ext = WDL_get_fileext(fn);
|
||||
if (*ext)
|
||||
{
|
||||
// see if extension is in list
|
||||
ext++;
|
||||
for (x = 0; x < nft; x ++)
|
||||
{
|
||||
NSString *s = [fileTypes objectAtIndex:x];
|
||||
if (s)
|
||||
{
|
||||
SWELL_CFStringToCString(s,tmp,sizeof(tmp));
|
||||
if (!stricmp(tmp,ext)) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (x == nft)
|
||||
{
|
||||
// this might no longer be necessary -- it was at one point when [accessoryview window] was not a NSSavePanel,
|
||||
// but we fixed that, so the extension should always be applied (probably)
|
||||
|
||||
// not in list: apply last-selected extension, then default extension, if specified, or first extension from list
|
||||
if (s_browse_extsel && *s_browse_extsel)
|
||||
{
|
||||
lstrcatn(fn,".",fnsize);
|
||||
lstrcatn(fn,s_browse_extsel,fnsize);
|
||||
}
|
||||
else if (initialfile && *initialfile == '.')
|
||||
{
|
||||
lstrcatn(fn,initialfile,fnsize);
|
||||
}
|
||||
else if (nft > 0)
|
||||
{
|
||||
NSString *s = [fileTypes objectAtIndex:0];
|
||||
if (s)
|
||||
{
|
||||
tmp[0] = '.';
|
||||
SWELL_CFStringToCString(s,tmp+1,sizeof(tmp)-1);
|
||||
lstrcatn(fn,tmp,fnsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = true;
|
||||
}
|
||||
}
|
||||
|
||||
[title release];
|
||||
[fileTypes release];
|
||||
[idir release];
|
||||
[ifn release];
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool BrowseForDirectory(const char *text, const char *initialdir, char *fn, int fnsize)
|
||||
{
|
||||
swell_autoarp auto_arp;
|
||||
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
NSString *title=(NSString *)SWELL_CStringToCFString(text);
|
||||
NSString *idir=NULL;
|
||||
|
||||
[panel setTitle:title];
|
||||
[panel setAllowsMultipleSelection:NO];
|
||||
[panel setCanChooseFiles:NO];
|
||||
[panel setCanCreateDirectories:YES];
|
||||
[panel setCanChooseDirectories:YES];
|
||||
[panel setResolvesAliases:YES];
|
||||
|
||||
HWND oh=NULL;
|
||||
if (BFSF_Templ_dlgproc && BFSF_Templ_dlgid) // create a child dialog and set it to the panel
|
||||
{
|
||||
oh=SWELL_CreateDialog(BFSF_Templ_reshead, BFSF_Templ_dlgid, (HWND)panel, BFSF_Templ_dlgproc, 0);
|
||||
BFSF_Templ_dlgproc=0;
|
||||
BFSF_Templ_dlgid=0;
|
||||
}
|
||||
|
||||
if (initialdir && *initialdir)
|
||||
{
|
||||
idir=(NSString *)SWELL_CStringToCFString(initialdir);
|
||||
}
|
||||
|
||||
HMENU hm=SWELL_GetDefaultModalWindowMenu();
|
||||
if (hm)
|
||||
{
|
||||
hm=SWELL_DuplicateMenu(hm);
|
||||
SWELL_SetCurrentMenu(hm);
|
||||
}
|
||||
NSInteger result = [panel runModalForDirectory:idir file:nil types:nil];
|
||||
restoreMenuForFocus();
|
||||
if (hm) DestroyMenu(hm);
|
||||
|
||||
if (oh) SendMessage(oh,WM_DESTROY,0,0);
|
||||
[panel setAccessoryView:nil];
|
||||
|
||||
[idir release];
|
||||
[title release];
|
||||
|
||||
if (result != NSOKButton) return 0;
|
||||
|
||||
NSArray *filesToOpen = [panel filenames];
|
||||
NSInteger count = [filesToOpen count];
|
||||
|
||||
if (!count) return 0;
|
||||
|
||||
NSString *aFile = [filesToOpen objectAtIndex:0];
|
||||
if (!aFile) return 0;
|
||||
if (fn && fnsize>0)
|
||||
{
|
||||
SWELL_CFStringToCString(aFile,fn,fnsize);
|
||||
fn[fnsize-1]=0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
char *BrowseForFiles(const char *text, const char *initialdir,
|
||||
const char *initialfile, bool allowmul, const char *extlist)
|
||||
{
|
||||
swell_autoarp auto_arp;
|
||||
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
NSString *title=(NSString *)SWELL_CStringToCFString(text);
|
||||
NSString *ifn=NULL, *idir=NULL;
|
||||
NSMutableArray *fileTypes = extensionsFromList(extlist);
|
||||
|
||||
HWND oh=NULL;
|
||||
if (BFSF_Templ_dlgproc && BFSF_Templ_dlgid) // create a child dialog and set it to the panel
|
||||
{
|
||||
oh=SWELL_CreateDialog(BFSF_Templ_reshead, BFSF_Templ_dlgid, (HWND)panel, BFSF_Templ_dlgproc, 0);
|
||||
BFSF_Templ_dlgproc=0;
|
||||
BFSF_Templ_dlgid=0;
|
||||
}
|
||||
|
||||
[panel setTitle:title];
|
||||
[panel setAllowsMultipleSelection:(allowmul?YES:NO)];
|
||||
[panel setCanChooseFiles:YES];
|
||||
[panel setCanChooseDirectories:NO];
|
||||
[panel setResolvesAliases:YES];
|
||||
|
||||
if (initialfile && *initialfile)
|
||||
{
|
||||
char s[2048];
|
||||
lstrcpyn_safe(s,initialfile,sizeof(s));
|
||||
char *p=s;
|
||||
while (*p) p++;
|
||||
while (p >= s && *p != '/') p--;
|
||||
if (p>=s)
|
||||
{
|
||||
*p=0;
|
||||
ifn=(NSString *)SWELL_CStringToCFString(p+1);
|
||||
idir=(NSString *)SWELL_CStringToCFString(s[0]?s:"/");
|
||||
}
|
||||
else
|
||||
ifn=(NSString *)SWELL_CStringToCFString(s);
|
||||
}
|
||||
if (!idir && initialdir && *initialdir)
|
||||
{
|
||||
idir=(NSString *)SWELL_CStringToCFString(initialdir);
|
||||
}
|
||||
|
||||
HMENU hm=SWELL_GetDefaultModalWindowMenu();
|
||||
if (hm)
|
||||
{
|
||||
hm=SWELL_DuplicateMenu(hm);
|
||||
SWELL_SetCurrentMenu(hm);
|
||||
}
|
||||
NSInteger result = [panel runModalForDirectory:idir file:ifn types:([fileTypes count]>0 ? fileTypes : nil)];
|
||||
|
||||
restoreMenuForFocus();
|
||||
if (hm) DestroyMenu(hm);
|
||||
|
||||
if (oh) SendMessage(oh,WM_DESTROY,0,0);
|
||||
[panel setAccessoryView:nil];
|
||||
|
||||
[ifn release];
|
||||
[idir release];
|
||||
|
||||
[fileTypes release];
|
||||
[title release];
|
||||
|
||||
if (result != NSOKButton) return 0;
|
||||
|
||||
NSArray *filesToOpen = [panel filenames];
|
||||
const NSInteger count = [filesToOpen count];
|
||||
|
||||
if (!count) return 0;
|
||||
|
||||
char fn[2048];
|
||||
if (count==1||!allowmul)
|
||||
{
|
||||
NSString *aFile = [filesToOpen objectAtIndex:0];
|
||||
if (!aFile) return 0;
|
||||
SWELL_CFStringToCString(aFile,fn,sizeof(fn));
|
||||
fn[sizeof(fn)-1]=0;
|
||||
char *ret=(char *)malloc(strlen(fn)+2);
|
||||
memcpy(ret,fn,strlen(fn));
|
||||
ret[strlen(fn)]=0;
|
||||
ret[strlen(fn)+1]=0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t rsize=1;
|
||||
char *ret=0;
|
||||
for (NSInteger i=0; i<count; i++)
|
||||
{
|
||||
NSString *aFile = [filesToOpen objectAtIndex:i];
|
||||
if (!aFile) continue;
|
||||
SWELL_CFStringToCString(aFile,fn,sizeof(fn));
|
||||
fn[sizeof(fn)-1]=0;
|
||||
|
||||
size_t tlen=strlen(fn)+1;
|
||||
ret=(char *)realloc(ret,rsize+tlen+1);
|
||||
if (!ret) return 0;
|
||||
|
||||
if (rsize==1) ret[0]=0;
|
||||
strcpy(ret+rsize,fn);
|
||||
rsize+=tlen;
|
||||
ret[rsize]=0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static NSString *mbidtostr(int idx)
|
||||
{
|
||||
switch (idx)
|
||||
{
|
||||
case IDOK: return @"OK";
|
||||
case IDCANCEL: return @"Cancel";
|
||||
case IDYES: return @"Yes";
|
||||
case IDNO: return @"No";
|
||||
case IDRETRY: return @"Retry";
|
||||
case IDABORT: return @"Abort";
|
||||
case IDIGNORE: return @"Ignore";
|
||||
default:
|
||||
WDL_ASSERT(idx == 0);
|
||||
return @"";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int MessageBox(HWND hwndParent, const char *text, const char *caption, int type)
|
||||
{
|
||||
swell_autoarp auto_arp;
|
||||
|
||||
NSString *title = (NSString *)SWELL_CStringToCFString(caption?caption:"");
|
||||
NSString *text2 = (NSString *)SWELL_CStringToCFString(text?text:"");
|
||||
|
||||
int b1=IDOK, b2=0, b3=0;
|
||||
switch (type & 0xf)
|
||||
{
|
||||
case MB_ABORTRETRYIGNORE:
|
||||
b1 = IDABORT;
|
||||
b2 = IDRETRY;
|
||||
b3 = IDIGNORE;
|
||||
break;
|
||||
case MB_RETRYCANCEL:
|
||||
b1 = IDRETRY;
|
||||
// fallthrough
|
||||
case MB_OKCANCEL:
|
||||
b2 = IDCANCEL;
|
||||
break;
|
||||
case MB_YESNOCANCEL:
|
||||
b3 = IDCANCEL;
|
||||
// fallthrough
|
||||
case MB_YESNO:
|
||||
b1 = IDYES;
|
||||
b2 = IDNO;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((type & MB_DEFBUTTON3) && b3)
|
||||
{
|
||||
// rotate buttons right (making b3 the default)
|
||||
const int tmp = b3;
|
||||
b3 = b2;
|
||||
b2 = b1;
|
||||
b1 = tmp;
|
||||
}
|
||||
else if ((type & MB_DEFBUTTON2) && b2)
|
||||
{
|
||||
// rotate buttons left
|
||||
const int tmp = b1;
|
||||
b1 = b2;
|
||||
b2 = b3 ? b3 : tmp;
|
||||
if (b3) b3=tmp;
|
||||
}
|
||||
|
||||
if (b2 && b3)
|
||||
{
|
||||
// NSRunAlertPanel ordering meh
|
||||
const int tmp = b3;
|
||||
b3 = b2;
|
||||
b2 = tmp;
|
||||
}
|
||||
|
||||
NSInteger ret = NSRunAlertPanel(title,@"%@",mbidtostr(b1),mbidtostr(b2),mbidtostr(b3),text2);
|
||||
|
||||
[text2 release];
|
||||
[title release];
|
||||
|
||||
return ret > 0 ? b1 : ret < 0 ? b3 : b2;
|
||||
}
|
||||
|
||||
static WDL_DLGRET color_okCancelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
SetWindowLongPtr(hwndDlg,0,0);
|
||||
return 0;
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
SetWindowLongPtr(hwndDlg,0,1);
|
||||
break;
|
||||
case IDCANCEL:
|
||||
SetWindowLongPtr(hwndDlg,0,2);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static void okcancel_create(HWND hwnd, int f)
|
||||
{
|
||||
SWELL_MakeSetCurParms(0.0, 0.0, 0,0,hwnd,false,false);
|
||||
SWELL_MakeButton(1,"OK",IDOK,48,2,44,14,0);
|
||||
SWELL_MakeButton(0,"Cancel",IDCANCEL,2,2,44,14,0);
|
||||
SWELL_MakeSetCurParms(0.0, 0.0, 0,0,NULL,false,false);
|
||||
}
|
||||
static HWND makeOKcancel(HWND par)
|
||||
{
|
||||
const char *dlgid = "";
|
||||
SWELL_DialogResourceIndex tmph = {
|
||||
dlgid, "",
|
||||
SWELL_DLG_WS_FLIPPED|SWELL_DLG_WS_NOAUTOSIZE|SWELL_DLG_WS_CHILD,
|
||||
okcancel_create,
|
||||
(int)(98*1.7),(int)(18*1.7),
|
||||
NULL
|
||||
};
|
||||
return SWELL_CreateDialog(&tmph,dlgid,par,color_okCancelProc,0);
|
||||
}
|
||||
|
||||
static bool ColorFromNSColor(NSColor *color, COLORREF *colout)
|
||||
{
|
||||
if (!color) return false;
|
||||
|
||||
CGFloat r,g,b;
|
||||
NSColor *color2=[color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
|
||||
if (!color2) return false;
|
||||
|
||||
[color2 getRed:&r green:&g blue:&b alpha:NULL];
|
||||
int rv=(int)(r*255.0 + 0.5);
|
||||
int gv=(int)(g*255.0 + 0.5);
|
||||
int bv=(int)(b*255.0 + 0.5);
|
||||
if (rv<0)rv=0; else if (rv>255)rv=255;
|
||||
if (gv<0)gv=0; else if (gv>255)gv=255;
|
||||
if (bv<0)bv=0; else if (bv>255)bv=255;
|
||||
|
||||
*colout = RGB(rv,gv,bv);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SWELL_ChooseColor(HWND unused, COLORREF *a, int ncustom, COLORREF *custom)
|
||||
{
|
||||
NSColorPanel *pan=[NSColorPanel sharedColorPanel];
|
||||
if (!pan||!a) return false;
|
||||
|
||||
NSColor *bkcol=[NSColor colorWithCalibratedRed:GetRValue(*a)/255.0f green:GetGValue(*a)/255.0f blue:GetBValue(*a)/255.0f alpha:1.0f];
|
||||
[pan setColor:bkcol];
|
||||
[pan setShowsAlpha:NO];
|
||||
[pan setAccessoryView:nil];
|
||||
|
||||
HWND h = makeOKcancel((HWND)pan);
|
||||
bool hadOK=!h;
|
||||
|
||||
NSModalSession ctx=[NSApp beginModalSessionForWindow:pan];
|
||||
while ([NSApp runModalSession:ctx]==NSRunContinuesResponse && [pan isVisible])
|
||||
{
|
||||
const LONG_PTR res = h ? GetWindowLongPtr(h,0) : 0;
|
||||
if (res) { hadOK=res==1; break; }
|
||||
Sleep(3);
|
||||
}
|
||||
|
||||
[NSApp endModalSession:ctx];
|
||||
|
||||
if (h)
|
||||
{
|
||||
SendMessage(h,WM_DESTROY,0,0);
|
||||
[pan setAccessoryView:nil]; // will destroy h anyway
|
||||
[pan close];
|
||||
}
|
||||
|
||||
return hadOK && ColorFromNSColor([pan color],a);
|
||||
}
|
||||
|
||||
bool SWELL_ChooseFont(HWND unused, LOGFONT *lf)
|
||||
{
|
||||
if (!lf) return false;
|
||||
|
||||
NSFontPanel *pan = [NSFontPanel sharedFontPanel];
|
||||
int sz=lf->lfHeight > 0 ? lf->lfHeight : lf->lfHeight < 0 ? -lf->lfHeight : lf->lfWidth;
|
||||
|
||||
char buf[1024];
|
||||
lstrcpyn_safe(buf,lf->lfFaceName,sizeof(buf));
|
||||
if (lf->lfWeight >= FW_BOLD) lstrcatn(buf," Bold",sizeof(buf));
|
||||
if (lf->lfItalic) lstrcatn(buf," Italic",sizeof(buf));
|
||||
|
||||
NSString *lbl=(NSString *)SWELL_CStringToCFString(buf);
|
||||
NSFont *tmpfont = [NSFont fontWithName:lbl size:sz];
|
||||
if (!tmpfont) tmpfont = [NSFont systemFontOfSize:sz];
|
||||
|
||||
if (lf->lfHeight > 0 && tmpfont)
|
||||
{
|
||||
// convert to total size
|
||||
#ifndef SWELL_NO_CORETEXT
|
||||
double SWELL_GetCTFontRealMetrics(const void *ptrfont, double pointSize, float *ascentOut, float *descentOut);
|
||||
|
||||
float asc,desc;
|
||||
SWELL_GetCTFontRealMetrics(tmpfont,sz,&asc,&desc);
|
||||
const double sc = sz / (asc+desc);
|
||||
|
||||
tmpfont = [NSFont fontWithName:lbl size:sz*sc];
|
||||
if (!tmpfont) tmpfont = [NSFont systemFontOfSize:sz*sc];
|
||||
#endif
|
||||
}
|
||||
|
||||
[lbl release];
|
||||
|
||||
[pan setPanelFont:tmpfont isMultiple:NO];
|
||||
|
||||
[pan setAccessoryView:nil];
|
||||
HWND h = makeOKcancel((HWND)pan);
|
||||
|
||||
bool hadOK=!h;
|
||||
NSModalSession ctx=[NSApp beginModalSessionForWindow:pan];
|
||||
while ([NSApp runModalSession:ctx]==NSRunContinuesResponse && [pan isVisible])
|
||||
{
|
||||
const LONG_PTR a = h ? GetWindowLongPtr(h,0) : 0;
|
||||
if (a) { hadOK=a==1; break; }
|
||||
Sleep(3);
|
||||
}
|
||||
|
||||
[NSApp endModalSession:ctx];
|
||||
|
||||
if (h)
|
||||
{
|
||||
SendMessage(h,WM_DESTROY,0,0);
|
||||
[pan setAccessoryView:nil]; // will destroy h
|
||||
[pan close];
|
||||
}
|
||||
|
||||
if (!hadOK) return false;
|
||||
|
||||
NSFont *newfont = [pan panelConvertFont:tmpfont];
|
||||
int newsz = - (int) ([newfont pointSize]+0.5);
|
||||
LOGFONT oldf=*lf;
|
||||
if (newsz != sz)
|
||||
{
|
||||
lf->lfWidth=0;
|
||||
lf->lfHeight = newsz;
|
||||
}
|
||||
|
||||
SWELL_CFStringToCString([newfont familyName],lf->lfFaceName, sizeof(lf->lfFaceName));
|
||||
SWELL_CFStringToCString([newfont displayName],buf,sizeof(buf));
|
||||
|
||||
lf->lfItalic = !! strstr(buf,"Italic");
|
||||
lf->lfWeight = strstr(buf,"Bold") ? FW_BOLD : FW_NORMAL;
|
||||
|
||||
return memcmp(lf,&oldf,sizeof(LOGFONT)) != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifdef SWELL_PROVIDED_BY_APP
|
||||
|
||||
#define SWELL_API_DEFPARM(x)
|
||||
#define SWELL_API_DEFINE(ret,func,parms) ret (*func) parms ;
|
||||
extern "C" {
|
||||
#include "swell.h"
|
||||
};
|
||||
|
||||
// only include this file in projects that are linked to libSwell.so
|
||||
|
||||
struct SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head;
|
||||
struct SWELL_DialogResourceIndex *SWELL_curmodule_dialogresource_head;
|
||||
struct SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head;
|
||||
|
||||
// define the functions
|
||||
|
||||
static struct
|
||||
{
|
||||
const char *name;
|
||||
void **func;
|
||||
} api_tab[]={
|
||||
|
||||
#undef _WDL_SWELL_H_API_DEFINED_
|
||||
#undef SWELL_API_DEFINE
|
||||
#define SWELL_API_DEFINE(ret, func, parms) {#func, (void **)&func },
|
||||
|
||||
#include "swell.h"
|
||||
|
||||
};
|
||||
|
||||
static int dummyFunc() { return 0; }
|
||||
|
||||
static int doinit(void *(*GetFunc)(const char *name))
|
||||
{
|
||||
int errcnt=0;
|
||||
for (int x = 0; x < (int)(sizeof(api_tab)/sizeof(api_tab[0])); x ++)
|
||||
{
|
||||
*api_tab[x].func=GetFunc(api_tab[x].name);
|
||||
if (!*api_tab[x].func)
|
||||
{
|
||||
printf("SWELL API not found: %s\n",api_tab[x].name);
|
||||
errcnt++;
|
||||
*api_tab[x].func = (void*)&dummyFunc;
|
||||
}
|
||||
}
|
||||
return errcnt;
|
||||
}
|
||||
|
||||
#ifdef SWELL_LOAD_SWELL_DYLIB
|
||||
|
||||
static void *(*__loaded_getfunc)(const char *name)=NULL;
|
||||
|
||||
class SwellAPPInitializer
|
||||
{
|
||||
public:
|
||||
SwellAPPInitializer()
|
||||
{
|
||||
void *(*SWELLAPI_GetFunc)(const char *name)=NULL;
|
||||
char fn[4096];
|
||||
const int nSize=sizeof(fn)-64;
|
||||
int sz=readlink("/proc/self/exe",fn,nSize);
|
||||
if (sz<1)
|
||||
{
|
||||
Dl_info inf={0,};
|
||||
if (dladdr(&api_tab,&inf) && inf.dli_fname)
|
||||
sz = (int) strlen(inf.dli_fname);
|
||||
else
|
||||
sz = 0;
|
||||
}
|
||||
if (sz>=nSize)sz=nSize-1;
|
||||
fn[sz]=0;
|
||||
char *p=fn;
|
||||
while (*p) p++;
|
||||
while (p >= fn && *p != '/') p--;
|
||||
p++;
|
||||
strcpy(p,p==fn ? "./libSwell.so" : "libSwell.so");
|
||||
|
||||
void *tmp = dlopen(fn,RTLD_LAZY);
|
||||
if (!tmp)
|
||||
{
|
||||
printf("Error loading '%s': %s\n",fn,dlerror());
|
||||
exit(2);
|
||||
}
|
||||
const char *preload_fn = (const char *)dlsym(tmp,"SWELL_WANT_LOAD_LIBRARY");
|
||||
if (preload_fn && *preload_fn)
|
||||
dlopen(preload_fn,RTLD_LAZY|RTLD_GLOBAL);
|
||||
|
||||
*(void **)&SWELLAPI_GetFunc = dlsym(tmp,"SWELLAPI_GetFunc");
|
||||
|
||||
if (SWELLAPI_GetFunc && SWELLAPI_GetFunc(NULL)==(void*)0x100)
|
||||
{
|
||||
void (*set_app_main)(INT_PTR (*AppMain)(int msg, INT_PTR parm1, INT_PTR parm2));
|
||||
*(void **)&set_app_main = dlsym(tmp,"SWELL_set_app_main");
|
||||
if (set_app_main) set_app_main(SWELLAppMain);
|
||||
|
||||
__loaded_getfunc = SWELLAPI_GetFunc;
|
||||
if (doinit(SWELLAPI_GetFunc)) exit(1);
|
||||
}
|
||||
}
|
||||
~SwellAPPInitializer()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
SwellAPPInitializer m_swell_appAPIinit;
|
||||
|
||||
extern "C" __attribute__ ((visibility ("default"))) void *SWELLAPI_GetFunc(const char *name)
|
||||
{
|
||||
if (__loaded_getfunc) return __loaded_getfunc(name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
extern "C" __attribute__ ((visibility ("default"))) int SWELL_dllMain(HINSTANCE hInst, DWORD callMode, LPVOID _GetFunc)
|
||||
{
|
||||
if (callMode == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
if (!_GetFunc) return 0;
|
||||
doinit((void *(*)(const char *)) _GetFunc);
|
||||
}
|
||||
|
||||
// this returning 1 allows DllMain to be called, if available
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,95 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifdef SWELL_PROVIDED_BY_APP
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <objc/objc-runtime.h>
|
||||
#define SWELL_API_DEFPARM(x)
|
||||
#define SWELL_API_DEFINE(ret,func,parms) ret (*func) parms ;
|
||||
#include "swell.h"
|
||||
|
||||
// only include this file in projects that are linked to swell.dylib
|
||||
|
||||
struct SWELL_DialogResourceIndex *SWELL_curmodule_dialogresource_head;
|
||||
struct SWELL_MenuResourceIndex *SWELL_curmodule_menuresource_head;
|
||||
|
||||
// define the functions
|
||||
|
||||
static struct
|
||||
{
|
||||
const char *name;
|
||||
void **func;
|
||||
} api_tab[]={
|
||||
|
||||
#undef _WDL_SWELL_H_API_DEFINED_
|
||||
#undef SWELL_API_DEFINE
|
||||
#define SWELL_API_DEFINE(ret, func, parms) {#func, (void **)&func },
|
||||
|
||||
#include "swell-functions.h"
|
||||
|
||||
};
|
||||
|
||||
static int dummyFunc() { return 0; }
|
||||
|
||||
class SwellAPPInitializer
|
||||
{
|
||||
public:
|
||||
SwellAPPInitializer()
|
||||
{
|
||||
void *(*SWELLAPI_GetFunc)(const char *name)=NULL;
|
||||
void *(*send_msg)(id, SEL) = (void *(*)(id, SEL))objc_msgSend;
|
||||
|
||||
id del = [NSApp delegate];
|
||||
if (del && [del respondsToSelector:@selector(swellGetAPPAPIFunc)])
|
||||
*(void **)&SWELLAPI_GetFunc = send_msg(del,@selector(swellGetAPPAPIFunc));
|
||||
|
||||
if (!SWELLAPI_GetFunc) NSLog(@"SWELL API provider not found\n");
|
||||
else if (SWELLAPI_GetFunc(NULL)!=(void*)0x100)
|
||||
{
|
||||
NSLog(@"SWELL API provider returned incorrect version\n");
|
||||
SWELLAPI_GetFunc=0;
|
||||
}
|
||||
|
||||
int x;
|
||||
for (x = 0; x < sizeof(api_tab)/sizeof(api_tab[0]); x ++)
|
||||
{
|
||||
*api_tab[x].func=SWELLAPI_GetFunc?SWELLAPI_GetFunc(api_tab[x].name):0;
|
||||
if (!*api_tab[x].func)
|
||||
{
|
||||
if (SWELLAPI_GetFunc) NSLog(@"SWELL API not found: %s\n",api_tab[x].name);
|
||||
*api_tab[x].func = (void*)&dummyFunc;
|
||||
}
|
||||
}
|
||||
}
|
||||
~SwellAPPInitializer()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
SwellAPPInitializer m_swell_appAPIinit;
|
||||
|
||||
extern "C" __attribute__ ((visibility ("default"))) int SWELL_dllMain(HINSTANCE hInst, DWORD callMode, LPVOID _GetFunc)
|
||||
{
|
||||
// this returning 1 allows DllMain to be called, if available
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,58 @@
|
||||
#ifndef _SWELL_WIN32_H_
|
||||
#define _SWELL_WIN32_H_
|
||||
|
||||
/*************
|
||||
** helpers to give swell-like functionality on win32
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
void SWELL_DisableContextMenu(HWND h, bool dis);
|
||||
|
||||
|
||||
|
||||
#ifndef SWELL_WIN32_DECLARE_ONLY
|
||||
|
||||
#include <windows.h>
|
||||
#include "../wdltypes.h"
|
||||
|
||||
#define SWELL_DISABLE_CTX_OLDPROC_NAME "SWELLDisableCtxOldProc"
|
||||
|
||||
static LRESULT WINAPI swellDisableCtxNewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HANDLE oldProc = uMsg != WM_CONTEXTMENU ? GetProp(hwnd,SWELL_DISABLE_CTX_OLDPROC_NAME) : NULL;
|
||||
if (uMsg == WM_DESTROY)
|
||||
{
|
||||
RemoveProp(hwnd,SWELL_DISABLE_CTX_OLDPROC_NAME);
|
||||
if (oldProc) SetWindowLongPtr(hwnd,GWLP_WNDPROC,(LPARAM)oldProc);
|
||||
}
|
||||
return oldProc ? CallWindowProc((WNDPROC)oldProc,hwnd,uMsg,wParam,lParam) : DefWindowProc(hwnd,uMsg,wParam,lParam);
|
||||
}
|
||||
|
||||
void SWELL_DisableContextMenu(HWND h, bool dis)
|
||||
{
|
||||
char classname[512];
|
||||
if (WDL_NOT_NORMALLY(!h)) return;
|
||||
if (GetClassName(h,classname,sizeof(classname)) && !strcmp(classname,"ComboBox"))
|
||||
{
|
||||
HWND h2 = FindWindowEx(h,NULL,"Edit",NULL);
|
||||
if (h2) h = h2;
|
||||
}
|
||||
|
||||
if (dis)
|
||||
{
|
||||
if (!GetProp(h,SWELL_DISABLE_CTX_OLDPROC_NAME))
|
||||
SetProp(h,SWELL_DISABLE_CTX_OLDPROC_NAME,(HANDLE)SetWindowLongPtr(h,GWLP_WNDPROC,(LPARAM)swellDisableCtxNewWndProc));
|
||||
}
|
||||
else
|
||||
{
|
||||
LPARAM op = (LPARAM)GetProp(h,SWELL_DISABLE_CTX_OLDPROC_NAME);
|
||||
if (op) SetWindowLongPtr(h,GWLP_WNDPROC,op);
|
||||
RemoveProp(h,SWELL_DISABLE_CTX_OLDPROC_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !SWELL_WIN32_DECLARE_ONLY
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
#endif // _SWELL_WIN32_H_
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1205
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,197 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
SWELL provides _EXTREMELY BASIC_ win32 wrapping for OS X and maybe other platforms.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
|
||||
#ifndef _WDL_SWELL_H_ // here purely for apps/other libraries (dirscan.h uses it), each section actually has its own define
|
||||
#define _WDL_SWELL_H_
|
||||
|
||||
|
||||
#if defined(__APPLE__) && !defined(SWELL_FORCE_GENERIC)
|
||||
#define SWELL_TARGET_OSX
|
||||
#define SWELL_TARGET_OSX_COCOA
|
||||
#endif
|
||||
|
||||
// for swell*generic
|
||||
// #define SWELL_TARGET_GDK
|
||||
// #define SWELL_LICE_GDI
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
// go ahead and get this included before we define FSHIFT in swell-types.h
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
// IF YOU ADD TO SWELL:
|
||||
// Adding types, defines, etc: add to swell-types.h
|
||||
// Adding functions: put them in swell-functions.h
|
||||
|
||||
|
||||
#include "swell-types.h"
|
||||
#include "swell-functions.h"
|
||||
|
||||
|
||||
#ifndef SWELL_PROVIDED_BY_APP
|
||||
#ifndef _WDL_SWELL_H_UTIL_DEFINED_
|
||||
#define _WDL_SWELL_H_UTIL_DEFINED_
|
||||
|
||||
// these should never be called directly!!! put SWELL_POSTMESSAGE_DELEGATE_IMPL in your nsapp delegate, and call SWELL_POSTMESSAGE_INIT at some point from there too
|
||||
|
||||
#define SWELL_POSTMESSAGE_INIT SWELL_Internal_PostMessage_Init();
|
||||
#define SWELL_POSTMESSAGE_DELEGATE_IMPL \
|
||||
-(bool)swellPostMessage:(HWND)dest msg:(int)message wp:(WPARAM)wParam lp:(LPARAM)lParam { \
|
||||
return SWELL_Internal_PostMessage(dest,message,wParam,lParam); \
|
||||
} \
|
||||
-(void)swellPostMessageClearQ:(HWND)dest { \
|
||||
SWELL_Internal_PMQ_ClearAllMessages(dest); \
|
||||
} \
|
||||
-(void)swellPostMessageTick:(id)sender { \
|
||||
SWELL_MessageQueue_Flush(); \
|
||||
}
|
||||
|
||||
BOOL SWELL_Internal_PostMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
void SWELL_Internal_PMQ_ClearAllMessages(HWND hwnd);
|
||||
|
||||
|
||||
// if you use this then include swell-appstub.mm in your project
|
||||
#define SWELL_APPAPI_DELEGATE_IMPL \
|
||||
-(void *)swellGetAPPAPIFunc { \
|
||||
void *SWELLAPI_GetFunc(const char *name); \
|
||||
return (void*)SWELLAPI_GetFunc; \
|
||||
}
|
||||
|
||||
#endif // _WDL_SWELL_H_UTIL_DEFINED_
|
||||
#endif // !SWELL_PROVIDED_BY_APP
|
||||
|
||||
#endif // !_WIN32
|
||||
|
||||
|
||||
#ifndef SWELL_TARGET_OSX
|
||||
|
||||
#ifndef SWELL_CB_InsertString
|
||||
|
||||
#define SWELL_CB_InsertString(hwnd, idx, pos, str) ((int)SendDlgItemMessage(hwnd,idx,CB_INSERTSTRING,(pos),(LPARAM)(str)))
|
||||
#define SWELL_CB_AddString(hwnd, idx, str) ((int)SendDlgItemMessage(hwnd,idx,CB_ADDSTRING,0,(LPARAM)(str)))
|
||||
#define SWELL_CB_SetCurSel(hwnd,idx,val) ((int)SendDlgItemMessage(hwnd,idx,CB_SETCURSEL,(WPARAM)(val),0))
|
||||
#define SWELL_CB_GetNumItems(hwnd,idx) ((int)SendDlgItemMessage(hwnd,idx,CB_GETCOUNT,0,0))
|
||||
#define SWELL_CB_GetCurSel(hwnd,idx) ((int)SendDlgItemMessage(hwnd,idx,CB_GETCURSEL,0,0))
|
||||
#define SWELL_CB_SetItemData(hwnd,idx,item,val) SendDlgItemMessage(hwnd,idx,CB_SETITEMDATA,(item),(val))
|
||||
#define SWELL_CB_GetItemData(hwnd,idx,item) SendDlgItemMessage(hwnd,idx,CB_GETITEMDATA,(item),0)
|
||||
#define SWELL_CB_GetItemText(hwnd,idx,item,buf,bufsz) SendDlgItemMessage(hwnd,idx,CB_GETLBTEXT,(item),(LPARAM)(buf))
|
||||
#define SWELL_CB_Empty(hwnd,idx) SendDlgItemMessage(hwnd,idx,CB_RESETCONTENT,0,0)
|
||||
#define SWELL_CB_DeleteString(hwnd,idx,str) SendDlgItemMessage(hwnd,idx,CB_DELETESTRING,str,0)
|
||||
|
||||
#define SWELL_TB_SetPos(hwnd, idx, pos) SendDlgItemMessage(hwnd,idx, TBM_SETPOS,TRUE,(pos))
|
||||
#define SWELL_TB_SetRange(hwnd, idx, low, hi) SendDlgItemMessage(hwnd,idx,TBM_SETRANGE,TRUE,(LPARAM)MAKELONG((low),(hi)))
|
||||
#define SWELL_TB_GetPos(hwnd, idx) ((int)SendDlgItemMessage(hwnd,idx,TBM_GETPOS,0,0))
|
||||
#define SWELL_TB_SetTic(hwnd, idx, pos) SendDlgItemMessage(hwnd,idx,TBM_SETTIC,0,(pos))
|
||||
|
||||
#endif
|
||||
|
||||
#endif// !SWELL_TARGET_OSX
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef WDL_GDP_CTX // stupid GDP compatibility layer, deprecated
|
||||
|
||||
|
||||
#define WDL_GDP_CTX HDC
|
||||
#define WDL_GDP_PEN HPEN
|
||||
#define WDL_GDP_BRUSH HBRUSH
|
||||
#define WDL_GDP_CreatePen(col, wid) (WDL_GDP_PEN)CreatePen(PS_SOLID,(wid),(col))
|
||||
#define WDL_GDP_DeletePen(pen) DeleteObject((HGDIOBJ)(pen))
|
||||
#define WDL_GDP_SetPen(ctx, pen) ((WDL_GDP_PEN)SelectObject(ctx,(HGDIOBJ)(pen)))
|
||||
#define WDL_GDP_SetBrush(ctx, brush) ((WDL_GDP_BRUSH)SelectObject(ctx,(HGDIOBJ)(brush)))
|
||||
#define WDL_GDP_CreateBrush(col) (WDL_GDP_BRUSH)CreateSolidBrush(col)
|
||||
#define WDL_GDP_DeleteBrush(brush) DeleteObject((HGDIOBJ)(brush))
|
||||
#define WDL_GDP_FillRectWithBrush(hdc,r,br) FillRect(hdc,r,(HBRUSH)(br))
|
||||
#define WDL_GDP_Rectangle(hdc,l,t,r,b) Rectangle(hdc,l,t,r,b)
|
||||
#define WDL_GDP_Polygon(hdc,pts,n) Polygon(hdc,pts,n)
|
||||
#define WDL_GDP_MoveToEx(hdc,x,y,op) MoveToEx(hdc,x,y,op)
|
||||
#define WDL_GDP_LineTo(hdc,x,y) LineTo(hdc,x,y)
|
||||
#define WDL_GDP_PutPixel(hdc,x,y,c) SetPixel(hdc,x,y,c)
|
||||
#define WDL_GDP_PolyBezierTo(hdc,p,np) PolyBezierTo(hdc,p,np)
|
||||
|
||||
#define SWELL_SyncCtxFrameBuffer(x) // no longer used
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(SWELL_AUTORELEASE_HELPER_DEFINED) && defined(__cplusplus) && (!defined(SWELL_TARGET_OSX) || defined(SWELL_API_DEFINE))
|
||||
#define SWELL_AUTORELEASE_HELPER_DEFINED
|
||||
|
||||
class SWELL_AutoReleaseHelper // no-op on non-apple
|
||||
{
|
||||
#ifdef SWELL_TARGET_OSX
|
||||
void *m_arp;
|
||||
#endif
|
||||
public:
|
||||
SWELL_AutoReleaseHelper()
|
||||
{
|
||||
#ifdef SWELL_TARGET_OSX
|
||||
m_arp = SWELL_InitAutoRelease();
|
||||
#endif
|
||||
}
|
||||
~SWELL_AutoReleaseHelper()
|
||||
{
|
||||
#ifdef SWELL_TARGET_OSX
|
||||
release();
|
||||
#endif
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
#ifdef SWELL_TARGET_OSX
|
||||
if (m_arp) { SWELL_QuitAutoRelease(m_arp); m_arp=NULL; }
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(LoadLibraryGlobals)
|
||||
#define LoadLibraryGlobals(a,b) LoadLibrary(a)
|
||||
#endif
|
||||
|
||||
#ifndef SWELLAPP_ONLOAD
|
||||
|
||||
#define SWELLAPP_ONLOAD 0x0001 // initialization of app vars etc
|
||||
#define SWELLAPP_LOADED 0x0002 // create dialogs etc
|
||||
#define SWELLAPP_DESTROY 0x0003 // about to destroy (cleanup etc)
|
||||
#define SWELLAPP_SHOULDDESTROY 0x0004 // return 0 to allow app to terminate, >0 to prevent
|
||||
|
||||
#define SWELLAPP_OPENFILE 0x0050 // parm1= (const char *)string, return >0 if allowed
|
||||
#define SWELLAPP_NEWFILE 0x0051 // new file, return >0 if allowed
|
||||
#define SWELLAPP_SHOULDOPENNEWFILE 0x0052 // allow opening new file? >0 if allowed
|
||||
|
||||
#define SWELLAPP_ONCOMMAND 0x0099 // parm1 = (int) command ID, parm2 = (id) sender
|
||||
#define SWELLAPP_PROCESSMESSAGE 0x0100 // parm1=(MSG *)msg (loosely), parm2= (NSEvent *) the event . return >0 to eat
|
||||
|
||||
#define SWELLAPP_ACTIVATE 0x1000 // parm1 = (bool) isactive. return nonzero to prevent WM_ACTIVATEAPP from being broadcasted
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,355 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
if (!function_exists('file_put_contents')) {
|
||||
function file_put_contents($filename, $data, $lockflag) {
|
||||
$f = @fopen($filename, 'w');
|
||||
if (!$f) {
|
||||
return false;
|
||||
} else {
|
||||
$bytes = fwrite($f, $data);
|
||||
fclose($f);
|
||||
return $bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function convertquotes($in)
|
||||
{
|
||||
$ret = "";
|
||||
$qs= 0;
|
||||
for ($x=0;$x<strlen($in); $x++)
|
||||
{
|
||||
if ($in[$x] == '"')
|
||||
{
|
||||
if (!$qs)
|
||||
{
|
||||
$qs=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$qs=0;
|
||||
if ($x < strlen($in) && $in[$x+1] == '"')
|
||||
{
|
||||
$ret .= "\\";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$ret .= $in[$x];
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function utf_fgets($fp, &$state)
|
||||
{
|
||||
if ($state==0)
|
||||
{
|
||||
$state = -1;
|
||||
$s = fread($fp,2);
|
||||
if (ord($s[0])==0xff && ord($s[1]) == 0xfe) $state=1; // UTF-16LE
|
||||
else if (ord($s[0])==0xfe && ord($s[1]) == 0xff) $state=2; // UTF-16BE
|
||||
else if (ord($s[0])==0xef && ord($s[1]) == 0xbb)
|
||||
{
|
||||
$s2 = fread($fp,1);
|
||||
if (ord($s2[0]) != 0xbf) return $s . $s2 . fgets($fp,4096);
|
||||
}
|
||||
}
|
||||
if ($state < 0) return fgets($fp,4096);
|
||||
|
||||
$ret = "";
|
||||
while ($s = fread($fp,2))
|
||||
{
|
||||
if ($state == 1) $s = ord($s[0]) | (ord($s[1])<<8);
|
||||
else $s = ord($s[1]) | (ord($s[0])<<8);
|
||||
if ($s < 128)
|
||||
{
|
||||
$ret .= chr($s);
|
||||
if ($s == ord("\n")) break;
|
||||
}
|
||||
else if ($s <= 0x7ff) $ret .= chr(0xc0 | (($s>>6)&0x1f)) . chr(0x80 | ($s&0x3f));
|
||||
else $ret .= chr(0xe0 | (($s>>12)&0xf)) . chr(0x80 | (($s)>>6)&0x3f) . chr(0x80 | ($s&0x3f));
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function swell_rc2cpp_dialog($fp) // returns array with ["data"] and optionally ["error"]
|
||||
{
|
||||
fseek($fp,0,SEEK_SET);
|
||||
$utf_state=0;
|
||||
$errstr="";
|
||||
$retstr = "";
|
||||
|
||||
$retstr .= '#ifndef SWELL_DLG_FLAGS_AUTOGEN' . "\n";
|
||||
$retstr .= '#define SWELL_DLG_FLAGS_AUTOGEN SWELL_DLG_WS_FLIPPED|SWELL_DLG_WS_NOAUTOSIZE' . "\n";
|
||||
$retstr .= "#endif\n";
|
||||
$retstr .= "\n";
|
||||
|
||||
$dlg_state=0; // 1 = before BEGIN, 2=after BEGIN
|
||||
|
||||
$dlg_name="";
|
||||
$dlg_size_w=0;
|
||||
$dlg_size_h=0;
|
||||
$dlg_title = "";
|
||||
$dlg_styles = "SWELL_DLG_FLAGS_AUTOGEN";
|
||||
$dlg_contents="";
|
||||
|
||||
$next_line="";
|
||||
for (;;)
|
||||
{
|
||||
if ($next_line != "") { $x=$next_line; $next_line =""; }
|
||||
else if (!($x=utf_fgets($fp,$utf_state))) break;
|
||||
$x = convertquotes($x);
|
||||
|
||||
$y=trim($x);
|
||||
if ($dlg_state>=2)
|
||||
{
|
||||
if (preg_match("/^LTEXT(.*), *WS_EX_RIGHT$/",$y,$match)) $y = "RTEXT" . $match[1];
|
||||
$dlg_contents .= $y . "\n";
|
||||
if ($y == "END")
|
||||
{
|
||||
if ($dlg_state==2) $dlg_styles.="|SWELL_DLG_WS_OPAQUE";
|
||||
$retstr .= "#ifndef SET_$dlg_name" . "_STYLE\n";
|
||||
$retstr .= "#define SET_$dlg_name" . "_STYLE $dlg_styles\n";
|
||||
$retstr .= "#endif\n";
|
||||
$retstr .= "#ifdef SET_$dlg_name" . "_SCALE\n";
|
||||
$retstr .= "SWELL_DEFINE_DIALOG_RESOURCE_BEGIN($dlg_name,SET_$dlg_name" . "_STYLE,\"$dlg_title\",$dlg_size_w,$dlg_size_h,SET_$dlg_name" . "_SCALE)\n";
|
||||
$retstr .= "#else\n";
|
||||
$retstr .= "SWELL_DEFINE_DIALOG_RESOURCE_BEGIN2($dlg_name,SET_$dlg_name" . "_STYLE,\"$dlg_title\",$dlg_size_w,$dlg_size_h)\n";
|
||||
$retstr .= "#endif\n";
|
||||
$dlg_contents=str_replace("NOT WS_VISIBLE","SWELL_NOT_WS_VISIBLE",$dlg_contents);
|
||||
$dlg_contents=str_replace("NOT\nWS_VISIBLE","SWELL_NOT_WS_VISIBLE",$dlg_contents);
|
||||
$dlg_contents=str_replace("NOT \nWS_VISIBLE","SWELL_NOT_WS_VISIBLE",$dlg_contents);
|
||||
$retstr .= $dlg_contents;
|
||||
$retstr .= "#ifdef SET_$dlg_name" . "_SCALE\n";
|
||||
$retstr .= "SWELL_DEFINE_DIALOG_RESOURCE_END($dlg_name)\n";
|
||||
$retstr .= "#else\n";
|
||||
$retstr .= "SWELL_DEFINE_DIALOG_RESOURCE_END2($dlg_name)\n";
|
||||
$retstr .= "#endif\n\n\n";
|
||||
$dlg_state=0;
|
||||
}
|
||||
else if (strlen($y)>1) $dlg_state=3;
|
||||
}
|
||||
else
|
||||
{
|
||||
$parms = explode(" ", $y);
|
||||
if (count($parms) > 0)
|
||||
{
|
||||
if ($dlg_state == 0)
|
||||
{
|
||||
// if (substr($parms[0],0,8) == "IDD_PREF")
|
||||
if (count($parms)>4 && ($parms[1] == 'DIALOGEX'||$parms[1] == 'DIALOG'))
|
||||
{
|
||||
$dlg_name=$parms[0];
|
||||
$rdidx = 2;
|
||||
if ($parms[$rdidx] == 'DISCARDABLE') $rdidx++;
|
||||
while ($parms[$rdidx] == "" && $rdidx < count($parms)) $rdidx++;
|
||||
$rdidx += 2;
|
||||
$dlg_size_w = str_replace(",","",$parms[$rdidx++]);
|
||||
$dlg_size_h = str_replace(",","",$parms[$rdidx++]);
|
||||
if (count($parms) >= $rdidx && $dlg_size_w != "" && $dlg_size_h != "")
|
||||
{
|
||||
$dlg_title="";
|
||||
$dlg_styles="SWELL_DLG_FLAGS_AUTOGEN";
|
||||
$dlg_contents="";
|
||||
$dlg_state=1;
|
||||
}
|
||||
else $errstr .= "WARNING: corrupted $dlg_name resource\n";
|
||||
}
|
||||
}
|
||||
else if ($dlg_state == 1)
|
||||
{
|
||||
if ($parms[0] == "BEGIN")
|
||||
{
|
||||
$dlg_state=2;
|
||||
$dlg_contents = $y ."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($parms[0] == "CAPTION")
|
||||
{
|
||||
$dlg_title = str_replace("\"","",trim(substr($y,8)));
|
||||
}
|
||||
else if ($parms[0] == "STYLE" || $parms[0] == "EXSTYLE")
|
||||
{
|
||||
$rep=0;
|
||||
for (;;)
|
||||
{
|
||||
$next_line = utf_fgets($fp,$utf_state);
|
||||
if (!($next_line )) { $next_line=""; break; }
|
||||
if (substr($next_line,0,1)==" " || substr($next_line,0,1)=="\t")
|
||||
{
|
||||
$y .= " " . trim(convertquotes($next_line));
|
||||
$rep++;
|
||||
$next_line="";
|
||||
}
|
||||
else break;
|
||||
}
|
||||
if ($rep) $parms = explode(" ", $y);
|
||||
$opmode=0;
|
||||
$rdidx=1;
|
||||
while ($rdidx < count($parms))
|
||||
{
|
||||
if ($parms[$rdidx] == '|') { $opmode=0; }
|
||||
else if ($parms[$rdidx] == 'NOT') { $opmode=1; }
|
||||
else if ($parms[$rdidx] == 'WS_CHILD')
|
||||
{
|
||||
if (!$opmode) $dlg_styles .= "|SWELL_DLG_WS_CHILD";
|
||||
}
|
||||
else if ($parms[$rdidx] == 'WS_THICKFRAME')
|
||||
{
|
||||
if (!$opmode) $dlg_styles .= "|SWELL_DLG_WS_RESIZABLE";
|
||||
}
|
||||
else if ($parms[$rdidx] == 'WS_EX_ACCEPTFILES')
|
||||
{
|
||||
if (!$opmode) $dlg_styles .= "|SWELL_DLG_WS_DROPTARGET";
|
||||
}
|
||||
else if ($parms[$rdidx] == 'WS_CLIPSIBLINGS')
|
||||
{
|
||||
if (!$opmode) $dlg_styles .= "|WS_CLIPSIBLINGS";
|
||||
}
|
||||
else $opmode=0;
|
||||
$rdidx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($dlg_state != 0)
|
||||
$errstr .= "WARNING: there may have been a truncated dialog resource ($dlg_name)\n";
|
||||
|
||||
$retstr .= "\n//EOF\n\n";
|
||||
$rv = array();
|
||||
$rv["data"] = $retstr;
|
||||
$rv["error"] = $errstr;
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function swell_rc2cpp_menu($fp) // returns array with ["data"] and optionally ["error"]
|
||||
{
|
||||
$retstr="";
|
||||
$errstr="";
|
||||
|
||||
fseek($fp,0,SEEK_SET);
|
||||
$utf_state=0;
|
||||
|
||||
$menu_symbol="";
|
||||
$menu_depth=0;
|
||||
while (($x=utf_fgets($fp,$utf_state)))
|
||||
{
|
||||
$x = convertquotes($x);
|
||||
|
||||
$y=trim($x);
|
||||
if ($menu_symbol == "")
|
||||
{
|
||||
$parms = explode(" ", $y);
|
||||
$tok = "MENU";
|
||||
if (count($parms) >= 2 && $parms[1] == $tok)
|
||||
{
|
||||
$menu_symbol = $parms[0];
|
||||
$menu_depth=0;
|
||||
$retstr .= "SWELL_DEFINE_MENU_RESOURCE_BEGIN($menu_symbol)\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($y == "END")
|
||||
{
|
||||
$menu_depth-=1;
|
||||
if ($menu_depth == 0)
|
||||
{
|
||||
$retstr .= "SWELL_DEFINE_MENU_RESOURCE_END($menu_symbol)\n\n\n";
|
||||
}
|
||||
if ($menu_depth < 1) $menu_symbol="";
|
||||
}
|
||||
if ($menu_depth>0)
|
||||
{
|
||||
if (substr($y,-strlen(", HELP")) == ", HELP")
|
||||
{
|
||||
$x=substr(rtrim($x),0,-strlen(", HELP")) . "\n";
|
||||
}
|
||||
$retstr .= $x;
|
||||
}
|
||||
if ($y == "BEGIN") $menu_depth+=1;
|
||||
}
|
||||
}
|
||||
|
||||
$retstr .= "\n//EOF\n\n";
|
||||
$rv = array();
|
||||
$rv["data"] = $retstr;
|
||||
$rv["error"] = $errstr;
|
||||
|
||||
return $rv;
|
||||
}
|
||||
|
||||
if (count($argv)<2) die("usage: swell_resgen.php [--force] file.rc ...\n");
|
||||
|
||||
$x=1;
|
||||
$forcemode = 0;
|
||||
if ($argv[$x] == "--force") { $forcemode=1; $x++; }
|
||||
|
||||
$lp = dirname(__FILE__);
|
||||
$proc=0;
|
||||
$skipped=0;
|
||||
$err=0;
|
||||
$quiet=0;
|
||||
for (; $x < count($argv); $x ++)
|
||||
{
|
||||
$srcfn = $argv[$x];
|
||||
if ($srcfn == "--quiet")
|
||||
{
|
||||
$quiet = 1;
|
||||
continue;
|
||||
}
|
||||
if (!stristr($srcfn,".rc") || !($fp = @fopen($srcfn,"r")))
|
||||
{
|
||||
$err++;
|
||||
echo "$srcfn: not valid or not found!\n";
|
||||
continue;
|
||||
}
|
||||
$ofnmenu = $srcfn . "_mac_menu";
|
||||
$ofndlg = $srcfn . "_mac_dlg";
|
||||
|
||||
$res = swell_rc2cpp_dialog($fp);
|
||||
$res2 = swell_rc2cpp_menu($fp);
|
||||
fclose($fp);
|
||||
if ($res["error"] != "" || $res2["error"] != "")
|
||||
{
|
||||
$err++;
|
||||
echo "$srcfn: error";
|
||||
if ($res["error"] != "") echo " dialog: " . $res["error"];
|
||||
if ($res2["error"] != "") echo " menu: " . $res2["error"];
|
||||
echo "\n";
|
||||
continue;
|
||||
}
|
||||
$f="";
|
||||
if ($forcemode || !file_exists($ofndlg) || file_get_contents($ofndlg) != $res["data"])
|
||||
{
|
||||
$f .= "dlg updated";
|
||||
if (!file_put_contents($ofndlg,$res["data"],LOCK_EX)) { echo "error writing $ofndlg\n"; $err++; }
|
||||
}
|
||||
if ($forcemode || !file_exists($ofnmenu) || file_get_contents($ofnmenu) != $res2["data"])
|
||||
{
|
||||
if ($f != "") $f .= ", ";
|
||||
$f .= "menu updated";
|
||||
if (!file_put_contents($ofnmenu,$res2["data"],LOCK_EX)) { echo "error writing $ofnmenu\n"; $err++; }
|
||||
}
|
||||
|
||||
if ($f != "")
|
||||
{
|
||||
$proc++;
|
||||
}
|
||||
else
|
||||
{
|
||||
$skipped++;
|
||||
$f = "skipped";
|
||||
}
|
||||
|
||||
if (!$quiet) echo "$srcfn: $f\n";
|
||||
}
|
||||
if (!$quiet || $err) echo "processed $proc, skipped $skipped, error $err\n";
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,359 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use Fcntl qw(:seek :flock);
|
||||
|
||||
my @input;
|
||||
my %style_xlate = (
|
||||
"WS_CHILD" => "SWELL_DLG_WS_CHILD",
|
||||
"WS_THICKFRAME" => "SWELL_DLG_WS_RESIZABLE",
|
||||
"WS_EX_ACCEPTFILES" => "SWELL_DLG_WS_DROPTARGET",
|
||||
"WS_CLIPSIBLINGS" => "WS_CLIPSIBLINGS",
|
||||
);
|
||||
|
||||
sub update_file {
|
||||
my($fn, $force, $data) = @_;
|
||||
|
||||
open(FPC_FH, '+>>', $fn) or return $!;
|
||||
if (!flock(FPC_FH, LOCK_EX)) {
|
||||
close(FPC_FH);
|
||||
return "error locking file";
|
||||
}
|
||||
seek FPC_FH, 0, SEEK_SET;
|
||||
|
||||
if ($force == 0)
|
||||
{
|
||||
my $v = "";
|
||||
while (<FPC_FH>) { $v .= $_; }
|
||||
if ($v eq $data) {
|
||||
close(FPC_FH);
|
||||
return "";
|
||||
}
|
||||
seek FPC_FH, 0, SEEK_SET;
|
||||
}
|
||||
truncate FPC_FH, 0;
|
||||
print FPC_FH $data;
|
||||
flock(FPC_FH, LOCK_UN);
|
||||
close(FPC_FH);
|
||||
return "OK";
|
||||
}
|
||||
|
||||
sub convertquotes {
|
||||
return $_[0] unless $_[0] =~ /"/;
|
||||
my @a = split(/"/,$_[0], -1);
|
||||
my $ret = $a[0];
|
||||
my $qs = 0;
|
||||
for (my $x=1;$x<@a; $x++) {
|
||||
my $s = $a[$x];
|
||||
if ($s eq "" && $qs && $x+1 < @a) {
|
||||
$ret .= '\\"' . $a[++$x];
|
||||
} else {
|
||||
$ret .= "\"$s";
|
||||
$qs = !$qs;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub swell_rc2cpp_dialog
|
||||
{
|
||||
my $errstr = "";
|
||||
my $retstr = '#ifndef SWELL_DLG_FLAGS_AUTOGEN
|
||||
#define SWELL_DLG_FLAGS_AUTOGEN SWELL_DLG_WS_FLIPPED|SWELL_DLG_WS_NOAUTOSIZE
|
||||
#endif
|
||||
|
||||
';
|
||||
|
||||
my $dlg_state=0; # 1 = before BEGIN, 2=after BEGIN
|
||||
|
||||
my $dlg_name="";
|
||||
my $dlg_size_w=0;
|
||||
my $dlg_size_h=0;
|
||||
my $dlg_title = "";
|
||||
my $dlg_styles = "SWELL_DLG_FLAGS_AUTOGEN";
|
||||
my $dlg_contents="";
|
||||
|
||||
for (my $idx = 0; $idx < @input; $idx++)
|
||||
{
|
||||
my $x = $input[$idx];
|
||||
|
||||
(my $y = $x) =~ s/^\s+|\s+$//g;
|
||||
if ($dlg_state>=2)
|
||||
{
|
||||
$y = "RTEXT" . $1 if $y =~ /^LTEXT(.*), *WS_EX_RIGHT$/;
|
||||
if ($dlg_contents =~ /, *\n$/)
|
||||
{
|
||||
$dlg_contents =~ s/ *\n$//;
|
||||
}
|
||||
elsif ($dlg_contents =~ /[|] *\n$/)
|
||||
{
|
||||
$dlg_contents =~ s/ *\n$/ /;
|
||||
}
|
||||
elsif ($dlg_contents =~ /NOT *\n$/)
|
||||
{
|
||||
$dlg_contents =~ s/NOT *\n$/NOT /;
|
||||
}
|
||||
$dlg_contents .= $y . "\n";
|
||||
if ($y eq "END")
|
||||
{
|
||||
if ($dlg_state==2) { $dlg_styles.="|SWELL_DLG_WS_OPAQUE" };
|
||||
$retstr .= "#ifndef SET_${dlg_name}_STYLE\n" .
|
||||
"#define SET_${dlg_name}_STYLE $dlg_styles\n" .
|
||||
"#endif\n" .
|
||||
"#ifdef SET_${dlg_name}_SCALE\n" .
|
||||
"SWELL_DEFINE_DIALOG_RESOURCE_BEGIN($dlg_name,SET_${dlg_name}_STYLE,\"$dlg_title\",$dlg_size_w,$dlg_size_h,SET_${dlg_name}_SCALE)\n" .
|
||||
"#else\n" .
|
||||
"SWELL_DEFINE_DIALOG_RESOURCE_BEGIN2($dlg_name,SET_${dlg_name}_STYLE,\"$dlg_title\",$dlg_size_w,$dlg_size_h)\n" .
|
||||
"#endif\n";
|
||||
|
||||
$dlg_contents =~ s/NOT\s+WS_VISIBLE/SWELL_NOT_WS_VISIBLE/gs;
|
||||
$retstr .= $dlg_contents;
|
||||
$retstr .= "#ifdef SET_${dlg_name}_SCALE\n";
|
||||
$retstr .= "SWELL_DEFINE_DIALOG_RESOURCE_END($dlg_name)\n";
|
||||
$retstr .= "#else\n";
|
||||
$retstr .= "SWELL_DEFINE_DIALOG_RESOURCE_END2($dlg_name)\n";
|
||||
$retstr .= "#endif\n\n\n";
|
||||
$dlg_state=0;
|
||||
}
|
||||
elsif (length($y)>1) { $dlg_state=3; }
|
||||
}
|
||||
else
|
||||
{
|
||||
my @parms = split " ", $y;
|
||||
if (@parms > 0)
|
||||
{
|
||||
if ($dlg_state == 0)
|
||||
{
|
||||
if (@parms>4 && ($parms[1] eq "DIALOGEX" || $parms[1] eq "DIALOG"))
|
||||
{
|
||||
$dlg_name=$parms[0];
|
||||
my $rdidx = 2;
|
||||
if ($parms[$rdidx] eq 'DISCARDABLE') { $rdidx++ };
|
||||
while ($rdidx < @parms && $parms[$rdidx] eq "") { $rdidx++; }
|
||||
$rdidx += 2;
|
||||
($dlg_size_w = $parms[$rdidx++]) =~ s/,//g;
|
||||
($dlg_size_h = $parms[$rdidx++]) =~ s/,//g;
|
||||
if (@parms >= $rdidx && $dlg_size_w ne "" && $dlg_size_h ne "")
|
||||
{
|
||||
$dlg_title="";
|
||||
$dlg_styles="SWELL_DLG_FLAGS_AUTOGEN";
|
||||
$dlg_contents="";
|
||||
$dlg_state=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$errstr .= "WARNING: corrupted $dlg_name resource\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif ($dlg_state == 1)
|
||||
{
|
||||
if ($parms[0] eq "BEGIN")
|
||||
{
|
||||
$dlg_state=2;
|
||||
$dlg_contents = $y ."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($parms[0] eq "CAPTION")
|
||||
{
|
||||
$dlg_title = substr $y, 8;
|
||||
$dlg_title =~ s/^\s+|\s+$|"//g;
|
||||
}
|
||||
elsif ($parms[0] eq "STYLE" || $parms[0] eq "EXSTYLE")
|
||||
{
|
||||
my $rep=0;
|
||||
for (;($idx+1) < @input; $idx++)
|
||||
{
|
||||
my $next_line = $input[$idx+1];
|
||||
last unless $next_line =~ /^[ \t]/;
|
||||
|
||||
$next_line =~ s/^\s+|\s+$//g;
|
||||
$y .= " " . $next_line;
|
||||
$rep++;
|
||||
}
|
||||
@parms = split " ", $y if $rep;
|
||||
my $opmode=0;
|
||||
for (my $rdidx = 1; $rdidx < @parms; $rdidx ++)
|
||||
{
|
||||
if ($parms[$rdidx] eq "NOT") { $opmode=1; }
|
||||
elsif ($opmode == 0)
|
||||
{
|
||||
my $s = $style_xlate{$parms[$rdidx]};
|
||||
$dlg_styles .= "|$s" if defined($s);
|
||||
}
|
||||
else { $opmode=0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$errstr .= "WARNING: there may have been a truncated dialog resource ($dlg_name)\n" if $dlg_state != 0;
|
||||
|
||||
$retstr .= "\n//EOF\n\n";
|
||||
return ( $retstr, $errstr );
|
||||
}
|
||||
|
||||
sub swell_rc2cpp_menu
|
||||
{
|
||||
my $retstr="";
|
||||
my $errstr="";
|
||||
|
||||
my $menu_symbol="";
|
||||
my $menu_depth=0;
|
||||
for (@input)
|
||||
{
|
||||
my $x = $_;
|
||||
(my $y = $x) =~ s/^\s+|\s+$//g;
|
||||
|
||||
if ($menu_symbol eq "")
|
||||
{
|
||||
my @parms = split " ", $y;
|
||||
if (@parms >= 2 && $parms[1] eq "MENU")
|
||||
{
|
||||
$menu_symbol = $parms[0];
|
||||
$menu_depth=0;
|
||||
$retstr .= "SWELL_DEFINE_MENU_RESOURCE_BEGIN($menu_symbol)\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($y eq "END")
|
||||
{
|
||||
$menu_depth-=1;
|
||||
if ($menu_depth == 0)
|
||||
{
|
||||
$retstr .= "SWELL_DEFINE_MENU_RESOURCE_END($menu_symbol)\n\n\n";
|
||||
}
|
||||
$menu_symbol="" if $menu_depth < 1;
|
||||
}
|
||||
|
||||
if ($menu_depth>0)
|
||||
{
|
||||
if (($retstr =~ /,\s*$/) || ($x =~ /^\s*,/)) {
|
||||
$retstr =~ s/\s*\n$//;
|
||||
$x =~ s/^\s*//;
|
||||
}
|
||||
|
||||
$x =~ s/, HELP\s*/\n/;
|
||||
$retstr .= $x;
|
||||
}
|
||||
$menu_depth+=1 if $y eq "BEGIN";
|
||||
}
|
||||
}
|
||||
|
||||
$retstr .= "\n//EOF\n\n";
|
||||
|
||||
return ($retstr, $errstr);
|
||||
}
|
||||
|
||||
die("usage: swell_resgen.pl [--force] file.rc ...\n") if @ARGV<1;
|
||||
|
||||
my $forcemode = 0;
|
||||
my $proc=0;
|
||||
my $skipped=0;
|
||||
my $err=0;
|
||||
my $quiet=0;
|
||||
for (my $x = 0; $x < @ARGV; $x ++)
|
||||
{
|
||||
my $srcfn = $ARGV[$x];
|
||||
if ($srcfn eq "--quiet")
|
||||
{
|
||||
$quiet = 1;
|
||||
next;
|
||||
}
|
||||
if ($srcfn eq "--force")
|
||||
{
|
||||
$forcemode = 1;
|
||||
next;
|
||||
}
|
||||
if (!($srcfn =~ /[.]rc$/i))
|
||||
{
|
||||
$err++;
|
||||
print "$srcfn: does not end in .rc!\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if (!open(UTF_FH, "<", $srcfn))
|
||||
{
|
||||
$err++;
|
||||
print "$srcfn: could not open!\n";
|
||||
continue;
|
||||
}
|
||||
$_ = <UTF_FH>;
|
||||
if (/^\xff\xfe/ || /^\xfe\xff/) {
|
||||
@input = ( );
|
||||
my $order = (ord($_) == 0xff) ? 0 : 1;
|
||||
seek UTF_FH, 2, SEEK_SET;
|
||||
|
||||
my $ret = "";
|
||||
while (read UTF_FH, my $s, 2)
|
||||
{
|
||||
$s = ($order == 1) ? (ord($s) | (ord(substr($s,1))<<8)) : (ord(substr($s,1)) | (ord($s)<<8));
|
||||
if ($s < 128) {
|
||||
$ret .= chr($s);
|
||||
if ($s == ord("\n")) {
|
||||
push(@input,convertquotes($ret));
|
||||
$ret = "";
|
||||
}
|
||||
}
|
||||
elsif ($s <= 0x7ff) {
|
||||
$ret .= chr(0xc0 | (($s>>6)&0x1f)) . chr(0x80 | ($s&0x3f));
|
||||
}
|
||||
else {
|
||||
$ret .= chr(0xe0 | (($s>>12)&0xf)) . chr(0x80 | (($s)>>6)&0x3f) . chr(0x80 | ($s&0x3f));
|
||||
}
|
||||
}
|
||||
push(@input,convertquotes($ret)) if $ret ne "";
|
||||
} else {
|
||||
$_ = substr($_,3) if /^\xef\xbb\xbf/;
|
||||
@input = ( $_ );
|
||||
while (<UTF_FH>) {
|
||||
push @input, convertquotes($_);
|
||||
}
|
||||
}
|
||||
|
||||
close(UTF_FH);
|
||||
|
||||
my $ofnmenu = $srcfn . "_mac_menu";
|
||||
my $ofndlg = $srcfn . "_mac_dlg";
|
||||
|
||||
my ($dlg_str, $dlg_err) = swell_rc2cpp_dialog();
|
||||
my ($menu_str, $menu_err) = swell_rc2cpp_menu();
|
||||
|
||||
if ($dlg_err ne "" || $menu_err ne "")
|
||||
{
|
||||
$err++;
|
||||
print "$srcfn: error";
|
||||
print " dialog: $dlg_err" if $dlg_err ne "";
|
||||
print " menu: $menu_err" if $menu_err ne "";
|
||||
print "\n";
|
||||
continue;
|
||||
}
|
||||
my $f="";
|
||||
my $ok = update_file($ofndlg, $forcemode, $dlg_str);
|
||||
$f .= ", dlg updated" if $ok eq "OK";
|
||||
if ($ok ne "OK" && $ok ne "") { print "error writing $ofndlg: $ok\n"; $err++; }
|
||||
|
||||
$ok = update_file($ofnmenu, $forcemode, $menu_str);
|
||||
$f .= ", menu updated" if $ok eq "OK";
|
||||
if ($ok ne "OK" && $ok ne "") { print "error writing $ofnmenu: $ok\n"; $err++; }
|
||||
|
||||
if ($f ne "")
|
||||
{
|
||||
$f =~ s/^, //;
|
||||
$proc++;
|
||||
}
|
||||
else
|
||||
{
|
||||
$skipped++;
|
||||
$f = "skipped";
|
||||
}
|
||||
|
||||
print "$srcfn: $f\n" if $quiet == 0;
|
||||
}
|
||||
|
||||
print "processed $proc, skipped $skipped, error $err\n" if $quiet==0 || $err>0;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
DIR="$(dirname $0)"
|
||||
if [ "v$DIR" = "v" ]; then DIR=. ; fi
|
||||
|
||||
"$DIR/swell_resgen.pl" $*
|
||||
@@ -0,0 +1,14 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface SWELLApplication : NSApplication {
|
||||
|
||||
}
|
||||
- (void)sendEvent:(NSEvent *)anEvent;
|
||||
|
||||
@end
|
||||
|
||||
@interface SWELLAppController : NSObject {
|
||||
}
|
||||
-(IBAction)onSysMenuCommand:(id)sender;
|
||||
@end
|
||||
@@ -0,0 +1,252 @@
|
||||
/* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
|
||||
Copyright (C) 2006 and later, Cockos, Inc.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#import "swellappmain.h"
|
||||
|
||||
#include "swell.h"
|
||||
#include "swell-internal.h"
|
||||
|
||||
|
||||
HMENU SWELL_app_stocksysmenu; // exposed to app, simply the contents of the default system menu (as defined in the nib)
|
||||
static bool IsMultiLineEditControl(NSView *cv, id fs)
|
||||
{
|
||||
if (fs && [fs isKindOfClass:[NSTextView class]])
|
||||
{
|
||||
NSTextView *v = (NSTextView *)fs;
|
||||
if ([v isEditable])
|
||||
{
|
||||
NSView *a=[v superview];
|
||||
while (a && a != cv)
|
||||
{
|
||||
if ([a isKindOfClass:[NSTextField class]]) return false;
|
||||
a = [a superview];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@implementation SWELLApplication
|
||||
- (void)sendEvent:(NSEvent *)anEvent
|
||||
{
|
||||
NSEventType etype = [anEvent type];
|
||||
if (etype == NSKeyUp)
|
||||
{
|
||||
// toss keyup if next keydown is the same key
|
||||
NSEvent *nextDown = [self nextEventMatchingMask:NSKeyDownMask untilDate:[NSDate dateWithTimeIntervalSinceNow:0.003] inMode:NSDefaultRunLoopMode dequeue:FALSE];
|
||||
if (nextDown && [nextDown keyCode] == [anEvent keyCode]) return;
|
||||
}
|
||||
else if (etype == NSKeyDown)
|
||||
{
|
||||
NSEvent *nextDown = [self nextEventMatchingMask:NSKeyDownMask untilDate:[NSDate dateWithTimeIntervalSinceNow:0.003] inMode:NSDefaultRunLoopMode dequeue:FALSE];
|
||||
if (nextDown && [nextDown keyCode] == [anEvent keyCode])
|
||||
{
|
||||
#if 0
|
||||
// no need to check timestamps -- if a queued key is there, just ignore this one(prevent a backlog)
|
||||
static double sc=0.0;
|
||||
if (sc == 0.0)
|
||||
{
|
||||
struct mach_timebase_info inf={0,};
|
||||
mach_timebase_info(&inf);
|
||||
if (inf.numer && inf.denom) sc = inf.numer / (inf.denom * 1000.0 * 1000.0 * 1000.0);
|
||||
}
|
||||
|
||||
if (sc != 0.0 && [anEvent timestamp] < (double) mach_absolute_time() * sc - 0.05)
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NSWindow *modalWindow = [NSApp modalWindow];
|
||||
|
||||
NSWindow *focwnd=[anEvent window];
|
||||
NSView *dest_view=NULL; // only valid when key message
|
||||
|
||||
if (etype==NSKeyDown||etype==NSKeyUp)
|
||||
{
|
||||
const UINT msgtype = etype==NSKeyDown ? WM_KEYDOWN : WM_KEYUP;
|
||||
int flag,code=SWELL_MacKeyToWindowsKey(anEvent,&flag);
|
||||
|
||||
if (focwnd)
|
||||
{
|
||||
if (flag&(FCONTROL|FALT))
|
||||
{
|
||||
NSWindow *f = focwnd;
|
||||
// handle carbon windows, sending all cmd/alt modified keys to their parent NSView (to be handled later)
|
||||
// perhaps it'd be good to have a flag on these to see if they want it .. i.e. SWELL_SetCarbonHostView_WantKeyFlgs()..
|
||||
while (f)
|
||||
{
|
||||
if ((dest_view=(NSView *)[f delegate]) && [dest_view respondsToSelector:@selector(swellIsCarbonHostingView)] && [(SWELL_hwndCarbonHost*)dest_view swellIsCarbonHostingView])
|
||||
{
|
||||
focwnd = [dest_view window];
|
||||
break;
|
||||
}
|
||||
dest_view=0;
|
||||
f=[f parentWindow];
|
||||
}
|
||||
}
|
||||
if (!dest_view) // get default dest_view, and validate it as a NSView
|
||||
{
|
||||
if ((dest_view=(NSView *)[focwnd firstResponder]) && ![dest_view isKindOfClass:[NSView class]]) dest_view=NULL;
|
||||
}
|
||||
}
|
||||
if (!modalWindow && (!focwnd || dest_view))
|
||||
{
|
||||
MSG msg={(HWND)dest_view,msgtype,(WPARAM)code,(LPARAM)flag}; // LPARAM is treated differently (giving modifier flags/FVIRTKEY etc) in sWELL's WM_KEYDOWN than in windows, deal with it
|
||||
|
||||
if (SWELLAppMain(SWELLAPP_PROCESSMESSAGE,(INT_PTR)&msg,(INT_PTR)anEvent)>0) return;
|
||||
}
|
||||
}
|
||||
// default window handling:
|
||||
if (etype == NSKeyDown && focwnd && dest_view)
|
||||
{
|
||||
NSView *cv = [focwnd contentView];
|
||||
if (cv && [cv respondsToSelector:@selector(onSwellMessage:p1:p2:)]) //only work for swell windows
|
||||
{
|
||||
int flag,code=SWELL_MacKeyToWindowsKey(anEvent,&flag);
|
||||
int cmdid=0;
|
||||
|
||||
// todo: other keys (such as shift+insert?)
|
||||
if (((flag&~FVIRTKEY)==FCONTROL && (code=='V'||code=='C' ||code=='X')) && [dest_view isKindOfClass:[NSText class]])
|
||||
{
|
||||
if (code=='V') [(NSText *)dest_view paste:(id)cv];
|
||||
else if (code=='C') [(NSText *)dest_view copy:(id)cv];
|
||||
else if (code=='X') [(NSText *)dest_view cut:(id)cv];
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!(flag&~(FVIRTKEY|FSHIFT)) && code == VK_ESCAPE) ||
|
||||
((flag&~FVIRTKEY)==FCONTROL && code=='W'))
|
||||
{
|
||||
if (code == 'W') cmdid= IDCANCEL; // cmd+w always idcancel's
|
||||
else if (!dest_view || ![dest_view isKindOfClass:[NSTextView class]]) cmdid=IDCANCEL; // not text view, idcancel
|
||||
else if (!(flag&FSHIFT) && !IsMultiLineEditControl(cv,dest_view)) cmdid=IDCANCEL; // if singleline edit and shift not set, idcancel
|
||||
|
||||
if (!cmdid)
|
||||
{
|
||||
SetFocus((HWND)cv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!(flag&0xff&~FVIRTKEY) && code == VK_RETURN)
|
||||
{
|
||||
// get default button command id, if any, if enabled
|
||||
if (!IsMultiLineEditControl(cv,dest_view))
|
||||
{
|
||||
cmdid = SWELL_GetDefaultButtonID((HWND)cv,true);
|
||||
|
||||
if (!cmdid) // no action, set focus to parent
|
||||
{
|
||||
SetFocus((HWND)cv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cmdid)
|
||||
{
|
||||
SendMessage((HWND)cv,WM_COMMAND,cmdid,0);
|
||||
return;
|
||||
}
|
||||
} // is swell CV
|
||||
} // key down
|
||||
|
||||
[super sendEvent:anEvent];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@implementation SWELLAppController
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
SWELL_EnsureMultithreadedCocoa();
|
||||
[NSApp setDelegate:(id) self];
|
||||
|
||||
SWELL_POSTMESSAGE_INIT
|
||||
|
||||
HMENU stockMenu=(HMENU)[NSApp mainMenu];
|
||||
if (stockMenu)
|
||||
{
|
||||
HMENU nf = GetSubMenu(stockMenu,0);
|
||||
if (nf) SWELL_app_stocksysmenu = SWELL_DuplicateMenu(nf);
|
||||
}
|
||||
|
||||
SWELLAppMain(SWELLAPP_ONLOAD,0,0);
|
||||
}
|
||||
|
||||
-(IBAction)onSysMenuCommand:(id)sender
|
||||
{
|
||||
INT_PTR a = (INT_PTR) [(NSMenuItem *)sender tag];
|
||||
if (a) SWELLAppMain(SWELLAPP_ONCOMMAND,a,(INT_PTR)sender);
|
||||
}
|
||||
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
|
||||
{
|
||||
char buf[4096];
|
||||
buf[0]=0;
|
||||
SWELL_CFStringToCString(filename,buf,sizeof(buf));
|
||||
return buf[0] && SWELLAppMain(SWELLAPP_OPENFILE,(INT_PTR)buf,0)>0;
|
||||
}
|
||||
- (BOOL)applicationOpenUntitledFile:(NSApplication *)theApplication
|
||||
{
|
||||
return SWELLAppMain(SWELLAPP_NEWFILE,0,0)>0;
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
|
||||
{
|
||||
return SWELLAppMain(SWELLAPP_SHOULDOPENNEWFILE,0,0)>0;
|
||||
}
|
||||
|
||||
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
SWELLAppMain(SWELLAPP_LOADED,0,0);
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||
{
|
||||
return SWELLAppMain(SWELLAPP_SHOULDDESTROY,0,0) > 0 ? NSTerminateLater : NSTerminateNow;
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)notification
|
||||
{
|
||||
SWELLAppMain(SWELLAPP_DESTROY,0,0);
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(NSNotification *)aNotification
|
||||
{
|
||||
if (!SWELLAppMain(SWELLAPP_ACTIVATE,TRUE,0))
|
||||
SWELL_BroadcastMessage(WM_ACTIVATEAPP,TRUE,0);
|
||||
}
|
||||
|
||||
- (void)applicationDidResignActive:(NSNotification *)aNotification
|
||||
{
|
||||
if (!SWELLAppMain(SWELLAPP_ACTIVATE,FALSE,0))
|
||||
SWELL_BroadcastMessage(WM_ACTIVATEAPP,FALSE,0);
|
||||
}
|
||||
|
||||
SWELL_APPAPI_DELEGATE_IMPL
|
||||
|
||||
SWELL_POSTMESSAGE_DELEGATE_IMPL
|
||||
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user