├── .travis.yml
├── LICENSE
├── README.md
├── WindowsAPI
├── README.txt
├── parse.sh
├── windows.c
├── windows.d.bk
├── windows.di
└── windows_impl.d
├── cocoa_library
├── bin
│ └── Debug
│ │ ├── dwc-osxTests.xctest
│ │ └── Contents
│ │ │ └── Info.plist
│ │ └── libdwc-osx.a
└── project
│ ├── dwc-osx.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── dwc-osx.xccheckout
│ └── xcuserdata
│ │ └── rikki.xcuserdatad
│ │ └── xcschemes
│ │ ├── dwc-osx.xcscheme
│ │ └── xcschememanagement.plist
│ ├── dwc-osx
│ ├── context.m
│ ├── dwc_cocoa.h
│ ├── events.h
│ ├── evtloop.m
│ ├── screen.m
│ ├── setup.m
│ ├── window.m
│ └── window_events.m
│ └── dwc-osxTests
│ └── Info.plist
├── dub.json
├── interfaces
└── devisualization
│ └── window
│ └── interfaces
│ ├── context.d
│ ├── eventable.d
│ ├── events.d
│ └── window.d
├── platforms
├── linux
│ └── devisualization
│ │ └── window
│ │ ├── context
│ │ ├── buffer2d.d
│ │ ├── opengl.d
│ │ └── package.d
│ │ └── window.d
├── macosx
│ └── devisualization
│ │ └── window
│ │ ├── context
│ │ ├── buffer2d.d
│ │ ├── opengl.d
│ │ └── package.d
│ │ └── window.d
└── win32
│ └── devisualization
│ └── window
│ ├── context
│ ├── buffer2d.d
│ ├── direct3d.d
│ ├── opengl.d
│ └── package.d
│ └── window.d
└── test
└── main.d
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: d
2 | install:
3 | - sudo apt-get update -q
4 | - sudo apt-get install -y libxrandr-dev
5 | matrix:
6 | allow_failures:
7 | # dmd FE 2.065
8 | - d: dmd-2.065.0
9 | - d: gdc-4.8.2
10 | - d: ldc-0.14.0
11 | include:
12 | - d: dmd-2.066.1
13 | - d: dmd-2.065.0
14 | - d: gdc-4.8.2
15 | - d: ldc-0.15.1
16 | - d: ldc-0.14.0
17 | install:
18 | - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
19 | - sudo apt-get update -q
20 | - sudo apt-get install libstdc++6
21 | script:
22 | - dub build de_window:test --compiler=${DC}
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Devisualization Window Toolkit
2 | ===
3 | Window creational toolkit, cross platform. Written in D.
4 | Depends on Derelict-GL3 for Opengl support.
5 | [](https://gitter.im/Devisualization/window?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
6 | [](https://travis-ci.org/Devisualization/window)
7 |
8 | There is currently issues for running within Cygwin on Windows. The window may seem choppy and will not auto flush standard output.
9 | There is no clear cut fix for this at the present time as it is on Cygwin's side.
10 |
11 | Features
12 | --------
13 | * Create, Destroy, On draw
14 | * Move, Resize
15 | * Key down/up with modifiers
16 | * Mouse left/right/middle down/up
17 | * Window Icon, Text
18 | * OpenGL (both legacy and 3+) context creation (Windows, X11, OSX (Cocoa))
19 | * Direct3d context creation on windows (untested)
20 | * 2D image buffer drawing context
21 |
22 | Example
23 | -------
24 | Custom event loop
25 | ```D
26 | import devisualization.window.window;
27 | import std.stdio;
28 |
29 | void main() {
30 | Window window = new Window(800, 600, "My window!"w);
31 | window.show();
32 |
33 | window.addOnDraw((Windowable window2) {
34 | writeln("drawing");
35 | });
36 |
37 | while(true) {
38 | import core.thread : Thread;
39 | import core.time : dur;
40 | Window.messageLoopIteration();
41 |
42 | if (window.hasBeenClosed)
43 | break;
44 | else
45 | window.onDraw();
46 | //Thread.sleep(dur!"msecs"(25));
47 | }
48 | }
49 | ```
50 | Thread sleep is optional, as messageLoopIteration is blocking but may not wait for a message.
51 | However it should be one draw per x time units. For most efficient loop.
52 | During the drawing, check if you have a valid context. OnDraw may occur while there is no valid context.
53 |
54 | Using as a dub package
55 | -----
56 | To add `de_window` as a dependency to your project use:
57 | ```
58 | "dependencies": {
59 | "de_window:platform": "~>0.1.2",
60 | }
61 | ```
62 | Of course instead of "~>0.1.2" can/should be your version number.
63 |
64 | TODO
65 | -----
66 | * Confirm prevent close works on Windows and X11
67 | * Direct3d abstraction within interfaces?
68 | * On window redisplay(undo of minimise)/maximise/minimise
69 | * Add messageLoopIteration respective function for wait till message (win/lin/osx)
70 |
71 | X11 based window manager weird behaviours:
72 | * Make sure icons work on Posix
73 | * Make sure full screen works correctly on Posix (tempermental on XFCE)
74 |
--------------------------------------------------------------------------------
/WindowsAPI/README.txt:
--------------------------------------------------------------------------------
1 | parse.sh Generates WindowsAPI bindings from MingX x64 headers.
2 |
3 | $ ./parse.sh windows.h
4 | $ mv windows.h.d windows.d
5 |
6 | Required:
7 | Bash
8 | Awk
9 | Sed
10 |
11 |
12 |
13 |
14 |
15 |
16 | ===============================
17 | FOR DWC:
18 | The output from the above commands was manually parsed and split into two files.
19 | windows.di is the interface files without macro expansion.
20 | windows_impl.d is the macros aka functions.
--------------------------------------------------------------------------------
/WindowsAPI/parse.sh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devisualization/window/2e8521eaec241061515ebb4f43c58a4c7f6e8fe4/WindowsAPI/parse.sh
--------------------------------------------------------------------------------
/WindowsAPI/windows.c:
--------------------------------------------------------------------------------
1 | #define _MMINTRIN_H_INCLUDED
2 | #define _XMMINTRIN_H_INCLUDED
3 | #define _EMMINTRIN_H_INCLUDED
4 | #define _PMMINTRIN_H_INCLUDED
5 | #define _TMMINTRIN_H_INCLUDED
6 | #define _AMMINTRIN_H_INCLUDED
7 | #define _SMMINTRIN_H_INCLUDED
8 | #define _WMMINTRIN_H_INCLUDED
9 | #define _IMMINTRIN_H_INCLUDED
10 | #define _MM3DNOW_H_INCLUDED
11 | #define _FMA4INTRIN_H_INCLUDED
12 | #define _XOPMMINTRIN_H_INCLUDED
13 | #define _LWPINTRIN_H_INCLUDED
14 | #define _BMIINTRIN_H_INCLUDED
15 | #define _BMI2INTRIN_H_INCLUDED
16 | #define _TBMINTRIN_H_INCLUDED
17 | #define _LZCNTINTRIN_H_INCLUDED
18 | #define _POPCNTINTRIN_H_INCLUDED
19 |
20 | #define _X86INTRIN_H_INCLUDED
21 |
22 | #define __INTRIN_H_
23 |
24 | #define _INC_EXCPT
25 |
26 | #include <_mingw.h>
27 | #undef __MINGW_INTRIN_INLINE
28 |
29 | typedef char * va_list;
30 |
31 | #include
--------------------------------------------------------------------------------
/WindowsAPI/windows_impl.d:
--------------------------------------------------------------------------------
1 | module windows_impl;
2 | import windows;
3 | alias size_t = windows.size_t;//conflict with object.size_t
4 |
5 | extern (System):
6 | //C static void *Ptr32ToPtr(const void *p) { return (void *) (ULONG_PTR) p; }
7 | struct _N10
8 | {
9 | DWORD __bitfield1;
10 | DWORD BaseMid() { return (__bitfield1 >> 0) & 0xff; }
11 | DWORD Type() { return (__bitfield1 >> 8) & 0x1f; }
12 | DWORD Dpl() { return (__bitfield1 >> 13) & 0x3; }
13 | DWORD Pres() { return (__bitfield1 >> 15) & 0x1; }
14 | DWORD LimitHi() { return (__bitfield1 >> 16) & 0xf; }
15 | DWORD Sys() { return (__bitfield1 >> 20) & 0x1; }
16 | DWORD Reserved_0() { return (__bitfield1 >> 21) & 0x1; }
17 | DWORD Default_Big() { return (__bitfield1 >> 22) & 0x1; }
18 | DWORD Granularity() { return (__bitfield1 >> 23) & 0x1; }
19 | DWORD BaseHi() { return (__bitfield1 >> 24) & 0xff; }
20 | }
21 | struct _N15
22 | {
23 | DWORD __bitfield1;
24 | DWORD RatePercent() { return (__bitfield1 >> 0) & 0x7f; }
25 | DWORD Reserved0() { return (__bitfield1 >> 7) & 0x1ffffff; }
26 | }
27 | union _RATE_QUOTA_LIMIT
28 | {
29 | DWORD RateData;
30 | DWORD RatePercent() { return 0x7f; }
31 | DWORD Reserved0() { return 0x1ffffff; }
32 | }
33 | struct _PROCESSOR_POWER_POLICY_INFO
34 | {
35 | DWORD TimeCheck;
36 | DWORD DemoteLimit;
37 | DWORD PromoteLimit;
38 | BYTE DemotePercent;
39 | BYTE PromotePercent;
40 | BYTE [2]Spare;
41 | DWORD __bitfield1;
42 | DWORD AllowDemotion() { return (__bitfield1 >> 0) & 0x1; }
43 | DWORD AllowPromotion() { return (__bitfield1 >> 1) & 0x1; }
44 | DWORD Reserved() { return (__bitfield1 >> 2) & 0x3fffffff; }
45 | }
46 | struct _PROCESSOR_POWER_POLICY
47 | {
48 | DWORD Revision;
49 | BYTE DynamicThrottle;
50 | BYTE [3]Spare;
51 | DWORD __bitfield1;
52 | DWORD DisableCStates() { return (__bitfield1 >> 0) & 0x1; }
53 | DWORD Reserved() { return (__bitfield1 >> 1) & 0x7fffffff; }
54 | DWORD PolicyCount;
55 | PROCESSOR_POWER_POLICY_INFO [3]Policy;
56 | }
57 | struct _N45
58 | {
59 | DWORD __bitfield1;
60 | DWORD NameOffset() { return (__bitfield1 >> 0) & 0x7fffffff; }
61 | DWORD NameIsString() { return (__bitfield1 >> 31) & 0x1; }
62 | }
63 | //C DWORD Name;
64 | //C WORD Id;
65 | //C } ;
66 | union _N44
67 | {
68 | DWORD __bitfield1;
69 | DWORD NameOffset() { return (__bitfield1 >> 0) & 0x7fffffff; }
70 | DWORD NameIsString() { return (__bitfield1 >> 31) & 0x1; }
71 | DWORD Name;
72 | WORD Id;
73 | }
74 | struct _N47
75 | {
76 | DWORD __bitfield1;
77 | DWORD OffsetToDirectory() { return (__bitfield1 >> 0) & 0x7fffffff; }
78 | DWORD DataIsDirectory() { return (__bitfield1 >> 31) & 0x1; }
79 | }
80 | //C } ;
81 | union _N46
82 | {
83 | DWORD OffsetToData;
84 | DWORD OffsetToDirectory() { return 0x7fffffff; }
85 | DWORD DataIsDirectory() { return 0x1; }
86 | }
87 | struct _IMAGE_RESOURCE_DIRECTORY_ENTRY
88 | {
89 | DWORD __bitfield1;
90 | DWORD NameOffset() { return (__bitfield1 >> 0) & 0x7fffffff; }
91 | DWORD NameIsString() { return (__bitfield1 >> 31) & 0x1; }
92 | DWORD Name;
93 | WORD Id;
94 | DWORD OffsetToData;
95 | DWORD OffsetToDirectory() { return (__bitfield1 >> 0) & 0x7fffffff; }
96 | DWORD DataIsDirectory() { return (__bitfield1 >> 31) & 0x1; }
97 | }
98 | struct _IMAGE_CE_RUNTIME_FUNCTION_ENTRY
99 | {
100 | DWORD FuncStart;
101 | DWORD __bitfield1;
102 | DWORD PrologLen() { return (__bitfield1 >> 0) & 0xff; }
103 | DWORD FuncLen() { return (__bitfield1 >> 8) & 0x3fffff; }
104 | DWORD ThirtyTwoBit() { return (__bitfield1 >> 30) & 0x1; }
105 | DWORD ExceptionFlag() { return (__bitfield1 >> 31) & 0x1; }
106 | }
107 | struct _FPO_DATA
108 | {
109 | DWORD ulOffStart;
110 | DWORD cbProcSize;
111 | DWORD cdwLocals;
112 | WORD cdwParams;
113 | WORD __bitfield1;
114 | WORD cbProlog() { return (__bitfield1 >> 0) & 0xff; }
115 | WORD cbRegs() { return (__bitfield1 >> 8) & 0x7; }
116 | WORD fHasSEH() { return (__bitfield1 >> 11) & 0x1; }
117 | WORD fUseBP() { return (__bitfield1 >> 12) & 0x1; }
118 | WORD reserved() { return (__bitfield1 >> 13) & 0x1; }
119 | WORD cbFrame() { return (__bitfield1 >> 14) & 0x3; }
120 | }
121 | struct _ImageArchitectureHeader
122 | {
123 | uint __bitfield1;
124 | uint AmaskValue() { return (__bitfield1 >> 0) & 0x1; }
125 | int Adummy1() { return (__bitfield1 << 24) >> 25; }
126 | uint AmaskShift() { return (__bitfield1 >> 8) & 0xff; }
127 | int Adummy2() { return (__bitfield1 << 0) >> 16; }
128 | DWORD FirstEntryRVA;
129 | }
130 | struct IMPORT_OBJECT_HEADER
131 | {
132 | WORD Sig1;
133 | WORD Sig2;
134 | WORD Version;
135 | WORD Machine;
136 | DWORD TimeDateStamp;
137 | DWORD SizeOfData;
138 | WORD Ordinal;
139 | WORD Hint;
140 | WORD __bitfield1;
141 | WORD Type() { return (__bitfield1 >> 0) & 0x3; }
142 | WORD NameType() { return (__bitfield1 >> 2) & 0x7; }
143 | WORD Reserved() { return (__bitfield1 >> 5) & 0x7ff; }
144 | }
145 | struct _COMSTAT
146 | {
147 | DWORD __bitfield1;
148 | DWORD fCtsHold() { return (__bitfield1 >> 0) & 0x1; }
149 | DWORD fDsrHold() { return (__bitfield1 >> 1) & 0x1; }
150 | DWORD fRlsdHold() { return (__bitfield1 >> 2) & 0x1; }
151 | DWORD fXoffHold() { return (__bitfield1 >> 3) & 0x1; }
152 | DWORD fXoffSent() { return (__bitfield1 >> 4) & 0x1; }
153 | DWORD fEof() { return (__bitfield1 >> 5) & 0x1; }
154 | DWORD fTxim() { return (__bitfield1 >> 6) & 0x1; }
155 | DWORD fReserved() { return (__bitfield1 >> 7) & 0x1ffffff; }
156 | DWORD cbInQue;
157 | DWORD cbOutQue;
158 | }
159 | struct _DCB
160 | {
161 | DWORD DCBlength;
162 | DWORD BaudRate;
163 | DWORD __bitfield1;
164 | DWORD fBinary() { return (__bitfield1 >> 0) & 0x1; }
165 | DWORD fParity() { return (__bitfield1 >> 1) & 0x1; }
166 | DWORD fOutxCtsFlow() { return (__bitfield1 >> 2) & 0x1; }
167 | DWORD fOutxDsrFlow() { return (__bitfield1 >> 3) & 0x1; }
168 | DWORD fDtrControl() { return (__bitfield1 >> 4) & 0x3; }
169 | DWORD fDsrSensitivity() { return (__bitfield1 >> 6) & 0x1; }
170 | DWORD fTXContinueOnXoff() { return (__bitfield1 >> 7) & 0x1; }
171 | DWORD fOutX() { return (__bitfield1 >> 8) & 0x1; }
172 | DWORD fInX() { return (__bitfield1 >> 9) & 0x1; }
173 | DWORD fErrorChar() { return (__bitfield1 >> 10) & 0x1; }
174 | DWORD fNull() { return (__bitfield1 >> 11) & 0x1; }
175 | DWORD fRtsControl() { return (__bitfield1 >> 12) & 0x3; }
176 | DWORD fAbortOnError() { return (__bitfield1 >> 14) & 0x1; }
177 | DWORD fDummy2() { return (__bitfield1 >> 15) & 0x1ffff; }
178 | WORD wReserved;
179 | WORD XonLim;
180 | WORD XoffLim;
181 | BYTE ByteSize;
182 | BYTE Parity;
183 | BYTE StopBits;
184 | char XonChar;
185 | char XoffChar;
186 | char ErrorChar;
187 | char EofChar;
188 | char EvtChar;
189 | WORD wReserved1;
190 | }
191 | struct tagMENUBARINFO
192 | {
193 | DWORD cbSize;
194 | RECT rcBar;
195 | HMENU hMenu;
196 | HWND hwndMenu;
197 | WINBOOL __bitfield1;
198 | WINBOOL fBarFocused() { return (__bitfield1 << 31) >> 31; }
199 | WINBOOL fFocused() { return (__bitfield1 << 30) >> 31; }
200 | }
201 | struct _N88
202 | {
203 | ushort __bitfield1;
204 | ushort bAppReturnCode() { return (__bitfield1 >> 0) & 0xff; }
205 | ushort reserved() { return (__bitfield1 >> 8) & 0x3f; }
206 | ushort fBusy() { return (__bitfield1 >> 14) & 0x1; }
207 | ushort fAck() { return (__bitfield1 >> 15) & 0x1; }
208 | }
209 | struct _N89
210 | {
211 | ushort __bitfield1;
212 | ushort reserved() { return (__bitfield1 >> 0) & 0x3fff; }
213 | ushort fDeferUpd() { return (__bitfield1 >> 14) & 0x1; }
214 | ushort fAckReq() { return (__bitfield1 >> 15) & 0x1; }
215 | short cfFormat;
216 | }
217 | struct _N90
218 | {
219 | ushort __bitfield1;
220 | ushort unused() { return (__bitfield1 >> 0) & 0xfff; }
221 | ushort fResponse() { return (__bitfield1 >> 12) & 0x1; }
222 | ushort fRelease() { return (__bitfield1 >> 13) & 0x1; }
223 | ushort reserved() { return (__bitfield1 >> 14) & 0x1; }
224 | ushort fAckReq() { return (__bitfield1 >> 15) & 0x1; }
225 | short cfFormat;
226 | BYTE [1]Value;
227 | }
228 | struct _N91
229 | {
230 | ushort __bitfield1;
231 | ushort unused() { return (__bitfield1 >> 0) & 0x1fff; }
232 | ushort fRelease() { return (__bitfield1 >> 13) & 0x1; }
233 | ushort fReserved() { return (__bitfield1 >> 14) & 0x3; }
234 | short cfFormat;
235 | BYTE [1]Value;
236 | }
237 | struct _N92
238 | {
239 | ushort __bitfield1;
240 | ushort unused() { return (__bitfield1 >> 0) & 0x1fff; }
241 | ushort fRelease() { return (__bitfield1 >> 13) & 0x1; }
242 | ushort fDeferUpd() { return (__bitfield1 >> 14) & 0x1; }
243 | ushort fAckReq() { return (__bitfield1 >> 15) & 0x1; }
244 | short cfFormat;
245 | }
246 | struct _N93
247 | {
248 | ushort __bitfield1;
249 | ushort unused() { return (__bitfield1 >> 0) & 0xfff; }
250 | ushort fAck() { return (__bitfield1 >> 12) & 0x1; }
251 | ushort fRelease() { return (__bitfield1 >> 13) & 0x1; }
252 | ushort fReserved() { return (__bitfield1 >> 14) & 0x1; }
253 | ushort fAckReq() { return (__bitfield1 >> 15) & 0x1; }
254 | short cfFormat;
255 | BYTE [1]rgb;
256 | }
257 | struct _MIDL_STUB_MESSAGE
258 | {
259 | PRPC_MESSAGE RpcMsg;
260 | ubyte *Buffer;
261 | ubyte *BufferStart;
262 | ubyte *BufferEnd;
263 | ubyte *BufferMark;
264 | uint BufferLength;
265 | uint MemorySize;
266 | ubyte *Memory;
267 | ubyte IsClient;
268 | ubyte Pad;
269 | ushort uFlags2;
270 | int ReuseBuffer;
271 | NDR_ALLOC_ALL_NODES_CONTEXT *pAllocAllNodesContext;
272 | NDR_POINTER_QUEUE_STATE *pPointerQueueState;
273 | int IgnoreEmbeddedPointers;
274 | ubyte *PointerBufferMark;
275 | ubyte fBufferValid;
276 | ubyte uFlags;
277 | ushort UniquePtrCount;
278 | ULONG_PTR MaxCount;
279 | uint Offset;
280 | uint ActualCount;
281 | void * function(size_t )pfnAllocate;
282 | void function(void *)pfnFree;
283 | ubyte *StackTop;
284 | ubyte *pPresentedType;
285 | ubyte *pTransmitType;
286 | handle_t SavedHandle;
287 | _MIDL_STUB_DESC *StubDesc;
288 | _FULL_PTR_XLAT_TABLES *FullPtrXlatTables;
289 | uint FullPtrRefId;
290 | uint PointerLength;
291 | int __bitfield1;
292 | int fInDontFree() { return (__bitfield1 << 31) >> 31; }
293 | int fDontCallFreeInst() { return (__bitfield1 << 30) >> 31; }
294 | int fInOnlyParam() { return (__bitfield1 << 29) >> 31; }
295 | int fHasReturn() { return (__bitfield1 << 28) >> 31; }
296 | int fHasExtensions() { return (__bitfield1 << 27) >> 31; }
297 | int fHasNewCorrDesc() { return (__bitfield1 << 26) >> 31; }
298 | int fIsOicfServer() { return (__bitfield1 << 25) >> 31; }
299 | int fHasMemoryValidateCallback() { return (__bitfield1 << 24) >> 31; }
300 | int fUnused() { return (__bitfield1 << 16) >> 24; }
301 | int fUnused2() { return (__bitfield1 << 0) >> 16; }
302 | uint dwDestContext;
303 | void *pvDestContext;
304 | NDR_SCONTEXT *SavedContextHandles;
305 | int ParamNumber;
306 | IRpcChannelBuffer *pRpcChannelBuffer;
307 | PARRAY_INFO pArrayInfo;
308 | uint *SizePtrCountArray;
309 | uint *SizePtrOffsetArray;
310 | uint *SizePtrLengthArray;
311 | void *pArgQueue;
312 | uint dwStubPhase;
313 | void *LowStackMark;
314 | PNDR_ASYNC_MESSAGE pAsyncMsg;
315 | PNDR_CORRELATION_INFO pCorrInfo;
316 | ubyte *pCorrMemory;
317 | void *pMemoryList;
318 | CS_STUB_INFO *pCSInfo;
319 | ubyte *ConformanceMark;
320 | ubyte *VarianceMark;
321 | INT_PTR Unused;
322 | _NDR_PROC_CONTEXT *pContext;
323 | void *pUserMarshalList;
324 | INT_PTR Reserved51_2;
325 | INT_PTR Reserved51_3;
326 | INT_PTR Reserved51_4;
327 | INT_PTR Reserved51_5;
328 | }
329 | //C return _Ptr;
330 | pure HWND HWND_TOP() {return cast(HWND)0;}
331 | pure WORD LOWORD(T)(T l) {return cast(WORD)((cast(DWORD_PTR)l) & 0xffff);}
332 | pure WORD HIWORD(T)(T l) {return cast(WORD)((cast(DWORD_PTR)l) >> 16);}
333 | pure short GET_WHEEL_DELTA_WPARAM(DWORD wParam) {return cast(short)HIWORD(wParam);}
334 | static if (__traits(compiles, typeof(_CONST_RETURN))) static if (!__traits(isStaticFunction, _CONST_RETURN)) static if (__traits(isPOD, typeof(_CONST_RETURN))) const _WConst_return = _CONST_RETURN;
335 |
--------------------------------------------------------------------------------
/cocoa_library/bin/Debug/dwc-osxTests.xctest/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 13F34
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | dwc-osxTests
11 | CFBundleIdentifier
12 | rikki-cattermole.dwc-osxTests
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | dwc-osxTests
17 | CFBundlePackageType
18 | BNDL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | DTCompiler
26 | com.apple.compilers.llvm.clang.1_0
27 | DTPlatformBuild
28 | 6A1052d
29 | DTPlatformVersion
30 | GM
31 | DTSDKBuild
32 | 14A382
33 | DTSDKName
34 | macosx10.10
35 | DTXcode
36 | 0610
37 | DTXcodeBuild
38 | 6A1052d
39 |
40 |
41 |
--------------------------------------------------------------------------------
/cocoa_library/bin/Debug/libdwc-osx.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Devisualization/window/2e8521eaec241061515ebb4f43c58a4c7f6e8fe4/cocoa_library/bin/Debug/libdwc-osx.a
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | BD027CED1A0A2EB000C9C88D /* window_events.m in Sources */ = {isa = PBXBuildFile; fileRef = BD027CEC1A0A2EB000C9C88D /* window_events.m */; };
11 | BD027CEF1A0C85F600C9C88D /* context.m in Sources */ = {isa = PBXBuildFile; fileRef = BD027CEE1A0C85F600C9C88D /* context.m */; };
12 | BD0421E91A00BD5C0074D88E /* evtloop.m in Sources */ = {isa = PBXBuildFile; fileRef = BD0421E81A00BD5C0074D88E /* evtloop.m */; };
13 | BD0421EF1A00BD5C0074D88E /* libdwc-osx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BD0421E31A00BD5C0074D88E /* libdwc-osx.a */; };
14 | BD0421FE1A01E7550074D88E /* screen.m in Sources */ = {isa = PBXBuildFile; fileRef = BD0421FD1A01E7550074D88E /* screen.m */; };
15 | BD0422001A01EA5D0074D88E /* setup.m in Sources */ = {isa = PBXBuildFile; fileRef = BD0421FF1A01EA5D0074D88E /* setup.m */; };
16 | BD0422031A01F9E50074D88E /* window.m in Sources */ = {isa = PBXBuildFile; fileRef = BD0422021A01F9E50074D88E /* window.m */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXContainerItemProxy section */
20 | BD0421F01A00BD5C0074D88E /* PBXContainerItemProxy */ = {
21 | isa = PBXContainerItemProxy;
22 | containerPortal = BD0421DB1A00BD5C0074D88E /* Project object */;
23 | proxyType = 1;
24 | remoteGlobalIDString = BD0421E21A00BD5C0074D88E;
25 | remoteInfo = "dwc-osx";
26 | };
27 | /* End PBXContainerItemProxy section */
28 |
29 | /* Begin PBXFileReference section */
30 | BD027CEB1A0A257500C9C88D /* events.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = events.h; sourceTree = ""; };
31 | BD027CEC1A0A2EB000C9C88D /* window_events.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = window_events.m; sourceTree = ""; };
32 | BD027CEE1A0C85F600C9C88D /* context.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = context.m; sourceTree = ""; };
33 | BD0421E31A00BD5C0074D88E /* libdwc-osx.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libdwc-osx.a"; sourceTree = BUILT_PRODUCTS_DIR; };
34 | BD0421E81A00BD5C0074D88E /* evtloop.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = evtloop.m; sourceTree = ""; };
35 | BD0421EE1A00BD5C0074D88E /* dwc-osxTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "dwc-osxTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
36 | BD0421F41A00BD5C0074D88E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
37 | BD0421FD1A01E7550074D88E /* screen.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = screen.m; sourceTree = ""; };
38 | BD0421FF1A01EA5D0074D88E /* setup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = setup.m; sourceTree = ""; };
39 | BD0422011A01EB2C0074D88E /* dwc_cocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dwc_cocoa.h; sourceTree = ""; };
40 | BD0422021A01F9E50074D88E /* window.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = window.m; sourceTree = ""; };
41 | /* End PBXFileReference section */
42 |
43 | /* Begin PBXFrameworksBuildPhase section */
44 | BD0421E01A00BD5C0074D88E /* Frameworks */ = {
45 | isa = PBXFrameworksBuildPhase;
46 | buildActionMask = 2147483647;
47 | files = (
48 | );
49 | runOnlyForDeploymentPostprocessing = 0;
50 | };
51 | BD0421EB1A00BD5C0074D88E /* Frameworks */ = {
52 | isa = PBXFrameworksBuildPhase;
53 | buildActionMask = 2147483647;
54 | files = (
55 | BD0421EF1A00BD5C0074D88E /* libdwc-osx.a in Frameworks */,
56 | );
57 | runOnlyForDeploymentPostprocessing = 0;
58 | };
59 | /* End PBXFrameworksBuildPhase section */
60 |
61 | /* Begin PBXGroup section */
62 | BD0421DA1A00BD5C0074D88E = {
63 | isa = PBXGroup;
64 | children = (
65 | BD0421E51A00BD5C0074D88E /* dwc-osx */,
66 | BD0421F21A00BD5C0074D88E /* dwc-osxTests */,
67 | BD0421E41A00BD5C0074D88E /* Products */,
68 | );
69 | sourceTree = "";
70 | };
71 | BD0421E41A00BD5C0074D88E /* Products */ = {
72 | isa = PBXGroup;
73 | children = (
74 | BD0421E31A00BD5C0074D88E /* libdwc-osx.a */,
75 | BD0421EE1A00BD5C0074D88E /* dwc-osxTests.xctest */,
76 | );
77 | name = Products;
78 | sourceTree = "";
79 | };
80 | BD0421E51A00BD5C0074D88E /* dwc-osx */ = {
81 | isa = PBXGroup;
82 | children = (
83 | BD0421E81A00BD5C0074D88E /* evtloop.m */,
84 | BD0421FD1A01E7550074D88E /* screen.m */,
85 | BD0421FF1A01EA5D0074D88E /* setup.m */,
86 | BD0422011A01EB2C0074D88E /* dwc_cocoa.h */,
87 | BD0422021A01F9E50074D88E /* window.m */,
88 | BD027CEB1A0A257500C9C88D /* events.h */,
89 | BD027CEC1A0A2EB000C9C88D /* window_events.m */,
90 | BD027CEE1A0C85F600C9C88D /* context.m */,
91 | );
92 | path = "dwc-osx";
93 | sourceTree = "";
94 | };
95 | BD0421F21A00BD5C0074D88E /* dwc-osxTests */ = {
96 | isa = PBXGroup;
97 | children = (
98 | BD0421F31A00BD5C0074D88E /* Supporting Files */,
99 | );
100 | path = "dwc-osxTests";
101 | sourceTree = "";
102 | };
103 | BD0421F31A00BD5C0074D88E /* Supporting Files */ = {
104 | isa = PBXGroup;
105 | children = (
106 | BD0421F41A00BD5C0074D88E /* Info.plist */,
107 | );
108 | name = "Supporting Files";
109 | sourceTree = "";
110 | };
111 | /* End PBXGroup section */
112 |
113 | /* Begin PBXHeadersBuildPhase section */
114 | BD0421E11A00BD5C0074D88E /* Headers */ = {
115 | isa = PBXHeadersBuildPhase;
116 | buildActionMask = 2147483647;
117 | files = (
118 | );
119 | runOnlyForDeploymentPostprocessing = 0;
120 | };
121 | /* End PBXHeadersBuildPhase section */
122 |
123 | /* Begin PBXNativeTarget section */
124 | BD0421E21A00BD5C0074D88E /* dwc-osx */ = {
125 | isa = PBXNativeTarget;
126 | buildConfigurationList = BD0421F71A00BD5C0074D88E /* Build configuration list for PBXNativeTarget "dwc-osx" */;
127 | buildPhases = (
128 | BD0421DF1A00BD5C0074D88E /* Sources */,
129 | BD0421E01A00BD5C0074D88E /* Frameworks */,
130 | BD0421E11A00BD5C0074D88E /* Headers */,
131 | );
132 | buildRules = (
133 | );
134 | dependencies = (
135 | );
136 | name = "dwc-osx";
137 | productName = "dwc-osx";
138 | productReference = BD0421E31A00BD5C0074D88E /* libdwc-osx.a */;
139 | productType = "com.apple.product-type.library.static";
140 | };
141 | BD0421ED1A00BD5C0074D88E /* dwc-osxTests */ = {
142 | isa = PBXNativeTarget;
143 | buildConfigurationList = BD0421FA1A00BD5C0074D88E /* Build configuration list for PBXNativeTarget "dwc-osxTests" */;
144 | buildPhases = (
145 | BD0421EA1A00BD5C0074D88E /* Sources */,
146 | BD0421EB1A00BD5C0074D88E /* Frameworks */,
147 | BD0421EC1A00BD5C0074D88E /* Resources */,
148 | );
149 | buildRules = (
150 | );
151 | dependencies = (
152 | BD0421F11A00BD5C0074D88E /* PBXTargetDependency */,
153 | );
154 | name = "dwc-osxTests";
155 | productName = "dwc-osxTests";
156 | productReference = BD0421EE1A00BD5C0074D88E /* dwc-osxTests.xctest */;
157 | productType = "com.apple.product-type.bundle.unit-test";
158 | };
159 | /* End PBXNativeTarget section */
160 |
161 | /* Begin PBXProject section */
162 | BD0421DB1A00BD5C0074D88E /* Project object */ = {
163 | isa = PBXProject;
164 | attributes = {
165 | LastUpgradeCheck = 0610;
166 | ORGANIZATIONNAME = "Rikki Cattermole";
167 | TargetAttributes = {
168 | BD0421E21A00BD5C0074D88E = {
169 | CreatedOnToolsVersion = 6.1;
170 | };
171 | BD0421ED1A00BD5C0074D88E = {
172 | CreatedOnToolsVersion = 6.1;
173 | };
174 | };
175 | };
176 | buildConfigurationList = BD0421DE1A00BD5C0074D88E /* Build configuration list for PBXProject "dwc-osx" */;
177 | compatibilityVersion = "Xcode 3.2";
178 | developmentRegion = English;
179 | hasScannedForEncodings = 0;
180 | knownRegions = (
181 | en,
182 | );
183 | mainGroup = BD0421DA1A00BD5C0074D88E;
184 | productRefGroup = BD0421E41A00BD5C0074D88E /* Products */;
185 | projectDirPath = "";
186 | projectRoot = "";
187 | targets = (
188 | BD0421E21A00BD5C0074D88E /* dwc-osx */,
189 | BD0421ED1A00BD5C0074D88E /* dwc-osxTests */,
190 | );
191 | };
192 | /* End PBXProject section */
193 |
194 | /* Begin PBXResourcesBuildPhase section */
195 | BD0421EC1A00BD5C0074D88E /* Resources */ = {
196 | isa = PBXResourcesBuildPhase;
197 | buildActionMask = 2147483647;
198 | files = (
199 | );
200 | runOnlyForDeploymentPostprocessing = 0;
201 | };
202 | /* End PBXResourcesBuildPhase section */
203 |
204 | /* Begin PBXSourcesBuildPhase section */
205 | BD0421DF1A00BD5C0074D88E /* Sources */ = {
206 | isa = PBXSourcesBuildPhase;
207 | buildActionMask = 2147483647;
208 | files = (
209 | BD0422001A01EA5D0074D88E /* setup.m in Sources */,
210 | BD0421E91A00BD5C0074D88E /* evtloop.m in Sources */,
211 | BD027CED1A0A2EB000C9C88D /* window_events.m in Sources */,
212 | BD027CEF1A0C85F600C9C88D /* context.m in Sources */,
213 | BD0421FE1A01E7550074D88E /* screen.m in Sources */,
214 | BD0422031A01F9E50074D88E /* window.m in Sources */,
215 | );
216 | runOnlyForDeploymentPostprocessing = 0;
217 | };
218 | BD0421EA1A00BD5C0074D88E /* Sources */ = {
219 | isa = PBXSourcesBuildPhase;
220 | buildActionMask = 2147483647;
221 | files = (
222 | );
223 | runOnlyForDeploymentPostprocessing = 0;
224 | };
225 | /* End PBXSourcesBuildPhase section */
226 |
227 | /* Begin PBXTargetDependency section */
228 | BD0421F11A00BD5C0074D88E /* PBXTargetDependency */ = {
229 | isa = PBXTargetDependency;
230 | target = BD0421E21A00BD5C0074D88E /* dwc-osx */;
231 | targetProxy = BD0421F01A00BD5C0074D88E /* PBXContainerItemProxy */;
232 | };
233 | /* End PBXTargetDependency section */
234 |
235 | /* Begin XCBuildConfiguration section */
236 | BD0421F51A00BD5C0074D88E /* Debug */ = {
237 | isa = XCBuildConfiguration;
238 | buildSettings = {
239 | ALWAYS_SEARCH_USER_PATHS = NO;
240 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
241 | CLANG_CXX_LIBRARY = "libc++";
242 | CLANG_ENABLE_MODULES = YES;
243 | CLANG_ENABLE_OBJC_ARC = YES;
244 | CLANG_WARN_BOOL_CONVERSION = YES;
245 | CLANG_WARN_CONSTANT_CONVERSION = YES;
246 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
247 | CLANG_WARN_EMPTY_BODY = YES;
248 | CLANG_WARN_ENUM_CONVERSION = YES;
249 | CLANG_WARN_INT_CONVERSION = YES;
250 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
251 | CLANG_WARN_UNREACHABLE_CODE = YES;
252 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
253 | COPY_PHASE_STRIP = NO;
254 | ENABLE_STRICT_OBJC_MSGSEND = YES;
255 | GCC_C_LANGUAGE_STANDARD = gnu99;
256 | GCC_DYNAMIC_NO_PIC = NO;
257 | GCC_OPTIMIZATION_LEVEL = 0;
258 | GCC_PREPROCESSOR_DEFINITIONS = (
259 | "DEBUG=1",
260 | "$(inherited)",
261 | );
262 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
263 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
264 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
265 | GCC_WARN_UNDECLARED_SELECTOR = YES;
266 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
267 | GCC_WARN_UNUSED_FUNCTION = YES;
268 | GCC_WARN_UNUSED_VARIABLE = YES;
269 | MACOSX_DEPLOYMENT_TARGET = 10.9;
270 | MTL_ENABLE_DEBUG_INFO = YES;
271 | ONLY_ACTIVE_ARCH = YES;
272 | SDKROOT = macosx;
273 | };
274 | name = Debug;
275 | };
276 | BD0421F61A00BD5C0074D88E /* Release */ = {
277 | isa = XCBuildConfiguration;
278 | buildSettings = {
279 | ALWAYS_SEARCH_USER_PATHS = NO;
280 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
281 | CLANG_CXX_LIBRARY = "libc++";
282 | CLANG_ENABLE_MODULES = YES;
283 | CLANG_ENABLE_OBJC_ARC = YES;
284 | CLANG_WARN_BOOL_CONVERSION = YES;
285 | CLANG_WARN_CONSTANT_CONVERSION = YES;
286 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
287 | CLANG_WARN_EMPTY_BODY = YES;
288 | CLANG_WARN_ENUM_CONVERSION = YES;
289 | CLANG_WARN_INT_CONVERSION = YES;
290 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
291 | CLANG_WARN_UNREACHABLE_CODE = YES;
292 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
293 | COPY_PHASE_STRIP = YES;
294 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
295 | ENABLE_NS_ASSERTIONS = NO;
296 | ENABLE_STRICT_OBJC_MSGSEND = YES;
297 | GCC_C_LANGUAGE_STANDARD = gnu99;
298 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
299 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
300 | GCC_WARN_UNDECLARED_SELECTOR = YES;
301 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
302 | GCC_WARN_UNUSED_FUNCTION = YES;
303 | GCC_WARN_UNUSED_VARIABLE = YES;
304 | MACOSX_DEPLOYMENT_TARGET = 10.9;
305 | MTL_ENABLE_DEBUG_INFO = NO;
306 | SDKROOT = macosx;
307 | };
308 | name = Release;
309 | };
310 | BD0421F81A00BD5C0074D88E /* Debug */ = {
311 | isa = XCBuildConfiguration;
312 | buildSettings = {
313 | EXECUTABLE_PREFIX = lib;
314 | PRODUCT_NAME = "$(TARGET_NAME)";
315 | };
316 | name = Debug;
317 | };
318 | BD0421F91A00BD5C0074D88E /* Release */ = {
319 | isa = XCBuildConfiguration;
320 | buildSettings = {
321 | EXECUTABLE_PREFIX = lib;
322 | PRODUCT_NAME = "$(TARGET_NAME)";
323 | };
324 | name = Release;
325 | };
326 | BD0421FB1A00BD5C0074D88E /* Debug */ = {
327 | isa = XCBuildConfiguration;
328 | buildSettings = {
329 | COMBINE_HIDPI_IMAGES = YES;
330 | FRAMEWORK_SEARCH_PATHS = (
331 | "$(DEVELOPER_FRAMEWORKS_DIR)",
332 | "$(inherited)",
333 | );
334 | GCC_PREPROCESSOR_DEFINITIONS = (
335 | "DEBUG=1",
336 | "$(inherited)",
337 | );
338 | INFOPLIST_FILE = "dwc-osxTests/Info.plist";
339 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
340 | PRODUCT_NAME = "$(TARGET_NAME)";
341 | };
342 | name = Debug;
343 | };
344 | BD0421FC1A00BD5C0074D88E /* Release */ = {
345 | isa = XCBuildConfiguration;
346 | buildSettings = {
347 | COMBINE_HIDPI_IMAGES = YES;
348 | FRAMEWORK_SEARCH_PATHS = (
349 | "$(DEVELOPER_FRAMEWORKS_DIR)",
350 | "$(inherited)",
351 | );
352 | INFOPLIST_FILE = "dwc-osxTests/Info.plist";
353 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
354 | PRODUCT_NAME = "$(TARGET_NAME)";
355 | };
356 | name = Release;
357 | };
358 | /* End XCBuildConfiguration section */
359 |
360 | /* Begin XCConfigurationList section */
361 | BD0421DE1A00BD5C0074D88E /* Build configuration list for PBXProject "dwc-osx" */ = {
362 | isa = XCConfigurationList;
363 | buildConfigurations = (
364 | BD0421F51A00BD5C0074D88E /* Debug */,
365 | BD0421F61A00BD5C0074D88E /* Release */,
366 | );
367 | defaultConfigurationIsVisible = 0;
368 | defaultConfigurationName = Release;
369 | };
370 | BD0421F71A00BD5C0074D88E /* Build configuration list for PBXNativeTarget "dwc-osx" */ = {
371 | isa = XCConfigurationList;
372 | buildConfigurations = (
373 | BD0421F81A00BD5C0074D88E /* Debug */,
374 | BD0421F91A00BD5C0074D88E /* Release */,
375 | );
376 | defaultConfigurationIsVisible = 0;
377 | defaultConfigurationName = Release;
378 | };
379 | BD0421FA1A00BD5C0074D88E /* Build configuration list for PBXNativeTarget "dwc-osxTests" */ = {
380 | isa = XCConfigurationList;
381 | buildConfigurations = (
382 | BD0421FB1A00BD5C0074D88E /* Debug */,
383 | BD0421FC1A00BD5C0074D88E /* Release */,
384 | );
385 | defaultConfigurationIsVisible = 0;
386 | defaultConfigurationName = Release;
387 | };
388 | /* End XCConfigurationList section */
389 | };
390 | rootObject = BD0421DB1A00BD5C0074D88E /* Project object */;
391 | }
392 |
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx.xcodeproj/project.xcworkspace/xcshareddata/dwc-osx.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | BA1DE8C0-DAB8-4D45-977A-0CB5EA88278D
9 | IDESourceControlProjectName
10 | dwc-osx
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 45359942D37DFD26B7D63CE7E11C6BB518ABC597
14 | https://github.com/rikkimax/DWC.git
15 |
16 | IDESourceControlProjectPath
17 | cocoa_library/project/dwc-osx.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | 45359942D37DFD26B7D63CE7E11C6BB518ABC597
21 | ../../../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/rikkimax/DWC.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | 45359942D37DFD26B7D63CE7E11C6BB518ABC597
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | 45359942D37DFD26B7D63CE7E11C6BB518ABC597
36 | IDESourceControlWCCName
37 | DWC
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx.xcodeproj/xcuserdata/rikki.xcuserdatad/xcschemes/dwc-osx.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
102 |
103 |
105 |
106 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx.xcodeproj/xcuserdata/rikki.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | dwc-osx.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | BD0421E21A00BD5C0074D88E
16 |
17 | primary
18 |
19 |
20 | BD0421ED1A00BD5C0074D88E
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx/context.m:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | #import "dwc_cocoa.h"
25 |
26 | /*
27 | * OpenGL
28 | */
29 |
30 | static NSOpenGLPixelFormatAttribute glAttributesLegacy[] = {
31 | NSOpenGLPFADoubleBuffer,
32 | NSOpenGLPFADepthSize, 32,
33 | 0
34 | };
35 |
36 | static NSOpenGLPixelFormatAttribute glAttributes3Plus[] = {
37 | NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
38 | NSOpenGLPFADoubleBuffer,
39 | NSOpenGLPFADepthSize, 32,
40 | 0
41 | };
42 |
43 | void cocoaCreateOGLContext(int id, int minVersion) {
44 | NSWindowDWC* window = (NSWindowDWC*)[NSApp windowWithWindowNumber: id];
45 |
46 | NSOpenGLPixelFormat *pixelFormat;
47 |
48 | if (minVersion == 3) {
49 | pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes: glAttributes3Plus];
50 | } else {
51 | pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes: glAttributesLegacy];
52 | }
53 |
54 | [window setOpenGLContext: [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]];
55 | [[window openGLContext] setView:[window contentView]];
56 | }
57 |
58 | void cocoaActivateOGLContext(int id) {
59 | NSWindowDWC* window = (NSWindowDWC*)[NSApp windowWithWindowNumber: id];
60 | [[window openGLContext] makeCurrentContext];
61 | }
62 |
63 | void cocoaDestroyOGLContext(int id) {
64 | NSWindowDWC* window = (NSWindowDWC*)[NSApp windowWithWindowNumber: id];
65 | [[window openGLContext] clearDrawable];
66 | [window setOpenGLContext: nil];
67 | }
68 |
69 | void cocoaSwapOGLBuffers(int id) {
70 | NSWindowDWC* window = (NSWindowDWC*)[NSApp windowWithWindowNumber: id];
71 | [[window openGLContext] flushBuffer];
72 | }
73 |
74 |
75 | /*
76 | * Buffer2D
77 | */
78 |
79 | void cocoaCreateBuffer2DContext(int id) {}
80 |
81 | void cocoaActivateBuffer2DContext(int id) {
82 | NSWindow* window = [NSApp windowWithWindowNumber: id];
83 | [[window contentView] setWantsLayer:YES];
84 | }
85 |
86 | void cocoaDestroyBuffer2DContext(int id) {
87 | NSWindow* window = [NSApp windowWithWindowNumber: id];
88 | [[window contentView] setWantsLayer:NO];
89 | }
90 |
91 | void cocoaSwapBuffer2DBuffers(int id, unsigned char** rgba, int width, int height) {
92 | NSWindow* window = [NSApp windowWithWindowNumber: id];
93 |
94 | NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: rgba
95 | pixelsWide: width
96 | pixelsHigh: height
97 | bitsPerSample: 8
98 | samplesPerPixel: 4
99 | hasAlpha: YES
100 | isPlanar: NO
101 | colorSpaceName: NSDeviceRGBColorSpace
102 | bitmapFormat: 0
103 | bytesPerRow: width * 4
104 | bitsPerPixel: 32];
105 |
106 | [imageRep setSize:NSMakeSize(16, 16)];
107 | NSData *data = [imageRep representationUsingType: NSPNGFileType properties: nil];
108 | [window setRepresentedURL:[NSURL fileURLWithPath: [window title]]];
109 |
110 | NSImage* image = [[NSImage alloc] initWithData: data];
111 |
112 | [[window contentView] layer].contents = image;
113 | }
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx/dwc_cocoa.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | #import "events.h"
25 |
26 | #ifndef dwc_osx_dwc_cocoa_h
27 | #define dwc_osx_dwc_cocoa_h
28 |
29 | /**
30 | * Initiates the cocoa runtime for the application
31 | */
32 | void cocoaInit();
33 |
34 | struct CocoaWindowData {
35 | int x;
36 | int y;
37 | int width;
38 | int height;
39 | char* title;
40 | };
41 |
42 | /**
43 | * Creates a Cocoa window
44 | *
45 | * Returns
46 | * pointer to the NSWindow object
47 | */
48 | int cocoaCreateWindow(struct CocoaWindowData data);
49 |
50 | /**
51 | * Runs an iteration of the runloop
52 | *
53 | * Returns:
54 | * 1 on event handled
55 | * 0 on no event handled
56 | */
57 | int cocoaRunLoopIterate();
58 |
59 | /**
60 | * Gets the height of the main screen
61 | *
62 | * Returns
63 | * 0 on failure
64 | * Otherwise the height of screen
65 | */
66 | int cocoaScreenHeight();
67 |
68 | /**
69 | * Gets the width of the main screen
70 | *
71 | * Returns
72 | * 0 on failure
73 | * Otherwise the width of screen
74 | */
75 | int cocoaScreenWidth();
76 |
77 | /**
78 | * Shows a given NSWindow*
79 | */
80 | void cocoaShowWindow(int window);
81 |
82 | /**
83 | * Hides an NSWindow*
84 | */
85 | void cocoaHideWindow(int window);
86 |
87 | /**
88 | * Closes a window
89 | */
90 | void cocoaCloseWindow(int window);
91 |
92 | /**
93 | * Is a window id valid?
94 | *
95 | * Returns
96 | * 1 if valid
97 | * 0 if not valid
98 | */
99 | int cocoaValidWindow(int window);
100 |
101 | //icon
102 | // need to be able to save the icon to file
103 | // as a file it can be used as an icon
104 | void cocoaSetIcon(int window, unsigned char** rgba, int width, int height);
105 |
106 | /**
107 | * Sets the windows title
108 | */
109 | void cocoaSetTitle(int window, char* title);
110 |
111 | /**
112 | * Sets the content areas size
113 | */
114 | void cocoaSetSize(int window, int width, int height);
115 |
116 | /**
117 | * Moves a window
118 | */
119 | void cocoaSetPosition(int window, int x, int y);
120 |
121 | /**
122 | * Sets if the window can be resized
123 | */
124 | void cocoaCanResize(int window, int can);
125 |
126 | /**
127 | * Makes the window fullscreen (or not)
128 | */
129 | void cocoaFullScreen(int window, int is);
130 |
131 | void cocoaCreateOGLContext(int window, int minVersion);
132 | void cocoaActivateOGLContext(int window);
133 | void cocoaDestroyOGLContext(int window);
134 | void cocoaSwapOGLBuffers(int window);
135 |
136 | #if 0
137 | void test() {
138 | unsigned char* icon = malloc(4*4);
139 |
140 | icon[0] = 255;
141 | icon[1] = 0;
142 | icon[2] = 0;
143 | icon[3] = 255;
144 |
145 | icon[5] = 255;
146 | icon[7] = 255;
147 |
148 | icon[10] = 255;
149 | icon[11] = 255;
150 |
151 | icon[15] = 255;
152 |
153 | cocoaInit();
154 |
155 | struct CocoaWindowData cArgs = {0, 0, 200, 200, "test"};
156 | int window = cocoaCreateWindow(cArgs);
157 | cocoaSetIcon(window, &icon, 2, 2);
158 | //cocoaHideWindow(window);
159 | //cocoaShowWindow(window);
160 |
161 | while(true) {
162 | if (cocoaRunLoopIterate()) {
163 | // do something
164 |
165 | } else {
166 | // thread sleep
167 | }
168 | }
169 | }
170 | #endif
171 |
172 | #endif
173 |
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx/events.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | #import
25 |
26 | #ifndef dwc_osx_events_h
27 | #define dwc_osx_events_h
28 |
29 | /**
30 | * Implementation for on Objective-C side
31 | */
32 |
33 | @interface NSWindowDWC : NSWindow
34 | -(int) lastX;
35 | -(int) lastY;
36 |
37 | -(void) setLastX: (int)value;
38 | -(void) setLastY: (int)value;
39 |
40 | -(NSOpenGLContext*) openGLContext;
41 | -(void) setOpenGLContext: (NSOpenGLContext*)value;
42 | @end
43 |
44 | /**
45 | * Interface definitions (for e.g. DWC usage)
46 | */
47 |
48 | enum CocoaMouseEventButton {
49 | Left = 0,
50 | Right = 1,
51 | Middle = 2
52 | };
53 |
54 | enum CocoaKeyModifiers : uint8 {
55 | None = 1 << 0,
56 | Shift = 1 << 1,
57 | Control = 1 << 2,
58 | Alt = 1 << 3,
59 | Super = 1 << 4
60 | };
61 |
62 | enum CocoaKeys {
63 | Unknown,
64 | F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
65 | A, B, C, D, E, F, G, H, LetterI, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
66 | Number0, Number1, Number2, Number3, Number4, Number5, Number6, Number7, Number8, Number9,
67 | LeftBracket, RightBracket, Semicolon, Comma, Period, Quote, Slash, Backslash, Tilde, Equals, Hyphen,
68 | Escape, Space, Enter, Backspace, Tab, PageUp, PageDown, End, Home, Insert, Delete, Pause,
69 | LeftArrow, RightArrow, UpArrow, DownArrow,
70 | Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9,
71 | Add, Subtract, Multiply, Divide
72 | };
73 |
74 | /**
75 | * To be implemented code on the D side
76 | */
77 |
78 | void cocoaEventMouseDown(int window, enum CocoaMouseEventButton button, float x, float y);
79 | void cocoaEventMouseUp(int window, enum CocoaMouseEventButton button, float x, float y);
80 | void cocoaEventMouseMove(int window, float x, float y);
81 | void cocoaEventOnClose(int window);
82 | void cocoaEventOnResize(int window, int width, int height);
83 | void cocoaEventOnMove(int window, int x, int y);
84 | void cocoaEventOnKeyDown(int window, uint8 modifiers, enum CocoaKeys key);
85 | void cocoaEventOnKeyUp(int window, uint8 modifiers, enum CocoaKeys key);
86 | void cocoaEventForceRedraw(int window);
87 | #endif
88 |
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx/evtloop.m:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | #import
25 |
26 | /**
27 | * @param minBlocking Will always be handled
28 | * @param maxNonBlocking Will not always be 100% handled. Return true if the last one completed all.
29 | */
30 | int cocoaRunLoopIterate(unsigned int minBlocking, unsigned int maxNonBlocking) {
31 | unsigned int i;
32 |
33 | // minBlocking
34 | while(i < minBlocking) {
35 | NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantFuture] inMode: NSDefaultRunLoopMode dequeue: YES];
36 | [NSApp sendEvent: event];
37 | [NSApp updateWindows];
38 | i++;
39 | }
40 |
41 |
42 | // maxNonBlockings
43 | i = 0;
44 | while(i < maxNonBlocking) {
45 | NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode: NSDefaultRunLoopMode dequeue: YES];
46 |
47 | if (event != nil) {
48 | [NSApp sendEvent: event];
49 | [NSApp updateWindows];
50 | } else {
51 | return false;
52 | }
53 |
54 | i++;
55 | }
56 |
57 | return true;
58 | }
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx/screen.m:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | #import
25 |
26 | int cocoaScreenHeight() {
27 | return [[NSScreen mainScreen] frame].size.height;
28 | }
29 |
30 | int cocoaScreenWidth() {
31 | return [[NSScreen mainScreen] frame].size.width;
32 | }
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx/setup.m:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | #import
25 |
26 | void cocoaInit() {
27 | [NSApplication sharedApplication];
28 | [NSApp setActivationPolicy: NSApplicationActivationPolicyRegular];
29 | [NSApp activateIgnoringOtherApps: YES];
30 | }
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx/window.m:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | #import
25 | #import
26 | #import "dwc_cocoa.h"
27 |
28 | NSMutableDictionary* windows;
29 | NSMutableDictionary* windowSizes;
30 |
31 | int cocoaCreateWindow(struct CocoaWindowData data) {
32 | if (windows == nil) {
33 | windows = [[NSMutableDictionary alloc] init];
34 | windowSizes = [[NSMutableDictionary alloc] init];
35 | }
36 |
37 | // not 100% on x/y/width/height estimates based upon input so not too much of a change visually
38 | NSWindowDWC* window = [[NSWindowDWC alloc]
39 | initWithContentRect: NSMakeRect(data.x, cocoaScreenHeight() - data.y, data.width, data.height)
40 | styleMask: NSResizableWindowMask | NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask
41 | backing: NSBackingStoreBuffered
42 | defer: NO];
43 | [window setAcceptsMouseMovedEvents: YES];
44 | [window setLastX: data.x];
45 | [window setLastY: data.y];
46 |
47 | NSNumber* windowNumber = [NSNumber numberWithInt: (int)[window windowNumber]];
48 | [windows setObject: window forKey: windowNumber];
49 |
50 | [NSApp beginModalSessionForWindow: window];
51 | [window makeKeyAndOrderFront: nil];
52 | [windowSizes setObject: NSStringFromRect([window frame]) forKey: windowNumber];
53 |
54 | cocoaSetTitle(windowNumber.intValue, data.title);
55 | cocoaSetPosition(windowNumber.intValue, data.x, data.y);
56 | cocoaSetSize(windowNumber.intValue, data.width, data.height);
57 |
58 | [[NSNotificationCenter defaultCenter] addObserver: window
59 | selector: @selector(windowResized:) name:NSWindowDidResizeNotification
60 | object: window];
61 | [[NSNotificationCenter defaultCenter] addObserver: window
62 | selector: @selector(windowMoved:) name:NSWindowDidMoveNotification
63 | object: window];
64 | [[NSNotificationCenter defaultCenter] addObserver: window
65 | selector: @selector(forceRedraw:) name:NSWindowDidExposeNotification
66 | object: window];
67 |
68 | return windowNumber.intValue;
69 | }
70 |
71 | void cocoaShowWindow(int id) {
72 | NSWindow* window = [NSApp windowWithWindowNumber: id];
73 | [window makeKeyAndOrderFront: nil];
74 |
75 | NSRect previousSize = NSRectFromString([windowSizes objectForKey: [NSNumber numberWithInt: id]]);
76 | [window setFrameOrigin: previousSize.origin];
77 | }
78 |
79 | void cocoaHideWindow(int id) {
80 | NSWindow* window = [NSApp windowWithWindowNumber: id];
81 | [window orderOut: window];
82 | }
83 |
84 | void cocoaCloseWindow(int id) {
85 | NSWindow* window = [NSApp windowWithWindowNumber: id];
86 | [window close];
87 |
88 | NSNumber* windowNumber = [NSNumber numberWithInt: id];
89 | [windows removeObjectForKey: windowNumber];
90 | [windowSizes removeObjectForKey: windowNumber];
91 | }
92 |
93 | int cocoaValidWindow(int id) {
94 | return [windows objectForKey: [NSNumber numberWithInt: id]] != nil;
95 | }
96 |
97 | void cocoaSetTitle(int id, char* title) {
98 | NSWindow* window = [NSApp windowWithWindowNumber: id];
99 |
100 | [window setTitle:
101 | [[NSString alloc]
102 | initWithUTF8String: title]];
103 | }
104 |
105 | void cocoaSetSize(int id, int width, int height) {
106 | NSWindowDWC* window = (NSWindowDWC*)[NSApp windowWithWindowNumber: id];
107 |
108 | NSRect previousSize = [window contentRectForFrameRect: [window frame]];
109 | previousSize.size.width = width;
110 | previousSize.size.height = height;
111 | [windowSizes setObject: NSStringFromRect(previousSize) forKey: [NSNumber numberWithInt: id]];
112 |
113 | [window setContentSize: NSMakeSize(width, height)];
114 | cocoaSetPosition(id, [window lastX], [window lastY]);
115 | }
116 |
117 | void cocoaSetPosition(int id, int x, int y) {
118 | NSWindowDWC* window = (NSWindowDWC*)[NSApp windowWithWindowNumber: id];
119 | [window setLastX: x];
120 | [window setLastY: y];
121 |
122 | y += [window frame].size.height;
123 | y = [[window screen] frame].size.height - y;
124 |
125 | NSRect previousSize = [window contentRectForFrameRect: [window frame]];
126 | previousSize.origin.x = x;
127 | previousSize.origin.y = y;
128 | [windowSizes setObject: NSStringFromRect(previousSize) forKey: [NSNumber numberWithInt: id]];
129 |
130 | [window setFrame: previousSize display: YES animate: YES];
131 | }
132 |
133 | void cocoaCanResize(int id, int can) {
134 | NSWindow* window = [NSApp windowWithWindowNumber: id];
135 |
136 | if (can) {
137 | [window setStyleMask: NSResizableWindowMask | NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask];
138 | } else {
139 | [window setStyleMask: NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask];
140 | }
141 | }
142 |
143 | void cocoaFullScreen(int id, int is) {
144 | NSWindow* window = [NSApp windowWithWindowNumber: id];
145 |
146 | if (([window styleMask] & NSFullScreenWindowMask)) {
147 | if (is) {
148 | [[window contentView] enterFullScreenMode: [NSScreen mainScreen] withOptions: nil];
149 | } else {
150 | [[window contentView] exitFullScreenModeWithOptions: nil];
151 | }
152 | }
153 | }
154 |
155 | void cocoaSetIcon(int id, unsigned char** rgba, int width, int height) {
156 | NSWindow* window = [NSApp windowWithWindowNumber: id];
157 |
158 | NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: rgba
159 | pixelsWide: width
160 | pixelsHigh: height
161 | bitsPerSample: 8
162 | samplesPerPixel: 4
163 | hasAlpha: YES
164 | isPlanar: NO
165 | colorSpaceName: NSDeviceRGBColorSpace
166 | bitmapFormat: 0
167 | bytesPerRow: width * 4
168 | bitsPerPixel: 32];
169 |
170 | [imageRep setSize:NSMakeSize(16, 16)];
171 | NSData *data = [imageRep representationUsingType: NSPNGFileType properties: nil];
172 | [window setRepresentedURL:[NSURL fileURLWithPath: [window title]]];
173 |
174 | NSImage* image = [[NSImage alloc] initWithData: data];
175 | [image setSize: NSMakeSize(16, 16)];
176 | [[window standardWindowButton:NSWindowDocumentIconButton] setImage: image];
177 | }
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osx/window_events.m:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | #import "events.h"
25 |
26 | @implementation NSWindowDWC
27 | int lastX_;
28 | int lastY_;
29 |
30 | -(int) lastX {
31 | return lastX_;
32 | }
33 |
34 | -(int) lastY {
35 | return lastY_;
36 | }
37 |
38 | -(void) setLastX: (int)value {
39 | lastX_ = value;
40 | }
41 |
42 | -(void) setLastY: (int)value {
43 | lastY_ = value;
44 | }
45 |
46 | NSOpenGLContext* openGLContext_;
47 |
48 | -(NSOpenGLContext*) openGLContext {
49 | return openGLContext_;
50 | }
51 |
52 | -(void) setOpenGLContext: (NSOpenGLContext*)value {
53 | openGLContext_ = value;
54 | }
55 |
56 | /**
57 | * Mouse down events (left, middle and right)
58 | */
59 |
60 | -(void)mouseDown: (NSEvent*)theEvent {
61 | [super mouseDown:theEvent];
62 |
63 | NSPoint location = [self mouseLocationOutsideOfEventStream];
64 | NSInteger height = self.frame.size.height;
65 |
66 | cocoaEventMouseDown((int)[self windowNumber], Left, location.x, height - location.y);
67 | }
68 |
69 | -(void)rightMouseDown:(NSEvent *)theEvent {
70 | [super mouseDown:theEvent];
71 |
72 | NSPoint location = [self mouseLocationOutsideOfEventStream];
73 | NSInteger height = self.frame.size.height;
74 |
75 | cocoaEventMouseDown((int)[self windowNumber], Right, location.x, height - location.y);
76 | }
77 |
78 | -(void) otherMouseDown:(NSEvent *)theEvent{
79 | [super mouseDown:theEvent];
80 |
81 | NSPoint location = [self mouseLocationOutsideOfEventStream];
82 | NSInteger height = self.frame.size.height;
83 |
84 | cocoaEventMouseDown((int)[self windowNumber], Middle, location.x, height - location.y);
85 | }
86 |
87 | /**
88 | * Mouse up events (left, middle, right)
89 | */
90 |
91 | -(void)mouseUp:(NSEvent *)theEvent {
92 | [super mouseDown:theEvent];
93 |
94 | NSPoint location = [self mouseLocationOutsideOfEventStream];
95 | NSInteger height = self.frame.size.height;
96 |
97 | cocoaEventMouseUp((int)[self windowNumber], Left, location.x, height - location.y);
98 | }
99 |
100 | -(void)rightMouseUp:(NSEvent *)theEvent {
101 | [super mouseDown:theEvent];
102 |
103 | NSPoint location = [self mouseLocationOutsideOfEventStream];
104 | NSInteger height = self.frame.size.height;
105 |
106 | cocoaEventMouseUp((int)[self windowNumber], Right, location.x, height - location.y);
107 | }
108 |
109 | -(void) otherMouseUp:(NSEvent *)theEvent {
110 | [super mouseDown:theEvent];
111 |
112 | NSPoint location = [self mouseLocationOutsideOfEventStream];
113 | NSInteger height = self.frame.size.height;
114 |
115 | cocoaEventMouseUp((int)[self windowNumber], Middle, location.x, height - location.y);
116 | }
117 |
118 | /**
119 | * Mouse move events
120 | */
121 |
122 | -(void) mouseMoved:(NSEvent *)theEvent {
123 | [super mouseDown:theEvent];
124 |
125 | NSRect windowLocation = [self frame];
126 | NSPoint location = [self mouseLocationOutsideOfEventStream];
127 | NSInteger height = self.frame.size.height;
128 |
129 | if (location.x >= 0 &&
130 | location.y >= 0 &&
131 | location.x <= windowLocation.size.width &&
132 | location.y <= windowLocation.size.height
133 | ) {
134 | cocoaEventMouseMove((int)[self windowNumber], location.x, height - location.y);
135 | }
136 | }
137 |
138 | -(void)windowResized:(NSNotification *)notification {
139 | NSRect contentRect = [self contentRectForFrameRect: [self frame]];
140 | cocoaEventOnResize((int)[self windowNumber], contentRect.size.width, contentRect.size.height);
141 | }
142 |
143 | -(void) windowMoved:(NSNotification *)notification {
144 | NSRect contentRect = [self frame];
145 | NSInteger height = [[self screen] frame].size.height;
146 |
147 | cocoaEventOnMove((int)[self windowNumber], contentRect.origin.x, height - (contentRect.origin.y + contentRect.size.height));
148 | }
149 |
150 | -(void) forceRedraw:(NSNotification *)notification {
151 | cocoaEventForceRedraw((int)[self windowNumber]);
152 | }
153 |
154 | -(void) keyDown:(NSEvent *)theEvent {
155 | uint8 modifiers = [self _getModifierFromCode: [theEvent modifierFlags]];
156 | enum CocoaKeys key = [self _getKeyFromKeyCode: [theEvent keyCode]];
157 |
158 | cocoaEventOnKeyDown((int)[self windowNumber], modifiers, key);
159 | }
160 |
161 | -(void) keyUp:(NSEvent *)theEvent {
162 | uint8 modifiers = [self _getModifierFromCode: [theEvent modifierFlags]];
163 | enum CocoaKeys key = [self _getKeyFromKeyCode: [theEvent keyCode]];
164 |
165 | cocoaEventOnKeyUp((int)[self windowNumber], modifiers, key);
166 | }
167 |
168 | - (BOOL)windowShouldClose:(id)sender {
169 | cocoaEventOnClose((int)[self windowNumber]);
170 | return NO;
171 | }
172 |
173 | - (uint8) _getModifierFromCode: (NSEventModifierFlags) modifiers {
174 | uint8 ret = 0;
175 |
176 | if (modifiers & NSAlphaShiftKeyMask || modifiers & NSShiftKeyMask) {
177 | ret |= Shift;
178 | }
179 |
180 | if (modifiers & NSControlKeyMask) {
181 | ret |= Control;
182 | }
183 |
184 | if (modifiers & NSAlternateKeyMask) {
185 | ret |= Alt;
186 | }
187 |
188 | if (modifiers & NSCommandKeyMask) {
189 | ret |= Super;
190 | }
191 |
192 | return ret;
193 | }
194 |
195 | - (enum CocoaKeys) _getKeyFromKeyCode: (unsigned int) keyCode {
196 | enum CocoaKeys ret = Unknown;
197 |
198 | switch(keyCode) {
199 | /*
200 | * ASFDGHJKL;'
201 | */
202 |
203 | case 0:
204 | ret = A;
205 | break;
206 | case 1:
207 | ret = S;
208 | break;
209 | case 2:
210 | ret = D;
211 | break;
212 | case 3:
213 | ret = F;
214 | break;
215 | case 5:
216 | ret = G;
217 | break;
218 | case 4:
219 | ret = H;
220 | break;
221 | case 38:
222 | ret = J;
223 | break;
224 | case 40:
225 | ret = K;
226 | break;
227 | case 37:
228 | ret = L;
229 | break;
230 | case 41:
231 | ret = Semicolon;
232 | break;
233 | case 39:
234 | ret = Quote;
235 | break;
236 |
237 | /*
238 | *ZXCVBNM,./
239 | */
240 |
241 | case 6:
242 | ret = Z;
243 | break;
244 | case 7:
245 | ret = X;
246 | break;
247 | case 8:
248 | ret = C;
249 | break;
250 | case 9:
251 | ret = V;
252 | break;
253 | case 11:
254 | ret = B;
255 | break;
256 | case 45:
257 | ret = N;
258 | break;
259 | case 46:
260 | ret = M;
261 | break;
262 | case 43:
263 | ret = Comma;
264 | break;
265 | case 47:
266 | ret = Period;
267 | break;
268 | case 44:
269 | ret = Slash;
270 | break;
271 |
272 | /*
273 | * QWERTYUIOP[]\
274 | */
275 |
276 | case 12:
277 | ret = Q;
278 | break;
279 | case 13:
280 | ret = W;
281 | break;
282 | case 14:
283 | ret = E;
284 | break;
285 | case 15:
286 | ret = R;
287 | break;
288 | case 17:
289 | ret = T;
290 | break;
291 | case 16:
292 | ret = Y;
293 | break;
294 | case 32:
295 | ret = U;
296 | break;
297 | case 34:
298 | ret = LetterI;
299 | break;
300 | case 31:
301 | ret = O;
302 | break;
303 | case 35:
304 | ret = P;
305 | break;
306 | case 33:
307 | ret = LeftBracket;
308 | break;
309 | case 30:
310 | ret = RightBracket;
311 | break;
312 | case 42:
313 | ret = Backslash;
314 | break;
315 |
316 | /*
317 | * `1234567890-=
318 | */
319 |
320 | case 50:
321 | ret = Tilde;
322 | break;
323 | case 18:
324 | ret = Number1;
325 | break;
326 | case 19:
327 | ret = Number2;
328 | break;
329 | case 20:
330 | ret = Number3;
331 | break;
332 | case 21:
333 | ret = Number4;
334 | break;
335 | case 23:
336 | ret = Number5;
337 | break;
338 | case 22:
339 | ret = Number6;
340 | break;
341 | case 26:
342 | ret = Number7;
343 | break;
344 | case 28:
345 | ret = Number8;
346 | break;
347 | case 25:
348 | ret = Number9;
349 | break;
350 | case 29:
351 | ret = Number0;
352 | break;
353 | case 27:
354 | ret = Hyphen;
355 | break;
356 | case 24:
357 | ret = Equals;
358 | break;
359 |
360 | /*
361 | * Escape, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12
362 | */
363 |
364 | case 53:
365 | ret = Escape;
366 | break;
367 | case 122:
368 | ret = F1;
369 | break;
370 | case 120:
371 | ret = F2;
372 | break;
373 | case 99:
374 | ret = F3;
375 | break;
376 | case 118:
377 | ret = F4;
378 | break;
379 | case 96:
380 | ret = F5;
381 | break;
382 | case 97:
383 | ret = F6;
384 | break;
385 | case 98:
386 | ret = F7;
387 | break;
388 | case 100:
389 | ret = F8;
390 | break;
391 | case 101:
392 | ret = F9;
393 | break;
394 | case 109:
395 | ret = F10;
396 | break;
397 | case 103:
398 | ret = F11;
399 | break;
400 | case 111:
401 | ret = F12;
402 | break;
403 |
404 | /*
405 | * Enter, Tab, BackSpace, Space
406 | */
407 |
408 | case 36:
409 | ret = Enter;
410 | break;
411 | case 48:
412 | ret = Tab;
413 | break;
414 | case 51:
415 | ret = Backspace;
416 | break;
417 | case 49:
418 | ret = Space;
419 | break;
420 |
421 | /*
422 | * Arrows: left, right, up, down
423 | */
424 |
425 | case 126:
426 | ret = LeftArrow;
427 | break;
428 | case 123:
429 | ret = RightArrow;
430 | break;
431 | case 124:
432 | ret = UpArrow;
433 | break;
434 | case 125:
435 | ret = DownArrow;
436 | break;
437 | }
438 |
439 | return ret;
440 | }
441 |
442 | @end
443 |
--------------------------------------------------------------------------------
/cocoa_library/project/dwc-osxTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | rikki-cattermole.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/dub.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "de_window",
3 | "description": "Provides window and OpenGL context creation cross platform.",
4 | "copyright": "Copyright © 2014, Richard Andrew Cattermole, Devisualization",
5 | "authors": ["Richard Andrew Cattermole"],
6 | "homepage": "https://github.com/Devisualization/window",
7 | "license": "MIT",
8 | "targetType": "none",
9 | "sourcePaths": [],
10 | "buildRequirements": ["noDefaultFlags"],
11 | "subPackages": [
12 | {
13 | "name": "interfaces",
14 | "sourcePaths": ["interfaces"],
15 | "importPaths": ["interfaces"],
16 | "dependencies": {
17 | "de_image:interfaces": ">=0.4.2"
18 | }
19 | },
20 | {
21 | "name": "platform",
22 | "targetType": "sourceLibrary",
23 |
24 | "sourcePaths-windows": ["platforms/win32", "WindowsAPI"],
25 | "importPaths-windows": ["platforms/win32", "WindowsAPI"],
26 | "libs-windows": ["gdi32", "user32"],
27 |
28 | "sourcePaths-linux": ["platforms/linux"],
29 | "importPaths-linux": ["platforms/linux"],
30 | "libs-linux": ["Xrandr"],
31 |
32 | "dependencies-linux": {
33 | "x11": "~master"
34 | },
35 |
36 | "sourcePaths-osx": ["platforms/macosx"],
37 | "importPaths-osx": ["platforms/macosx"],
38 | "lflags-osx": ["/System/Library/Frameworks/Cocoa.framework/Cocoa"],
39 | "sourceFiles-osx": ["cocoa_library/bin/Debug/libdwc-osx.a"],
40 |
41 | "dependencies": {
42 | "de_window:interfaces": "*",
43 | "derelict-gl3": ">=1.0.12",
44 | "de_util:core": ">=0.0.7"
45 | },
46 |
47 | "configurations": [
48 | {
49 | "name": "opengl"
50 | },
51 | {
52 | "name": "directx",
53 | "platforms": ["windows"],
54 |
55 | "libs-windows": ["d3dcompiler", "d3d11", "dxgi"],
56 |
57 | "dependencies-windows": {
58 | "directx-d": ">=0.9.1"
59 | }
60 | }
61 | ]
62 | },
63 | {
64 | "name": "test",
65 | "sourcePaths": ["test"],
66 | "importPaths": ["test"],
67 | "targetType": "executable",
68 | "dependencies": {
69 | "de_window:platform": "*",
70 | "de_image:mutable": "*"
71 | }
72 | }
73 | ]
74 | }
75 |
--------------------------------------------------------------------------------
/interfaces/devisualization/window/interfaces/context.d:
--------------------------------------------------------------------------------
1 | /**
2 | * Context related interfaces.
3 | *
4 | * Authors:
5 | * Richard Andrew Cattermole
6 | *
7 | * License:
8 | * The MIT License (MIT)
9 | *
10 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
11 | *
12 | * Permission is hereby granted, free of charge, to any person obtaining a copy
13 | * of this software and associated documentation files (the "Software"), to deal
14 | * in the Software without restriction, including without limitation the rights
15 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 | * copies of the Software, and to permit persons to whom the Software is
17 | * furnished to do so, subject to the following conditions:
18 | *
19 | * The above copyright notice and this permission notice shall be included in all
20 | * copies or substantial portions of the Software.
21 | *
22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 | * SOFTWARE.
29 | */
30 | module devisualization.window.interfaces.context;
31 | import devisualization.image.image;
32 |
33 | /**
34 | * The type of context available.
35 | */
36 | enum WindowContextType : ushort {
37 | /**
38 | * No context to be used.
39 | */
40 | None = 0,
41 |
42 | /**
43 | * Both legacy (1.x .. 2.x) and 3+ contexts for OpenGL.
44 | * 3+ preferred if only one available.
45 | */
46 | Opengl = OpenglLegacy | Opengl3Plus,
47 |
48 | /**
49 | * Direct3D context.
50 | * Highly unlikely implemented.
51 | */
52 | Direct3D = 1 << 1,
53 |
54 | /**
55 | * Legacy OpenGL context (1.x .. 2.x)
56 | */
57 | OpenglLegacy = 1 << 2,
58 |
59 | /**
60 | * OpenGL context 3+
61 | */
62 | Opengl3Plus = 1 << 3,
63 |
64 | /**
65 | * A 2d buffer is provided to draw into
66 | */
67 | Buffer2D = 1 << 4
68 | }
69 |
70 | /**
71 | * Context definition for a 3d rendering toolkit.
72 | */
73 | interface IContext {
74 | @property {
75 | /**
76 | * Activates the context for use.
77 | */
78 | void activate();
79 |
80 | /**
81 | * Destroys a context.
82 | */
83 | void destroy();
84 |
85 | /**
86 | * Swap the buffers, to make the output display.
87 | */
88 | void swapBuffers();
89 |
90 | /**
91 | * What type of context is this?
92 | *
93 | * Returns:
94 | * The context type.
95 | */
96 | WindowContextType type();
97 |
98 | /**
99 | * Version of the toolkit being used.
100 | *
101 | * Returns:
102 | * The toolkit version.
103 | * This is implementation defined with no clear structure.
104 | * Is for debugging/logging and should not be relied upon.
105 | */
106 | string toolkitVersion();
107 |
108 | /**
109 | * Version of the shading language available
110 | *
111 | * Returns:
112 | * The shader language version.
113 | * This is implementation defined with no clear structure.
114 | * IS for debugging/logging and should not be relied upon.
115 | */
116 | string shadingLanguageVersion();
117 | }
118 | }
119 |
120 | /**
121 | * Allows for drawing into a predefined buffer for 2d operations
122 | */
123 | interface ContextBuffer2D : IContext {
124 | @property {
125 | /**
126 | * Buffer to draw into.
127 | * Default value will be null. Must be set first before using.
128 | *
129 | * Returns:
130 | * The buffer that can be drawn into.
131 | * Will not clear between swapping of buffers.
132 | */
133 | ref Image buffer();
134 |
135 | /**
136 | * Sets the buffer to draw into.
137 | *
138 | * Params:
139 | * buffer = The image buffer to draw into
140 | */
141 | void buffer(Image buffer);
142 | }
143 | }
--------------------------------------------------------------------------------
/interfaces/devisualization/window/interfaces/eventable.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.interfaces.eventable;
25 | import std.string : toUpper;
26 | import std.algorithm : filter, moveAll;
27 |
28 | /**
29 | * Provides an interface version of an eventing mechanism.
30 | *
31 | * See_Also:
32 | * Eventing
33 | */
34 | mixin template IEventing(string name, T...) {
35 | mixin("void add" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ q{(bool delegate(T));});
36 | mixin("void add" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ q{(void delegate(T));});
37 |
38 | mixin("void remove" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ q{(bool delegate(T));});
39 | mixin("void remove" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ q{(void delegate(T));});
40 |
41 | mixin("size_t count" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ "();");
42 |
43 | mixin("void clear" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ q{();});
44 |
45 | static if (__traits(compiles, typeof(this)) && is(typeof(this) : T[0])) {
46 | mixin("void " ~ name ~ q{(T[1 .. $] args);});
47 | } else {
48 | mixin("void " ~ name ~ q{(T args);});
49 | }
50 | }
51 |
52 |
53 | /**
54 | * Implements an eventable interface for something.
55 | * Includes support for bool delegate(T) and void delegate(T).
56 | * Will consume a call to all delegates if it returns true. Default false.
57 | *
58 | * Example usage:
59 | * mixin Eventing!("onNewListing", ListableObject);
60 | *
61 | * If is(T[0] == typeof(this)) then it'll use this as being the first argument.
62 | */
63 | mixin template Eventing(string name, T...) {
64 | private {
65 | mixin(q{bool delegate(T)[] } ~ name ~ "_;");
66 | mixin(q{bool delegate(T)[size_t] } ~ name ~ "_assoc;");
67 |
68 | union ptrToSizeT {
69 | void delegate(T) from;
70 | size_t value;
71 | }
72 | }
73 |
74 | mixin("void add" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ q{(void delegate(T) value) {
75 | mixin(name ~ "_ ~= (T args) => {value(args); return false;}();");
76 | mixin(name ~ "_assoc[ptrToSizeT(value).value] = " ~ name ~ "_[$-1];");
77 | }});
78 |
79 | mixin("void add" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ q{(bool delegate(T) value) {
80 | mixin(name ~ "_ ~= value;");
81 | }});
82 |
83 | mixin("void remove" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ q{(bool delegate(T) value) {
84 | import std.range : walkLength;
85 |
86 | mixin("auto t = filter!(a => a !is value)(" ~ name ~ "_);");
87 | t.moveAll(mixin(name ~ "_"));
88 | mixin(name ~ "_.length = t.walkLength;");
89 | }});
90 |
91 | mixin("void remove" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ q{(void delegate(T) value) {
92 | if (ptrToSizeT(value).value in mixin(name ~ "_assoc")) {
93 | mixin("remove" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ "(" ~ name ~ "_assoc[ptrToSizeT(value).value]);");
94 | mixin(name ~ "_assoc.remove(ptrToSizeT(value).value);");
95 | }
96 | }});
97 |
98 | mixin("size_t count" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ q{(){
99 | return cast(size_t)(mixin(name ~ "_.length") + mixin(name ~ "_assoc.length"));
100 | }});
101 |
102 | mixin("void clear" ~ toUpper(name[0] ~ "") ~ name[1 ..$] ~ q{() {
103 | mixin(name ~ "_") = [];
104 | }});
105 |
106 | static if (__traits(compiles, typeof(this)) && is(typeof(this) : T[0])) {
107 | mixin("void " ~ name ~ q{(T[1 .. $] args) {
108 | foreach (del; mixin(name ~ "_")) {
109 | if (del(this, args))
110 | return;
111 | }
112 | }});
113 | } else {
114 | mixin("void " ~ name ~ q{(T args) {
115 | foreach (del; mixin(name ~ "_")) {
116 | if (del(args))
117 | return;
118 | }
119 | }});
120 | }
121 | }
--------------------------------------------------------------------------------
/interfaces/devisualization/window/interfaces/events.d:
--------------------------------------------------------------------------------
1 | /**
2 | * Types that identify events values
3 | *
4 | * Authors:
5 | * Richard Andrew Cattermole
6 | *
7 | * License:
8 | * The MIT License (MIT)
9 | *
10 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
11 | *
12 | * Permission is hereby granted, free of charge, to any person obtaining a copy
13 | * of this software and associated documentation files (the "Software"), to deal
14 | * in the Software without restriction, including without limitation the rights
15 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 | * copies of the Software, and to permit persons to whom the Software is
17 | * furnished to do so, subject to the following conditions:
18 | *
19 | * The above copyright notice and this permission notice shall be included in all
20 | * copies or substantial portions of the Software.
21 | *
22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 | * SOFTWARE.
29 | */
30 | module devisualization.window.interfaces.events;
31 |
32 | /**
33 | * Identifies mouse buttons by name.
34 | */
35 | enum MouseButtons {
36 | Left,
37 | Right,
38 | Middle
39 | }
40 |
41 | /**
42 | * Bitwised key modifiers.
43 | * Expected to be combined to modify how a key is represented.
44 | *
45 | * See_Also:
46 | * Keys
47 | */
48 | enum KeyModifiers : ubyte {
49 | None = 1 << 0,
50 | Shift = 1 << 1,
51 | Control = 1 << 2,
52 | Alt = 1 << 3,
53 | Super = 1 << 4
54 | }
55 |
56 | /**
57 | * Known keys to be handled by most operating system using a 101 key keyboard.
58 | */
59 | enum Keys {
60 | Unknown,
61 | F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
62 | A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
63 | Number0, Number1, Number2, Number3, Number4, Number5, Number6, Number7, Number8, Number9,
64 | LeftBracket, RightBracket, Semicolon, Comma, Period, Quote, Slash, Backslash, Tilde, Equals, Hyphen,
65 | Escape, Space, Enter, Backspace, Tab, PageUp, PageDown, End, Home, Insert, Delete, Pause,
66 | Left, Right, Up, Down,
67 | Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9,
68 | Add, Subtract, Multiply, Divide
69 | }
--------------------------------------------------------------------------------
/interfaces/devisualization/window/interfaces/window.d:
--------------------------------------------------------------------------------
1 | /**
2 | * Declared the majority of the interfaces for Devisualization.Window
3 | *
4 | * Authors:
5 | * Richard Andrew Cattermole
6 | *
7 | * License:
8 | * The MIT License (MIT)
9 | *
10 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
11 | *
12 | * Permission is hereby granted, free of charge, to any person obtaining a copy
13 | * of this software and associated documentation files (the "Software"), to deal
14 | * in the Software without restriction, including without limitation the rights
15 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 | * copies of the Software, and to permit persons to whom the Software is
17 | * furnished to do so, subject to the following conditions:
18 | *
19 | * The above copyright notice and this permission notice shall be included in all
20 | * copies or substantial portions of the Software.
21 | *
22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 | * SOFTWARE.
29 | *
30 | * Examples:
31 | * To create a window without an OpenGL context:
32 | * ---
33 | * Windowable window = new Window(800, 600, "My window!"w, 100, 100);
34 | * window.show();
35 | * Window.messageLoop();
36 | * ---
37 | *
38 | * This runs the message loop after showing the window.
39 | * Does nothing with events. Or show any content.
40 | */
41 | module devisualization.window.interfaces.window;
42 | import devisualization.window.interfaces.eventable;
43 | public import devisualization.window.interfaces.events;
44 | import devisualization.window.interfaces.context;
45 |
46 | /**
47 | * Arguments to create a window.
48 | * Some may be optional.
49 | *
50 | * A minimum width and height should be supplied.
51 | *
52 | * See_Also:
53 | * Windowable
54 | */
55 | struct WindowConfig {
56 | /**
57 | * Width of the window to create.
58 | * Must be atleast 0 (px).
59 | */
60 | uint width;
61 |
62 | /**
63 | * Height of the window to create.
64 | * Must be atleast 0 (px).
65 | */
66 | uint height;
67 |
68 | /**
69 | * The title of the window to create.
70 | * Commonly a UTF-8 support should be available.
71 | * However if not ASCII will be used. Which is effectively a string.
72 | * Assume ASCII values are safe as a value.
73 | *
74 | * Default:
75 | * "A DWC window"
76 | */
77 | wstring title = "A DWC window";
78 |
79 | /**
80 | * The x position of the window to be created.
81 | * It is possible that this is ignored by the implementation.
82 | *
83 | * Default:
84 | * 0 (px)
85 | */
86 | int x;
87 |
88 | /**
89 | * The y position of the window to be created.
90 | * It is possible that this is ignored by the implementation.
91 | *
92 | * Default:
93 | * 0 (px)
94 | */
95 | int y;
96 |
97 | /**
98 | * Specifies the type of context to create. Validated by the window implementation.
99 | *
100 | * Default:
101 | * None
102 | */
103 | WindowContextType contextType;
104 |
105 | /**
106 | * Forces width and height to be atleast 0 (px).
107 | */
108 | invariant() {
109 | assert(width > 0, "Should a window really have a 0px width?");
110 | assert(height > 0, "Should a window really have a 0px height?");
111 | }
112 | }
113 |
114 | /**
115 | * A generic window interface.
116 | *
117 | * Should be supportive of majority of windowing toolkits in existance.
118 | * Is unaware of screens.
119 | *
120 | * Implementation should support two constructors:
121 | * ---
122 | * this(T...)(T config) { this(WindowConfig(config)); }
123 | * this(WindowConfig config);
124 | * ---
125 | *
126 | * Events_Mechanism:
127 | * A window support a set number of events.
128 | * From those the event offer set functionality to manipulate them.
129 | *
130 | * Adds a listener on an event
131 | * ---
132 | * void addEventName(void delegate(T));
133 | * void addEventName(bool delegate(T));
134 | * ---
135 | *
136 | * Removes the provided listener
137 | * ---
138 | * void removeEventName(bool delegate(T));
139 | * void removeEventName(void delegate(T));
140 | * ---
141 | *
142 | * Counts how many listeners for an event
143 | * ---
144 | * size_t countEventName();
145 | * ---
146 | *
147 | * Runs the event for all listeners with the given arguments
148 | * ---
149 | * void eventName(T);
150 | * ---
151 | *
152 | * Clears all listeners for an event
153 | * ---
154 | * void clearEventName();
155 | * ---
156 | *
157 | * Optionally will also support:
158 | * ---
159 | * void eventName(T[1 .. $]);
160 | * ---
161 | * Where T[0] is Windowable.
162 | * This will run the event and pass in as first argument this (Windowable).
163 | *
164 | * Events:
165 | * Upon the message loop drawing period this is called.
166 | * onDraw = Windowable
167 | *
168 | * When the message loop is informed the window has moved, this is called.
169 | * onMove = Windowable, int x, int y
170 | *
171 | * When the message loop is informed the window has resized, this is called.
172 | * onResize = Windowable, uint newWidth, uint newHeight
173 | *
174 | * When the window has been requested to be closed from the user, this is called.
175 | * On this event Windowable.close must be called manually.
176 | * onClose = Windowable
177 | */
178 | interface Windowable {
179 | import devisualization.image;
180 |
181 | //this(T...)(T config) { this(WindowConfig(config)); }
182 | //this(WindowConfig);
183 |
184 | static {
185 | /**
186 | * Continues iteration of the message loop.
187 | *
188 | * This is expected functionality provided from the implementation.
189 | */
190 | void messageLoop();
191 |
192 | /**
193 | * A single iteration of the message loop.
194 | *
195 | * This is expected functionality provided from the implementation.
196 | */
197 | void messageLoopIteration();
198 | }
199 |
200 | /**
201 | * Hides the window.
202 | *
203 | * See_Also:
204 | * hide
205 | */
206 | void show();
207 |
208 | /**
209 | * Shows the window.
210 | *
211 | * See_Also:
212 | * close
213 | */
214 | void hide();
215 |
216 | /*
217 | * Window
218 | */
219 |
220 | mixin IEventing!("onDraw", Windowable);
221 | mixin IEventing!("onMove", Windowable, int, int);
222 | mixin IEventing!("onResize", Windowable, uint, uint);
223 | mixin IEventing!("onClose", Windowable);
224 |
225 | /*
226 | * Mouse
227 | */
228 |
229 | mixin IEventing!("onMouseDown", Windowable, MouseButtons, int, int);
230 | mixin IEventing!("onMouseMove", Windowable, int, int);
231 | mixin IEventing!("onMouseUp", Windowable, MouseButtons);
232 |
233 | /*
234 | * Keyboard
235 | * KeyModifiers is an or'd mask or modifiers upon the key
236 | */
237 |
238 | mixin IEventing!("onKeyDown", Windowable, Keys, KeyModifiers);
239 | mixin IEventing!("onKeyUp", Windowable, Keys, KeyModifiers);
240 |
241 | @property {
242 |
243 | /**
244 | * Sets the title text.
245 | *
246 | * Params:
247 | * text = The text to set the title of the window to
248 | */
249 | void title(string text);
250 |
251 | /**
252 | * Sets the title text.
253 | *
254 | * Params:
255 | * text = The text to set the title of the window to
256 | */
257 | void title(dstring text);
258 |
259 | /**
260 | * Sets the title text.
261 | *
262 | * Params:
263 | * text = The text to set the title of the window to
264 | */
265 | void title(wstring text);
266 |
267 | /**
268 | * Resize the window.
269 | *
270 | * Does not animate.
271 | *
272 | * Params:
273 | * width = The width to set to
274 | * height = The height to set to
275 | */
276 | void size(uint width, uint height);
277 |
278 | /**
279 | * Move the window to coordinate.
280 | *
281 | * Coordinate system based upon Top left corner of screen.
282 | * Does not support screens (could be moved outside main screen).
283 | * Coordinates can be negative, but is dependent upon the OS.
284 | *
285 | * Params:
286 | * x = The x coordinate to move to
287 | * y = The y coordinate to move to
288 | */
289 | void move(int x, int y);
290 |
291 | /**
292 | * Enable / disable resizing of the window.
293 | *
294 | * Params:
295 | * can = Is it possible to resize the window (default yes)
296 | */
297 | void canResize(bool can = true);
298 |
299 | /**
300 | * Go into/out fullscreen
301 | *
302 | * Params:
303 | * isFullscreen = Should be fullscreen (default yes)
304 | */
305 | void fullscreen(bool isFullscreen = true);
306 |
307 | /**
308 | * Closes the window.
309 | * The window cannot reopened once closed.
310 | *
311 | * See_Also:
312 | * hide
313 | */
314 | void close();
315 |
316 | /**
317 | * Has the window been closed?
318 | *
319 | * Returns:
320 | * True if close has been called
321 | *
322 | * See_Also:
323 | * close
324 | */
325 | bool hasBeenClosed();
326 |
327 | /**
328 | * Gets the current context that the window has open or null for none.
329 | *
330 | * Returns:
331 | * A context that has a buffer that can be swapped and activated once created
332 | */
333 | IContext context();
334 | }
335 |
336 | /**
337 | * Sets the icon for the window.
338 | * Supports transparency.
339 | *
340 | * Params:
341 | * image = The image (from Devisualization.Image).
342 | */
343 | void icon(Image image);
344 |
345 | /**
346 | * Sets the icon for the window.
347 | * Supports transparency.
348 | *
349 | * Params:
350 | * width = The width of the icon
351 | * height = The height of the icon
352 | * data = rgb data 0 .. 255, 3 bytes per pixel
353 | * transparent = The given pixel (3 bytes like data) color to use as transparency
354 | *
355 | * Deprecated:
356 | * Superseded by using Devisualization.Image's Image, as argument instead.
357 | */
358 | deprecated("Use Devisualization.Image method instead")
359 | void icon(ushort width, ushort height, ubyte[3][] data, ubyte[3]* transparent = null);
360 | }
361 |
362 | class WindowNotCreatable : Exception {
363 | @safe pure nothrow this(string file = __FILE__, size_t line = __LINE__, Throwable next = null) {
364 | super("Window failed to be created.", file, line, next);
365 | }
366 |
367 | @safe pure nothrow this(Throwable next, string file = __FILE__, size_t line = __LINE__) {
368 | super("Window failed to be created.", file, line, next);
369 | }
370 | }
--------------------------------------------------------------------------------
/platforms/linux/devisualization/window/context/buffer2d.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.context.buffer2d;
25 | import devisualization.window.window;
26 | import devisualization.window.interfaces.context;
27 |
28 | class Buffer2DContext : ContextBuffer2D {
29 | import devisualization.image.image;
30 |
31 | private {
32 | import xx11 = x11.X;
33 | import xlib = x11.Xlib;
34 | import xutil = x11.Xutil;
35 |
36 | Window window;
37 | xlib.Display* display;
38 | xlib.Window x11win;
39 | xlib.Pixmap pixmap;
40 |
41 | Image buffer_;
42 | ubyte[4][] bufferdata;
43 | xlib.XImage* txImage;
44 | }
45 |
46 | this(Window window, WindowConfig config) {
47 | this.window = window;
48 | x11win = window.x11Window();
49 | display = window.x11Display();
50 |
51 | pixmap = xlib.XCreatePixmap(display, x11win, config.width, config.height, 24);
52 |
53 | buffer_ = null;
54 | activate();
55 | }
56 |
57 | @property {
58 | void activate() {}
59 |
60 | void destroy() {}
61 |
62 | void swapBuffers() {
63 | if (buffer_ !is null) {
64 |
65 | if (bufferdata.length != buffer_.rgba.length) {
66 | // delete old image used for buffer
67 | if (txImage !is null)
68 | xutil.XDestroyImage(txImage);
69 |
70 | // create a new buffer
71 | ubyte[4][] tbufferdata;
72 | tbufferdata.length = buffer_.rgba.length;
73 | bufferdata = tbufferdata;
74 |
75 | txImage = xlib.XCreateImage(display, cast(xlib.Visual*)&pixmap, 24, xx11.XYPixmap, 0, cast(char*)bufferdata[0].ptr, cast(uint)buffer_.width, cast(uint)buffer_.height, 32, 0);
76 | }
77 |
78 | foreach(i, pixel; buffer_.rgba.allPixels) {
79 | bufferdata[i][0] = pixel.b_ubyte;
80 | bufferdata[i][1] = pixel.g_ubyte;
81 | bufferdata[i][2] = pixel.r_ubyte;
82 | bufferdata[i][3] = pixel.a_ubyte;
83 | }
84 |
85 | xlib.XPutImage(display, x11win, xlib.DefaultGC(display, 0), txImage, 0, 0, 0, 0, cast(uint)buffer_.width, cast(uint)buffer_.height);
86 | xlib.XSetWindowBackgroundPixmap(display, x11win, pixmap);
87 | }
88 | }
89 |
90 | WindowContextType type() { return WindowContextType.Buffer2D; }
91 | string toolkitVersion() { return null; }
92 | string shadingLanguageVersion() { return null; }
93 |
94 | ref Image buffer() { return buffer_; }
95 | void buffer(Image buffer) { buffer_ = buffer; }
96 | }
97 | }
--------------------------------------------------------------------------------
/platforms/linux/devisualization/window/context/opengl.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.context.opengl;
25 | import devisualization.window.window;
26 | import devisualization.window.interfaces.context;
27 |
28 | private {
29 | bool loadedDGL;
30 | }
31 |
32 | class OpenglContext : IContext {
33 | private {
34 | import derelict.opengl3.gl;
35 | import dglx = derelict.opengl3.glx;
36 | import dxtypes = derelict.util.xtypes;
37 |
38 | import xx11 = x11.X;
39 | import xlib = x11.Xlib;
40 |
41 | dxtypes.XVisualInfo* vi;
42 | dglx.GLXContext glc;
43 | xlib.Display* display;
44 | xlib.Window window;
45 | }
46 |
47 | this(Window window, WindowConfig config) {
48 | if (!loadedDGL) {
49 | DerelictGL.load();
50 | loadedDGL = true;
51 | }
52 | this.window = window.x11Window;
53 | display = window.x11Display;
54 |
55 | int[] att = [dglx.GLX_RGBA, dglx.GLX_DEPTH_SIZE, 24, dglx.GLX_DOUBLEBUFFER, xx11.None];
56 | vi = dglx.glXChooseVisual(display, 0, att.ptr);
57 |
58 | glc = dglx.glXCreateContext(display, vi, null, GL_TRUE);
59 |
60 | activate();
61 | }
62 |
63 | @property {
64 | void activate() {
65 | dglx.glXMakeCurrent(display, cast(uint)window, glc);
66 | DerelictGL.reload();
67 | }
68 |
69 | void destroy() {
70 | xlib.XFree(vi);
71 | dglx.glXDestroyContext(display, glc);
72 | }
73 |
74 | void swapBuffers() {
75 | glFlush();
76 | dglx.glXSwapBuffers(display, cast(uint)window);
77 | }
78 |
79 | WindowContextType type() { return WindowContextType.Opengl; }
80 |
81 | string toolkitVersion() {
82 | char[] str;
83 | const(char*) c = glGetString(GL_VERSION);
84 | size_t i;
85 |
86 | if (c !is null) {
87 | while (c[i] != '\0') {
88 | str ~= c[i];
89 | i++;
90 | }
91 | }
92 |
93 | return str.idup;
94 | }
95 |
96 | string shadingLanguageVersion() {
97 | char[] str;
98 | const(char*) c = glGetString(GL_SHADING_LANGUAGE_VERSION);
99 | size_t i;
100 |
101 | if (c !is null) {
102 | while (c[i] != '\0') {
103 | str ~= c[i];
104 | i++;
105 | }
106 | }
107 |
108 | return str.idup;
109 | }
110 |
111 | string[] extensions() {
112 | string[] ret;
113 |
114 | char[] str;
115 | const(char*) c = glGetString(GL_SHADING_LANGUAGE_VERSION);
116 | size_t i;
117 |
118 | if (c !is null) {
119 | while (c[i] != '\0') {
120 | if (c[i] == ' ') {
121 | ret ~= str.idup;
122 | str.length = 0;
123 | } else {
124 | str ~= c[i];
125 | }
126 | i++;
127 | }
128 | }
129 |
130 | return ret;
131 | }
132 | }
133 | }
--------------------------------------------------------------------------------
/platforms/linux/devisualization/window/context/package.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.context;
25 | public import devisualization.window.context.opengl;
26 | public import devisualization.window.context.buffer2d;
--------------------------------------------------------------------------------
/platforms/linux/devisualization/window/window.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.window;
25 | import devisualization.window.context;
26 | import devisualization.window.interfaces.window;
27 | import devisualization.window.interfaces.eventable;
28 | public import devisualization.window.interfaces.window : WindowConfig, Windowable;
29 | public import devisualization.window.interfaces.events : MouseButtons, Keys, KeyModifiers;
30 | public import devisualization.window.interfaces.context : WindowContextType, IContext;
31 | import std.conv : to;
32 |
33 | private {
34 | import xlib = x11.Xlib;
35 | import xx11 = x11.X;
36 | import xutil = x11.Xutil;
37 | import xrandr = x11.extensions.Xrandr;
38 | }
39 |
40 | class Window : Windowable {
41 | private {
42 | xlib.Window wind_;
43 | int screen_;
44 |
45 | string lastTitle;
46 |
47 | int lastX, lastY, lastWidth, lastHeight;
48 | xrandr.SizeID oldVideoMode;
49 |
50 | bool hasBeenClosed_;
51 | xlib.Atom closeAtom_;
52 |
53 | IContext context_;
54 | }
55 |
56 | this(T...)(T config) { this(WindowConfig(config)); }
57 |
58 | this(WindowConfig config) {
59 | lastX = config.x;
60 | lastY = config.y;
61 | lastWidth = config.width;
62 | lastHeight = config.height;
63 | wind_ = createWindow(config.x, config.y, config.width, config.height, screen_, closeAtom_);
64 | synchronized {
65 | dispToInsts[wind_] = this;
66 | }
67 |
68 | title = config.title;
69 |
70 | if ((config.contextType | WindowContextType.Opengl3Plus) == WindowContextType.Opengl3Plus || (config.contextType | WindowContextType.OpenglLegacy) == WindowContextType.OpenglLegacy) {
71 | // create Opengl context!
72 | context_ = new OpenglContext(this, config);
73 | } else if (config.contextType == WindowContextType.Direct3D) {
74 | // create Direct3d context!
75 | throw new Exception("Cannot create Direct3D context on non Windows targets");
76 | } else if (config.contextType == WindowContextType.Buffer2D) {
77 | context_ = new Buffer2DContext(this, config);
78 | }
79 | }
80 |
81 | static {
82 | void messageLoop() {
83 | import core.thread : Thread;
84 | import core.time : dur;
85 |
86 | while(true) {
87 | while(Window.messageLoopIteration()) {}
88 | Thread.sleep(dur!"msecs"(50));
89 | }
90 | }
91 |
92 | bool messageLoopIteration(uint minBlocking = 0, uint maxNonBlocking = 1) {
93 | xlib.XEvent e;
94 | uint i;
95 |
96 | void handleEvent() {
97 | if (e.type == xx11.Expose) {
98 | if (e.xexpose.window in dispToInsts) {
99 | Window window = dispToInsts[e.xexpose.window];
100 | if (!window.hasBeenClosed_)
101 | window.onDraw();
102 | }
103 | } else if (e.type == xx11.ConfigureNotify) {
104 | if (e.xconfigure.window in dispToInsts) {
105 | Window window = dispToInsts[e.xconfigure.window];
106 |
107 | if (!window.hasBeenClosed_) {
108 | if (window.lastX != e.xconfigure.x || window.lastY != e.xconfigure.y) {
109 | window.onMove(e.xconfigure.x, e.xconfigure.y);
110 | window.lastX = e.xconfigure.x;
111 | window.lastY = e.xconfigure.y;
112 | }
113 |
114 | if (window.lastWidth != e.xconfigure.width || window.lastHeight != e.xconfigure.height) {
115 | uint w = e.xconfigure.width;
116 | uint h = e.xconfigure.height;
117 | window.onResize(w, h);
118 | window.lastWidth = e.xconfigure.width;
119 | window.lastHeight = e.xconfigure.height;
120 | }
121 | }
122 | }
123 | } else if (e.type == xx11.ClientMessage) {
124 | if (e.xclient.window in dispToInsts) {
125 | Window window = dispToInsts[e.xclient.window];
126 | if (!window.hasBeenClosed_) {
127 | if (e.xclient.format == 32 && e.xclient.data.l[0] == window.closeAtom_) {
128 | window.onClose();
129 | if (window.countOnClose() == 0)
130 | window.close();
131 | }
132 | }
133 | }
134 | } else if (e.type == xx11.MotionNotify) {
135 | if (e.xmotion.window in dispToInsts) {
136 | Window window = dispToInsts[e.xmotion.window];
137 | if (!window.hasBeenClosed_) {
138 | window.onMouseMove(e.xmotion.x, e.xmotion.y);
139 | }
140 | }
141 | } else if (e.type == xx11.ButtonPress) {
142 | if (e.xbutton.window in dispToInsts) {
143 | Window window = dispToInsts[e.xbutton.window];
144 | if (!window.hasBeenClosed_) {
145 | MouseButtons button;
146 |
147 | switch(e.xbutton.button) {
148 | case xx11.Button2:
149 | button = MouseButtons.Middle;
150 | break;
151 |
152 | case xx11.Button3:
153 | button = MouseButtons.Right;
154 | break;
155 |
156 | case xx11.Button1:
157 | default:
158 | button = MouseButtons.Left;
159 | break;
160 | }
161 |
162 | window.onMouseDown(button, e.xbutton.x, e.xbutton.y);
163 | }
164 | }
165 | } else if (e.type == xx11.ButtonRelease) {
166 | if (e.xbutton.window in dispToInsts) {
167 | Window window = dispToInsts[e.xbutton.window];
168 | if (!window.hasBeenClosed_) {
169 | MouseButtons button;
170 |
171 | switch(e.xbutton.button) {
172 | case xx11.Button2:
173 | button = MouseButtons.Middle;
174 | break;
175 |
176 | case xx11.Button3:
177 | button = MouseButtons.Right;
178 | break;
179 |
180 | case xx11.Button1:
181 | default:
182 | button = MouseButtons.Left;
183 | break;
184 | }
185 |
186 | window.onMouseUp(button);
187 | }
188 | }
189 | } else if (e.type == xx11.KeyPress) {
190 | if (e.xkey.window in dispToInsts) {
191 | Window window = dispToInsts[e.xkey.window];
192 | if (!window.hasBeenClosed_) {
193 | xlib.KeySym symbol;
194 | xutil.XLookupString(cast(xlib.XKeyEvent*)(&e.xkey), null, 0, &symbol, null);
195 | window.onKeyDown(convertKeyFromXlibEvent(cast(uint)symbol), convertKeyFromXlibEventModifiers(e.xkey.state));
196 | }
197 | }
198 | } else if (e.type == xx11.KeyRelease) {
199 | if (e.xkey.window in dispToInsts) {
200 | Window window = dispToInsts[e.xkey.window];
201 | if (!window.hasBeenClosed_) {
202 | xlib.KeySym symbol;
203 | xutil.XLookupString(cast(xlib.XKeyEvent*)(&e.xkey), null, 0, &symbol, null);
204 | window.onKeyUp(convertKeyFromXlibEvent(cast(uint)symbol), convertKeyFromXlibEventModifiers(e.xkey.state));
205 | }
206 | }
207 | }
208 | }
209 |
210 | while (i < minBlocking) {
211 | xlib.XNextEvent(display_, &e);
212 | handleEvent();
213 |
214 | i++;
215 | }
216 |
217 | i = 0;
218 | while (i < maxNonBlocking) {
219 | if (xlib.XPending(display_) <= 0) {
220 | return false;
221 | }
222 |
223 | xlib.XNextEvent(display_, &e);
224 | handleEvent();
225 |
226 | i++;
227 | }
228 |
229 | return true;
230 | }
231 | }
232 |
233 | @property {
234 | xlib.Window x11Window()
235 | in {
236 | assert(!hasBeenClosed_);
237 | } body {
238 | return wind_;
239 | }
240 |
241 | xlib.Display* x11Display()
242 | in {
243 | assert(!hasBeenClosed_);
244 | } body {
245 | return display_;
246 | }
247 |
248 | int x11ScreenNumber()
249 | in {
250 | assert(!hasBeenClosed_);
251 | } body {
252 | return screen_;
253 | }
254 |
255 | xlib.Screen* x11Screen()
256 | in {
257 | assert(!hasBeenClosed_);
258 | } body {
259 | return xlib.XScreenOfDisplay(display_, screen_);
260 | }
261 |
262 | void title(string value)
263 | in {
264 | assert(!hasBeenClosed_);
265 | } body {
266 | lastTitle = value;
267 | xlib.XStoreName(display_, wind_, cast(char*)lastTitle.ptr);
268 | }
269 |
270 | void title(dstring value)
271 | in {
272 | assert(!hasBeenClosed_);
273 | } body {
274 | title(to!string(value));
275 | }
276 |
277 | void title(wstring value)
278 | in {
279 | assert(!hasBeenClosed_);
280 | } body {
281 | title(to!string(value));
282 | }
283 |
284 | void size(uint width, uint height)
285 | in {
286 | assert(!hasBeenClosed_);
287 | } body {
288 | xlib.XResizeWindow(display_, wind_, width, height);
289 | xlib.XFlush(display_);
290 | }
291 |
292 | void move(int x, int y)
293 | in {
294 | assert(!hasBeenClosed_);
295 | } body {
296 | xlib.XMoveWindow(display_, wind_, x, y);
297 | xlib.XFlush(display_);
298 | }
299 |
300 | void canResize(bool can = true)
301 | in {
302 | assert(!hasBeenClosed_);
303 | } body {
304 | WMHints hints;
305 | hints.Flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
306 | hints.Decorations = MWM_DECOR_TITLE;
307 | hints.Functions = MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE;
308 |
309 | if (can) {
310 | hints.Decorations |= MWM_DECOR_MAXIMIZE | MWM_DECOR_RESIZEH | MWM_DECOR_BORDER | MWM_DECOR_MINIMIZE;
311 | hints.Functions |= MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE;
312 | }
313 |
314 | xlib.Atom windowHints = xlib.XInternAtom(display_, cast(char*)"_MOTIF_WM_HINTS\0".ptr, false);
315 | xlib.XChangeProperty(display_, wind_, windowHints, windowHints, 32, xx11.PropModeReplace, cast(ubyte*)&hints, 5);
316 | }
317 |
318 | /**
319 | * Tempermental inside Virtualbox with XFCE
320 | */
321 | void fullscreen(bool isfs = true)
322 | in {
323 | assert(!hasBeenClosed_);
324 | } body {
325 | if (isfs) {
326 | xrandr.XRRScreenConfiguration* config = xrandr.XRRGetScreenInfo(display_, xlib.RootWindow(display_, screen_));
327 |
328 | xrandr.Rotation currentRotation;
329 | oldVideoMode = xrandr.XRRConfigCurrentConfiguration(config, ¤tRotation);
330 |
331 | int nbSizes;
332 | xrandr.XRRScreenSize* sizes = xrandr.XRRConfigSizes(config, &nbSizes);
333 | for (int i = 0; i < nbSizes; i++) {
334 | if (sizes[i].width == lastWidth && sizes[i].height == lastHeight) {
335 | xrandr.XRRSetScreenConfig(display_, config,xlib. RootWindow(display_, screen_), i, currentRotation, xx11.CurrentTime);
336 | break;
337 | }
338 | }
339 |
340 | xrandr.XRRFreeScreenConfigInfo(config);
341 | } else {
342 | xrandr.XRRScreenConfiguration* config = xrandr.XRRGetScreenInfo(display_, xlib.RootWindow(display_, screen_));
343 | xrandr.Rotation currentRotation;
344 | xrandr.XRRConfigCurrentConfiguration(config, ¤tRotation);
345 | xrandr.XRRSetScreenConfig(display_, config, xlib.RootWindow(display_, screen_), oldVideoMode, currentRotation, xx11.CurrentTime);
346 | xrandr.XRRFreeScreenConfigInfo(config);
347 | }
348 | }
349 |
350 | void close()
351 | in {
352 | assert(!hasBeenClosed_);
353 | } body {
354 | hide();
355 | synchronized {
356 | dispToInsts.remove(wind_);
357 | }
358 | xlib.XDestroyWindow(display_, wind_);
359 | hasBeenClosed_ = true;
360 | }
361 |
362 | IContext context()
363 | in {
364 | assert(!hasBeenClosed_);
365 | } body {
366 | return context_;
367 | }
368 |
369 | bool hasBeenClosed() { return hasBeenClosed_; }
370 | }
371 |
372 | override {
373 | void show()
374 | in {
375 | assert(!hasBeenClosed_);
376 | } body {
377 | xlib.XMapWindow(display_, wind_);
378 | }
379 |
380 | void hide()
381 | in {
382 | assert(!hasBeenClosed_);
383 | } body {
384 | xlib.XUnmapWindow(display_, wind_);
385 | }
386 |
387 | void icon(Image image)
388 | in {
389 | assert(!hasBeenClosed_);
390 | assert(image !is null);
391 | } body {
392 | import devisualization.image;
393 | int length = cast(int)(2 + (image.width * image.height));
394 | xlib.Atom net_wm_icon = xlib.XInternAtom(display_, cast(char*)"_NET_WM_ICON\0".ptr, cast(int)false);
395 | xlib.Atom cardinal = xlib.XInternAtom(display_, cast(char*)"CARDINAL\0".ptr, cast(int)false);
396 | xlib.XChangeProperty(display_, wind_, net_wm_icon, cardinal, 32, xx11.PropModeReplace, cast(ubyte*)ubyteRawColor(image.rgba.allPixels).ptr, length);
397 | }
398 |
399 | /**
400 | * Don't think this works. Atleast not in XFCE
401 | */
402 | deprecated("Use Devisualization.Image method instead")
403 | void icon(ushort width, ushort height, ubyte[3][] idata, ubyte[3]* transparent = null)
404 | in {
405 | assert(!hasBeenClosed_);
406 | assert(width * height == data.length, "Icon pixels length must be equal to width * height");
407 | } body {
408 | uint[] imageData;
409 | imageData ~= (height << 16) | width;
410 |
411 | foreach(datem; idata) {
412 | imageData ~= (datem[0]) | (datem[1] << 8) | (datem[2] << 16) | (0 << 24);
413 | }
414 |
415 | int length = 2 + (width * height);
416 | xlib.Atom net_wm_icon = xlib.XInternAtom(display_, cast(char*)"_NET_WM_ICON\0".ptr, cast(int)false);
417 | xlib.Atom cardinal = xlib.XInternAtom(display_, cast(char*)"CARDINAL\0".ptr, cast(int)false);
418 | xlib.XChangeProperty(display_, wind_, net_wm_icon, cardinal, 32, xx11.PropModeReplace, cast(ubyte*)imageData.ptr, length);
419 | }
420 | }
421 |
422 | mixin Eventing!("onDraw", Windowable);
423 | mixin Eventing!("onMove", Windowable, int, int);
424 | mixin Eventing!("onResize", Windowable, uint, uint);
425 | mixin Eventing!("onClose", Windowable);
426 |
427 | mixin Eventing!("onMouseDown", Windowable, MouseButtons, int, int);
428 | mixin Eventing!("onMouseMove", Windowable, int, int);
429 | mixin Eventing!("onMouseUp", Windowable, MouseButtons);
430 | mixin Eventing!("onKeyDown", Windowable, Keys, KeyModifiers);
431 | mixin Eventing!("onKeyUp", Windowable, Keys, KeyModifiers);
432 | }
433 |
434 | private {
435 | Window[xlib.Window] dispToInsts;
436 | xlib.Display* display_;
437 |
438 | struct WMHints {
439 | ulong Flags;
440 | ulong Functions;
441 | ulong Decorations;
442 | long InputMode;
443 | ulong State;
444 | }
445 |
446 | enum MWM_HINTS_FUNCTIONS = 1 << 0;
447 | enum MWM_HINTS_DECORATIONS = 1 << 1;
448 | enum MWM_HINTS_INPUT_MODE = 1 << 2;
449 |
450 | enum MWM_DECOR_BORDER = 1 << 1;
451 | enum MWM_DECOR_RESIZEH = 1 << 2;
452 | enum MWM_DECOR_TITLE = 1 << 3;
453 | enum MWM_DECOR_MENU = 1 << 4;
454 | enum MWM_DECOR_MINIMIZE = 1 << 5;
455 | enum MWM_DECOR_MAXIMIZE = 1 << 6;
456 |
457 | enum MWM_FUNC_RESIZE = 1 << 1;
458 | enum MWM_FUNC_MOVE = 1 << 2;
459 | enum MWM_FUNC_MINIMIZE = 1 << 3;
460 | enum MWM_FUNC_MAXIMIZE = 1 << 4;
461 | enum MWM_FUNC_CLOSE = 1 << 5;
462 |
463 | xlib.Window createWindow(int x, int y, uint width, uint height, out int screen_, out xlib.Atom closeAtom) {
464 | xlib.Window w;
465 |
466 | if (display_ is null) {
467 | display_ = xlib.XOpenDisplay(null);
468 | if (display_ is null)
469 | throw new WindowNotCreatable();
470 | }
471 |
472 | screen_ = xlib.DefaultScreen(display_);
473 | w = xlib.XCreateSimpleWindow(display_, xlib.RootWindow(display_, screen_), x, y, width, height, 1, xlib.BlackPixel(display_, screen_), xlib.WhitePixel(display_, screen_));
474 |
475 | xlib.XSelectInput(display_, w, xx11.ExposureMask | xx11.StructureNotifyMask | xx11.KeyPressMask | xx11.KeyReleaseMask | xx11.ButtonPressMask | xx11.ButtonReleaseMask | xx11.PointerMotionMask);
476 |
477 | closeAtom = xlib.XInternAtom(display_, cast(char*)"WM_DELETE_WINDOW\0".ptr, cast(int)true);
478 | xlib.XSetWMProtocols(display_, w, &closeAtom, 1);
479 |
480 | return w;
481 | }
482 |
483 | Keys convertKeyFromXlibEvent(uint code) {
484 | import x11.keysymdef;
485 |
486 | if (code >= 'a' && code <= 'z') code -= 'a' - 'A';
487 | switch (code) {
488 | case XK_semicolon: return Keys.Semicolon;
489 | case XK_slash: return Keys.Slash;
490 | case XK_equal: return Keys.Equals;
491 | case XK_minus: return Keys.Hyphen;
492 | case XK_bracketleft: return Keys.LeftBracket;
493 | case XK_bracketright: return Keys.RightBracket;
494 | case XK_comma: return Keys.Comma;
495 | case XK_period: return Keys.Period;
496 | case XK_dead_acute: return Keys.Quote;
497 | case XK_backslash: return Keys.Backslash;
498 | case XK_dead_grave: return Keys.Tilde;
499 | case XK_Escape: return Keys.Escape;
500 | case XK_space: return Keys.Space;
501 | case XK_Return: return Keys.Enter;
502 | case XK_KP_Enter: return Keys.Enter;
503 | case XK_BackSpace: return Keys.Backspace;
504 | case XK_Tab: return Keys.Tab;
505 | case XK_Prior: return Keys.PageUp;
506 | case XK_Next: return Keys.PageDown;
507 | case XK_End: return Keys.End;
508 | case XK_Home: return Keys.Home;
509 | case XK_Insert: return Keys.Insert;
510 | case XK_Delete: return Keys.Delete;
511 | case XK_KP_Add: return Keys.Add;
512 | case XK_KP_Subtract: return Keys.Subtract;
513 | case XK_KP_Multiply: return Keys.Multiply;
514 | case XK_KP_Divide: return Keys.Divide;
515 | case XK_Pause: return Keys.Pause;
516 | case XK_Left: return Keys.Left;
517 | case XK_Right: return Keys.Right;
518 | case XK_Up: return Keys.Up;
519 | case XK_Down: return Keys.Down;
520 | default:
521 | if (code >= XK_F1 && code <= XK_F12)
522 | return cast(Keys)(Keys.F1 + (code - XK_F1));
523 | else if (code >= XK_KP_0 && code <= XK_KP_9)
524 | return cast(Keys)(Keys.Numpad0 + (code - XK_KP_0));
525 | else if (code >= 'A' && code <= 'Z')
526 | return cast(Keys)(Keys.A + (code - 'A'));
527 | else if (code >= '0' && code <= '9')
528 | return cast(Keys)(Keys.Number0 + (code - '0'));
529 | break;
530 | }
531 | return Keys.Unknown;
532 | }
533 |
534 | KeyModifiers convertKeyFromXlibEventModifiers(uint code) {
535 | KeyModifiers ret;
536 |
537 | if (code & xx11.Mod1Mask)
538 | ret |= KeyModifiers.Alt;
539 | if (code & xx11.ControlMask)
540 | ret |= KeyModifiers.Control;
541 | if (code & xx11.ShiftMask || code & xx11.LockMask)
542 | ret |= KeyModifiers.Shift;
543 |
544 | return ret;
545 | }
546 | }
--------------------------------------------------------------------------------
/platforms/macosx/devisualization/window/context/buffer2d.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.context.buffer2d;
25 | import devisualization.window.window;
26 | import devisualization.window.interfaces.context;
27 |
28 | private {
29 | bool loadedDGL;
30 | }
31 |
32 | class Buffer2DContext : ContextBuffer2D {
33 | import devisualization.image.image;
34 |
35 | private {
36 | int cocoaId;
37 |
38 | Image buffer_;
39 | ubyte[4][] bufferdata;
40 | }
41 |
42 | this(Window window, WindowConfig config, int cocoaId) {
43 | this.cocoaId = cocoaId;
44 | cocoaCreateBuffer2DContext(cocoaId);
45 | activate();
46 | }
47 |
48 | @property {
49 | void activate() {
50 | cocoaActivateBuffer2DContext(cocoaId);
51 | }
52 |
53 | void destroy() {
54 | cocoaDestroyBuffer2DContext(cocoaId);
55 | }
56 |
57 | void swapBuffers() {
58 | if (buffer_ !is null) {
59 | // will only reallocate raw data buffer IF the Image buffer size has changed
60 | bufferdata.length = buffer_.rgba.length;
61 |
62 | foreach(i, pixel; buffer_.rgba.allPixels) {
63 | bufferdata[i][0] = pixel.r_ubyte;
64 | bufferdata[i][1] = pixel.g_ubyte;
65 | bufferdata[i][2] = pixel.b_ubyte;
66 | bufferdata[i][3] = pixel.a_ubyte;
67 | }
68 |
69 | ubyte* data = bufferdata[0].ptr;
70 | cocoaSwapBuffer2DBuffers(cocoaId, &data, buffer_.width, buffer_.height);
71 | }
72 | }
73 |
74 | WindowContextType type() { return WindowContextType.Buffer2D; }
75 | string toolkitVersion() { return null; }
76 | string shadingLanguageVersion() { return null; }
77 | string[] extensions() { return null; }
78 |
79 | ref Image buffer() { return buffer_; }
80 | void buffer(Image buffer) { buffer_ = buffer; }
81 | }
82 | }
83 |
84 | private {
85 | extern(C) {
86 | void cocoaCreateBuffer2DContext(int window);
87 | void cocoaActivateBuffer2DContext(int window);
88 | void cocoaDestroyBuffer2DContext(int window);
89 | void cocoaSwapBuffer2DBuffers(int window, ubyte** buffer, size_t width, size_t height);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/platforms/macosx/devisualization/window/context/opengl.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.context.opengl;
25 | import devisualization.window.window;
26 | import devisualization.window.interfaces.context;
27 |
28 | private {
29 | bool loadedDGL;
30 | }
31 |
32 | class OpenglContext : IContext {
33 | private {
34 | import derelict.opengl3.gl;
35 |
36 | int cocoaId;
37 | }
38 |
39 | this(Window window, WindowConfig config, int cocoaId) {
40 | if (!loadedDGL) {
41 | DerelictGL.load();
42 | loadedDGL = true;
43 | }
44 |
45 | this.cocoaId = cocoaId;
46 |
47 | if ((config.contextType | WindowContextType.Opengl3Plus) == WindowContextType.Opengl3Plus) {
48 | cocoaCreateOGLContext(cocoaId, 3);
49 | } else {
50 | cocoaCreateOGLContext(cocoaId, 1);
51 | }
52 |
53 | activate();
54 | }
55 |
56 | @property {
57 | void activate() {
58 | cocoaActivateOGLContext(cocoaId);
59 | DerelictGL.reload();
60 | }
61 |
62 | void destroy() {
63 | cocoaDestroyOGLContext(cocoaId);
64 | }
65 |
66 | void swapBuffers() {
67 | glFlush();
68 | cocoaSwapOGLBuffers(cocoaId);
69 | }
70 |
71 | WindowContextType type() { return WindowContextType.Opengl; }
72 |
73 | string toolkitVersion() {
74 | char[] str;
75 | const(char*) c = glGetString(GL_VERSION);
76 | size_t i;
77 |
78 | if (c !is null) {
79 | while (c[i] != '\0') {
80 | str ~= c[i];
81 | i++;
82 | }
83 | }
84 |
85 | return str.idup;
86 | }
87 |
88 | string shadingLanguageVersion() {
89 | char[] str;
90 | const(char*) c = glGetString(GL_SHADING_LANGUAGE_VERSION);
91 | size_t i;
92 |
93 | if (c !is null) {
94 | while (c[i] != '\0') {
95 | str ~= c[i];
96 | i++;
97 | }
98 | }
99 |
100 | return str.idup;
101 | }
102 |
103 | string[] extensions() {
104 | string[] ret;
105 |
106 | char[] str;
107 | const(char*) c = glGetString(GL_SHADING_LANGUAGE_VERSION);
108 | size_t i;
109 |
110 | if (c !is null) {
111 | while (c[i] != '\0') {
112 | if (c[i] == ' ') {
113 | ret ~= str.idup;
114 | str.length = 0;
115 | } else {
116 | str ~= c[i];
117 | }
118 | i++;
119 | }
120 | }
121 |
122 | return ret;
123 | }
124 | }
125 | }
126 |
127 | private {
128 | extern(C) {
129 | void cocoaCreateOGLContext(int window, int minVersion);
130 | void cocoaActivateOGLContext(int window);
131 | void cocoaDestroyOGLContext(int window);
132 | void cocoaSwapOGLBuffers(int window);
133 | }
134 | }
--------------------------------------------------------------------------------
/platforms/macosx/devisualization/window/context/package.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.context;
25 | public import devisualization.window.context.opengl;
26 | public import devisualization.window.context.buffer2d;
--------------------------------------------------------------------------------
/platforms/macosx/devisualization/window/window.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.window;
25 | import devisualization.window.context;
26 | import devisualization.window.interfaces.window;
27 | import devisualization.window.interfaces.eventable;
28 | public import devisualization.window.interfaces.window : WindowConfig, Windowable;
29 | public import devisualization.window.interfaces.events : MouseButtons, Keys, KeyModifiers;
30 | public import devisualization.window.interfaces.context : WindowContextType, IContext;
31 | import std.conv : to;
32 |
33 | class Window : Windowable {
34 | private {
35 | int cocoaId;
36 | bool hasBeenClosed_;
37 | IContext context_;
38 |
39 | ubyte* iconImageData_;
40 | }
41 |
42 | this(T...)(T config) { this(WindowConfig(config)); }
43 |
44 | this(WindowConfig config) {
45 | synchronized {
46 | if (!hasBeenSetup) {
47 | cocoaInit();
48 | hasBeenSetup = true;
49 | }
50 |
51 | string titleValue = to!string(config.title) ~ "\0";
52 | cocoaId = cocoaCreateWindow(CocoaWindowData(config.x, config.y, config.width, config.height, cast(char*)&titleValue[0]));
53 | dispToInsts[cocoaId] = this;
54 | }
55 |
56 | if ((config.contextType | WindowContextType.Opengl3Plus) == WindowContextType.Opengl3Plus || (config.contextType | WindowContextType.OpenglLegacy) == WindowContextType.OpenglLegacy) {
57 | // create Opengl context!
58 | context_ = new OpenglContext(this, config, cocoaId);
59 | } else if (config.contextType == WindowContextType.Direct3D) {
60 | // create Direct3d context!
61 | throw new Exception("Cannot create Direct3D context on non Windows targets");
62 | } else if (config.contextType == WindowContextType.Buffer2D) {
63 | context_ = new Buffer2DContext(this, config, cocoaId);
64 | }
65 | }
66 |
67 | static {
68 | void messageLoop() {
69 | import core.thread : Thread;
70 | import core.time : dur;
71 |
72 | while(true) {
73 | while(Window.messageLoopIteration()){}
74 | Thread.sleep(dur!"msecs"(50));
75 | }
76 | }
77 |
78 | bool messageLoopIteration(uint minBlocking=0, uint maxNonblocking=1) {
79 | return cast(bool)cocoaRunLoopIterate(minBlocking, maxNonBlocking);
80 | }
81 | }
82 |
83 | @property {
84 | void title(string value)
85 | in {
86 | assert(!hasBeenClosed_);
87 | } body {
88 | cocoaSetTitle(cocoaId, cast(char*)(value ~ "\0").ptr);
89 | }
90 |
91 | void title(dstring value)
92 | in {
93 | assert(!hasBeenClosed_);
94 | } body {
95 | title(to!string(value));
96 | }
97 |
98 | void title(wstring value)
99 | in {
100 | assert(!hasBeenClosed_);
101 | } body {
102 | title(to!string(value));
103 | }
104 |
105 | void size(uint width, uint height)
106 | in {
107 | assert(!hasBeenClosed_);
108 | } body {
109 | cocoaSetSize(cocoaId, width, height);
110 | }
111 |
112 | void move(int x, int y)
113 | in {
114 | assert(!hasBeenClosed_);
115 | } body {
116 | cocoaSetPosition(cocoaId, x, y);
117 | }
118 |
119 | void canResize(bool can = true)
120 | in {
121 | assert(!hasBeenClosed_);
122 | } body {
123 | cocoaCanResize(cocoaId, cast(uint)can);
124 | }
125 |
126 | void fullscreen(bool isfs = true)
127 | in {
128 | assert(!hasBeenClosed_);
129 | } body {
130 | cocoaFullScreen(cocoaId, cast(int)isfs);
131 | }
132 |
133 | void close()
134 | in {
135 | assert(!hasBeenClosed_);
136 | } body {
137 | synchronized {
138 | dispToInsts.remove(cocoaId);
139 | }
140 | cocoaCloseWindow(cocoaId);
141 | hasBeenClosed_ = true;
142 | }
143 |
144 | IContext context()
145 | in {
146 | assert(!hasBeenClosed_);
147 | } body {
148 | return context_;
149 | }
150 |
151 | bool hasBeenClosed() { return hasBeenClosed_; }
152 | }
153 |
154 | override {
155 | void show()
156 | in {
157 | assert(!hasBeenClosed_);
158 | } body {
159 | cocoaShowWindow(cocoaId);
160 | }
161 |
162 | void hide()
163 | in {
164 | assert(!hasBeenClosed_);
165 | } body {
166 | cocoaHideWindow(cocoaId);
167 | }
168 |
169 | void icon(Image image)
170 | in {
171 | assert(!hasBeenClosed_);
172 | assert(image !is null);
173 | } body {
174 | import devisualization.image;
175 | import core.memory;
176 | GC.free(iconImageData_);
177 | iconImageData_ = cast(ubyte*)ubyteRawColor(image.rgba.allPixels).ptr;
178 | cocoaSetIcon(cocoaId, &iconImageData_, cast(int)image.width, cast(int)image.height);
179 | }
180 |
181 | deprecated("Use Devisualization.Image method instead")
182 | void icon(ushort width, ushort height, ubyte[3][] idata, ubyte[3]* transparent = null)
183 | in {
184 | assert(!hasBeenClosed_);
185 | assert(width * height == data.length, "Icon pixels length must be equal to width * height");
186 | } body {
187 | import core.memory;
188 |
189 | GC.free(iconImageData_);
190 | iconImageData_ = cast(ubyte*)GC.malloc(width * height * 4);
191 |
192 | size_t done = 0;
193 |
194 | foreach(datem; idata) {
195 | iconImageData_[done + 0] = datem[0];
196 | iconImageData_[done + 1] = datem[1];
197 | iconImageData_[done + 2] = datem[2];
198 |
199 | if (transparent !is null &&
200 | datem[0] == (*transparent)[0] &&
201 | datem[1] == (*transparent)[1] &&
202 | datem[2] == (*transparent)[2]) {
203 | iconImageData_[done + 3] = 0;
204 | } else {
205 | iconImageData_[done + 3] = 255;
206 | }
207 |
208 | done += 4;
209 | }
210 |
211 | cocoaSetIcon(cocoaId, &iconImageData_, width, height);
212 | }
213 | }
214 |
215 | mixin Eventing!("onDraw", Windowable);
216 | mixin Eventing!("onMove", Windowable, int, int);
217 | mixin Eventing!("onResize", Windowable, uint, uint);
218 | mixin Eventing!("onClose", Windowable);
219 |
220 | mixin Eventing!("onMouseDown", Windowable, MouseButtons, int, int);
221 | mixin Eventing!("onMouseMove", Windowable, int, int);
222 | mixin Eventing!("onMouseUp", Windowable, MouseButtons);
223 | mixin Eventing!("onKeyDown", Windowable, Keys, KeyModifiers);
224 | mixin Eventing!("onKeyUp", Windowable, Keys, KeyModifiers);
225 | }
226 |
227 | private {
228 | Window[int] dispToInsts;
229 | bool hasBeenSetup;
230 |
231 | extern(C) {
232 | struct CocoaWindowData {
233 | int x;
234 | int y;
235 | int width;
236 | int height;
237 | char* title;
238 | }
239 |
240 | void cocoaInit();
241 | int cocoaCreateWindow(CocoaWindowData data);
242 | int cocoaRunLoopIterate(uint maxBlocking, uint maxNonBlocking);
243 | void cocoaSetTitle(int window, char* title);
244 | void cocoaSetSize(int window, int width, int height);
245 | void cocoaSetPosition(int window, int x, int y);
246 | void cocoaCanResize(int window, int can);
247 | void cocoaFullScreen(int id, int is_);
248 | void cocoaCloseWindow(int window);
249 | void cocoaShowWindow(int window);
250 | void cocoaHideWindow(int window);
251 | void cocoaSetIcon(int window, ubyte** rgba, int width, int height);
252 |
253 | void cocoaEventMouseDown(int window, MouseButtons button, float x, float y) {
254 | dispToInsts[window].onMouseDown(button, cast(int)x, cast(int)y);
255 | }
256 |
257 | void cocoaEventMouseUp(int window, MouseButtons button, float x, float y) {
258 | dispToInsts[window].onMouseUp(button);
259 | }
260 |
261 | void cocoaEventMouseMove(int window, float x, float y) {
262 | dispToInsts[window].onMouseMove(cast(int)x, cast(int)y);
263 | }
264 |
265 | void cocoaEventOnClose(int window) {
266 | dispToInsts[window].onClose();
267 | }
268 |
269 | void cocoaEventOnResize(int window, int width, int height) {
270 | dispToInsts[window].onResize(width, height);
271 | }
272 |
273 | void cocoaEventOnMove(int window, int x, int y) {
274 | dispToInsts[window].onMove(x, y);
275 | }
276 |
277 | void cocoaEventOnKeyDown(int window, ubyte modifiers, Keys key) {
278 | dispToInsts[window].onKeyDown(key, cast(KeyModifiers)modifiers);
279 | }
280 |
281 | void cocoaEventOnKeyUp(int window, ubyte modifiers, Keys key) {
282 | dispToInsts[window].onKeyUp(key, cast(KeyModifiers)modifiers);
283 | }
284 |
285 | void cocoaEventForceRedraw(int window) {
286 | dispToInsts[window].onDraw();
287 | }
288 | }
289 | }
--------------------------------------------------------------------------------
/platforms/win32/devisualization/window/context/buffer2d.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.context.buffer2d;
25 | import devisualization.window.window;
26 | import devisualization.window.interfaces.context;
27 |
28 | private enum SRCCOPY = 0x00CC0020;
29 |
30 | class Buffer2DContext : ContextBuffer2D {
31 | import windows;
32 | import devisualization.image.image;
33 |
34 | private {
35 | PAINTSTRUCT ps;
36 | HDC hdc;
37 | HDC hdcMem;
38 | RECT winsize;
39 | HBITMAP bitmap;
40 |
41 | HWND hwnd;
42 | Window window;
43 |
44 | Image buffer_;
45 | ubyte[4][] bufferdata;
46 | }
47 |
48 | this(Window window, WindowConfig config) {
49 | this.window = window;
50 | hwnd = window.hwnd;
51 |
52 | buffer_ = null;
53 | }
54 |
55 | @property {
56 | void activate() {}
57 | void destroy() {}
58 |
59 | void swapBuffers() {
60 | hdc = BeginPaint(hwnd, &ps);
61 | hdcMem = CreateCompatibleDC(hdc);
62 |
63 | if (buffer_ !is null) {
64 | // will only reallocate raw data buffer IF the Image buffer size has changed
65 | auto rgba = buffer_.rgba;
66 | bufferdata.length = rgba.length;
67 |
68 | foreach(i, pixel; rgba) {
69 | bufferdata[i][2] = pixel.r_ubyte;
70 | bufferdata[i][1] = pixel.g_ubyte;
71 | bufferdata[i][0] = pixel.b_ubyte;
72 | bufferdata[i][3] = pixel.a_ubyte;
73 | }
74 |
75 | GetClientRect(hwnd, &winsize);
76 |
77 | HBITMAP hBitmap = CreateBitmap(cast(uint)buffer_.width, cast(uint)buffer_.height, 1, 32, bufferdata.ptr);
78 | HGDIOBJ oldBitmap = SelectObject(hdcMem, hBitmap);
79 |
80 | GetObjectA(hBitmap, HBITMAP.sizeof, &bitmap);
81 |
82 | // auto stretch the image buffer to client screen size
83 | StretchBlt(hdc, 0, 0, cast(uint)buffer_.width, cast(uint)buffer_.height, hdcMem, 0, 0, winsize.right, winsize.bottom, SRCCOPY);
84 |
85 | SelectObject(hdcMem, oldBitmap);
86 | DeleteObject(hBitmap);
87 | }
88 |
89 | EndPaint(hwnd, &ps);
90 | DeleteDC(hdcMem);
91 |
92 | // perform the actual redraw!
93 | InvalidateRgn(hwnd, null, false);
94 | }
95 |
96 | WindowContextType type() { return WindowContextType.Buffer2D; }
97 | string toolkitVersion() { return null; }
98 | string shadingLanguageVersion() { return null; }
99 |
100 | ref Image buffer() { return buffer_; }
101 | void buffer(Image buffer) { buffer_ = buffer; }
102 | }
103 | }
--------------------------------------------------------------------------------
/platforms/win32/devisualization/window/context/direct3d.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.context.direct3d;
25 |
26 | version(Have_directx_d) {
27 | import devisualization.window.window;
28 | import devisualization.window.interfaces.context;
29 |
30 | class Direct3dContext : IContext {
31 | import devisualization.image.image;
32 | import winapi = windows;
33 | import directx.d3d11;
34 |
35 | private {
36 | winapi.HWND hWnd;
37 | Window window;
38 |
39 | ID3D11Device dev;
40 | ID3D11DeviceContext devcon;
41 | IDXGISwapChain swapchain;
42 | ID3D11RenderTargetView backbuffer;
43 | }
44 |
45 | this(Window window, WindowConfig config) {
46 | this.window = window;
47 | hWnd = window.hwnd;
48 |
49 | init();
50 | }
51 |
52 | @property {
53 | void activate() {}
54 |
55 | void destroy() {
56 | swapchain.Release();
57 | backbuffer.Release();
58 | dev.Release();
59 | devcon.Release();
60 | }
61 |
62 | void swapBuffers() {
63 | swapchain.Present(0, 0);
64 | }
65 |
66 | WindowContextType type() { return WindowContextType.Direct3D; }
67 |
68 | string toolkitVersion() {
69 | import std.conv : text;
70 | return text(devcon.GetType) ~ " " ~ text(dev.GetFeatureLevel());
71 | }
72 |
73 | string shadingLanguageVersion() {
74 | switch(dev.GetFeatureLevel()) {
75 | case D3D_FEATURE_LEVEL_9_1:
76 | case D3D_FEATURE_LEVEL_9_2:
77 | return "2";
78 | case D3D_FEATURE_LEVEL_9_3:
79 | return "2.0b";
80 | case D3D_FEATURE_LEVEL_10_0:
81 | case D3D_FEATURE_LEVEL_10_1:
82 | return "4";
83 | case D3D_FEATURE_LEVEL_11_0:
84 | return "5";
85 | //case D3D_FEATURE_LEVEL_11_1:
86 | // return "5 with logical blend operations";
87 |
88 | default:
89 | return null;
90 | }
91 | }
92 |
93 | ID3D11Device device() { return dev; }
94 | ID3D11DeviceContext deviceContext() { return devcon; }
95 | IDXGISwapChain swapChain() { return swapchain; }
96 | ID3D11RenderTargetView backBuffer() { return backbuffer; }
97 | }
98 |
99 | private {
100 | void init() {
101 | import std.c.string : memset;
102 |
103 | // create a struct to hold information about the swap chain
104 | DXGI_SWAP_CHAIN_DESC scd;
105 |
106 | // clear out the struct for use
107 | memset(&scd, 0, DXGI_SWAP_CHAIN_DESC.sizeof );
108 |
109 | // fill the swap chain description struct
110 | scd.BufferCount = 1; // one back buffer
111 | scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color
112 | scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used
113 | scd.OutputWindow = hWnd; // the window to be used
114 | scd.SampleDesc.Count = 4; // how many multisamples
115 | scd.Windowed = true; // windowed/full-screen mode
116 |
117 | // create a device, device context and swap chain using the information in the scd struct
118 | D3D11CreateDeviceAndSwapChain(null,
119 | D3D_DRIVER_TYPE_HARDWARE,
120 | null,
121 | 0,
122 | null,
123 | 0,
124 | D3D11_SDK_VERSION,
125 | &scd,
126 | &swapchain,
127 | &dev,
128 | null,
129 | &devcon);
130 |
131 | // get the address of the back buffer
132 | ID3D11Texture2D pBackBuffer;
133 | swapchain.GetBuffer(0, &IID_ID3D11Texture2D, cast(void**)&pBackBuffer);
134 |
135 | // use the back buffer address to create the render target
136 | dev.CreateRenderTargetView(pBackBuffer, null, &backbuffer);
137 | pBackBuffer.Release();
138 |
139 | // set the render target as the back buffer
140 | devcon.OMSetRenderTargets(1, &backbuffer, null);
141 |
142 | winapi.RECT winsize;
143 | winapi.GetClientRect(hWnd, &winsize);
144 |
145 | // Set the viewport
146 | D3D11_VIEWPORT viewport;
147 | memset(&viewport, 0, D3D11_VIEWPORT.sizeof);
148 |
149 | viewport.TopLeftX = 0;
150 | viewport.TopLeftY = 0;
151 | viewport.Width = winsize.right;
152 | viewport.Height = winsize.bottom;
153 |
154 | devcon.RSSetViewports(1, &viewport);
155 | }
156 | }
157 | }
158 | }
--------------------------------------------------------------------------------
/platforms/win32/devisualization/window/context/opengl.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.context.opengl;
25 | import devisualization.window.window;
26 | import devisualization.window.interfaces.context;
27 |
28 | import derelict.opengl3.gl;
29 | import derelict.opengl3.wgl;
30 | import derelict.opengl3.wglext;
31 |
32 | private {
33 | bool loadedDGL;
34 | }
35 |
36 | class OpenglContext : IContext {
37 | private {
38 | HDC hdc_;
39 | HGLRC hglrc_;
40 | }
41 |
42 | this(Window window, WindowConfig config) {
43 | if (!loadedDGL) {
44 | DerelictGL.load();
45 | loadedDGL = true;
46 | }
47 |
48 | import windows : GetDC;
49 | hdc_ = GetDC(window.hwnd);
50 |
51 | configurePixelFormat(window, config, hdc_);
52 |
53 | hglrc_ = cast(HGLRC)wglCreateContext(hdc_);
54 | activate();
55 | }
56 |
57 | @property {
58 | void activate() {
59 | wglMakeCurrent(hdc_, hglrc_);
60 | DerelictGL.reload();
61 | }
62 |
63 | void destroy() {
64 | wglDeleteContext(hglrc_);
65 | }
66 |
67 | void swapBuffers() {
68 | glFlush();
69 | SwapBuffers(hdc_);
70 | }
71 |
72 | WindowContextType type() { return WindowContextType.Opengl; }
73 |
74 | string toolkitVersion() {
75 | char[] str;
76 | const(char*) c = glGetString(GL_VERSION);
77 | size_t i;
78 |
79 | if (c !is null) {
80 | while (c[i] != '\0') {
81 | str ~= c[i];
82 | i++;
83 | }
84 | }
85 |
86 | return str.idup;
87 | }
88 |
89 | string shadingLanguageVersion() {
90 | char[] str;
91 | const(char*) c = glGetString(GL_SHADING_LANGUAGE_VERSION);
92 | size_t i;
93 |
94 | if (c !is null) {
95 | while (c[i] != '\0') {
96 | str ~= c[i];
97 | i++;
98 | }
99 | }
100 |
101 | return str.idup;
102 | }
103 |
104 | string[] extensions() {
105 | string[] ret;
106 |
107 | char[] str;
108 | const(char*) c = glGetString(GL_SHADING_LANGUAGE_VERSION);
109 | size_t i;
110 |
111 | if (c !is null) {
112 | while (c[i] != '\0') {
113 | if (c[i] == ' ') {
114 | ret ~= str.idup;
115 | str.length = 0;
116 | } else {
117 | str ~= c[i];
118 | }
119 | i++;
120 | }
121 | }
122 |
123 | return ret;
124 | }
125 | }
126 | }
127 |
128 | private {
129 | import windows : SwapBuffers, HDC, HGLRC;
130 |
131 | void configurePixelFormat(Window window, WindowConfig config, HDC hdc_) {
132 | import windows : PIXELFORMATDESCRIPTOR, ChoosePixelFormat, SetPixelFormat, PFD_DRAW_TO_WINDOW, PFD_SUPPORT_OPENGL, PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, PFD_MAIN_PLANE;
133 | PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR(
134 | PIXELFORMATDESCRIPTOR.sizeof,
135 | 1, // version number
136 | PFD_DRAW_TO_WINDOW | // support window
137 | PFD_SUPPORT_OPENGL | // support OpenGL
138 | PFD_DOUBLEBUFFER, // double buffered
139 | PFD_TYPE_RGBA, // RGBA type
140 | 24, // 24-bit color depth
141 | 0, 0, 0, 0, 0, 0, // color bits ignored
142 | 0, // no alpha buffer
143 | 0, // shift bit ignored
144 | 0, // no accumulation buffer
145 | 0, 0, 0, 0, // accum bits ignored
146 | 32, // 32-bit z-buffer
147 | 8, // 8-bit stencil buffer
148 | 0, // no auxiliary buffer
149 | PFD_MAIN_PLANE, // main layer
150 | 0, // reserved
151 | 0, 0, 0 // layer masks ignored
152 | );
153 |
154 | int iPixelFormat;
155 |
156 | // get the best available match of pixel format for the device context
157 | iPixelFormat = ChoosePixelFormat(hdc_, &pfd);
158 |
159 | // make that the pixel format of the device context
160 | SetPixelFormat(hdc_, iPixelFormat, &pfd);
161 | }
162 | }
--------------------------------------------------------------------------------
/platforms/win32/devisualization/window/context/package.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.context;
25 | public import devisualization.window.context.opengl;
26 | public import devisualization.window.context.buffer2d;
27 | public import devisualization.window.context.direct3d;
--------------------------------------------------------------------------------
/platforms/win32/devisualization/window/window.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module devisualization.window.window;
25 | import devisualization.window.interfaces.window;
26 | public import devisualization.window.interfaces.window : WindowConfig, Windowable;
27 | public import devisualization.window.interfaces.events : MouseButtons, Keys, KeyModifiers;
28 | public import devisualization.window.interfaces.context : WindowContextType, IContext;
29 | public import devisualization.window.context;
30 | import devisualization.window.interfaces.eventable;
31 | import std.conv : to;
32 |
33 | class Window : Windowable {
34 | private {
35 | HWND hwnd_;
36 | HICON previousIcon_;
37 | wstring lastTitle;
38 | bool hasBeenClosed_;
39 |
40 | WindowConfig config_;
41 | IContext context_ = null;
42 | }
43 |
44 | this(T...)(T config) { this(WindowConfig(config)); }
45 |
46 | this(WindowConfig config) {
47 | config_ = config;
48 | title = config.title;
49 |
50 | Window this_ = this;
51 | hwnd_ = createWindow(config.x, config.y, config.width, config.height, &windowHandler, &this_);
52 | }
53 |
54 | static {
55 | void messageLoop() {
56 | import core.thread : Thread;
57 | import core.time : dur;
58 |
59 | while(true) {
60 | while(Window.messageLoopIteration()) {}
61 | Thread.sleep(dur!"msecs"(50));
62 | }
63 | }
64 |
65 | bool messageLoopIteration(uint minBlocking = 0, uint maxNonBlocking = 1) {
66 | MSG msg;
67 | uint i;
68 |
69 | while (i < minBlocking) {
70 | int ret = GetMessageW(&msg, null, 0, 0);
71 |
72 | TranslateMessage(&msg);
73 | DispatchMessageW(&msg);
74 |
75 | i++;
76 | }
77 |
78 | i = 0;
79 | while (i < maxNonBlocking) {
80 | int ret = PeekMessageW(&msg, null, 0, 0, PM_REMOVE);
81 |
82 | if (ret == 0) {
83 | return false;
84 | } else {
85 | TranslateMessage(&msg);
86 | DispatchMessageW(&msg);
87 | }
88 |
89 | i++;
90 | }
91 |
92 | return true;
93 | }
94 | }
95 |
96 | @property {
97 | HWND hwnd()
98 | in {
99 | assert(!hasBeenClosed_);
100 | } body {
101 | return hwnd_;
102 | }
103 |
104 | void title(string value)
105 | in {
106 | assert(!hasBeenClosed_);
107 | } body {
108 | title(to!wstring(value));
109 | }
110 |
111 | void title(dstring value)
112 | in {
113 | assert(!hasBeenClosed_);
114 | } body {
115 | title(to!wstring(value));
116 | }
117 |
118 | void title(wstring value)
119 | in {
120 | assert(!hasBeenClosed_);
121 | } body {
122 | if (value != ""w && value[$-1] != '\0')
123 | value ~= '\0';
124 | else if (value == ""w)
125 | value = "\0"w;
126 | lastTitle = value;
127 |
128 | SetWindowTextW(hwnd_, cast(ushort*)lastTitle.ptr);
129 | }
130 |
131 | void size(uint width, uint height)
132 | in {
133 | assert(!hasBeenClosed_);
134 | } body {
135 | // calculates correct width/height size of window
136 | RECT rect;
137 |
138 | rect.top = 0;
139 | rect.left = 0;
140 | rect.right = width;
141 | rect.bottom = height;
142 |
143 | auto style = GetWindowLongW(hwnd_, GWL_STYLE);
144 | if (style == dwFullscreen) {
145 | SetWindowLongW(hwnd_, GWL_STYLE, dwStyle);
146 | SetWindowLongW(hwnd_, GWL_EXSTYLE, dwExStyle);
147 | }
148 |
149 | AdjustWindowRectEx(&rect, dwStyle, false, dwExStyle);
150 | width = rect.right;
151 | height = rect.bottom;
152 | // calculates correct width/height size of window
153 |
154 | SetWindowPos(hwnd_, null, 0, 0, width, height, SWP_NOMOVE | SWP_NOOWNERZORDER);
155 | }
156 |
157 | void move(int x, int y)
158 | in {
159 | assert(!hasBeenClosed_);
160 | } body {
161 | SetWindowPos(hwnd_, null, x, y, 0, 0, SWP_NOSIZE | SWP_NOOWNERZORDER);
162 | }
163 |
164 | void canResize(bool can = true)
165 | in {
166 | assert(!hasBeenClosed_);
167 | } body {
168 | auto style = GetWindowLongW(hwnd_, GWL_STYLE);
169 | if (can)
170 | style |= WS_SIZEBOX | WS_MAXIMIZEBOX;
171 | else
172 | style &= ~(WS_SIZEBOX | WS_MAXIMIZEBOX);
173 | SetWindowLongW(hwnd_, GWL_STYLE, style);
174 | }
175 |
176 | void fullscreen(bool isfs = true)
177 | in {
178 | assert(!hasBeenClosed_);
179 | } body {
180 | if (isfs) {
181 | SetWindowLongW(hwnd_, GWL_STYLE, dwFullscreen);
182 | SetWindowLongW(hwnd_, GWL_EXSTYLE, dwExFullscreen);
183 |
184 | int cx = GetSystemMetrics(SM_CXSCREEN);
185 | int cy = GetSystemMetrics(SM_CYSCREEN);
186 | SetWindowPos(hwnd_, HWND_TOP, 0, 0, cx, cy, SWP_SHOWWINDOW);
187 | } else {
188 | canResize = true;
189 | }
190 | }
191 |
192 | void close()
193 | in {
194 | assert(!hasBeenClosed_);
195 | } body {
196 | DestroyWindow(hwnd_);
197 | CloseWindow(hwnd_);
198 | hasBeenClosed_ = true;
199 | }
200 |
201 | IContext context()
202 | in {
203 | assert(!hasBeenClosed_);
204 | } body {
205 | return context_;
206 | }
207 | }
208 |
209 | override {
210 | void show()
211 | in {
212 | assert(!hasBeenClosed_);
213 | } body {
214 | ShowWindow(hwnd_, SW_SHOW);
215 | }
216 |
217 | void hide()
218 | in {
219 | assert(!hasBeenClosed_);
220 | } body {
221 | ShowWindow(hwnd_, SW_HIDE);
222 | }
223 |
224 | void icon(Image image)
225 | in {
226 | assert(!hasBeenClosed_);
227 | assert(image !is null);
228 | } body {
229 | ubyte[4][] data;
230 | foreach(pixel; image.rgba.allPixels) {
231 | data ~= [pixel.b_ubyte, pixel.g_ubyte, pixel.r_ubyte, pixel.a_ubyte];
232 | }
233 |
234 | HBITMAP bitmap = CreateBitmap(cast(uint)image.width, cast(uint)image.height, 1, 32, data.ptr);
235 | HBITMAP hbmMask = CreateCompatibleBitmap(GetDC(hwnd_), cast(uint)image.width, cast(uint)image.height);
236 |
237 | ICONINFO ii;
238 | ii.fIcon = TRUE;
239 | ii.hbmColor = bitmap;
240 | ii.hbmMask = hbmMask;
241 |
242 | HICON hIcon = CreateIconIndirect(&ii);
243 | DeleteObject(hbmMask);
244 |
245 | if (hIcon) {
246 | SendMessageW(hwnd_, WM_SETICON, cast(WPARAM)ICON_BIG, cast(LPARAM)hIcon);
247 | SendMessageW(hwnd_, WM_SETICON, cast(WPARAM)ICON_SMALL, cast(LPARAM)hIcon);
248 | }
249 | }
250 |
251 | deprecated("Use Devisualization.Image method instead")
252 | void icon(ushort width, ushort height, ubyte[3][] idata, ubyte[3]* transparent = null)
253 | in {
254 | assert(!hasBeenClosed_);
255 | assert(width * height == data.length, "Icon pixels length must be equal to width * height");
256 | } body {
257 | ubyte[4][] data;
258 | foreach(v; idata) {
259 | data ~= [v[2], v[1], v[0], 0];
260 | }
261 |
262 | HBITMAP bitmap = CreateBitmap(width, height, 1, 32, data.ptr);
263 | HBITMAP hbmMask;
264 | if (transparent is null)
265 | hbmMask = CreateCompatibleBitmap(GetDC(hwnd_), width, height);
266 | else {
267 | COLORREF crTransparent = RGB((*transparent)[0], (*transparent)[1], (*transparent)[2]);
268 |
269 | HDC hdcMem, hdcMem2;
270 | BITMAP bm;
271 |
272 | GetObjectA(bitmap, BITMAP.sizeof, &bm);
273 | hbmMask = CreateBitmap(width, height, 1, 1, null);
274 |
275 | hdcMem = CreateCompatibleDC(GetDC(hwnd_));
276 | hdcMem2 = CreateCompatibleDC(GetDC(hwnd_));
277 |
278 | SelectObject(hdcMem, bitmap);
279 | SelectObject(hdcMem2, hbmMask);
280 |
281 | SetBkColor(hdcMem, crTransparent);
282 | BitBlt(hdcMem2, 0, 0, width, height, hdcMem, 0, 0, SRCCOPY);
283 | BitBlt(hdcMem, 0, 0, width, height, hdcMem2, 0, 0, SRCINVERT);
284 |
285 | DeleteDC(hdcMem);
286 | DeleteDC(hdcMem2);
287 | }
288 |
289 | ICONINFO ii;
290 | ii.fIcon = TRUE;
291 | ii.hbmColor = bitmap;
292 | ii.hbmMask = hbmMask;
293 |
294 | HICON hIcon = CreateIconIndirect(&ii);
295 | DeleteObject(hbmMask);
296 |
297 | if (hIcon) {
298 | SendMessageW(hwnd_, WM_SETICON, cast(WPARAM)ICON_BIG, cast(LPARAM)hIcon);
299 | SendMessageW(hwnd_, WM_SETICON, cast(WPARAM)ICON_SMALL, cast(LPARAM)hIcon);
300 | }
301 | }
302 |
303 | bool hasBeenClosed() { return hasBeenClosed_; }
304 | }
305 |
306 | mixin Eventing!("onDraw", Windowable);
307 | mixin Eventing!("onMove", Windowable, int, int);
308 | mixin Eventing!("onResize", Windowable, uint, uint);
309 | mixin Eventing!("onClose", Windowable);
310 |
311 | mixin Eventing!("onMouseDown", Windowable, MouseButtons, int, int);
312 | mixin Eventing!("onMouseMove", Windowable, int, int);
313 | mixin Eventing!("onMouseUp", Windowable, MouseButtons);
314 | mixin Eventing!("onKeyDown", Windowable, Keys, KeyModifiers);
315 | mixin Eventing!("onKeyUp", Windowable, Keys, KeyModifiers);
316 | }
317 |
318 |
319 | private {
320 | import windows;
321 |
322 | enum DWORD dwExStyle = 0;
323 | enum DWORD dwStyle = WS_OVERLAPPEDWINDOW;
324 |
325 | enum wstring WindowClassName = "Devisualization.Window window\0"w;
326 |
327 | enum DWORD dwFullscreen = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
328 | enum DWORD dwExFullscreen = WS_EX_APPWINDOW | WS_EX_TOPMOST;
329 |
330 | // wasn't in windows bindings woops
331 |
332 | enum GCL_HICON = -14;
333 | enum SRCCOPY = 0xCC0020;
334 | enum SRCINVERT = 0x660046;
335 |
336 | COLORREF RGB(ubyte r, ubyte g, ubyte b) {
337 | r = r & 0xFF;
338 | g = g & 0xFF;
339 | b = b & 0xFF;
340 | return cast(COLORREF)((b << 16) | (g << 8) | r);
341 | }
342 |
343 |
344 | // more actual code
345 |
346 | HWND createWindow(int x, int y, uint width, uint height, WindowProc wProc, Window* windowPtr) {
347 | static HINSTANCE hInstance;
348 |
349 | if (hInstance is HINSTANCE.init)
350 | hInstance = GetModuleHandleA(null);
351 |
352 | WNDCLASSW wc;
353 | wc.lpfnWndProc = wProc;
354 | wc.hInstance = hInstance;
355 | wc.lpszClassName = cast(ushort*)WindowClassName.ptr;
356 | wc.hCursor = LoadCursorW(null, cast(ushort*)IDC_ARROW);
357 | wc.style |= CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
358 | if (!RegisterClassW(&wc))
359 | throw new WindowNotCreatable();
360 |
361 | // calculates correct width/height size of window
362 | RECT rect;
363 |
364 | rect.top = 0;
365 | rect.left = 0;
366 | rect.right = width;
367 | rect.bottom = height;
368 |
369 | AdjustWindowRectEx(&rect, dwStyle, false, dwExStyle);
370 | width = rect.right;
371 | height = rect.bottom;
372 | // calculates correct width/height size of window
373 |
374 | HWND hwnd = CreateWindowExW(
375 | dwExStyle,
376 | cast(ushort*)WindowClassName.ptr,
377 | null,
378 | dwStyle,
379 | x, y,
380 | width, height,
381 | null,
382 | null,
383 | hInstance,
384 | windowPtr);
385 |
386 | if (hwnd is null)
387 | throw new WindowNotCreatable();
388 |
389 | InvalidateRgn(hwnd, null, true);
390 |
391 | return hwnd;
392 | }
393 |
394 | extern(Windows) {
395 | alias WindowProc = LRESULT function(HWND hwnd, uint uMsg, WPARAM wParam, LPARAM lParam);
396 |
397 | LRESULT windowHandler(HWND hwnd, uint uMsg, WPARAM wParam, LPARAM lParam) {
398 | /*
399 | * Handles creational arguments aka the current window
400 | */
401 | Window window;
402 | switch(uMsg) {
403 | case WM_CREATE:
404 | CREATESTRUCTW pCreate = *cast(CREATESTRUCTW*)lParam;
405 | void* pState = pCreate.lpCreateParams;
406 |
407 | version(X86_64) {
408 | SetWindowLongPtrW(hwnd, GWLP_USERDATA, *cast(ulong*)pState);
409 | } else {
410 | SetWindowLongW(hwnd, GWLP_USERDATA, *cast(uint*)pState);
411 | }
412 |
413 | return cast(LRESULT)0;
414 |
415 | default:
416 | version(X86_64) {
417 | window = cast(Window)cast(ulong*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
418 | } else {
419 | window = cast(Window)cast(uint*)GetWindowLongW(hwnd, GWLP_USERDATA);
420 | }
421 | }
422 |
423 | /*
424 | * Normal flow handling
425 | */
426 | switch(uMsg) {
427 | case WM_DESTROY:
428 | return cast(LRESULT)0;
429 |
430 | case WM_PAINT:
431 | if (window.context_ is null) {
432 | if ((window.config_.contextType | WindowContextType.Opengl3Plus) == WindowContextType.Opengl3Plus || (window.config_.contextType | WindowContextType.OpenglLegacy) == WindowContextType.OpenglLegacy) {
433 | window.context_ = new OpenglContext(window, window.config_);
434 | } else if (window.config_.contextType == WindowContextType.Direct3D) {
435 | version(Have_directx_d) {
436 | window.context_ = new Direct3dContext(window, window.config_);
437 | }
438 | } else if (window.config_.contextType == WindowContextType.Buffer2D) {
439 | window.context_ = new Buffer2DContext(window, window.config_);
440 | }
441 | }
442 | window.onDraw();
443 | return cast(LRESULT)0;
444 |
445 | case WM_SIZE:
446 | window.onResize(LOWORD(lParam), HIWORD(lParam));
447 | return cast(LRESULT)0;
448 |
449 | case WM_MOVE:
450 | window.onMove(LOWORD(lParam), HIWORD(lParam));
451 | return cast(LRESULT)0;
452 |
453 | case WM_LBUTTONDOWN:
454 | window.onMouseDown(MouseButtons.Left, LOWORD(lParam), HIWORD(lParam));
455 | return cast(LRESULT)0;
456 | case WM_MBUTTONDOWN:
457 | window.onMouseDown(MouseButtons.Middle, LOWORD(lParam), HIWORD(lParam));
458 | return cast(LRESULT)0;
459 | case WM_RBUTTONDOWN:
460 | window.onMouseDown(MouseButtons.Right, LOWORD(lParam), HIWORD(lParam));
461 | return cast(LRESULT)0;
462 |
463 | case WM_MOUSEMOVE:
464 | window.onMouseMove(LOWORD(lParam), HIWORD(lParam));
465 | return cast(LRESULT)0;
466 |
467 | case WM_LBUTTONUP:
468 | window.onMouseUp(MouseButtons.Left);
469 | return cast(LRESULT)0;
470 | case WM_MBUTTONUP:
471 | window.onMouseUp(MouseButtons.Middle);
472 | return cast(LRESULT)0;
473 | case WM_RBUTTONUP:
474 | window.onMouseUp(MouseButtons.Right);
475 | return cast(LRESULT)0;
476 |
477 | case WM_SYSKEYDOWN:
478 | case WM_KEYDOWN:
479 | window.onKeyDown(convertWinKeys(cast(uint)wParam), convertWinKeyModifiers());
480 | return cast(LRESULT)0;
481 |
482 | case WM_SYSKEYUP:
483 | case WM_KEYUP:
484 | window.onKeyUp(convertWinKeys(cast(uint)wParam), convertWinKeyModifiers());
485 | return cast(LRESULT)0;
486 | case WM_CLOSE:
487 | window.onClose();
488 | if (window.countOnClose() == 0)
489 | window.close();
490 | return cast(LRESULT)0;
491 |
492 | default:
493 | break;
494 | }
495 | return DefWindowProcW(hwnd, uMsg, wParam, lParam);
496 | }
497 | }
498 |
499 | Keys convertWinKeys(uint code) {
500 | switch (code)
501 | {
502 | case VK_OEM_1: return Keys.Semicolon;
503 | case VK_OEM_2: return Keys.Slash;
504 | case VK_OEM_PLUS: return Keys.Equals;
505 | case VK_OEM_MINUS: return Keys.Hyphen;
506 | case VK_OEM_4: return Keys.LeftBracket;
507 | case VK_OEM_6: return Keys.RightBracket;
508 | case VK_OEM_COMMA: return Keys.Comma;
509 | case VK_OEM_PERIOD: return Keys.Period;
510 | case VK_OEM_7: return Keys.Quote;
511 | case VK_OEM_5: return Keys.Backslash;
512 | case VK_OEM_3: return Keys.Tilde;
513 | case VK_ESCAPE: return Keys.Escape;
514 | case VK_SPACE: return Keys.Space;
515 | case VK_RETURN: return Keys.Enter;
516 | case VK_BACK: return Keys.Backspace;
517 | case VK_TAB: return Keys.Tab;
518 | case VK_PRIOR: return Keys.PageUp;
519 | case VK_NEXT: return Keys.PageDown;
520 | case VK_END: return Keys.End;
521 | case VK_HOME: return Keys.Home;
522 | case VK_INSERT: return Keys.Insert;
523 | case VK_DELETE: return Keys.Delete;
524 | case VK_ADD: return Keys.Add;
525 | case VK_SUBTRACT: return Keys.Subtract;
526 | case VK_MULTIPLY: return Keys.Multiply;
527 | case VK_DIVIDE: return Keys.Divide;
528 | case VK_PAUSE: return Keys.Pause;
529 | case VK_LEFT: return Keys.Left;
530 | case VK_RIGHT: return Keys.Right;
531 | case VK_UP: return Keys.Up;
532 | case VK_DOWN: return Keys.Down;
533 |
534 | default:
535 | if (code >= VK_F1 && code <= VK_F12)
536 | return cast(Keys)(Keys.F1 + code - VK_F1);
537 | else if (code >= VK_NUMPAD0 && code <= VK_NUMPAD9)
538 | return cast(Keys)(Keys.Numpad0 + code - VK_NUMPAD0);
539 | else if (code >= 'A' && code <= 'Z')
540 | return cast(Keys)(Keys.A + code - 'A');
541 | else if (code >= '0' && code <= '9')
542 | return cast(Keys)(Keys.Number0 + code - '0');
543 | }
544 |
545 | return Keys.Unknown;
546 | }
547 |
548 | KeyModifiers convertWinKeyModifiers() {
549 | KeyModifiers ret;
550 |
551 | if (HIWORD(GetKeyState(VK_MENU)) != 0)
552 | ret |= KeyModifiers.Alt;
553 | if (HIWORD(GetKeyState(VK_CONTROL)) != 0)
554 | ret |= KeyModifiers.Control;
555 | if (HIWORD(GetKeyState(VK_SHIFT)) != 0 || LOWORD(GetKeyState(VK_CAPITAL)) != 0)
556 | ret |= KeyModifiers.Shift;
557 |
558 | return ret;
559 | }
560 | }
--------------------------------------------------------------------------------
/test/main.d:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | module test.main;
25 | import devisualization.window.window;
26 | import devisualization.window.interfaces.context;
27 | import devisualization.image;
28 | import devisualization.image.mutable;
29 | import std.stdio;
30 |
31 | void main() {
32 | Window window = new Window(800, 600, "My DWC window!"w, 100, 100, WindowContextType.Buffer2D);
33 | window.show();
34 |
35 | window.size(200, 200);
36 | window.move(200, 200);
37 |
38 | auto myBuffer = new MutableImage(800, 600);
39 | auto myBufferRGBA = myBuffer.rgba;
40 |
41 | window.addOnDraw((Windowable window2) {
42 | //writeln("drawing");
43 |
44 | Window window = cast(Window)window2;
45 | IContext context = window.context;
46 | if (context !is null) {
47 | writeln("has context");
48 | writeln("type: ", context.type);
49 | writeln("toolkit version: ", context.toolkitVersion);
50 | writeln("shading language version: ", context.shadingLanguageVersion);
51 | } else {
52 | //writeln("has not got context");
53 | return;
54 | }
55 |
56 | if (auto hasbuf = cast(ContextBuffer2D)window.context) {
57 | foreach(i, p; myBufferRGBA) {
58 | myBufferRGBA[i].r = ushort.max;
59 | myBufferRGBA[i].a = ushort.max;
60 | }
61 | } else {
62 | version(Windows) {
63 | if (context.type == WindowContextType.Opengl) {
64 | import derelict.opengl3.gl;
65 | glLoadIdentity();
66 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
67 | glColor3f(0f, 1f, 0f);
68 |
69 | glBegin(GL_TRIANGLES);
70 | glVertex2f(-100, -100);
71 | glVertex2f(100, -100);
72 | glVertex2f(100, 100);
73 |
74 | glVertex2f(-100, -100);
75 | glVertex2f(-100, 100);
76 | glVertex2f(100, 100);
77 | glEnd();
78 | } else if (context !is null && context.type == WindowContextType.Direct3D) {
79 | } else {
80 | }
81 | } else version(linux) {
82 | import xlib = x11.Xlib;
83 | import xx11 = x11.X;
84 |
85 | xlib.Window root;
86 | int x, y;
87 | uint width, height, border, depth;
88 |
89 | auto x11Window = window.x11Window;
90 | auto x11Display = window.x11Display;
91 | auto x11Screen = window.x11Window;
92 | auto x11ScreenNumber = window.x11ScreenNumber;
93 |
94 | xlib.XGetGeometry(x11Display, x11Window, &root, &x, &y, &width, &height, &border, &depth);
95 |
96 | xlib.GC gc;
97 | xlib.XColor color;
98 | xlib.Colormap colormap;
99 |
100 | colormap = xlib.DefaultColormap(x11Display, x11ScreenNumber);
101 | gc = xlib.XCreateGC(x11Display, x11Window, 0, null);
102 |
103 | xlib.XParseColor(x11Display, colormap, cast(char*)"#777777\0".ptr, &color);
104 | xlib.XAllocColor(x11Display, colormap, &color);
105 |
106 | xlib.XSetForeground(x11Display, gc, color.pixel);
107 |
108 | xlib.XFillRectangle(window.x11Display, window.x11Window, gc, 0, 0, width, height);
109 |
110 | xlib.XFreeGC(x11Display, gc);
111 | } else version(OSX) {
112 | if (context.type == WindowContextType.Opengl) {
113 | import derelict.opengl3.gl;
114 | glLoadIdentity();
115 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
116 | glColor3f(0f, 1f, 0f);
117 |
118 | glBegin(GL_TRIANGLES);
119 | glVertex2f(-100, -100);
120 | glVertex2f(100, -100);
121 | glVertex2f(100, 100);
122 |
123 | glVertex2f(-100, -100);
124 | glVertex2f(-100, 100);
125 | glVertex2f(100, 100);
126 | glEnd();
127 | }
128 | }
129 | }
130 | });
131 |
132 | window.addOnMove((Windowable window, int x, int y) {
133 | writeln("move: ", x, ", ", y);
134 | });
135 |
136 | window.addOnResize((Windowable window, uint width, uint height) {
137 | writeln("resize: ", width, " x ", height);
138 | });
139 |
140 | window.addOnMouseDown((Windowable window, MouseButtons button, int x, int y) {
141 | writeln("mouse down ", button, " x=", x, ", y=", y);
142 | });
143 |
144 | window.addOnMouseMove((Windowable window, int x, int y) {
145 | writeln("mouse move x=", x, ", y=", y);
146 | });
147 |
148 | window.addOnMouseUp((Windowable window, MouseButtons button) {
149 | writeln("mouse up ", button);
150 | });
151 |
152 | window.addOnKeyDown((Windowable window, Keys key, KeyModifiers modifiers) {
153 | writeln("key down ", key, " modifiers ", modifiers);
154 | });
155 |
156 | window.addOnKeyUp((Windowable window, Keys key, KeyModifiers modifiers) {
157 | writeln("key up ", key, " modifiers ", modifiers);
158 | });
159 |
160 | window.addOnClose((Windowable window) {
161 | writeln("close");
162 | window.close();
163 | });
164 |
165 | //window.canResize = false;
166 |
167 | window.icon(new MutableImage(2, 2, colorsFromArray([[255, 0, 0], [0, 255, 0, 0], [0, 0, 255], [0, 0, 0]])));
168 |
169 | //window.fullscreen(true);
170 |
171 | //Window.messageLoop();
172 | while(true) {
173 | import core.thread : Thread;
174 | import core.time : dur;
175 | Window.messageLoopIteration();
176 |
177 | bool initContext;
178 |
179 | if (window.hasBeenClosed)
180 | break;
181 | else {
182 | if (window.context !is null && !initContext) {
183 | if (auto hasbuf = cast(ContextBuffer2D)window.context) {
184 | hasbuf.buffer = myBuffer;
185 | initContext = true;
186 | }
187 | }
188 |
189 | window.onDraw();
190 | if (initContext)
191 | window.context.swapBuffers();
192 | }
193 | Thread.sleep(dur!"msecs"(25));
194 | }
195 | }
--------------------------------------------------------------------------------