Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java
32288 views
/*1* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package sun.awt.X11;2526import java.awt.AWTEvent;27import java.awt.AWTException;28import java.awt.BufferCapabilities;29import java.awt.Color;30import java.awt.Component;31import java.awt.Container;32import java.awt.Cursor;33import java.awt.Dimension;34import java.awt.Font;35import java.awt.FontMetrics;36import java.awt.Graphics;37import java.awt.GraphicsConfiguration;38import java.awt.Image;39import java.awt.Insets;40import java.awt.Rectangle;41import java.awt.SystemColor;42import java.awt.Toolkit;43import java.awt.Window;44import java.awt.dnd.DropTarget;45import java.awt.dnd.peer.DropTargetPeer;46import java.awt.event.FocusEvent;47import java.awt.event.InputEvent;48import java.awt.event.InputMethodEvent;49import java.awt.event.KeyEvent;50import java.awt.event.MouseEvent;51import java.awt.event.MouseWheelEvent;52import java.awt.event.PaintEvent;53import java.awt.event.WindowEvent;54import java.awt.event.InvocationEvent;55import java.awt.image.ImageObserver;56import java.awt.image.ImageProducer;57import java.awt.image.VolatileImage;58import java.awt.peer.ComponentPeer;59import java.awt.peer.ContainerPeer;60import java.lang.reflect.*;61import java.security.*;62import java.util.Collection;63import java.util.Objects;64import java.util.Set;65import sun.util.logging.PlatformLogger;66import sun.awt.*;67import sun.awt.event.IgnorePaintEvent;68import sun.awt.image.SunVolatileImage;69import sun.awt.image.ToolkitImage;70import sun.java2d.BackBufferCapsProvider;71import sun.java2d.pipe.Region;727374public class XComponentPeer extends XWindow implements ComponentPeer, DropTargetPeer,75BackBufferCapsProvider76{77private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XComponentPeer");78private static final PlatformLogger buffersLog = PlatformLogger.getLogger("sun.awt.X11.XComponentPeer.multibuffer");79private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XComponentPeer");80private static final PlatformLogger fontLog = PlatformLogger.getLogger("sun.awt.X11.font.XComponentPeer");81private static final PlatformLogger enableLog = PlatformLogger.getLogger("sun.awt.X11.enable.XComponentPeer");82private static final PlatformLogger shapeLog = PlatformLogger.getLogger("sun.awt.X11.shape.XComponentPeer");8384boolean paintPending = false;85boolean isLayouting = false;86private boolean enabled;8788// Actually used only by XDecoratedPeer89protected int boundsOperation;9091Color foreground;92Color background;9394// Colors calculated as on Motif using MotifColorUtilties.95// If you use these, call updateMotifColors() in the peer's Constructor and96// setBackground(). Examples are XCheckboxPeer and XButtonPeer.97Color darkShadow;98Color lightShadow;99Color selectColor;100101Font font;102private long backBuffer = 0;103private VolatileImage xBackBuffer = null;104105static Color[] systemColors;106107XComponentPeer() {108}109110XComponentPeer (XCreateWindowParams params) {111super(params);112}113114XComponentPeer(Component target, long parentWindow, Rectangle bounds) {115super(target, parentWindow, bounds);116}117118/**119* Standard peer constructor, with corresponding Component120*/121XComponentPeer(Component target) {122super(target);123}124125126void preInit(XCreateWindowParams params) {127super.preInit(params);128boundsOperation = DEFAULT_OPERATION;129}130void postInit(XCreateWindowParams params) {131super.postInit(params);132133pSetCursor(target.getCursor());134135foreground = target.getForeground();136background = target.getBackground();137font = target.getFont();138139if (isInitialReshape()) {140Rectangle r = target.getBounds();141reshape(r.x, r.y, r.width, r.height);142}143144setEnabled(target.isEnabled());145146if (target.isVisible()) {147setVisible(true);148}149}150151protected boolean isInitialReshape() {152return true;153}154155public void reparent(ContainerPeer newNativeParent) {156XComponentPeer newPeer = (XComponentPeer)newNativeParent;157XToolkit.awtLock();158try {159XlibWrapper.XReparentWindow(XToolkit.getDisplay(), getWindow(), newPeer.getContentWindow(), x, y);160parentWindow = newPeer;161} finally {162XToolkit.awtUnlock();163}164}165public boolean isReparentSupported() {166return System.getProperty("sun.awt.X11.XComponentPeer.reparentNotSupported", "false").equals("false");167}168169public boolean isObscured() {170Container container = (target instanceof Container) ?171(Container)target : target.getParent();172173if (container == null) {174return true;175}176177Container parent;178while ((parent = container.getParent()) != null) {179container = parent;180}181182if (container instanceof Window) {183XWindowPeer wpeer = (XWindowPeer)(container.getPeer());184if (wpeer != null) {185return (wpeer.winAttr.visibilityState !=186wpeer.winAttr.AWT_UNOBSCURED);187}188}189return true;190}191192public boolean canDetermineObscurity() {193return true;194}195196/*************************************************197* FOCUS STUFF198*************************************************/199200/**201* Keeps the track of focused state of the _NATIVE_ window202*/203boolean bHasFocus = false;204205/**206* Descendants should use this method to determine whether or not native window207* has focus.208*/209final public boolean hasFocus() {210return bHasFocus;211}212213/**214* Called when component receives focus215*/216public void focusGained(FocusEvent e) {217if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {218focusLog.fine("{0}", e);219}220bHasFocus = true;221}222223/**224* Called when component loses focus225*/226public void focusLost(FocusEvent e) {227if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {228focusLog.fine("{0}", e);229}230bHasFocus = false;231}232233public boolean isFocusable() {234/* should be implemented by other sub-classes */235return false;236}237238private static Class seClass;239private static Constructor seCtor;240241final static AWTEvent wrapInSequenced(AWTEvent event) {242try {243if (seClass == null) {244seClass = Class.forName("java.awt.SequencedEvent");245}246247if (seCtor == null) {248seCtor = (Constructor) AccessController.doPrivileged(new PrivilegedExceptionAction() {249public Object run() throws Exception {250Constructor ctor = seClass.getConstructor(new Class[] { AWTEvent.class });251ctor.setAccessible(true);252return ctor;253}254});255}256257return (AWTEvent) seCtor.newInstance(new Object[] { event });258}259catch (ClassNotFoundException e) {260throw new NoClassDefFoundError("java.awt.SequencedEvent.");261}262catch (PrivilegedActionException ex) {263throw new NoClassDefFoundError("java.awt.SequencedEvent.");264}265catch (InstantiationException e) {266assert false;267}268catch (IllegalAccessException e) {269assert false;270}271catch (InvocationTargetException e) {272assert false;273}274275return null;276}277278// TODO: consider moving it to KeyboardFocusManagerPeerImpl279final public boolean requestFocus(Component lightweightChild, boolean temporary,280boolean focusedWindowChangeAllowed, long time,281CausedFocusEvent.Cause cause)282{283if (XKeyboardFocusManagerPeer.284processSynchronousLightweightTransfer(target, lightweightChild, temporary,285focusedWindowChangeAllowed, time))286{287return true;288}289290int result = XKeyboardFocusManagerPeer.291shouldNativelyFocusHeavyweight(target, lightweightChild,292temporary, focusedWindowChangeAllowed,293time, cause);294295switch (result) {296case XKeyboardFocusManagerPeer.SNFH_FAILURE:297return false;298case XKeyboardFocusManagerPeer.SNFH_SUCCESS_PROCEED:299// Currently we just generate focus events like we deal with lightweight instead of calling300// XSetInputFocus on native window301if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {302focusLog.finer("Proceeding with request to " +303lightweightChild + " in " + target);304}305/**306* The problems with requests in non-focused window arise because shouldNativelyFocusHeavyweight307* checks that native window is focused while appropriate WINDOW_GAINED_FOCUS has not yet308* been processed - it is in EventQueue. Thus, SNFH allows native request and stores request record309* in requests list - and it breaks our requests sequence as first record on WGF should be the last310* focus owner which had focus before WLF. So, we should not add request record for such requests311* but store this component in mostRecent - and return true as before for compatibility.312*/313Window parentWindow = SunToolkit.getContainingWindow(target);314if (parentWindow == null) {315return rejectFocusRequestHelper("WARNING: Parent window is null");316}317XWindowPeer wpeer = (XWindowPeer)parentWindow.getPeer();318if (wpeer == null) {319return rejectFocusRequestHelper("WARNING: Parent window's peer is null");320}321/*322* Passing null 'actualFocusedWindow' as we don't want to restore focus on it323* when a component inside a Frame is requesting focus.324* See 6314575 for details.325*/326boolean res = wpeer.requestWindowFocus(null);327328if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {329focusLog.finer("Requested window focus: " + res);330}331// If parent window can be made focused and has been made focused(synchronously)332// then we can proceed with children, otherwise we retreat.333if (!(res && parentWindow.isFocused())) {334return rejectFocusRequestHelper("Waiting for asynchronous processing of the request");335}336return XKeyboardFocusManagerPeer.deliverFocus(lightweightChild,337(Component)target,338temporary,339focusedWindowChangeAllowed,340time, cause);341// Motif compatibility code342case XKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:343// Either lightweight or excessive request - all events are generated.344return true;345}346return false;347}348349private boolean rejectFocusRequestHelper(String logMsg) {350if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {351focusLog.finer(logMsg);352}353XKeyboardFocusManagerPeer.removeLastFocusRequest(target);354return false;355}356357void handleJavaFocusEvent(AWTEvent e) {358if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {359focusLog.finer(e.toString());360}361if (e.getID() == FocusEvent.FOCUS_GAINED) {362focusGained((FocusEvent)e);363} else {364focusLost((FocusEvent)e);365}366}367368void handleJavaWindowFocusEvent(AWTEvent e) {369}370371/*************************************************372* END OF FOCUS STUFF373*************************************************/374375376377public void setVisible(boolean b) {378xSetVisible(b);379}380381public void hide() {382setVisible(false);383}384385/**386* @see java.awt.peer.ComponentPeer387*/388public void setEnabled(final boolean value) {389if (enableLog.isLoggable(PlatformLogger.Level.FINE)) {390enableLog.fine("{0}ing {1}", (value ? "Enabl" : "Disabl"), this);391}392boolean status = value;393// If any of our heavyweight ancestors are disable, we should be too394// See 6176875 for more information395final Container cp = SunToolkit.getNativeContainer(target);396if (cp != null) {397status &= ((XComponentPeer) cp.getPeer()).isEnabled();398}399synchronized (getStateLock()) {400if (enabled == status) {401return;402}403enabled = status;404}405406if (target instanceof Container) {407final Component[] list = ((Container) target).getComponents();408for (final Component child : list) {409final ComponentPeer p = child.getPeer();410if (p != null) {411p.setEnabled(status && child.isEnabled());412}413}414}415repaint();416}417418//419// public so aw/Window can call it420//421public final boolean isEnabled() {422synchronized (getStateLock()) {423return enabled;424}425}426427@Override428public void paint(final Graphics g) {429super.paint(g);430// allow target to change the picture431target.paint(g);432}433434public Graphics getGraphics() {435return getGraphics(surfaceData, getPeerForeground(), getPeerBackground(), getPeerFont());436}437public void print(Graphics g) {438// clear rect here to emulate X clears rect before Expose439g.setColor(target.getBackground());440g.fillRect(0, 0, target.getWidth(), target.getHeight());441g.setColor(target.getForeground());442// paint peer443paintPeer(g);444// allow target to change the picture445target.print(g);446}447448public void setBounds(int x, int y, int width, int height, int op) {449this.x = x;450this.y = y;451this.width = width;452this.height = height;453xSetBounds(x,y,width,height);454validateSurface();455layout();456}457458public void reshape(int x, int y, int width, int height) {459setBounds(x, y, width, height, SET_BOUNDS);460}461462public void coalescePaintEvent(PaintEvent e) {463Rectangle r = e.getUpdateRect();464if (!(e instanceof IgnorePaintEvent)) {465paintArea.add(r, e.getID());466}467if (true) {468switch(e.getID()) {469case PaintEvent.UPDATE:470if (log.isLoggable(PlatformLogger.Level.FINER)) {471log.finer("XCP coalescePaintEvent : UPDATE : add : x = " +472r.x + ", y = " + r.y + ", width = " + r.width + ",height = " + r.height);473}474return;475case PaintEvent.PAINT:476if (log.isLoggable(PlatformLogger.Level.FINER)) {477log.finer("XCP coalescePaintEvent : PAINT : add : x = " +478r.x + ", y = " + r.y + ", width = " + r.width + ",height = " + r.height);479}480return;481}482}483}484485XWindowPeer getParentTopLevel() {486AWTAccessor.ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor();487Container parent = (target instanceof Container) ? ((Container)target) : (compAccessor.getParent(target));488// Search for parent window489while (parent != null && !(parent instanceof Window)) {490parent = compAccessor.getParent(parent);491}492if (parent != null) {493return (XWindowPeer)compAccessor.getPeer(parent);494} else {495return null;496}497}498499/* This method is intended to be over-ridden by peers to perform user interaction */500void handleJavaMouseEvent(MouseEvent e) {501switch (e.getID()) {502case MouseEvent.MOUSE_PRESSED:503if (target == e.getSource() &&504!target.isFocusOwner() &&505XKeyboardFocusManagerPeer.shouldFocusOnClick(target))506{507XWindowPeer parentXWindow = getParentTopLevel();508Window parentWindow = ((Window)parentXWindow.getTarget());509// Simple windows are non-focusable in X terms but focusable in Java terms.510// As X-non-focusable they don't receive any focus events - we should generate them511// by ourselfves.512// if (parentXWindow.isFocusableWindow() /*&& parentXWindow.isSimpleWindow()*/ &&513// !(getCurrentNativeFocusedWindow() == parentWindow))514// {515// setCurrentNativeFocusedWindow(parentWindow);516// WindowEvent wfg = new WindowEvent(parentWindow, WindowEvent.WINDOW_GAINED_FOCUS);517// parentWindow.dispatchEvent(wfg);518// }519XKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT);520}521break;522}523}524525/* This method is intended to be over-ridden by peers to perform user interaction */526void handleJavaKeyEvent(KeyEvent e) {527}528529/* This method is intended to be over-ridden by peers to perform user interaction */530void handleJavaMouseWheelEvent(MouseWheelEvent e) {531}532533534/* This method is intended to be over-ridden by peers to perform user interaction */535void handleJavaInputMethodEvent(InputMethodEvent e) {536}537538void handleF10JavaKeyEvent(KeyEvent e) {539if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_F10) {540XWindowPeer winPeer = this.getToplevelXWindow();541if (winPeer instanceof XFramePeer) {542XMenuBarPeer mPeer = ((XFramePeer)winPeer).getMenubarPeer();543if (mPeer != null) {544mPeer.handleF10KeyPress(e);545}546}547}548}549550public void handleEvent(java.awt.AWTEvent e) {551if ((e instanceof InputEvent) && !((InputEvent)e).isConsumed() && target.isEnabled()) {552if (e instanceof MouseEvent) {553if (e instanceof MouseWheelEvent) {554handleJavaMouseWheelEvent((MouseWheelEvent) e);555}556else557handleJavaMouseEvent((MouseEvent) e);558}559else if (e instanceof KeyEvent) {560handleF10JavaKeyEvent((KeyEvent)e);561handleJavaKeyEvent((KeyEvent)e);562}563}564else if (e instanceof KeyEvent && !((InputEvent)e).isConsumed()) {565// even if target is disabled.566handleF10JavaKeyEvent((KeyEvent)e);567}568else if (e instanceof InputMethodEvent) {569handleJavaInputMethodEvent((InputMethodEvent) e);570}571572int id = e.getID();573574switch(id) {575case PaintEvent.PAINT:576// Got native painting577paintPending = false;578// Fallthrough to next statement579case PaintEvent.UPDATE:580// Skip all painting while layouting and all UPDATEs581// while waiting for native paint582if (!isLayouting && !paintPending) {583paintArea.paint(target,false);584}585return;586case FocusEvent.FOCUS_LOST:587case FocusEvent.FOCUS_GAINED:588handleJavaFocusEvent(e);589break;590case WindowEvent.WINDOW_LOST_FOCUS:591case WindowEvent.WINDOW_GAINED_FOCUS:592handleJavaWindowFocusEvent(e);593break;594default:595break;596}597598}599600public Dimension getMinimumSize() {601return target.getSize();602}603604public Dimension getPreferredSize() {605return getMinimumSize();606}607608public void layout() {}609610void updateMotifColors(Color bg) {611int red = bg.getRed();612int green = bg.getGreen();613int blue = bg.getBlue();614615darkShadow = new Color(MotifColorUtilities.calculateBottomShadowFromBackground(red,green,blue));616lightShadow = new Color(MotifColorUtilities.calculateTopShadowFromBackground(red,green,blue));617selectColor= new Color(MotifColorUtilities.calculateSelectFromBackground(red,green,blue));618}619620/*621* Draw a 3D rectangle using the Motif colors.622* "Normal" rectangles have shadows on the bottom.623* "Depressed" rectangles (such as pressed buttons) have shadows on the top,624* in which case true should be passed for topShadow.625*/626public void drawMotif3DRect(Graphics g,627int x, int y, int width, int height,628boolean topShadow) {629g.setColor(topShadow ? darkShadow : lightShadow);630g.drawLine(x, y, x+width, y); // top631g.drawLine(x, y+height, x, y); // left632633g.setColor(topShadow ? lightShadow : darkShadow );634g.drawLine(x+1, y+height, x+width, y+height); // bottom635g.drawLine(x+width, y+height, x+width, y+1); // right636}637638@Override639public void setBackground(Color c) {640if (log.isLoggable(PlatformLogger.Level.FINE)) {641log.fine("Set background to " + c);642}643synchronized (getStateLock()) {644if (Objects.equals(background, c)) {645return;646}647background = c;648}649super.setBackground(c);650repaint();651}652653@Override654public void setForeground(Color c) {655if (log.isLoggable(PlatformLogger.Level.FINE)) {656log.fine("Set foreground to " + c);657}658synchronized (getStateLock()) {659if (Objects.equals(foreground, c)) {660return;661}662foreground = c;663}664repaint();665}666667/**668* Gets the font metrics for the specified font.669* @param font the font for which font metrics is to be670* obtained671* @return the font metrics for <code>font</code>672* @see #getFont673* @see #getPeer674* @see java.awt.peer.ComponentPeer#getFontMetrics(Font)675* @see Toolkit#getFontMetrics(Font)676* @since JDK1.0677*/678public FontMetrics getFontMetrics(Font font) {679if (fontLog.isLoggable(PlatformLogger.Level.FINE)) {680fontLog.fine("Getting font metrics for " + font);681}682return sun.font.FontDesignMetrics.getMetrics(font);683}684685@Override686public void setFont(Font f) {687if (f == null) {688f = XWindow.getDefaultFont();689}690synchronized (getStateLock()) {691if (f.equals(font)) {692return;693}694font = f;695}696// as it stands currently we don't need to do layout since697// layout is done in the Component upon setFont.698//layout();699repaint();700}701702public Font getFont() {703return font;704}705706public void updateCursorImmediately() {707XGlobalCursorManager.getCursorManager().updateCursorImmediately();708}709710public final void pSetCursor(Cursor cursor) {711this.pSetCursor(cursor, true);712}713714/*715* The method changes the cursor.716* @param cursor - a new cursor to change to.717* @param ignoreSubComponents - if {@code true} is passed then718* the new cursor will be installed on window.719* if {@code false} is passed then720* subsequent components will try to handle721* this request and install their cursor.722*/723//ignoreSubComponents not used here724public void pSetCursor(Cursor cursor, boolean ignoreSubComponents) {725XToolkit.awtLock();726try {727long xcursor = XGlobalCursorManager.getCursor(cursor);728729XSetWindowAttributes xwa = new XSetWindowAttributes();730xwa.set_cursor(xcursor);731732long valuemask = XConstants.CWCursor;733734XlibWrapper.XChangeWindowAttributes(XToolkit.getDisplay(),getWindow(),valuemask,xwa.pData);735XlibWrapper.XFlush(XToolkit.getDisplay());736xwa.dispose();737} finally {738XToolkit.awtUnlock();739}740}741742public Image createImage(ImageProducer producer) {743return new ToolkitImage(producer);744}745746public Image createImage(int width, int height) {747return graphicsConfig.createAcceleratedImage(target, width, height);748}749750public VolatileImage createVolatileImage(int width, int height) {751return new SunVolatileImage(target, width, height);752}753754public boolean prepareImage(Image img, int w, int h, ImageObserver o) {755return Toolkit.getDefaultToolkit().prepareImage(img, w, h, o);756}757758public int checkImage(Image img, int w, int h, ImageObserver o) {759return Toolkit.getDefaultToolkit().checkImage(img, w, h, o);760}761762public Dimension preferredSize() {763return getPreferredSize();764}765766public Dimension minimumSize() {767return getMinimumSize();768}769770public Insets getInsets() {771return new Insets(0, 0, 0, 0);772}773774public void beginValidate() {775}776777public void endValidate() {778}779780781/**782* DEPRECATED: Replaced by getInsets().783*/784785public Insets insets() {786return getInsets();787}788789// Returns true if we are inside begin/endLayout and790// are waiting for native painting791public boolean isPaintPending() {792return paintPending && isLayouting;793}794795public boolean handlesWheelScrolling() {796return false;797}798799public void beginLayout() {800// Skip all painting till endLayout801isLayouting = true;802803}804805public void endLayout() {806if (!paintPending && !paintArea.isEmpty()807&& !AWTAccessor.getComponentAccessor().getIgnoreRepaint(target))808{809// if not waiting for native painting repaint damaged area810postEvent(new PaintEvent(target, PaintEvent.PAINT,811new Rectangle()));812}813isLayouting = false;814}815816public Color getWinBackground() {817return getPeerBackground();818}819820static int[] getRGBvals(Color c) {821822int rgbvals[] = new int[3];823824rgbvals[0] = c.getRed();825rgbvals[1] = c.getGreen();826rgbvals[2] = c.getBlue();827828return rgbvals;829}830831static final int BACKGROUND_COLOR = 0;832static final int HIGHLIGHT_COLOR = 1;833static final int SHADOW_COLOR = 2;834static final int FOREGROUND_COLOR = 3;835836public Color[] getGUIcolors() {837Color c[] = new Color[4];838float backb, highb, shadowb, hue, saturation;839c[BACKGROUND_COLOR] = getWinBackground();840if (c[BACKGROUND_COLOR] == null) {841c[BACKGROUND_COLOR] = super.getWinBackground();842}843if (c[BACKGROUND_COLOR] == null) {844c[BACKGROUND_COLOR] = Color.lightGray;845}846847int[] rgb = getRGBvals(c[BACKGROUND_COLOR]);848849float[] hsb = Color.RGBtoHSB(rgb[0],rgb[1],rgb[2],null);850851hue = hsb[0];852saturation = hsb[1];853backb = hsb[2];854855856/* Calculate Highlight Brightness */857858highb = backb + 0.2f;859shadowb = backb - 0.4f;860if ((highb > 1.0) ) {861if ((1.0 - backb) < 0.05) {862highb = shadowb + 0.25f;863} else {864highb = 1.0f;865}866} else {867if (shadowb < 0.0) {868if ((backb - 0.0) < 0.25) {869highb = backb + 0.75f;870shadowb = highb - 0.2f;871} else {872shadowb = 0.0f;873}874}875}876c[HIGHLIGHT_COLOR] = Color.getHSBColor(hue,saturation,highb);877c[SHADOW_COLOR] = Color.getHSBColor(hue,saturation,shadowb);878879880/*881c[SHADOW_COLOR] = c[BACKGROUND_COLOR].darker();882int r2 = c[SHADOW_COLOR].getRed();883int g2 = c[SHADOW_COLOR].getGreen();884int b2 = c[SHADOW_COLOR].getBlue();885*/886887c[FOREGROUND_COLOR] = getPeerForeground();888if (c[FOREGROUND_COLOR] == null) {889c[FOREGROUND_COLOR] = Color.black;890}891/*892if ((c[BACKGROUND_COLOR].equals(c[HIGHLIGHT_COLOR]))893&& (c[BACKGROUND_COLOR].equals(c[SHADOW_COLOR]))) {894c[SHADOW_COLOR] = new Color(c[BACKGROUND_COLOR].getRed() + 75,895c[BACKGROUND_COLOR].getGreen() + 75,896c[BACKGROUND_COLOR].getBlue() + 75);897c[HIGHLIGHT_COLOR] = c[SHADOW_COLOR].brighter();898} else if (c[BACKGROUND_COLOR].equals(c[HIGHLIGHT_COLOR])) {899c[HIGHLIGHT_COLOR] = c[SHADOW_COLOR];900c[SHADOW_COLOR] = c[SHADOW_COLOR].darker();901}902*/903if (! isEnabled()) {904c[BACKGROUND_COLOR] = c[BACKGROUND_COLOR].darker();905// Reduce the contrast906// Calculate the NTSC gray (NB: REC709 L* might be better!)907// for foreground and background; then multiply the foreground908// by the average lightness909910911Color tc = c[BACKGROUND_COLOR];912int bg = tc.getRed() * 30 + tc.getGreen() * 59 + tc.getBlue() * 11;913914tc = c[FOREGROUND_COLOR];915int fg = tc.getRed() * 30 + tc.getGreen() * 59 + tc.getBlue() * 11;916917float ave = (float) ((fg + bg) / 51000.0);918// 255 * 100 * 2919920Color newForeground = new Color((int) (tc.getRed() * ave),921(int) (tc.getGreen() * ave),922(int) (tc.getBlue() * ave));923924if (newForeground.equals(c[FOREGROUND_COLOR])) {925// This probably means the foreground color is black or white926newForeground = new Color(ave, ave, ave);927}928c[FOREGROUND_COLOR] = newForeground;929930}931932933return c;934}935936/**937* Returns an array of Colors similar to getGUIcolors(), but using the938* System colors. This is useful if pieces of a Component (such as939* the integrated scrollbars of a List) should retain the System color940* instead of the background color set by Component.setBackground().941*/942static Color[] getSystemColors() {943if (systemColors == null) {944systemColors = new Color[4];945systemColors[BACKGROUND_COLOR] = SystemColor.window;946systemColors[HIGHLIGHT_COLOR] = SystemColor.controlLtHighlight;947systemColors[SHADOW_COLOR] = SystemColor.controlShadow;948systemColors[FOREGROUND_COLOR] = SystemColor.windowText;949}950return systemColors;951}952953/**954* Draw a 3D oval.955*/956public void draw3DOval(Graphics g, Color colors[],957int x, int y, int w, int h, boolean raised)958{959Color c = g.getColor();960g.setColor(raised ? colors[HIGHLIGHT_COLOR] : colors[SHADOW_COLOR]);961g.drawArc(x, y, w, h, 45, 180);962g.setColor(raised ? colors[SHADOW_COLOR] : colors[HIGHLIGHT_COLOR]);963g.drawArc(x, y, w, h, 225, 180);964g.setColor(c);965}966967public void draw3DRect(Graphics g, Color colors[],968int x, int y, int width, int height, boolean raised)969{970Color c = g.getColor();971g.setColor(raised ? colors[HIGHLIGHT_COLOR] : colors[SHADOW_COLOR]);972g.drawLine(x, y, x, y + height);973g.drawLine(x + 1, y, x + width - 1, y);974g.setColor(raised ? colors[SHADOW_COLOR] : colors[HIGHLIGHT_COLOR]);975g.drawLine(x + 1, y + height, x + width, y + height);976g.drawLine(x + width, y, x + width, y + height - 1);977g.setColor(c);978}979980/*981* drawXXX() methods are used to print the native components by982* rendering the Motif look ourselves.983* ToDo(aim): needs to query native motif for more accurate color984* information.985*/986void draw3DOval(Graphics g, Color bg,987int x, int y, int w, int h, boolean raised)988{989Color c = g.getColor();990Color shadow = bg.darker();991Color highlight = bg.brighter();992993g.setColor(raised ? highlight : shadow);994g.drawArc(x, y, w, h, 45, 180);995g.setColor(raised ? shadow : highlight);996g.drawArc(x, y, w, h, 225, 180);997g.setColor(c);998}9991000void draw3DRect(Graphics g, Color bg,1001int x, int y, int width, int height,1002boolean raised) {1003Color c = g.getColor();1004Color shadow = bg.darker();1005Color highlight = bg.brighter();10061007g.setColor(raised ? highlight : shadow);1008g.drawLine(x, y, x, y + height);1009g.drawLine(x + 1, y, x + width - 1, y);1010g.setColor(raised ? shadow : highlight);1011g.drawLine(x + 1, y + height, x + width, y + height);1012g.drawLine(x + width, y, x + width, y + height - 1);1013g.setColor(c);1014}10151016void drawScrollbar(Graphics g, Color bg, int thickness, int length,1017int min, int max, int val, int vis, boolean horizontal) {1018Color c = g.getColor();1019double f = (double)(length - 2*(thickness-1)) / Math.max(1, ((max - min) + vis));1020int v1 = thickness + (int)(f * (val - min));1021int v2 = (int)(f * vis);1022int w2 = thickness-4;1023int tpts_x[] = new int[3];1024int tpts_y[] = new int[3];10251026if (length < 3*w2 ) {1027v1 = v2 = 0;1028if (length < 2*w2 + 2) {1029w2 = (length-2)/2;1030}1031} else if (v2 < 7) {1032// enforce a minimum handle size1033v1 = Math.max(0, v1 - ((7 - v2)>>1));1034v2 = 7;1035}10361037int ctr = thickness/2;1038int sbmin = ctr - w2/2;1039int sbmax = ctr + w2/2;10401041// paint the background slightly darker1042{1043Color d = new Color((int) (bg.getRed() * 0.85),1044(int) (bg.getGreen() * 0.85),1045(int) (bg.getBlue() * 0.85));10461047g.setColor(d);1048if (horizontal) {1049g.fillRect(0, 0, length, thickness);1050} else {1051g.fillRect(0, 0, thickness, length);1052}1053}10541055// paint the thumb and arrows in the normal background color1056g.setColor(bg);1057if (v1 > 0) {1058if (horizontal) {1059g.fillRect(v1, 3, v2, thickness-3);1060} else {1061g.fillRect(3, v1, thickness-3, v2);1062}1063}10641065tpts_x[0] = ctr; tpts_y[0] = 2;1066tpts_x[1] = sbmin; tpts_y[1] = w2;1067tpts_x[2] = sbmax; tpts_y[2] = w2;1068if (horizontal) {1069g.fillPolygon(tpts_y, tpts_x, 3);1070} else {1071g.fillPolygon(tpts_x, tpts_y, 3);1072}10731074tpts_y[0] = length-2;1075tpts_y[1] = length-w2;1076tpts_y[2] = length-w2;1077if (horizontal) {1078g.fillPolygon(tpts_y, tpts_x, 3);1079} else {1080g.fillPolygon(tpts_x, tpts_y, 3);1081}10821083Color highlight = bg.brighter();10841085// // // // draw the "highlighted" edges1086g.setColor(highlight);10871088// outline & arrows1089if (horizontal) {1090g.drawLine(1, thickness, length - 1, thickness);1091g.drawLine(length - 1, 1, length - 1, thickness);10921093// arrows1094g.drawLine(1, ctr, w2, sbmin);1095g.drawLine(length - w2, sbmin, length - w2, sbmax);1096g.drawLine(length - w2, sbmin, length - 2, ctr);10971098} else {1099g.drawLine(thickness, 1, thickness, length - 1);1100g.drawLine(1, length - 1, thickness, length - 1);11011102// arrows1103g.drawLine(ctr, 1, sbmin, w2);1104g.drawLine(sbmin, length - w2, sbmax, length - w2);1105g.drawLine(sbmin, length - w2, ctr, length - 2);1106}11071108// thumb1109if (v1 > 0) {1110if (horizontal) {1111g.drawLine(v1, 2, v1 + v2, 2);1112g.drawLine(v1, 2, v1, thickness-3);1113} else {1114g.drawLine(2, v1, 2, v1 + v2);1115g.drawLine(2, v1, thickness-3, v1);1116}1117}11181119Color shadow = bg.darker();11201121// // // // draw the "shadowed" edges1122g.setColor(shadow);11231124// outline && arrows1125if (horizontal) {1126g.drawLine(0, 0, 0, thickness);1127g.drawLine(0, 0, length - 1, 0);11281129// arrows1130g.drawLine(w2, sbmin, w2, sbmax);1131g.drawLine(w2, sbmax, 1, ctr);1132g.drawLine(length-2, ctr, length-w2, sbmax);11331134} else {1135g.drawLine(0, 0, thickness, 0);1136g.drawLine(0, 0, 0, length - 1);11371138// arrows1139g.drawLine(sbmin, w2, sbmax, w2);1140g.drawLine(sbmax, w2, ctr, 1);1141g.drawLine(ctr, length-2, sbmax, length-w2);1142}11431144// thumb1145if (v1 > 0) {1146if (horizontal) {1147g.drawLine(v1 + v2, 2, v1 + v2, thickness-2);1148g.drawLine(v1, thickness-2, v1 + v2, thickness-2);1149} else {1150g.drawLine(2, v1 + v2, thickness-2, v1 + v2);1151g.drawLine(thickness-2, v1, thickness-2, v1 + v2);1152}1153}1154g.setColor(c);1155}11561157/**1158* The following multibuffering-related methods delegate to our1159* associated GraphicsConfig (X11 or GLX) to handle the appropriate1160* native windowing system specific actions.1161*/11621163private BufferCapabilities backBufferCaps;11641165public void createBuffers(int numBuffers, BufferCapabilities caps)1166throws AWTException1167{1168if (buffersLog.isLoggable(PlatformLogger.Level.FINE)) {1169buffersLog.fine("createBuffers(" + numBuffers + ", " + caps + ")");1170}1171// set the caps first, they're used when creating the bb1172backBufferCaps = caps;1173backBuffer = graphicsConfig.createBackBuffer(this, numBuffers, caps);1174xBackBuffer = graphicsConfig.createBackBufferImage(target,1175backBuffer);1176}11771178@Override1179public BufferCapabilities getBackBufferCaps() {1180return backBufferCaps;1181}11821183public void flip(int x1, int y1, int x2, int y2,1184BufferCapabilities.FlipContents flipAction)1185{1186if (buffersLog.isLoggable(PlatformLogger.Level.FINE)) {1187buffersLog.fine("flip(" + flipAction + ")");1188}1189if (backBuffer == 0) {1190throw new IllegalStateException("Buffers have not been created");1191}1192graphicsConfig.flip(this, target, xBackBuffer,1193x1, y1, x2, y2, flipAction);1194}11951196public Image getBackBuffer() {1197if (buffersLog.isLoggable(PlatformLogger.Level.FINE)) {1198buffersLog.fine("getBackBuffer()");1199}1200if (backBuffer == 0) {1201throw new IllegalStateException("Buffers have not been created");1202}1203return xBackBuffer;1204}12051206public void destroyBuffers() {1207if (buffersLog.isLoggable(PlatformLogger.Level.FINE)) {1208buffersLog.fine("destroyBuffers()");1209}1210graphicsConfig.destroyBackBuffer(backBuffer);1211backBuffer = 0;1212xBackBuffer = null;1213}12141215// End of multi-buffering12161217public void notifyTextComponentChange(boolean add){1218Container parent = AWTAccessor.getComponentAccessor().getParent(target);1219while(!(parent == null ||1220parent instanceof java.awt.Frame ||1221parent instanceof java.awt.Dialog)) {1222parent = AWTAccessor.getComponentAccessor().getParent(parent);1223}12241225/* FIX ME - FIX ME need to implement InputMethods1226if (parent instanceof java.awt.Frame ||1227parent instanceof java.awt.Dialog) {1228if (add)1229((MInputMethodControl)parent.getPeer()).addTextComponent((MComponentPeer)this);1230else1231((MInputMethodControl)parent.getPeer()).removeTextComponent((MComponentPeer)this);1232}1233*/1234}12351236/**1237* Returns true if this event is disabled and shouldn't be processed by window1238* Currently if target component is disabled the following event will be disabled on window:1239* ButtonPress, ButtonRelease, KeyPress, KeyRelease, EnterNotify, LeaveNotify, MotionNotify1240*/1241protected boolean isEventDisabled(XEvent e) {1242if (enableLog.isLoggable(PlatformLogger.Level.FINEST)) {1243enableLog.finest("Component is {1}, checking for disabled event {0}", e, (isEnabled()?"enabled":"disable"));1244}1245if (!isEnabled()) {1246switch (e.get_type()) {1247case XConstants.ButtonPress:1248case XConstants.ButtonRelease:1249case XConstants.KeyPress:1250case XConstants.KeyRelease:1251case XConstants.EnterNotify:1252case XConstants.LeaveNotify:1253case XConstants.MotionNotify:1254if (enableLog.isLoggable(PlatformLogger.Level.FINER)) {1255enableLog.finer("Event {0} is disable", e);1256}1257return true;1258}1259}1260switch(e.get_type()) {1261case XConstants.MapNotify:1262case XConstants.UnmapNotify:1263return true;1264}1265return super.isEventDisabled(e);1266}12671268Color getPeerBackground() {1269return background;1270}12711272Color getPeerForeground() {1273return foreground;1274}12751276Font getPeerFont() {1277return font;1278}12791280Dimension getPeerSize() {1281return new Dimension(width,height);1282}12831284public void setBoundsOperation(int operation) {1285synchronized(getStateLock()) {1286if (boundsOperation == DEFAULT_OPERATION) {1287boundsOperation = operation;1288} else if (operation == RESET_OPERATION) {1289boundsOperation = DEFAULT_OPERATION;1290}1291}1292}12931294static String operationToString(int operation) {1295switch (operation) {1296case SET_LOCATION:1297return "SET_LOCATION";1298case SET_SIZE:1299return "SET_SIZE";1300case SET_CLIENT_SIZE:1301return "SET_CLIENT_SIZE";1302default:1303case SET_BOUNDS:1304return "SET_BOUNDS";1305}1306}13071308/**1309* Lowers this component at the bottom of the above HW peer. If the above parameter1310* is null then the method places this component at the top of the Z-order.1311*/1312public void setZOrder(ComponentPeer above) {1313long aboveWindow = (above != null) ? ((XComponentPeer)above).getWindow() : 0;13141315XToolkit.awtLock();1316try{1317XlibWrapper.SetZOrder(XToolkit.getDisplay(), getWindow(), aboveWindow);1318}finally{1319XToolkit.awtUnlock();1320}1321}13221323private void addTree(Collection order, Set set, Container cont) {1324for (int i = 0; i < cont.getComponentCount(); i++) {1325Component comp = cont.getComponent(i);1326ComponentPeer peer = comp.getPeer();1327if (peer instanceof XComponentPeer) {1328Long window = Long.valueOf(((XComponentPeer)peer).getWindow());1329if (!set.contains(window)) {1330set.add(window);1331order.add(window);1332}1333} else if (comp instanceof Container) {1334// It is lightweight container, it might contain heavyweight components attached to this1335// peer1336addTree(order, set, (Container)comp);1337}1338}1339}13401341/****** DropTargetPeer implementation ********************/13421343public void addDropTarget(DropTarget dt) {1344Component comp = target;1345while(!(comp == null || comp instanceof Window)) {1346comp = comp.getParent();1347}13481349if (comp instanceof Window) {1350XWindowPeer wpeer = (XWindowPeer)(comp.getPeer());1351if (wpeer != null) {1352wpeer.addDropTarget();1353}1354}1355}13561357public void removeDropTarget(DropTarget dt) {1358Component comp = target;1359while(!(comp == null || comp instanceof Window)) {1360comp = comp.getParent();1361}13621363if (comp instanceof Window) {1364XWindowPeer wpeer = (XWindowPeer)(comp.getPeer());1365if (wpeer != null) {1366wpeer.removeDropTarget();1367}1368}1369}13701371/**1372* Applies the shape to the X-window.1373* @since 1.71374*/1375public void applyShape(Region shape) {1376if (XlibUtil.isShapingSupported()) {1377if (shapeLog.isLoggable(PlatformLogger.Level.FINER)) {1378shapeLog.finer(1379"*** INFO: Setting shape: PEER: " + this1380+ "; WINDOW: " + getWindow()1381+ "; TARGET: " + target1382+ "; SHAPE: " + shape);1383}1384XToolkit.awtLock();1385try {1386if (shape != null) {1387XlibWrapper.SetRectangularShape(1388XToolkit.getDisplay(),1389getWindow(),1390shape.getLoX(), shape.getLoY(),1391shape.getHiX(), shape.getHiY(),1392(shape.isRectangular() ? null : shape)1393);1394} else {1395XlibWrapper.SetRectangularShape(1396XToolkit.getDisplay(),1397getWindow(),13980, 0,13990, 0,1400null1401);1402}1403} finally {1404XToolkit.awtUnlock();1405}1406} else {1407if (shapeLog.isLoggable(PlatformLogger.Level.FINER)) {1408shapeLog.finer("*** WARNING: Shaping is NOT supported!");1409}1410}1411}14121413public boolean updateGraphicsData(GraphicsConfiguration gc) {1414int oldVisual = -1, newVisual = -1;14151416if (graphicsConfig != null) {1417oldVisual = graphicsConfig.getVisual();1418}1419if (gc != null && gc instanceof X11GraphicsConfig) {1420newVisual = ((X11GraphicsConfig)gc).getVisual();1421}14221423// If the new visual differs from the old one, the peer must be1424// recreated because X11 does not allow changing the visual on the fly.1425// So we even skip the initGraphicsConfiguration() call.1426// The initial assignment should happen though, hence the != -1 thing.1427if (oldVisual != -1 && oldVisual != newVisual) {1428return true;1429}14301431initGraphicsConfiguration();1432doValidateSurface();1433return false;1434}1435}143614371438