File: API.cs

package info (click to toggle)
opentk 1.1.4c%2Bdfsg-2.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 68,640 kB
  • sloc: cs: 525,501; xml: 277,501; ansic: 3,597; makefile: 41
file content (1792 lines) | stat: -rw-r--r-- 75,609 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
#region --- License ---
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
 * Contributions from Erik Ylvisaker
 * See license.txt for license info
 */
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;

#pragma warning disable 3019    // CLS-compliance checking
#pragma warning disable 0649    // struct members not explicitly initialized
#pragma warning disable 0169    // field / method is never used.
#pragma warning disable 0414    // field assigned but never used.

namespace OpenTK.Platform.X11
{
    #region Types

    // using XID = System.Int32;
    using Window = System.IntPtr;
    using Drawable = System.IntPtr;
    using Font = System.IntPtr;
    using Pixmap = System.IntPtr;
    using Cursor = System.IntPtr;
    using Colormap = System.IntPtr;
    using GContext = System.IntPtr;
    using KeySym = System.IntPtr;
    using Mask = System.IntPtr;
    using Atom = System.IntPtr;
    using VisualID = System.IntPtr;
    using Time = System.IntPtr;
    using KeyCode = System.Byte;    // Or maybe ushort?

    using Display = System.IntPtr;
    using XPointer = System.IntPtr;

    using XcursorBool = System.Int32;
    using XcursorUInt = System.UInt32;
    using XcursorDim = System.UInt32;
    using XcursorPixel = System.UInt32;

    // Randr and Xrandr
    using Bool = System.Boolean;
    using XRRScreenConfiguration = System.IntPtr; // opaque datatype
    using Rotation = System.UInt16;
    using Status = System.Int32;
    using SizeID = System.UInt16;

    #endregion

    #region internal static class API

    internal static class API
    {
        #region --- Fields ---

        private const string _dll_name = "libX11";
        private const string _dll_name_vid = "libXxf86vm";

        static Display defaultDisplay;
        static int defaultScreen;
        static Window rootWindow;
        static int screenCount;

        internal static Display DefaultDisplay { get { return defaultDisplay; } }
        static int DefaultScreen { get { return defaultScreen; } }
        //internal static Window RootWindow { get { return rootWindow; } }
        internal static int ScreenCount { get { return screenCount; } }
        
        internal static object Lock = new object();

        #endregion

        static API()
        {
            int has_threaded_x = Functions.XInitThreads();
            Debug.Print("Initializing threaded X11: {0}.", has_threaded_x.ToString());
        
            defaultDisplay = Functions.XOpenDisplay(IntPtr.Zero);
                
            if (defaultDisplay == IntPtr.Zero)
                throw new PlatformException("Could not establish connection to the X-Server.");

            using (new XLock(defaultDisplay))
            {
                screenCount = Functions.XScreenCount(DefaultDisplay);
            }
            Debug.Print("Display connection: {0}, Screen count: {1}", DefaultDisplay, ScreenCount);

            //AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
        }

        static void CurrentDomain_ProcessExit(object sender, EventArgs e)
        {
            if (defaultDisplay != IntPtr.Zero)
            {
                Functions.XCloseDisplay(defaultDisplay);
                defaultDisplay = IntPtr.Zero;
                defaultScreen = 0;
                rootWindow = IntPtr.Zero;
            }
        }

        // Display management
        //[DllImport(_dll_name, EntryPoint = "XOpenDisplay")]
        //extern public static IntPtr OpenDisplay([MarshalAs(UnmanagedType.LPTStr)] string display_name);

        //[DllImport(_dll_name, EntryPoint = "XCloseDisplay")]
        //extern public static void CloseDisplay(Display display);

        //[DllImport(_dll_name, EntryPoint = "XCreateColormap")]
        //extern public static IntPtr CreateColormap(Display display, Window window, IntPtr visual, int alloc);

        #region Window handling

        [DllImport(_dll_name, EntryPoint = "XCreateSimpleWindow")]
        public extern static Window CreateSimpleWindow(
            Display display,
            Window parent,
            int x, int y,
            int width, int height,
            int border_width,
            long border,
            long background
        );

        [DllImport(_dll_name, EntryPoint = "XResizeWindow")]
        public extern static int XResizeWindow(Display display, Window window, int width, int height);

        [DllImport(_dll_name, EntryPoint = "XDestroyWindow")]
        public extern static void DestroyWindow(Display display, Window window);

        [DllImport(_dll_name, EntryPoint = "XMapWindow")]
        extern public static void MapWindow(Display display, Window window);

        [DllImport(_dll_name, EntryPoint = "XMapRaised")]
        extern public static void MapRaised(Display display, Window window);

        #endregion

        [DllImport(_dll_name, EntryPoint = "XDefaultVisual")]
        extern public static IntPtr DefaultVisual(Display display, int screen_number);

        #region XFree

        /// <summary>
        /// Frees the memory used by an X structure. Only use on unmanaged structures!
        /// </summary>
        /// <param name="buffer">A pointer to the structure that will be freed.</param>
        [DllImport(_dll_name, EntryPoint = "XFree")]
        extern public static void Free(IntPtr buffer);

        #endregion

        #region Event queue management

        [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport(_dll_name, EntryPoint = "XEventsQueued")]
        extern public static int EventsQueued(Display display, int mode);

        [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport(_dll_name, EntryPoint = "XPending")]
        extern public static int Pending(Display display);

        //[System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport(_dll_name, EntryPoint = "XNextEvent")]
        extern public static void NextEvent(
            Display display,
            [MarshalAs(UnmanagedType.AsAny)][In, Out]object e);

        [DllImport(_dll_name, EntryPoint = "XNextEvent")]
        extern public static void NextEvent(Display display, [In, Out] IntPtr e);

        [DllImport(_dll_name, EntryPoint = "XPeekEvent")]
        extern public static void PeekEvent(
            Display display,
            [MarshalAs(UnmanagedType.AsAny)][In, Out]object event_return
        );

        [DllImport(_dll_name, EntryPoint = "XPeekEvent")]
        extern public static void PeekEvent(Display display, [In, Out]XEvent event_return);

        [DllImport(_dll_name, EntryPoint = "XSendEvent")]
        [return: MarshalAs(UnmanagedType.Bool)]
        extern public static bool SendEvent(Display display, Window window, bool propagate,
            [MarshalAs(UnmanagedType.SysInt)]EventMask event_mask, ref XEvent event_send);

        /// <summary>
        /// The XSelectInput() function requests that the X server report the events associated
        /// with the specified event mask.
        /// </summary>
        /// <param name="display">Specifies the connection to the X server.</param>
        /// <param name="w">Specifies the window whose events you are interested in.</param>
        /// <param name="event_mask">Specifies the event mask.</param>
        /// <remarks>
        /// Initially, X will not report any of these events.
        /// Events are reported relative to a window.
        /// If a window is not interested in a device event,
        /// it usually propagates to the closest ancestor that is interested,
        /// unless the do_not_propagate mask prohibits it.
        /// Setting the event-mask attribute of a window overrides any previous call for the same window but not for other clients. Multiple clients can select for the same events on the same window with the following restrictions: 
        /// <para>Multiple clients can select events on the same window because their event masks are disjoint. When the X server generates an event, it reports it to all interested clients. </para>
        /// <para>Only one client at a time can select CirculateRequest, ConfigureRequest, or MapRequest events, which are associated with the event mask SubstructureRedirectMask. </para>
        /// <para>Only one client at a time can select a ResizeRequest event, which is associated with the event mask ResizeRedirectMask. </para>
        /// <para>Only one client at a time can select a ButtonPress event, which is associated with the event mask ButtonPressMask. </para>
        /// <para>The server reports the event to all interested clients. </para>
        /// <para>XSelectInput() can generate a BadWindow error.</para>
        /// </remarks>
        [DllImport(_dll_name, EntryPoint = "XSelectInput")]
        public static extern void SelectInput(Display display, Window w, EventMask event_mask);

