From 1d8a329235a2adce4fbbd9b44c3f00354a9e846e Mon Sep 17 00:00:00 2001 From: nathan Date: Fri, 12 Dec 2014 02:19:04 +0100 Subject: [PATCH] Small system tweaks. JNA tweaks. --- Dorkbox-Util/src/dorkbox/util/SwingUtil.java | 128 ++++++++++++++++++ .../src/dorkbox/util/crypto/Crypto.java | 52 +++++-- .../dorkbox/util/jna/linux/AppIndicator.java | 1 - .../src/dorkbox/util/jna/linux/GThread.java | 12 ++ .../src/dorkbox/util/jna/linux/Gtk.java | 14 ++ .../dorkbox/util/jna/linux/GtkSupport.java | 10 +- 6 files changed, 202 insertions(+), 15 deletions(-) create mode 100644 Dorkbox-Util/src/dorkbox/util/SwingUtil.java create mode 100644 Dorkbox-Util/src/dorkbox/util/jna/linux/GThread.java diff --git a/Dorkbox-Util/src/dorkbox/util/SwingUtil.java b/Dorkbox-Util/src/dorkbox/util/SwingUtil.java new file mode 100644 index 0000000..2ce9be4 --- /dev/null +++ b/Dorkbox-Util/src/dorkbox/util/SwingUtil.java @@ -0,0 +1,128 @@ +/* + * Copyright 2014 dorkbox, llc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package dorkbox.util; + +import java.awt.Container; +import java.awt.EventQueue; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.Rectangle; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +import javax.swing.SwingUtilities; + +public class SwingUtil { + public static void showOnSameScreenAsMouseCenter(Container frame) { + Point mouseLocation = MouseInfo.getPointerInfo().getLocation(); + + GraphicsDevice deviceAtMouse = getGraphicsDeviceAt(mouseLocation); + Rectangle bounds = deviceAtMouse.getDefaultConfiguration().getBounds(); + frame.setLocation(bounds.x + bounds.width / 2 - frame.getWidth() / 2, bounds.height / 2 - frame.getHeight() / 2); + } + + public static void showOnSameScreenAsMouse(Container frame) { + Point mouseLocation = MouseInfo.getPointerInfo().getLocation(); + + GraphicsDevice deviceAtMouse = getGraphicsDeviceAt(mouseLocation); + frame.setLocation(deviceAtMouse.getDefaultConfiguration().getBounds().x, frame.getY()); + } + + public static Rectangle getScreenBoundsAt(Point pos) { + GraphicsDevice gd = SwingUtil.getGraphicsDeviceAt(pos); + Rectangle bounds = null; + if (gd != null) { + bounds = gd.getDefaultConfiguration().getBounds(); + } + + return bounds; + } + + public static GraphicsDevice getGraphicsDeviceAt(Point pos) { + GraphicsDevice device; + + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice lstGDs[] = ge.getScreenDevices(); + + ArrayList lstDevices = new ArrayList(lstGDs.length); + + for (GraphicsDevice gd : lstGDs) { + + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + Rectangle screenBounds = gc.getBounds(); + + if (screenBounds.contains(pos)) { + lstDevices.add(gd); + } + } + + if (lstDevices.size() > 0) { + device = lstDevices.get(0); + } else { + device = ge.getDefaultScreenDevice(); + } + + return device; + } + + +// public static Rectangle getSafeScreenBounds(Point pos) { +// Rectangle bounds = getScreenBoundsAt(pos); +// Insets insets = getScreenInsetsAt(pos); +// +// bounds.x += insets.left; +// bounds.y += insets.top; +// bounds.width -= insets.left + insets.right; +// bounds.height -= insets.top + insets.bottom; +// +// return bounds; +// } + +// public static Insets getScreenInsetsAt(Point pos) { +// GraphicsDevice gd = getGraphicsDeviceAt(pos); +// Insets insets = null; +// if (gd != null) { +// insets = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration()); +// } +// +// return insets; +// } + + public static void invokeLater(Runnable runnable) { + if (EventQueue.isDispatchThread()) { + runnable.run(); + } else { + SwingUtilities.invokeLater(runnable); + } + } + + public static void invokeAndWait(Runnable runnable) { + if (EventQueue.isDispatchThread()) { + runnable.run(); + } else { + try { + EventQueue.invokeAndWait(runnable); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} diff --git a/Dorkbox-Util/src/dorkbox/util/crypto/Crypto.java b/Dorkbox-Util/src/dorkbox/util/crypto/Crypto.java index 879a4a9..810d6e0 100644 --- a/Dorkbox-Util/src/dorkbox/util/crypto/Crypto.java +++ b/Dorkbox-Util/src/dorkbox/util/crypto/Crypto.java @@ -67,7 +67,8 @@ import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.math.ec.ECPoint; -import dorkbox.urlHandler.Box; +import dorkbox.util.OS; +import dorkbox.util.bytes.LittleEndian; /** * http://en.wikipedia.org/wiki/NSA_Suite_B @@ -167,15 +168,16 @@ public class Crypto { } } + // CUSTOM_HEADER USE + private static byte[] CUSTOM_HEADER = new byte[] {-54, -98, 98, 120}; /** * Specifically, to return the hash of the ALL files/directories inside the jar, minus the action specified (LGPL) files. */ public static final byte[] hashJarContentsExcludeAction(JarFile jarFile, Digest digest, int action) throws IOException { - String token = Box.repack; - Enumeration jarElements = jarFile.entries(); boolean okToHash = false; + boolean hasAction = false; byte[] buffer = new byte[2048]; int read = 0; digest.reset(); @@ -189,21 +191,49 @@ public class Crypto { continue; } - okToHash = false; - int startIndex = name.lastIndexOf(token); // lastIndexOf, in case there are multiple box files stacked in eachother - if (startIndex > -1) { - String type = name.substring(startIndex + 2); - int parseInt = Integer.parseInt(type); + okToHash = true; + hasAction = false; - if ((parseInt & action) != action) { - okToHash = true; + byte[] extraData = jarEntry.getExtra(); + if (extraData != null && extraData.length > 4) { + for (int i = 0; i < CUSTOM_HEADER.length; i++) { + if (extraData[i] != CUSTOM_HEADER[i]) { + // can hash if we don't have an action assigned (LGPL will ALWAYS have an action assigned) + okToHash = false; + break; + } + } + + // this means we matched our header + int fileAction = 0; + + if (okToHash) { + if (extraData[4] > 0) { + hasAction = true; + // we have an ACTION describing how it was compressed, etc + fileAction = LittleEndian.Int_.fromBytes(new byte[] {extraData[5], extraData[6], extraData[7], extraData[8]}); + } + + if ((fileAction & action) == action) { + okToHash = false; + } } } // skips hashing lgpl files. (technically, whatever our action bitmask is...) + // we want to hash everything BY DEFAULT. we ALSO want to hash the NAME, LOAD ACTION TYPE, and the contents if (okToHash) { - InputStream inputStream = jarFile.getInputStream(jarEntry); + // hash the file name + byte[] bytes = name.getBytes(OS.US_ASCII); + digest.update(bytes, 0, bytes.length); + if (hasAction) { + // hash the action + digest.update(extraData, 5, 4); + } + + // hash the contents + InputStream inputStream = jarFile.getInputStream(jarEntry); while ((read = inputStream.read(buffer)) > 0) { digest.update(buffer, 0, read); } diff --git a/Dorkbox-Util/src/dorkbox/util/jna/linux/AppIndicator.java b/Dorkbox-Util/src/dorkbox/util/jna/linux/AppIndicator.java index c4a06ab..8e5cd0a 100644 --- a/Dorkbox-Util/src/dorkbox/util/jna/linux/AppIndicator.java +++ b/Dorkbox-Util/src/dorkbox/util/jna/linux/AppIndicator.java @@ -17,7 +17,6 @@ import dorkbox.util.jna.linux.Gobject.GObjectStruct; public interface AppIndicator extends Library { public static AppIndicator INSTANCE = (AppIndicator) Native.loadLibrary("appindicator", AppIndicator.class); - public static final int CATEGORY_APPLICATION_STATUS = 0; public static final int CATEGORY_COMMUNICATIONS = 1; public static final int CATEGORY_SYSTEM_SERVICES = 2; diff --git a/Dorkbox-Util/src/dorkbox/util/jna/linux/GThread.java b/Dorkbox-Util/src/dorkbox/util/jna/linux/GThread.java new file mode 100644 index 0000000..f44a2de --- /dev/null +++ b/Dorkbox-Util/src/dorkbox/util/jna/linux/GThread.java @@ -0,0 +1,12 @@ +package dorkbox.util.jna.linux; + + +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.Pointer; + +public interface GThread extends Library { + public static final GThread INSTANCE = (GThread) Native.loadLibrary("gthread-2.0", GThread.class); + + public void g_thread_init(Pointer GThreadFunctions); +} diff --git a/Dorkbox-Util/src/dorkbox/util/jna/linux/Gtk.java b/Dorkbox-Util/src/dorkbox/util/jna/linux/Gtk.java index da1dc98..9bea38c 100644 --- a/Dorkbox-Util/src/dorkbox/util/jna/linux/Gtk.java +++ b/Dorkbox-Util/src/dorkbox/util/jna/linux/Gtk.java @@ -47,7 +47,21 @@ public interface Gtk extends Library { } public void gtk_init(int argc, String[] argv); + + /** + * Runs the main loop until gtk_main_quit() is called. + * You can nest calls to gtk_main(). In that case gtk_main_quit() will make the innermost invocation of the main loop return. + */ public void gtk_main(); + /** + * Makes the innermost invocation of the main loop return when it regains control. + */ + public void gtk_main_quit(); + + public void gdk_threads_init(); + public void gdk_threads_enter(); + public void gdk_threads_leave(); + public Pointer gtk_menu_new(); public Pointer gtk_menu_item_new_with_label(String label); diff --git a/Dorkbox-Util/src/dorkbox/util/jna/linux/GtkSupport.java b/Dorkbox-Util/src/dorkbox/util/jna/linux/GtkSupport.java index 7e666a5..eccc1a5 100644 --- a/Dorkbox-Util/src/dorkbox/util/jna/linux/GtkSupport.java +++ b/Dorkbox-Util/src/dorkbox/util/jna/linux/GtkSupport.java @@ -7,7 +7,7 @@ public class GtkSupport { public static final boolean usesSwtMainLoop; static { - if (Gtk.INSTANCE != null && AppIndicator.INSTANCE != null && Gobject.INSTANCE != null) { + if (Gtk.INSTANCE != null && AppIndicator.INSTANCE != null && Gobject.INSTANCE != null && GThread.INSTANCE != null) { isSupported = true; boolean hasSwt = false; @@ -18,9 +18,13 @@ public class GtkSupport { } } catch (Exception ignore) {} - // swt already init's gtk. + // swt already init's gtk. Maybe this is the wrong way to go about this? if (!hasSwt) { - Gtk.INSTANCE.gtk_init(0, null); + Gtk instance = Gtk.INSTANCE; + instance.gtk_init(0, null); + GThread.INSTANCE.g_thread_init(null); + instance.gdk_threads_init(); + usesSwtMainLoop = false; } else { usesSwtMainLoop = true;