Mercurial > projects > dwt-linux
annotate dwt/graphics/Device.d @ 28:10acbb123580
Widget and TypedListener
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Wed, 09 Jan 2008 02:59:32 +0100 |
parents | fc2b263b8a3f |
children | 27324bbbac70 |
rev | line source |
---|---|
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 */ | |
28 | 80 protected void* xDisplay; |
19 | 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 | |
28 | 290 static synchronized Device findDevice (void* 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) { | |
25
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
464 FontData[] newFds = new FontData[fds.length + n_families]; |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
465 System.arraycopy(fds, 0, newFds, 0, nFds); |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
466 fds = newFds; |
18 | 467 } |
468 fds[nFds++] = data; | |
469 OS.pango_font_description_free(fontDesc); | |
470 } | |
471 OS.g_free(faces[0]); | |
19 | 472 if (faceName !is null) break; |
18 | 473 } |
474 } | |
19 | 475 OS.g_free(families); |
18 | 476 OS.g_object_unref(context); |
477 if (nFds == fds.length) return fds; | |
25
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
478 FontData[] result = new FontData[nFds]; |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
479 System.arraycopy(fds, 0, result, 0, nFds); |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
480 return result; |
18 | 481 } |
482 | |
483 /** | |
484 * Returns the matching standard color for the given | |
485 * constant, which should be one of the color constants | |
486 * specified in class <code>SWT</code>. Any value other | |
487 * than one of the SWT color constants which is passed | |
488 * in will result in the color black. This color should | |
489 * not be freed because it was allocated by the system, | |
490 * not the application. | |
491 * | |
492 * @param id the color constant | |
493 * @return the matching color | |
494 * | |
495 * @exception SWTException <ul> | |
496 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
497 * </ul> | |
498 * | |
499 * @see SWT | |
500 */ | |
501 public Color getSystemColor (int id) { | |
502 checkDevice (); | |
503 switch (id) { | |
504 case SWT.COLOR_BLACK: return COLOR_BLACK; | |
505 case SWT.COLOR_DARK_RED: return COLOR_DARK_RED; | |
506 case SWT.COLOR_DARK_GREEN: return COLOR_DARK_GREEN; | |
507 case SWT.COLOR_DARK_YELLOW: return COLOR_DARK_YELLOW; | |
508 case SWT.COLOR_DARK_BLUE: return COLOR_DARK_BLUE; | |
509 case SWT.COLOR_DARK_MAGENTA: return COLOR_DARK_MAGENTA; | |
510 case SWT.COLOR_DARK_CYAN: return COLOR_DARK_CYAN; | |
511 case SWT.COLOR_GRAY: return COLOR_GRAY; | |
512 case SWT.COLOR_DARK_GRAY: return COLOR_DARK_GRAY; | |
513 case SWT.COLOR_RED: return COLOR_RED; | |
514 case SWT.COLOR_GREEN: return COLOR_GREEN; | |
515 case SWT.COLOR_YELLOW: return COLOR_YELLOW; | |
516 case SWT.COLOR_BLUE: return COLOR_BLUE; | |
517 case SWT.COLOR_MAGENTA: return COLOR_MAGENTA; | |
518 case SWT.COLOR_CYAN: return COLOR_CYAN; | |
519 case SWT.COLOR_WHITE: return COLOR_WHITE; | |
520 } | |
521 return COLOR_BLACK; | |
522 } | |
523 | |
524 /** | |
525 * Returns a reasonable font for applications to use. | |
526 * On some platforms, this will match the "default font" | |
527 * or "system font" if such can be found. This font | |
528 * should not be freed because it was allocated by the | |
529 * system, not the application. | |
530 * <p> | |
531 * Typically, applications which want the default look | |
532 * should simply not set the font on the widgets they | |
533 * create. Widgets are always created with the correct | |
534 * default font for the class of user-interface component | |
535 * they represent. | |
536 * </p> | |
537 * | |
538 * @return a font | |
539 * | |
540 * @exception SWTException <ul> | |
541 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
542 * </ul> | |
543 */ | |
544 public Font getSystemFont () { | |
545 checkDevice (); | |
546 return systemFont; | |
547 } | |
548 | |
549 /** | |
550 * Returns <code>true</code> if the underlying window system prints out | |
551 * warning messages on the console, and <code>setWarnings</code> | |
552 * had previously been called with <code>true</code>. | |
553 * | |
554 * @return <code>true</code>if warnings are being handled, and <code>false</code> otherwise | |
555 * | |
556 * @exception SWTException <ul> | |
557 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
558 * </ul> | |
559 */ | |
19 | 560 public bool getWarnings () { |
18 | 561 checkDevice (); |
562 return warningLevel == 0; | |
563 } | |
564 | |
565 /** | |
566 * Initializes any internal resources needed by the | |
567 * device. | |
568 * <p> | |
569 * This method is called after <code>create</code>. | |
570 * </p><p> | |
571 * If subclasses reimplement this method, they must | |
572 * call the <code>super</code> implementation. | |
573 * </p> | |
574 * | |
575 * @see #create | |
576 */ | |
577 protected void init () { | |
19 | 578 if (xDisplay !is null) { |
579 int event_basep, error_basep; | |
580 if (OS.XRenderQueryExtension (xDisplay, &event_basep, &error_basep)) { | |
581 int major_version, minor_version; | |
582 OS.XRenderQueryVersion (xDisplay, &major_version, &minor_version); | |
583 useXRender = major_version > 0 || (major_version == 0 && minor_version >= 8); | |
18 | 584 } |
585 } | |
586 | |
19 | 587 if (debugging) { |
588 if (xDisplay !is null) { | |
18 | 589 /* Create the warning and error callbacks */ |
19 | 590 synchronized (CREATE_LOCK) { |
18 | 591 int index = 0; |
592 while (index < Devices.length) { | |
593 if (Devices [index] != null) break; | |
594 index++; | |
595 } | |
596 if (index == Devices.length) { | |
19 | 597 OS.XSetErrorHandler ( & XErrorProcFunc ); |
598 OS.XSetIOErrorHandler ( & XIOErrorProcFunc ); | |
18 | 599 } |
600 } | |
601 OS.XSynchronize (xDisplay, true); | |
602 } | |
603 } | |
604 | |
605 /* Create GTK warnings and error callbacks */ | |
19 | 606 if (xDisplay !is null) { |
18 | 607 /* Set GTK warning and error handlers */ |
19 | 608 if (debugging) { |
18 | 609 int flags = OS.G_LOG_LEVEL_MASK | OS.G_LOG_FLAG_FATAL | OS.G_LOG_FLAG_RECURSION; |
610 for (int i=0; i<log_domains.length; i++) { | |
19 | 611 handler_ids [i] = OS.g_log_set_handler (toStringz(log_domains [i]), cast(GLogLevelFlags)flags, & logFunction, cast(void*)this); |
18 | 612 } |
613 } | |
614 } | |
615 | |
19 | 616 /* Create the standard colors */ |
18 | 617 COLOR_BLACK = new Color (this, 0,0,0); |
618 COLOR_DARK_RED = new Color (this, 0x80,0,0); | |
619 COLOR_DARK_GREEN = new Color (this, 0,0x80,0); | |
620 COLOR_DARK_YELLOW = new Color (this, 0x80,0x80,0); | |
621 COLOR_DARK_BLUE = new Color (this, 0,0,0x80); | |
622 COLOR_DARK_MAGENTA = new Color (this, 0x80,0,0x80); | |
623 COLOR_DARK_CYAN = new Color (this, 0,0x80,0x80); | |
624 COLOR_GRAY = new Color (this, 0xC0,0xC0,0xC0); | |
625 COLOR_DARK_GRAY = new Color (this, 0x80,0x80,0x80); | |
626 COLOR_RED = new Color (this, 0xFF,0,0); | |
627 COLOR_GREEN = new Color (this, 0,0xFF,0); | |
628 COLOR_YELLOW = new Color (this, 0xFF,0xFF,0); | |
629 COLOR_BLUE = new Color (this, 0,0,0xFF); | |
630 COLOR_MAGENTA = new Color (this, 0xFF,0,0xFF); | |
631 COLOR_CYAN = new Color (this, 0,0xFF,0xFF); | |
632 COLOR_WHITE = new Color (this, 0xFF,0xFF,0xFF); | |
633 | |
634 emptyTab = OS.pango_tab_array_new(1, false); | |
19 | 635 if (emptyTab is null) SWT.error(SWT.ERROR_NO_HANDLES); |
636 OS.pango_tab_array_set_tab(emptyTab, 0, cast(PangoTabAlign) OS.PANGO_TAB_LEFT, 1); | |
18 | 637 |
19 | 638 shellHandle = OS.gtk_window_new(cast(GtkWindowType)OS.GTK_WINDOW_TOPLEVEL); |
639 if (shellHandle is null) SWT.error(SWT.ERROR_NO_HANDLES); | |
18 | 640 OS.gtk_widget_realize(shellHandle); |
641 } | |
642 | |
643 /** | |
644 * Invokes platform specific functionality to allocate a new GC handle. | |
645 * <p> | |
646 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
647 * API for <code>Device</code>. It is marked public only so that it | |
648 * can be shared within the packages provided by SWT. It is not | |
649 * available on all platforms, and should never be called from | |
650 * application code. | |
651 * </p> | |
652 * | |
653 * @param data the platform specific GC data | |
654 * @return the platform specific GC handle | |
655 */ | |
19 | 656 public abstract GdkGC* internal_new_GC (GCData data); |
18 | 657 |
658 /** | |
659 * Invokes platform specific functionality to dispose a GC handle. | |
660 * <p> | |
661 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
662 * API for <code>Device</code>. It is marked public only so that it | |
663 * can be shared within the packages provided by SWT. It is not | |
664 * available on all platforms, and should never be called from | |
665 * application code. | |
666 * </p> | |
667 * | |
668 * @param hDC the platform specific GC handle | |
669 * @param data the platform specific GC data | |
670 */ | |
19 | 671 public abstract void internal_dispose_GC (GdkGC* handle, GCData data); |
18 | 672 |
673 /** | |
674 * Returns <code>true</code> if the device has been disposed, | |
675 * and <code>false</code> otherwise. | |
676 * <p> | |
677 * This method gets the dispose state for the device. | |
678 * When a device has been disposed, it is an error to | |
679 * invoke any other method using the device. | |
680 * | |
681 * @return <code>true</code> when the device is disposed and <code>false</code> otherwise | |
682 */ | |
19 | 683 public bool isDisposed () { |
18 | 684 return disposed; |
685 } | |
686 | |
687 /** | |
688 * Loads the font specified by a file. The font will be | |
689 * present in the list of fonts available to the application. | |
690 * | |
691 * @param path the font file path | |
692 * @return whether the font was successfully loaded | |
693 * | |
694 * @exception SWTException <ul> | |
695 * <li>ERROR_NULL_ARGUMENT - if path is null</li> | |
696 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
697 * </ul> | |
698 * | |
699 * @see Font | |
700 * | |
701 * @since 3.3 | |
702 */ | |
19 | 703 public bool loadFont (char[] path) { |
18 | 704 checkDevice(); |
705 if (path == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); | |
19 | 706 return cast(bool) OS.FcConfigAppFontAddFile (null, toStringz(path)); |
18 | 707 } |
708 | |
19 | 709 private static extern(C) void logFunction (char* log_domain, GLogLevelFlags log_level, char* message, void* user_data) { |
710 Device dev = cast(Device)user_data; | |
711 if (dev.warningLevel == 0) { | |
712 if (DEBUG || dev.debugging) { | |
713 foreach( msg; new TracedException ("") ){ | |
714 Stderr.formatln( "trc {}", msg ); | |
715 } | |
18 | 716 } |
19 | 717 OS.g_log_default_handler (log_domain, log_level, message, user_data); |
18 | 718 } |
719 return 0; | |
720 } | |
721 | |
722 void new_Object (Object object) { | |
723 for (int i=0; i<objects.length; i++) { | |
19 | 724 if (objects [i] is null) { |
18 | 725 objects [i] = object; |
19 | 726 errors [i] = new TracedException (""); |
18 | 727 return; |
728 } | |
729 } | |
25
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
730 Object [] newObjects = new Object [objects.length + 128]; |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
731 System.arraycopy (objects, 0, newObjects, 0, objects.length); |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
732 newObjects [objects.length] = object; |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
733 objects = newObjects; |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
734 TracedException [] newErrors = new TracedException [errors.length + 128]; |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
735 System.arraycopy (errors, 0, newErrors, 0, errors.length); |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
736 newErrors [errors.length] = new TracedException (""); |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
737 errors = newErrors; |
18 | 738 } |
739 | |
740 static synchronized void register (Device device) { | |
741 for (int i=0; i<Devices.length; i++) { | |
19 | 742 if (Devices [i] is null) { |
18 | 743 Devices [i] = device; |
744 return; | |
745 } | |
746 } | |
25
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
747 Device [] newDevices = new Device [Devices.length + 4]; |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
748 System.arraycopy (Devices, 0, newDevices, 0, Devices.length); |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
749 newDevices [Devices.length] = device; |
fc2b263b8a3f
Merged back the System.arraycopy and use a System class
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
750 Devices = newDevices; |
18 | 751 } |
752 | |
753 /** | |
754 * Releases any internal resources back to the operating | |
755 * system and clears all fields except the device handle. | |
756 * <p> | |
757 * When a device is destroyed, resources that were acquired | |
758 * on behalf of the programmer need to be returned to the | |
759 * operating system. For example, if the device allocated a | |
760 * font to be used as the system font, this font would be | |
761 * freed in <code>release</code>. Also,to assist the garbage | |
762 * collector and minimize the amount of memory that is not | |
763 * reclaimed when the programmer keeps a reference to a | |
764 * disposed device, all fields except the handle are zero'd. | |
765 * The handle is needed by <code>destroy</code>. | |
766 * </p> | |
767 * This method is called before <code>destroy</code>. | |
768 * </p><p> | |
769 * If subclasses reimplement this method, they must | |
770 * call the <code>super</code> implementation. | |
771 * </p> | |
772 * | |
773 * @see #dispose | |
774 * @see #destroy | |
775 */ | |
776 protected void release () { | |
19 | 777 if (shellHandle !is null) OS.gtk_widget_destroy(shellHandle); |
778 shellHandle = null; | |
18 | 779 |
19 | 780 if (gdkColors !is null) { |
781 auto colormap = OS.gdk_colormap_get_system(); | |
18 | 782 for (int i = 0; i < gdkColors.length; i++) { |
19 | 783 GdkColor* color = gdkColors [i]; |
784 if (color !is null) { | |
18 | 785 while (colorRefCount [i] > 0) { |
786 OS.gdk_colormap_free_colors(colormap, color, 1); | |
787 --colorRefCount [i]; | |
788 } | |
789 } | |
790 } | |
791 } | |
792 gdkColors = null; | |
793 colorRefCount = null; | |
794 COLOR_BLACK = COLOR_DARK_RED = COLOR_DARK_GREEN = COLOR_DARK_YELLOW = COLOR_DARK_BLUE = | |
795 COLOR_DARK_MAGENTA = COLOR_DARK_CYAN = COLOR_GRAY = COLOR_DARK_GRAY = COLOR_RED = | |
796 COLOR_GREEN = COLOR_YELLOW = COLOR_BLUE = COLOR_MAGENTA = COLOR_CYAN = COLOR_WHITE = null; | |
797 | |
19 | 798 if (emptyTab !is null ) OS.pango_tab_array_free(emptyTab); |
799 emptyTab = null; | |
18 | 800 |
801 /* Free the GTK error and warning handler */ | |
19 | 802 if (xDisplay !is null) { |
18 | 803 for (int i=0; i<handler_ids.length; i++) { |
19 | 804 if (handler_ids [i] !is 0 ) { |
805 OS.g_log_remove_handler (toStringz(log_domains [i]), handler_ids [i]); | |
18 | 806 handler_ids [i] = 0; |
807 } | |
808 } | |
19 | 809 //logCallback.dispose (); logCallback = null; |
18 | 810 handler_ids = null; log_domains = null; |
19 | 811 //logProcFld = 0; |
18 | 812 } |
813 } | |
814 | |
815 /** | |
816 * If the underlying window system supports printing warning messages | |
817 * to the console, setting warnings to <code>false</code> prevents these | |
818 * messages from being printed. If the argument is <code>true</code> then | |
819 * message printing is not blocked. | |
820 * | |
821 * @param warnings <code>true</code>if warnings should be printed, and <code>false</code> otherwise | |
822 * | |
823 * @exception SWTException <ul> | |
824 * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> | |
825 * </ul> | |
826 */ | |
19 | 827 public void setWarnings (bool warnings) { |
18 | 828 checkDevice (); |
829 if (warnings) { | |
830 if (--warningLevel == 0) { | |
19 | 831 if (debugging) return; |
832 for (int i=0; i<handler_ids.length; i++) { | |
833 if (handler_ids [i] != 0) { | |
834 OS.g_log_remove_handler (toStringz(log_domains [i]), handler_ids [i]); | |
835 handler_ids [i] = 0; | |
836 } | |
837 } | |
18 | 838 } |
839 } else { | |
840 if (warningLevel++ == 0) { | |
19 | 841 if (debugging) return; |
842 int flags = OS.G_LOG_LEVEL_MASK | OS.G_LOG_FLAG_FATAL | OS.G_LOG_FLAG_RECURSION; | |
843 for (int i=0; i<log_domains.length; i++) { | |
844 handler_ids [i] = OS.g_log_set_handler (toStringz(log_domains [i]), cast(GLogLevelFlags)flags, & logFunction, cast(void*)this ); | |
845 } | |
18 | 846 } |
847 } | |
848 } | |
849 | |
28 | 850 private static extern(C) int /*long*/ XErrorProcFunc (void* xDisplay, dwt.internal.gtk.OS.XErrorEvent* xErrorEvent) { |
18 | 851 Device device = findDevice (xDisplay); |
852 if (device != null) { | |
853 if (device.warningLevel == 0) { | |
19 | 854 if (DEBUG || device.debugging) { |
855 foreach( msg; new TracedException ("") ){ | |
856 Stderr.formatln( "trc {}", msg ); | |
857 } | |
18 | 858 } |
19 | 859 //PORTING_FIXME ?? |
860 //OS.Call (XErrorProc, xDisplay, xErrorEvent); | |
18 | 861 } |
862 } else { | |
19 | 863 if (DEBUG) (new SWTError ()).printStackTrace (); |
864 //PORTING_FIXME ?? | |
865 //OS.Call (XErrorProc, xDisplay, xErrorEvent); | |
18 | 866 } |
867 return 0; | |
868 } | |
869 | |
28 | 870 private static extern(C) int /*long*/ XIOErrorProcFunc (void* xDisplay) { |
18 | 871 Device device = findDevice (xDisplay); |
872 if (device != null) { | |
19 | 873 if (DEBUG || device.debugging) { |
874 foreach( msg; new TracedException ("") ){ | |
875 Stderr.formatln( "trc {}", msg ); | |
876 } | |
18 | 877 } |
878 } else { | |
19 | 879 if (DEBUG) { |
880 foreach( msg; new TracedException ("") ){ | |
881 Stderr.formatln( "trc {}", msg ); | |
882 } | |
883 } | |
18 | 884 } |
19 | 885 //PORTING_FIXME ?? |
886 //OS.Call (XIOErrorProc, xDisplay, 0); | |
18 | 887 return 0; |
888 } | |
889 | |
890 } |