├── .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 | [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/Devisualization/window?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 6 | [![Build Status](https://travis-ci.org/Devisualization/window.svg)](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 | } --------------------------------------------------------------------------------