From 505f0d27d20be97d43e049222cad0ad81582b314 Mon Sep 17 00:00:00 2001 From: Lyor Goldstein Date: Sun, 6 Dec 2015 15:10:47 +0200 Subject: [PATCH] Initial code --- CHANGES.md | 1 + .../src/com/sun/jna/platform/unix/LibC.java | 25 +++ .../com/sun/jna/platform/unix/LibCAPI.java | 76 +++++++++ .../src/com/sun/jna/platform/unix/Reboot.java | 43 ++++++ .../com/sun/jna/platform/unix/Resource.java | 101 ++++++++++++ .../src/com/sun/jna/platform/unix/X11.java | 146 +++++++++++++----- .../unix/AbstractUnixTestSupport.java | 42 +++++ .../com/sun/jna/platform/unix/LibCTest.java | 51 ++++++ .../com/sun/jna/platform/unix/X11Test.java | 6 +- 9 files changed, 447 insertions(+), 44 deletions(-) create mode 100644 contrib/platform/src/com/sun/jna/platform/unix/LibC.java create mode 100644 contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java create mode 100644 contrib/platform/src/com/sun/jna/platform/unix/Reboot.java create mode 100644 contrib/platform/src/com/sun/jna/platform/unix/Resource.java create mode 100644 contrib/platform/test/com/sun/jna/platform/unix/AbstractUnixTestSupport.java create mode 100644 contrib/platform/test/com/sun/jna/platform/unix/LibCTest.java diff --git a/CHANGES.md b/CHANGES.md index c03ee34e51..44b68bc39a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -23,6 +23,7 @@ Features * [#548](https://github.com/java-native-access/jna/pull/548): Return 64-bit unsigned integer from `com.sun.jna.platform.win32.WinBase.FILETIME` - [@dbwiddis](https://github.com/dbwiddis). * [#524](https://github.com/java-native-access/jna/pull/524): Added IShellFolder interface plus necessary utility functions to Windows platform, and a sample for enumerating objects in My Computer - [@lwahonen](https://github.com/lwahonen). * [#484](https://github.com/twall/jna/pull/484): Added `XFetchName` to `X11` interface - [@pinaf](https://github.com/pinaf). +* [#554](https://github.com/java-native-access/jna/pull/554): Initial code for a few Unix 'libc' API(s) [@lgoldstein](https://github.com/lgoldstein) Bug Fixes --------- diff --git a/contrib/platform/src/com/sun/jna/platform/unix/LibC.java b/contrib/platform/src/com/sun/jna/platform/unix/LibC.java new file mode 100644 index 0000000000..0f473fb715 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/unix/LibC.java @@ -0,0 +1,25 @@ +/* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.unix; + +import com.sun.jna.Library; +import com.sun.jna.Native; + +/** + * libc API + * @author Lyor Goldstein + */ +public interface LibC extends LibCAPI, Library { + String NAME = "c"; + LibC INSTANCE = (LibC) Native.loadLibrary(NAME, LibC.class); +} diff --git a/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java b/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java new file mode 100644 index 0000000000..9418abacb4 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/unix/LibCAPI.java @@ -0,0 +1,76 @@ +/* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.unix; + +/** + * Note: we are using this "intermediate" API in order to allow + * Linux-like O/S-es to implement the same API, but maybe using a different + * library name + * @author Lyor Goldstein + */ +public interface LibCAPI extends Reboot, Resource { + // see man(2) get/set uid/gid + int getuid(); + int geteuid(); + int getgid(); + int getegid(); + + int setuid(int uid); + int seteuid(int uid); + int setgid(int gid); + int setegid(int gid); + + // see man(2) get/set hostname + int HOST_NAME_MAX = 255; // not including the '\0' + int gethostname(char[] name, int len); + int sethostname(char[] name, int len); + + // see man(2) get/set domainname + int getdomainname(char[] name, int len); + int setdomainname(char[] name, int len); + + /** + * @param name Environment variable name + * @return Returns the value in the environment, or {@code null} if there + * is no match for the name + * @see getenv(3) + */ + String getenv(String name); + + /** + * Update or add a variable in the environment of the calling process. + * @param name Environment variable name + * @param value Required value + * @param overwrite If the environment variable already exists and the + * value of {@code overwrite} is non-zero, the function shall return + * success and the environment shall be updated. If the environment + * variable already exists and the value of {@code overwrite} is zero, the + * function shall return success and the environment shall remain unchanged. + * @return Upon successful completion, zero shall be returned. Otherwise, + * -1 shall be returned, {@code errno} set to indicate the error, and the + * environment shall be unchanged + * @see getenv(3) + */ + int setenv(String name, String value, int overwrite); + + /** + * @param name Environment variable name - If the named variable does not + * exist in the current environment, the environment shall be unchanged + * and the function is considered to have completed successfully. + * @return Upon successful completion, zero shall be returned. Otherwise, + * -1 shall be returned, {@code errno} set to indicate the error, and the + * environment shall be unchanged + * @see getenv(3) + */ + int unsetenv(String name); +} diff --git a/contrib/platform/src/com/sun/jna/platform/unix/Reboot.java b/contrib/platform/src/com/sun/jna/platform/unix/Reboot.java new file mode 100644 index 0000000000..135104b476 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/unix/Reboot.java @@ -0,0 +1,43 @@ +/* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.unix; + +/** + * Contains definitions related to the {@code reboot} API + * @author Lyor Goldstein + */ +public interface Reboot { + /** Perform a hard reset now. */ + int RB_AUTOBOOT = 0x01234567; + /* Halt the system. */ + int RB_HALT_SYSTEM = 0xcdef0123; + /** Enable reboot using Ctrl-Alt-Delete keystroke. */ + int RB_ENABLE_CAD = 0x89abcdef; + /** Disable reboot using Ctrl-Alt-Delete keystroke. */ + int RB_DISABLE_CAD = 0; + /** Stop system and switch power off if possible. */ + int RB_POWER_OFF = 0x4321fedc; + /** Suspend system using software suspend. */ + int RB_SW_SUSPEND = 0xd000fce2; + /** Reboot system into new kernel. */ + int RB_KEXEC = 0x45584543; + + /** + * Stops/Reboots the machine + * @param cmd The command + * @return If successful, this call never returns. Otherwise, a -1 + * is returned and an error is returned in the global variable {@code errno}. + * @see man 2 reboot + */ + int reboot(int cmd); +} diff --git a/contrib/platform/src/com/sun/jna/platform/unix/Resource.java b/contrib/platform/src/com/sun/jna/platform/unix/Resource.java new file mode 100644 index 0000000000..37673bc4a7 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/unix/Resource.java @@ -0,0 +1,101 @@ +/* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.unix; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Structure; + +/** + * Definitions related to {@code getrlimit}/{@code setrlimit} + * @author Lyor Goldstein + */ +public interface Resource { + /** Per-process CPU limit, in seconds. */ + int RLIMIT_CPU = 0; + + /** Largest file that can be created, in bytes. */ + int RLIMIT_FSIZE = 1; + + /** Maximum size of data segment, in bytes. */ + int RLIMIT_DATA = 2; + + /** Maximum size of stack segment, in bytes. */ + int RLIMIT_STACK = 3; + + /** Largest core file that can be created, in bytes. */ + int RLIMIT_CORE = 4; + + /** + * Largest resident set size, in bytes. This affects swapping; processes + * that are exceeding their resident set size will be more likely to have + * physical memory taken from them. + */ + int RLIMIT_RSS = 5; + + /** Number of open files. */ + int RLIMIT_NOFILE = 7; + + /** Address space limit. */ + int RLIMIT_AS = 9; + + /** Number of processes. */ + int RLIMIT_NPROC = 6; + + /** Locked-in-memory address space. */ + int RLIMIT_MEMLOCK = 8; + + /** Maximum number of file locks. */ + int RLIMIT_LOCKS = 10; + + /** Maximum number of pending signals. */ + int RLIMIT_SIGPENDING = 11; + + /** Maximum bytes in POSIX message queues. */ + int RLIMIT_MSGQUEUE = 12; + + /** + * Maximum nice priority allowed to raise to. Nice levels 19 .. -20 + * correspond to 0 .. 39 values of this resource limit. + */ + int RLIMIT_NICE = 13; + int RLIMIT_RTPRIO = 14; + + /** + * Maximum CPU time in microseconds that a process scheduled under a + * real-time scheduling policy may consume without making a blocking + * system call before being forcibly de-scheduled. + */ + int RLIMIT_RTTIME = 15; + + /** Number of {@code rlimit} values */ + int RLIMIT_NLIMITS = 16; + + public static class Rlimit extends Structure { + /** The current (soft) limit. */ + public long rlim_cur; + + /** The hard limit. */ + public long rlim_max; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "rlim_cur", "rlim_max" }); + } + } + + // see man(2) rlimit + int getrlimit(int resource, Rlimit rlim); + int setrlimit(int resource, Rlimit rlim); +} diff --git a/contrib/platform/src/com/sun/jna/platform/unix/X11.java b/contrib/platform/src/com/sun/jna/platform/unix/X11.java index df12670ae2..3856302dd2 100644 --- a/contrib/platform/src/com/sun/jna/platform/unix/X11.java +++ b/contrib/platform/src/com/sun/jna/platform/unix/X11.java @@ -17,7 +17,6 @@ import com.sun.jna.Callback; import com.sun.jna.FromNativeContext; -import com.sun.jna.IntegerType; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLong; @@ -43,6 +42,7 @@ protected boolean isNone(Object o) { || (o instanceof Number && ((Number)o).longValue() == X11.None); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -60,11 +60,13 @@ protected boolean isNone(Object o) { || (o instanceof Number && ((Number)o).longValue() == X11.None); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; return new XID(((Number)nativeValue).longValue()); } + @Override public String toString() { return "0x" + Long.toHexString(longValue()); } @@ -75,6 +77,7 @@ class Atom extends XID { public Atom() { } public Atom(long id) { super(id); } /** Return constants for predefined Atom values. */ + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { long value = ((Number)nativeValue).longValue(); if (value <= Integer.MAX_VALUE) { @@ -166,6 +169,7 @@ class Colormap extends XID { public static final Colormap None = null; public Colormap() { } public Colormap(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -177,6 +181,7 @@ class Font extends XID { public static final Font None = null; public Font() { } public Font(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -188,6 +193,7 @@ class Cursor extends XID { public static final Cursor None = null; public Cursor() { } public Cursor(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -199,6 +205,7 @@ class KeySym extends XID { public static final KeySym None = null; public KeySym() { } public KeySym(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -210,6 +217,7 @@ class Drawable extends XID { public static final Drawable None = null; public Drawable() { } public Drawable(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -221,6 +229,7 @@ class Window extends Drawable { public static final Window None = null; public Window() { } public Window(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -239,6 +248,7 @@ class Pixmap extends Drawable { public static final Pixmap None = null; public Pixmap() { } public Pixmap(long id) { super(id); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -254,6 +264,7 @@ public VisualID getVisualID() { return new VisualID(getPointer().getNativeLong(Native.POINTER_SIZE).longValue()); throw new IllegalStateException("Attempting to retrieve VisualID from a null Visual"); } + @Override public String toString() { return "Visual: VisualID=0x" + Long.toHexString(getVisualID().longValue()); } @@ -291,8 +302,9 @@ class XRenderDirectFormat extends Structure { public short green, greenMask; public short blue, blueMask; public short alpha, alphaMask; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "red", "redMask", "green", "greenMask", "blue", "blueMask", "alpha", "alphaMask" }); + return Arrays.asList(new String[] { "red", "redMask", "green", "greenMask", "blue", "blueMask", "alpha", "alphaMask" }); } } class PictFormat extends XID { @@ -300,6 +312,7 @@ class PictFormat extends XID { public static final PictFormat None = null; public PictFormat(long value) { super(value); } public PictFormat() { this(0); } + @Override public Object fromNative(Object nativeValue, FromNativeContext context) { if (isNone(nativeValue)) return None; @@ -312,8 +325,9 @@ class XRenderPictFormat extends Structure { public int depth; public XRenderDirectFormat direct; public Colormap colormap; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "id", "type", "depth", "direct", "colormap" }); + return Arrays.asList(new String[] { "id", "type", "depth", "direct", "colormap" }); } } int PictTypeIndexed = 0x0; @@ -363,8 +377,9 @@ interface XTest extends Library { class XInputClassInfoByReference extends Structure implements Structure.ByReference { public byte input_class; public byte event_type_base; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "input_class", "event_type_base" }); + return Arrays.asList(new String[] { "input_class", "event_type_base" }); } } @@ -372,8 +387,9 @@ class XDeviceByReference extends Structure implements Structure.ByReference { public XID device_id; public int num_classes; public XInputClassInfoByReference classes; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "device_id", "num_classes", "classes" }); + return Arrays.asList(new String[] { "device_id", "num_classes", "classes" }); } } @@ -402,8 +418,9 @@ class XWMHints extends Structure { public int icon_x, icon_y; public Pixmap icon_mask; public XID window_group; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "flags", "input", "initial_state", "icon_pixmap", "icon_window", "icon_x", "icon_y", "icon_mask", "window_group" }); + return Arrays.asList(new String[] { "flags", "input", "initial_state", "icon_pixmap", "icon_window", "icon_x", "icon_y", "icon_mask", "window_group" }); } } @@ -420,8 +437,9 @@ class XTextProperty extends Structure { public Atom encoding; public int format; public NativeLong nitems; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "value", "encoding", "format", "nitems" }); + return Arrays.asList(new String[] { "value", "encoding", "format", "nitems" }); } } @@ -451,12 +469,14 @@ class XSizeHints extends Structure { public static class Aspect extends Structure { public int x; // numerator public int y; // denominator + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "x", "y" }); } } public Aspect min_aspect, max_aspect; public int base_width, base_height; public int win_gravity; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "flags", "x", "y", "width", "height", "min_width", "min_height", "max_width", "max_height", "width_inc", "height_inc", "min_aspect", "max_aspect", "base_width", "base_height", "win_gravity" }); } } @@ -512,8 +532,9 @@ class XWindowAttributes extends Structure { public NativeLong do_not_propagate_mask; public boolean override_redirect; public Screen screen; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "x", "y", "width", "height", "border_width", "depth", "visual", "root", "c_class", "bit_gravity", "win_gravity", "backing_store", "backing_planes", "backing_pixel", "save_under", "colormap", "map_installed", "map_state", "all_event_masks", "your_event_mask", "do_not_propagate_mask", "override_redirect", "screen" }); + return Arrays.asList(new String[] { "x", "y", "width", "height", "border_width", "depth", "visual", "root", "c_class", "bit_gravity", "win_gravity", "backing_store", "backing_planes", "backing_pixel", "save_under", "colormap", "map_installed", "map_state", "all_event_masks", "your_event_mask", "do_not_propagate_mask", "override_redirect", "screen" }); } } @@ -552,8 +573,9 @@ class XSetWindowAttributes extends Structure { public boolean override_redirect; public Colormap colormap; public Cursor cursor; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "background_pixmap", "background_pixel", "border_pixmap", "border_pixel", "bit_gravity", "win_gravity", "backing_store", "backing_planes", "backing_pixel", "save_under", "event_mask", "do_not_propagate_mask", "override_redirect", "colormap", "cursor" }); + return Arrays.asList(new String[] { "background_pixmap", "background_pixel", "border_pixmap", "border_pixel", "bit_gravity", "win_gravity", "backing_store", "backing_planes", "backing_pixel", "save_under", "event_mask", "do_not_propagate_mask", "override_redirect", "colormap", "cursor" }); } } @@ -597,12 +619,14 @@ class XVisualInfo extends Structure { public NativeLong blue_mask; public int colormap_size; public int bits_per_rgb; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "visual", "visualid", "screen", "depth", "c_class", "red_mask", "green_mask", "blue_mask", "colormap_size", "bits_per_rgb" }); + return Arrays.asList(new String[] { "visual", "visualid", "screen", "depth", "c_class", "red_mask", "green_mask", "blue_mask", "colormap_size", "bits_per_rgb" }); } } class XPoint extends Structure { public short x, y; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "x", "y" }); } @@ -615,6 +639,7 @@ public XPoint(short x, short y) { class XRectangle extends Structure { public short x, y; public short width, height; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "x", "y", "width", "height" }); } @@ -761,7 +786,7 @@ Pixmap XCreateBitmapFromData(Display display, Window window, Pointer data, * without I/O if there are events already in the queue. XEventsQueued * with mode QueuedAfterFlush is identical in behavior to * XPending. XEventsQueued with mode QueuedAlready is identical to the - * XQLength function. + * XQLength function. * @param display target Display * @param mode QueuedAlready, QueuedAfterFlush, or QueuedAfterReading * @return status @@ -806,8 +831,9 @@ class XGCValues extends Structure { public Pixmap clip_mask; /* bitmap clipping; other calls for rects */ public int dash_offset; /* patterned/dashed line information */ public byte dashes; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "function", "plane_mask", "foreground", "background", "line_width", "line_style", "cap_style", "join_style", "fill_style", "fill_rule", "arc_mode", "tile", "stipple", "ts_x_origin", "ts_y_origin", "font", "subwindow_mode", "graphics_exposures", "clip_x_origin", "clip_y_origin", "clip_mask", "dash_offset", "dashes" }); + return Arrays.asList(new String[] { "function", "plane_mask", "foreground", "background", "line_width", "line_style", "cap_style", "join_style", "fill_style", "fill_rule", "arc_mode", "tile", "stipple", "ts_x_origin", "ts_y_origin", "font", "subwindow_mode", "graphics_exposures", "clip_x_origin", "clip_y_origin", "clip_mask", "dash_offset", "dashes" }); } } GC XCreateGC(Display display, Drawable drawable, NativeLong mask, XGCValues values); @@ -840,11 +866,11 @@ boolean XQueryPointer(Display display, Window window, int XGetWindowAttributes(Display display, Window window, XWindowAttributes attributes); int XChangeWindowAttributes(Display display, Window window, NativeLong valuemask, XSetWindowAttributes attributes); // Status XGetGeometry(Display *display, Drawable d, Window *root_return, int *x_return, int *y_return, unsigned int *width_return, - // unsigned int *height_return, unsigned int *border_width_return, unsigned int *depth_return); + // unsigned int *height_return, unsigned int *border_width_return, unsigned int *depth_return); int XGetGeometry(Display display, Drawable d, WindowByReference w, IntByReference x, IntByReference y, IntByReference width, IntByReference heigth, IntByReference border_width, IntByReference depth); // Bool XTranslateCoordinates(Display *display, Window src_w, dest_w, int src_x, int src_y, - // int *dest_x_return, int *dest_y_return, Window *child_return); + // int *dest_x_return, int *dest_y_return, Window *child_return); boolean XTranslateCoordinates(Display display, Window src_w, Window dest_w, int src_x, int src_y, IntByReference dest_x_return, IntByReference dest_y_return, WindowByReference child_return); @@ -1434,8 +1460,9 @@ public static class XAnyEvent extends Structure { public int send_event; // true if this came from a SendEvent request public Display display; // Display the event was read from public Window window; // window on which event was requested in event mask + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window" }); } } @@ -1453,8 +1480,9 @@ class XKeyEvent extends Structure { public int state; // key or button mask public int keycode; // detail public int same_screen; // same screen flag + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "state", "keycode", "same_screen" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "state", "keycode", "same_screen" }); } } @@ -1472,8 +1500,9 @@ class XButtonEvent extends Structure { public int state; // key or button mask public int button; // detail public int same_screen; // same screen flag + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "state", "button", "same_screen" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "state", "button", "same_screen" }); } } @@ -1492,8 +1521,9 @@ public static class XClientMessageEvent extends Structure { public Atom message_type; public int format; public Data data; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "message_type", "format", "data" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "message_type", "format", "data" }); } public static class Data extends Union { @@ -1517,8 +1547,9 @@ class XMotionEvent extends Structure { public int state; // key or button mask public byte is_hint; // detail public int same_screen; // same screen flag + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "state", "is_hint", "same_screen" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "state", "is_hint", "same_screen" }); } } @@ -1545,8 +1576,9 @@ class XCrossingEvent extends Structure { public int same_screen; // same screen flag public int focus; // boolean focus public int state; // key or button mask + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "mode", "detail", "same_screen", "focus", "state" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "root", "subwindow", "time", "x", "y", "x_root", "y_root", "mode", "detail", "same_screen", "focus", "state" }); } } @@ -1569,8 +1601,9 @@ class XFocusChangeEvent extends Structure { * NotifyNonlinear,NotifyNonlinearVirtual, NotifyPointer, * NotifyPointerRoot, NotifyDetailNone */ + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "mode", "detail" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "mode", "detail" }); } } @@ -1589,8 +1622,9 @@ class XExposeEvent extends Structure { public int x, y; public int width, height; public int count; // if non-zero, at least this many more + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "x", "y", "width", "height", "count" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "x", "y", "width", "height", "count" }); } } @@ -1605,8 +1639,9 @@ class XGraphicsExposeEvent extends Structure { public int count; // if non-zero, at least this many more public int major_code; // core is CopyArea or CopyPlane public int minor_code; // not defined in the core + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "drawable", "x", "y", "width", "height", "count", "major_code", "minor_code" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "drawable", "x", "y", "width", "height", "count", "major_code", "minor_code" }); } } @@ -1618,8 +1653,9 @@ class XNoExposeEvent extends Structure { public Drawable drawable; public int major_code; // core is CopyArea or CopyPlane public int minor_code; // not defined in the core + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "drawable", "major_code", "minor_code" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "drawable", "major_code", "minor_code" }); } } @@ -1630,8 +1666,9 @@ class XVisibilityEvent extends Structure { public Display display; // Display the event was read from public Window window; public int state; // Visibility state + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "state" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "state" }); } } @@ -1646,8 +1683,9 @@ class XCreateWindowEvent extends Structure { public int width, height; // size of window public int border_width; // border width public int override_redirect; // creation should be overridden + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "parent", "window", "x", "y", "width", "height", "border_width", "override_redirect" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "parent", "window", "x", "y", "width", "height", "border_width", "override_redirect" }); } } @@ -1658,6 +1696,7 @@ class XDestroyWindowEvent extends Structure { public Display display; // Display the event was read from public Window event; public Window window; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window" }); } } @@ -1670,6 +1709,7 @@ class XUnmapEvent extends Structure { public Window event; public Window window; public int from_configure; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "from_configure" }); } @@ -1683,6 +1723,7 @@ class XMapEvent extends Structure { public Window event; public Window window; public int override_redirect; // boolean, is override set... + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "override_redirect" }); } @@ -1695,6 +1736,7 @@ class XMapRequestEvent extends Structure { public Display display; // Display the event was read from public Window parent; public Window window; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "parent", "window" }); } @@ -1710,6 +1752,7 @@ class XReparentEvent extends Structure { public Window parent; public int x, y; public int override_redirect; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "parent", "x", "y", "override_redirect" }); } @@ -1727,6 +1770,7 @@ class XConfigureEvent extends Structure { public int border_width; public Window above; public int override_redirect; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "x", "y", "width", "height", "border_width", "above", "override_redirect" }); } @@ -1740,6 +1784,7 @@ class XGravityEvent extends Structure { public Window event; public Window window; public int x, y; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "x", "y" }); } @@ -1752,8 +1797,9 @@ class XResizeRequestEvent extends Structure { public Display display; // Display the event was read from public Window window; public int width, height; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "width", "height" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "width", "height" }); } } @@ -1770,6 +1816,7 @@ class XConfigureRequestEvent extends Structure { public Window above; public int detail; // Above, Below, TopIf, BottomIf, Opposite public NativeLong value_mask; + @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "parent", "window", "x", "y", "width", "height", "border_width", "above", "detail", "value_mask" }); } @@ -1783,8 +1830,9 @@ class XCirculateEvent extends Structure { public Window event; public Window window; public int place; // PlaceOnTop, PlaceOnBottom + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "place" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "event", "window", "place" }); } } @@ -1796,8 +1844,9 @@ class XCirculateRequestEvent extends Structure { public Window parent; public Window window; public int place; // PlaceOnTop, PlaceOnBottom + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "parent", "window", "place" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "parent", "window", "place" }); } } @@ -1810,8 +1859,9 @@ class XPropertyEvent extends Structure { public Atom atom; public NativeLong time; public int state; // NewValue, Deleted + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "atom", "time", "state" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "atom", "time", "state" }); } } @@ -1823,8 +1873,9 @@ class XSelectionClearEvent extends Structure { public Window window; public Atom selection; public NativeLong time; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "selection", "time" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "selection", "time" }); } } @@ -1839,8 +1890,9 @@ class XSelectionRequestEvent extends Structure { public Atom target; public Atom property; public NativeLong time; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "owner", "requestor", "selection", "target", "property", "time" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "owner", "requestor", "selection", "target", "property", "time" }); } } @@ -1854,8 +1906,9 @@ class XSelectionEvent extends Structure { public Atom target; public Atom property; // ATOM or None public NativeLong time; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "requestor", "selection", "target", "property", "time" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "requestor", "selection", "target", "property", "time" }); } } @@ -1868,8 +1921,9 @@ class XColormapEvent extends Structure { public Colormap colormap; // COLORMAP or None public int c_new; // C++ public int state; // ColormapInstalled, ColormapUninstalled + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "colormap", "c_new", "state" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "colormap", "c_new", "state" }); } } @@ -1882,8 +1936,9 @@ class XMappingEvent extends Structure { public int request; // one of MappingModifier, MappingKeyboard, MappingPointer public int first_keycode; // first keycode public int count; // defines range of change w. first_keycode*/ + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "request", "first_keycode", "count" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "request", "first_keycode", "count" }); } } @@ -1895,8 +1950,9 @@ class XErrorEvent extends Structure { public byte request_code; // Major op-code of failed request public byte minor_code; // Minor op-code of failed request public XID resourceid; // resource id + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "display", "serial", "error_code", "request_code", "minor_code", "resourceid" }); + return Arrays.asList(new String[] { "type", "display", "serial", "error_code", "request_code", "minor_code", "resourceid" }); } } @@ -1908,8 +1964,9 @@ class XKeymapEvent extends Structure { public Display display; // Display the event was read from public Window window; public byte key_vector[] = new byte[32]; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "key_vector" }); + return Arrays.asList(new String[] { "type", "serial", "send_event", "display", "window", "key_vector" }); } } @@ -1990,7 +2047,7 @@ public interface XErrorHandler extends Callback { /* * KeySyms, Keycodes, Keymaps */ - + String XKeysymToString(KeySym keysym); KeySym XStringToKeysym(String string); byte XKeysymToKeycode(Display display, KeySym keysym); @@ -2217,11 +2274,12 @@ public interface XErrorHandler extends Callback { class XModifierKeymapRef extends Structure implements Structure.ByReference{ public int max_keypermod; /* The server's max # of keys per modifier */ public Pointer modifiermap; /* An 8 by max_keypermod array of modifiers */ + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "max_keypermod", "modifiermap" }); + return Arrays.asList(new String[] { "max_keypermod", "modifiermap" }); } } - + class XKeyboardControlRef extends Structure implements Structure.ByReference { /** Volume for key clicks between 0 (off) and 100 (loud) inclusive, if possible. A setting of -1 restores the default. */ public int key_click_percent; @@ -2240,10 +2298,12 @@ class XKeyboardControlRef extends Structure implements Structure.ByReference { /** AutoRepeatModeOff, AutoRepeatModeOn, AutoRepeatModeDefault. */ public int auto_repeat_mode; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "key_click_percent", "bell_percent", "bell_pitch", "bell_duration", "led", "led_mode", "key", "auto_repeat_mode" }); + return Arrays.asList(new String[] { "key_click_percent", "bell_percent", "bell_pitch", "bell_duration", "led", "led_mode", "key", "auto_repeat_mode" }); } + @Override public String toString() { return "XKeyboardControlByReference{" + "key_click_percent=" + key_click_percent + @@ -2274,10 +2334,12 @@ class XKeyboardStateRef extends Structure implements Structure.ByReference { /** Bit vector. Each bit set to 1 indicates that auto-repeat is enabled for the corresponding key. 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. */ public byte auto_repeats[] = new byte[32]; + @Override protected List getFieldOrder() { - return Arrays.asList(new String[] { "key_click_percent", "bell_percent", "bell_pitch", "bell_duration", "led_mask", "global_auto_repeat", "auto_repeats" }); + return Arrays.asList(new String[] { "key_click_percent", "bell_percent", "bell_pitch", "bell_duration", "led_mask", "global_auto_repeat", "auto_repeats" }); } + @Override public String toString() { return "XKeyboardStateByReference{" + "key_click_percent=" + key_click_percent + diff --git a/contrib/platform/test/com/sun/jna/platform/unix/AbstractUnixTestSupport.java b/contrib/platform/test/com/sun/jna/platform/unix/AbstractUnixTestSupport.java new file mode 100644 index 0000000000..9574301293 --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/unix/AbstractUnixTestSupport.java @@ -0,0 +1,42 @@ +/* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.unix; + +import com.sun.jna.Native; +import com.sun.jna.platform.AbstractPlatformTestSupport; + +/** + * @author Lyor Goldstein + */ +public abstract class AbstractUnixTestSupport extends AbstractPlatformTestSupport { + protected AbstractUnixTestSupport() { + super(); + } + + public static int getErrno() { + return Native.getLastError(); + } + + /** + * Checks if result is zero. If not, then throws an assertion error with the {@code errno} value + * + * @param message The failure message to prepend if necessary + * @param result The syscall result code + */ + public static void assertSuccessResult(String message, int result) { + if (result != 0) { + int errno = getErrno(); + fail(message + ": result=" + result + ", errno=" + errno); + } + } +} diff --git a/contrib/platform/test/com/sun/jna/platform/unix/LibCTest.java b/contrib/platform/test/com/sun/jna/platform/unix/LibCTest.java new file mode 100644 index 0000000000..6a7539a6aa --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/unix/LibCTest.java @@ -0,0 +1,51 @@ +/* Copyright (c) 2015 Goldstein Lyor, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.unix; + +import java.sql.Date; +import java.util.Map; + +import org.junit.Test; + +/** + * @author Lyor Goldstein + */ +public class LibCTest extends AbstractUnixTestSupport { + public LibCTest() { + super(); + } + + @Test + public void testGetenv() { + Map env = System.getenv(); + for (Map.Entry ee : env.entrySet()) { + String name = ee.getKey(); + String expected = ee.getValue(); + String actual = LibC.INSTANCE.getenv(name); + assertEquals(name, expected, actual); + } + } + + @Test + public void testSetenv() { + String name = getCurrentTestName(); + try { + String expected = new Date(System.currentTimeMillis()).toString(); + assertSuccessResult("setenv", LibC.INSTANCE.setenv(name, expected, 1)); + assertEquals("Mismatched values", expected, LibC.INSTANCE.getenv(name)); + assertSuccessResult("unsetenv", LibC.INSTANCE.unsetenv(name)); + } finally { + LibC.INSTANCE.unsetenv(name); + } + } +} diff --git a/contrib/platform/test/com/sun/jna/platform/unix/X11Test.java b/contrib/platform/test/com/sun/jna/platform/unix/X11Test.java index 1065144ca8..30d1dc466e 100644 --- a/contrib/platform/test/com/sun/jna/platform/unix/X11Test.java +++ b/contrib/platform/test/com/sun/jna/platform/unix/X11Test.java @@ -13,11 +13,11 @@ package com.sun.jna.platform.unix; import java.awt.GraphicsEnvironment; -import junit.framework.TestCase; -import com.sun.jna.Pointer; import com.sun.jna.ptr.PointerByReference; +import junit.framework.TestCase; + /** * Exercise the {@link X11} class. * @@ -29,6 +29,7 @@ public class X11Test extends TestCase { private X11.Display display = null; private X11.Window root = null; + @Override protected void setUp() { if (!GraphicsEnvironment.isHeadless()) { display = X11.INSTANCE.XOpenDisplay(null); @@ -42,6 +43,7 @@ protected void setUp() { } } + @Override protected void tearDown() { if (display != null) { X11.INSTANCE.XCloseDisplay(display);