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 = (String)AccessController. 47 doPrivileged( 48 new PrivilegedAction() { 49 public Object run() { 50 return System.getProperty("sun.arch.data.model"); 51 } 52 }); 53 try { 54 dataModel = Integer.parseInt(dataModelProp); 55 } catch (Exception e) { 56 dataModel = 32; 57 } 58 if (dataModel == 32) { 59 longSize = 4; 60 } else { 61 longSize = 8; 62 } 63 } 64 65 /** 66 * Set of helper function to read data of different PLATFORM types 67 * from memory pointer by <code>ptr</code> 68 * Note, names of types in function are NATIVE PLATFORM types 69 * and they have the same size as they would have in C compiler 70 * on the same platform. 71 */ 72 getBool(long ptr)73 static boolean getBool(long ptr) { return getInt(ptr) != 0; } getBool(long ptr, int index)74 static boolean getBool(long ptr, int index) { return getInt(ptr, index) != 0; } putBool(long ptr, boolean data)75 static void putBool(long ptr, boolean data) { putInt(ptr, (data)?(1):(0)); } putBool(long ptr, int index, boolean data)76 static void putBool(long ptr, int index, boolean data) { putInt(ptr, index, (data)?(1):(0)); } 77 78 79 /** 80 * Access to C byte data(one byte) 81 */ getByteSize()82 static int getByteSize() { return 1; } getByte(long ptr)83 static byte getByte(long ptr) { return unsafe.getByte(ptr); } 84 getByte(long ptr, int index)85 static byte getByte(long ptr, int index) { 86 return getByte(ptr+index); 87 } 88 /** 89 * Stores to C byte data(one byte) 90 */ putByte(long ptr, byte data)91 static void putByte(long ptr, byte data) { unsafe.putByte(ptr, data); } 92 putByte(long ptr, int index, byte data)93 static void putByte(long ptr, int index, byte data) { 94 putByte(ptr+index, data); 95 } 96 /** 97 * Converts length bytes of data pointed by <code>data</code> into byte array 98 * Returns null if data is zero 99 * @param data native pointer to native memory 100 * @param length size in bytes of native memory 101 */ toBytes(long data, int length)102 static byte[] toBytes(long data, int length) { 103 if (data == 0) { 104 return null; 105 } 106 byte[] res = new byte[length]; 107 for (int i = 0; i < length; i++, data++) { 108 res[i] = getByte(data); 109 } 110 return res; 111 } 112 /** 113 * Stores byte array into native memory and returns pointer to this memory 114 * Returns 0 if bytes is null 115 */ toData(byte[] bytes)116 static long toData(byte[] bytes) { 117 if (bytes == null) { 118 return 0; 119 } 120 long res = XlibWrapper.unsafe.allocateMemory(bytes.length); 121 for (int i = 0; i < bytes.length; i++) { 122 putByte(res+i, bytes[i]); 123 } 124 return res; 125 } 126 127 /** 128 * Access to C unsigned byte data(one byte) 129 */ getUByteSize()130 static int getUByteSize() { return 1; } getUByte(long ptr)131 static short getUByte(long ptr) { return (short)(0xFF & unsafe.getByte(ptr)); } 132 getUByte(long ptr, int index)133 static short getUByte(long ptr, int index) { 134 return getUByte(ptr+index); 135 } 136 137 /** 138 * Stores to C unsigned byte data(one byte) 139 */ putUByte(long ptr, short data)140 static void putUByte(long ptr, short data) { unsafe.putByte(ptr, (byte)data); } 141 putUByte(long ptr, int index, short data)142 static void putUByte(long ptr, int index, short data) { 143 putUByte(ptr+index, data); 144 } 145 146 /** 147 * Converts length usnigned bytes of data pointed by <code>data</code> into 148 * short array 149 * Returns null if data is zero 150 * @param data native pointer to native memory 151 * @param length size in bytes of native memory 152 */ toUBytes(long data, int length)153 static short[] toUBytes(long data, int length) { 154 if (data == 0) { 155 return null; 156 } 157 short[] res = new short[length]; 158 for (int i = 0; i < length; i++, data++) { 159 res[i] = getUByte(data); 160 } 161 return res; 162 } 163 /** 164 * Stores short array as unsigned bytes into native memory and returns pointer 165 * to this memory 166 * Returns 0 if bytes is null 167 */ toUData(short[] bytes)168 static long toUData(short[] bytes) { 169 if (bytes == null) { 170 return 0; 171 } 172 long res = XlibWrapper.unsafe.allocateMemory(bytes.length); 173 for (int i = 0; i < bytes.length; i++) { 174 putUByte(res+i, bytes[i]); 175 } 176 return res; 177 } 178 179 /** 180 * Access to C short data(two bytes) 181 */ getShortSize()182 static int getShortSize() { return 2; } getShort(long ptr)183 static short getShort(long ptr) { return unsafe.getShort(ptr); } 184 /** 185 * Stores to C short data(two bytes) 186 */ putShort(long ptr, short data)187 static void putShort(long ptr, short data) { unsafe.putShort(ptr, data); } putShort(long ptr, int index, short data)188 static void putShort(long ptr, int index, short data) { 189 putShort(ptr + index*getShortSize(), data); 190 } toData(short[] shorts)191 static long toData(short[] shorts) { 192 if (shorts == null) { 193 return 0; 194 } 195 long res = XlibWrapper.unsafe.allocateMemory(shorts.length*getShortSize()); 196 for (int i = 0; i < shorts.length; i++) { 197 putShort(res, i, shorts[i]); 198 } 199 return res; 200 } 201 202 /** 203 * Access to C unsigned short data(two bytes) 204 */ getUShortSize()205 static int getUShortSize() { return 2; } 206 getUShort(long ptr)207 static int getUShort(long ptr) { return 0xFFFF & unsafe.getShort(ptr); } 208 /** 209 * Stores to C unsigned short data(two bytes) 210 */ putUShort(long ptr, int data)211 static void putUShort(long ptr, int data) { unsafe.putShort(ptr, (short)data); } putUShort(long ptr, int index, int data)212 static void putUShort(long ptr, int index, int data) { 213 putUShort(ptr + index*getShortSize(), data); 214 } 215 216 /** 217 * Stores int array as unsigned shorts into native memory and returns pointer 218 * to this memory 219 * Returns 0 if bytes is null 220 */ toUData(int[] shorts)221 static long toUData(int[] shorts) { 222 if (shorts == null) { 223 return 0; 224 } 225 long res = XlibWrapper.unsafe.allocateMemory(shorts.length*getShortSize()); 226 for (int i = 0; i < shorts.length; i++) { 227 putUShort(res, i, shorts[i]); 228 } 229 return res; 230 } 231 232 /** 233 * Access to C int data(four bytes) 234 */ getIntSize()235 static int getIntSize() { return 4; } getInt(long ptr)236 static int getInt(long ptr) { return unsafe.getInt(ptr); } getInt(long ptr, int index)237 static int getInt(long ptr, int index) { return getInt(ptr +getIntSize()*index); } 238 /** 239 * Stores to C int data(four bytes) 240 */ putInt(long ptr, int data)241 static void putInt(long ptr, int data) { unsafe.putInt(ptr, data); } putInt(long ptr, int index, int data)242 static void putInt(long ptr, int index, int data) { 243 putInt(ptr + index*getIntSize(), data); 244 } toData(int[] ints)245 static long toData(int[] ints) { 246 if (ints == null) { 247 return 0; 248 } 249 long res = XlibWrapper.unsafe.allocateMemory(ints.length*getIntSize()); 250 for (int i = 0; i < ints.length; i++) { 251 putInt(res, i, ints[i]); 252 } 253 return res; 254 } 255 256 /** 257 * Access to C unsigned int data(four bytes) 258 */ getUIntSize()259 static int getUIntSize() { return 4; } getUInt(long ptr)260 static long getUInt(long ptr) { return 0xFFFFFFFFL & unsafe.getInt(ptr); } getUInt(long ptr, int index)261 static long getUInt(long ptr, int index) { return getUInt(ptr +getIntSize()*index); } 262 /** 263 * Stores to C unsigned int data(four bytes) 264 */ putUInt(long ptr, long data)265 static void putUInt(long ptr, long data) { unsafe.putInt(ptr, (int)data); } putUInt(long ptr, int index, long data)266 static void putUInt(long ptr, int index, long data) { 267 putUInt(ptr + index*getIntSize(), data); 268 } 269 270 /** 271 * Stores long array as unsigned intss into native memory and returns pointer 272 * to this memory 273 * Returns 0 if bytes is null 274 */ toUData(long[] ints)275 static long toUData(long[] ints) { 276 if (ints == null) { 277 return 0; 278 } 279 long res = XlibWrapper.unsafe.allocateMemory(ints.length*getIntSize()); 280 for (int i = 0; i < ints.length; i++) { 281 putUInt(res, i, ints[i]); 282 } 283 return res; 284 } 285 286 /** 287 * Access to C long data(size depends on platform) 288 */ getLongSize()289 static int getLongSize() { 290 return longSize; 291 } getLong(long ptr)292 static long getLong(long ptr) { 293 if (XlibWrapper.dataModel == 32) { 294 return unsafe.getInt(ptr); 295 } else { 296 return unsafe.getLong(ptr); 297 } 298 } 299 /** 300 * Stores to C long data(four bytes) 301 * Note: <code>data</code> has <code>long</code> type 302 * to be able to keep 64-bit C <code>long</code> data 303 */ putLong(long ptr, long data)304 static void putLong(long ptr, long data) { 305 if (XlibWrapper.dataModel == 32) { 306 unsafe.putInt(ptr, (int)data); 307 } else { 308 unsafe.putLong(ptr, data); 309 } 310 } 311 putLong(long ptr, int index, long data)312 static void putLong(long ptr, int index, long data) { 313 putLong(ptr+index*getLongSize(), data); 314 } 315 316 /** 317 * Returns index's element of the array of native long pointed by ptr 318 */ getLong(long ptr, int index)319 static long getLong(long ptr, int index) { 320 return getLong(ptr + index*getLongSize()); 321 } 322 /** 323 * Stores Java long[] array into memory. Memory location is treated as array 324 * of native <code>long</code>s 325 */ put(long ptr, long[] arr)326 static void put(long ptr, long[] arr) { 327 for (int i = 0; i < arr.length; i ++, ptr += getLongSize()) { 328 putLong(ptr, arr[i]); 329 } 330 } 331 332 /** 333 * Stores Java Vector of Longs into memory. Memory location is treated as array 334 * of native <code>long</code>s 335 */ putLong(long ptr, Vector arr)336 static void putLong(long ptr, Vector arr) { 337 for (int i = 0; i < arr.size(); i ++, ptr += getLongSize()) { 338 putLong(ptr, ((Long)arr.elementAt(i)).longValue()); 339 } 340 } 341 342 /** 343 * Stores Java Vector of Longs into memory. Memory location is treated as array 344 * of native <code>long</code>s. Array is stored in reverse order 345 */ putLongReverse(long ptr, Vector arr)346 static void putLongReverse(long ptr, Vector arr) { 347 for (int i = arr.size()-1; i >= 0; i--, ptr += getLongSize()) { 348 putLong(ptr, ((Long)arr.elementAt(i)).longValue()); 349 } 350 } 351 /** 352 * Converts length bytes of data pointed by <code>data</code> into byte array 353 * Returns null if data is zero 354 * @param data native pointer to native memory 355 * @param length size in longs(platform dependent) of native memory 356 */ toLongs(long data, int length)357 static long[] toLongs(long data, int length) { 358 if (data == 0) { 359 return null; 360 } 361 long[] res = new long[length]; 362 for (int i = 0; i < length; i++, data += getLongSize()) { 363 res[i] = getLong(data); 364 } 365 return res; 366 } toData(long[] longs)367 static long toData(long[] longs) { 368 if (longs == null) { 369 return 0; 370 } 371 long res = XlibWrapper.unsafe.allocateMemory(longs.length*getLongSize()); 372 for (int i = 0; i < longs.length; i++) { 373 putLong(res, i, longs[i]); 374 } 375 return res; 376 } 377 378 379 /** 380 * Access to C "unsigned long" date type, which is XID in X 381 */ getULong(long ptr)382 static long getULong(long ptr) { 383 if (XlibWrapper.dataModel == 32) { 384 // Compensate sign-expansion 385 return ((long)unsafe.getInt(ptr)) & 0xFFFFFFFFL; 386 } else { 387 // Can't do anything!!! 388 return unsafe.getLong(ptr); 389 } 390 } 391 putULong(long ptr, long value)392 static void putULong(long ptr, long value) { 393 putLong(ptr, value); 394 } 395 396 /** 397 * Allocates memory for array of native <code>long</code>s of the size <code>length</code> 398 */ allocateLongArray(int length)399 static long allocateLongArray(int length) { 400 return unsafe.allocateMemory(getLongSize() * length); 401 } 402 403 getWindow(long ptr)404 static long getWindow(long ptr) { 405 return getLong(ptr); 406 } getWindow(long ptr, int index)407 static long getWindow(long ptr, int index) { 408 return getLong(ptr + getWindowSize()*index); 409 } 410 putWindow(long ptr, long window)411 static void putWindow(long ptr, long window) { 412 putLong(ptr, window); 413 } 414 putWindow(long ptr, int index, long window)415 static void putWindow(long ptr, int index, long window) { 416 putLong(ptr, index, window); 417 } 418 419 /** 420 * Set of function to return sizes of C data of the appropriate 421 * type. 422 */ getWindowSize()423 static int getWindowSize() { 424 return getLongSize(); 425 } 426 427 428 /** 429 * Set of function to access CARD32 type. All data which types are derived 430 * from CARD32 should be accessed using this accessors. 431 * These types are: XID(Window, Drawable, Font, Pixmap, Cursor, Colormap, GContext, KeySym), 432 * Atom, Mask, VisualID, Time 433 */ getCard32(long ptr)434 static long getCard32(long ptr) { 435 return getLong(ptr); 436 } putCard32(long ptr, long value)437 static void putCard32(long ptr, long value) { 438 putLong(ptr, value); 439 } getCard32(long ptr, int index)440 static long getCard32(long ptr, int index) { 441 return getLong(ptr, index); 442 } putCard32(long ptr, int index, long value)443 static void putCard32(long ptr, int index, long value) { 444 putLong(ptr, index, value); 445 } getCard32Size()446 static int getCard32Size() { 447 return getLongSize(); 448 } card32ToArray(long ptr, int length)449 static long[] card32ToArray(long ptr, int length) { 450 return toLongs(ptr, length); 451 } card32ToData(long[] arr)452 static long card32ToData(long[] arr) { 453 return toData(arr); 454 } 455 } 456