001/*
002 * :tabSize=8:indentSize=8:noTabs=false:
003 * :folding=explicit:collapseFolds=1:
004 *
005 * OperatingSystem.java - OS detection
006 * :tabSize=8:indentSize=8:noTabs=false:
007 * :folding=explicit:collapseFolds=1:
008 *
009 * Copyright (C) 2002, 2003 Slava Pestov
010 *
011 * This program is free software; you can redistribute it and/or
012 * modify it under the terms of the GNU General Public License
013 * as published by the Free Software Foundation; either version 2
014 * of the License, or any later version.
015 *
016 * This program is distributed in the hope that it will be useful,
017 * but WITHOUT ANY WARRANTY; without even the implied warranty of
018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
019 * GNU General Public License for more details.
020 *
021 * You should have received a copy of the GNU General Public License
022 * along with this program; if not, write to the Free Software
023 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
024 */
025
026package ca.bc.webarts.widgets;
027
028import java.awt.GraphicsConfiguration;
029import java.awt.GraphicsDevice;
030import java.awt.GraphicsEnvironment;
031import java.awt.Rectangle;
032import java.awt.Toolkit;
033import javax.swing.UIManager;
034import java.io.File;
035import java.util.Enumeration;
036import java.util.Vector;
037//import org.gjt.sp.util.Log;
038
039/**
040 * Operating system detection routines.
041 * @author Slava Pestov
042 * @version $Id: OperatingSystem.java,v 1.14 2003/06/08 22:49:09 spestov Exp $
043 * @since jEdit 4.0pre4
044 */
045public class OperatingSystem
046{
047        //{{{ getScreenBounds() method
048        /**
049         * Returns the bounds of the default screen.
050         */
051        public static final Rectangle getScreenBounds()
052        {
053                int screenX = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth();
054                int screenY = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
055                int x, y, w, h;
056                
057                if (isMacOS())
058                {
059                        x = 0;
060                        y = 22;
061                        w = screenX;
062                        h = screenY - y - 4;//shadow size
063                }
064                else if (isWindows())
065                {
066                        x = -4;
067                        y = -4;
068                        w = screenX - 2*x;
069                        h = screenY - 2*y;
070                }
071                else
072                {
073                        x = 0;
074                        y = 0;
075                        w = screenX;
076                        h = screenY;
077                }
078                
079                return new Rectangle(x,y,w,h);
080        } //}}}
081
082        //{{{ getScreenBounds() method
083        /**
084         * Returns the bounds of the (virtual) screen that the window should be in
085         * @param window The bounds of the window to get the screen for
086         */
087        public static final Rectangle getScreenBounds(Rectangle window)
088        {
089                GraphicsDevice[] gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
090                Vector intersects = new Vector();
091                
092                // Get available screens
093                // O(n^3), this is nasty, but since we aren't dealling with
094                // many items it should be fine
095                for (int i=0; i < gd.length; i++)
096                {
097                        GraphicsConfiguration[] gc = gd[i].getConfigurations();
098L2:                     for (int j=0; j < gc.length; j++)
099                        {
100                                // Don't add duplicates
101                                if (window.intersects(gc[j].getBounds()))
102                                {
103                                        for (Enumeration e = intersects.elements(); e.hasMoreElements();)
104                                        {
105                                                GraphicsConfiguration gcc = (GraphicsConfiguration)e.nextElement();
106                                                if (gcc.getBounds().equals(gc[j].getBounds()))
107                                                        continue L2;
108                                        }
109                                        intersects.add(gc[j]);
110                                }
111                        }
112                }
113                
114                GraphicsConfiguration choice = null;
115                if (intersects.size() > 0)
116                {
117                        // Pick screen with largest intersection
118                        for (Enumeration e = intersects.elements(); e.hasMoreElements();)
119                        {
120                                GraphicsConfiguration gcc = (GraphicsConfiguration)e.nextElement();
121                                if (choice == null)
122                                        choice = gcc;
123                                else
124                                {
125                                        Rectangle int1 = choice.getBounds().intersection(window);
126                                        Rectangle int2 = gcc.getBounds().intersection(window);
127                                        int area1 = int1.width * int1.height;
128                                        int area2 = int2.width * int2.height;
129                                        if (area2 > area1)
130                                                choice = gcc;
131                                }
132                        }
133                }
134                else
135                        choice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
136                
137                // Make adjustments for some OS's
138                int screenX = (int)choice.getBounds().x;
139                int screenY = (int)choice.getBounds().y;
140                int screenW = (int)choice.getBounds().width;
141                int screenH = (int)choice.getBounds().height;
142                int x, y, w, h;
143                
144                if (isMacOS())
145                {
146                        x = screenX;
147                        y = screenY + 22;
148                        w = screenW;
149                        h = screenH - y - 4;//shadow size
150                }
151                else if (isWindows())
152                {
153                        x = screenX - 4;
154                        y = screenY - 4;
155                        w = screenW - 2*x;
156                        h = screenH - 2*y;
157                }
158                else
159                {
160                        x = screenX;
161                        y = screenY;
162                        w = screenW;
163                        h = screenH;
164                }
165                
166                // Yay, we're finally there
167                return new Rectangle(x,y,w,h);
168        } //}}}
169
170        
171        //{{{ isDOSDerived() method
172        /**
173         * Returns if we're running Windows 95/98/ME/NT/2000/XP, or OS/2.
174         */
175        public static final boolean isDOSDerived()
176        {
177                return isWindows() || isOS2();
178        } //}}}
179
180        
181        //{{{ isWindows() method
182        /**
183         * Returns if we're running Windows 95/98/ME/NT/2000/XP.
184         */
185        public static final boolean isWindows()
186        {
187                return os == WINDOWS_9x || os == WINDOWS_NT;
188        } //}}}
189
190        
191        //{{{ isWindows9x() method
192        /**
193         * Returns if we're running Windows 95/98/ME.
194         */
195        public static final boolean isWindows9x()
196        {
197                return os == WINDOWS_9x;
198        } //}}}
199
200        
201        //{{{ isWindowsNT() method
202        /**
203         * Returns if we're running Windows NT/2000/XP.
204         */
205        public static final boolean isWindowsNT()
206        {
207                return os == WINDOWS_NT;
208        } //}}}
209
210        
211        //{{{ isOS2() method
212        /**
213         * Returns if we're running OS/2.
214         */
215        public static final boolean isOS2()
216        {
217                return os == OS2;
218        } //}}}
219
220        
221        //{{{ isUnix() method
222        /**
223         * Returns if we're running Unix (this includes MacOS X).
224         */
225        public static final boolean isUnix()
226        {
227                return os == UNIX || os == MAC_OS_X;
228        } //}}}
229
230        
231        //{{{ isMacOS() method
232        /**
233         * Returns if we're running MacOS X.
234         */
235        public static final boolean isMacOS()
236        {
237                return os == MAC_OS_X;
238        } //}}}
239
240        
241        //{{{ isX11() method
242        /**
243         * Returns if this OS is likely to be using X11 as the graphics
244         * system.
245         * @since jEdit 4.2pre3
246         */
247        public static boolean isX11()
248        {
249                return os == UNIX;
250        } //}}}
251
252        
253        //{{{ isVMS() method
254        /**
255         * Returns if we're running VMS.
256         */
257        public static final boolean isVMS()
258        {
259                return os == VMS;
260        } //}}}
261
262        
263        //{{{ isMacOSLF() method
264        /**
265        * Returns if we're running MacOS X and using the native look and feel.
266        */
267        public static final boolean isMacOSLF()
268        {
269                return (isMacOS() && UIManager.getLookAndFeel().isNativeLookAndFeel());
270        } //}}}
271
272        
273        //{{{ hasScreenMenuBar
274        /**
275         * Returns whether the screen menu bar on Mac OS X is in use.
276         * @since jEdit 4.2pre1
277        */
278        public static final boolean hasScreenMenuBar()
279        {
280                if(!isMacOS())
281                        return false;
282                else if(hasScreenMenuBar == -1)
283                {
284                        String result = System.getProperty("apple.laf.useScreenMenuBar");
285                        if (result == null)
286                                result = System.getProperty("com.apple.macos.useScreenMenuBar");
287                        hasScreenMenuBar = ("true".equals(result)) ? 1 : 0;
288                }
289
290                return (hasScreenMenuBar == 1);
291        } //}}}
292
293        //{{{ isJava14() method
294        /**
295         * Returns if Java 2 version 1.4 is in use.
296         */
297        public static final boolean hasJava14()
298        {
299                return java14;
300        } //}}}
301
302        
303        //{{{ Private members
304        private static final int UNIX = 0x31337;
305        private static final int WINDOWS_9x = 0x640;
306        private static final int WINDOWS_NT = 0x666;
307        private static final int OS2 = 0xDEAD;
308        private static final int MAC_OS_X = 0xABC;
309        private static final int VMS = 0xDEAD2;
310        private static final int UNKNOWN = 0xBAD;
311
312        private static int os;
313        private static boolean java14;
314        private static int hasScreenMenuBar = -1;
315
316        //{{{ Class initializer
317        static
318        {
319                if(System.getProperty("mrj.version") != null)
320                {
321                        os = MAC_OS_X;
322                }
323                else
324                {
325                        String osName = System.getProperty("os.name");
326                        if(osName.indexOf("Windows 9") != -1
327                                || osName.indexOf("Windows M") != -1)
328                        {
329                                os = WINDOWS_9x;
330                        }
331                        else if(osName.indexOf("Windows") != -1)
332                        {
333                                os = WINDOWS_NT;
334                        }
335                        else if(osName.indexOf("OS/2") != -1)
336                        {
337                                os = OS2;
338                        }
339                        else if(osName.indexOf("VMS") != -1)
340                        {
341                                os = VMS;
342                        }
343                        else if(File.separatorChar == '/')
344                        {
345                                os = UNIX;
346                        }
347                        else
348                        {
349                                os = UNKNOWN;
350                                /*Log.log(Log.WARNING,OperatingSystem.class,
351                                        "Unknown operating system: " + osName);*/
352                        }
353                }
354
355                if(System.getProperty("java.version").compareTo("1.4") >= 0
356                        && System.getProperty("jedit.nojava14") == null)
357                        java14 = true;
358        } //}}}
359
360        //}}}
361}