Package org.gudy.azureus2.ui.swt.win32

Source Code of org.gudy.azureus2.ui.swt.win32.Win32UIEnhancer

/**
* Copyright (C) 2006 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SAS au capital de 63.529,40 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/

package org.gudy.azureus2.ui.swt.win32;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Shell;

import org.gudy.azureus2.core3.util.AEThread2;
import org.gudy.azureus2.core3.util.Constants;
import org.gudy.azureus2.platform.win32.access.AEWin32Access;
import org.gudy.azureus2.platform.win32.access.AEWin32Manager;
import org.gudy.azureus2.platform.win32.access.impl.AEWin32AccessImpl;
import org.gudy.azureus2.platform.win32.access.impl.AEWin32AccessInterface;

import com.aelitis.azureus.core.drivedetector.*;

/**
* @author TuxPaper
* @created Nov 29, 2006
*
* Note: You can safely exclude this class from the build path.
* All calls to this class use (or at least should use) reflection
*/
public class Win32UIEnhancer
{

  public static final boolean DEBUG = false;

  public static final int SHGFI_ICON = 0x000000100;
 
  public static final int SHGFI_SMALLICON= 0x1;
 
  public static final int SHGFI_USEFILEATTRIBUTES = 0x000000010;

  public static final int SHGFI_LARGEICON = 0x2;

  public static final int WM_DEVICECHANGE = 0x219;

  public static final int DBT_DEVICEARRIVAL = 0x8000;

  public static final int DBT_DEVICEREMOVECOMPLETE = 0x8004;

  public static final int DBT_DEVTYP_VOLUME = 0x2;

  public static final int FILE_ATTRIBUTE_NORMAL = 0x00000080;

  private static int messageProcInt;

  private static long messageProcLong;

  private static Object /* Callback */messageCallback;

  private static DriveDetectedInfo loc;

  private static Class<?> claOS;

  private static boolean useLong;

  private static Class<?> claCallback;

  private static Constructor<?> constCallBack;

  private static Method mCallback_getAddress;

  private static Method mSetWindowLongPtr;

  private static int OS_GWLP_WNDPROC;

  private static Method mOS_memmove_byte;

  private static Method mOS_memmove_int;

  private static boolean isUnicode;

  private static Class<?> claSHFILEINFO;

  private static Class<?> claSHFILEINFOA;

  private static Class<?> claSHFILEINFOW;

  private static Class<?> claTCHAR;

  private static Method mSHGetFileInfo;

  private static Method mImage_win32_new;

  private static Constructor<?> constTCHAR3;

  private static int SHFILEINFO_sizeof;

  static {
    try {
      claOS = Class.forName("org.eclipse.swt.internal.win32.OS");
     
      isUnicode = claOS.getDeclaredField("IsUnicode").getBoolean(null);
           
      claSHFILEINFO = Class.forName("org.eclipse.swt.internal.win32.SHFILEINFO");
     
      SHFILEINFO_sizeof = claSHFILEINFO.getField("sizeof").getInt(null);
     
      claSHFILEINFOA = Class.forName("org.eclipse.swt.internal.win32.SHFILEINFOA");
      claSHFILEINFOW = Class.forName("org.eclipse.swt.internal.win32.SHFILEINFOW");
     
      claTCHAR = Class.forName("org.eclipse.swt.internal.win32.TCHAR");
     
      // public TCHAR (int codePage, String string, boolean terminate) {
      constTCHAR3 = claTCHAR.getConstructor(new Class[] {
        int.class,
        String.class,
        boolean.class
      });
     
      //public static long /*int*/ SHGetFileInfo (TCHAR pszPath, int dwFileAttributes, SHFILEINFO psfi, int cbFileInfo, int uFlags)
      mSHGetFileInfo = claOS.getMethod("SHGetFileInfo", new Class<?>[] {
        claTCHAR,
        int.class,
        claSHFILEINFO,
        int.class,
        int.class,
      });


      // public Callback (Object object, String method, int argCount)
      claCallback = Class.forName("org.eclipse.swt.internal.Callback");
      constCallBack = claCallback.getDeclaredConstructor(new Class[] {
        Object.class,
        String.class,
        int.class
      });
      // public long /*int*/ getAddress ()
      mCallback_getAddress = claCallback.getDeclaredMethod("getAddress",
          new Class[] {});

      try {
        //int /*long*/ SetWindowLongPtr (int /*long*/ hWnd, int nIndex, int /*long*/ dwNewLong) {
        mSetWindowLongPtr = claOS.getMethod("SetWindowLongPtr",
            new Class[] {
              int.class,
              int.class,
              int.class
            });

        useLong = false;
       
        mOS_memmove_byte = claOS.getMethod("memmove", new Class[] {
          byte[].class,
          int.class,
          int.class
        });
        mOS_memmove_int = claOS.getMethod("memmove", new Class[] {
          int[].class,
          int.class,
          int.class
        });
       
        mImage_win32_new = Image.class.getMethod("win32_new", new Class[] {
          Device.class,
          int.class,
          int.class
        });
      } catch (Exception e) {
        //e.printStackTrace();
        mSetWindowLongPtr = claOS.getMethod("SetWindowLongPtr",
            new Class[] {
              long.class,
              int.class,
              long.class
            });

        useLong = true;
        mOS_memmove_byte = claOS.getMethod("memmove", new Class[] {
          byte[].class,
          long.class,
          long.class
        });
        mOS_memmove_int = claOS.getMethod("memmove", new Class[] {
          int[].class,
          long.class,
          long.class
        });

        mImage_win32_new = Image.class.getMethod("win32_new", new Class[] {
          Device.class,
          int.class,
          long.class
        });
      }

      //OS.GWLP_WNDPROC
      OS_GWLP_WNDPROC = ((Integer) claOS.getField("GWLP_WNDPROC").get(null)).intValue();
    } catch (Throwable e) {
      e.printStackTrace();
    }
  }

