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