18
|
1 /*******************************************************************************
|
|
2 * Copyright (c) 2000, 2007 IBM Corporation and others.
|
|
3 * All rights reserved. This program and the accompanying materials
|
|
4 * are made available under the terms of the Eclipse Public License v1.0
|
|
5 * which accompanies this distribution, and is available at
|
|
6 * http://www.eclipse.org/legal/epl-v10.html
|
|
7 *
|
|
8 * Contributors:
|
|
9 * IBM Corporation - initial API and implementation
|
|
10 *******************************************************************************/
|
|
11 module dwt.graphics.Device;
|
|
12
|
19
|
13 import dwt.internal.gtk.c.gdktypes;
|
|
14 import dwt.internal.gtk.c.gtktypes;
|
18
|
15 import dwt.graphics.Color;
|
19
|
16 import dwt.graphics.Font;
|
|
17 import dwt.graphics.Drawable;
|
|
18 import dwt.graphics.DeviceData;
|
|
19 import dwt.graphics.Rectangle;
|
|
20 import dwt.graphics.FontData;
|
|
21 import dwt.graphics.Font;
|
|
22 import dwt.graphics.GCData;
|
|
23 import dwt.dwthelper.Runnable;
|
|
24 import dwt.SWT;
|
|
25 import dwt.SWTError;
|
|
26 import dwt.internal.Compatibility;
|
|
27 import dwt.internal.gtk.OS;
|
|
28 import dwt.internal.gtk.c.gdktypes;
|
|
29
|
|
30 import tango.core.Exception;
|
|
31 import tango.stdc.stringz;
|
|
32 import tango.io.Stdout;
|
|
33
|
|
34 /+
|
18
|
35 class Device{
|
|
36 static Device getDevice(){
|
|
37 return null;
|
|
38 }
|
|
39 void new_Object (Object object) {
|
|
40 }
|
|
41 void dispose_Object (Object object) {
|
|
42 }
|
|
43 bool tracking;
|
|
44 bool useXRender;
|
|
45 bool isDisposed(){
|
|
46 return false;
|
|
47 }
|
|
48 int[] colorRefCount;
|
|
49 GdkColor*[] gdkColors;
|
|
50 public Color getSystemColor (int id) {
|
|
51 return null;
|
|
52 }
|
19
|
53 Font systemFont;
|
|
54 Color COLOR_BLACK, COLOR_DARK_RED, COLOR_DARK_GREEN, COLOR_DARK_YELLOW, COLOR_DARK_BLUE;
|
|
55 Color COLOR_DARK_MAGENTA, COLOR_DARK_CYAN, COLOR_GRAY, COLOR_DARK_GRAY, COLOR_RED;
|
|
56 Color COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE;
|
18
|
57 }
|
|
58
|
19
|
59 +/
|
18
|
60
|
19
|
61
|
18
|
62
|
|
63 /**
|
|
64 * This class is the abstract superclass of all device objects,
|
|
65 * such as the Display device and the Printer device. Devices
|
|
66 * can have a graphics context (GC) created for them, and they
|
|
67 * can be drawn on by sending messages to the associated GC.
|
|
68 */
|
19
|
69 public abstract class Device : Drawable {
|
18
|
70 /**
|
|
71 * the handle to the X Display
|
|
72 * (Warning: This field is platform dependent)
|
|
73 * <p>
|
|
74 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
|
|
75 * public API. It is marked protected only so that it can be shared
|
|
76 * within the packages provided by SWT. It is not available on all
|
|
77 * platforms and should never be accessed from application code.
|
|
78 * </p>
|
|
79 */
|
19
|
80 protected dwt.internal.gtk.c.cairotypes.Display* xDisplay;
|
|
81 GtkWidget* shellHandle;
|
18
|
82
|
|
83 /* Debugging */
|
19
|
84 public static bool DEBUG;
|
|
85 bool debugging;
|
|
86 bool tracking;
|
|
87 TracedException [] errors;
|
18
|
88 Object [] objects;
|
|
89
|
|
90 /* Colormap and reference count */
|
19
|
91 GdkColor *[] gdkColors;
|
18
|
92 int [] colorRefCount;
|
|
93
|
|
94 /* Disposed flag */
|
19
|
95 bool disposed;
|
18
|
96
|
|
97 /* Warning and Error Handlers */
|
19
|
98 //int /*long*/ logProcFld;
|
|
99 //GLogFunc logCallback;
|
18
|
100 //NOT DONE - get list of valid names
|
19
|
101 char[] [] log_domains = ["GLib-GObject"[], "GLib", "GObject", "Pango", "ATK", "GdkPixbuf", "Gdk", "Gtk", "GnomeVFS"];
|
|
102 int [] handler_ids;// = new int [log_domains.length];
|
18
|
103 int warningLevel;
|
|
104
|
|
105 /* X Warning and Error Handlers */
|
19
|
106 static extern(C) int function(void *) mXIOErrorHandler;
|
|
107 static extern(C) int function(void *, XErrorEvent *) mXErrorHandler;
|
|
108 //static int mXErrorCallback, mXIOErrorCallback;
|
|
109
|
18
|
110 static int /*long*/ XErrorProc, XIOErrorProc, XNullErrorProc, XNullIOErrorProc;
|
19
|
111 static Device[] Devices;
|
18
|
112
|
|
113 /*
|
|
114 * The following colors are listed in the Windows
|
|
115 * Programmer's Reference as the colors in the default
|
|
116 * palette.
|
|
117 */
|
|
118 Color COLOR_BLACK, COLOR_DARK_RED, COLOR_DARK_GREEN, COLOR_DARK_YELLOW, COLOR_DARK_BLUE;
|
|
119 Color COLOR_DARK_MAGENTA, COLOR_DARK_CYAN, COLOR_GRAY, COLOR_DARK_GRAY, COLOR_RED;
|
|
120 Color COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE;
|
|
121
|
|
122 /* System Font */
|
|
123 Font systemFont;
|
|
124
|
19
|
125 PangoTabArray* emptyTab;
|
18
|
126
|
19
|
127 bool useXRender;
|
18
|
128
|
19
|
129 static bool CAIRO_LOADED;
|
18
|
130
|
19
|
131 static const Object CREATE_LOCK;
|
18
|
132
|
|
133 /*
|
|
134 * TEMPORARY CODE. When a graphics object is
|
|
135 * created and the device parameter is null,
|
|
136 * the current Display is used. This presents
|
|
137 * a problem because SWT graphics does not
|
|
138 * reference classes in SWT widgets. The correct
|
|
139 * fix is to remove this feature. Unfortunately,
|
|
140 * too many application programs rely on this
|
|
141 * feature.
|
|
142 *
|
|
143 * This code will be removed in the future.
|
|
144 */
|
|
145 protected static Device CurrentDevice;
|
|
146 protected static Runnable DeviceFinder;
|
|
147
|
19
|
148 static this(){
|
|
149 CREATE_LOCK = new Object();
|
|
150 Devices = new Device[4];
|
|
151 }
|
18
|
152 /*
|
|
153 * TEMPORARY CODE.
|
|
154 */
|
|
155 static synchronized Device getDevice () {
|
19
|
156 if (DeviceFinder !is null) DeviceFinder.run();
|
18
|
157 Device device = CurrentDevice;
|
|
158 CurrentDevice = null;
|
|
159 return device;
|
|
160 }
|
|
161
|
|
162 /**
|
|
163 * Constructs a new instance of this class.
|
|
164 * <p>
|
|
165 * You must dispose the device when it is no longer required.
|
|
166 * </p>
|
|
167 *
|
|
168 * @see #create
|
|
169 * @see #init
|
|
170 *
|
|
171 * @since 3.1
|
|
172 */
|
19
|
173 public this() {
|
18
|
174 this(null);
|
|
175 }
|
|
176
|
|
177 /**
|
|
178 * Constructs a new instance of this class.
|
|
179 * <p>
|
|
180 * You must dispose the device when it is no longer required.
|
|
181 * </p>
|
|
182 *
|
|
183 * @param data the DeviceData which describes the receiver
|
|
184 *
|
|
185 * @see #create
|
|
186 * @see #init
|
|
187 * @see DeviceData
|
|
188 */
|
19
|
189 public this(DeviceData data) {
|
|
190 handler_ids = new int [log_domains.length];
|
|
191 debugging = DEBUG;
|
|
192 tracking = DEBUG;
|
|
193
|
18
|
194 synchronized (CREATE_LOCK) {
|
|
195 if (data != null) {
|
19
|
196 debugging = data.debugging;
|
18
|
197 tracking = data.tracking;
|
|
198 }
|
|
199 if (tracking) {
|
19
|
200 errors = new TracedException [128];
|
18
|
201 objects = new Object [128];
|
|
202 }
|
|
203 create (data);
|
|
204 init ();
|
|
205 register (this);
|
|
206
|
|
207 /* Initialize the system font slot */
|
|
208 systemFont = getSystemFont ();
|
|
209 }
|
|
210 }
|
|
211
|
|
212 void checkCairo() {
|
|
213 }
|
|
214
|
|
215 /**
|
|
216 * Throws an <code>SWTException</code> if the receiver can not
|
|
217 * be accessed by the caller. This may include both checks on
|
|
218 * the state of the receiver and more generally on the entire
|
|
219 * execution context. This method <em>should</em> be called by
|
|
220 * device implementors to enforce the standard SWT invariants.
|
|
221 * <p>
|
|
222 * Currently, it is an error to invoke any method (other than
|
|
223 * <code>isDisposed()</code> and <code>dispose()</code>) on a
|
|
224 * device that has had its <code>dispose()</code> method called.
|
|
225 * </p><p>
|
|
226 * In future releases of SWT, there may be more or fewer error
|
|
227 * checks and exceptions may be thrown for different reasons.
|
|
228 * <p>
|
|
229 *
|
|
230 * @exception SWTException <ul>
|
|
231 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
|
232 * </ul>
|
|
233 */
|
|
234 protected void checkDevice () {
|
|
235 if (disposed) SWT.error(SWT.ERROR_DEVICE_DISPOSED);
|
|
236 }
|
|
237
|
|
238 /**
|
|
239 * Creates the device in the operating system. If the device
|
|
240 * does not have a handle, this method may do nothing depending
|
|
241 * on the device.
|
|
242 * <p>
|
|
243 * This method is called before <code>init</code>.
|
|
244 * </p><p>
|
|
245 * Subclasses are supposed to reimplement this method and not
|
|
246 * call the <code>super</code> implementation.
|
|
247 * </p>
|
|
248 *
|
|
249 * @param data the DeviceData which describes the receiver
|
|
250 *
|
|
251 * @see #init
|
|
252 */
|
|
253 protected void create (DeviceData data) {
|
|
254 }
|
|
255
|
|
256 /**
|
|
257 * Disposes of the operating system resources associated with
|
|
258 * the receiver. After this method has been invoked, the receiver
|
|
259 * will answer <code>true</code> when sent the message
|
|
260 * <code>isDisposed()</code>.
|
|
261 *
|
|
262 * @see #release
|
|
263 * @see #destroy
|
|
264 * @see #checkDevice
|
|
265 */
|
|
266 public void dispose () {
|
|
267 if (isDisposed()) return;
|
|
268 checkDevice ();
|
|
269 release ();
|
|
270 destroy ();
|
|
271 deregister (this);
|
19
|
272 xDisplay = null;
|
18
|
273 disposed = true;
|
|
274 if (tracking) {
|
|
275 objects = null;
|
|
276 errors = null;
|
|
277 }
|
|
278 }
|
|
279
|
|
280 void dispose_Object (Object object) {
|
|
281 for (int i=0; i<objects.length; i++) {
|
19
|
282 if (objects [i] is object) {
|
18
|
283 objects [i] = null;
|
|
284 errors [i] = null;
|
|
285 return;
|
|
286 }
|
|
287 }
|
|
288 }
|
|
289
|
19
|
290 static synchronized Device findDevice (dwt.internal.gtk.c.cairotypes.Display* xDisplay) {
|
18
|
291 for (int i=0; i<Devices.length; i++) {
|
|
292 Device device = Devices [i];
|
19
|
293 if (device !is null && device.xDisplay is xDisplay) {
|
18
|
294 return device;
|
|
295 }
|
|
296 }
|
|
297 return null;
|
|
298 }
|
|
299
|
|
300 synchronized static void deregister (Device device) {
|
|
301 for (int i=0; i<Devices.length; i++) {
|
19
|
302 if (device is Devices [i]) Devices [i] = null;
|
18
|
303 }
|
|
304 }
|
|
305
|
|
306 /**
|
|
307 * Destroys the device in the operating system and releases
|
|
308 * the device's handle. If the device does not have a handle,
|
|
309 * this method may do nothing depending on the device.
|
|
310 * <p>
|
|
311 * This method is called after <code>release</code>.
|
|
312 * </p><p>
|
|
313 * Subclasses are supposed to reimplement this method and not
|
|
314 * call the <code>super</code> implementation.
|
|
315 * </p>
|
|
316 *
|
|
317 * @see #dispose
|
|
318 * @see #release
|
|
319 */
|
|
320 protected void destroy () {
|
|
321 }
|
|
322
|
|
323 /**
|
|
324 * Returns a rectangle describing the receiver's size and location.
|
|
325 *
|
|
326 * @return the bounding rectangle
|
|
327 *
|
|
328 * @exception SWTException <ul>
|
|
329 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
|
|
330 * </ul>
|
|
331 */
|
|
332 public Rectangle getBounds () {
|
|
333 checkDevice ();
|
|
334 return new Rectangle(0, 0, 0, 0);
|
|
335 }
|
|
336
|
|
337 /**
|
|
338 * Returns a <code>DeviceData</code> based on the receiver.
|
|
339 * Modifications made to this <code>DeviceData</code> will not
|
|
340 * affect the receiver.
|
|
341 *
|
|
342 * @return a <code>DeviceData</code> containing the device's data and attributes
|
|
343 *
|
|
344 * @exception SWTException <ul>
|
|
345 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
|
|
346 * </ul>
|
|
347 *
|
|
348 * @see DeviceData
|
|
349 */
|
|
350 public DeviceData getDeviceData () {
|
|
351 checkDevice();
|
|
352 DeviceData data = new DeviceData ();
|
19
|
353 data.debugging = debugging;
|
18
|
354 data.tracking = tracking;
|
|
355 int count = 0, length = 0;
|
|
356 if (tracking) length = objects.length;
|
|
357 for (int i=0; i<length; i++) {
|
|
358 if (objects [i] != null) count++;
|
|
359 }
|
|
360 int index = 0;
|
|
361 data.objects = new Object [count];
|
19
|
362 data.errors = new TracedException [count];
|
18
|
363 for (int i=0; i<length; i++) {
|
|
364 if (objects [i] != null) {
|
|
365 data.objects [index] = objects [i];
|
|
366 data.errors [index] = errors [i];
|
|
367 index++;
|
|
368 }
|
|
369 }
|
|
370 return data;
|
|
371 }
|
|
372
|
|
373 /**
|
|
374 * Returns a rectangle which describes the area of the
|
|
375 * receiver which is capable of displaying data.
|
|
376 *
|
|
377 * @return the client area
|
|
378 *
|
|
379 * @exception SWTException <ul>
|
|
380 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
|
|
381 * </ul>
|
|
382 *
|
|
383 * @see #getBounds
|
|
384 */
|
|
385 public Rectangle getClientArea () {
|
|
386 checkDevice ();
|
|
387 return getBounds ();
|
|
388 }
|
|
389
|
|
390 /**
|
|
391 * Returns the bit depth of the screen, which is the number of
|
|
392 * bits it takes to represent the number of unique colors that
|
|
393 * the screen is currently capable of displaying. This number
|
|
394 * will typically be one of 1, 8, 15, 16, 24 or 32.
|
|
395 *
|
|
396 * @return the depth of the screen
|
|
397 *
|
|
398 * @exception SWTException <ul>
|
|
399 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
|
|
400 * </ul>
|
|
401 */
|
|
402 public int getDepth () {
|
|
403 checkDevice ();
|
|
404 return 0;
|
|
405 }
|
|
406
|
|
407 /**
|
|
408 * Returns a point whose x coordinate is the horizontal
|
|
409 * dots per inch of the display, and whose y coordinate
|
|
410 * is the vertical dots per inch of the display.
|
|
411 *
|
|
412 * @return the horizontal and vertical DPI
|
|
413 *
|
|
414 * @exception SWTException <ul>
|
|
415 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
|
|
416 * </ul>
|
|
417 */
|
|
418 public Point getDPI () {
|
|
419 checkDevice ();
|
|
420 return new Point (72, 72);
|
|
421 }
|
|
422
|
|
423 /**
|
|
424 * Returns <code>FontData</code> objects which describe
|
|
425 * the fonts that match the given arguments. If the
|
|
426 * <code>faceName</code> is null, all fonts will be returned.
|
|
427 *
|
|
428 * @param faceName the name of the font to look for, or null
|
|
429 * @param scalable if true only scalable fonts are returned, otherwise only non-scalable fonts are returned.
|
|
430 * @return the matching font data
|
|
431 *
|
|
432 * @exception SWTException <ul>
|
|
433 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
|
|
434 * </ul>
|
|
435 */
|
19
|
436 public FontData[] getFontList (char[] faceName, bool scalable) {
|
18
|
437 checkDevice ();
|
|
438 if (!scalable) return new FontData[0];
|
19
|
439 PangoFontFamily* family;
|
|
440 PangoFontFace * face;
|
|
441 PangoFontFamily** families;
|
|
442 int n_families;
|
|
443 PangoFontFace ** faces;
|
|
444 int n_faces;
|
|
445 auto context = OS.gdk_pango_context_get();
|
|
446 OS.pango_context_list_families(context, &families, &n_families);
|
18
|
447 int nFds = 0;
|
19
|
448 FontData[] fds = new FontData[faceName != null ? 4 : n_families];
|
|
449 for (int i=0; i<n_families; i++) {
|
|
450 family = families[i];
|
|
451 bool match = true;
|
18
|
452 if (faceName != null) {
|
19
|
453 auto familyName = OS.pango_font_family_get_name(family);
|
|
454 match = Compatibility.equalsIgnoreCase(faceName, fromUtf8z( familyName ));
|
18
|
455 }
|
|
456 if (match) {
|
19
|
457 OS.pango_font_family_list_faces(family, &faces, &n_faces);
|
|
458 for (int j=0; j<n_faces; j++) {
|
|
459 face = faces[j];
|
|
460 auto fontDesc = OS.pango_font_face_describe(face);
|
18
|
461 Font font = Font.gtk_new(this, fontDesc);
|
|
462 FontData data = font.getFontData()[0];
|
|
463 if (nFds == fds.length) {
|
19
|
464 fds.length = fds.length + n_families;
|
18
|
465 }
|
|
466 fds[nFds++] = data;
|
|
467 OS.pango_font_description_free(fontDesc);
|
|
468 }
|
|
469 OS.g_free(faces[0]);
|
19
|
470 if (faceName !is null) break;
|
18
|
471 }
|
|
472 }
|
19
|
473 OS.g_free(families);
|
18
|
474 OS.g_object_unref(context);
|
|
475 if (nFds == fds.length) return fds;
|
19
|
476 return fds[ 0 .. nFds ].dup;
|
18
|
477 }
|
|
478
|
|
479 /**
|
|
480 * Returns the matching standard color for the given
|
|
481 * constant, which should be one of the color constants
|
|
482 * specified in class <code>SWT</code>. Any value other
|
|
483 * than one of the SWT color constants which is passed
|
|
484 * in will result in the color black. This color should
|
|
485 * not be freed because it was allocated by the system,
|
|
486 * not the application.
|
|
487 *
|
|
488 * @param id the color constant
|
|
489 * @return the matching color
|
|
490 *
|
|
491 * @exception SWTException <ul>
|
|
492 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
|
|
493 * </ul>
|
|
494 *
|
|
495 * @see SWT
|
|
496 */
|
|
497 public Color getSystemColor (int id) {
|
|
498 checkDevice ();
|
|
499 switch (id) {
|
|
500 case SWT.COLOR_BLACK: return COLOR_BLACK;
|
|
501 case SWT.COLOR_DARK_RED: return COLOR_DARK_RED;
|
|
502 case SWT.COLOR_DARK_GREEN: return COLOR_DARK_GREEN;
|
|
503 case SWT.COLOR_DARK_YELLOW: return COLOR_DARK_YELLOW;
|
|
504 case SWT.COLOR_DARK_BLUE: return COLOR_DARK_BLUE;
|
|
505 case SWT.COLOR_DARK_MAGENTA: return COLOR_DARK_MAGENTA;
|
|
506 case SWT.COLOR_DARK_CYAN: return COLOR_DARK_CYAN;
|
|
507 case SWT.COLOR_GRAY: return COLOR_GRAY;
|
|
508 case SWT.COLOR_DARK_GRAY: return COLOR_DARK_GRAY;
|
|
509 case SWT.COLOR_RED: return COLOR_RED;
|
|
510 case SWT.COLOR_GREEN: return COLOR_GREEN;
|
|
511 case SWT.COLOR_YELLOW: return COLOR_YELLOW;
|
|
512 case SWT.COLOR_BLUE: return COLOR_BLUE;
|
|
513 case SWT.COLOR_MAGENTA: return COLOR_MAGENTA;
|
|
514 case SWT.COLOR_CYAN: return COLOR_CYAN;
|
|
515 case SWT.COLOR_WHITE: return COLOR_WHITE;
|
|
516 }
|
|
517 return COLOR_BLACK;
|
|
518 }
|
|
519
|
|
520 /**
|
|
521 * Returns a reasonable font for applications to use.
|
|
522 * On some platforms, this will match the "default font"
|
|
523 * or "system font" if such can be found. This font
|
|
524 * should not be freed because it was allocated by the
|
|
525 * system, not the application.
|
|
526 * <p>
|
|
527 * Typically, applications which want the default look
|
|
528 * should simply not set the font on the widgets they
|
|
529 * create. Widgets are always created with the correct
|
|
530 * default font for the class of user-interface component
|
|
531 * they represent.
|
|
532 * </p>
|
|
533 *
|
|
534 * @return a font
|
|
535 *
|
|
536 * @exception SWTException <ul>
|
|
537 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
|
|
538 * </ul>
|
|
539 */
|
|
540 public Font getSystemFont () {
|
|
541 checkDevice ();
|
|
542 return systemFont;
|
|
543 }
|
|
544
|
|
545 /**
|
|
546 * Returns <code>true</code> if the underlying window system prints out
|
|
547 * warning messages on the console, and <code>setWarnings</code>
|
|
548 * had previously been called with <code>true</code>.
|
|
549 *
|
|
550 * @return <code>true</code>if warnings are being handled, and <code>false</code> otherwise
|
|
551 *
|
|
552 * @exception SWTException <ul>
|
|
553 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
|
|
554 * </ul>
|
|
555 */
|
19
|
556 public bool getWarnings () {
|
18
|
557 checkDevice ();
|
|
558 return warningLevel == 0;
|
|
559 }
|
|
560
|
|
561 /**
|
|
562 * Initializes any internal resources needed by the
|
|
563 * device.
|
|
564 * <p>
|
|
565 * This method is called after <code>create</code>.
|
|
566 * </p><p>
|
|
567 * If subclasses reimplement this method, they must
|
|
568 * call the <code>super</code> implementation.
|
|
569 * </p>
|
|
570 *
|
|
571 * @see #create
|
|
572 */
|
|
573 protected void init () {
|
19
|
574 if (xDisplay !is null) {
|
|
575 int event_basep, error_basep;
|
|
576 if (OS.XRenderQueryExtension (xDisplay, &event_basep, &error_basep)) {
|
|
577 int major_version, minor_version;
|
|
578 OS.XRenderQueryVersion (xDisplay, &major_version, &minor_version);
|
|
579 useXRender = major_version > 0 || (major_version == 0 && minor_version >= 8);
|
18
|
580 }
|
|
581 }
|
|
582
|
19
|
583 if (debugging) {
|
|
584 if (xDisplay !is null) {
|
18
|
585 /* Create the warning and error callbacks */
|
19
|
586 synchronized (CREATE_LOCK) {
|
18
|
587 int index = 0;
|
|
588 while (index < Devices.length) {
|
|
589 if (Devices [index] != null) break;
|
|
590 index++;
|
|
591 }
|
|
592 if (index == Devices.length) {
|
19
|
593 OS.XSetErrorHandler ( & XErrorProcFunc );
|
|
594 OS.XSetIOErrorHandler ( & XIOErrorProcFunc );
|
18
|
595 }
|
|
596 }
|
|
597 OS.XSynchronize (xDisplay, true);
|
|
598 }
|
|
599 }
|
|
600
|
|
601 /* Create GTK warnings and error callbacks */
|
19
|
602 if (xDisplay !is null) {
|
18
|
603 /* Set GTK warning and error handlers */
|
19
|
604 if (debugging) {
|
18
|
605 int flags = OS.G_LOG_LEVEL_MASK | OS.G_LOG_FLAG_FATAL | OS.G_LOG_FLAG_RECURSION;
|
|
606 for (int i=0; i<log_domains.length; i++) {
|
19
|
607 handler_ids [i] = OS.g_log_set_handler (toStringz(log_domains [i]), cast(GLogLevelFlags)flags, & logFunction, cast(void*)this);
|
18
|
608 }
|
|
609 }
|
|
610 }
|
|
611
|
19
|
612 /* Create the standard colors */
|
18
|
613 COLOR_BLACK = new Color (this, 0,0,0);
|
|
614 COLOR_DARK_RED = new Color (this, 0x80,0,0);
|
|
615 COLOR_DARK_GREEN = new Color (this, 0,0x80,0);
|
|
616 COLOR_DARK_YELLOW = new Color (this, 0x80,0x80,0);
|
|
617 COLOR_DARK_BLUE = new Color (this, 0,0,0x80);
|
|
618 COLOR_DARK_MAGENTA = new Color (this, 0x80,0,0x80);
|
|
619 COLOR_DARK_CYAN = new Color (this, 0,0x80,0x80);
|
|
620 COLOR_GRAY = new Color (this, 0xC0,0xC0,0xC0);
|
|
621 COLOR_DARK_GRAY = new Color (this, 0x80,0x80,0x80);
|
|
622 COLOR_RED = new Color (this, 0xFF,0,0);
|
|
623 COLOR_GREEN = new Color (this, 0,0xFF,0);
|
|
624 COLOR_YELLOW = new Color (this, 0xFF,0xFF,0);
|
|
625 COLOR_BLUE = new Color (this, 0,0,0xFF);
|
|
626 COLOR_MAGENTA = new Color (this, 0xFF,0,0xFF);
|
|
627 COLOR_CYAN = new Color (this, 0,0xFF,0xFF);
|
|
628 COLOR_WHITE = new Color (this, 0xFF,0xFF,0xFF);
|
|
629
|
|
630 emptyTab = OS.pango_tab_array_new(1, false);
|
19
|
631 if (emptyTab is null) SWT.error(SWT.ERROR_NO_HANDLES);
|
|
632 OS.pango_tab_array_set_tab(emptyTab, 0, cast(PangoTabAlign) OS.PANGO_TAB_LEFT, 1);
|
18
|
633
|
19
|
634 shellHandle = OS.gtk_window_new(cast(GtkWindowType)OS.GTK_WINDOW_TOPLEVEL);
|
|
635 if (shellHandle is null) SWT.error(SWT.ERROR_NO_HANDLES);
|
18
|
636 OS.gtk_widget_realize(shellHandle);
|
|
637 }
|
|
638
|
|
639 /**
|
|
640 * Invokes platform specific functionality to allocate a new GC handle.
|
|
641 * <p>
|
|
642 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
|
|
643 * API for <code>Device</code>. It is marked public only so that it
|
|
644 * can be shared within the packages provided by SWT. It is not
|
|
645 * available on all platforms, and should never be called from
|
|
646 * application code.
|
|
647 * </p>
|
|
648 *
|
|
649 * @param data the platform specific GC data
|
|
650 * @return the platform specific GC handle
|
|
651 */
|
19
|
652 public abstract GdkGC* internal_new_GC (GCData data);
|
18
|
653
|
|
654 /**
|
|
655 * Invokes platform specific functionality to dispose a GC handle.
|
|
656 * <p>
|
|
657 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
|
|
658 * API for <code>Device</code>. It is marked public only so that it
|
|
659 * can be shared within the packages provided by SWT. It is not
|
|
660 * available on all platforms, and should never be called from
|
|
661 * application code.
|
|
662 * </p>
|
|
663 *
|
|
664 * @param hDC the platform specific GC handle
|
|
665 * @param data the platform specific GC data
|
|
666 */
|
19
|
667 public abstract void internal_dispose_GC (GdkGC* handle, GCData data);
|
18
|
668
|
|
669 /**
|
|
670 * Returns <code>true</code> if the device has been disposed,
|
|
671 * and <code>false</code> otherwise.
|
|
672 * <p>
|
|
673 * This method gets the dispose state for the device.
|
|
674 * When a device has been disposed, it is an error to
|
|
675 * invoke any other method using the device.
|
|
676 *
|
|
677 * @return <code>true</code> when the device is disposed and <code>false</code> otherwise
|
|
678 */
|
19
|
679 public bool isDisposed () {
|
18
|
680 return disposed;
|
|
681 }
|
|
682
|
|
683 /**
|
|
684 * Loads the font specified by a file. The font will be
|
|
685 * present in the list of fonts available to the application.
|
|
686 *
|
|
687 * @param path the font file path
|
|
688 * @return whether the font was successfully loaded
|
|
689 *
|
|
690 * @exception SWTException <ul>
|
|
691 * <li>ERROR_NULL_ARGUMENT - if path is null</li>
|
|
692 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
|
|
693 * </ul>
|
|
694 *
|
|
695 * @see Font
|
|
696 *
|
|
697 * @since 3.3
|
|
698 */
|
19
|
699 public bool loadFont (char[] path) {
|
18
|
700 checkDevice();
|
|
701 if (path == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
|
19
|
702 return cast(bool) OS.FcConfigAppFontAddFile (null, toStringz(path));
|
18
|
703 }
|
|
704
|
19
|
705 private static extern(C) void logFunction (char* log_domain, GLogLevelFlags log_level, char* message, void* user_data) {
|
|
706 Device dev = cast(Device)user_data;
|
|
707 if (dev.warningLevel == 0) {
|
|
708 if (DEBUG || dev.debugging) {
|
|
709 foreach( msg; new TracedException ("") ){
|
|
710 Stderr.formatln( "trc {}", msg );
|
|
711 }
|
18
|
712 }
|
19
|
713 OS.g_log_default_handler (log_domain, log_level, message, user_data);
|
18
|
714 }
|
|
715 return 0;
|
|
716 }
|
|
717
|
|
718 void new_Object (Object object) {
|
|
719 for (int i=0; i<objects.length; i++) {
|
19
|
720 if (objects [i] is null) {
|
18
|
721 objects [i] = object;
|
19
|
722 errors [i] = new TracedException ("");
|
18
|
723 return;
|
|
724 }
|
|
725 }
|
19
|
726 int oldLen = objects.length;
|
|
727 objects.length = objects.length + 128;
|
|
728 objects[ oldLen ] = object;
|
|
729
|
|
730 oldLen = errors.length;
|
|
731 errors.length = errors.length + 128;
|
|
732 errors[ oldLen ] = new TracedException ("");
|
18
|
733 }
|
|
734
|
|
735 static synchronized void register (Device device) {
|
|
736 for (int i=0; i<Devices.length; i++) {
|
19
|
737 if (Devices [i] is null) {
|
18
|
738 Devices [i] = device;
|
|
739 return;
|
|
740 }
|
|
741 }
|
19
|
742 int oldLen = Devices.length;
|
|
743 Devices.length = Devices.length + 128;
|
|
744 Devices[ oldLen ] = device;
|
18
|
745 }
|
|
746
|
|
747 /**
|
|
748 * Releases any internal resources back to the operating
|
|
749 * system and clears all fields except the device handle.
|
|
750 * <p>
|
|
751 * When a device is destroyed, resources that were acquired
|
|
752 * on behalf of the programmer need to be returned to the
|
|
753 * operating system. For example, if the device allocated a
|
|
754 * font to be used as the system font, this font would be
|
|
755 * freed in <code>release</code>. Also,to assist the garbage
|
|
756 * collector and minimize the amount of memory that is not
|
|
757 * reclaimed when the programmer keeps a reference to a
|
|
758 * disposed device, all fields except the handle are zero'd.
|
|
759 * The handle is needed by <code>destroy</code>.
|
|
760 * </p>
|
|
761 * This method is called before <code>destroy</code>.
|
|
762 * </p><p>
|
|
763 * If subclasses reimplement this method, they must
|
|
764 * call the <code>super</code> implementation.
|
|
765 * </p>
|
|
766 *
|
|
767 * @see #dispose
|
|
768 * @see #destroy
|
|
769 */
|
|
770 protected void release () {
|
19
|
771 if (shellHandle !is null) OS.gtk_widget_destroy(shellHandle);
|
|
772 shellHandle = null;
|
18
|
773
|
19
|
774 if (gdkColors !is null) {
|
|
775 auto colormap = OS.gdk_colormap_get_system();
|
18
|
776 for (int i = 0; i < gdkColors.length; i++) {
|
19
|
777 GdkColor* color = gdkColors [i];
|
|
778 if (color !is null) {
|
18
|
779 while (colorRefCount [i] > 0) {
|
|
780 OS.gdk_colormap_free_colors(colormap, color, 1);
|
|
781 --colorRefCount [i];
|
|
782 }
|
|
783 }
|
|
784 }
|
|
785 }
|
|
786 gdkColors = null;
|
|
787 colorRefCount = null;
|
|
788 COLOR_BLACK = COLOR_DARK_RED = COLOR_DARK_GREEN = COLOR_DARK_YELLOW = COLOR_DARK_BLUE =
|
|
789 COLOR_DARK_MAGENTA = COLOR_DARK_CYAN = COLOR_GRAY = COLOR_DARK_GRAY = COLOR_RED =
|
|
790 COLOR_GREEN = COLOR_YELLOW = COLOR_BLUE = COLOR_MAGENTA = COLOR_CYAN = COLOR_WHITE = null;
|
|
791
|
19
|
792 if (emptyTab !is null ) OS.pango_tab_array_free(emptyTab);
|
|
793 emptyTab = null;
|
18
|
794
|
|
795 /* Free the GTK error and warning handler */
|
19
|
796 if (xDisplay !is null) {
|
18
|
797 for (int i=0; i<handler_ids.length; i++) {
|
19
|
798 if (handler_ids [i] !is 0 ) {
|
|
799 OS.g_log_remove_handler (toStringz(log_domains [i]), handler_ids [i]);
|
18
|
800 handler_ids [i] = 0;
|
|
801 }
|
|
802 }
|
19
|
803 //logCallback.dispose (); logCallback = null;
|
18
|
804 handler_ids = null; log_domains = null;
|
19
|
805 //logProcFld = 0;
|
18
|
806 }
|
|
807 }
|
|
808
|
|
809 /**
|
|
810 * If the underlying window system supports printing warning messages
|
|
811 * to the console, setting warnings to <code>false</code> prevents these
|
|
812 * messages from being printed. If the argument is <code>true</code> then
|
|
813 * message printing is not blocked.
|
|
814 *
|
|
815 * @param warnings <code>true</code>if warnings should be printed, and <code>false</code> otherwise
|
|
816 *
|
|
817 * @exception SWTException <ul>
|
|
818 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
|
|
819 * </ul>
|
|
820 */
|
19
|
821 public void setWarnings (bool warnings) {
|
18
|
822 checkDevice ();
|
|
823 if (warnings) {
|
|
824 if (--warningLevel == 0) {
|
19
|
825 if (debugging) return;
|
|
826 for (int i=0; i<handler_ids.length; i++) {
|
|
827 if (handler_ids [i] != 0) {
|
|
828 OS.g_log_remove_handler (toStringz(log_domains [i]), handler_ids [i]);
|
|
829 handler_ids [i] = 0;
|
|
830 }
|
|
831 }
|
18
|
832 }
|
|
833 } else {
|
|
834 if (warningLevel++ == 0) {
|
19
|
835 if (debugging) return;
|
|
836 int flags = OS.G_LOG_LEVEL_MASK | OS.G_LOG_FLAG_FATAL | OS.G_LOG_FLAG_RECURSION;
|
|
837 for (int i=0; i<log_domains.length; i++) {
|
|
838 handler_ids [i] = OS.g_log_set_handler (toStringz(log_domains [i]), cast(GLogLevelFlags)flags, & logFunction, cast(void*)this );
|
|
839 }
|
18
|
840 }
|
|
841 }
|
|
842 }
|
|
843
|
19
|
844 private static extern(C) int /*long*/ XErrorProcFunc (dwt.internal.gtk.c.cairotypes.Display* xDisplay, dwt.internal.gtk.OS.XErrorEvent* xErrorEvent) {
|
18
|
845 Device device = findDevice (xDisplay);
|
|
846 if (device != null) {
|
|
847 if (device.warningLevel == 0) {
|
19
|
848 if (DEBUG || device.debugging) {
|
|
849 foreach( msg; new TracedException ("") ){
|
|
850 Stderr.formatln( "trc {}", msg );
|
|
851 }
|
18
|
852 }
|
19
|
853 //PORTING_FIXME ??
|
|
854 //OS.Call (XErrorProc, xDisplay, xErrorEvent);
|
18
|
855 }
|
|
856 } else {
|
19
|
857 if (DEBUG) (new SWTError ()).printStackTrace ();
|
|
858 //PORTING_FIXME ??
|
|
859 //OS.Call (XErrorProc, xDisplay, xErrorEvent);
|
18
|
860 }
|
|
861 return 0;
|
|
862 }
|
|
863
|
19
|
864 private static extern(C) int /*long*/ XIOErrorProcFunc (dwt.internal.gtk.c.cairotypes.Display* xDisplay) {
|
18
|
865 Device device = findDevice (xDisplay);
|
|
866 if (device != null) {
|
19
|
867 if (DEBUG || device.debugging) {
|
|
868 foreach( msg; new TracedException ("") ){
|
|
869 Stderr.formatln( "trc {}", msg );
|
|
870 }
|
18
|
871 }
|
|
872 } else {
|
19
|
873 if (DEBUG) {
|
|
874 foreach( msg; new TracedException ("") ){
|
|
875 Stderr.formatln( "trc {}", msg );
|
|
876 }
|
|
877 }
|
18
|
878 }
|
19
|
879 //PORTING_FIXME ??
|
|
880 //OS.Call (XIOErrorProc, xDisplay, 0);
|
18
|
881 return 0;
|
|
882 }
|
|
883
|
|
884 }
|