0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2006 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.swt.widgets;
0011:
0012: import org.eclipse.swt.internal.*;
0013: import org.eclipse.swt.internal.carbon.CGRect;
0014: import org.eclipse.swt.internal.carbon.OS;
0015: import org.eclipse.swt.internal.carbon.RGBColor;
0016: import org.eclipse.swt.internal.carbon.Rect;
0017: import org.eclipse.swt.internal.carbon.PixMap;
0018: import org.eclipse.swt.internal.carbon.BitMap;
0019:
0020: import org.eclipse.swt.*;
0021: import org.eclipse.swt.graphics.*;
0022: import org.eclipse.swt.events.*;
0023:
0024: /**
0025: * This class is the abstract superclass of all user interface objects.
0026: * Widgets are created, disposed and issue notification to listeners
0027: * when events occur which affect them.
0028: * <dl>
0029: * <dt><b>Styles:</b></dt>
0030: * <dd>(none)</dd>
0031: * <dt><b>Events:</b></dt>
0032: * <dd>Dispose</dd>
0033: * </dl>
0034: * <p>
0035: * IMPORTANT: This class is intended to be subclassed <em>only</em>
0036: * within the SWT implementation. However, it has not been marked
0037: * final to allow those outside of the SWT development team to implement
0038: * patched versions of the class in order to get around specific
0039: * limitations in advance of when those limitations can be addressed
0040: * by the team. Any class built using subclassing to access the internals
0041: * of this class will likely fail to compile or run between releases and
0042: * may be strongly platform specific. Subclassing should not be attempted
0043: * without an intimate and detailed understanding of the workings of the
0044: * hierarchy. No support is provided for user-written classes which are
0045: * implemented as subclasses of this class.
0046: * </p>
0047: *
0048: * @see #checkSubclass
0049: */
0050: public abstract class Widget {
0051: int style, state;
0052: Display display;
0053: EventTable eventTable;
0054: Object data;
0055:
0056: /* Global state flags */
0057: static final int DISPOSED = 1 << 0;
0058: static final int CANVAS = 1 << 1;
0059: static final int KEYED_DATA = 1 << 2;
0060: static final int DISABLED = 1 << 3;
0061: static final int HIDDEN = 1 << 4;
0062: static final int GRAB = 1 << 5;
0063: static final int MOVED = 1 << 6;
0064: static final int RESIZED = 1 << 7;
0065: static final int EXPANDING = 1 << 8;
0066: static final int IGNORE_WHEEL = 1 << 9;
0067: static final int PARENT_BACKGROUND = 1 << 10;
0068: static final int THEME_BACKGROUND = 1 << 11;
0069:
0070: /* A layout was requested on this widget */
0071: static final int LAYOUT_NEEDED = 1 << 12;
0072:
0073: /* The preferred size of a child has changed */
0074: static final int LAYOUT_CHANGED = 1 << 13;
0075:
0076: /* A layout was requested in this widget hierachy */
0077: static final int LAYOUT_CHILD = 1 << 14;
0078:
0079: /* More global state flags */
0080: static final int RELEASED = 1 << 15;
0081: static final int DISPOSE_SENT = 1 << 16;
0082:
0083: /* Default size for widgets */
0084: static final int DEFAULT_WIDTH = 64;
0085: static final int DEFAULT_HEIGHT = 64;
0086:
0087: static final Rect EMPTY_RECT = new Rect();
0088:
0089: // GOOGLE: patched in from https://bugs.eclipse.org/bugs/show_bug.cgi?id=161259
0090: static final String CLEAR_GRAB_BIT = "org.eclipse.swt.internal.carbon.clearGrabBit";
0091:
0092: Widget() {
0093: /* Do nothing */
0094: }
0095:
0096: /**
0097: * Constructs a new instance of this class given its parent
0098: * and a style value describing its behavior and appearance.
0099: * <p>
0100: * The style value is either one of the style constants defined in
0101: * class <code>SWT</code> which is applicable to instances of this
0102: * class, or must be built by <em>bitwise OR</em>'ing together
0103: * (that is, using the <code>int</code> "|" operator) two or more
0104: * of those <code>SWT</code> style constants. The class description
0105: * lists the style constants that are applicable to the class.
0106: * Style bits are also inherited from superclasses.
0107: * </p>
0108: *
0109: * @param parent a widget which will be the parent of the new instance (cannot be null)
0110: * @param style the style of widget to construct
0111: *
0112: * @exception IllegalArgumentException <ul>
0113: * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
0114: * <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
0115: * </ul>
0116: * @exception SWTException <ul>
0117: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
0118: * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
0119: * </ul>
0120: *
0121: * @see SWT
0122: * @see #checkSubclass
0123: * @see #getStyle
0124: */
0125: public Widget(Widget parent, int style) {
0126: checkSubclass();
0127: checkParent(parent);
0128: this .style = style;
0129: display = parent.display;
0130: }
0131:
0132: int actionProc(int theControl, int partCode) {
0133: return OS.noErr;
0134: }
0135:
0136: /**
0137: * Adds the listener to the collection of listeners who will
0138: * be notified when an event of the given type occurs. When the
0139: * event does occur in the widget, the listener is notified by
0140: * sending it the <code>handleEvent()</code> message. The event
0141: * type is one of the event constants defined in class <code>SWT</code>.
0142: *
0143: * @param eventType the type of event to listen for
0144: * @param listener the listener which should be notified when the event occurs
0145: *
0146: * @exception IllegalArgumentException <ul>
0147: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0148: * </ul>
0149: * @exception SWTException <ul>
0150: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0151: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0152: * </ul>
0153: *
0154: * @see Listener
0155: * @see SWT
0156: * @see #removeListener
0157: * @see #notifyListeners
0158: */
0159: public void addListener(int eventType, Listener listener) {
0160: checkWidget();
0161: if (listener == null)
0162: error(SWT.ERROR_NULL_ARGUMENT);
0163: _addListener(eventType, listener);
0164: }
0165:
0166: void _addListener(int eventType, Listener listener) {
0167: if (eventTable == null)
0168: eventTable = new EventTable();
0169: eventTable.hook(eventType, listener);
0170: }
0171:
0172: int callPaintEventHandler(int control, int damageRgn,
0173: int visibleRgn, int theEvent, int nextHandler) {
0174: return OS.CallNextEventHandler(nextHandler, theEvent);
0175: }
0176:
0177: /**
0178: * Adds the listener to the collection of listeners who will
0179: * be notified when the widget is disposed. When the widget is
0180: * disposed, the listener is notified by sending it the
0181: * <code>widgetDisposed()</code> message.
0182: *
0183: * @param listener the listener which should be notified when the receiver is disposed
0184: *
0185: * @exception IllegalArgumentException <ul>
0186: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
0187: * </ul>
0188: * @exception SWTException <ul>
0189: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0190: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0191: * </ul>
0192: *
0193: * @see DisposeListener
0194: * @see #removeDisposeListener
0195: */
0196: public void addDisposeListener(DisposeListener listener) {
0197: checkWidget();
0198: if (listener == null)
0199: error(SWT.ERROR_NULL_ARGUMENT);
0200: TypedListener typedListener = new TypedListener(listener);
0201: addListener(SWT.Dispose, typedListener);
0202: }
0203:
0204: static int checkBits(int style, int int0, int int1, int int2,
0205: int int3, int int4, int int5) {
0206: int mask = int0 | int1 | int2 | int3 | int4 | int5;
0207: if ((style & mask) == 0)
0208: style |= int0;
0209: if ((style & int0) != 0)
0210: style = (style & ~mask) | int0;
0211: if ((style & int1) != 0)
0212: style = (style & ~mask) | int1;
0213: if ((style & int2) != 0)
0214: style = (style & ~mask) | int2;
0215: if ((style & int3) != 0)
0216: style = (style & ~mask) | int3;
0217: if ((style & int4) != 0)
0218: style = (style & ~mask) | int4;
0219: if ((style & int5) != 0)
0220: style = (style & ~mask) | int5;
0221: return style;
0222: }
0223:
0224: void calculateVisibleRegion(int control, int visibleRgn,
0225: boolean clipChildren) {
0226: int tempRgn = OS.NewRgn();
0227: if (OS.IsControlVisible(control)) {
0228: int childRgn = OS.NewRgn();
0229: int window = OS.GetControlOwner(control);
0230: short[] count = new short[1];
0231: int[] outControl = new int[1];
0232: OS.GetRootControl(window, outControl);
0233: int root = outControl[0];
0234: OS.GetControlRegion(root,
0235: (short) OS.kControlStructureMetaPart, visibleRgn);
0236: int tempControl = control, lastControl = 0;
0237: while (tempControl != root) {
0238: OS.GetControlRegion(tempControl,
0239: (short) OS.kControlStructureMetaPart, tempRgn);
0240: if (OS.HIVIEW)
0241: OS.HIViewConvertRegion(tempRgn, tempControl, root);
0242: OS.SectRgn(tempRgn, visibleRgn, visibleRgn);
0243: if (OS.EmptyRgn(visibleRgn))
0244: break;
0245: if (clipChildren || tempControl != control) {
0246: OS.CountSubControls(tempControl, count);
0247: for (int i = 0; i < count[0]; i++) {
0248: OS.GetIndexedSubControl(tempControl,
0249: (short) (OS.HIVIEW ? count[0] - i
0250: : i + 1), outControl);
0251: int child = outControl[0];
0252: if (child == lastControl)
0253: break;
0254: if (!OS.IsControlVisible(child))
0255: continue;
0256: OS.GetControlRegion(child,
0257: (short) OS.kControlStructureMetaPart,
0258: tempRgn);
0259: if (OS.HIVIEW)
0260: OS
0261: .HIViewConvertRegion(tempRgn,
0262: child, root);
0263: OS.UnionRgn(tempRgn, childRgn, childRgn);
0264: }
0265: }
0266: lastControl = tempControl;
0267: OS.GetSuperControl(tempControl, outControl);
0268: tempControl = outControl[0];
0269: }
0270: OS.DiffRgn(visibleRgn, childRgn, visibleRgn);
0271: OS.DisposeRgn(childRgn);
0272: } else {
0273: OS.CopyRgn(tempRgn, visibleRgn);
0274: }
0275: OS.DisposeRgn(tempRgn);
0276: }
0277:
0278: void checkOpen() {
0279: /* Do nothing */
0280: }
0281:
0282: void checkOrientation(Widget parent) {
0283: style &= ~SWT.MIRRORED;
0284: if ((style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT)) == 0) {
0285: if (parent != null) {
0286: if ((parent.style & SWT.LEFT_TO_RIGHT) != 0)
0287: style |= SWT.LEFT_TO_RIGHT;
0288: if ((parent.style & SWT.RIGHT_TO_LEFT) != 0)
0289: style |= SWT.RIGHT_TO_LEFT;
0290: }
0291: }
0292: style = checkBits(style, SWT.LEFT_TO_RIGHT, SWT.RIGHT_TO_LEFT,
0293: 0, 0, 0, 0);
0294: }
0295:
0296: void checkParent(Widget parent) {
0297: if (parent == null)
0298: error(SWT.ERROR_NULL_ARGUMENT);
0299: if (parent.isDisposed())
0300: error(SWT.ERROR_INVALID_ARGUMENT);
0301: parent.checkWidget();
0302: parent.checkOpen();
0303: }
0304:
0305: /**
0306: * Checks that this class can be subclassed.
0307: * <p>
0308: * The SWT class library is intended to be subclassed
0309: * only at specific, controlled points (most notably,
0310: * <code>Composite</code> and <code>Canvas</code> when
0311: * implementing new widgets). This method enforces this
0312: * rule unless it is overridden.
0313: * </p><p>
0314: * <em>IMPORTANT:</em> By providing an implementation of this
0315: * method that allows a subclass of a class which does not
0316: * normally allow subclassing to be created, the implementer
0317: * agrees to be fully responsible for the fact that any such
0318: * subclass will likely fail between SWT releases and will be
0319: * strongly platform specific. No support is provided for
0320: * user-written classes which are implemented in this fashion.
0321: * </p><p>
0322: * The ability to subclass outside of the allowed SWT classes
0323: * is intended purely to enable those not on the SWT development
0324: * team to implement patches in order to get around specific
0325: * limitations in advance of when those limitations can be
0326: * addressed by the team. Subclassing should not be attempted
0327: * without an intimate and detailed understanding of the hierarchy.
0328: * </p>
0329: *
0330: * @exception SWTException <ul>
0331: * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
0332: * </ul>
0333: */
0334: protected void checkSubclass() {
0335: if (!isValidSubclass())
0336: error(SWT.ERROR_INVALID_SUBCLASS);
0337: }
0338:
0339: /**
0340: * Throws an <code>SWTException</code> if the receiver can not
0341: * be accessed by the caller. This may include both checks on
0342: * the state of the receiver and more generally on the entire
0343: * execution context. This method <em>should</em> be called by
0344: * widget implementors to enforce the standard SWT invariants.
0345: * <p>
0346: * Currently, it is an error to invoke any method (other than
0347: * <code>isDisposed()</code>) on a widget that has had its
0348: * <code>dispose()</code> method called. It is also an error
0349: * to call widget methods from any thread that is different
0350: * from the thread that created the widget.
0351: * </p><p>
0352: * In future releases of SWT, there may be more or fewer error
0353: * checks and exceptions may be thrown for different reasons.
0354: * </p>
0355: *
0356: * @exception SWTException <ul>
0357: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0358: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0359: * </ul>
0360: */
0361: protected void checkWidget() {
0362: Display display = this .display;
0363: if (display == null)
0364: error(SWT.ERROR_WIDGET_DISPOSED);
0365: if (display.thread != Thread.currentThread())
0366: error(SWT.ERROR_THREAD_INVALID_ACCESS);
0367: if ((state & DISPOSED) != 0)
0368: error(SWT.ERROR_WIDGET_DISPOSED);
0369: }
0370:
0371: int colorProc(int inControl, int inMessage, int inDrawDepth,
0372: int inDrawInColor) {
0373: return OS.eventNotHandledErr;
0374: }
0375:
0376: boolean contains(int shellX, int shellY) {
0377: return true;
0378: }
0379:
0380: int controlProc(int nextHandler, int theEvent, int userData) {
0381: int eventKind = OS.GetEventKind(theEvent);
0382: switch (eventKind) {
0383: case OS.kEventControlActivate:
0384: return kEventControlActivate(nextHandler, theEvent,
0385: userData);
0386: case OS.kEventControlApplyBackground:
0387: return kEventControlApplyBackground(nextHandler, theEvent,
0388: userData);
0389: case OS.kEventControlBoundsChanged:
0390: return kEventControlBoundsChanged(nextHandler, theEvent,
0391: userData);
0392: case OS.kEventControlClick:
0393: return kEventControlClick(nextHandler, theEvent, userData);
0394: case OS.kEventControlContextualMenuClick:
0395: return kEventControlContextualMenuClick(nextHandler,
0396: theEvent, userData);
0397: case OS.kEventControlDeactivate:
0398: return kEventControlDeactivate(nextHandler, theEvent,
0399: userData);
0400: case OS.kEventControlDraw:
0401: return kEventControlDraw(nextHandler, theEvent, userData);
0402: case OS.kEventControlHit:
0403: return kEventControlHit(nextHandler, theEvent, userData);
0404: case OS.kEventControlSetCursor:
0405: return kEventControlSetCursor(nextHandler, theEvent,
0406: userData);
0407: case OS.kEventControlSetFocusPart:
0408: return kEventControlSetFocusPart(nextHandler, theEvent,
0409: userData);
0410: case OS.kEventControlTrack:
0411: return kEventControlTrack(nextHandler, theEvent, userData);
0412: case OS.kEventControlGetFocusPart:
0413: return kEventControlGetFocusPart(nextHandler, theEvent,
0414: userData);
0415: case OS.kEventControlHitTest:
0416: return kEventControlHitTest(nextHandler, theEvent, userData);
0417: case OS.kEventControlGetClickActivation:
0418: return kEventControlGetClickActivation(nextHandler,
0419: theEvent, userData);
0420: }
0421: return OS.eventNotHandledErr;
0422: }
0423:
0424: int accessibilityProc(int nextHandler, int theEvent, int userData) {
0425: int eventKind = OS.GetEventKind(theEvent);
0426: switch (eventKind) {
0427: case OS.kEventAccessibleGetChildAtPoint:
0428: return kEventAccessibleGetChildAtPoint(nextHandler,
0429: theEvent, userData);
0430: case OS.kEventAccessibleGetAllAttributeNames:
0431: return kEventAccessibleGetAllAttributeNames(nextHandler,
0432: theEvent, userData);
0433: case OS.kEventAccessibleGetNamedAttribute:
0434: return kEventAccessibleGetNamedAttribute(nextHandler,
0435: theEvent, userData);
0436: }
0437: return OS.eventNotHandledErr;
0438: }
0439:
0440: int createCIcon(Image image) {
0441: int imageHandle = image.handle;
0442: int width = OS.CGImageGetWidth(imageHandle);
0443: int height = OS.CGImageGetHeight(imageHandle);
0444: int bpr = OS.CGImageGetBytesPerRow(imageHandle);
0445: int bpp = OS.CGImageGetBitsPerPixel(imageHandle);
0446: int bpc = OS.CGImageGetBitsPerComponent(imageHandle);
0447: int alphaInfo = OS.CGImageGetAlphaInfo(imageHandle);
0448:
0449: int maskBpl = (((width + 7) / 8) + 3) / 4 * 4;
0450: int maskSize = height * maskBpl;
0451: int pixmapSize = height * bpr;
0452:
0453: /* Create the icon */
0454: int iconSize = PixMap.sizeof + BitMap.sizeof * 2 + 4 + maskSize;
0455: int iconHandle = OS.NewHandle(iconSize);
0456: if (iconHandle == 0)
0457: SWT.error(SWT.ERROR_NO_HANDLES);
0458: OS.HLock(iconHandle);
0459: int[] iconPtr = new int[1];
0460: OS.memcpy(iconPtr, iconHandle, 4);
0461:
0462: /* Initialize the pixmap */
0463: PixMap iconPMap = new PixMap();
0464: iconPMap.rowBytes = (short) (bpr | 0x8000);
0465: iconPMap.right = (short) width;
0466: iconPMap.bottom = (short) height;
0467: iconPMap.cmpCount = 3;
0468: iconPMap.cmpSize = (short) bpc;
0469: iconPMap.pmTable = OS.NewHandle(0);
0470: iconPMap.hRes = 72 << 16;
0471: iconPMap.vRes = 72 << 16;
0472: iconPMap.pixelType = (short) OS.RGBDirect;
0473: iconPMap.pixelSize = (short) bpp;
0474: iconPMap.pixelFormat = (short) bpp;
0475: OS.memcpy(iconPtr[0], iconPMap, PixMap.sizeof);
0476:
0477: /* Initialize the mask */
0478: BitMap iconMask = new BitMap();
0479: iconMask.rowBytes = (short) maskBpl;
0480: iconMask.right = (short) width;
0481: iconMask.bottom = (short) height;
0482: OS.memcpy(iconPtr[0] + PixMap.sizeof, iconMask, BitMap.sizeof);
0483:
0484: /* Initialize the icon data */
0485: int iconData = OS.NewHandle(pixmapSize);
0486: OS.HLock(iconData);
0487: int[] iconDataPtr = new int[1];
0488: OS.memcpy(iconDataPtr, iconData, 4);
0489: OS.memcpy(iconDataPtr[0], image.data, pixmapSize);
0490: OS.HUnlock(iconData);
0491: OS.memcpy(iconPtr[0] + PixMap.sizeof + 2 * BitMap.sizeof,
0492: new int[] { iconData }, 4);
0493:
0494: /* Initialize the mask data */
0495: if (alphaInfo != OS.kCGImageAlphaFirst) {
0496: OS.memset(iconPtr[0] + PixMap.sizeof + 2 * BitMap.sizeof
0497: + 4, -1, maskSize);
0498: } else {
0499: byte[] srcData = new byte[pixmapSize];
0500: OS.memcpy(srcData, image.data, pixmapSize);
0501: byte[] maskData = new byte[maskSize];
0502: int offset = 0, maskOffset = 0;
0503: for (int y = 0; y < height; y++) {
0504: for (int x = 0; x < width; x++) {
0505: if ((srcData[offset] & 0xFF) > 128) {
0506: maskData[maskOffset + (x >> 3)] |= (1 << (7 - (x & 0x7)));
0507: } else {
0508: maskData[maskOffset + (x >> 3)] &= ~(1 << (7 - (x & 0x7)));
0509: }
0510: offset += 4;
0511: }
0512: maskOffset += maskBpl;
0513: }
0514: OS.memcpy(iconPtr[0] + PixMap.sizeof + 2 * BitMap.sizeof
0515: + 4, maskData, maskData.length);
0516: }
0517:
0518: OS.HUnlock(iconHandle);
0519: return iconHandle;
0520: }
0521:
0522: void createHandle() {
0523: }
0524:
0525: int createIconRef(Image image) {
0526: int imageHandle = image.handle;
0527: int imageData = image.data;
0528: int width = OS.CGImageGetWidth(imageHandle);
0529: int height = OS.CGImageGetHeight(imageHandle);
0530: int bpr = OS.CGImageGetBytesPerRow(imageHandle);
0531: int alphaInfo = OS.CGImageGetAlphaInfo(imageHandle);
0532:
0533: int type = 0, maskType = 0;
0534: if (width == 16 && height == 16) {
0535: type = OS.kSmall32BitData;
0536: maskType = OS.kSmall8BitMask;
0537: } else if (width == 32 && height == 32) {
0538: type = OS.kLarge32BitData;
0539: maskType = OS.kLarge8BitMask;
0540: } else if (width == 48 && height == 48) {
0541: type = OS.kHuge32BitData;
0542: maskType = OS.kHuge8BitMask;
0543: } else if (width == 128 && height == 128) {
0544: type = OS.kThumbnail32BitData;
0545: maskType = OS.kThumbnail8BitMask;
0546: } else {
0547: type = OS.kSmall32BitData;
0548: maskType = OS.kSmall8BitMask;
0549: int size = 16;
0550: if (width > 16 || height > 16) {
0551: type = OS.kHuge32BitData;
0552: maskType = OS.kHuge8BitMask;
0553: size = 32;
0554: }
0555: if (width > 32 || height > 32) {
0556: type = OS.kHuge32BitData;
0557: maskType = OS.kHuge8BitMask;
0558: size = 48;
0559: }
0560: if (width > 48 || height > 48) {
0561: type = OS.kThumbnail32BitData;
0562: maskType = OS.kThumbnail8BitMask;
0563: size = 128;
0564: }
0565: width = height = size;
0566: bpr = width * 4;
0567: int dataSize = height * bpr;
0568: imageData = OS.NewPtr(dataSize);
0569: if (imageData == 0)
0570: SWT.error(SWT.ERROR_NO_HANDLES);
0571: int colorspace = OS.CGColorSpaceCreateDeviceRGB();
0572: if (colorspace == 0)
0573: SWT.error(SWT.ERROR_NO_HANDLES);
0574: int context = OS.CGBitmapContextCreate(imageData, width,
0575: height, 8, bpr, colorspace,
0576: OS.kCGImageAlphaNoneSkipFirst);
0577: OS.CGColorSpaceRelease(colorspace);
0578: if (context == 0)
0579: SWT.error(SWT.ERROR_NO_HANDLES);
0580: CGRect rect = new CGRect();
0581: rect.width = width;
0582: rect.height = height;
0583: OS.CGContextDrawImage(context, rect, imageHandle);
0584: OS.CGContextRelease(context);
0585: }
0586: if (type == 0)
0587: return 0;
0588:
0589: int iconFamily = OS.NewHandle(0);
0590: if (iconFamily == 0)
0591: SWT.error(SWT.ERROR_NO_HANDLES);
0592:
0593: int dataSize = height * bpr;
0594: int dataHandle = OS.NewHandle(dataSize);
0595: if (dataHandle == 0)
0596: SWT.error(SWT.ERROR_NO_HANDLES);
0597: int[] dataPtr = new int[1];
0598: OS.HLock(dataHandle);
0599: OS.memcpy(dataPtr, dataHandle, 4);
0600: OS.memcpy(dataPtr[0], imageData, dataSize);
0601: OS.HUnlock(dataHandle);
0602: OS.SetIconFamilyData(iconFamily, type, dataHandle);
0603: OS.DisposeHandle(dataHandle);
0604:
0605: /* Initialize the mask data */
0606: int maskSize = width * height;
0607: int maskHandle = OS.NewHandle(maskSize);
0608: if (maskHandle == 0)
0609: SWT.error(SWT.ERROR_NO_HANDLES);
0610: OS.HLock(maskHandle);
0611: int[] maskPtr = new int[1];
0612: OS.memcpy(maskPtr, maskHandle, 4);
0613: if (alphaInfo != OS.kCGImageAlphaFirst) {
0614: OS.memset(maskPtr[0], 0xFF, maskSize);
0615: } else {
0616: byte[] srcData = new byte[dataSize];
0617: OS.memcpy(srcData, imageData, dataSize);
0618: byte[] maskData = new byte[maskSize];
0619: int offset = 0, maskOffset = 0;
0620: for (int y = 0; y < height; y++) {
0621: for (int x = 0; x < width; x++) {
0622: maskData[maskOffset++] = srcData[offset];
0623: offset += 4;
0624: }
0625: }
0626: OS.memcpy(maskPtr[0], maskData, maskData.length);
0627: }
0628: OS.HUnlock(maskHandle);
0629: OS.SetIconFamilyData(iconFamily, maskType, maskHandle);
0630: OS.DisposeHandle(maskHandle);
0631:
0632: if (imageData != image.data)
0633: OS.DisposePtr(imageData);
0634:
0635: /* Create the icon ref */
0636: int[] iconRef = new int[1];
0637: OS.HLock(iconFamily);
0638: int[] iconPtr = new int[1];
0639: OS.memcpy(iconPtr, iconFamily, 4);
0640: OS.GetIconRefFromIconFamilyPtr(iconPtr[0], OS
0641: .GetHandleSize(iconFamily), iconRef);
0642: OS.HUnlock(iconFamily);
0643: OS.DisposeHandle(iconFamily);
0644: return iconRef[0];
0645: }
0646:
0647: void createWidget() {
0648: createHandle();
0649: register();
0650: hookEvents();
0651: }
0652:
0653: int commandProc(int nextHandler, int theEvent, int userData) {
0654: int eventKind = OS.GetEventKind(theEvent);
0655: switch (eventKind) {
0656: case OS.kEventProcessCommand:
0657: return kEventProcessCommand(nextHandler, theEvent, userData);
0658: }
0659: return OS.eventNotHandledErr;
0660: }
0661:
0662: void deregister() {
0663: }
0664:
0665: void destroyWidget() {
0666: releaseHandle();
0667: }
0668:
0669: void destroyCIcon(int iconHandle) {
0670: OS.HLock(iconHandle);
0671:
0672: /* Dispose the ColorTable */
0673: int[] iconPtr = new int[1];
0674: OS.memcpy(iconPtr, iconHandle, 4);
0675: PixMap iconPMap = new PixMap();
0676: OS.memcpy(iconPMap, iconPtr[0], PixMap.sizeof);
0677: if (iconPMap.pmTable != 0)
0678: OS.DisposeHandle(iconPMap.pmTable);
0679:
0680: /* Dispose the icon data */
0681: int[] iconData = new int[1];
0682: OS.memcpy(iconData, iconPtr[0] + PixMap.sizeof + 2
0683: * BitMap.sizeof, 4);
0684: if (iconData[0] != 0)
0685: OS.DisposeHandle(iconData[0]);
0686:
0687: OS.HUnlock(iconHandle);
0688:
0689: /* Dispose the icon */
0690: OS.DisposeHandle(iconHandle);
0691: }
0692:
0693: int drawItemProc(int browser, int item, int property,
0694: int itemState, int theRect, int gdDepth, int colorDevice) {
0695: return OS.noErr;
0696: }
0697:
0698: /**
0699: * Disposes of the operating system resources associated with
0700: * the receiver and all its descendents. After this method has
0701: * been invoked, the receiver and all descendents will answer
0702: * <code>true</code> when sent the message <code>isDisposed()</code>.
0703: * Any internal connections between the widgets in the tree will
0704: * have been removed to facilitate garbage collection.
0705: * <p>
0706: * NOTE: This method is not called recursively on the descendents
0707: * of the receiver. This means that, widget implementers can not
0708: * detect when a widget is being disposed of by re-implementing
0709: * this method, but should instead listen for the <code>Dispose</code>
0710: * event.
0711: * </p>
0712: *
0713: * @exception SWTException <ul>
0714: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0715: * </ul>
0716: *
0717: * @see #addDisposeListener
0718: * @see #removeDisposeListener
0719: * @see #checkWidget
0720: */
0721: public void dispose() {
0722: /*
0723: * Note: It is valid to attempt to dispose a widget
0724: * more than once. If this happens, fail silently.
0725: */
0726: if (isDisposed())
0727: return;
0728: if (!isValidThread())
0729: error(SWT.ERROR_THREAD_INVALID_ACCESS);
0730: release(true);
0731: }
0732:
0733: void drawBackground(int control, int context) {
0734: /* Do nothing */
0735: }
0736:
0737: void drawWidget(int control, int context, int damageRgn,
0738: int visibleRgn, int theEvent) {
0739: }
0740:
0741: void error(int code) {
0742: SWT.error(code);
0743: }
0744:
0745: boolean filters(int eventType) {
0746: return display.filters(eventType);
0747: }
0748:
0749: int fixMnemonic(char[] buffer) {
0750: int i = 0, j = 0;
0751: while (i < buffer.length) {
0752: if ((buffer[j++] = buffer[i++]) == '&') {
0753: if (i == buffer.length) {
0754: continue;
0755: }
0756: if (buffer[i] == '&') {
0757: i++;
0758: continue;
0759: }
0760: j--;
0761: }
0762: }
0763: return j;
0764: }
0765:
0766: Rectangle getControlBounds(int control) {
0767: if (OS.HIVIEW) {
0768: CGRect rect = new CGRect();
0769: OS.HIViewGetFrame(control, rect);
0770: Rect inset = getInset();
0771: rect.x -= inset.left;
0772: rect.y -= inset.top;
0773: rect.width += inset.right + inset.left;
0774: rect.height += inset.bottom + inset.top;
0775: return new Rectangle((int) rect.x, (int) rect.y,
0776: (int) rect.width, (int) rect.height);
0777: }
0778: Rect rect = new Rect();
0779: OS.GetControlBounds(control, rect);
0780: int window = OS.GetControlOwner(control);
0781: int[] theRoot = new int[1];
0782: OS.GetRootControl(window, theRoot);
0783: int[] parentHandle = new int[1];
0784: OS.GetSuperControl(control, parentHandle);
0785: if (parentHandle[0] != theRoot[0]) {
0786: Rect parentRect = new Rect();
0787: OS.GetControlBounds(parentHandle[0], parentRect);
0788: OS.OffsetRect(rect, (short) -parentRect.left,
0789: (short) -parentRect.top);
0790: }
0791: Rect inset = getInset();
0792: rect.left -= inset.left;
0793: rect.top -= inset.top;
0794: rect.right += inset.right;
0795: rect.bottom += inset.bottom;
0796: return new Rectangle(rect.left, rect.top, rect.right
0797: - rect.left, rect.bottom - rect.top);
0798: }
0799:
0800: Point getControlSize(int control) {
0801: if (OS.HIVIEW) {
0802: CGRect rect = new CGRect();
0803: OS.HIViewGetFrame(control, rect);
0804: Rect inset = getInset();
0805: int width = (int) rect.width + inset.left + inset.right;
0806: int height = (int) rect.height + inset.top + inset.bottom;
0807: return new Point(width, height);
0808: }
0809: Rect rect = new Rect();
0810: OS.GetControlBounds(control, rect);
0811: Rect inset = getInset();
0812: rect.left -= inset.left;
0813: rect.top -= inset.top;
0814: rect.right += inset.right;
0815: rect.bottom += inset.bottom;
0816: return new Point(rect.right - rect.left, rect.bottom - rect.top);
0817: }
0818:
0819: /**
0820: * Returns the application defined widget data associated
0821: * with the receiver, or null if it has not been set. The
0822: * <em>widget data</em> is a single, unnamed field that is
0823: * stored with every widget.
0824: * <p>
0825: * Applications may put arbitrary objects in this field. If
0826: * the object stored in the widget data needs to be notified
0827: * when the widget is disposed of, it is the application's
0828: * responsibility to hook the Dispose event on the widget and
0829: * do so.
0830: * </p>
0831: *
0832: * @return the widget data
0833: *
0834: * @exception SWTException <ul>
0835: * <li>ERROR_WIDGET_DISPOSED - when the receiver has been disposed</li>
0836: * <li>ERROR_THREAD_INVALID_ACCESS - when called from the wrong thread</li>
0837: * </ul>
0838: *
0839: * @see #setData(Object)
0840: */
0841: public Object getData() {
0842: checkWidget();
0843: return (state & KEYED_DATA) != 0 ? ((Object[]) data)[0] : data;
0844: }
0845:
0846: /**
0847: * Returns the application defined property of the receiver
0848: * with the specified name, or null if it has not been set.
0849: * <p>
0850: * Applications may have associated arbitrary objects with the
0851: * receiver in this fashion. If the objects stored in the
0852: * properties need to be notified when the widget is disposed
0853: * of, it is the application's responsibility to hook the
0854: * Dispose event on the widget and do so.
0855: * </p>
0856: *
0857: * @param key the name of the property
0858: * @return the value of the property or null if it has not been set
0859: *
0860: * @exception IllegalArgumentException <ul>
0861: * <li>ERROR_NULL_ARGUMENT - if the key is null</li>
0862: * </ul>
0863: * @exception SWTException <ul>
0864: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0865: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0866: * </ul>
0867: *
0868: * @see #setData(String, Object)
0869: */
0870: public Object getData(String key) {
0871: checkWidget();
0872: if (key == null)
0873: error(SWT.ERROR_NULL_ARGUMENT);
0874: if ((state & KEYED_DATA) != 0) {
0875: Object[] table = (Object[]) data;
0876: for (int i = 1; i < table.length; i += 2) {
0877: if (key.equals(table[i]))
0878: return table[i + 1];
0879: }
0880: }
0881: return null;
0882: }
0883:
0884: /**
0885: * Returns the <code>Display</code> that is associated with
0886: * the receiver.
0887: * <p>
0888: * A widget's display is either provided when it is created
0889: * (for example, top level <code>Shell</code>s) or is the
0890: * same as its parent's display.
0891: * </p>
0892: *
0893: * @return the receiver's display
0894: *
0895: * @exception SWTException <ul>
0896: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0897: * </ul>
0898: */
0899: public Display getDisplay() {
0900: Display display = this .display;
0901: if (display == null)
0902: error(SWT.ERROR_WIDGET_DISPOSED);
0903: return display;
0904: }
0905:
0906: int getDrawCount(int control) {
0907: return 0;
0908: }
0909:
0910: Rect getInset() {
0911: return EMPTY_RECT;
0912: }
0913:
0914: String getName() {
0915: String string = getClass().getName();
0916: int index = string.lastIndexOf('.');
0917: if (index == -1)
0918: return string;
0919: return string.substring(index + 1, string.length());
0920: }
0921:
0922: String getNameText() {
0923: return "";
0924: }
0925:
0926: /**
0927: * Returns the receiver's style information.
0928: * <p>
0929: * Note that the value which is returned by this method <em>may
0930: * not match</em> the value which was provided to the constructor
0931: * when the receiver was created. This can occur when the underlying
0932: * operating system does not support a particular combination of
0933: * requested styles. For example, if the platform widget used to
0934: * implement a particular SWT widget always has scroll bars, the
0935: * result of calling this method would always have the
0936: * <code>SWT.H_SCROLL</code> and <code>SWT.V_SCROLL</code> bits set.
0937: * </p>
0938: *
0939: * @return the style bits
0940: *
0941: * @exception SWTException <ul>
0942: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
0943: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
0944: * </ul>
0945: */
0946: public int getStyle() {
0947: checkWidget();
0948: return style;
0949: }
0950:
0951: int getVisibleRegion(int control, boolean clipChildren) {
0952: int visibleRgn = OS.NewRgn();
0953: calculateVisibleRegion(control, visibleRgn, clipChildren);
0954: return visibleRgn;
0955: }
0956:
0957: int helpProc(int inControl, int inGlobalMouse, int inRequest,
0958: int outContentProvided, int ioHelpContent) {
0959: return OS.eventNotHandledErr;
0960: }
0961:
0962: int hitTestProc(int browser, int item, int property, int theRect,
0963: int mouseRect) {
0964: /* Return true to indicate that the item can be selected */
0965: return 1;
0966: }
0967:
0968: void hookEvents() {
0969: }
0970:
0971: boolean hooks(int eventType) {
0972: if (eventTable == null)
0973: return false;
0974: return eventTable.hooks(eventType);
0975: }
0976:
0977: void invalidateVisibleRegion(int control) {
0978: }
0979:
0980: void invalWindowRgn(int window, int rgn) {
0981: OS.InvalWindowRgn(window, rgn);
0982: }
0983:
0984: /**
0985: * Returns <code>true</code> if the widget has been disposed,
0986: * and <code>false</code> otherwise.
0987: * <p>
0988: * This method gets the dispose state for the widget.
0989: * When a widget has been disposed, it is an error to
0990: * invoke any other method using the widget.
0991: * </p>
0992: *
0993: * @return <code>true</code> when the widget is disposed and <code>false</code> otherwise
0994: */
0995: public boolean isDisposed() {
0996: return (state & DISPOSED) != 0;
0997: }
0998:
0999: boolean isDrawing(int control) {
1000: return OS.IsControlVisible(control)
1001: && getDrawCount(control) == 0;
1002: }
1003:
1004: boolean isEnabled() {
1005: return true;
1006: }
1007:
1008: /**
1009: * Returns <code>true</code> if there are any listeners
1010: * for the specified event type associated with the receiver,
1011: * and <code>false</code> otherwise. The event type is one of
1012: * the event constants defined in class <code>SWT</code>.
1013: *
1014: * @param eventType the type of event
1015: * @return true if the event is hooked
1016: *
1017: * @exception SWTException <ul>
1018: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1019: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1020: * </ul>
1021: *
1022: * @see SWT
1023: */
1024: public boolean isListening(int eventType) {
1025: checkWidget();
1026: return hooks(eventType);
1027: }
1028:
1029: boolean isTrimHandle(int trimHandle) {
1030: return false;
1031: }
1032:
1033: boolean isValidSubclass() {
1034: return Display.isValidClass(getClass());
1035: }
1036:
1037: boolean isValidThread() {
1038: return getDisplay().isValidThread();
1039: }
1040:
1041: int itemCompareProc(int browser, int itemOne, int itemTwo,
1042: int sortProperty) {
1043: return OS.noErr;
1044: }
1045:
1046: int itemDataProc(int browser, int item, int property, int itemData,
1047: int setValue) {
1048: return OS.noErr;
1049: }
1050:
1051: int itemNotificationProc(int browser, int item, int message) {
1052: return OS.noErr;
1053: }
1054:
1055: int kEventAccessibleGetChildAtPoint(int nextHandler, int theEvent,
1056: int userData) {
1057: return OS.eventNotHandledErr;
1058: }
1059:
1060: int kEventAccessibleGetAllAttributeNames(int nextHandler,
1061: int theEvent, int userData) {
1062: return OS.eventNotHandledErr;
1063: }
1064:
1065: int kEventAccessibleGetNamedAttribute(int nextHandler,
1066: int theEvent, int userData) {
1067: return OS.eventNotHandledErr;
1068: }
1069:
1070: int kEventProcessCommand(int nextHandler, int theEvent, int userData) {
1071: return OS.eventNotHandledErr;
1072: }
1073:
1074: int kEventControlApplyBackground(int nextHandler, int theEvent,
1075: int userData) {
1076: return OS.eventNotHandledErr;
1077: }
1078:
1079: int kEventControlActivate(int nextHandler, int theEvent,
1080: int userData) {
1081: return OS.eventNotHandledErr;
1082: }
1083:
1084: int kEventControlBoundsChanged(int nextHandler, int theEvent,
1085: int userData) {
1086: return OS.eventNotHandledErr;
1087: }
1088:
1089: int kEventControlClick(int nextHandler, int theEvent, int userData) {
1090: return OS.eventNotHandledErr;
1091: }
1092:
1093: int kEventControlContextualMenuClick(int nextHandler, int theEvent,
1094: int userData) {
1095: return OS.eventNotHandledErr;
1096: }
1097:
1098: int kEventControlDeactivate(int nextHandler, int theEvent,
1099: int userData) {
1100: return OS.eventNotHandledErr;
1101: }
1102:
1103: int kEventControlDraw(int nextHandler, int theEvent, int userData) {
1104: int[] theControl = new int[1];
1105: OS.GetEventParameter(theEvent, OS.kEventParamDirectObject,
1106: OS.typeControlRef, null, 4, null, theControl);
1107: int[] region = new int[1];
1108: OS.GetEventParameter(theEvent, OS.kEventParamRgnHandle,
1109: OS.typeQDRgnHandle, null, 4, null, region);
1110: if (OS.HIVIEW) {
1111: boolean oldInPaint = display.inPaint;
1112: display.inPaint = true;
1113: int[] context = new int[1];
1114: OS.GetEventParameter(theEvent, OS.kEventParamCGContextRef,
1115: OS.typeCGContextRef, null, 4, null, context);
1116: int visibleRgn = region[0];
1117: drawBackground(theControl[0], context[0]);
1118: callPaintEventHandler(theControl[0], region[0], visibleRgn,
1119: theEvent, nextHandler);
1120: drawWidget(theControl[0], context[0], region[0],
1121: visibleRgn, theEvent);
1122: display.inPaint = oldInPaint;
1123: } else {
1124: if (getDrawCount(theControl[0]) > 0)
1125: return OS.noErr;
1126: int visibleRgn = getVisibleRegion(theControl[0], true);
1127: OS.SectRgn(region[0], visibleRgn, visibleRgn);
1128: if (!OS.EmptyRgn(visibleRgn)) {
1129: int[] port = new int[1];
1130: OS.GetPort(port);
1131: OS.LockPortBits(port[0]);
1132: // OS.QDSetDirtyRegion (port, visibleRgn);
1133: int oldClip = OS.NewRgn();
1134: OS.GetClip(oldClip);
1135: OS.SetClip(visibleRgn);
1136: drawBackground(theControl[0], 0);
1137: callPaintEventHandler(theControl[0], region[0],
1138: visibleRgn, theEvent, nextHandler);
1139: drawWidget(theControl[0], 0, region[0], visibleRgn,
1140: theEvent);
1141: OS.SetClip(oldClip);
1142: OS.DisposeRgn(oldClip);
1143: OS.UnlockPortBits(port[0]);
1144: }
1145: OS.DisposeRgn(visibleRgn);
1146: }
1147: return OS.noErr;
1148: }
1149:
1150: int kEventControlGetClickActivation(int nextHandler, int theEvent,
1151: int userData) {
1152: return OS.eventNotHandledErr;
1153: }
1154:
1155: int kEventControlGetFocusPart(int nextHandler, int theEvent,
1156: int userData) {
1157: return OS.eventNotHandledErr;
1158: }
1159:
1160: int kEventControlHit(int nextHandler, int theEvent, int userData) {
1161: return OS.eventNotHandledErr;
1162: }
1163:
1164: int kEventControlHitTest(int nextHandler, int theEvent, int userData) {
1165: return OS.eventNotHandledErr;
1166: }
1167:
1168: int kEventControlSetCursor(int nextHandler, int theEvent,
1169: int userData) {
1170: return OS.eventNotHandledErr;
1171: }
1172:
1173: int kEventControlSetFocusPart(int nextHandler, int theEvent,
1174: int userData) {
1175: return OS.eventNotHandledErr;
1176: }
1177:
1178: int kEventControlTrack(int nextHandler, int theEvent, int userData) {
1179: return OS.eventNotHandledErr;
1180: }
1181:
1182: int kEventMenuCalculateSize(int nextHandler, int theEvent,
1183: int userData) {
1184: return OS.eventNotHandledErr;
1185: }
1186:
1187: int kEventMenuClosed(int nextHandler, int theEvent, int userData) {
1188: return OS.eventNotHandledErr;
1189: }
1190:
1191: int kEventMenuCreateFrameView(int nextHandler, int theEvent,
1192: int userData) {
1193: return OS.eventNotHandledErr;
1194: }
1195:
1196: int kEventMenuDrawItem(int nextHandler, int theEvent, int userData) {
1197: return OS.eventNotHandledErr;
1198: }
1199:
1200: int kEventMenuDrawItemContent(int nextHandler, int theEvent,
1201: int userData) {
1202: return OS.eventNotHandledErr;
1203: }
1204:
1205: int kEventMenuGetFrameBounds(int nextHandler, int theEvent,
1206: int userData) {
1207: return OS.eventNotHandledErr;
1208: }
1209:
1210: int kEventMenuMeasureItemWidth(int nextHandler, int theEvent,
1211: int userData) {
1212: return OS.eventNotHandledErr;
1213: }
1214:
1215: int kEventMenuOpening(int nextHandler, int theEvent, int userData) {
1216: return OS.eventNotHandledErr;
1217: }
1218:
1219: int kEventMenuTargetItem(int nextHandler, int theEvent, int userData) {
1220: return OS.eventNotHandledErr;
1221: }
1222:
1223: int kEventMouseDown(int nextHandler, int theEvent, int userData) {
1224: return OS.eventNotHandledErr;
1225: }
1226:
1227: int kEventMouseDragged(int nextHandler, int theEvent, int userData) {
1228: return OS.eventNotHandledErr;
1229: }
1230:
1231: int kEventMouseMoved(int nextHandler, int theEvent, int userData) {
1232: return OS.eventNotHandledErr;
1233: }
1234:
1235: int kEventMouseUp(int nextHandler, int theEvent, int userData) {
1236: return OS.eventNotHandledErr;
1237: }
1238:
1239: int kEventMouseWheelMoved(int nextHandler, int theEvent,
1240: int userData) {
1241: return OS.eventNotHandledErr;
1242: }
1243:
1244: int kEventRawKeyDown(int nextHandler, int theEvent, int userData) {
1245: return kEventRawKeyPressed(nextHandler, theEvent, userData);
1246: }
1247:
1248: int kEventRawKeyModifiersChanged(int nextHandler, int theEvent,
1249: int userData) {
1250: Display display = this .display;
1251: int[] modifiers = new int[1];
1252: OS.GetEventParameter(theEvent, OS.kEventParamKeyModifiers,
1253: OS.typeUInt32, null, modifiers.length * 4, null,
1254: modifiers);
1255: int lastModifiers = display.lastModifiers;
1256: int chord = OS.GetCurrentEventButtonState();
1257: int type = SWT.KeyUp;
1258: if ((modifiers[0] & OS.alphaLock) != 0
1259: && (lastModifiers & OS.alphaLock) == 0)
1260: type = SWT.KeyDown;
1261: if ((modifiers[0] & OS.shiftKey) != 0
1262: && (lastModifiers & OS.shiftKey) == 0)
1263: type = SWT.KeyDown;
1264: if ((modifiers[0] & OS.controlKey) != 0
1265: && (lastModifiers & OS.controlKey) == 0)
1266: type = SWT.KeyDown;
1267: if ((modifiers[0] & OS.cmdKey) != 0
1268: && (lastModifiers & OS.cmdKey) == 0)
1269: type = SWT.KeyDown;
1270: if ((modifiers[0] & OS.optionKey) != 0
1271: && (lastModifiers & OS.optionKey) == 0)
1272: type = SWT.KeyDown;
1273: if (type == SWT.KeyUp && (modifiers[0] & OS.alphaLock) == 0
1274: && (lastModifiers & OS.alphaLock) != 0) {
1275: Event event = new Event();
1276: event.keyCode = SWT.CAPS_LOCK;
1277: setInputState(event, SWT.KeyDown, chord, modifiers[0]);
1278: sendKeyEvent(SWT.KeyDown, event);
1279: }
1280: Event event = new Event();
1281: setInputState(event, type, chord, modifiers[0]);
1282: if (event.keyCode == 0 && event.character == 0)
1283: return OS.eventNotHandledErr;
1284: boolean result = sendKeyEvent(type, event);
1285: if (type == SWT.KeyDown && (modifiers[0] & OS.alphaLock) != 0
1286: && (lastModifiers & OS.alphaLock) == 0) {
1287: event = new Event();
1288: event.keyCode = SWT.CAPS_LOCK;
1289: setInputState(event, SWT.KeyUp, chord, modifiers[0]);
1290: sendKeyEvent(SWT.KeyUp, event);
1291: }
1292: display.lastModifiers = modifiers[0];
1293: return result ? OS.eventNotHandledErr : OS.noErr;
1294: }
1295:
1296: int kEventRawKeyPressed(int nextHandler, int theEvent, int userData) {
1297: return OS.eventNotHandledErr;
1298: }
1299:
1300: int kEventRawKeyRepeat(int nextHandler, int theEvent, int userData) {
1301: return kEventRawKeyPressed(nextHandler, theEvent, userData);
1302: }
1303:
1304: int kEventRawKeyUp(int nextHandler, int theEvent, int userData) {
1305: if (!sendKeyEvent(SWT.KeyUp, theEvent))
1306: return OS.noErr;
1307: return OS.eventNotHandledErr;
1308: }
1309:
1310: int kEventTextInputUnicodeForKeyEvent(int nextHandler,
1311: int theEvent, int userData) {
1312: return OS.eventNotHandledErr;
1313: }
1314:
1315: int kEventWindowActivated(int nextHandler, int theEvent,
1316: int userData) {
1317: return OS.eventNotHandledErr;
1318: }
1319:
1320: int kEventWindowBoundsChanged(int nextHandler, int theEvent,
1321: int userData) {
1322: return OS.eventNotHandledErr;
1323: }
1324:
1325: int kEventWindowClose(int nextHandler, int theEvent, int userData) {
1326: return OS.eventNotHandledErr;
1327: }
1328:
1329: int kEventWindowCollapsed(int nextHandler, int theEvent,
1330: int userData) {
1331: return OS.eventNotHandledErr;
1332: }
1333:
1334: int kEventWindowDeactivated(int nextHandler, int theEvent,
1335: int userData) {
1336: return OS.eventNotHandledErr;
1337: }
1338:
1339: int kEventWindowDrawContent(int nextHandler, int theEvent,
1340: int userData) {
1341: return OS.eventNotHandledErr;
1342: }
1343:
1344: int kEventWindowExpanded(int nextHandler, int theEvent, int userData) {
1345: return OS.eventNotHandledErr;
1346: }
1347:
1348: int kEventWindowGetClickModality(int nextHandler, int theEvent,
1349: int userData) {
1350: return OS.eventNotHandledErr;
1351: }
1352:
1353: int kEventWindowGetRegion(int nextHandler, int theEvent,
1354: int userData) {
1355: return OS.eventNotHandledErr;
1356: }
1357:
1358: int kEventWindowHidden(int nextHandler, int theEvent, int userData) {
1359: return OS.eventNotHandledErr;
1360: }
1361:
1362: int kEventWindowHitTest(int nextHandler, int theEvent, int userData) {
1363: return OS.eventNotHandledErr;
1364: }
1365:
1366: int kEventWindowShown(int nextHandler, int theEvent, int userData) {
1367: return OS.eventNotHandledErr;
1368: }
1369:
1370: int kEventWindowUpdate(int nextHandler, int theEvent, int userData) {
1371: return OS.eventNotHandledErr;
1372: }
1373:
1374: int keyboardProc(int nextHandler, int theEvent, int userData) {
1375: int eventKind = OS.GetEventKind(theEvent);
1376: switch (eventKind) {
1377: case OS.kEventRawKeyDown:
1378: return kEventRawKeyDown(nextHandler, theEvent, userData);
1379: case OS.kEventRawKeyModifiersChanged:
1380: return kEventRawKeyModifiersChanged(nextHandler, theEvent,
1381: userData);
1382: case OS.kEventRawKeyRepeat:
1383: return kEventRawKeyRepeat(nextHandler, theEvent, userData);
1384: case OS.kEventRawKeyUp:
1385: return kEventRawKeyUp(nextHandler, theEvent, userData);
1386: }
1387: return OS.eventNotHandledErr;
1388: }
1389:
1390: int menuProc(int nextHandler, int theEvent, int userData) {
1391: int eventKind = OS.GetEventKind(theEvent);
1392: switch (eventKind) {
1393: case OS.kEventMenuCalculateSize:
1394: return kEventMenuCalculateSize(nextHandler, theEvent,
1395: userData);
1396: case OS.kEventMenuClosed:
1397: return kEventMenuClosed(nextHandler, theEvent, userData);
1398: case OS.kEventMenuCreateFrameView:
1399: return kEventMenuCreateFrameView(nextHandler, theEvent,
1400: userData);
1401: case OS.kEventMenuDrawItem:
1402: return kEventMenuDrawItem(nextHandler, theEvent, userData);
1403: case OS.kEventMenuDrawItemContent:
1404: return kEventMenuDrawItemContent(nextHandler, theEvent,
1405: userData);
1406: case OS.kEventMenuGetFrameBounds:
1407: return kEventMenuGetFrameBounds(nextHandler, theEvent,
1408: userData);
1409: case OS.kEventMenuMeasureItemWidth:
1410: return kEventMenuMeasureItemWidth(nextHandler, theEvent,
1411: userData);
1412: case OS.kEventMenuOpening:
1413: return kEventMenuOpening(nextHandler, theEvent, userData);
1414: case OS.kEventMenuTargetItem:
1415: return kEventMenuTargetItem(nextHandler, theEvent, userData);
1416: }
1417: return OS.eventNotHandledErr;
1418: }
1419:
1420: int mouseProc(int nextHandler, int theEvent, int userData) {
1421: int eventKind = OS.GetEventKind(theEvent);
1422: switch (eventKind) {
1423: case OS.kEventMouseDown:
1424: return kEventMouseDown(nextHandler, theEvent, userData);
1425: case OS.kEventMouseUp:
1426: return kEventMouseUp(nextHandler, theEvent, userData);
1427: case OS.kEventMouseDragged:
1428: return kEventMouseDragged(nextHandler, theEvent, userData);
1429: // case OS.kEventMouseEntered: return kEventMouseEntered (nextHandler, theEvent, userData);
1430: // case OS.kEventMouseExited: return kEventMouseExited (nextHandler, theEvent, userData);
1431: case OS.kEventMouseMoved:
1432: return kEventMouseMoved(nextHandler, theEvent, userData);
1433: case OS.kEventMouseWheelMoved:
1434: return kEventMouseWheelMoved(nextHandler, theEvent,
1435: userData);
1436: }
1437: return OS.eventNotHandledErr;
1438: }
1439:
1440: /**
1441: * Notifies all of the receiver's listeners for events
1442: * of the given type that one such event has occurred by
1443: * invoking their <code>handleEvent()</code> method. The
1444: * event type is one of the event constants defined in class
1445: * <code>SWT</code>.
1446: *
1447: * @param eventType the type of event which has occurred
1448: * @param event the event data
1449: *
1450: * @exception SWTException <ul>
1451: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1452: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1453: * </ul>
1454: *
1455: * @see SWT
1456: * @see #addListener
1457: * @see #removeListener
1458: */
1459: public void notifyListeners(int eventType, Event event) {
1460: checkWidget();
1461: if (event == null)
1462: event = new Event();
1463: sendEvent(eventType, event);
1464: }
1465:
1466: void postEvent(int eventType) {
1467: sendEvent(eventType, null, false);
1468: }
1469:
1470: void postEvent(int eventType, Event event) {
1471: sendEvent(eventType, event, false);
1472: }
1473:
1474: void redrawChildren(int control) {
1475: int child = OS.HIViewGetFirstSubview(control);
1476: while (child != 0) {
1477: OS.HIViewSetNeedsDisplay(child, true);
1478: redrawChildren(child);
1479: child = OS.HIViewGetNextView(child);
1480: }
1481: }
1482:
1483: void redrawChildren(int control, int rgn) {
1484: int child = OS.HIViewGetFirstSubview(control);
1485: while (child != 0) {
1486: OS.HIViewConvertRegion(rgn, control, child);
1487: OS.HIViewSetNeedsDisplayInRegion(child, rgn, true);
1488: redrawChildren(child, rgn);
1489: OS.HIViewConvertRegion(rgn, child, control);
1490: child = OS.HIViewGetNextView(child);
1491: }
1492: }
1493:
1494: void redrawWidget(int control, boolean children) {
1495: if (OS.HIVIEW) {
1496: if (display.inPaint) {
1497: int rgn = OS.NewRgn();
1498: Rect rect = new Rect();
1499: OS.GetControlBounds(control, rect);
1500: rect.right += rect.left;
1501: rect.bottom += rect.top;
1502: rect.top = rect.left = 0;
1503: OS.RectRgn(rgn, rect);
1504: OS.HIViewConvertRegion(rgn, control, 0);
1505: invalWindowRgn(0, rgn);
1506: OS.DisposeRgn(rgn);
1507: } else {
1508: OS.HIViewSetNeedsDisplay(control, true);
1509: if (children)
1510: redrawChildren(control);
1511: }
1512: return;
1513: }
1514: if (!isDrawing(control))
1515: return;
1516: int window = OS.GetControlOwner(control);
1517: int visibleRgn = getVisibleRegion(control, !children);
1518: invalWindowRgn(window, visibleRgn);
1519: OS.DisposeRgn(visibleRgn);
1520: }
1521:
1522: void redrawWidget(int control, int x, int y, int width, int height,
1523: boolean children) {
1524: if (OS.HIVIEW) {
1525: int rgn = OS.NewRgn();
1526: Rect rect = new Rect();
1527: OS.SetRect(rect, (short) x, (short) y, (short) (x + width),
1528: (short) (y + height));
1529: OS.RectRgn(rgn, rect);
1530: if (display.inPaint) {
1531: OS.HIViewConvertRegion(rgn, control, 0);
1532: invalWindowRgn(0, rgn);
1533: } else {
1534: OS.HIViewSetNeedsDisplayInRegion(control, rgn, true);
1535: if (children)
1536: redrawChildren(control, rgn);
1537: }
1538: OS.DisposeRgn(rgn);
1539: return;
1540: }
1541: if (!isDrawing(control))
1542: return;
1543: Rect rect = new Rect();
1544: OS.GetControlBounds(control, rect);
1545: x += rect.left;
1546: y += rect.top;
1547: OS.SetRect(rect, (short) x, (short) y, (short) (x + width),
1548: (short) (y + height));
1549: int rectRgn = OS.NewRgn();
1550: OS.RectRgn(rectRgn, rect);
1551: int visibleRgn = getVisibleRegion(control, !children);
1552: OS.SectRgn(rectRgn, visibleRgn, visibleRgn);
1553: int window = OS.GetControlOwner(control);
1554: invalWindowRgn(window, visibleRgn);
1555: OS.DisposeRgn(rectRgn);
1556: OS.DisposeRgn(visibleRgn);
1557: }
1558:
1559: void register() {
1560: }
1561:
1562: void release(boolean destroy) {
1563: if ((state & DISPOSE_SENT) == 0) {
1564: state |= DISPOSE_SENT;
1565: sendEvent(SWT.Dispose);
1566: }
1567: if ((state & DISPOSED) == 0) {
1568: releaseChildren(destroy);
1569: }
1570: if ((state & RELEASED) == 0) {
1571: state |= RELEASED;
1572: if (destroy) {
1573: releaseParent();
1574: releaseWidget();
1575: destroyWidget();
1576: } else {
1577: releaseWidget();
1578: releaseHandle();
1579: }
1580: }
1581: }
1582:
1583: void releaseChildren(boolean destroy) {
1584: }
1585:
1586: void releaseHandle() {
1587: state |= DISPOSED;
1588: display = null;
1589: }
1590:
1591: void releaseParent() {
1592: /* Do nothing */
1593: }
1594:
1595: void releaseWidget() {
1596: deregister();
1597: eventTable = null;
1598: data = null;
1599: }
1600:
1601: /**
1602: * Removes the listener from the collection of listeners who will
1603: * be notified when an event of the given type occurs. The event
1604: * type is one of the event constants defined in class <code>SWT</code>.
1605: *
1606: * @param eventType the type of event to listen for
1607: * @param listener the listener which should no longer be notified when the event occurs
1608: *
1609: * @exception IllegalArgumentException <ul>
1610: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1611: * </ul>
1612: * @exception SWTException <ul>
1613: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1614: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1615: * </ul>
1616: *
1617: * @see Listener
1618: * @see SWT
1619: * @see #addListener
1620: * @see #notifyListeners
1621: */
1622: public void removeListener(int eventType, Listener handler) {
1623: checkWidget();
1624: if (handler == null)
1625: error(SWT.ERROR_NULL_ARGUMENT);
1626: if (eventTable == null)
1627: return;
1628: eventTable.unhook(eventType, handler);
1629: }
1630:
1631: /**
1632: * Removes the listener from the collection of listeners who will
1633: * be notified when an event of the given type occurs.
1634: * <p>
1635: * <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT
1636: * public API. It is marked public only so that it can be shared
1637: * within the packages provided by SWT. It should never be
1638: * referenced from application code.
1639: * </p>
1640: *
1641: * @param eventType the type of event to listen for
1642: * @param listener the listener which should no longer be notified when the event occurs
1643: *
1644: * @exception IllegalArgumentException <ul>
1645: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1646: * </ul>
1647: * @exception SWTException <ul>
1648: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1649: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1650: * </ul>
1651: *
1652: * @see Listener
1653: * @see #addListener
1654: */
1655: protected void removeListener(int eventType,
1656: SWTEventListener handler) {
1657: checkWidget();
1658: if (handler == null)
1659: error(SWT.ERROR_NULL_ARGUMENT);
1660: if (eventTable == null)
1661: return;
1662: eventTable.unhook(eventType, handler);
1663: }
1664:
1665: /**
1666: * Removes the listener from the collection of listeners who will
1667: * be notified when the widget is disposed.
1668: *
1669: * @param listener the listener which should no longer be notified when the receiver is disposed
1670: *
1671: * @exception IllegalArgumentException <ul>
1672: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1673: * </ul>
1674: * @exception SWTException <ul>
1675: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1676: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1677: * </ul>
1678: *
1679: * @see DisposeListener
1680: * @see #addDisposeListener
1681: */
1682: public void removeDisposeListener(DisposeListener listener) {
1683: checkWidget();
1684: if (listener == null)
1685: error(SWT.ERROR_NULL_ARGUMENT);
1686: if (eventTable == null)
1687: return;
1688: eventTable.unhook(SWT.Dispose, listener);
1689: }
1690:
1691: void sendEvent(Event event) {
1692: Display display = event.display;
1693: if (!display.filterEvent(event)) {
1694: if (eventTable != null)
1695: eventTable.sendEvent(event);
1696: }
1697: }
1698:
1699: void sendEvent(int eventType) {
1700: sendEvent(eventType, null, true);
1701: }
1702:
1703: void sendEvent(int eventType, Event event) {
1704: sendEvent(eventType, event, true);
1705: }
1706:
1707: void sendEvent(int eventType, Event event, boolean send) {
1708: if (eventTable == null && !display.filters(eventType)) {
1709: return;
1710: }
1711: if (event == null)
1712: event = new Event();
1713: event.type = eventType;
1714: event.display = display;
1715: event.widget = this ;
1716: if (event.time == 0) {
1717: event.time = display.getLastEventTime();
1718: }
1719: if (send) {
1720: sendEvent(event);
1721: } else {
1722: display.postEvent(event);
1723: }
1724: }
1725:
1726: boolean sendKeyEvent(int type, int theEvent) {
1727: int[] length = new int[1];
1728: int status = OS.GetEventParameter(theEvent,
1729: OS.kEventParamKeyUnicodes, OS.typeUnicodeText, null, 4,
1730: length, (char[]) null);
1731: if (status == OS.noErr && length[0] > 2) {
1732: int count = 0;
1733: int[] chord = new int[1];
1734: OS.GetEventParameter(theEvent, OS.kEventParamMouseChord,
1735: OS.typeUInt32, null, 4, null, chord);
1736: int[] modifiers = new int[1];
1737: OS.GetEventParameter(theEvent, OS.kEventParamKeyModifiers,
1738: OS.typeUInt32, null, 4, null, modifiers);
1739: char[] chars = new char[length[0] / 2];
1740: OS.GetEventParameter(theEvent, OS.kEventParamKeyUnicodes,
1741: OS.typeUnicodeText, null, chars.length * 2, null,
1742: chars);
1743: for (int i = 0; i < chars.length; i++) {
1744: Event event = new Event();
1745: event.character = chars[i];
1746: setInputState(event, type, chord[0], modifiers[0]);
1747: if (sendKeyEvent(type, event))
1748: chars[count++] = chars[i];
1749: }
1750: if (count == 0)
1751: return false;
1752: if (count != chars.length - 1) {
1753: OS.SetEventParameter(theEvent,
1754: OS.kEventParamKeyUnicodes, OS.typeUnicodeText,
1755: count * 2, chars);
1756: }
1757: return true;
1758: } else {
1759: Event event = new Event();
1760: if (!setKeyState(event, type, theEvent))
1761: return true;
1762: return sendKeyEvent(type, event);
1763: }
1764: }
1765:
1766: boolean sendKeyEvent(int type, Event event) {
1767: sendEvent(type, event);
1768: // widget could be disposed at this point
1769:
1770: /*
1771: * It is possible (but unlikely), that application
1772: * code could have disposed the widget in the key
1773: * events. If this happens, end the processing of
1774: * the key by returning false.
1775: */
1776: if (isDisposed())
1777: return false;
1778: return event.doit;
1779: }
1780:
1781: int setBounds(int control, int x, int y, int width, int height,
1782: boolean move, boolean resize, boolean events) {
1783: boolean sameOrigin = true, sameExtent = true;
1784: if (OS.HIVIEW) {
1785: CGRect oldBounds = new CGRect();
1786: OS.HIViewGetFrame(control, oldBounds);
1787: Rect inset = getInset();
1788: oldBounds.x -= inset.left;
1789: oldBounds.y -= inset.top;
1790: oldBounds.width += inset.left + inset.right;
1791: oldBounds.height += inset.top + inset.bottom;
1792: if (!move) {
1793: x = (int) oldBounds.x;
1794: y = (int) oldBounds.y;
1795: }
1796: if (!resize) {
1797: width = (int) oldBounds.width;
1798: height = (int) oldBounds.height;
1799: }
1800: CGRect newBounds = new CGRect();
1801: newBounds.x = x + inset.left;
1802: newBounds.y = y + inset.top;
1803: newBounds.width = width - inset.right - inset.left;
1804: newBounds.height = height - inset.bottom - inset.top;
1805: sameOrigin = newBounds.x == oldBounds.x
1806: && newBounds.y == oldBounds.y;
1807: sameExtent = newBounds.width == oldBounds.width
1808: && newBounds.height == oldBounds.height;
1809: if (sameOrigin && sameExtent)
1810: return 0;
1811: OS.HIViewSetFrame(control, newBounds);
1812: invalidateVisibleRegion(control);
1813: } else {
1814: /* Compute the old bounds */
1815: Rect oldBounds = new Rect();
1816: OS.GetControlBounds(control, oldBounds);
1817: int[] theRoot = new int[1];
1818: int window = OS.GetControlOwner(control);
1819: OS.GetRootControl(window, theRoot);
1820: int[] parentHandle = new int[1];
1821: OS.GetSuperControl(control, parentHandle);
1822: Rect parentRect = new Rect();
1823: if (parentHandle[0] != theRoot[0]) {
1824: OS.GetControlBounds(parentHandle[0], parentRect);
1825: OS.OffsetRect(oldBounds, (short) -parentRect.left,
1826: (short) -parentRect.top);
1827: }
1828: Rect inset = getInset();
1829: oldBounds.left -= inset.left;
1830: oldBounds.top -= inset.top;
1831: oldBounds.right += inset.right;
1832: oldBounds.bottom += inset.bottom;
1833:
1834: /* Compute the new bounds */
1835: if (!move) {
1836: x = oldBounds.left;
1837: y = oldBounds.top;
1838: }
1839: if (!resize) {
1840: width = oldBounds.right - oldBounds.left;
1841: height = oldBounds.bottom - oldBounds.top;
1842: }
1843: Rect newBounds = new Rect();
1844: newBounds.left = (short) (parentRect.left + x + inset.left);
1845: newBounds.top = (short) (parentRect.top + y + inset.top);
1846: newBounds.right = (short) (newBounds.left + width
1847: - inset.right - inset.left);
1848: newBounds.bottom = (short) (newBounds.top + height
1849: - inset.bottom - inset.top);
1850: if (newBounds.bottom < newBounds.top)
1851: newBounds.bottom = newBounds.top;
1852: if (newBounds.right < newBounds.left)
1853: newBounds.right = newBounds.left;
1854:
1855: /* Get bounds again, since the one above is in SWT coordinates */
1856: OS.GetControlBounds(control, oldBounds);
1857:
1858: /* Check if anything changed */
1859: sameOrigin = newBounds.left == oldBounds.left
1860: && newBounds.top == oldBounds.top;
1861: sameExtent = (newBounds.right - newBounds.left) == (oldBounds.right - oldBounds.left)
1862: && (newBounds.bottom - newBounds.top) == (oldBounds.bottom - oldBounds.top);
1863: if (sameOrigin && sameExtent)
1864: return 0;
1865:
1866: /* Apply changes and invalidate appropriate rectangles */
1867: int tempRgn = 0;
1868: boolean visible = OS.IsControlVisible(control);
1869: if (visible) {
1870: tempRgn = OS.NewRgn();
1871: OS.GetControlRegion(control,
1872: (short) OS.kControlStructureMetaPart, tempRgn);
1873: invalWindowRgn(window, tempRgn);
1874: }
1875: OS.SetControlBounds(control, newBounds);
1876: invalidateVisibleRegion(control);
1877: if (visible) {
1878: OS.GetControlRegion(control,
1879: (short) OS.kControlStructureMetaPart, tempRgn);
1880: invalWindowRgn(window, tempRgn);
1881: OS.DisposeRgn(tempRgn);
1882: }
1883: }
1884:
1885: /* Send events */
1886: int result = 0;
1887: if (move && !sameOrigin) {
1888: if (events)
1889: sendEvent(SWT.Move);
1890: result |= MOVED;
1891: }
1892: if (resize && !sameExtent) {
1893: if (events)
1894: sendEvent(SWT.Resize);
1895: result |= RESIZED;
1896: }
1897: return result;
1898: }
1899:
1900: /**
1901: * Sets the application defined widget data associated
1902: * with the receiver to be the argument. The <em>widget
1903: * data</em> is a single, unnamed field that is stored
1904: * with every widget.
1905: * <p>
1906: * Applications may put arbitrary objects in this field. If
1907: * the object stored in the widget data needs to be notified
1908: * when the widget is disposed of, it is the application's
1909: * responsibility to hook the Dispose event on the widget and
1910: * do so.
1911: * </p>
1912: *
1913: * @param data the widget data
1914: *
1915: * @exception SWTException <ul>
1916: * <li>ERROR_WIDGET_DISPOSED - when the receiver has been disposed</li>
1917: * <li>ERROR_THREAD_INVALID_ACCESS - when called from the wrong thread</li>
1918: * </ul>
1919: *
1920: * @see #getData()
1921: */
1922: public void setData(Object data) {
1923: checkWidget();
1924: if ((state & KEYED_DATA) != 0) {
1925: ((Object[]) this .data)[0] = data;
1926: } else {
1927: this .data = data;
1928: }
1929: }
1930:
1931: /**
1932: * Sets the application defined property of the receiver
1933: * with the specified name to the given value.
1934: * <p>
1935: * Applications may associate arbitrary objects with the
1936: * receiver in this fashion. If the objects stored in the
1937: * properties need to be notified when the widget is disposed
1938: * of, it is the application's responsibility to hook the
1939: * Dispose event on the widget and do so.
1940: * </p>
1941: *
1942: * @param key the name of the property
1943: * @param value the new value for the property
1944: *
1945: * @exception IllegalArgumentException <ul>
1946: * <li>ERROR_NULL_ARGUMENT - if the key is null</li>
1947: * </ul>
1948: * @exception SWTException <ul>
1949: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1950: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1951: * </ul>
1952: *
1953: * @see #getData(String)
1954: */
1955: public void setData(String key, Object value) {
1956: checkWidget();
1957: if (key == null)
1958: error(SWT.ERROR_NULL_ARGUMENT);
1959: // GOOGLE: patched in from https://bugs.eclipse.org/bugs/show_bug.cgi?id=161259
1960: if (key.equals(CLEAR_GRAB_BIT)) {
1961: state &= ~GRAB;
1962: return;
1963: }
1964: int index = 1;
1965: Object[] table = null;
1966: if ((state & KEYED_DATA) != 0) {
1967: table = (Object[]) data;
1968: while (index < table.length) {
1969: if (key.equals(table[index]))
1970: break;
1971: index += 2;
1972: }
1973: }
1974: if (value != null) {
1975: if ((state & KEYED_DATA) != 0) {
1976: if (index == table.length) {
1977: Object[] newTable = new Object[table.length + 2];
1978: System.arraycopy(table, 0, newTable, 0,
1979: table.length);
1980: data = table = newTable;
1981: }
1982: } else {
1983: table = new Object[3];
1984: table[0] = data;
1985: data = table;
1986: state |= KEYED_DATA;
1987: }
1988: table[index] = key;
1989: table[index + 1] = value;
1990: } else {
1991: if ((state & KEYED_DATA) != 0) {
1992: if (index != table.length) {
1993: int length = table.length - 2;
1994: if (length == 1) {
1995: data = table[0];
1996: state &= ~KEYED_DATA;
1997: } else {
1998: Object[] newTable = new Object[length];
1999: System.arraycopy(table, 0, newTable, 0, index);
2000: System.arraycopy(table, index + 2, newTable,
2001: index, length - index);
2002: data = newTable;
2003: }
2004: }
2005: }
2006: }
2007: }
2008:
2009: boolean setInputState(Event event, int type, int chord,
2010: int modifiers) {
2011: if ((chord & 0x01) != 0)
2012: event.stateMask |= SWT.BUTTON1;
2013: if ((chord & 0x02) != 0)
2014: event.stateMask |= SWT.BUTTON3;
2015: if ((chord & 0x04) != 0)
2016: event.stateMask |= SWT.BUTTON2;
2017: if ((chord & 0x08) != 0)
2018: event.stateMask |= SWT.BUTTON4;
2019: if ((chord & 0x10) != 0)
2020: event.stateMask |= SWT.BUTTON5;
2021:
2022: if ((modifiers & OS.optionKey) != 0)
2023: event.stateMask |= SWT.ALT;
2024: if ((modifiers & OS.shiftKey) != 0)
2025: event.stateMask |= SWT.SHIFT;
2026: if ((modifiers & OS.controlKey) != 0)
2027: event.stateMask |= SWT.CONTROL;
2028: if ((modifiers & OS.cmdKey) != 0)
2029: event.stateMask |= SWT.COMMAND;
2030: switch (type) {
2031: case SWT.MouseDown:
2032: case SWT.MouseDoubleClick:
2033: if (event.button == 1)
2034: event.stateMask &= ~SWT.BUTTON1;
2035: if (event.button == 2)
2036: event.stateMask &= ~SWT.BUTTON2;
2037: if (event.button == 3)
2038: event.stateMask &= ~SWT.BUTTON3;
2039: if (event.button == 4)
2040: event.stateMask &= ~SWT.BUTTON4;
2041: if (event.button == 5)
2042: event.stateMask &= ~SWT.BUTTON5;
2043: break;
2044: case SWT.MouseUp:
2045: if (event.button == 1)
2046: event.stateMask |= SWT.BUTTON1;
2047: if (event.button == 2)
2048: event.stateMask |= SWT.BUTTON2;
2049: if (event.button == 3)
2050: event.stateMask |= SWT.BUTTON3;
2051: if (event.button == 4)
2052: event.stateMask |= SWT.BUTTON4;
2053: if (event.button == 5)
2054: event.stateMask |= SWT.BUTTON5;
2055: break;
2056: case SWT.KeyDown:
2057: case SWT.Traverse: {
2058: if (event.keyCode != 0 || event.character != 0)
2059: return true;
2060: int lastModifiers = display.lastModifiers;
2061: if ((modifiers & OS.alphaLock) != 0
2062: && (lastModifiers & OS.alphaLock) == 0) {
2063: event.keyCode = SWT.CAPS_LOCK;
2064: return true;
2065: }
2066: if ((modifiers & OS.shiftKey) != 0
2067: && (lastModifiers & OS.shiftKey) == 0) {
2068: event.stateMask &= ~SWT.SHIFT;
2069: event.keyCode = SWT.SHIFT;
2070: return true;
2071: }
2072: if ((modifiers & OS.controlKey) != 0
2073: && (lastModifiers & OS.controlKey) == 0) {
2074: event.stateMask &= ~SWT.CONTROL;
2075: event.keyCode = SWT.CONTROL;
2076: return true;
2077: }
2078: if ((modifiers & OS.cmdKey) != 0
2079: && (lastModifiers & OS.cmdKey) == 0) {
2080: event.stateMask &= ~SWT.COMMAND;
2081: event.keyCode = SWT.COMMAND;
2082: return true;
2083: }
2084: if ((modifiers & OS.optionKey) != 0
2085: && (lastModifiers & OS.optionKey) == 0) {
2086: event.stateMask &= ~SWT.ALT;
2087: event.keyCode = SWT.ALT;
2088: return true;
2089: }
2090: break;
2091: }
2092: case SWT.KeyUp: {
2093: if (event.keyCode != 0 || event.character != 0)
2094: return true;
2095: int lastModifiers = display.lastModifiers;
2096: if ((modifiers & OS.alphaLock) == 0
2097: && (lastModifiers & OS.alphaLock) != 0) {
2098: event.keyCode = SWT.CAPS_LOCK;
2099: return true;
2100: }
2101: if ((modifiers & OS.shiftKey) == 0
2102: && (lastModifiers & OS.shiftKey) != 0) {
2103: event.stateMask |= SWT.SHIFT;
2104: event.keyCode = SWT.SHIFT;
2105: return true;
2106: }
2107: if ((modifiers & OS.controlKey) == 0
2108: && (lastModifiers & OS.controlKey) != 0) {
2109: event.stateMask |= SWT.CONTROL;
2110: event.keyCode = SWT.CONTROL;
2111: return true;
2112: }
2113: if ((modifiers & OS.cmdKey) == 0
2114: && (lastModifiers & OS.cmdKey) != 0) {
2115: event.stateMask |= SWT.COMMAND;
2116: event.keyCode = SWT.COMMAND;
2117: return true;
2118: }
2119: if ((modifiers & OS.optionKey) == 0
2120: && (lastModifiers & OS.optionKey) != 0) {
2121: event.stateMask |= SWT.ALT;
2122: event.keyCode = SWT.ALT;
2123: return true;
2124: }
2125: break;
2126: }
2127: }
2128: return true;
2129: }
2130:
2131: boolean setKeyState(Event event, int type, int theEvent) {
2132: boolean isNull = false;
2133: int[] keyCode = new int[1];
2134: OS.GetEventParameter(theEvent, OS.kEventParamKeyCode,
2135: OS.typeUInt32, null, keyCode.length * 4, null, keyCode);
2136: event.keyCode = Display.translateKey(keyCode[0]);
2137: switch (event.keyCode) {
2138: case SWT.LF: {
2139: /*
2140: * Feature in the Macintosh. When the numeric key pad
2141: * Enter key is pressed, it generates '\n'. This is the
2142: * correct platform behavior but is not portable. The
2143: * fix is to convert the '\n' into '\r'.
2144: */
2145: event.keyCode = SWT.KEYPAD_CR;
2146: event.character = '\r';
2147: break;
2148: }
2149: case SWT.BS:
2150: event.character = '\b';
2151: break;
2152: case SWT.CR:
2153: event.character = '\r';
2154: break;
2155: case SWT.DEL:
2156: event.character = 0x7F;
2157: break;
2158: case SWT.ESC:
2159: event.character = 0x1B;
2160: break;
2161: case SWT.TAB:
2162: event.character = '\t';
2163: break;
2164: default: {
2165: if (event.keyCode == 0
2166: || (SWT.KEYPAD_MULTIPLY <= event.keyCode && event.keyCode <= SWT.KEYPAD_CR)) {
2167: int[] length = new int[1];
2168: int status = OS.GetEventParameter(theEvent,
2169: OS.kEventParamKeyUnicodes, OS.typeUnicodeText,
2170: null, 4, length, (char[]) null);
2171: if (status == OS.noErr && length[0] != 0) {
2172: char[] chars = new char[1];
2173: OS.GetEventParameter(theEvent,
2174: OS.kEventParamKeyUnicodes,
2175: OS.typeUnicodeText, null, 2, null, chars);
2176: event.character = chars[0];
2177: }
2178: /*
2179: * Bug in the Mactonish. For some reason, Ctrl+Shift+'2' and Ctrl+Shift+'6'
2180: * fail to give 0x0 (^@ or ASCII NUL) and 0x1e (^^). Other control character
2181: * key sequences such as ^A or even Ctrl+Shift+'-' (^_ or 0x1f) are correctly
2182: * translated to control characters. Since it is not possible to know which
2183: * key combination gives '@' on an international keyboard, there is no way to
2184: * test for either character and convert it to a control character (Shift+'2'
2185: * gives '@' only on an English keyboard) to work around the problem.
2186: *
2187: * There is no fix at this time.
2188: */
2189: }
2190: if (event.keyCode == 0) {
2191: int kchrPtr = OS
2192: .GetScriptManagerVariable((short) OS.smKCHRCache);
2193: if (display.kchrPtr != kchrPtr) {
2194: display.kchrPtr = kchrPtr;
2195: display.kchrState[0] = 0;
2196: }
2197: int result = OS.KeyTranslate(display.kchrPtr,
2198: (short) keyCode[0], display.kchrState);
2199: if (result <= 0x7f) {
2200: event.keyCode = result & 0x7f;
2201: } else {
2202: int[] encoding = new int[1];
2203: short keyScript = (short) OS
2204: .GetScriptManagerVariable((short) OS.smKeyScript);
2205: short regionCode = (short) OS
2206: .GetScriptManagerVariable((short) OS.smRegionCode);
2207: if (OS.UpgradeScriptInfoToTextEncoding(keyScript,
2208: (short) OS.kTextLanguageDontCare,
2209: regionCode, null, encoding) == OS.paramErr) {
2210: if (OS.UpgradeScriptInfoToTextEncoding(
2211: keyScript,
2212: (short) OS.kTextLanguageDontCare,
2213: (short) OS.kTextRegionDontCare, null,
2214: encoding) == OS.paramErr) {
2215: encoding[0] = OS.kTextEncodingMacRoman;
2216: }
2217: }
2218: int[] encodingInfo = new int[1];
2219: OS.CreateTextToUnicodeInfoByEncoding(encoding[0],
2220: encodingInfo);
2221: if (encodingInfo[0] != 0) {
2222: char[] chars = new char[1];
2223: int[] nchars = new int[1];
2224: byte[] buffer = new byte[2];
2225: buffer[0] = 1;
2226: buffer[1] = (byte) (result & 0xFF);
2227: OS
2228: .ConvertFromPStringToUnicode(
2229: encodingInfo[0], buffer,
2230: chars.length * 2, nchars, chars);
2231: OS.DisposeTextToUnicodeInfo(encodingInfo);
2232: event.keyCode = chars[0];
2233: }
2234: }
2235: }
2236: break;
2237: }
2238: }
2239: if (event.keyCode == 0 && event.character == 0) {
2240: if (!isNull)
2241: return false;
2242: }
2243: int[] chord = new int[1];
2244: OS.GetEventParameter(theEvent, OS.kEventParamMouseChord,
2245: OS.typeUInt32, null, 4, null, chord);
2246: int[] modifiers = new int[1];
2247: OS.GetEventParameter(theEvent, OS.kEventParamKeyModifiers,
2248: OS.typeUInt32, null, 4, null, modifiers);
2249: return setInputState(event, type, chord[0], modifiers[0]);
2250: }
2251:
2252: void setVisible(int control, boolean visible) {
2253: if (OS.HIVIEW) {
2254: OS.HIViewSetVisible(control, visible);
2255: invalidateVisibleRegion(control);
2256: } else {
2257: int visibleRgn = 0;
2258: boolean drawing = getDrawCount(control) == 0;
2259: if (drawing && !visible)
2260: visibleRgn = getVisibleRegion(control, false);
2261: OS.SetControlVisibility(control, visible, false);
2262: invalidateVisibleRegion(control);
2263: if (drawing && visible)
2264: visibleRgn = getVisibleRegion(control, false);
2265: if (drawing) {
2266: int window = OS.GetControlOwner(control);
2267: invalWindowRgn(window, visibleRgn);
2268: OS.DisposeRgn(visibleRgn);
2269: }
2270: }
2271: }
2272:
2273: void setZOrder(int control, int otheControl, boolean above) {
2274: if (OS.HIVIEW) {
2275: int inOp = above ? OS.kHIViewZOrderAbove
2276: : OS.kHIViewZOrderBelow;
2277: OS.HIViewSetZOrder(control, inOp, otheControl);
2278: invalidateVisibleRegion(control);
2279: } else {
2280: int inOp = above ? OS.kHIViewZOrderBelow
2281: : OS.kHIViewZOrderAbove;
2282: int oldRgn = 0;
2283: boolean drawing = isDrawing(control);
2284: if (drawing)
2285: oldRgn = getVisibleRegion(control, false);
2286: OS.HIViewSetZOrder(control, inOp, otheControl);
2287: invalidateVisibleRegion(control);
2288: if (drawing) {
2289: int newRgn = getVisibleRegion(control, false);
2290: if (above) {
2291: OS.DiffRgn(newRgn, oldRgn, newRgn);
2292: } else {
2293: OS.DiffRgn(oldRgn, newRgn, newRgn);
2294: }
2295: int window = OS.GetControlOwner(control);
2296: invalWindowRgn(window, newRgn);
2297: OS.DisposeRgn(oldRgn);
2298: OS.DisposeRgn(newRgn);
2299: }
2300: }
2301: }
2302:
2303: int textInputProc(int nextHandler, int theEvent, int userData) {
2304: int eventKind = OS.GetEventKind(theEvent);
2305: switch (eventKind) {
2306: case OS.kEventTextInputUnicodeForKeyEvent:
2307: return kEventTextInputUnicodeForKeyEvent(nextHandler,
2308: theEvent, userData);
2309: }
2310: return OS.eventNotHandledErr;
2311: }
2312:
2313: RGBColor toRGBColor(float[] color) {
2314: RGBColor rgb = new RGBColor();
2315: rgb.red = (short) (color[0] * 0xffff);
2316: rgb.green = (short) (color[1] * 0xffff);
2317: rgb.blue = (short) (color[2] * 0xffff);
2318: return rgb;
2319: }
2320:
2321: /**
2322: * Returns a string containing a concise, human-readable
2323: * description of the receiver.
2324: *
2325: * @return a string representation of the receiver
2326: */
2327: public String toString() {
2328: String string = "*Disposed*";
2329: if (!isDisposed()) {
2330: string = "*Wrong Thread*";
2331: if (isValidThread())
2332: string = getNameText();
2333: }
2334: return getName() + " {" + string + "}";
2335: }
2336:
2337: int trackingProc(int browser, int itemID, int property,
2338: int theRect, int startPt, int modifiers) {
2339: /* Return one to indicate that the data browser should process the click */
2340: return 1;
2341: }
2342:
2343: int windowProc(int nextHandler, int theEvent, int userData) {
2344: int eventKind = OS.GetEventKind(theEvent);
2345: switch (eventKind) {
2346: case OS.kEventWindowActivated:
2347: return kEventWindowActivated(nextHandler, theEvent,
2348: userData);
2349: case OS.kEventWindowBoundsChanged:
2350: return kEventWindowBoundsChanged(nextHandler, theEvent,
2351: userData);
2352: case OS.kEventWindowClose:
2353: return kEventWindowClose(nextHandler, theEvent, userData);
2354: case OS.kEventWindowCollapsed:
2355: return kEventWindowCollapsed(nextHandler, theEvent,
2356: userData);
2357: case OS.kEventWindowDeactivated:
2358: return kEventWindowDeactivated(nextHandler, theEvent,
2359: userData);
2360: case OS.kEventWindowDrawContent:
2361: return kEventWindowDrawContent(nextHandler, theEvent,
2362: userData);
2363: case OS.kEventWindowExpanded:
2364: return kEventWindowExpanded(nextHandler, theEvent, userData);
2365: case OS.kEventWindowGetRegion:
2366: return kEventWindowGetRegion(nextHandler, theEvent,
2367: userData);
2368: case OS.kEventWindowHidden:
2369: return kEventWindowHidden(nextHandler, theEvent, userData);
2370: case OS.kEventWindowHitTest:
2371: return kEventWindowHitTest(nextHandler, theEvent, userData);
2372: case OS.kEventWindowShown:
2373: return kEventWindowShown(nextHandler, theEvent, userData);
2374: case OS.kEventWindowUpdate:
2375: return kEventWindowUpdate(nextHandler, theEvent, userData);
2376: case OS.kEventWindowGetClickModality:
2377: return kEventWindowGetClickModality(nextHandler, theEvent,
2378: userData);
2379: }
2380: return OS.eventNotHandledErr;
2381: }
2382:
2383: }
|