4 * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
7 * GiWoong Kim <giwoong.kim@samsung.com>
8 * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 package org.tizen.emulator.skin.util;
33 import java.lang.reflect.Array;
34 import java.lang.reflect.Field;
35 import java.lang.reflect.InvocationTargetException;
36 import java.lang.reflect.Method;
37 import java.util.List;
38 import java.util.logging.Level;
39 import java.util.logging.Logger;
41 import org.eclipse.swt.graphics.Image;
42 import org.eclipse.swt.graphics.ImageData;
43 import org.eclipse.swt.graphics.Point;
44 import org.eclipse.swt.graphics.Rectangle;
45 import org.eclipse.swt.graphics.Region;
46 import org.eclipse.swt.widgets.MessageBox;
47 import org.eclipse.swt.widgets.Shell;
48 import org.tizen.emulator.skin.comm.ICommunicator.RotationInfo;
49 import org.tizen.emulator.skin.comm.ICommunicator.Scale;
50 import org.tizen.emulator.skin.config.EmulatorConfig;
51 import org.tizen.emulator.skin.config.EmulatorConfig.ArgsConstants;
52 import org.tizen.emulator.skin.config.EmulatorConfig.SkinPropertiesConstants;
53 import org.tizen.emulator.skin.dbi.EventInfoType;
54 import org.tizen.emulator.skin.dbi.KeyMapListType;
55 import org.tizen.emulator.skin.dbi.KeyMapType;
56 import org.tizen.emulator.skin.dbi.RegionType;
57 import org.tizen.emulator.skin.dbi.RotationType;
58 import org.tizen.emulator.skin.image.ImageRegistry;
59 import org.tizen.emulator.skin.image.ImageRegistry.ImageType;
60 import org.tizen.emulator.skin.layout.HWKey;
61 import org.tizen.emulator.skin.log.SkinLogger;
68 public class SkinUtil {
70 public static final String GTK_OS_CLASS = "org.eclipse.swt.internal.gtk.OS";
71 public static final String WIN32_OS_CLASS = "org.eclipse.swt.internal.win32.OS";
72 public static final String COCOA_OS_CLASS = "org.eclipse.swt.internal.cocoa.OS";
74 public static final int UNKNOWN_KEYCODE = -1;
75 public static final int SCALE_CONVERTER = 100;
76 public static final String EMULATOR_PREFIX = "emulator";
78 private static Logger logger =
79 SkinLogger.getSkinLogger(SkinUtil.class).getLogger();
85 public static String getVmName( EmulatorConfig config ) {
87 String vmPath = config.getArg( ArgsConstants.VM_PATH );
90 if ( SwtUtil.isWindowsPlatform() ) {
91 regex = "\\" + File.separator;
93 regex = File.separator;
95 String[] split = StringUtil.nvl( vmPath ).split( regex );
96 String vmName = split[split.length - 1];
102 public static String makeEmulatorName( EmulatorConfig config ) {
104 String vmName = getVmName( config );
106 if ( StringUtil.isEmpty( vmName ) ) {
107 vmName = EMULATOR_PREFIX;
110 int portNumber = config.getArgInt( ArgsConstants.NET_BASE_PORT );
111 return vmName + ":" + portNumber;
115 public static String getSdbPath() {
116 String sdbPath = null;
118 if (SwtUtil.isWindowsPlatform()) {
119 sdbPath = ".\\..\\..\\ansicon.exe";
121 sdbPath = "./../../sdb";
127 public static List<KeyMapType> getHWKeyMapList(short rotationId) {
128 RotationType rotation = SkinRotation.getRotation(rotationId);
129 if (rotation == null) {
133 KeyMapListType list = rotation.getKeyMapList();
135 /* try to using a KeyMapList of portrait */
136 rotation = SkinRotation.getRotation(RotationInfo.PORTRAIT.id());
137 if (rotation == null) {
141 list = rotation.getKeyMapList();
147 return list.getKeyMap();
150 public static HWKey getHWKey(
151 int currentX, int currentY, short rotationId, int scale) {
152 float convertedScale = convertScale(scale);
154 List<KeyMapType> keyMapList = getHWKeyMapList(rotationId);
155 if (keyMapList == null) {
159 for (KeyMapType keyMap : keyMapList) {
160 RegionType region = keyMap.getRegion();
162 int scaledX = (int) (region.getLeft() * convertedScale);
163 int scaledY = (int) (region.getTop() * convertedScale);
164 int scaledWidth = (int) (region.getWidth() * convertedScale);
165 int scaledHeight = (int) (region.getHeight() * convertedScale);
167 if (isInGeometry(currentX, currentY, scaledX, scaledY, scaledWidth, scaledHeight)) {
168 EventInfoType eventInfo = keyMap.getEventInfo();
170 HWKey hwKey = new HWKey();
171 hwKey.setKeyCode(eventInfo.getKeyCode());
172 hwKey.setRegion(new SkinRegion(scaledX, scaledY, scaledWidth, scaledHeight));
173 hwKey.setTooltip(keyMap.getTooltip());
182 public static boolean isInGeometry( int currentX, int currentY, int targetX, int targetY, int targetWidth,
185 if ( ( currentX >= targetX ) && ( currentY >= targetY ) ) {
186 if ( ( currentX <= ( targetX + targetWidth ) ) && ( currentY <= ( targetY + targetHeight ) ) ) {
195 public static void trimShell( Shell shell, Image image ) {
197 // trim transparent pixels in image. especially, corner round areas.
199 if ( null == image ) {
203 ImageData imageData = image.getImageData();
205 int width = imageData.width;
206 int height = imageData.height;
208 Region region = new Region();
209 region.add( new Rectangle( 0, 0, width, height ) );
211 for ( int i = 0; i < width; i++ ) {
212 for ( int j = 0; j < height; j++ ) {
213 int alpha = imageData.getAlpha( i, j );
215 region.subtract( i, j, 1, 1 );
220 shell.setRegion( region );
224 public static void trimShell(Shell shell, Image image,
225 int left, int top, int width, int height) {
231 ImageData imageData = image.getImageData();
233 int right = left + width;
234 int bottom = top + height;
236 Region region = shell.getRegion();
237 if (region == null) {
241 for (int i = left; i < right; i++) {
242 for (int j = top; j < bottom; j++) {
243 int alpha = imageData.getAlpha(i, j);
245 region.subtract(i, j, 1, 1);
247 region.add(i, j, 1, 1);
252 shell.setRegion(region);
255 public static int[] convertMouseGeometry( int originalX, int originalY, int lcdWidth, int lcdHeight, int scale,
258 float convertedScale = convertScale( scale );
260 int x = (int) ( originalX * ( 1 / convertedScale ) );
261 int y = (int) ( originalY * ( 1 / convertedScale ) );
266 if ( RotationInfo.LANDSCAPE.angle() == angle ) {
267 rotatedX = lcdWidth - y;
269 } else if ( RotationInfo.REVERSE_PORTRAIT.angle() == angle ) {
270 rotatedX = lcdWidth - x;
271 rotatedY = lcdHeight - y;
272 } else if ( RotationInfo.REVERSE_LANDSCAPE.angle() == angle ) {
274 rotatedY = lcdHeight - x;
277 return new int[] { rotatedX, rotatedY };
281 public static Image createScaledImage( ImageRegistry imageRegistry, Shell shell, short rotationId, int scale,
284 ImageData originalImageData = imageRegistry.getSkinImageData( rotationId, type );
286 if ( null == originalImageData ) {
290 ImageData imageData = (ImageData) originalImageData.clone();
292 float convertedScale = convertScale( scale );
294 int width = (int) ( originalImageData.width * convertedScale );
295 int height = (int) ( originalImageData.height * convertedScale );
296 imageData = imageData.scaledTo( width, height );
298 Image image = new Image( shell.getDisplay(), imageData );
303 public static float convertScale( int scale ) {
304 return (float) scale / SCALE_CONVERTER;
307 public static int getValidScale( EmulatorConfig config ) {
309 int storedScale = config.getSkinPropertyInt( SkinPropertiesConstants.WINDOW_SCALE,
310 EmulatorConfig.DEFAULT_WINDOW_SCALE );
312 if ( !SkinUtil.isValidScale( storedScale ) ) {
313 return EmulatorConfig.DEFAULT_WINDOW_SCALE;
320 public static boolean isValidScale( int scale ) {
321 if ( Scale.SCALE_100.value() == scale || Scale.SCALE_75.value() == scale
322 || Scale.SCALE_50.value() == scale || Scale.SCALE_25.value() == scale ) {
329 public static <T> int openMessage(Shell shell,
330 String title, String message, int style, EmulatorConfig config) {
331 MessageBox messageBox = new MessageBox(shell, style);
333 if (!StringUtil.isEmpty(title)) {
334 messageBox.setText(title);
336 messageBox.setText(makeEmulatorName(config));
339 messageBox.setMessage(StringUtil.nvl(message));
340 return messageBox.open();
343 /* for java reflection */
344 private static Field getOSField(String field) {
345 String className = "";
347 if (SwtUtil.isLinuxPlatform()) {
348 className = GTK_OS_CLASS;
349 } else if (SwtUtil.isWindowsPlatform()) {
350 className = WIN32_OS_CLASS;
351 } else if (SwtUtil.isMacPlatform()) {
352 className = COCOA_OS_CLASS;
357 f = Class.forName(className).getField(field);
358 } catch (ClassNotFoundException e) {
359 logger.log(Level.SEVERE, e.getMessage(), e);
360 } catch (SecurityException e) {
361 logger.log(Level.SEVERE, e.getMessage(), e);
362 } catch (NoSuchFieldException e) {
363 logger.log(Level.SEVERE, e.getMessage(), e);
369 private static Method getOSMethod(String method, Class<?>... parameterTypes) {
370 String className = "";
372 if (SwtUtil.isLinuxPlatform()) {
373 className = GTK_OS_CLASS;
374 } else if (SwtUtil.isWindowsPlatform()) {
375 className = WIN32_OS_CLASS;
376 } else if (SwtUtil.isMacPlatform()) {
377 className = COCOA_OS_CLASS;
382 m = Class.forName(className).getMethod(method, parameterTypes);
383 } catch (ClassNotFoundException e) {
384 logger.log(Level.SEVERE, e.getMessage(), e);
385 } catch (SecurityException e) {
386 logger.log(Level.SEVERE, e.getMessage(), e);
387 } catch (NoSuchMethodException e) {
388 logger.log(Level.SEVERE, e.getMessage(), e);
394 private static Method getOSMethod(String method) {
395 return getOSMethod(method, new Class<?>[] {});
398 private static Object invokeOSMethod(Method method, Object... args) {
399 if (null == method) {
404 return method.invoke(null, args);
405 } catch (IllegalArgumentException e) {
406 logger.log(Level.SEVERE, e.getMessage(), e);
407 } catch (IllegalAccessException e) {
408 logger.log(Level.SEVERE, e.getMessage(), e);
409 } catch (InvocationTargetException e) {
410 logger.log(Level.SEVERE, e.getMessage(), e);
416 private static Object invokeOSMethod(Method method) {
417 return invokeOSMethod(method, new Object[] {});
420 private static boolean setTopMost32(Shell shell, boolean isOnTop) {
422 if (SwtUtil.isLinuxPlatform()) {
424 http://wmctrl.sourcearchive.com/documentation/1.07/main_8c-source.html */
426 /* if (!OS.GDK_WINDOWING_X11()) {
427 logger.warning("There is no x11 system.");
431 int eventData0 = isOnTop ? 1 : 0; // 'add' or 'remove'
436 m = Shell.class.getDeclaredMethod("topHandle", new Class<?>[] {});
437 m.setAccessible(true);
438 topHandle = (Integer) m.invoke( shell, new Object[] {});
439 } catch (SecurityException ex) {
440 logger.log(Level.SEVERE, ex.getMessage(), ex);
441 } catch (NoSuchMethodException ex) {
442 logger.log(Level.SEVERE, ex.getMessage(), ex);
443 } catch (IllegalArgumentException ex) {
444 logger.log(Level.SEVERE, ex.getMessage(), ex);
445 } catch (IllegalAccessException ex) {
446 logger.log(Level.SEVERE, ex.getMessage(), ex);
447 } catch (InvocationTargetException ex) {
448 logger.log(Level.SEVERE, ex.getMessage(), ex);
451 int xWindow = OS.gdk_x11_drawable_get_xid(
452 OS.GTK_WIDGET_WINDOW(topHandle));
453 int xDisplay = OS.GDK_DISPLAY();
455 byte[] messageBuffer = Converter.wcsToMbcs(null, "_NET_WM_STATE", true);
456 int xMessageAtomType = OS.XInternAtom(xDisplay, messageBuffer, false);
458 messageBuffer = Converter.wcsToMbcs(null, "_NET_WM_STATE_ABOVE", true);
459 int xMessageAtomAbove = OS.XInternAtom(xDisplay, messageBuffer, false);
461 XClientMessageEvent event = new XClientMessageEvent();
462 event.type = OS.ClientMessage;
463 event.window = xWindow;
464 event.message_type = xMessageAtomType;
466 event.data[0] = eventData0;
467 event.data[1] = xMessageAtomAbove;
469 int clientEvent = OS.g_malloc(XClientMessageEvent.sizeof);
470 OS.memmove(clientEvent, event, XClientMessageEvent.sizeof);
471 int rootWin = OS.XDefaultRootWindow(xDisplay);
472 // SubstructureRedirectMask : 1L<<20 | SubstructureNotifyMask : 1L<<19
473 OS.XSendEvent(xDisplay, rootWin, false,
474 (int) ( 1L << 20 | 1L << 19 ), clientEvent);
475 OS.g_free(clientEvent); */
478 Boolean gdkWindowingX11 =
479 (Boolean) invokeOSMethod(getOSMethod("GDK_WINDOWING_X11"));
480 if (null == gdkWindowingX11) {
481 logger.warning("GDK_WINDOWING_X11 returned null. There is no x11 system.");
485 int eventData0 = isOnTop ? 1 : 0; /* 'add' or 'remove' */
490 m = Shell.class.getDeclaredMethod("topHandle", new Class<?>[] {});
492 m.setAccessible(true);
493 topHandle = (Integer) m.invoke(shell, new Object[] {});
494 } catch (SecurityException ex) {
495 logger.log(Level.SEVERE, ex.getMessage(), ex);
497 } catch (NoSuchMethodException ex) {
498 logger.log(Level.SEVERE, ex.getMessage(), ex);
500 } catch (IllegalArgumentException ex) {
501 logger.log(Level.SEVERE, ex.getMessage(), ex);
503 } catch (IllegalAccessException ex) {
504 logger.log(Level.SEVERE, ex.getMessage(), ex);
506 } catch (InvocationTargetException ex ) {
507 logger.log(Level.SEVERE, ex.getMessage(), ex);
511 Integer gtkWidgetWindow = (Integer) invokeOSMethod(
512 getOSMethod("GTK_WIDGET_WINDOW", int.class), topHandle);
513 if (null == gtkWidgetWindow) {
514 logger.warning("GTK_WIDGET_WINDOW returned null");
518 Integer xWindow = (Integer) invokeOSMethod(
519 getOSMethod("gdk_x11_drawable_get_xid", int.class), gtkWidgetWindow);
520 if (null == xWindow) {
521 logger.warning("gdk_x11_drawable_get_xid returned null");
525 Integer xDisplay = (Integer) invokeOSMethod(getOSMethod("GDK_DISPLAY"));
526 if (null == xDisplay) {
527 logger.warning("GDK_DISPLAY returned null");
531 Method xInternAtom = getOSMethod(
532 "XInternAtom", int.class, byte[].class, boolean.class);
534 Class<?> converterClass = null;
536 converterClass = Class.forName("org.eclipse.swt.internal.Converter");
537 } catch (ClassNotFoundException ex) {
538 logger.log(Level.SEVERE, ex.getMessage(), ex);
542 Method wcsToMbcs = null;
543 byte[] messageBufferState = null;
544 byte[] messageBufferAbove = null;
547 wcsToMbcs = converterClass.getMethod(
548 "wcsToMbcs", String.class, String.class, boolean.class);
549 } catch (SecurityException ex) {
550 logger.log(Level.SEVERE, ex.getMessage(), ex);
552 } catch (NoSuchMethodException ex) {
553 logger.log(Level.SEVERE, ex.getMessage(), ex);
559 (byte[]) wcsToMbcs.invoke(null, null, "_NET_WM_STATE", true);
561 (byte[]) wcsToMbcs.invoke(null, null, "_NET_WM_STATE_ABOVE", true);
562 } catch (IllegalArgumentException ex) {
563 logger.log(Level.SEVERE, ex.getMessage(), ex);
565 } catch (IllegalAccessException ex) {
566 logger.log(Level.SEVERE, ex.getMessage(), ex);
568 } catch (InvocationTargetException ex) {
569 logger.log(Level.SEVERE, ex.getMessage(), ex);
573 Integer xMessageAtomType =
574 (Integer) invokeOSMethod(xInternAtom, xDisplay, messageBufferState, false);
575 if (null == xMessageAtomType) {
576 logger.warning("xMessageAtomType is null");
580 Integer xMessageAtomAbove =
581 (Integer) invokeOSMethod(xInternAtom, xDisplay, messageBufferAbove, false);
582 if (null == xMessageAtomAbove) {
583 logger.warning("xMessageAtomAbove is null");
587 Class<?> eventClazz = null;
590 eventClazz = Class.forName("org.eclipse.swt.internal.gtk.XClientMessageEvent");
591 event = eventClazz.newInstance();
592 } catch (InstantiationException ex) {
593 logger.log(Level.SEVERE, ex.getMessage(), ex);
594 } catch (IllegalAccessException ex) {
595 logger.log(Level.SEVERE, ex.getMessage(), ex);
596 } catch (ClassNotFoundException ex) {
597 logger.log(Level.SEVERE, ex.getMessage(), ex);
600 if (null == eventClazz || null == event) {
604 Integer malloc = null;
606 Field type = eventClazz.getField("type");
608 Field clientMessageField = getOSField("ClientMessage");
609 if (null == clientMessageField) {
610 logger.warning("clientMessageField is null");
613 type.set(event, clientMessageField.get(null));
615 Field window = eventClazz.getField("window");
616 window.set(event, xWindow);
617 Field messageType = eventClazz.getField("message_type");
618 messageType.set(event, xMessageAtomType);
619 Field format = eventClazz.getField("format");
620 format.set(event, 32);
622 Object data = Array.newInstance(int.class, 5);
623 Array.setInt(data, 0, eventData0);
624 Array.setInt(data, 1, xMessageAtomAbove);
625 Array.setInt(data, 2, 0);
626 Array.setInt(data, 3, 0);
627 Array.setInt(data, 4, 0);
629 Field dataField = eventClazz.getField("data");
630 dataField.set(event, data);
632 Field sizeofField = eventClazz.getField("sizeof");
633 Integer sizeof = (Integer) sizeofField.get(null);
635 Method gMalloc = getOSMethod("g_malloc", int.class);
636 malloc = (Integer) invokeOSMethod(gMalloc, sizeof);
639 getOSMethod("memmove", int.class, eventClazz, int.class);
640 invokeOSMethod(memmove, malloc, event, sizeof);
642 } catch (NoSuchFieldException ex) {
643 logger.log(Level.SEVERE, ex.getMessage(), ex);
645 } catch (IllegalAccessException ex) {
646 logger.log(Level.SEVERE, ex.getMessage(), ex);
650 Method xDefaultRootWindow =
651 getOSMethod("XDefaultRootWindow", int.class);
653 (Integer) invokeOSMethod(xDefaultRootWindow, xDisplay);
655 Method xSendEvent = getOSMethod("XSendEvent",
656 int.class, int.class, boolean.class, int.class, int.class);
658 /* SubstructureRedirectMask : 1L<<20 | SubstructureNotifyMask : 1L<<19 */
659 invokeOSMethod(xSendEvent, xDisplay, rootWin,
660 false, (int) (1L << 20 | 1L << 19), malloc);
661 invokeOSMethod(getOSMethod("g_free", int.class), malloc);
663 } else if (SwtUtil.isWindowsPlatform()) {
664 Point location = shell.getLocation();
666 /* int hWndInsertAfter = 0;
668 hWndInsertAfter = OS.HWND_TOPMOST;
670 hWndInsertAfter = OS.HWND_NOTOPMOST;
672 OS.SetWindowPos(shell.handle,
673 hWndInsertAfter, location.x, location.y, 0, 0, OS.SWP_NOSIZE); */
675 int hWndInsertAfter = 0;
680 Field topMost = getOSField("HWND_TOPMOST");
681 if (null == topMost) {
682 logger.warning("topMost is null");
686 hWndInsertAfter = topMost.getInt(null);
688 Field noTopMost = getOSField("HWND_NOTOPMOST");
689 if (null == noTopMost) {
690 logger.warning("HWND_NOTOPMOST is null");
694 hWndInsertAfter = noTopMost.getInt(null);
697 Field noSizeField = getOSField("SWP_NOSIZE");
698 if (null == noSizeField) {
699 logger.warning("SWP_NOSIZE is null");
703 noSize = noSizeField.getInt(null);
705 } catch (IllegalArgumentException ex) {
706 logger.log(Level.SEVERE, ex.getMessage(), ex);
708 } catch (IllegalAccessException ex) {
709 logger.log(Level.SEVERE, ex.getMessage(), ex);
713 Method m = getOSMethod("SetWindowPos",
714 int.class, int.class, int.class,
715 int.class, int.class, int.class, int.class);
717 /* org.eclipse.swt.widgets.Shell */
720 Field field = shell.getClass().getField("handle");
721 shellHandle = field.getInt(shell);
722 logger.info("shell.handle:" + shellHandle);
723 } catch (IllegalArgumentException e) {
724 logger.log(Level.SEVERE, e.getMessage(), e);
726 } catch (IllegalAccessException e) {
727 logger.log(Level.SEVERE, e.getMessage(), e);
729 } catch (SecurityException e) {
730 logger.log(Level.SEVERE, e.getMessage(), e);
732 } catch (NoSuchFieldException e) {
733 logger.log(Level.SEVERE, e.getMessage(), e);
737 invokeOSMethod(m, shellHandle, hWndInsertAfter,
738 location.x, location.y, 0, 0, noSize);
739 } else if (SwtUtil.isMacPlatform()) {
741 logger.warning("not supported yet");
748 private static boolean setTopMost64(Shell shell, boolean isOnTop) {
750 if (SwtUtil.isLinuxPlatform()) {
751 Boolean gdkWindowingX11 =
752 (Boolean) invokeOSMethod(getOSMethod("GDK_WINDOWING_X11"));
753 if (null == gdkWindowingX11) {
754 logger.warning("GDK_WINDOWING_X11 returned null. There is no x11 system.");
758 int eventData0 = isOnTop ? 1 : 0; /* 'add' or 'remove' */
763 m = Shell.class.getDeclaredMethod("topHandle", new Class<?>[] {});
765 m.setAccessible(true);
766 topHandle = (Long) m.invoke(shell, new Object[] {});
767 } catch (SecurityException ex) {
768 logger.log(Level.SEVERE, ex.getMessage(), ex);
770 } catch (NoSuchMethodException ex) {
771 logger.log(Level.SEVERE, ex.getMessage(), ex);
773 } catch (IllegalArgumentException ex) {
774 logger.log(Level.SEVERE, ex.getMessage(), ex);
776 } catch (IllegalAccessException ex) {
777 logger.log(Level.SEVERE, ex.getMessage(), ex);
779 } catch (InvocationTargetException ex) {
780 logger.log(Level.SEVERE, ex.getMessage(), ex);
784 Long gtkWidgetWindow = (Long) invokeOSMethod(
785 getOSMethod("GTK_WIDGET_WINDOW", long.class), topHandle);
786 if (null == gtkWidgetWindow) {
787 logger.warning("GTK_WIDGET_WINDOW returned null");
791 Long xWindow = (Long) invokeOSMethod(
792 getOSMethod("gdk_x11_drawable_get_xid", long.class), gtkWidgetWindow);
793 if (null == xWindow) {
794 logger.warning("gdk_x11_drawable_get_xid returned null");
798 Long xDisplay = (Long) invokeOSMethod( getOSMethod("GDK_DISPLAY"));
799 if (null == xDisplay) {
800 logger.warning("GDK_DISPLAY returned null");
804 Method xInternAtom = getOSMethod(
805 "XInternAtom", long.class, byte[].class, boolean.class);
807 Class<?> converterClass = null;
809 converterClass = Class.forName("org.eclipse.swt.internal.Converter");
810 } catch (ClassNotFoundException ex) {
811 logger.log(Level.SEVERE, ex.getMessage(), ex);
815 Method wcsToMbcs = null;
816 byte[] messageBufferState = null;
817 byte[] messageBufferAbove = null;
820 wcsToMbcs = converterClass.getMethod(
821 "wcsToMbcs", String.class, String.class, boolean.class);
822 } catch (SecurityException ex) {
823 logger.log(Level.SEVERE, ex.getMessage(), ex);
825 } catch (NoSuchMethodException ex) {
826 logger.log(Level.SEVERE, ex.getMessage(), ex);
832 (byte[]) wcsToMbcs.invoke(null, null, "_NET_WM_STATE", true);
834 (byte[]) wcsToMbcs.invoke(null, null, "_NET_WM_STATE_ABOVE", true);
835 } catch (IllegalArgumentException ex) {
836 logger.log(Level.SEVERE, ex.getMessage(), ex);
838 } catch (IllegalAccessException ex) {
839 logger.log(Level.SEVERE, ex.getMessage(), ex);
841 } catch (InvocationTargetException ex) {
842 logger.log(Level.SEVERE, ex.getMessage(), ex);
846 Long xMessageAtomType =
847 (Long) invokeOSMethod(xInternAtom, xDisplay, messageBufferState, false);
848 if (null == xMessageAtomType) {
849 logger.warning("xMessageAtomType is null");
853 Long xMessageAtomAbove =
854 (Long) invokeOSMethod(xInternAtom, xDisplay, messageBufferAbove, false);
855 if (null == xMessageAtomAbove) {
856 logger.warning("xMessageAtomAbove is null");
860 Class<?> eventClazz = null;
863 eventClazz = Class.forName("org.eclipse.swt.internal.gtk.XClientMessageEvent");
864 event = eventClazz.newInstance();
865 } catch (InstantiationException ex) {
866 logger.log(Level.SEVERE, ex.getMessage(), ex);
867 } catch (IllegalAccessException ex) {
868 logger.log(Level.SEVERE, ex.getMessage(), ex);
869 } catch (ClassNotFoundException ex) {
870 logger.log(Level.SEVERE, ex.getMessage(), ex);
873 if (null == eventClazz || null == event) {
879 Field type = eventClazz.getField("type");
881 Field clientMessageField = getOSField("ClientMessage");
882 if (null == clientMessageField) {
883 logger.warning("clientMessageField is null");
886 type.set(event, clientMessageField.get(null));
888 Field window = eventClazz.getField("window");
889 window.set(event, xWindow);
890 Field messageType = eventClazz.getField("message_type");
891 messageType.set(event, xMessageAtomType);
892 Field format = eventClazz.getField("format");
893 format.set(event, 32);
895 Object data = Array.newInstance(long.class, 5);
896 Array.setLong(data, 0, eventData0);
897 Array.setLong(data, 1, xMessageAtomAbove);
898 Array.setLong(data, 2, 0);
899 Array.setLong(data, 3, 0);
900 Array.setLong(data, 4, 0);
902 Field dataField = eventClazz.getField("data");
903 dataField.set(event, data);
905 Field sizeofField = eventClazz.getField("sizeof");
906 Integer sizeof = (Integer) sizeofField.get(null);
908 Method gMalloc = getOSMethod("g_malloc", long.class);
909 malloc = (Long) invokeOSMethod(gMalloc, sizeof.longValue());
912 getOSMethod("memmove", long.class, eventClazz, long.class);
913 invokeOSMethod(memmove, malloc, event, sizeof.longValue());
915 } catch (NoSuchFieldException ex) {
916 logger.log(Level.SEVERE, ex.getMessage(), ex);
918 } catch (IllegalAccessException ex) {
919 logger.log(Level.SEVERE, ex.getMessage(), ex);
923 Method xDefaultRootWindow =
924 getOSMethod("XDefaultRootWindow", long.class);
926 (Long) invokeOSMethod(xDefaultRootWindow, xDisplay);
928 Method xSendEvent = getOSMethod("XSendEvent", long.class, long.class, boolean.class,
929 long.class, long.class);
931 /* ubstructureRedirectMask : 1L<<20 | SubstructureNotifyMask : 1L<<19 */
932 invokeOSMethod(xSendEvent, xDisplay, rootWin,
933 false, (long) (1L << 20 | 1L << 19), malloc);
934 invokeOSMethod(getOSMethod("g_free", long.class), malloc);
935 } else if (SwtUtil.isWindowsPlatform()) {
936 Point location = shell.getLocation();
938 long hWndInsertAfter = 0;
943 Field topMost = getOSField("HWND_TOPMOST");
944 if (null == topMost) {
945 logger.warning("topMost is null");
949 hWndInsertAfter = topMost.getLong(null);
951 Field noTopMost = getOSField("HWND_NOTOPMOST");
952 if (null == noTopMost) {
953 logger.warning("noTopMost is null");
957 hWndInsertAfter = noTopMost.getLong(null);
960 Field noSizeField = getOSField("SWP_NOSIZE");
961 if (null == noSizeField) {
962 logger.warning("SWP_NOSIZE is null");
966 noSize = noSizeField.getInt(null);
968 } catch (IllegalArgumentException ex) {
969 logger.log(Level.SEVERE, ex.getMessage(), ex);
971 } catch (IllegalAccessException ex) {
972 logger.log(Level.SEVERE, ex.getMessage(), ex);
976 Method m = getOSMethod("SetWindowPos",
977 long.class, long.class, int.class,
978 int.class, int.class, int.class, int.class);
980 /* org.eclipse.swt.widgets.Shell */
981 long shellHandle = 0;
983 Field field = shell.getClass().getField("handle");
984 shellHandle = field.getLong(shell);
985 logger.info("shell.handle:" + shellHandle);
986 } catch (IllegalArgumentException e) {
987 logger.log(Level.SEVERE, e.getMessage(), e);
989 } catch (IllegalAccessException e) {
990 logger.log(Level.SEVERE, e.getMessage(), e);
992 } catch (SecurityException e) {
993 logger.log(Level.SEVERE, e.getMessage(), e);
995 } catch (NoSuchFieldException e) {
996 logger.log(Level.SEVERE, e.getMessage(), e);
1000 invokeOSMethod(m, shellHandle, hWndInsertAfter,
1001 location.x, location.y, 0, 0, noSize);
1002 } else if (SwtUtil.isMacPlatform()) {
1004 logger.warning("not supported yet");
1011 public static boolean setTopMost(Shell shell, boolean isOnTop) {
1012 if (shell == null) {
1016 /* internal/Library.java::arch() */
1017 String osArch = System.getProperty("os.arch"); /* $NON-NLS-1$ */
1019 if (osArch.equals("amd64") || osArch.equals("x86_64") ||
1020 osArch.equals("IA64W") || osArch.equals("ia64")) {
1021 /* $NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$ */
1022 logger.info("64bit architecture : " + osArch);
1024 return setTopMost64(shell, isOnTop); /* 64bit */
1027 logger.info("32bit architecture : " + osArch);
1028 return setTopMost32(shell, isOnTop); /* 32bit */