        /// <summary>
        /// When the predicate procedure finds a match, XCheckIfEvent() copies the matched event into the client-supplied XEvent structure and returns True. (This event is removed from the queue.) If the predicate procedure finds no match, XCheckIfEvent() returns False, and the output buffer will have been flushed. All earlier events stored in the queue are not discarded.
        /// </summary>
        /// <param name="display">Specifies the connection to the X server.</param>
        /// <param name="event_return">Returns a copy of the matched event's associated structure.</param>
        /// <param name="predicate">Specifies the procedure that is to be called to determine if the next event in the queue matches what you want</param>
        /// <param name="arg">Specifies the user-supplied argument that will be passed to the predicate procedure.</param>
        /// <returns>true if the predicate returns true for some event, false otherwise</returns>
        [DllImport(_dll_name, EntryPoint = "XCheckIfEvent")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool CheckIfEvent(Display display, ref XEvent event_return,
            /*[MarshalAs(UnmanagedType.FunctionPtr)] */ CheckEventPredicate predicate, /*XPointer*/ IntPtr arg);

        [DllImport(_dll_name, EntryPoint = "XIfEvent")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool IfEvent(Display display, ref XEvent event_return,
            /*[MarshalAs(UnmanagedType.FunctionPtr)] */ CheckEventPredicate predicate, /*XPointer*/ IntPtr arg);

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate bool CheckEventPredicate(Display display, ref XEvent @event, IntPtr arg);

        [DllImport(_dll_name, EntryPoint = "XCheckMaskEvent")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool CheckMaskEvent(Display display, EventMask event_mask, ref XEvent event_return);

        #endregion

        #region Pointer and Keyboard functions

        [DllImport(_dll_name, EntryPoint = "XGrabPointer")]
        extern public static ErrorCodes GrabPointer(Display display, IntPtr grab_window,
            bool owner_events, int event_mask, GrabMode pointer_mode, GrabMode keyboard_mode,
            IntPtr confine_to, IntPtr cursor, int time);

        [DllImport(_dll_name, EntryPoint = "XUngrabPointer")]
        extern public static ErrorCodes UngrabPointer(Display display, int time);

        [DllImport(_dll_name, EntryPoint = "XGrabKeyboard")]
        extern public static ErrorCodes GrabKeyboard(Display display, IntPtr grab_window,
            bool owner_events, GrabMode pointer_mode, GrabMode keyboard_mode, int time);

        [DllImport(_dll_name, EntryPoint = "XUngrabKeyboard")]
        extern public static void UngrabKeyboard(Display display, int time);

        /// <summary>
        /// The XGetKeyboardMapping() function returns the symbols for the specified number of KeyCodes starting with first_keycode.
        /// </summary>
        /// <param name="display">Specifies the connection to the X server.</param>
        /// <param name="first_keycode">Specifies the first KeyCode that is to be returned.</param>
        /// <param name="keycode_count">Specifies the number of KeyCodes that are to be returned</param>
        /// <param name="keysyms_per_keycode_return">Returns the number of KeySyms per KeyCode.</param>
        /// <returns></returns>
        /// <remarks>
        /// <para>The value specified in first_keycode must be greater than or equal to min_keycode as returned by XDisplayKeycodes(), or a BadValue error results. In addition, the following expression must be less than or equal to max_keycode as returned by XDisplayKeycodes(): </para>
        /// <para>first_keycode + keycode_count - 1 </para>
        /// <para>If this is not the case, a BadValue error results. The number of elements in the KeySyms list is: </para>
        /// <para>keycode_count * keysyms_per_keycode_return </para>
        /// <para>KeySym number N, counting from zero, for KeyCode K has the following index in the list, counting from zero: </para>
        /// <para> (K - first_code) * keysyms_per_code_return + N </para>
        /// <para>The X server arbitrarily chooses the keysyms_per_keycode_return value to be large enough to report all requested symbols. A special KeySym value of NoSymbol is used to fill in unused elements for individual KeyCodes. To free the storage returned by XGetKeyboardMapping(), use XFree(). </para>
        /// <para>XGetKeyboardMapping() can generate a BadValue error.</para>
        /// <para>Diagnostics:</para>
        /// <para>BadValue:    Some numeric value falls outside the range of values accepted by the request. Unless a specific range is specified for an argument, the full range defined by the argument's type is accepted. Any argument defined as a set of alternatives can generate this error.</para>
        /// </remarks>
        [DllImport(_dll_name, EntryPoint = "XGetKeyboardMapping")]
        public static extern KeySym GetKeyboardMapping(Display display, KeyCode first_keycode, int keycode_count,
            ref int keysyms_per_keycode_return);

        /// <summary>
        /// The XDisplayKeycodes() function returns the min-keycodes and max-keycodes supported by the specified display.
        /// </summary>
        /// <param name="display">Specifies the connection to the X server.</param>
        /// <param name="min_keycodes_return">Returns the minimum number of KeyCodes</param>
        /// <param name="max_keycodes_return">Returns the maximum number of KeyCodes.</param>
        /// <remarks> The minimum number of KeyCodes returned is never less than 8, and the maximum number of KeyCodes returned is never greater than 255. Not all KeyCodes in this range are required to have corresponding keys.</remarks>
        [DllImport(_dll_name, EntryPoint = "XDisplayKeycodes")]
        public static extern void DisplayKeycodes(Display display, ref int min_keycodes_return, ref int max_keycodes_return);

        #endregion

        #region Xf86VidMode internal structures

        [StructLayout(LayoutKind.Sequential)]
        internal struct XF86VidModeModeLine
        {
            public short hdisplay;   /* Number of display pixels horizontally */
            public short hsyncstart; /* Horizontal sync start */
            public short hsyncend;   /* Horizontal sync end */
            public short htotal;     /* Total horizontal pixels */
            public short vdisplay;   /* Number of display pixels vertically */
            public short vsyncstart; /* Vertical sync start */
            public short vsyncend;   /* Vertical sync start */
            public short vtotal;     /* Total vertical pixels */
            public int flags;      /* Mode flags */
            public int privsize;   /* Size of private */
            public IntPtr _private;   /* Server privates */
        }

        /// <summary>
        /// Specifies an XF86 display mode.
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        internal struct XF86VidModeModeInfo
        {
            /// <summary>
            /// Pixel clock.
            /// </summary>
            public int dotclock;

            /// <summary>
            /// Number of display pixels horizontally
            /// </summary>
            public short hdisplay;

            /// <summary>
            /// Horizontal sync start
            /// </summary>
            public short hsyncstart;

            /// <summary>
            /// Horizontal sync end
            /// </summary>
            public short hsyncend;

            /// <summary>
            /// Total horizontal pixel
            /// </summary>
            public short htotal;

            /// <summary>
            /// 
            /// </summary>
            public short hskew;

            /// <summary>
            /// Number of display pixels vertically
            /// </summary>
            public short vdisplay;

            /// <summary>
            /// Vertical sync start
            /// </summary>
            public short vsyncstart;

            /// <summary>
            /// Vertical sync end
            /// </summary>
            public short vsyncend;

            /// <summary>
            /// Total vertical pixels
            /// </summary>
            public short vtotal;

            /// <summary>
            /// 
            /// </summary>
            public short vskew;

            /// <summary>
            /// Mode flags
            /// </summary>
            public int flags;

            int privsize;   /* Size of private */
            IntPtr _private;   /* Server privates */
        }

        //Monitor information:
        [StructLayout(LayoutKind.Sequential)]
        internal struct XF86VidModeMonitor
        {
            [MarshalAs(UnmanagedType.LPStr)]
            string vendor;     /* Name of manufacturer */
            [MarshalAs(UnmanagedType.LPStr)]
            string model;      /* Model name */
            float EMPTY;      /* unused, for backward compatibility */
            byte nhsync;     /* Number of horiz sync ranges */
            /*XF86VidModeSyncRange* */
            IntPtr hsync;/* Horizontal sync ranges */
            byte nvsync;     /* Number of vert sync ranges */
            /*XF86VidModeSyncRange* */
            IntPtr vsync;/* Vertical sync ranges */
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct XF86VidModeSyncRange
        {
            float hi;         /* Top of range */
            float lo;         /* Bottom of range */
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct XF86VidModeNotifyEvent
        {
            int type;                      /* of event */
            ulong serial;          /* # of last request processed by server */
            bool send_event;               /* true if this came from a SendEvent req */
            Display display;              /* Display the event was read from */
            IntPtr root;                   /* root window of event screen */
            int state;                     /* What happened */
            int kind;                      /* What happened */
            bool forced;                   /* extents of new region */
            /* Time */
            IntPtr time;                     /* event timestamp */
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct XF86VidModeGamma
        {
            float red;                     /* Red Gamma value */
            float green;                   /* Green Gamma value */
            float blue;                    /* Blue Gamma value */
        }
        #endregion

        #region libXxf86vm Functions

        [DllImport(_dll_name_vid)]
        extern public static bool XF86VidModeQueryExtension(
            Display display,
            out int event_base_return,
            out int error_base_return);
        /*
        [DllImport(_dll_name_vid)]
        extern public static bool XF86VidModeSwitchMode(
            Display display,
            int screen,
            int zoom);
        */

        [DllImport(_dll_name_vid)]
        extern public static bool XF86VidModeSwitchToMode(
            Display display,
            int screen,
            IntPtr
            /*XF86VidModeModeInfo* */ modeline);


        [DllImport(_dll_name_vid)]
        extern public static bool XF86VidModeQueryVersion(
            Display display,
            out int major_version_return,
            out int minor_version_return);

        [DllImport(_dll_name_vid)]
        extern public static bool XF86VidModeGetModeLine(
            Display display,
            int screen,
            out int dotclock_return,
            out XF86VidModeModeLine modeline);

        [DllImport(_dll_name_vid)]
        extern public static bool XF86VidModeGetAllModeLines(
            Display display,
            int screen,
            out int modecount_return,
            /*XF86VidModeModeInfo***  <-- yes, that's three *'s. */
            out IntPtr modesinfo);

        [DllImport(_dll_name_vid)]
        extern public static bool XF86VidModeGetViewPort(
            Display display,
            int screen,
            out int x_return,
            out int y_return);

        [DllImport(_dll_name_vid)]
        extern public static bool XF86VidModeSetViewPort(
            Display display,
            int screen,
            int x,
            int y);

        /*
Bool XF86VidModeSetClientVersion(
    Display *display);

Bool XF86VidModeDeleteModeLine(
    Display *display,
    int screen,
    XF86VidModeModeInfo *modeline);

Bool XF86VidModeModModeLine(
    Display *display,
    int screen,
    XF86VidModeModeLine *modeline);

Status XF86VidModeValidateModeLine(
    Display *display,
    int screen,
    XF86VidModeModeLine *modeline);

Bool XF86VidModeLockModeSwitch(
    Display *display,
    int screen,
    int lock);

Bool XF86VidModeGetMonitor(
    Display *display,
    int screen,
    XF86VidModeMonitor *monitor);

XF86VidModeGetDotClocks(
    Display *display,
    int screen,
    int *flags return,
    int *number of clocks return,
    int *max dot clock return,
    int **clocks return);

XF86VidModeGetGamma(
    Display *display,
    int screen,
    XF86VidModeGamma *Gamma);

XF86VidModeSetGamma(
    Display *display,
    int screen,
    XF86VidModeGamma *Gamma);

XF86VidModeGetGammaRamp(
    Display *display,
    int screen,
    int size,
    unsigned short *red array,
    unsigned short *green array,
    unsigned short *blue array);

XF86VidModeSetGammaRamp(
    Display *display,
    int screen,
    int size,
    unsigned short *red array,
    unsigned short *green array,
    unsigned short *blue array);

XF86VidModeGetGammaRampSize(
    Display *display,
    int screen,
    int *size);
         * */

        #endregion

        [DllImport(_dll_name, EntryPoint = "XLookupKeysym")]
        public static extern KeySym LookupKeysym(ref XKeyEvent key_event, int index);

    }
    #endregion

    #region X11 Structures

    #region Xcursor

    [StructLayout(LayoutKind.Sequential)]
    unsafe struct XcursorImage
    {
        public XcursorUInt version;
        public XcursorDim size;
        public XcursorDim width;
        public XcursorDim height;
        public XcursorDim xhot;
        public XcursorDim yhot;
        public XcursorUInt delay;
        public XcursorPixel* pixels;
    }
    
    [StructLayout(LayoutKind.Sequential)]
    unsafe struct XcursorImages 
    {
        public int nimage;
        public XcursorImage **images;
        public char *name;
    }
    
    [StructLayout(LayoutKind.Sequential)]
    unsafe struct XcursorCursors 
    {
        public Display dpy;
        public int refcount;
        public int ncursor;
        public Cursor *cursors;
    }
    
    [StructLayout(LayoutKind.Sequential)]
    unsafe struct XcursorAnimate 
    {
        public XcursorCursors *cursors;
        public int sequence;
    }

    #endregion

    #region internal class XVisualInfo

    [StructLayout(LayoutKind.Sequential)]
    struct XVisualInfo
    {
        public IntPtr Visual;
        public VisualID VisualID;
        public int Screen;
        public int Depth;
        public XVisualClass Class;
        public long RedMask;
        public long GreenMask;
        public long blueMask;
        public int ColormapSize;
        public int BitsPerRgb;

        public override string ToString()
        {
            return String.Format("id ({0}), screen ({1}), depth ({2}), class ({3})",
                VisualID, Screen, Depth, Class);
        }
    }

    #endregion

    #region internal class SetWindowAttributes

    [StructLayout(LayoutKind.Sequential), Obsolete("Use XSetWindowAttributes instead")]
    internal class SetWindowAttributes
    {
        /// <summary>
        /// background, None, or ParentRelative
        /// </summary>
        public Pixmap background_pixmap;
        /// <summary>
        /// background pixel
        /// </summary>
        public long background_pixel;
        /// <summary>
        /// border of the window or CopyFromParent
        /// </summary>
        public Pixmap border_pixmap;
        /// <summary>
        /// border pixel value
        /// </summary>
        public long border_pixel;
        /// <summary>
        /// one of bit gravity values
        /// </summary>
        public int bit_gravity;
        /// <summary>
        /// one of the window gravity values
        /// </summary>
        public int win_gravity;
        /// <summary>
        /// NotUseful, WhenMapped, Always
        /// </summary>
        public int backing_store;
        /// <summary>
        /// planes to be preserved if possible
        /// </summary>
        public long backing_planes;
        /// <summary>
        /// value to use in restoring planes
        /// </summary>
        public long backing_pixel;
        /// <summary>
        /// should bits under be saved? (popups)
        /// </summary>
        public bool save_under;
        /// <summary>
        /// set of events that should be saved
        /// </summary>
        public EventMask event_mask;
        /// <summary>
        /// set of events that should not propagate
        /// </summary>
        public long do_not_propagate_mask;
        /// <summary>
        /// boolean value for override_redirect
        /// </summary>
        public bool override_redirect;
        /// <summary>
        /// color map to be associated with window
        /// </summary>
        public Colormap colormap;
        /// <summary>
        /// cursor to be displayed (or None)
        /// </summary>
        public Cursor cursor;
    }

    #endregion

    #region internal struct SizeHints

    [StructLayout(LayoutKind.Sequential)]
    internal struct SizeHints
    {
        public long flags;         /* marks which fields in this structure are defined */
        public int x, y;           /* Obsolete */
        public int width, height;  /* Obsolete */
        public int min_width, min_height;
        public int max_width, max_height;
        public int width_inc, height_inc;
        public Rectangle min_aspect, max_aspect;
        public int base_width, base_height;
        public int win_gravity;
        internal struct Rectangle
        {
            public int x;       /* numerator */
            public int y;       /* denominator */
            private void stop_the_compiler_warnings() { x = y = 0; }
        }
        /* this structure may be extended in the future */
    }

    #endregion

    #region internal struct XRRScreenSize

    internal struct XRRScreenSize
    {
        internal int Width, Height;
        internal int MWidth, MHeight;
    };

    #endregion

    #region unsafe internal struct Screen

    unsafe internal struct Screen
    {
        XExtData ext_data;    /* hook for extension to hang buffer */
        IntPtr display;     /* back pointer to display structure */ /* _XDisplay */
        Window root;        /* Root window id. */
        int width, height;    /* width and height of screen */
        int mwidth, mheight;    /* width and height of  in millimeters */
        int ndepths;        /* number of depths possible */
        //Depth *depths;        /* list of allowable depths on the screen */
        int root_depth;        /* bits per pixel */
        //Visual* root_visual;    /* root visual */
        IntPtr default_gc;        /* GC for the root root visual */   // GC
        Colormap cmap;        /* default color map */
        UIntPtr white_pixel;    // unsigned long
        UIntPtr black_pixel;    /* White and Black pixel values */  // unsigned long
        int max_maps, min_maps;    /* max and min color maps */
        int backing_store;    /* Never, WhenMapped, Always */
        Bool save_unders;    
        long root_input_mask;    /* initial root input mask */
    }

    #endregion

    #region unsafe internal class XExtData

    unsafe internal class XExtData
    {
        int number;        /* number returned by XRegisterExtension */
        XExtData next;    /* next item on list of buffer for structure */
        delegate int FreePrivateDelegate(XExtData extension);
        FreePrivateDelegate FreePrivate;    /* called to free private storage */
        XPointer private_data;    /* buffer private to this extension. */
    };

    #endregion
    
    #region Motif
    
    [StructLayout(LayoutKind.Sequential)]
    internal struct MotifWmHints
    {
        internal IntPtr flags;
        internal IntPtr functions;
        internal IntPtr decorations;
        internal IntPtr input_mode;
        internal IntPtr status;

        public override string ToString ()
        {
            return string.Format("MotifWmHints <flags={0}, functions={1}, decorations={2}, input_mode={3}, status={4}", (MotifFlags) flags.ToInt32 (), (MotifFunctions) functions.ToInt32 (), (MotifDecorations) decorations.ToInt32 (), (MotifInputMode) input_mode.ToInt32 (), status.ToInt32 ());
        }
    }
    
    [Flags]
    internal enum MotifFlags
    {
        Functions    = 1,
        Decorations  = 2,
        InputMode    = 4,
        Status       = 8
    }

    [Flags]
    internal enum MotifFunctions
    {
        All         = 0x01,
        Resize      = 0x02,
        Move        = 0x04,
        Minimize    = 0x08,
        Maximize    = 0x10,
        Close       = 0x20
    }

    [Flags]
    internal enum MotifDecorations
    {
        All         = 0x01,
        Border      = 0x02,
        ResizeH     = 0x04,
        Title       = 0x08,
        Menu        = 0x10,
        Minimize    = 0x20,
        Maximize    = 0x40,
        
    }

    [Flags]
    internal enum MotifInputMode
    {
        Modeless                = 0,
        ApplicationModal        = 1,
        SystemModal             = 2,
        FullApplicationModal    = 3
    }
    
    #endregion

    #endregion

    #region X11 Constants and Enums

    internal struct Constants
    {
        public const int QueuedAlready = 0;
        public const int QueuedAfterReading = 1;
        public const int QueuedAfterFlush = 2;

        public const int CopyFromParent = 0;
        public const int CWX = 1;
        public const int InputOutput = 1;
        public const int InputOnly = 2;

        /* The hints we recognize */
        public const string XA_WIN_PROTOCOLS           = "_WIN_PROTOCOLS";
        public const string XA_WIN_ICONS               = "_WIN_ICONS";
        public const string XA_WIN_WORKSPACE           = "_WIN_WORKSPACE";
        public const string XA_WIN_WORKSPACE_COUNT     = "_WIN_WORKSPACE_COUNT";
        public const string XA_WIN_WORKSPACE_NAMES     = "_WIN_WORKSPACE_NAMES";
        public const string XA_WIN_LAYER               = "_WIN_LAYER";
        public const string XA_WIN_STATE               = "_WIN_STATE";
        public const string XA_WIN_HINTS               = "_WIN_HINTS";
        public const string XA_WIN_WORKAREA            = "_WIN_WORKAREA";
        public const string XA_WIN_CLIENT_LIST         = "_WIN_CLIENT_LIST";
        public const string XA_WIN_APP_STATE           = "_WIN_APP_STATE";
        public const string XA_WIN_EXPANDED_SIZE       = "_WIN_EXPANDED_SIZE";
        public const string XA_WIN_CLIENT_MOVING       = "_WIN_CLIENT_MOVING";
        public const string XA_WIN_SUPPORTING_WM_CHECK = "_WIN_SUPPORTING_WM_CHECK";
    }

    internal enum WindowLayer
    {
        Desktop    = 0,
        Below      = 2,
        Normal     = 4,
        OnTop      = 6,
        Dock       = 8,
        AboveDock  = 10,
        Menu       = 12,
    }

    internal enum WindowState
    {
        Sticky           = (1<<0), /* everyone knows sticky */
        Minimized        = (1<<1), /* ??? */
        MaximizedVertically = (1<<2), /* window in maximized V state */
        MaximizedHorizontally = (1<<3), /* window in maximized H state */
        Hidden           = (1<<4), /* not on taskbar but window visible */
        Shaded           = (1<<5), /* shaded (NeXT style), */
        HID_WORKSPACE    = (1<<6), /* not on current desktop */
        HID_TRANSIENT    = (1<<7), /* owner of transient is hidden */
        FixedPosition    = (1<<8), /* window is fixed in position even */
        ArrangeIgnore    = (1<<9),  /* ignore for auto arranging */
    }

    internal enum WindowHints
    {
        SkipFocus = (1<<0), /* "alt-tab" skips this win */
        SkipWinlist = (1<<1), /* not in win list */
        SkipTaskbar = (1<<2), /* not on taskbar */
        GroupTransient = (1<<3), /* ??????? */
        FocusOnClick = (1<<4), /* app only accepts focus when clicked */
        DoNotCover = (1<<5),  /* attempt to not cover this window */
    }

    internal enum ErrorCodes : int
    {
        Success = 0,
        BadRequest = 1,
        BadValue = 2,
        BadWindow = 3,
        BadPixmap = 4,
        BadAtom = 5,
        BadCursor = 6,
        BadFont = 7,
        BadMatch = 8,
        BadDrawable = 9,
        BadAccess = 10,
        BadAlloc = 11,
        BadColor = 12,
        BadGC = 13,
        BadIDChoice = 14,
        BadName = 15,
        BadLength = 16,
        BadImplementation = 17,
    }

    [Flags]
    internal enum CreateWindowMask : long//: ulong
    {
        CWBackPixmap    = (1L<<0),
        CWBackPixel     = (1L<<1),
        CWSaveUnder        = (1L<<10),
        CWEventMask        = (1L<<11),
        CWDontPropagate    = (1L<<12),
        CWColormap      = (1L<<13),
        CWCursor        = (1L<<14),
        CWBorderPixmap    = (1L<<2),
        CWBorderPixel    = (1L<<3),
        CWBitGravity    = (1L<<4),
        CWWinGravity    = (1L<<5),
        CWBackingStore    = (1L<<6),
        CWBackingPlanes    = (1L<<7),
        CWBackingPixel     = (1L<<8),
        CWOverrideRedirect    = (1L<<9),

        //CWY    = (1<<1),
        //CWWidth    = (1<<2),
        //CWHeight    = (1<<3),
        //CWBorderWidth    = (1<<4),
        //CWSibling    = (1<<5),
        //CWStackMode    = (1<<6),
    }

    #region XKey

    /// <summary>
    /// Defines LATIN-1 and miscellaneous keys.
    /// </summary>
    [CLSCompliant(false)]
    internal enum XKey
    {
        /*
         * TTY function keys, cleverly chosen to map to ASCII, for convenience of
         * programming, but could have been arbitrary (at the cost of lookup
         * tables in client code).
         */

        BackSpace                   = 0xff08,  /* Back space, back char */
        Tab                         = 0xff09,
        Linefeed                    = 0xff0a,  /* Linefeed, LF */
        Clear                       = 0xff0b,
        Return                      = 0xff0d,  /* Return, enter */
        Pause                       = 0xff13,  /* Pause, hold */
        Scroll_Lock                 = 0xff14,
        Sys_Req                     = 0xff15,
        Escape                      = 0xff1b,
        Delete                      = 0xffff,  /* Delete, rubout */



        /* International & multi-key character composition */

        Multi_key                   = 0xff20,  /* Multi-key character compose */
        Codeinput                   = 0xff37,
        SingleCandidate             = 0xff3c,
        MultipleCandidate           = 0xff3d,
        PreviousCandidate           = 0xff3e,
                
        /* Japanese keyboard support */

        Kanji                       = 0xff21,  /* Kanji, Kanji convert */
        Muhenkan                    = 0xff22,  /* Cancel Conversion */
        Henkan_Mode                 = 0xff23,  /* Start/Stop Conversion */
        Henkan                      = 0xff23,  /* Alias for Henkan_Mode */
        Romaji                      = 0xff24,  /* to Romaji */
        Hiragana                    = 0xff25,  /* to Hiragana */
        Katakana                    = 0xff26,  /* to Katakana */
        Hiragana_Katakana           = 0xff27,  /* Hiragana/Katakana toggle */
        Zenkaku                     = 0xff28,  /* to Zenkaku */
        Hankaku                     = 0xff29,  /* to Hankaku */
        Zenkaku_Hankaku             = 0xff2a,  /* Zenkaku/Hankaku toggle */
        Touroku                     = 0xff2b,  /* Add to Dictionary */
        Massyo                      = 0xff2c,  /* Delete from Dictionary */
        Kana_Lock                   = 0xff2d,  /* Kana Lock */
        Kana_Shift                  = 0xff2e,  /* Kana Shift */
        Eisu_Shift                  = 0xff2f,  /* Alphanumeric Shift */
        Eisu_toggle                 = 0xff30,  /* Alphanumeric toggle */
        Kanji_Bangou                = 0xff37,  /* Codeinput */
        Zen_Koho                    = 0xff3d,  /* Multiple/All Candidate(s) */
        Mae_Koho                    = 0xff3e,  /* Previous Candidate */

        /* 0xff31 thru 0xff3f are under XK_KOREAN */

        /* Cursor control & motion */

        Home                        = 0xff50,
        Left                        = 0xff51,  /* Move left, left arrow */
        Up                          = 0xff52,  /* Move up, up arrow */
        Right                       = 0xff53,  /* Move right, right arrow */
        Down                        = 0xff54,  /* Move down, down arrow */
        Prior                       = 0xff55,  /* Prior, previous */
        Page_Up                     = 0xff55,
        Next                        = 0xff56,  /* Next */
        Page_Down                   = 0xff56,
        End                         = 0xff57,  /* EOL */
        Begin                       = 0xff58,  /* BOL */


        /* Misc functions */

        Select                      = 0xff60,  /* Select, mark */
        Print                       = 0xff61,
        Execute                     = 0xff62,  /* Execute, run, do */
        Insert                      = 0xff63,  /* Insert, insert here */
        Undo                        = 0xff65,
        Redo                        = 0xff66,  /* Redo, again */
        Menu                        = 0xff67,
        Find                        = 0xff68,  /* Find, search */
        Cancel                      = 0xff69,  /* Cancel, stop, abort, exit */
        Help                        = 0xff6a,  /* Help */
        Break                       = 0xff6b,
        Mode_switch                 = 0xff7e,  /* Character set switch */
        script_switch               = 0xff7e,  /* Alias for mode_switch */
        Num_Lock                    = 0xff7f,

        /* Keypad functions, keypad numbers cleverly chosen to map to ASCII */

        KP_Space                    = 0xff80,  /* Space */
        KP_Tab                      = 0xff89,
        KP_Enter                    = 0xff8d,  /* Enter */
        KP_F1                       = 0xff91,  /* PF1, KP_A, ... */
        KP_F2                       = 0xff92,
        KP_F3                       = 0xff93,
        KP_F4                       = 0xff94,
        KP_Home                     = 0xff95,
        KP_Left                     = 0xff96,
        KP_Up                       = 0xff97,
        KP_Right                    = 0xff98,
        KP_Down                     = 0xff99,
        KP_Prior                    = 0xff9a,
        KP_Page_Up                  = 0xff9a,
        KP_Next                     = 0xff9b,
        KP_Page_Down                = 0xff9b,
        KP_End                      = 0xff9c,
        KP_Begin                    = 0xff9d,
        KP_Insert                   = 0xff9e,
        KP_Delete                   = 0xff9f,
        KP_Equal                    = 0xffbd,  /* Equals */
        KP_Multiply                 = 0xffaa,
        KP_Add                      = 0xffab,
        KP_Separator                = 0xffac,  /* Separator, often comma */
        KP_Subtract                 = 0xffad,
        KP_Decimal                  = 0xffae,
        KP_Divide                   = 0xffaf,

        KP_0                        = 0xffb0,
        KP_1                        = 0xffb1,
        KP_2                        = 0xffb2,
        KP_3                        = 0xffb3,
        KP_4                        = 0xffb4,
        KP_5                        = 0xffb5,
        KP_6                        = 0xffb6,
        KP_7                        = 0xffb7,
        KP_8                        = 0xffb8,
        KP_9                        = 0xffb9,

        /*
         * Auxiliary functions; note the duplicate definitions for left and right
         * function keys;  Sun keyboards and a few other manufacturers have such
         * function key groups on the left and/or right sides of the keyboard.
         * We've not found a keyboard with more than 35 function keys total.
         */

        F1                          = 0xffbe,
        F2                          = 0xffbf,
        F3                          = 0xffc0,
        F4                          = 0xffc1,
        F5                          = 0xffc2,
        F6                          = 0xffc3,
        F7                          = 0xffc4,
        F8                          = 0xffc5,
        F9                          = 0xffc6,
        F10                         = 0xffc7,
        F11                         = 0xffc8,
        L1                          = 0xffc8,
        F12                         = 0xffc9,
        L2                          = 0xffc9,
        F13                         = 0xffca,
        L3                          = 0xffca,
        F14                         = 0xffcb,
        L4                          = 0xffcb,
        F15                         = 0xffcc,
        L5                          = 0xffcc,
        F16                         = 0xffcd,
        L6                          = 0xffcd,
        F17                         = 0xffce,
        L7                          = 0xffce,
        F18                         = 0xffcf,
        L8                          = 0xffcf,
        F19                         = 0xffd0,
        L9                          = 0xffd0,
        F20                         = 0xffd1,
        L10                         = 0xffd1,
        F21                         = 0xffd2,
        R1                          = 0xffd2,
        F22                         = 0xffd3,
        R2                          = 0xffd3,
        F23                         = 0xffd4,
        R3                          = 0xffd4,
        F24                         = 0xffd5,
        R4                          = 0xffd5,
        F25                         = 0xffd6,
        R5                          = 0xffd6,
        F26                         = 0xffd7,
        R6                          = 0xffd7,
        F27                         = 0xffd8,
        R7                          = 0xffd8,
        F28                         = 0xffd9,
        R8                          = 0xffd9,
        F29                         = 0xffda,
        R9                          = 0xffda,
        F30                         = 0xffdb,
        R10                         = 0xffdb,
        F31                         = 0xffdc,
        R11                         = 0xffdc,
        F32                         = 0xffdd,
        R12                         = 0xffdd,
        F33                         = 0xffde,
        R13                         = 0xffde,
        F34                         = 0xffdf,
        R14                         = 0xffdf,
        F35                         = 0xffe0,
        R15                         = 0xffe0,

        /* Modifiers */

        Shift_L                     = 0xffe1,  /* Left shift */
        Shift_R                     = 0xffe2,  /* Right shift */
        Control_L                   = 0xffe3,  /* Left control */
        Control_R                   = 0xffe4,  /* Right control */
        Caps_Lock                   = 0xffe5,  /* Caps lock */
        Shift_Lock                  = 0xffe6,  /* Shift lock */

        Meta_L                      = 0xffe7,  /* Left meta */
        Meta_R                      = 0xffe8,  /* Right meta */
        Alt_L                       = 0xffe9,  /* Left alt */
        Alt_R                       = 0xffea,  /* Right alt */
        Super_L                     = 0xffeb,  /* Left super */
        Super_R                     = 0xffec,  /* Right super */
        Hyper_L                     = 0xffed,  /* Left hyper */
        Hyper_R                     = 0xffee,  /* Right hyper */

        ISO_Level3_Shift = 0xfe03,

        /*
         * Latin 1
         * (ISO/IEC 8859-1 = Unicode U+0020..U+00FF)
         * Byte 3 = 0
         */

        space                       = 0x0020,  /* U+0020 SPACE */
        exclam                      = 0x0021,  /* U+0021 EXCLAMATION MARK */
        quotedbl                    = 0x0022,  /* U+0022 QUOTATION MARK */
        numbersign                  = 0x0023,  /* U+0023 NUMBER SIGN */
        dollar                      = 0x0024,  /* U+0024 DOLLAR SIGN */
        percent                     = 0x0025,  /* U+0025 PERCENT SIGN */
        ampersand                   = 0x0026,  /* U+0026 AMPERSAND */
        apostrophe                  = 0x0027,  /* U+0027 APOSTROPHE */
        quoteright                  = 0x0027,  /* deprecated */
        parenleft                   = 0x0028,  /* U+0028 LEFT PARENTHESIS */
        parenright                  = 0x0029,  /* U+0029 RIGHT PARENTHESIS */
        asterisk                    = 0x002a,  /* U+002A ASTERISK */
        plus                        = 0x002b,  /* U+002B PLUS SIGN */
        comma                       = 0x002c,  /* U+002C COMMA */
        minus                       = 0x002d,  /* U+002D HYPHEN-MINUS */
        period                      = 0x002e,  /* U+002E FULL STOP */
        slash                       = 0x002f,  /* U+002F SOLIDUS */
        Number0                           = 0x0030,  /* U+0030 DIGIT ZERO */
        Number1                           = 0x0031,  /* U+0031 DIGIT ONE */
        Number2                           = 0x0032,  /* U+0032 DIGIT TWO */
        Number3                           = 0x0033,  /* U+0033 DIGIT THREE */
        Number4                           = 0x0034,  /* U+0034 DIGIT FOUR */
        Number5                           = 0x0035,  /* U+0035 DIGIT FIVE */
        Number6                           = 0x0036,  /* U+0036 DIGIT SIX */
        Number7                           = 0x0037,  /* U+0037 DIGIT SEVEN */
        Number8                           = 0x0038,  /* U+0038 DIGIT EIGHT */
        Number9                     = 0x0039,  /* U+0039 DIGIT NINE */
        colon                       = 0x003a,  /* U+003A COLON */
        semicolon                   = 0x003b,  /* U+003B SEMICOLON */
        less                        = 0x003c,  /* U+003C LESS-THAN SIGN */
        equal                       = 0x003d,  /* U+003D EQUALS SIGN */
        greater                     = 0x003e,  /* U+003E GREATER-THAN SIGN */
        question                    = 0x003f,  /* U+003F QUESTION MARK */
        at                          = 0x0040,  /* U+0040 COMMERCIAL AT */
        A                           = 0x0041,  /* U+0041 LATIN CAPITAL LETTER A */
        B                           = 0x0042,  /* U+0042 LATIN CAPITAL LETTER B */
        C                           = 0x0043,  /* U+0043 LATIN CAPITAL LETTER C */
        D                           = 0x0044,  /* U+0044 LATIN CAPITAL LETTER D */
        E                           = 0x0045,  /* U+0045 LATIN CAPITAL LETTER E */
        F                           = 0x0046,  /* U+0046 LATIN CAPITAL LETTER F */
        G                           = 0x0047,  /* U+0047 LATIN CAPITAL LETTER G */
        H                           = 0x0048,  /* U+0048 LATIN CAPITAL LETTER H */
        I                           = 0x0049,  /* U+0049 LATIN CAPITAL LETTER I */
        J                           = 0x004a,  /* U+004A LATIN CAPITAL LETTER J */
        K                           = 0x004b,  /* U+004B LATIN CAPITAL LETTER K */
        L                           = 0x004c,  /* U+004C LATIN CAPITAL LETTER L */
        M                           = 0x004d,  /* U+004D LATIN CAPITAL LETTER M */
        N                           = 0x004e,  /* U+004E LATIN CAPITAL LETTER N */
        O                           = 0x004f,  /* U+004F LATIN CAPITAL LETTER O */
        P                           = 0x0050,  /* U+0050 LATIN CAPITAL LETTER P */
        Q                           = 0x0051,  /* U+0051 LATIN CAPITAL LETTER Q */
        R                           = 0x0052,  /* U+0052 LATIN CAPITAL LETTER R */
        S                           = 0x0053,  /* U+0053 LATIN CAPITAL LETTER S */
        T                           = 0x0054,  /* U+0054 LATIN CAPITAL LETTER T */
        U                           = 0x0055,  /* U+0055 LATIN CAPITAL LETTER U */
        V                           = 0x0056,  /* U+0056 LATIN CAPITAL LETTER V */
        W                           = 0x0057,  /* U+0057 LATIN CAPITAL LETTER W */
        X                           = 0x0058,  /* U+0058 LATIN CAPITAL LETTER X */
        Y                           = 0x0059,  /* U+0059 LATIN CAPITAL LETTER Y */
        Z                           = 0x005a,  /* U+005A LATIN CAPITAL LETTER Z */
        bracketleft                 = 0x005b,  /* U+005B LEFT SQUARE BRACKET */
        backslash                   = 0x005c,  /* U+005C REVERSE SOLIDUS */
        bracketright                = 0x005d,  /* U+005D RIGHT SQUARE BRACKET */
        asciicircum                 = 0x005e,  /* U+005E CIRCUMFLEX ACCENT */
        underscore                  = 0x005f,  /* U+005F LOW LINE */
        grave                       = 0x0060,  /* U+0060 GRAVE ACCENT */
        quoteleft                   = 0x0060,  /* deprecated */
        a                           = 0x0061,  /* U+0061 LATIN SMALL LETTER A */
        b                           = 0x0062,  /* U+0062 LATIN SMALL LETTER B */
        c                           = 0x0063,  /* U+0063 LATIN SMALL LETTER C */
        d                           = 0x0064,  /* U+0064 LATIN SMALL LETTER D */
        e                           = 0x0065,  /* U+0065 LATIN SMALL LETTER E */
        f                           = 0x0066,  /* U+0066 LATIN SMALL LETTER F */
        g                           = 0x0067,  /* U+0067 LATIN SMALL LETTER G */
        h                           = 0x0068,  /* U+0068 LATIN SMALL LETTER H */
        i                           = 0x0069,  /* U+0069 LATIN SMALL LETTER I */
        j                           = 0x006a,  /* U+006A LATIN SMALL LETTER J */
        k                           = 0x006b,  /* U+006B LATIN SMALL LETTER K */
        l                           = 0x006c,  /* U+006C LATIN SMALL LETTER L */
        m                           = 0x006d,  /* U+006D LATIN SMALL LETTER M */
        n                           = 0x006e,  /* U+006E LATIN SMALL LETTER N */
        o                           = 0x006f,  /* U+006F LATIN SMALL LETTER O */
        p                           = 0x0070,  /* U+0070 LATIN SMALL LETTER P */
        q                           = 0x0071,  /* U+0071 LATIN SMALL LETTER Q */
        r                           = 0x0072,  /* U+0072 LATIN SMALL LETTER R */
        s                           = 0x0073,  /* U+0073 LATIN SMALL LETTER S */
        t                           = 0x0074,  /* U+0074 LATIN SMALL LETTER T */
        u                           = 0x0075,  /* U+0075 LATIN SMALL LETTER U */
        v                           = 0x0076,  /* U+0076 LATIN SMALL LETTER V */
        w                           = 0x0077,  /* U+0077 LATIN SMALL LETTER W */
        x                           = 0x0078,  /* U+0078 LATIN SMALL LETTER X */
        y                           = 0x0079,  /* U+0079 LATIN SMALL LETTER Y */
        z                           = 0x007a,  /* U+007A LATIN SMALL LETTER Z */
        braceleft                   = 0x007b,  /* U+007B LEFT CURLY BRACKET */
        bar                         = 0x007c,  /* U+007C VERTICAL LINE */
        braceright                  = 0x007d,  /* U+007D RIGHT CURLY BRACKET */
        asciitilde                  = 0x007e,  /* U+007E TILDE */

        // Extra keys

        XF86AudioMute = 0x1008ff12,
        XF86AudioLowerVolume = 0x1008ff11,
        XF86AudioRaiseVolume = 0x1008ff13,
        XF86PowerOff = 0x1008ff2a,
        XF86Suspend = 0x1008ffa7,
        XF86Copy = 0x1008ff57,
        XF86Paste = 0x1008ff6d,
        XF86Cut = 0x1008ff58,
        XF86MenuKB = 0x1008ff65,
        XF86Calculator = 0x1008ff1d,
        XF86Sleep = 0x1008ff2f,
        XF86WakeUp = 0x1008ff2b ,
        XF86Explorer = 0x1008ff5d,
        XF86Send = 0x1008ff7b,
        XF86Xfer = 0x1008ff8a,
        XF86Launch1 = 0x1008ff41,
        XF86Launch2 =     0x1008ff42,
        XF86Launch3 = 0x1008ff43,
        XF86Launch4 =     0x1008ff44,
        XF86Launch5 = 0x1008ff45,
        XF86LaunchA = 0x1008ff4a,
        XF86LaunchB = 0x1008ff4b,
        XF86WWW = 0x1008ff2e,
        XF86DOS = 0x1008ff5a,
        XF86ScreenSaver = 0x1008ff2d,
        XF86RotateWindows = 0x1008ff74,
        XF86Mail = 0x1008ff19,
        XF86Favorites = 0x1008ff30,
        XF86MyComputer = 0x1008ff33,
        XF86Back = 0x1008ff26,
        XF86Forward = 0x1008ff27 ,
        XF86Eject = 0x1008ff2c,
        XF86AudioPlay = 0x1008ff14,
        XF86AudioStop = 0x1008ff15,
        XF86AudioPrev = 0x1008ff16,
        XF86AudioNext = 0x1008ff17,
        XF86AudioRecord = 0x1008ff1c,
        XF86AudioPause =0x1008ff31,
        XF86AudioRewind = 0x1008ff3e,
        XF86AudioForward = 0x1008ff97,
        XF86Phone = 0x1008ff6e,
        XF86Tools = 0x1008ff81,
        XF86HomePage = 0x1008ff18,
        XF86Close = 0x1008ff56,
        XF86Reload = 0x1008ff73,
        XF86ScrollUp = 0x1008ff78,
        XF86ScrollDown = 0x1008ff79,
        XF86New = 0x1008ff68,
        XF86TouchpadToggle = 0x1008ffa9,
        XF86WebCam = 0x1008ff8f,
        XF86Search = 0x1008ff1b,
        XF86Finance = 0x1008ff3c,
        XF86Shop = 0x1008ff36,
        XF86MonBrightnessDown = 0x1008ff03,
        XF86MonBrightnessUp = 0x1008ff02,
        XF86AudioMedia = 0x1008ff32,
        XF86Display = 0x1008ff59,
        XF86KbdLightOnOff = 0x1008ff04,
        XF86KbdBrightnessDown = 0x1008ff06,
        XF86KbdBrightnessUp = 0x1008ff05,
        XF86Reply = 0x1008ff72,
        XF86MailForward = 0x1008ff90,
        XF86Save = 0x1008ff77,
        XF86Documents = 0x1008ff5b,
        XF86Battery = 0x1008ff93,
        XF86Bluetooth = 0x1008ff94,
        XF86WLAN = 0x1008ff95,

         SunProps = 0x1005ff70,
         SunOpen = 0x1005ff73,
    }

    #endregion

#pragma warning disable 1591

    public enum XVisualClass : int
    {
        StaticGray = 0,
        GrayScale = 1,
        StaticColor = 2,
        PseudoColor = 3,
        TrueColor = 4,
        DirectColor = 5,
    }

#pragma warning restore 1591

    [Flags]
    internal enum XVisualInfoMask
    {
        No = 0x0,
        ID = 0x1,
        Screen = 0x2,
        Depth = 0x4,
        Class = 0x8,
        Red = 0x10,
        Green = 0x20,
        Blue = 0x40,
        ColormapSize = 0x80,
        BitsPerRGB = 0x100,
        All = 0x1FF,
    }

    #region internal enum MouseMask

    internal enum MouseMask
    {
        Button1MotionMask = (1 << 8),
        Button2MotionMask = (1 << 9),
        Button3MotionMask = (1 << 10),
        Button4MotionMask = (1 << 11),
        Button5MotionMask = (1 << 12),
        Button1Mask = (1 << 8),
        Button2Mask = (1 << 9),
        Button3Mask = (1 << 10),
        Button4Mask = (1 << 11),
        Button5Mask = (1 << 12),
        Button6Mask = (1 << 13),
        Button7Mask = (1 << 14),
        Button8Mask = (1 << 15),
        ShiftMask = (1 << 0),
        LockMask = (1 << 1),
        ControlMask = (1 << 2),
        Mod1Mask = (1 << 3),
        Mod2Mask = (1 << 4),
        Mod3Mask = (1 << 5),
        Mod4Mask = (1 << 6),
        Mod5Mask = (1 << 7),
    }

    #endregion

    #endregion

    internal static partial class Functions
    {
        internal const string X11Library = "libX11";
        internal const string XcursorLibrary = "libXcursor.so.1";

        #region XCreateWindow

        /// <summary>
        /// The XCreateWindow function creates an unmapped subwindow for a specified parent window, returns the window ID of the created window, and causes the X server to generate a CreateNotify event. The created window is placed on top in the stacking order with respect to siblings.
        /// </summary>
        /// <param name="display">Specifies the connection to the X server.</param>
        /// <param name="parent">Specifies the parent window.</param>
        /// <param name="x">Specify the x coordinates, which are the top-left outside corner of the window's borders and are relative to the inside of the parent window's borders.</param>
        /// <param name="y">Specify the y coordinates, which are the top-left outside corner of the window's borders and are relative to the inside of the parent window's borders.</param>
        /// <param name="width">Specify the width, which is the created window's inside dimensions and do not include the created window's borders.</param>
        /// <param name="height">Specify the height, which is the created window's inside dimensions and do not include the created window's borders.</param>
        /// <param name="border_width">Specifies the width of the created window's border in pixels.</param>
        /// <param name="depth">Specifies the window's depth. A depth of CopyFromParent means the depth is taken from the parent.</param>
        /// <param name="class">Specifies the created window's class. You can pass InputOutput, InputOnly, or CopyFromParent. A class of CopyFromParent means the class is taken from the parent.</param>
        /// <param name="visual">Specifies the visual type. A visual of CopyFromParent means the visual type is taken from the parent.</param>
        /// <param name="valuemask">Specifies which window attributes are defined in the attributes argument. This mask is the bitwise inclusive OR of the valid attribute mask bits. If valuemask is zero, the attributes are ignored and are not referenced.</param>
        /// <param name="attributes">Specifies the structure from which the values (as specified by the value mask) are to be taken. The value mask should have the appropriate bits set to indicate which attributes have been set in the structure.</param>
        /// <returns>The window ID of the created window.</returns>
        /// <remarks>
        /// The coordinate system has the X axis horizontal and the Y axis vertical with the origin [0, 0] at the upper-left corner. Coordinates are integral, in terms of pixels, and coincide with pixel centers. Each window and pixmap has its own coordinate system. For a window, the origin is inside the border at the inside, upper-left corner. 
        /// <para>The border_width for an InputOnly window must be zero, or a BadMatch error results. For class InputOutput, the visual type and depth must be a combination supported for the screen, or a BadMatch error results. The depth need not be the same as the parent, but the parent must not be a window of class InputOnly, or a BadMatch error results. For an InputOnly window, the depth must be zero, and the visual must be one supported by the screen. If either condition is not met, a BadMatch error results. The parent window, however, may have any depth and class. If you specify any invalid window attribute for a window, a BadMatch error results. </para>
        /// <para>The created window is not yet displayed (mapped) on the user's display. To display the window, call XMapWindow(). The new window initially uses the same cursor as its parent. A new cursor can be defined for the new window by calling XDefineCursor(). The window will not be visible on the screen unless it and all of its ancestors are mapped and it is not obscured by any of its ancestors. </para>
        /// <para>XCreateWindow can generate BadAlloc BadColor, BadCursor, BadMatch, BadPixmap, BadValue, and BadWindow errors. </para>
        /// <para>The XCreateSimpleWindow function creates an unmapped InputOutput subwindow for a specified parent window, returns the window ID of the created window, and causes the X server to generate a CreateNotify event. The created window is placed on top in the stacking order with respect to siblings. Any part of the window that extends outside its parent window is clipped. The border_width for an InputOnly window must be zero, or a BadMatch error results. XCreateSimpleWindow inherits its depth, class, and visual from its parent. All other window attributes, except background and border, have their default values. </para>
        /// <para>XCreateSimpleWindow can generate BadAlloc, BadMatch, BadValue, and BadWindow errors.</para>
        /// </remarks>
        public static Window XCreateWindow(Display display, Window parent,
            int x, int y, int width, int height, int border_width, int depth,
            CreateWindowArgs @class, IntPtr visual, SetWindowValuemask valuemask,
            XSetWindowAttributes? attributes)
        {
            unsafe
            {
                if (attributes.HasValue)
                {
                    XSetWindowAttributes attr = attributes.Value;
                    return XCreateWindow(display, parent, x, y, width, height, border_width, depth,
                        (int)@class, visual, (IntPtr)valuemask, &attr);
                }
                else
                {
                    return XCreateWindow(display, parent, x, y, width, height, border_width, depth,
                        (int)@class, visual, (IntPtr)valuemask, null);
                }
            }
        }

        #endregion

        #region XChangeWindowAttributes

        [DllImport(X11Library)]
        internal static extern void XChangeWindowAttributes(Display display, Window w, UIntPtr valuemask, ref XSetWindowAttributes attributes);

        internal static void XChangeWindowAttributes(Display display, Window w, SetWindowValuemask valuemask, ref XSetWindowAttributes attributes)
        {
            XChangeWindowAttributes(display, w, (UIntPtr)valuemask, ref attributes);
        }

        #endregion

        #region Xcursor

        [DllImport(XcursorLibrary)]
        internal static unsafe extern XcursorImage* XcursorImageCreate(int width, int height);

        [DllImport(XcursorLibrary)]
        internal static unsafe extern void XcursorImageDestroy(XcursorImage* image);

        [DllImport(XcursorLibrary)]
        internal static unsafe extern Cursor XcursorImageLoadCursor(Display dpy, XcursorImage* image); 

        #endregion

        #region XQueryKeymap

        /*
        /// <summary>
        /// The XQueryKeymap() function returns a bit vector for the logical state of the keyboard, where each bit set to 1 indicates that the corresponding key is currently pressed down. The vector is represented as 32 bytes. Byte N (from 0) contains the bits for keys 8N to 8N + 7 with the least-significant bit in the byte representing key 8N.
        /// </summary>
        /// <param name="display">Specifies the connection to the X server.</param>
        /// <param name="keys">Returns an array of bytes that identifies which keys are pressed down. Each bit represents one key of the keyboard.</param>
        /// <remarks>Note that the logical state of a device (as seen by client applications) may lag the physical state if device event processing is frozen.</remarks>
        [DllImport(_dll_name, EntryPoint = "XQueryKeymap")]
        extern public static void XQueryKeymap(IntPtr display, [MarshalAs(UnmanagedType.LPArray, SizeConst = 32), In, Out] Keymap keys);
        */

        /// <summary>
        /// The XQueryKeymap() function returns a bit vector for the logical state of the keyboard, where each bit set to 1 indicates that the corresponding key is currently pressed down. The vector is represented as 32 bytes. Byte N (from 0) contains the bits for keys 8N to 8N + 7 with the least-significant bit in the byte representing key 8N.
        /// </summary>
        /// <param name="display">Specifies the connection to the X server.</param>
        /// <param name="keys">Returns an array of bytes that identifies which keys are pressed down. Each bit represents one key of the keyboard.</param>
        /// <remarks>Note that the logical state of a device (as seen by client applications) may lag the physical state if device event processing is frozen.</remarks>
        [DllImport(X11Library, EntryPoint = "XQueryKeymap")]
        extern public static void XQueryKeymap(IntPtr display, byte[] keys);

        #endregion

        #region XMaskEvent

        /// <summary>
        /// The XMaskEvent() function searches the event queue for the events associated with the specified mask. When it finds a match, XMaskEvent() removes that event and copies it into the specified XEvent structure. The other events stored in the queue are not discarded. If the event you requested is not in the queue, XMaskEvent() flushes the output buffer and blocks until one is received.
        /// </summary>
        /// <param name="display">Specifies the connection to the X server.</param>
        /// <param name="event_mask">Specifies the event mask.</param>
        /// <param name="e">Returns the matched event's associated structure.</param>
        [DllImport(X11Library, EntryPoint = "XMaskEvent")]
        extern public static void XMaskEvent(IntPtr display, EventMask event_mask, ref XEvent e);

        #endregion

        #region XPutBackEvent

        /// <summary>
        /// The XPutBackEvent() function pushes an event back onto the head of the display's event queue by copying the event into the queue. This can be useful if you read an event and then decide that you would rather deal with it later. There is no limit to the number of times in succession that you can call XPutBackEvent().
        /// </summary>
        /// <param name="display">Specifies the connection to the X server.</param>
        /// <param name="event">Specifies the event.</param>
        [DllImport(X11Library, EntryPoint = "XPutBackEvent")]
        public static extern void XPutBackEvent(IntPtr display, ref XEvent @event);
        
        #endregion

        #region Xrandr

        const string XrandrLibrary = "libXrandr.so.2";

        [DllImport(XrandrLibrary)]
        public static extern Bool XRRQueryExtension(Display dpy, ref int event_basep, ref int error_basep);

        [DllImport(XrandrLibrary)]
        public static extern Status XRRQueryVersion(Display dpy, ref int major_versionp, ref int minor_versionp);

        [DllImport(XrandrLibrary)]
        public static extern XRRScreenConfiguration XRRGetScreenInfo(Display dpy, Drawable draw);

        [DllImport(XrandrLibrary)]
        public static extern void XRRFreeScreenConfigInfo(XRRScreenConfiguration config);

        [DllImport(XrandrLibrary)]
        public static extern Status XRRSetScreenConfig(Display dpy, XRRScreenConfiguration config,
            Drawable draw, int size_index, Rotation rotation, Time timestamp);

        [DllImport(XrandrLibrary)]
        public static extern Status XRRSetScreenConfigAndRate(Display dpy, XRRScreenConfiguration config,
            Drawable draw, int size_index, Rotation rotation, short rate, Time timestamp);

        [DllImport(XrandrLibrary)]
        public static extern Rotation XRRConfigRotations(XRRScreenConfiguration config, ref Rotation current_rotation);

        [DllImport(XrandrLibrary)]
        public static extern Time XRRConfigTimes(XRRScreenConfiguration config, ref Time config_timestamp);

        [DllImport(XrandrLibrary)]
        [return: MarshalAs(UnmanagedType.LPStruct)]
        public static extern XRRScreenSize XRRConfigSizes(XRRScreenConfiguration config, int[] nsizes);

        [DllImport(XrandrLibrary)]
        unsafe public static extern short* XRRConfigRates(XRRScreenConfiguration config, int size_index, int[] nrates);

        [DllImport(XrandrLibrary)]
        public static extern SizeID XRRConfigCurrentConfiguration(XRRScreenConfiguration config, out Rotation rotation);

        [DllImport(XrandrLibrary)]
        public static extern short XRRConfigCurrentRate(XRRScreenConfiguration config);

        [DllImport(XrandrLibrary)]
        public static extern int XRRRootToScreen(Display dpy, Window root);

        [DllImport(XrandrLibrary)]
        public static extern XRRScreenConfiguration XRRScreenConfig(Display dpy, int screen);

        [DllImport(XrandrLibrary)]
        public static extern XRRScreenConfiguration XRRConfig(ref Screen screen);

        [DllImport(XrandrLibrary)]
        public static extern void XRRSelectInput(Display dpy, Window window, int mask);

        /*
         * intended to take RRScreenChangeNotify,  or
         * ConfigureNotify (on the root window)
         * returns 1 if it is an event type it understands, 0 if not
         */
        [DllImport(XrandrLibrary)]
        public static extern int XRRUpdateConfiguration(ref XEvent @event);

        /*
         * the following are always safe to call, even if RandR is
         * not implemented on a screen
         */
        [DllImport(XrandrLibrary)]
        public static extern Rotation XRRRotations(Display dpy, int screen, ref Rotation current_rotation);

        [DllImport(XrandrLibrary)]
        unsafe static extern IntPtr XRRSizes(Display dpy, int screen, int* nsizes);

        public static XRRScreenSize[] XRRSizes(Display dpy, int screen)
        {
            XRRScreenSize[] sizes;
            //IntPtr ptr;
            int count;
            unsafe
            {
                //ptr = XRRSizes(dpy, screen, &nsizes);

                byte* data = (byte*)XRRSizes(dpy, screen, &count);//(byte*)ptr;
                if (count == 0)
                    return null;
                sizes = new XRRScreenSize[count];
                for (int i = 0; i < count; i++)
                {
                    sizes[i] = new XRRScreenSize();
                    sizes[i] = (XRRScreenSize)Marshal.PtrToStructure((IntPtr)data, typeof(XRRScreenSize));
                    data += Marshal.SizeOf(typeof(XRRScreenSize));
                }
                //XFree(ptr);   // Looks like we must not free this.
                return sizes;
            }
        }

        [DllImport(XrandrLibrary)]
        unsafe static extern short* XRRRates(Display dpy, int screen, int size_index, int* nrates);

        public static short[] XRRRates(Display dpy, int screen, int size_index)
        {
            short[] rates;
            int count;
            unsafe
            {
                short* data = (short*)XRRRates(dpy, screen, size_index, &count);
                if (count == 0)
                    return null;
                rates = new short[count];
                for (int i = 0; i < count; i++)
                    rates[i] = *(data + i);
            }
            return rates;
        }

        [DllImport(XrandrLibrary)]
        public static extern Time XRRTimes(Display dpy, int screen, out Time config_timestamp);

        #endregion

        #region Display, Screen and Window functions

        #region XScreenCount

        [DllImport(X11Library)]
        public static extern int XScreenCount(Display display);

        #endregion

        #region XListDepths

        [DllImport(X11Library)]
        unsafe static extern int *XListDepths(Display display, int screen_number, int* count_return);

        public static int[] XListDepths(Display display, int screen_number)
        {
            unsafe
            {
                int count;
                int* data = XListDepths(display, screen_number, &count);
                if (count == 0)
                    return null;
                int[] depths = new int[count];
                for (int i = 0; i < count; i++)
                    depths[i] = *(data + i);

                return depths;
            }
        }

        #endregion

        #endregion

        public static Pixmap XCreateBitmapFromData(Display display, Window d, byte[,] data)
        {
            if (data == null)
                throw new ArgumentNullException("data");

            unsafe
            {
                fixed (byte* pdata = data)
                {
                    return XCreateBitmapFromData(display, d, pdata, data.GetLength(0), data.GetLength(1));
                }
            }
        }

        [DllImport(X11Library)]
        unsafe public static extern Pixmap XCreateBitmapFromData(Display display, Window d, byte* data, int width, int height);

        [DllImport("libX11", EntryPoint = "XAllocColor")]
        public static extern Status XAllocNamedColor(Display display, Colormap colormap, string color_name, out XColor screen_def_return, out XColor exact_def_return);
    }
    /*
    [StructLayout(LayoutKind.Sequential)]
    internal struct Keymap
    {
        unsafe fixed byte bits[32];

        public bool this[KeyCode key]
        {
            get
            {
                unsafe
                {
                    fixed (Keymap* ptr = &this)
                    {
                        return ((ptr->bits[key / 8] >> (key % 8)) & 0x01) != 0;
                    }
                }
            }
        }
    }
    */

    // Helper structure for calling XLock/UnlockDisplay
    struct XLock : IDisposable
    {
        IntPtr _display;

        public IntPtr Display
        {
            get
            {
                if (_display == IntPtr.Zero)
                    throw new InvalidOperationException("Internal error (XLockDisplay with IntPtr.Zero). Please report this at http://www.opentk.com/node/add/project-issue/opentk");
                return _display;
            }
            set
            {
                if (value == IntPtr.Zero)
                    throw new ArgumentException();
                _display = value;
            }
        }

        public XLock(IntPtr display)
            : this()
        {
            Display = display;
            Functions.XLockDisplay(Display);
        }

        public void Dispose()
        {
            Functions.XUnlockDisplay(Display);
        }
    }

    // XAllowEvent modes
    enum EventMode
    {
        AsyncPointer = 0,
        SyncPointer,
        ReplayPointer,
        AsyncKeyboard,
        SyncKeyboard,
        ReplayKeyboard,
        AsyncBoth,
        SyncBoth
    }
}

#pragma warning restore 3019
#pragma warning restore 0649
#pragma warning restore 0169
#pragma warning restore 0414