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 sun.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</code> 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 72 static boolean getBool(long ptr) { return getInt(ptr) != 0; } 73 static boolean getBool(long ptr, int index) { return getInt(ptr, index) != 0; } 74 static void putBool(long ptr, boolean data) { putInt(ptr, (data)?(1):(0)); } 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 */ 81 static int getByteSize() { return 1; } 82 static byte getByte(long ptr) { return unsafe.getByte(ptr); } 83 84 static byte getByte(long ptr, int index) { 85 return getByte(ptr+index); 86 } 87 /** 88 * Stores to C byte data(one byte) 89 */ 90 static void putByte(long ptr, byte data) { unsafe.putByte(ptr, data); } 91 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</code> 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 */ 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 */ 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 */ 129 static int getUByteSize() { return 1; } 130 static short getUByte(long ptr) { return (short)(0xFF & unsafe.getByte(ptr)); } 131 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 */ 139 static void putUByte(long ptr, short data) { unsafe.putByte(ptr, (byte)data); } 140 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</code> 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 */ 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 */ 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 */ 181 static int getShortSize() { return 2; } 182 static short getShort(long ptr) { return unsafe.getShort(ptr); } 183 /** 184 * Stores to C short data(two bytes) 185 */ 186 static void putShort(long ptr, short data) { unsafe.putShort(ptr, data); } 187 static void putShort(long ptr, int index, short data) { 188 putShort(ptr + index*getShortSize(), data); 189 } 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 */ 204 static int getUShortSize() { return 2; } 205 206 static int getUShort(long ptr) { return 0xFFFF & unsafe.getShort(ptr); } 207 /** 208 * Stores to C unsigned short data(two bytes) 209 */ 210 static void putUShort(long ptr, int data) { unsafe.putShort(ptr, (short)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 */ 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 */ 234 static int getIntSize() { return 4; } 235 static int getInt(long ptr) { return unsafe.getInt(ptr); } 236 static int getInt(long ptr, int index) { return getInt(ptr +getIntSize()*index); } 237 /** 238 * Stores to C int data(four bytes) 239 */ 240 static void putInt(long ptr, int data) { unsafe.putInt(ptr, data); } 241 static void putInt(long ptr, int index, int data) { 242 putInt(ptr + index*getIntSize(), data); 243 } 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 */ 258 static int getUIntSize() { return 4; } 259 static long getUInt(long ptr) { return 0xFFFFFFFFL & unsafe.getInt(ptr); } 260 static long getUInt(long ptr, int index) { return getUInt(ptr +getIntSize()*index); } 261 /** 262 * Stores to C unsigned int data(four bytes) 263 */ 264 static void putUInt(long ptr, long data) { unsafe.putInt(ptr, (int)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 */ 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 */ 288 static int getLongSize() { 289 return longSize; 290 } 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</code> has <code>long</code> type 301 * to be able to keep 64-bit C <code>long</code> data 302 */ 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 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 */ 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</code>s 324 */ 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</code>s 334 */ 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</code>s. Array is stored in reverse order 344 */ 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</code> 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 */ 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 } 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 */ 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 391 static void putULong(long ptr, long value) { 392 putLong(ptr, value); 393 } 394 395 /** 396 * Allocates memory for array of native <code>long</code>s of the size <code>length</code> 397 */ 398 static long allocateLongArray(int length) { 399 return unsafe.allocateMemory(getLongSize() * length); 400 } 401 402 403 static long getWindow(long ptr) { 404 return getLong(ptr); 405 } 406 static long getWindow(long ptr, int index) { 407 return getLong(ptr + getWindowSize()*index); 408 } 409 410 static void putWindow(long ptr, long window) { 411 putLong(ptr, window); 412 } 413 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 */ 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 */ 433 static long getCard32(long ptr) { 434 return getLong(ptr); 435 } 436 static void putCard32(long ptr, long value) { 437 putLong(ptr, value); 438 } 439 static long getCard32(long ptr, int index) { 440 return getLong(ptr, index); 441 } 442 static void putCard32(long ptr, int index, long value) { 443 putLong(ptr, index, value); 444 } 445 static int getCard32Size() { 446 return getLongSize(); 447 } 448 static long[] card32ToArray(long ptr, int length) { 449 return toLongs(ptr, length); 450 } 451 static long card32ToData(long[] arr) { 452 return toData(arr); 453 } 454 }