1 /*
2  * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package sun.awt.X11;
27 
28 import jdk.internal.misc.Unsafe;
29 import java.util.Vector;
30 import java.security.AccessController;
31 import java.security.PrivilegedAction;
32 
33 /**
34  * This class contains the collection of utility functions to help work with
35  * native data types on different platforms similarly.
36  */
37 
38 class Native {
39 
40     private static Unsafe unsafe = XlibWrapper.unsafe;
41 
42     static int longSize;
43 
44     static int dataModel;
45     static {
46         String dataModelProp = AccessController.doPrivileged(
47             new PrivilegedAction<String>() {
48                 public String run() {
49                     return System.getProperty("sun.arch.data.model");
50                 }
51             });
52         try {
53             dataModel = Integer.parseInt(dataModelProp);
54         } catch (Exception e) {
55             dataModel = 32;
56         }
57         if (dataModel == 32) {
58             longSize = 4;
59         } else {
60             longSize = 8;
61         }
62     }
63 
64     /**
65      * Set of helper function to read data of different PLATFORM types
66      * from memory pointer by {@code ptr}
67      * Note, names of types in function are NATIVE PLATFORM types
68      * and they have the same size as they would have in C compiler
69      * on the same platform.
70      */
71 
getBool(long ptr)72     static boolean getBool(long ptr) { return getInt(ptr) != 0; }
getBool(long ptr, int index)73     static boolean getBool(long ptr, int index) { return getInt(ptr, index) != 0; }
putBool(long ptr, boolean data)74     static void putBool(long ptr, boolean data) { putInt(ptr, (data)?(1):(0)); }
putBool(long ptr, int index, boolean data)75     static void putBool(long ptr, int index, boolean data) { putInt(ptr, index, (data)?(1):(0)); }
76 
77 
78     /**
79      * Access to C byte data(one byte)
80      */
getByteSize()81     static int getByteSize() { return 1; }
getByte(long ptr)82     static byte getByte(long ptr) { return unsafe.getByte(ptr); }
83 
getByte(long ptr, int index)84     static byte getByte(long ptr, int index) {
85         return getByte(ptr+index);
86     }
87     /**
88      * Stores to C byte data(one byte)
89      */
putByte(long ptr, byte data)90     static void putByte(long ptr, byte data) { unsafe.putByte(ptr, data); }
91 
putByte(long ptr, int index, byte data)92     static void putByte(long ptr, int index, byte data) {
93         putByte(ptr+index, data);
94     }
95     /**
96      * Converts length bytes of data pointed by {@code data} into byte array
97      * Returns null if data is zero
98      * @param data native pointer to native memory
99      * @param length size in bytes of native memory
100      */
toBytes(long data, int length)101     static byte[] toBytes(long data, int length) {
102         if (data == 0) {
103             return null;
104         }
105         byte[] res = new byte[length];
106         for (int i = 0; i < length; i++, data++) {
107             res[i] = getByte(data);
108         }
109         return res;
110     }
111     /**
112      * Stores byte array into native memory and returns pointer to this memory
113      * Returns 0 if bytes is null
114      */
toData(byte[] bytes)115     static long toData(byte[] bytes) {
116         if (bytes == null) {
117             return 0;
118         }
119         long res = XlibWrapper.unsafe.allocateMemory(bytes.length);
120         for (int i = 0; i < bytes.length; i++) {
121             putByte(res+i, bytes[i]);
122         }
123         return res;
124     }
125 
126     /**
127      * Access to C unsigned byte data(one byte)
128      */
getUByteSize()129     static int getUByteSize() { return 1; }
getUByte(long ptr)130     static short getUByte(long ptr) { return (short)(0xFF & unsafe.getByte(ptr));  }
131 
getUByte(long ptr, int index)132     static short getUByte(long ptr, int index) {
133         return getUByte(ptr+index);
134     }
135 
136     /**
137      * Stores to C unsigned byte data(one byte)
138      */
putUByte(long ptr, short data)139     static void putUByte(long ptr, short data) { unsafe.putByte(ptr, (byte)data); }
140 
putUByte(long ptr, int index, short data)141     static void putUByte(long ptr, int index, short data) {
142         putUByte(ptr+index, data);
143     }
144 
145     /**
146      * Converts length usnigned bytes of data pointed by {@code data} into
147      * short array
148      * Returns null if data is zero
149      * @param data native pointer to native memory
150      * @param length size in bytes of native memory
151      */
toUBytes(long data, int length)152     static short[] toUBytes(long data, int length) {
153         if (data == 0) {
154             return null;
155         }
156         short[] res = new short[length];
157         for (int i = 0; i < length; i++, data++) {
158             res[i] = getUByte(data);
159         }
160         return res;
161     }
162     /**
163      * Stores short array as unsigned bytes into native memory and returns pointer
164      * to this memory
165      * Returns 0 if bytes is null
166      */
toUData(short[] bytes)167     static long toUData(short[] bytes) {
168         if (bytes == null) {
169             return 0;
170         }
171         long res = XlibWrapper.unsafe.allocateMemory(bytes.length);
172         for (int i = 0; i < bytes.length; i++) {
173             putUByte(res+i, bytes[i]);
174         }
175         return res;
176     }
177 
178     /**
179      * Access to C short data(two bytes)
180      */
getShortSize()181     static int getShortSize() { return 2; }
getShort(long ptr)182     static short getShort(long ptr) { return unsafe.getShort(ptr); }
183     /**
184      * Stores to C short data(two bytes)
185      */
putShort(long ptr, short data)186     static void putShort(long ptr, short data) { unsafe.putShort(ptr, data); }
putShort(long ptr, int index, short data)187     static void putShort(long ptr, int index, short data) {
188         putShort(ptr + index*getShortSize(), data);
189     }
toData(short[] shorts)190     static long toData(short[] shorts) {
191         if (shorts == null) {
192             return 0;
193         }
194         long res = XlibWrapper.unsafe.allocateMemory(shorts.length*getShortSize());
195         for (int i = 0; i < shorts.length; i++) {
196             putShort(res, i, shorts[i]);
197         }
198         return res;
199     }
200 
201     /**
202      * Access to C unsigned short data(two bytes)
203      */
getUShortSize()204     static int getUShortSize() { return 2; }
205 
getUShort(long ptr)206     static int getUShort(long ptr) { return 0xFFFF & unsafe.getShort(ptr); }
207     /**
208      * Stores to C unsigned short data(two bytes)
209      */
putUShort(long ptr, int data)210     static void putUShort(long ptr, int data) { unsafe.putShort(ptr, (short)data); }
putUShort(long ptr, int index, int data)211     static void putUShort(long ptr, int index, int data) {
212         putUShort(ptr + index*getShortSize(), data);
213     }
214 
215     /**
216      * Stores int array as unsigned shorts into native memory and returns pointer
217      * to this memory
218      * Returns 0 if bytes is null
219      */
toUData(int[] shorts)220     static long toUData(int[] shorts) {
221         if (shorts == null) {
222             return 0;
223         }
224         long res = XlibWrapper.unsafe.allocateMemory(shorts.length*getShortSize());
225         for (int i = 0; i < shorts.length; i++) {
226             putUShort(res, i, shorts[i]);
227         }
228         return res;
229     }
230 
231     /**
232      * Access to C int data(four bytes)
233      */
getIntSize()234     static int getIntSize() { return 4; }
getInt(long ptr)235     static int getInt(long ptr) { return unsafe.getInt(ptr); }
getInt(long ptr, int index)236     static int getInt(long ptr, int index) { return getInt(ptr +getIntSize()*index); }
237     /**
238      * Stores to C int data(four bytes)
239      */
putInt(long ptr, int data)240     static void putInt(long ptr, int data) { unsafe.putInt(ptr, data); }
putInt(long ptr, int index, int data)241     static void putInt(long ptr, int index, int data) {
242         putInt(ptr + index*getIntSize(), data);
243     }
toData(int[] ints)244     static long toData(int[] ints) {
245         if (ints == null) {
246             return 0;
247         }
248         long res = XlibWrapper.unsafe.allocateMemory(ints.length*getIntSize());
249         for (int i = 0; i < ints.length; i++) {
250             putInt(res, i, ints[i]);
251         }
252         return res;
253     }
254 
255     /**
256      * Access to C unsigned int data(four bytes)
257      */
getUIntSize()258     static int getUIntSize() { return 4; }
getUInt(long ptr)259     static long getUInt(long ptr) { return 0xFFFFFFFFL & unsafe.getInt(ptr); }
getUInt(long ptr, int index)260     static long getUInt(long ptr, int index) { return getUInt(ptr +getIntSize()*index); }
261     /**
262      * Stores to C unsigned int data(four bytes)
263      */
putUInt(long ptr, long data)264     static void putUInt(long ptr, long data) { unsafe.putInt(ptr, (int)data); }
putUInt(long ptr, int index, long data)265     static void putUInt(long ptr, int index, long data) {
266         putUInt(ptr + index*getIntSize(), data);
267     }
268 
269     /**
270      * Stores long array as unsigned intss into native memory and returns pointer
271      * to this memory
272      * Returns 0 if bytes is null
273      */
toUData(long[] ints)274     static long toUData(long[] ints) {
275         if (ints == null) {
276             return 0;
277         }
278         long res = XlibWrapper.unsafe.allocateMemory(ints.length*getIntSize());
279         for (int i = 0; i < ints.length; i++) {
280             putUInt(res, i, ints[i]);
281         }
282         return res;
283     }
284 
285     /**
286      * Access to C long data(size depends on platform)
287      */
getLongSize()288     static int getLongSize() {
289         return longSize;
290     }
getLong(long ptr)291     static long getLong(long ptr) {
292         if (XlibWrapper.dataModel == 32) {
293             return unsafe.getInt(ptr);
294         } else {
295             return unsafe.getLong(ptr);
296         }
297     }
298     /**
299      * Stores to C long data(four bytes)
300      * Note: {@code data} has {@code long} type
301      * to be able to keep 64-bit C {@code long} data
302      */
putLong(long ptr, long data)303     static void putLong(long ptr, long data) {
304         if (XlibWrapper.dataModel == 32) {
305             unsafe.putInt(ptr, (int)data);
306         } else {
307             unsafe.putLong(ptr, data);
308         }
309     }
310 
putLong(long ptr, int index, long data)311     static void putLong(long ptr, int index, long data) {
312         putLong(ptr+index*getLongSize(), data);
313     }
314 
315     /**
316      * Returns index's element of the array of native long pointed by ptr
317      */
getLong(long ptr, int index)318     static long getLong(long ptr, int index) {
319         return getLong(ptr + index*getLongSize());
320     }
321     /**
322      * Stores Java long[] array into memory. Memory location is treated as array
323      * of native {@code long}s
324      */
put(long ptr, long[] arr)325     static void put(long ptr, long[] arr) {
326         for (int i = 0; i < arr.length; i ++, ptr += getLongSize()) {
327             putLong(ptr, arr[i]);
328         }
329     }
330 
331     /**
332      * Stores Java Vector of Longs into memory. Memory location is treated as array
333      * of native {@code long}s
334      */
putLong(long ptr, Vector<Long> arr)335     static void putLong(long ptr, Vector<Long> arr) {
336         for (int i = 0; i < arr.size(); i ++, ptr += getLongSize()) {
337             putLong(ptr, arr.elementAt(i).longValue());
338         }
339     }
340 
341     /**
342      * Stores Java Vector of Longs into memory. Memory location is treated as array
343      * of native {@code long}s. Array is stored in reverse order
344      */
putLongReverse(long ptr, Vector<Long> arr)345     static void putLongReverse(long ptr, Vector<Long> arr) {
346         for (int i = arr.size()-1; i >= 0; i--, ptr += getLongSize()) {
347             putLong(ptr, arr.elementAt(i).longValue());
348         }
349     }
350     /**
351      * Converts length bytes of data pointed by {@code data} into byte array
352      * Returns null if data is zero
353      * @param data native pointer to native memory
354      * @param length size in longs(platform dependent) of native memory
355      */
toLongs(long data, int length)356     static long[] toLongs(long data, int length) {
357         if (data == 0) {
358             return null;
359         }
360         long[] res = new long[length];
361         for (int i = 0; i < length; i++, data += getLongSize()) {
362             res[i] = getLong(data);
363         }
364         return res;
365     }
toData(long[] longs)366     static long toData(long[] longs) {
367         if (longs == null) {
368             return 0;
369         }
370         long res = XlibWrapper.unsafe.allocateMemory(longs.length*getLongSize());
371         for (int i = 0; i < longs.length; i++) {
372             putLong(res, i, longs[i]);
373         }
374         return res;
375     }
376 
377 
378     /**
379      * Access to C "unsigned long" date type, which is XID in X
380      */
getULong(long ptr)381     static long getULong(long ptr) {
382         if (XlibWrapper.dataModel == 32) {
383             // Compensate sign-expansion
384             return ((long)unsafe.getInt(ptr)) & 0xFFFFFFFFL;
385         } else {
386             // Can't do anything!!!
387             return unsafe.getLong(ptr);
388         }
389     }
390 
putULong(long ptr, long value)391     static void putULong(long ptr, long value) {
392         putLong(ptr, value);
393     }
394 
395     /**
396      * Allocates memory for array of native {@code long}s of the size {@code length}
397      */
allocateLongArray(int length)398     static long allocateLongArray(int length) {
399         return unsafe.allocateMemory(getLongSize() * length);
400     }
401 
402 
getWindow(long ptr)403     static long getWindow(long ptr) {
404         return getLong(ptr);
405     }
getWindow(long ptr, int index)406     static long getWindow(long ptr, int index) {
407         return getLong(ptr + getWindowSize()*index);
408     }
409 
putWindow(long ptr, long window)410     static void putWindow(long ptr, long window) {
411         putLong(ptr, window);
412     }
413 
putWindow(long ptr, int index, long window)414     static void putWindow(long ptr, int index, long window) {
415         putLong(ptr, index, window);
416     }
417 
418     /**
419      * Set of function to return sizes of C data of the appropriate
420      * type.
421      */
getWindowSize()422     static int getWindowSize() {
423         return getLongSize();
424     }
425 
426 
427     /**
428      * Set of function to access CARD32 type. All data which types are derived
429      * from CARD32 should be accessed using this accessors.
430      * These types are: XID(Window, Drawable, Font, Pixmap, Cursor, Colormap, GContext, KeySym),
431      *                  Atom, Mask, VisualID, Time
432      */
getCard32(long ptr)433     static long getCard32(long ptr) {
434         return getLong(ptr);
435     }
putCard32(long ptr, long value)436     static void putCard32(long ptr, long value) {
437         putLong(ptr, value);
438     }
getCard32(long ptr, int index)439     static long getCard32(long ptr, int index) {
440         return getLong(ptr, index);
441     }
putCard32(long ptr, int index, long value)442     static void putCard32(long ptr, int index, long value) {
443         putLong(ptr, index, value);
444     }
getCard32Size()445     static int getCard32Size() {
446         return getLongSize();
447     }
card32ToArray(long ptr, int length)448     static long[] card32ToArray(long ptr, int length) {
449         return toLongs(ptr, length);
450     }
card32ToData(long[] arr)451     static long card32ToData(long[] arr) {
452         return toData(arr);
453     }
454 }
455