  public static Image getFileIcon(File file, boolean big) {
    try {
      int flags = SHGFI_ICON;
      flags |= big ? SHGFI_LARGEICON : SHGFI_SMALLICON;
      if (!file.exists()) {
        flags |= SHGFI_USEFILEATTRIBUTES;
      }
      Object shfi;
      if (isUnicode) {
        shfi = claSHFILEINFOW.newInstance();
      } else {
        shfi = claSHFILEINFOA.newInstance();
      }
      Object pszPath = constTCHAR3.newInstance(0, file.getAbsolutePath(), true);
     
      mSHGetFileInfo.invoke(null, new Object[] {
        pszPath,
        file.isDirectory() ? 16
            : FILE_ATTRIBUTE_NORMAL, shfi, SHFILEINFO_sizeof, flags
      });
 
      Field fldHIcon = claSHFILEINFO.getField("hIcon");
      if (fldHIcon.getLong(shfi) == 0) {
        return null;
      }
      Image image = null;
      if (useLong) {
        image = (Image) mImage_win32_new.invoke(null, new Object[] {
          null,
          SWT.ICON,
          fldHIcon.getLong(shfi)
        });
      } else {
        image = (Image) mImage_win32_new.invoke(null, new Object[] {
          null,
          SWT.ICON,
          fldHIcon.getInt(shfi)
        });
      }
     
      return image;
    } catch (Exception e) {
      return null;
    }
  }

