mirror of
https://github.com/2003scape/deep-c-rsc.git
synced 2024-03-22 05:49:51 -04:00
491 lines
19 KiB
Java
491 lines
19 KiB
Java
/*
|
|
* This file is modified by Ivan Maidanski <ivmai@ivmaisoft.com>
|
|
* Project name: JCGO-SUNAWT (http://www.ivmaisoft.com/jcgo/)
|
|
*/
|
|
|
|
/*
|
|
* @(#)MFramePeer.java 1.100 03/01/23
|
|
*
|
|
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
|
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
*/
|
|
package sun.awt.motif;
|
|
|
|
import java.util.Vector;
|
|
import java.awt.*;
|
|
import java.awt.peer.*;
|
|
import java.awt.event.*;
|
|
import sun.awt.motif.X11InputMethod;
|
|
import sun.awt.motif.MInputMethodControl;
|
|
import sun.awt.im.*;
|
|
import java.awt.image.ColorModel;
|
|
import java.awt.image.BufferedImage;
|
|
import java.awt.image.DataBuffer;
|
|
import java.awt.image.DataBufferInt;
|
|
import java.awt.image.DataBufferByte;
|
|
import java.awt.image.DataBufferUShort;
|
|
import java.awt.image.ImageObserver;
|
|
import java.awt.image.WritableRaster;
|
|
import sun.awt.image.ImageRepresentation;
|
|
|
|
class MFramePeer extends MWindowPeer implements FramePeer, MInputMethodControl {
|
|
static Vector allFrames = new Vector();
|
|
|
|
// XXX: Stub out for now. Need to propagate to normal size hints.
|
|
public void setMaximizedBounds(Rectangle b) {}
|
|
|
|
public void create(MComponentPeer parent, Object arg) {
|
|
super.create( parent );
|
|
}
|
|
|
|
MFramePeer(Frame target) {
|
|
super();
|
|
// set the window attributes for this Frame
|
|
winAttr.nativeDecor = !target.isUndecorated();
|
|
winAttr.initialFocus = true;
|
|
winAttr.isResizable = target.isResizable();
|
|
winAttr.initialState = target.getState();
|
|
winAttr.title = target.getTitle();
|
|
winAttr.icon = target.getIconImage();
|
|
if (winAttr.nativeDecor) {
|
|
winAttr.decorations = winAttr.AWT_DECOR_ALL;
|
|
} else {
|
|
winAttr.decorations = winAttr.AWT_DECOR_NONE;
|
|
}
|
|
|
|
// for input method windows, use minimal decorations
|
|
if (target instanceof InputMethodWindow) {
|
|
winAttr.initialFocus = false;
|
|
winAttr.decorations = (winAttr.AWT_DECOR_TITLE | winAttr.AWT_DECOR_BORDER);
|
|
}
|
|
|
|
// create and init native component
|
|
init( target);
|
|
if (winAttr.icon != null) {
|
|
setIconImage(winAttr.icon);
|
|
}
|
|
allFrames.addElement(this);
|
|
}
|
|
|
|
public void setTitle(String title) {
|
|
pSetTitle(title);
|
|
}
|
|
|
|
protected void disposeImpl() {
|
|
allFrames.removeElement(this);
|
|
super.disposeImpl();
|
|
}
|
|
|
|
public void setMenuBar(MenuBar mb) {
|
|
MMenuBarPeer mbpeer = (MMenuBarPeer) MToolkit.targetToPeer(mb);
|
|
pSetMenuBar(mbpeer);
|
|
|
|
Rectangle r = target.bounds();
|
|
|
|
pReshape(r.x, r.y, r.width, r.height);
|
|
if (target.isVisible()) {
|
|
target.validate();
|
|
}
|
|
}
|
|
|
|
public void setIconImage(Image im) {
|
|
int width;
|
|
int height;
|
|
GraphicsConfiguration defaultGC;
|
|
if (im != null) { // 4633887 Avoid Null pointer exception.
|
|
if (im instanceof X11Image) {
|
|
ImageRepresentation ir = ((X11Image)im).getImageRep();
|
|
ir.reconstruct(ImageObserver.ALLBITS);
|
|
width = ir.getWidth();
|
|
height = ir.getHeight();
|
|
}
|
|
else {
|
|
width = im.getWidth(null);
|
|
height = im.getHeight(null);
|
|
}
|
|
if (pGetIconSize(width, height)) {
|
|
//Icons are displayed using the default visual, so create image
|
|
//using default GraphicsConfiguration
|
|
defaultGC = getGraphicsConfiguration().getDevice().
|
|
getDefaultConfiguration();
|
|
ColorModel model = defaultGC.getColorModel();
|
|
WritableRaster raster =
|
|
model.createCompatibleWritableRaster(iconWidth, iconHeight);
|
|
Image image = new BufferedImage(model, raster,
|
|
model.isAlphaPremultiplied(),
|
|
null);
|
|
|
|
// ARGB BufferedImage to hunt for transparent pixels
|
|
BufferedImage bimage =
|
|
new BufferedImage(iconWidth, iconHeight,
|
|
BufferedImage.TYPE_INT_ARGB);
|
|
ColorModel alphaCheck = bimage.getColorModel();
|
|
Graphics g = image.getGraphics();
|
|
Graphics big = bimage.getGraphics();
|
|
try {
|
|
g.drawImage(im, 0, 0, iconWidth, iconHeight, null);
|
|
big.drawImage(im, 0, 0, iconWidth, iconHeight, null);
|
|
} finally {
|
|
g.dispose();
|
|
big.dispose();
|
|
}
|
|
|
|
DataBuffer db = ((BufferedImage)image).getRaster().getDataBuffer();
|
|
DataBuffer bidb = bimage.getRaster().getDataBuffer();
|
|
byte[] bytedata = null;
|
|
int[] intdata = null;
|
|
int bidbLen = bidb.getSize();
|
|
int imgDataIdx;
|
|
//Get native RGB value for window background color
|
|
//Should work for byte as well as int
|
|
int bgRGB = getNativeColor(SystemColor.window, defaultGC);
|
|
|
|
/* My first attempt at a solution to bug 4175560 was to use
|
|
* the iconMask and iconPixmap attributes of Windows.
|
|
* This worked fine on CDE/dtwm, however olwm displayed only
|
|
* single color icons (white on background). Instead, the
|
|
* fix gets the default background window color and replaces
|
|
* transparent pixels in the icon image with this color. This
|
|
* solutions works well with dtwm as well as olwm.
|
|
*/
|
|
|
|
for (imgDataIdx = 0; imgDataIdx < bidbLen; imgDataIdx++) {
|
|
if (alphaCheck.getAlpha(bidb.getElem(imgDataIdx)) == 0 ) {
|
|
//Assuming single data bank
|
|
db.setElem(imgDataIdx, bgRGB);
|
|
}
|
|
}
|
|
short[] ushortdata = null;
|
|
if (db instanceof DataBufferByte) {
|
|
// Pseudocolor data
|
|
bytedata = ((DataBufferByte)db).getData();
|
|
}
|
|
else if (db instanceof DataBufferInt) {
|
|
// Truecolor data
|
|
intdata = ((DataBufferInt) db).getData();
|
|
}
|
|
else if (db instanceof DataBufferUShort) {
|
|
// Truecolor data
|
|
ushortdata = ((DataBufferUShort) db).getData();
|
|
}
|
|
pSetIconImage(bytedata, intdata, ushortdata,
|
|
iconWidth, iconHeight);
|
|
}
|
|
}
|
|
}
|
|
|
|
native boolean pGetIconSize(int widthHint, int heightHint);
|
|
|
|
// [jk] added ushortData for 16-bpp displays
|
|
native void pSetIconImage(byte[] byteData,
|
|
int[] intData,
|
|
short[] ushortData,
|
|
int iconWidth, int iconHeight);
|
|
private native void pSetIconImage(boolean dummy);
|
|
|
|
// NOTE: This method may be called by privileged threads.
|
|
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
|
public void handleIconify() {
|
|
postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_ICONIFIED));
|
|
}
|
|
|
|
// NOTE: This method may be called by privileged threads.
|
|
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
|
public void handleDeiconify() {
|
|
postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_DEICONIFIED));
|
|
}
|
|
|
|
|
|
/**
|
|
* Called to inform the Frame that it has moved.
|
|
*/
|
|
// NOTE: This method may be called by privileged threads.
|
|
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
|
public void handleMoved(int x, int y) {
|
|
postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));
|
|
}
|
|
|
|
static final int CROSSHAIR_INSET = 5;
|
|
|
|
static final int BUTTON_Y = CROSSHAIR_INSET + 1;
|
|
static final int BUTTON_W = 17;
|
|
static final int BUTTON_H = 17;
|
|
|
|
static final int SYS_MENU_X = CROSSHAIR_INSET + 1;
|
|
static final int SYS_MENU_CONTAINED_X = SYS_MENU_X + 5;
|
|
static final int SYS_MENU_CONTAINED_Y = BUTTON_Y + 7;
|
|
static final int SYS_MENU_CONTAINED_W = 8;
|
|
static final int SYS_MENU_CONTAINED_H = 3;
|
|
|
|
static final int MAXIMIZE_X_DIFF = CROSSHAIR_INSET + BUTTON_W;
|
|
static final int MAXIMIZE_CONTAINED_X_DIFF = MAXIMIZE_X_DIFF - 5;
|
|
static final int MAXIMIZE_CONTAINED_Y = BUTTON_Y + 5;
|
|
static final int MAXIMIZE_CONTAINED_W = 8;
|
|
static final int MAXIMIZE_CONTAINED_H = 8;
|
|
|
|
static final int MINIMIZE_X_DIFF = MAXIMIZE_X_DIFF + BUTTON_W;
|
|
static final int MINIMIZE_CONTAINED_X_DIFF = MINIMIZE_X_DIFF - 7;
|
|
static final int MINIMIZE_CONTAINED_Y = BUTTON_Y + 7;
|
|
static final int MINIMIZE_CONTAINED_W = 3;
|
|
static final int MINIMIZE_CONTAINED_H = 3;
|
|
|
|
static final int TITLE_X = SYS_MENU_X + BUTTON_W;
|
|
static final int TITLE_W_DIFF = BUTTON_W * 3 + CROSSHAIR_INSET * 2 - 1;
|
|
static final int TITLE_MID_Y = BUTTON_Y + (BUTTON_H / 2);
|
|
|
|
static final int MENUBAR_X = CROSSHAIR_INSET + 1;
|
|
static final int MENUBAR_Y = BUTTON_Y + BUTTON_H;
|
|
|
|
static final int HORIZ_RESIZE_INSET = CROSSHAIR_INSET + BUTTON_H;
|
|
static final int VERT_RESIZE_INSET = CROSSHAIR_INSET + BUTTON_W;
|
|
|
|
|
|
/*
|
|
* Print the native component by rendering the Motif look ourselves.
|
|
* We also explicitly print the MenuBar since a MenuBar isn't a subclass
|
|
* of Component (and thus it has no "print" method which gets called by
|
|
* default).
|
|
*/
|
|
public void print(Graphics g) {
|
|
super.print(g);
|
|
|
|
Frame f = (Frame)target;
|
|
Insets finsets = f.getInsets();
|
|
Dimension fsize = f.getSize();
|
|
|
|
Color bg = f.getBackground();
|
|
Color fg = f.getForeground();
|
|
Color highlight = bg.brighter();
|
|
Color shadow = bg.darker();
|
|
|
|
// Well, we could query for the currently running window manager
|
|
// and base the look on that, or we could just always do dtwm.
|
|
// aim, tball, and levenson all agree we'll just do dtwm.
|
|
|
|
if (hasDecorations(MWindowAttributes.AWT_DECOR_BORDER)) {
|
|
|
|
// top outer -- because we'll most likely be drawing on white paper,
|
|
// for aesthetic reasons, don't make any part of the outer border
|
|
// pure white
|
|
if (highlight.equals(Color.white)) {
|
|
g.setColor(new Color(230, 230, 230));
|
|
}
|
|
else {
|
|
g.setColor(highlight);
|
|
}
|
|
g.drawLine(0, 0, fsize.width, 0);
|
|
g.drawLine(0, 1, fsize.width - 1, 1);
|
|
|
|
// left outer
|
|
// if (highlight.equals(Color.white)) {
|
|
// g.setColor(new Color(230, 230, 230));
|
|
// }
|
|
// else {
|
|
// g.setColor(highlight);
|
|
// }
|
|
g.drawLine(0, 0, 0, fsize.height);
|
|
g.drawLine(1, 0, 1, fsize.height - 1);
|
|
|
|
// bottom cross-hair
|
|
g.setColor(highlight);
|
|
g.drawLine(CROSSHAIR_INSET + 1, fsize.height - CROSSHAIR_INSET,
|
|
fsize.width - CROSSHAIR_INSET,
|
|
fsize.height - CROSSHAIR_INSET);
|
|
|
|
// right cross-hair
|
|
// g.setColor(highlight);
|
|
g.drawLine(fsize.width - CROSSHAIR_INSET, CROSSHAIR_INSET + 1,
|
|
fsize.width - CROSSHAIR_INSET,
|
|
fsize.height - CROSSHAIR_INSET);
|
|
|
|
// bottom outer
|
|
g.setColor(shadow);
|
|
g.drawLine(1, fsize.height, fsize.width, fsize.height);
|
|
g.drawLine(2, fsize.height - 1, fsize.width, fsize.height - 1);
|
|
|
|
// right outer
|
|
// g.setColor(shadow);
|
|
g.drawLine(fsize.width, 1, fsize.width, fsize.height);
|
|
g.drawLine(fsize.width - 1, 2, fsize.width - 1, fsize.height);
|
|
|
|
// top cross-hair
|
|
// g.setColor(shadow);
|
|
g.drawLine(CROSSHAIR_INSET, CROSSHAIR_INSET,
|
|
fsize.width - CROSSHAIR_INSET, CROSSHAIR_INSET);
|
|
|
|
// left cross-hair
|
|
// g.setColor(shadow);
|
|
g.drawLine(CROSSHAIR_INSET, CROSSHAIR_INSET, CROSSHAIR_INSET,
|
|
fsize.height - CROSSHAIR_INSET);
|
|
}
|
|
|
|
if (hasDecorations(MWindowAttributes.AWT_DECOR_TITLE)) {
|
|
|
|
if (hasDecorations(MWindowAttributes.AWT_DECOR_MENU)) {
|
|
|
|
// system menu
|
|
g.setColor(bg);
|
|
g.fill3DRect(SYS_MENU_X, BUTTON_Y, BUTTON_W, BUTTON_H, true);
|
|
g.fill3DRect(SYS_MENU_CONTAINED_X, SYS_MENU_CONTAINED_Y,
|
|
SYS_MENU_CONTAINED_W, SYS_MENU_CONTAINED_H, true);
|
|
}
|
|
|
|
// title bar
|
|
// g.setColor(bg);
|
|
g.fill3DRect(TITLE_X, BUTTON_Y, fsize.width - TITLE_W_DIFF, BUTTON_H,
|
|
true);
|
|
|
|
if (hasDecorations(MWindowAttributes.AWT_DECOR_MINIMIZE)) {
|
|
|
|
// minimize button
|
|
// g.setColor(bg);
|
|
g.fill3DRect(fsize.width - MINIMIZE_X_DIFF, BUTTON_Y, BUTTON_W,
|
|
BUTTON_H, true);
|
|
g.fill3DRect(fsize.width - MINIMIZE_CONTAINED_X_DIFF,
|
|
MINIMIZE_CONTAINED_Y, MINIMIZE_CONTAINED_W,
|
|
MINIMIZE_CONTAINED_H, true);
|
|
}
|
|
|
|
if (hasDecorations(MWindowAttributes.AWT_DECOR_MAXIMIZE)) {
|
|
|
|
// maximize button
|
|
// g.setColor(bg);
|
|
g.fill3DRect(fsize.width - MAXIMIZE_X_DIFF, BUTTON_Y, BUTTON_W,
|
|
BUTTON_H, true);
|
|
g.fill3DRect(fsize.width - MAXIMIZE_CONTAINED_X_DIFF,
|
|
MAXIMIZE_CONTAINED_Y, MAXIMIZE_CONTAINED_W,
|
|
MAXIMIZE_CONTAINED_H, true);
|
|
}
|
|
|
|
// title bar text
|
|
g.setColor(fg);
|
|
Font sysfont = new Font("SansSerif", Font.PLAIN, 10);
|
|
g.setFont(sysfont);
|
|
FontMetrics sysfm = g.getFontMetrics();
|
|
String ftitle = f.getTitle();
|
|
g.drawString(ftitle,
|
|
((TITLE_X + TITLE_X + fsize.width - TITLE_W_DIFF) / 2) -
|
|
(sysfm.stringWidth(ftitle) / 2),
|
|
TITLE_MID_Y + sysfm.getMaxDescent());
|
|
}
|
|
|
|
if (f.isResizable() &&
|
|
hasDecorations(MWindowAttributes.AWT_DECOR_RESIZEH)) {
|
|
|
|
// add resize cross hairs
|
|
|
|
// upper-left horiz (shadow)
|
|
g.setColor(shadow);
|
|
g.drawLine(1, HORIZ_RESIZE_INSET, CROSSHAIR_INSET,
|
|
HORIZ_RESIZE_INSET);
|
|
// upper-left vert (shadow)
|
|
// g.setColor(shadow);
|
|
g.drawLine(VERT_RESIZE_INSET, 1, VERT_RESIZE_INSET, CROSSHAIR_INSET);
|
|
// upper-right horiz (shadow)
|
|
// g.setColor(shadow);
|
|
g.drawLine(fsize.width - CROSSHAIR_INSET + 1, HORIZ_RESIZE_INSET,
|
|
fsize.width, HORIZ_RESIZE_INSET);
|
|
// upper-right vert (shadow)
|
|
// g.setColor(shadow);
|
|
g.drawLine(fsize.width - VERT_RESIZE_INSET - 1, 2,
|
|
fsize.width - VERT_RESIZE_INSET - 1, CROSSHAIR_INSET + 1);
|
|
// lower-left horiz (shadow)
|
|
// g.setColor(shadow);
|
|
g.drawLine(1, fsize.height - HORIZ_RESIZE_INSET - 1,
|
|
CROSSHAIR_INSET, fsize.height - HORIZ_RESIZE_INSET - 1);
|
|
// lower-left vert (shadow)
|
|
// g.setColor(shadow);
|
|
g.drawLine(VERT_RESIZE_INSET, fsize.height - CROSSHAIR_INSET + 1,
|
|
VERT_RESIZE_INSET, fsize.height);
|
|
// lower-right horiz (shadow)
|
|
// g.setColor(shadow);
|
|
g.drawLine(fsize.width - CROSSHAIR_INSET + 1,
|
|
fsize.height - HORIZ_RESIZE_INSET - 1, fsize.width,
|
|
fsize.height - HORIZ_RESIZE_INSET - 1);
|
|
// lower-right vert (shadow)
|
|
// g.setColor(shadow);
|
|
g.drawLine(fsize.width - VERT_RESIZE_INSET - 1,
|
|
fsize.height - CROSSHAIR_INSET + 1,
|
|
fsize.width - VERT_RESIZE_INSET - 1, fsize.height);
|
|
|
|
// upper-left horiz (highlight)
|
|
g.setColor(highlight);
|
|
g.drawLine(2, HORIZ_RESIZE_INSET + 1, CROSSHAIR_INSET,
|
|
HORIZ_RESIZE_INSET + 1);
|
|
// upper-left vert (highlight)
|
|
// g.setColor(highlight);
|
|
g.drawLine(VERT_RESIZE_INSET + 1, 2, VERT_RESIZE_INSET + 1,
|
|
CROSSHAIR_INSET);
|
|
// upper-right horiz (highlight)
|
|
// g.setColor(highlight);
|
|
g.drawLine(fsize.width - CROSSHAIR_INSET + 1,
|
|
HORIZ_RESIZE_INSET + 1, fsize.width - 1,
|
|
HORIZ_RESIZE_INSET + 1);
|
|
// upper-right vert (highlight)
|
|
// g.setColor(highlight);
|
|
g.drawLine(fsize.width - VERT_RESIZE_INSET, 2,
|
|
fsize.width - VERT_RESIZE_INSET, CROSSHAIR_INSET);
|
|
// lower-left horiz (highlight)
|
|
// g.setColor(highlight);
|
|
g.drawLine(2, fsize.height - HORIZ_RESIZE_INSET, CROSSHAIR_INSET,
|
|
fsize.height - HORIZ_RESIZE_INSET);
|
|
// lower-left vert (highlight)
|
|
// g.setColor(highlight);
|
|
g.drawLine(VERT_RESIZE_INSET + 1,
|
|
fsize.height - CROSSHAIR_INSET + 1,
|
|
VERT_RESIZE_INSET + 1, fsize.height - 1);
|
|
// lower-right horiz (highlight)
|
|
// g.setColor(highlight);
|
|
g.drawLine(fsize.width - CROSSHAIR_INSET + 1,
|
|
fsize.height - HORIZ_RESIZE_INSET, fsize.width - 1,
|
|
fsize.height - HORIZ_RESIZE_INSET);
|
|
// lower-right vert (highlight)
|
|
// g.setColor(highlight);
|
|
g.drawLine(fsize.width - VERT_RESIZE_INSET,
|
|
fsize.height - CROSSHAIR_INSET + 1,
|
|
fsize.width - VERT_RESIZE_INSET, fsize.height - 1);
|
|
}
|
|
|
|
MenuBar mb = f.getMenuBar();
|
|
if (mb != null) {
|
|
MMenuBarPeer peer = (MMenuBarPeer) MToolkit.targetToPeer(mb);
|
|
if (peer != null) {
|
|
Insets insets = getInsets();
|
|
Graphics ng = g.create();
|
|
int menubarX = 0;
|
|
int menubarY = 0;
|
|
if (hasDecorations(MWindowAttributes.AWT_DECOR_BORDER)) {
|
|
menubarX += CROSSHAIR_INSET + 1;
|
|
menubarY += CROSSHAIR_INSET + 1;
|
|
}
|
|
if (hasDecorations(MWindowAttributes.AWT_DECOR_TITLE)) {
|
|
menubarY += BUTTON_H;
|
|
}
|
|
try {
|
|
ng.translate(menubarX, menubarY);
|
|
peer.print(ng);
|
|
} finally {
|
|
ng.dispose();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Saveunders are not done by Frame.
|
|
void setSaveUnder(boolean state) {}
|
|
|
|
/* Returns the native paint should be posted after setting new size
|
|
*/
|
|
public boolean checkNativePaintOnSetBounds(int width, int height) {
|
|
// Fix for 4418155. Undecorated Frame does not repaint
|
|
// automticaly if shrinking. Should not wait for Expose
|
|
return ((Frame)target).isUndecorated() ?
|
|
((width > oldWidth) || (height > oldHeight)):
|
|
((width != oldWidth) || (height != oldHeight));
|
|
}
|
|
|
|
final boolean isTargetUndecorated() {
|
|
return ((Frame)target).isUndecorated();
|
|
}
|
|
}
|