  public static void initMainShell(Shell shell) {
    //Canvas canvas = new Canvas(shell, SWT.NO_BACKGROUND | SWT.NO_TRIM);
    //canvas.setVisible(false);
    Shell subshell = new Shell(shell);

    try {
      messageCallback = constCallBack.newInstance(new Object[] {
        Win32UIEnhancer.class,
        "messageProc2",
        4
      });

      Object oHandle = subshell.getClass().getField("handle").get(subshell);
      if (useLong) {
        Number n = (Number) mCallback_getAddress.invoke(messageCallback,
            new Object[] {});
        messageProcLong = n.longValue();
        if (messageProcLong != 0) {
          mSetWindowLongPtr.invoke(null, new Object[] {
            oHandle,
            OS_GWLP_WNDPROC,
            messageProcLong
          });
        }
      } else {
        Number n = (Number) mCallback_getAddress.invoke(messageCallback,
            new Object[] {});
        messageProcInt = n.intValue();
        if (messageProcInt != 0) {
          mSetWindowLongPtr.invoke(null, new Object[] {
            oHandle,
            OS_GWLP_WNDPROC,
            messageProcInt
          });
        }
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }

    new AEThread2( "Async:USB" )
    {
      public void
      run()
      {
        if ( Constants.isWindows7OrHigher ){
         
          String version = AEWin32Manager.getAccessor( false ).getVersion();
         
          if ( Constants.compareVersions( "1.21", version ) > 0 ){
       
              // bug fixed in 1.21 whereby some win7 users got crashes
           
            return;
          }
        }
       
          Map<File, Map> drives = AEWin32Manager.getAccessor(false).getAllDrives();
          if (drives != null) {
            for (File file : drives.keySet()) {
              Map driveInfo = drives.get(file);
              boolean isWritableUSB = AEWin32Manager.getAccessor(false).isUSBDrive(driveInfo);
              driveInfo.put("isWritableUSB", isWritableUSB);
              DriveDetectorFactory.getDeviceDetector().driveDetected(file, driveInfo);
            }
          }
      }
    }.start();
  }

  static int /*long*/messageProc2(int /*long*/hwnd, int /*long*/msg,
      int /*long*/wParam, int /*long*/lParam) {
    return (int) messageProc2(hwnd, msg, (long) wParam, (long) lParam);
  }

  static long /*int*/messageProc2(long /*int*/hwnd, long /*int*/msg,
      long /*int*/wParam, long /*int*/lParam) {
    try {
      // I'll clean this up soon
      switch ((int) /*64*/msg) {
        case WM_DEVICECHANGE:
          if (wParam == DBT_DEVICEARRIVAL) {
            int[] st = new int[3];
            if (useLong) {
              mOS_memmove_int.invoke(null, new Object[] {
                st,
                lParam,
                (long) 12
              });
            } else {
              mOS_memmove_int.invoke(null, new Object[] {
                st,
                (int) lParam,
                (int) 12
              });
            }

            if (DEBUG) {
              System.out.println("Arrival: " + st[0] + "/" + st[1] + "/"
                  + st[2]);
            }

            if (st[1] == DBT_DEVTYP_VOLUME) {
              if (DEBUG) {
                System.out.println("NEW VOLUME!");
              }

              byte b[] = new byte[st[0]];
             
              if (useLong) {
                mOS_memmove_byte.invoke(null, new Object[] {
                  b,
                  lParam,
                  (int) st[0]
                });
              } else {
                mOS_memmove_byte.invoke(null, new Object[] {
                  b,
                  (int) lParam,
                  (int) st[0]
                });
              }
              long unitMask = (b[12] & 255) + ((b[13] & 255) << 8) + ((b[14] & 255) << 16)
                  + ((b[15] & 3) << 24);
              char letter = '?';
              for (int i = 0; i < 26; i++) {
                if (((1 << i) & unitMask) > 0) {
                  letter = (char) ('A' + i);
                  if (DEBUG) {
                    System.out.println("Drive " + letter + ";mask=" + unitMask);
                  }
                  Map driveInfo = AEWin32AccessInterface.getDriveInfo(letter);
                  boolean isWritableUSB = AEWin32Manager.getAccessor(false).isUSBDrive(driveInfo);
                  driveInfo.put("isWritableUSB", isWritableUSB);
                  DriveDetector driveDetector = DriveDetectorFactory.getDeviceDetector();
                  driveDetector.driveDetected(new File(letter + ":\\"), driveInfo);
                }
              }
            }

          } else if (wParam == DBT_DEVICEREMOVECOMPLETE) {
            int[] st = new int[3];
            if (useLong) {
              mOS_memmove_int.invoke(null, new Object[] {
                st,
                lParam,
                (long) 12
              });
            } else {
              mOS_memmove_int.invoke(null, new Object[] {
                st,
                (int) lParam,
                (int) 12
              });
            }

            if (DEBUG) {
              System.out.println("Remove: " + st[0] + "/" + st[1] + "/" + st[2]);
            }

            if (st[1] == DBT_DEVTYP_VOLUME) {
              if (DEBUG) {
                System.out.println("REMOVE VOLUME!");
              }

              byte b[] = new byte[st[0]];
              if (useLong) {
                mOS_memmove_byte.invoke(null, new Object[] {
                  b,
                  lParam,
                  (int) st[0]
                });
              } else {
                mOS_memmove_byte.invoke(null, new Object[] {
                  b,
                  (int) lParam,
                  (int) st[0]
                });
              }
              long unitMask = (b[12] & 255) + ((b[13] & 255) << 8)
                  + ((b[14] & 255) << 16) + ((b[15] & 3) << 24);
              char letter = '?';
              DriveDetector driveDetector = DriveDetectorFactory.getDeviceDetector();
              for (int i = 0; i < 26; i++) {
                if (((1 << i) & unitMask) > 0) {
                  letter = (char) ('A' + i);
                  if (DEBUG) {
                    System.out.println("Drive " + letter + ";mask=" + unitMask);
                  }
                  driveDetector.driveRemoved(new File(letter + ":\\"));
                }
              }

              Map<File, Map> drives = AEWin32Manager.getAccessor(false).getAllDrives();
              if (drives != null) {
                DriveDetectedInfo[] existingDrives = driveDetector.getDetectedDriveInfo();
                for (DriveDetectedInfo existingDrive : existingDrives) {
                  File existingDriveFile = existingDrive.getLocation();
                  boolean found = drives.containsKey(existingDriveFile);
                  if (!found) {
                    if (DEBUG) {
                      System.out.println("Fixup: Remove Drive " + existingDriveFile);
                    }
                    driveDetector.driveRemoved(existingDriveFile);
                  }
                }
              }

            }

          }
          if (DEBUG) {
            System.out.println("DEVICE CHANGE" + wParam + "/" + lParam);
          }
          break;
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return 0;// OS.DefWindowProc (hwnd, (int)/*64*/msg, wParam, lParam);
  }
}
TOP

Related Classes of org.gudy.azureus2.ui.swt.win32.Win32UIEnhancer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.