Move negative tests from ilasm/tests to ilasm/errors.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ThemeGtk.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004-2006 Novell, Inc.
21 //
22 // Authors:
23 //      Jordi Mas i Hernandez, jordi@ximian.com
24 //      Alexander Olk, alex.olk@googlemail.com
25 //
26 //      This is an experimental GTK theme. 
27 //
28 //      Comments:
29 //              - For now we would keep all the themes in the same assembly to have
30 //              handy the internals methods. 
31 //              - We are using Pinovoke for now to access GTK/GDK to avoid adding 
32 //              gtk-sharp as a SWF dependency
33 //              - The ThemeGtk comes from ThemeWin32Classic, we use it as the default
34 //              implementation for the methods that we are not taking care of.
35 //              - When GDK is initialised it opens its own display. There is not way of changing it,
36 //              then we use that display as SWF display
37 //              - You can activate this Theme in Linux doing export MONO_THEME=gtk
38 //              - GTK paints controls into a window not a device context. We should inverstigate if we 
39 //              we can encapsulate a dc in a gtkwindow.
40
41
42 // NOT COMPLETE
43
44 // TODO:        - fix position of button focus rectangle
45 //              - fix TrackBar drawing location
46
47
48 //#define _EXPERIMENTAL_
49
50 using System;
51 using System.Drawing;
52 using System.Drawing.Drawing2D;
53 using System.Drawing.Imaging;
54 using System.Reflection;
55 using System.Runtime.InteropServices;
56 using System.IO;
57
58 namespace System.Windows.Forms
59 {
60         internal class ThemeGtk : ThemeWin32Classic
61         {               
62                 /* GTK enums */
63                 internal enum StateType 
64                 {
65                         Normal,
66                         Active,
67                         Prelight,
68                         Selected,
69                         Insensitive,
70                 }       
71
72                 internal enum ShadowType 
73                 {
74                         None,
75                         In,
76                         Out,
77                         EtchedIn,
78                         EtchedOut,
79                 }       
80
81                 internal enum ArrowType 
82                 {
83                         Up,
84                         Down,
85                         Left,
86                         Right,
87                 }
88                 
89                 /* Structs */
90                 [StructLayout(LayoutKind.Sequential)]   
91                 internal struct GdkColorStruct
92                 {
93                         internal int pixel;
94                         internal short red;
95                         internal short green;
96                         internal short blue;
97                 }
98
99                 [StructLayout(LayoutKind.Sequential)]   
100                 internal struct GtkStyleStruct
101                 {
102                         [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=12)]
103                         internal byte[] obj; /* GObject is 12 bytes*/
104                         [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
105                         internal GdkColorStruct[] fg;
106                         [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]               
107                         internal GdkColorStruct[] bg;
108                         [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
109                         internal GdkColorStruct[] light;
110                         [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
111                         internal GdkColorStruct[] dark;
112                         [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
113                         internal GdkColorStruct[] mid;
114                         [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
115                         internal GdkColorStruct[] text;
116                         [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
117                         internal GdkColorStruct[] baseclr;
118                         [MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=5)]
119                         internal GdkColorStruct[] text_aa;              /* Halfway between text/base */
120   
121                         internal GdkColorStruct black;
122                         internal GdkColorStruct white;
123
124                         /* TODO: There is more stuff that we will add when we need it*/
125                 }
126                 
127                 /* GDK imports */
128                 [DllImport("libgdk-x11-2.0.so")]
129                 internal static extern IntPtr gdk_display_manager_get ();
130
131                 [DllImport("libgdk-x11-2.0.so")]
132                 internal static extern IntPtr gdk_display_manager_get_default_display (IntPtr display_manager);
133
134                 [DllImport("libgdk-x11-2.0.so")]
135                 internal static extern void gdk_display_manager_set_default_display (IntPtr display_manager, IntPtr display);
136
137                 [DllImport("libgdk-x11-2.0.so")]
138                 internal static extern IntPtr gdk_x11_display_get_xdisplay (IntPtr display);
139
140                 [DllImport("libgdk-x11-2.0.so")]
141                 static extern IntPtr gdk_window_foreign_new_for_display (IntPtr display, uint anid);
142
143                 [DllImport("libgdk-x11-2.0.so")]
144                 static extern bool gdk_init_check(out int argc, string argv);   
145                 
146                 [DllImport("libgdk-x11-2.0.so")]
147                 static extern IntPtr gdk_pixmap_new (IntPtr drawable, int width, int height, int depth);
148                 
149                 [DllImport("libgdk-x11-2.0.so")]
150                 static extern IntPtr gdk_pixbuf_get_from_drawable (IntPtr dest, IntPtr drawable_src, IntPtr cmap,
151                                                                    int src_x, int src_y, int dest_x, int dest_y, int width, int height);
152                 
153                 [DllImport("libgdk-x11-2.0.so")]
154                 static extern bool gdk_pixbuf_save_to_buffer (IntPtr pixbuf, out IntPtr buffer, out UIntPtr buffer_size, string type, out IntPtr error, IntPtr option_dummy);
155                 
156                 [DllImport("libgdk-x11-2.0.so")]
157                 static extern IntPtr gdk_drawable_get_colormap (IntPtr drawable);
158                 
159                 [DllImport("libgdk-x11-2.0.so")]
160                 static extern IntPtr gdk_colormap_get_system ();
161                 
162                 [DllImport("libgdk-x11-2.0.so")]
163                 static extern IntPtr gdk_pixbuf_new (int colorspace, bool has_alpha, int bits_per_sample, int width, int height);
164                 
165                 [DllImport("libgdk-x11-2.0.so")]
166                 static extern IntPtr gdk_gc_new (IntPtr drawable);
167                 
168                 /* glib imports*/
169                 [DllImport("libglib-2.0.so")]
170                 static extern void g_free (IntPtr mem);
171                 
172                 [DllImport("libgobject-2.0.so")]
173                 static extern void g_object_unref (IntPtr nativeObject);
174
175                 /* GTK imports */               
176                 [DllImport("libgtk-x11-2.0.so")]
177                 static extern bool gtk_init_check (out int argc, string argv);
178
179                 [DllImport("libgtk-x11-2.0.so")]
180                 static extern IntPtr gtk_adjustment_new (double value, double lower, double upper, double step_increment, double page_increment, double page_size);
181
182                 [DllImport("libgtk-x11-2.0.so")]
183                 static extern IntPtr gtk_rc_get_style (IntPtr widget);
184
185                 [DllImport("libgtk-x11-2.0.so")]
186                 static extern IntPtr gtk_vscrollbar_new(IntPtr adjustment);
187                 
188                 [DllImport("libgtk-x11-2.0.so")]
189                 static extern IntPtr gtk_hscrollbar_new(IntPtr adjustment);
190
191                 [DllImport("libgtk-x11-2.0.so")]
192                 static extern IntPtr gtk_style_attach (IntPtr raw, IntPtr window);
193
194                 [DllImport("libgtk-x11-2.0.so")]
195                 static extern IntPtr gtk_rc_style_new ();
196
197                 [DllImport("libgtk-x11-2.0.so")]
198                 static extern IntPtr gtk_invisible_new ();
199
200                 [DllImport("libgtk-x11-2.0.so")]
201                 static extern void gtk_widget_ensure_style (IntPtr raw);
202
203                 [DllImport("libgtk-x11-2.0.so")]
204                 static extern IntPtr gtk_widget_get_style (IntPtr raw);
205
206                 [DllImport("libgtk-x11-2.0.so")]
207                 static extern void gtk_style_detach (IntPtr raw);
208                 
209                 [DllImport("libgtk-x11-2.0.so")]
210                 static extern IntPtr gtk_button_new ();
211                 
212                 [DllImport("libgtk-x11-2.0.so")]
213                 static extern IntPtr gtk_progress_bar_new ();
214                 
215                 [DllImport("libgtk-x11-2.0.so")]
216                 static extern IntPtr gtk_radio_button_new (IntPtr group);
217                 
218                 [DllImport("libgtk-x11-2.0.so")]
219                 static extern IntPtr gtk_check_button_new ();
220                 
221                 [DllImport("libgtk-x11-2.0.so")]
222                 static extern IntPtr gtk_hscale_new (IntPtr adjustment);
223                 
224                 [DllImport("libgtk-x11-2.0.so")]
225                 static extern IntPtr gtk_vscale_new (IntPtr adjustment);
226                 
227                 [DllImport("libgtk-x11-2.0.so")]
228                 static extern void gtk_range_set_range (IntPtr range, double min, double max);
229                 
230                 [DllImport("libgtk-x11-2.0.so")]
231                 static extern void gtk_range_set_value (IntPtr range, double value);
232
233                 /* GTK Drawing */
234                 [DllImport("libgtk-x11-2.0.so")]
235                 static extern void gtk_paint_handle (IntPtr style, IntPtr window, int state_type, int shadow_type, IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height, int orientation);
236
237                 [DllImport("libgtk-x11-2.0.so")]
238                 static extern void gtk_paint_arrow (IntPtr style, IntPtr window, int state_type, int shadow_type, 
239                                                     IntPtr area, IntPtr widget, string detail, int arrow_type, bool fill, int x, int y, int width, int height);
240
241                 [DllImport("libgtk-x11-2.0.so")]
242                 static extern void gtk_paint_slider (IntPtr style, IntPtr window, int state_type, int shadow_type, 
243                                                      IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height, int orientation);
244
245                 [DllImport("libgtk-x11-2.0.so")]
246                 static extern void gtk_paint_box (IntPtr style, IntPtr window, int state_type, int shadow_type, 
247                                                   IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height);
248                 
249                 [DllImport("libgtk-x11-2.0.so")]
250                 static extern void gtk_paint_flat_box (IntPtr style, IntPtr window, int state_type, int shadow_type,
251                                                        IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height);
252                 
253                 [DllImport("libgtk-x11-2.0.so")]
254                 static extern void gtk_paint_hline(IntPtr style, IntPtr window, int state_type, IntPtr area, IntPtr widget, string detail, int x1, int x2, int y);
255                 
256                 [DllImport("libgtk-x11-2.0.so")]
257                 static extern void gtk_paint_vline(IntPtr style, IntPtr window, int state_type, IntPtr area, IntPtr widget, string detail, int y1, int y2, int x);
258                 
259                 [DllImport("libgtk-x11-2.0.so")]
260                 static extern void gtk_paint_check(IntPtr style, IntPtr window, int state_type, int shadow_type, IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height);
261                 
262                 [DllImport("libgtk-x11-2.0.so")]
263                 static extern void gtk_paint_focus(IntPtr style, IntPtr window, int state_type, IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height);
264                 
265                 [DllImport("libgtk-x11-2.0.so")]
266                 static extern void gtk_widget_size_allocate (IntPtr widget, ref Rectangle allocation);
267                 
268                 [DllImport("libgtk-x11-2.0.so")]
269                 static extern void gtk_paint_option (IntPtr style, IntPtr window, int state_type, int shadow_type, IntPtr area, IntPtr widget, string detail, int x, int y, int width, int height);
270                 
271                 [DllImport("libgtk-x11-2.0.so")]
272                 static extern void gtk_widget_grab_focus (IntPtr widget);
273                 
274                 /* Data */
275                 static protected IntPtr dispmgr;
276                 static protected IntPtr gdkdisplay;
277                 static protected IntPtr widget;
278                 static protected IntPtr global_style;
279                 
280                 #if _EXPERIMENTAL_
281                 static protected IntPtr global_color_map = IntPtr.Zero;
282                 #endif
283                 
284                 static protected IntPtr global_gtk_button = IntPtr.Zero;
285                 static protected IntPtr global_gtk_button_style = IntPtr.Zero;
286                 
287                 static protected IntPtr global_gtk_vscrollbar = IntPtr.Zero;
288                 static protected IntPtr global_gtk_vscrollbar_style = IntPtr.Zero;
289                 
290                 static protected IntPtr global_gtk_hscrollbar = IntPtr.Zero;
291                 static protected IntPtr global_gtk_hscrollbar_style = IntPtr.Zero;
292                 
293                 static protected IntPtr global_gtk_progress_bar = IntPtr.Zero;
294                 static protected IntPtr global_gtk_progress_bar_style = IntPtr.Zero;
295                 
296                 static protected IntPtr global_gtk_radio_button = IntPtr.Zero;
297                 static protected IntPtr global_gtk_radio_button_style = IntPtr.Zero;
298                 
299                 static protected IntPtr global_gtk_check_button = IntPtr.Zero;
300                 static protected IntPtr global_gtk_check_button_style = IntPtr.Zero;
301                 
302                 static protected IntPtr global_gtk_hscale = IntPtr.Zero;
303                 static protected IntPtr global_gtk_hscale_style = IntPtr.Zero;
304                 
305                 static protected IntPtr global_gtk_vscale = IntPtr.Zero;
306                 static protected IntPtr global_gtk_vscale_style = IntPtr.Zero;
307                 
308                 static protected IntPtr current_gdk_drawable = IntPtr.Zero;
309                 static protected IntPtr current_style = IntPtr.Zero;
310                 static protected IntPtr current_widget = IntPtr.Zero;
311
312                 public static void InitGtk ()
313                 {       
314                         Console.WriteLine ("ThemeGtk Init");            
315                         int argc = 0;
316                         string argv = "";
317                         
318                         gdk_init_check (out argc, argv);        
319
320                         dispmgr =  gdk_display_manager_get ();
321                         gdkdisplay =  gdk_display_manager_get_default_display (dispmgr);
322                         gtk_init_check (out argc, argv);
323
324                         widget = gtk_invisible_new ();
325                         gtk_widget_ensure_style (widget);
326                         global_style = gtk_widget_get_style (widget);                   
327
328                         XplatUIX11.GetInstance().SetDisplay (gdk_x11_display_get_xdisplay (gdkdisplay));
329                         
330                         global_gtk_button = gtk_button_new();
331                         gtk_widget_ensure_style (global_gtk_button);
332                         global_gtk_button_style = gtk_rc_get_style (global_gtk_button);
333                         
334                         IntPtr adj = gtk_adjustment_new (0, 0, 0, 0, 0, 0);
335                         global_gtk_vscrollbar = gtk_vscrollbar_new (adj);
336                         gtk_widget_ensure_style (global_gtk_vscrollbar);
337                         global_gtk_vscrollbar_style = gtk_rc_get_style (global_gtk_vscrollbar);
338                         
339                         global_gtk_hscrollbar = gtk_hscrollbar_new (adj);
340                         gtk_widget_ensure_style (global_gtk_hscrollbar);
341                         global_gtk_hscrollbar_style = gtk_rc_get_style (global_gtk_hscrollbar);
342                         
343                         global_gtk_progress_bar = gtk_progress_bar_new ();
344                         gtk_widget_ensure_style (global_gtk_progress_bar);
345                         global_gtk_progress_bar_style = gtk_rc_get_style (global_gtk_progress_bar);
346                         
347                         global_gtk_radio_button = gtk_radio_button_new (IntPtr.Zero);
348                         gtk_widget_ensure_style (global_gtk_radio_button);
349                         global_gtk_radio_button_style = gtk_rc_get_style (global_gtk_radio_button);
350                         
351                         global_gtk_check_button = gtk_check_button_new ();
352                         gtk_widget_ensure_style (global_gtk_check_button);
353                         global_gtk_check_button_style = gtk_rc_get_style (global_gtk_check_button);
354                         
355                         global_gtk_hscale = gtk_hscale_new (adj);
356                         gtk_widget_ensure_style (global_gtk_hscale);
357                         global_gtk_hscale_style = gtk_rc_get_style (global_gtk_hscale);
358                         
359                         global_gtk_vscale = gtk_vscale_new (adj);
360                         gtk_widget_ensure_style (global_gtk_vscale);
361                         global_gtk_vscale_style = gtk_rc_get_style (global_gtk_vscale);
362                         
363                         #if _EXPERIMENTAL_
364                         global_color_map = gdk_colormap_get_system ();
365                         #endif
366                 }
367
368                 public void LoadSysDefaultColors ()
369                 {
370                         GtkStyleStruct style_struct;                    
371                         
372                         style_struct = (GtkStyleStruct) Marshal.PtrToStructure (global_style, typeof (GtkStyleStruct));                 
373                         defaultWindowBackColor = ColorFromGdkColor (style_struct.bg[0]);
374                         defaultWindowForeColor = ColorFromGdkColor (style_struct.fg[0]);
375                 }
376
377                 public ThemeGtk () : base ()
378                 {
379                         Console.WriteLine ("ThemeGtk constructor");
380                         InitGtk ();
381                         default_font =  new Font (FontFamily.GenericSansSerif, 8.25f);
382                         
383                         LoadSysDefaultColors ();        
384
385                         always_draw_hotkeys = true;
386                 }       
387
388                 public override bool DoubleBufferingSupported {
389                         #if _EXPERIMENTAL_
390                         get {return true; }
391                         #else
392                         get {return false; }
393                         #endif
394                 }
395                 
396                 private void SetDrawableAndStyle (Control control)
397                 {
398                         #if _EXPERIMENTAL_
399                         if (current_gdk_drawable != IntPtr.Zero) {
400                                 g_object_unref (current_gdk_drawable);
401                                 current_gdk_drawable = IntPtr.Zero;
402                         }
403                         current_gdk_drawable = gdk_pixmap_new (IntPtr.Zero, control.ClientRectangle.Width, control.ClientRectangle.Height, 24);
404                         #else
405                         current_gdk_drawable = gdk_window_foreign_new_for_display (gdkdisplay, (uint) control.Handle);
406                         #endif
407                         
408                         IntPtr tmp_style = IntPtr.Zero;
409                         
410                         if (control is ButtonBase) {
411                                 tmp_style = global_gtk_button_style;
412                                 current_widget = global_gtk_button;
413                         } else
414                         if (control is ScrollBar) {
415                                 ScrollBar bar = control as ScrollBar;
416                                 if (bar.vert) {
417                                         tmp_style = global_gtk_vscrollbar_style;
418                                         current_widget = global_gtk_vscrollbar;
419                                 } else {
420                                         tmp_style = global_gtk_hscrollbar_style;
421                                         current_widget = global_gtk_hscrollbar;
422                                 }
423                         } else
424                         if (control is ProgressBar) {
425                                 tmp_style = global_gtk_progress_bar_style;
426                                 current_widget = global_gtk_progress_bar;
427                         } else
428                         if (control is RadioButton) {
429                                 tmp_style = global_gtk_radio_button_style;
430                                 current_widget = global_gtk_radio_button;
431                         } else
432                         if (control is CheckBox) {
433                                 tmp_style = global_gtk_check_button_style;
434                                 current_widget = global_gtk_check_button;
435                         } else
436                         if (control is TrackBar) {
437                                 TrackBar bar = control as TrackBar;
438                                 if (bar.Orientation == Orientation.Vertical) {
439                                         tmp_style = global_gtk_vscale_style;
440                                         current_widget = global_gtk_vscale;
441                                 } else {
442                                         tmp_style = global_gtk_hscale_style;
443                                         current_widget = global_gtk_hscale;
444                                 }
445                         } else
446                                 tmp_style = global_style;
447                         
448                         current_style = gtk_style_attach (tmp_style, current_gdk_drawable);  // need it
449                 }
450                 
451                 #if _EXPERIMENTAL_
452                 private void SetDrawableAndStyle (Rectangle area, Type type, Orientation orientation)
453                 {
454                         if (current_gdk_drawable != IntPtr.Zero) {
455                                 g_object_unref (current_gdk_drawable);
456                                 current_gdk_drawable = IntPtr.Zero;
457                         }
458                         current_gdk_drawable = gdk_pixmap_new (IntPtr.Zero, area.Width, area.Height, 24);
459                         
460                         IntPtr tmp_style = IntPtr.Zero;
461                         
462                         if (type == typeof(ButtonBase)) {
463                                 tmp_style = global_gtk_button_style;
464                                 current_widget = global_gtk_button;
465                         } else
466                         if (type == typeof(ScrollBar)) {
467                                 if (orientation == Orientation.Vertical) {
468                                         tmp_style = global_gtk_vscrollbar_style;
469                                         current_widget = global_gtk_vscrollbar;
470                                 } else {
471                                         tmp_style = global_gtk_hscrollbar_style;
472                                         current_widget = global_gtk_hscrollbar;
473                                 }
474                         } else
475                         if (type == typeof(ProgressBar)) {
476                                 tmp_style = global_gtk_progress_bar_style;
477                                 current_widget = global_gtk_progress_bar;
478                         } else
479                         if (type == typeof(RadioButton)) {
480                                 tmp_style = global_gtk_radio_button_style;
481                                 current_widget = global_gtk_radio_button;
482                         } else
483                         if (type == typeof(CheckBox)) {
484                                 tmp_style = global_gtk_check_button_style;
485                                 current_widget = global_gtk_check_button;
486                         } else
487                         if (type == typeof(TrackBar)) {
488                                 if (orientation == Orientation.Vertical) {
489                                         tmp_style = global_gtk_vscale_style;
490                                         current_widget = global_gtk_vscale;
491                                 } else {
492                                         tmp_style = global_gtk_hscale_style;
493                                         current_widget = global_gtk_hscale;
494                                 }
495                         } else
496                                 tmp_style = global_style;
497                         
498                         current_style = gtk_style_attach (tmp_style, current_gdk_drawable);  // need it
499                 }
500                 #endif
501                 
502                 #if _EXPERIMENTAL_
503                 private void DrawDrawableToDC (Graphics dc, Control control)
504                 {
505                         IntPtr new_pixbuf = gdk_pixbuf_new (0, true, 8, control.ClientRectangle.Width, control.ClientRectangle.Height);
506                         
507                         gdk_pixbuf_get_from_drawable (new_pixbuf,
508                                                       current_gdk_drawable,
509                                                       global_color_map,
510                                                       0,
511                                                       0,
512                                                       0,
513                                                       0,
514                                                       -1,
515                                                       -1);
516                         
517                         IntPtr error = IntPtr.Zero;
518                         IntPtr buffer;
519                         UIntPtr buffer_size_as_ptr;
520                         string type = "png";
521                         
522                         bool saved = gdk_pixbuf_save_to_buffer (new_pixbuf, out buffer, out buffer_size_as_ptr, type, out error, IntPtr.Zero);
523                         
524                         if (!saved)
525                                 return;
526                         
527                         int buffer_size = (int) (uint) buffer_size_as_ptr;
528                         byte[] result = new byte [buffer_size];
529                         Marshal.Copy (buffer, result, 0, (int) buffer_size);
530                         g_free (buffer);
531                         g_object_unref (new_pixbuf);
532                         
533                         Image image = null;
534                         using (MemoryStream s = new MemoryStream (result))
535                                 image = Image.FromStream (s);
536                         
537                         dc.DrawImage (image, control.ClientRectangle);
538                 }
539                 
540                 private void DrawDrawableToDC (Graphics dc, Rectangle area)
541                 {
542                         IntPtr new_pixbuf = gdk_pixbuf_new (0, true, 8, area.Width, area.Height);
543                         
544                         gdk_pixbuf_get_from_drawable (new_pixbuf,
545                                                       current_gdk_drawable,
546                                                       global_color_map,
547                                                       0,
548                                                       0,
549                                                       0,
550                                                       0,
551                                                       -1,
552                                                       -1);
553                         
554                         IntPtr error = IntPtr.Zero;
555                         IntPtr buffer;
556                         UIntPtr buffer_size_as_ptr;
557                         string type = "png";
558                         
559                         bool saved = gdk_pixbuf_save_to_buffer (new_pixbuf, out buffer, out buffer_size_as_ptr, type, out error, IntPtr.Zero);
560                         
561                         if (!saved)
562                                 return;
563                         
564                         int buffer_size = (int) (uint) buffer_size_as_ptr;
565                         byte[] result = new byte [buffer_size];
566                         Marshal.Copy (buffer, result, 0, (int) buffer_size);
567                         g_free (buffer);
568                         g_object_unref (new_pixbuf);
569                         
570                         Image image = null;
571                         using (MemoryStream s = new MemoryStream (result))
572                                 image = Image.FromStream (s);
573                         
574                         dc.DrawImage (image, area);
575                 }
576                 #endif
577                 
578                 public override void DrawButtonBase (Graphics dc, Rectangle clip_area, ButtonBase button)
579                 {
580                         SetDrawableAndStyle (button);
581                         
582                         // Draw the button: fill rectangle, draw border, etc.
583                         ButtonBase_DrawButton (button, dc);
584                         
585                         // First, draw the image
586                         if ((button.image != null) || (button.image_list != null))
587                                 ButtonBase_DrawImage (button, dc);
588                         
589                         // Draw the focus rectangle
590                         if (button.has_focus)
591                                 ButtonBase_DrawFocus (button, dc);
592                         
593                         #if _EXPERIMENTAL_
594                         DrawDrawableToDC (dc, button);
595                         #endif
596
597                         // Now the text
598                         if (button.text != null && button.text != String.Empty)
599                                 ButtonBase_DrawText (button, dc);
600                 }
601                 
602                 protected override void ButtonBase_DrawButton(ButtonBase button, Graphics dc)
603                 {
604                         Rectangle buttonRectangle = button.ClientRectangle;
605                         
606                         StateType state_type = StateType.Normal;
607                         ShadowType shadow_type = button.flat_style == FlatStyle.Flat ? ShadowType.In : ShadowType.Out;
608                         string detail = "buttondefault";
609                         
610                         if (((button is CheckBox) && (((CheckBox)button).check_state == CheckState.Checked)) ||
611                             ((button is RadioButton) && (((RadioButton)button).check_state == CheckState.Checked))) {
612                                 state_type = StateType.Active;
613                                 shadow_type = ShadowType.In;
614                                 detail = "button";
615                         } else
616                         if (!button.is_enabled) {
617                                 state_type = StateType.Insensitive;
618                         } else
619                         if (button.is_pressed) {
620                                 state_type = StateType.Active;
621                                 shadow_type = ShadowType.In;
622                                 detail = "button";
623                         } else
624                         if (button.is_entered) {
625                                 state_type = StateType.Prelight;
626                         }
627                         
628                         if (button.Focused)
629                                 gtk_widget_grab_focus (global_gtk_button);
630                         
631                         if (button.flat_style == FlatStyle.Flat)
632                                 gtk_paint_flat_box (current_style,
633                                                     current_gdk_drawable,
634                                                     (int) state_type,
635                                                     (int) shadow_type,
636                                                     IntPtr.Zero,
637                                                     global_gtk_button,
638                                                     detail,
639                                                     buttonRectangle.X, buttonRectangle.Y,
640                                                     buttonRectangle.Width, buttonRectangle.Height);
641                         else
642                         if (button.flat_style != FlatStyle.Popup || (button.flat_style == FlatStyle.Popup && button.is_entered))
643                                 gtk_paint_box (current_style,
644                                                current_gdk_drawable,
645                                                (int) state_type,
646                                                (int) shadow_type,
647                                                IntPtr.Zero,
648                                                global_gtk_button,
649                                                detail,
650                                                buttonRectangle.X, buttonRectangle.Y,
651                                                buttonRectangle.Width, buttonRectangle.Height);
652                 }
653                 
654                 protected override void ButtonBase_DrawFocus (ButtonBase button, Graphics dc)
655                 {
656                         if (!button.is_enabled)
657                                 return;
658                         
659                         Rectangle focus_rect = new Rectangle (button.ClientRectangle.X + 4, button.ClientRectangle.Y + 4, button.ClientRectangle.Width - 9, button.ClientRectangle.Height - 9);
660                         
661                         gtk_widget_grab_focus (global_gtk_button);
662                         
663                         gtk_paint_focus (current_style,
664                                          current_gdk_drawable,
665                                          (int) StateType.Active,
666                                          IntPtr.Zero,
667                                          global_gtk_button,
668                                          "button",
669                                          focus_rect.X,
670                                          focus_rect.Y,
671                                          focus_rect.Width,
672                                          focus_rect.Height);
673                 }
674                 
675                 #region ScrollBar
676                 public override void DrawScrollBar( Graphics dc, Rectangle clip, ScrollBar bar ) {
677                         int             scrollbutton_width = bar.scrollbutton_width;
678                         int             scrollbutton_height = bar.scrollbutton_height;
679                         Rectangle       first_arrow_area;
680                         Rectangle       second_arrow_area;                      
681                         Rectangle       thumb_pos;
682                         
683                         SetDrawableAndStyle (bar);
684                         
685                         Rectangle allocation = new Rectangle (bar.ClientRectangle.X, bar.ClientRectangle.Y, bar.ClientRectangle.Width, bar.ClientRectangle.Height);
686                         
687                         // fix for artefacts
688                         Color fix_color = bar.Parent != null ? bar.Parent.BackColor : ColorControl;
689                         
690                         if (bar.vert) {
691                                 gtk_widget_size_allocate (global_gtk_vscrollbar, ref allocation);
692                                 
693                                 // fix for artefacts
694                                 dc.FillRectangle (ResPool.GetSolidBrush (fix_color), 
695                                                   bar.ClientRectangle.X, bar.ClientRectangle.Y, bar.ClientRectangle.Width, 3);
696                                 dc.FillRectangle (ResPool.GetSolidBrush (fix_color), 
697                                                   bar.ClientRectangle.X, bar.ClientRectangle.Bottom - 4, bar.ClientRectangle.Width, 3);
698                         } else {
699                                 gtk_widget_size_allocate (global_gtk_hscrollbar, ref allocation);
700                                 
701                                 // fix for artefacts
702                                 dc.FillRectangle (ResPool.GetSolidBrush (fix_color), 
703                                                   bar.ClientRectangle.X, bar.ClientRectangle.Y, 3, bar.ClientRectangle.Height);
704                                 dc.FillRectangle (ResPool.GetSolidBrush (fix_color), 
705                                                   bar.ClientRectangle.Right - 4, bar.ClientRectangle.Y, 3, bar.ClientRectangle.Height);
706                         }
707                         
708                         thumb_pos = bar.ThumbPos;
709                         
710                         if ( bar.vert ) {
711                                 first_arrow_area = new Rectangle( 0, 0, bar.Width, scrollbutton_height + 1 );
712                                 bar.FirstArrowArea = first_arrow_area;
713                                 
714                                 second_arrow_area = new Rectangle( 0, bar.ClientRectangle.Height - scrollbutton_height - 1, bar.Width, scrollbutton_height + 1 );
715                                 bar.SecondArrowArea = second_arrow_area;
716                                 
717                                 thumb_pos.Width = bar.Width;
718                                 bar.ThumbPos = thumb_pos;
719                                 
720                                 ScrollBar_Vertical_Draw_ThumbMoving_None (scrollbutton_height, bar, clip, dc);
721                                 
722                                 /* Buttons */
723                                 if ( clip.IntersectsWith( first_arrow_area ) )
724                                         CPDrawScrollButton( dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state );
725                                 if ( clip.IntersectsWith( second_arrow_area ) )
726                                         CPDrawScrollButton( dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state );
727                         } else {
728                                 first_arrow_area = new Rectangle( 0, 0, scrollbutton_width + 1, bar.Height );
729                                 bar.FirstArrowArea = first_arrow_area;
730                                 
731                                 second_arrow_area = new Rectangle( bar.ClientRectangle.Width - scrollbutton_width - 1, 0, scrollbutton_width + 1, bar.Height );
732                                 bar.SecondArrowArea = second_arrow_area;
733                                 
734                                 thumb_pos.Height = bar.Height;
735                                 bar.ThumbPos = thumb_pos;
736                                 
737                                 /* Background */                                        
738                                 ScrollBar_Horizontal_Draw_ThumbMoving_None (scrollbutton_width, bar, clip, dc);
739                                 
740                                 /* Buttons */
741                                 if ( clip.IntersectsWith( first_arrow_area ) )
742                                         CPDrawScrollButton( dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state );
743                                 if ( clip.IntersectsWith( second_arrow_area ) )
744                                         CPDrawScrollButton( dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state );
745                         }
746                         
747                         /* Thumb */
748                         ScrollBar_DrawThumb( bar, thumb_pos, clip, dc );
749                         
750                         #if _EXPERIMENTAL_
751                         DrawDrawableToDC (dc, bar);
752                         #endif
753                 }
754                 
755                 protected override void ScrollBar_DrawThumb( ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc ) {
756                         if ( bar.Enabled)
757                                 DrawScrollBarThumb( dc, thumb_pos, bar );
758                 }
759                 
760                 protected override void ScrollBar_Vertical_Draw_ThumbMoving_None (int scrollbutton_height, ScrollBar bar, Rectangle clip, Graphics dc)
761                 {
762                         Rectangle r = new Rectangle (0,
763                                                      scrollbutton_height, bar.ClientRectangle.Width, bar.ClientRectangle.Height - (scrollbutton_height * 2));
764                         gtk_paint_box (current_style, 
765                                        current_gdk_drawable, 
766                                        (int) StateType.Active,
767                                        (int) ShadowType.In,
768                                        IntPtr.Zero,
769                                        global_gtk_vscrollbar,
770                                        "vscrollbar",
771                                        r.X, r.Y,
772                                        r.Width, r.Height);
773                 }
774                 
775                 protected override void ScrollBar_Horizontal_Draw_ThumbMoving_None (int scrollbutton_width, ScrollBar bar, Rectangle clip, Graphics dc)
776                 {
777                         Rectangle r = new Rectangle (scrollbutton_width,
778                                                      0, bar.ClientRectangle.Width - (scrollbutton_width * 2), bar.ClientRectangle.Height);
779                         
780                         gtk_paint_box (current_style, 
781                                        current_gdk_drawable, 
782                                        (int) StateType.Active,
783                                        (int) ShadowType.In,
784                                        IntPtr.Zero,
785                                        global_gtk_hscrollbar,
786                                        "hscrollbar",
787                                        r.X, r.Y,
788                                        r.Width, r.Height);
789                 }
790                 
791                 private void DrawScrollBarThumb( Graphics dc, Rectangle area, ScrollBar bar ) {
792                         IntPtr gtk_scrollbar = bar.vert ? global_gtk_vscrollbar : global_gtk_hscrollbar;
793                         
794                         gtk_paint_box (current_style, 
795                                        current_gdk_drawable, 
796                                        (int) StateType.Active,
797                                        (int) ShadowType.Out,
798                                        IntPtr.Zero,
799                                        gtk_scrollbar,
800                                        "slider",
801                                        area.X, area.Y,
802                                        area.Width, area.Height);
803                 }
804                 #endregion      // ScrollBar
805                 
806                 #region ProgressBar
807                 public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl)
808                 {
809                         Rectangle       client_area = ctrl.client_area;
810                         int             barpos_pixels;
811                         
812                         SetDrawableAndStyle (ctrl);
813                         
814                         // draw background
815                         gtk_paint_box (current_style,
816                                        current_gdk_drawable,
817                                        (int) StateType.Normal,
818                                        (int) ShadowType.In, 
819                                        IntPtr.Zero,
820                                        global_gtk_progress_bar,
821                                        "trough",
822                                        ctrl.ClientRectangle.X, 
823                                        ctrl.ClientRectangle.Y,
824                                        ctrl.ClientRectangle.Width,
825                                        ctrl.ClientRectangle.Height);
826                         
827                         // don't draw the bar if Value is = 0
828                         if (ctrl.Value <= 0)
829                                 return;
830                         
831                         int value = ctrl.Value;
832                         
833                         if (value > ctrl.Maximum)
834                                 value = ctrl.Maximum;
835                         
836                         if (value == ctrl.Maximum)
837                                 barpos_pixels = client_area.Width + 2;
838                         else
839                                 barpos_pixels = (((value - ctrl.Minimum) * client_area.Width) / (ctrl.Maximum - ctrl.Minimum)) + 1;
840                         
841                         gtk_paint_box (current_style, 
842                                        current_gdk_drawable, 
843                                        (int) StateType.Prelight,
844                                        (int) ShadowType.Out,
845                                        IntPtr.Zero,
846                                        global_gtk_progress_bar,
847                                        "bar",
848                                        client_area.X - 1, client_area.Y - 1,
849                                        barpos_pixels, client_area.Height + 2);
850                         
851                         #if _EXPERIMENTAL_
852                         DrawDrawableToDC (dc, ctrl);
853                         #endif
854                 }
855                 #endregion      // ProgressBar
856                 
857                 #region RadioButton
858                 protected override void RadioButton_DrawButton (RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle)
859                 {
860                         // we currently don't care for flat or popup radio buttons
861                         if (radio_button.appearance == Appearance.Button) {
862                                 DrawButtonBase (dc, radio_button.ClientRectangle, radio_button);
863                         } else {
864                                 DrawRadioButton (dc, radio_button, state, radiobutton_rectangle);
865                         }
866                 }
867                 
868                 private void DrawRadioButton (Graphics dc, RadioButton radio_button, ButtonState state, Rectangle radiobutton_rectangle)
869                 {
870                         SetDrawableAndStyle (radio_button);
871                         
872                         ShadowType shadow_type;
873                         
874                         if (!radio_button.Enabled)
875                                 shadow_type = ShadowType.Out;
876                         else
877                                 shadow_type = radio_button.Checked ? ShadowType.In : ShadowType.EtchedIn;
878                         
879                         StateType state_type = StateType.Normal;
880                         
881                         if (!radio_button.Enabled)
882                                 state_type = StateType.Insensitive;
883                         else
884                         if (radio_button.is_pressed)
885                                 state_type = StateType.Active;
886                         else
887                         if (radio_button.is_entered)
888                                 state_type = StateType.Prelight;
889                         
890                         gtk_paint_option (current_style,
891                                           current_gdk_drawable,
892                                           (int) state_type,
893                                           (int) shadow_type,
894                                           IntPtr.Zero,
895                                           global_gtk_radio_button,
896                                           "radiobutton",
897                                           radiobutton_rectangle.X,
898                                           radiobutton_rectangle.Y,
899                                           radiobutton_rectangle.Width,
900                                           radiobutton_rectangle.Height);
901                         
902                         #if _EXPERIMENTAL_
903                         DrawDrawableToDC (dc, radio_button);
904                         #endif
905                 }
906                 
907                 protected override void RadioButton_DrawText (RadioButton radio_button, Rectangle text_rectangle, Graphics dc, StringFormat text_format)
908                 {
909                         if (radio_button.Appearance != Appearance.Button)
910                                 base.RadioButton_DrawText (radio_button, text_rectangle, dc, text_format);
911                 }
912         
913                 protected override void RadioButton_DrawFocus (RadioButton radio_button, Graphics dc, Rectangle text_rectangle)
914                 {
915                         if (radio_button.Focused && radio_button.appearance != Appearance.Button) {
916                                 gtk_paint_focus (current_style,
917                                                  current_gdk_drawable,
918                                                  (int) StateType.Active,
919                                                  IntPtr.Zero,
920                                                  global_gtk_radio_button,
921                                                  "radiobutton",
922                                                  text_rectangle.X,
923                                                  text_rectangle.Y,
924                                                  text_rectangle.Width,
925                                                  text_rectangle.Height);
926                         }
927                         
928                         #if _EXPERIMENTAL_
929                         DrawDrawableToDC (dc, radio_button);
930                         #endif
931                 }
932                 #endregion      // RadioButton
933                 
934                 #region CheckBox
935                 protected override void CheckBox_DrawCheckBox (Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle)
936                 {
937                         // render as per normal button
938                         if (checkbox.appearance == Appearance.Button) {
939                                 DrawButtonBase (dc, checkbox.ClientRectangle, checkbox);
940                         } else {
941                                 InternalDrawCheckBox (dc, checkbox, state, checkbox_rectangle);
942                         }
943                 }
944                 
945                 private void InternalDrawCheckBox (Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle)
946                 {
947                         SetDrawableAndStyle (checkbox);
948                         
949                         ShadowType shadow_type;
950                         
951                         if (!checkbox.Enabled)
952                                 shadow_type = ShadowType.Out;
953                         else
954                                 shadow_type = checkbox.Checked ? ShadowType.In : ShadowType.EtchedIn;
955                         
956                         StateType state_type = StateType.Normal;
957                         
958                         if (!checkbox.Enabled)
959                                 state_type = StateType.Insensitive;
960                         else
961                         if (checkbox.is_pressed)
962                                 state_type = StateType.Active;
963                         else
964                         if (checkbox.is_entered)
965                                 state_type = StateType.Prelight;
966                         
967                         gtk_paint_check (current_style,
968                                          current_gdk_drawable,
969                                          (int) state_type,
970                                          (int) shadow_type,
971                                          IntPtr.Zero,
972                                          global_gtk_check_button,
973                                          "checkbutton",
974                                          checkbox_rectangle.X,
975                                          checkbox_rectangle.Y,
976                                          checkbox_rectangle.Width,
977                                          checkbox_rectangle.Height);
978                         
979                         #if _EXPERIMENTAL_
980                         DrawDrawableToDC (dc, checkbox);
981                         #endif
982                 }
983                 
984                 protected override void CheckBox_DrawText (CheckBox checkbox, Rectangle text_rectangle, Graphics dc, StringFormat text_format)
985                 {
986                         if (checkbox.Appearance != Appearance.Button)
987                                 base.CheckBox_DrawText (checkbox, text_rectangle, dc, text_format);
988                 }
989                 
990                 protected override void CheckBox_DrawFocus( CheckBox checkbox, Graphics dc, Rectangle text_rectangle )
991                 {
992                         if (checkbox.Focused && checkbox.appearance != Appearance.Button) {
993                                 gtk_paint_focus (current_style,
994                                                  current_gdk_drawable,
995                                                  (int) StateType.Active,
996                                                  IntPtr.Zero,
997                                                  global_gtk_check_button,
998                                                  "checkbutton",
999                                                  text_rectangle.X,
1000                                                  text_rectangle.Y,
1001                                                  text_rectangle.Width,
1002                                                  text_rectangle.Height);
1003                         }
1004                         
1005                         #if _EXPERIMENTAL_
1006                         DrawDrawableToDC (dc, checkbox);
1007                         #endif
1008                 }
1009                 #endregion      // CheckBox
1010                 
1011                 #region TrackBar
1012                 private void DrawTrackBar_Vertical (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
1013                                                     ref Rectangle thumb_pos, ref Rectangle thumb_area,
1014                                                     float ticks, int value_pos, bool mouse_value)
1015                 {                       
1016                         Point toptick_startpoint = new Point ();
1017                         Point bottomtick_startpoint = new Point ();
1018                         Point channel_startpoint = new Point ();
1019                         float pixel_len;
1020                         float pixels_betweenticks;
1021                         const int space_from_right = 8;
1022                         const int space_from_left = 8;
1023                         Rectangle area = tb.ClientRectangle;
1024                         
1025                         Rectangle allocation = new Rectangle (area.X, area.Y, area.Width, area.Height);
1026                         
1027                         gtk_widget_size_allocate (current_widget, ref allocation);
1028                         
1029                         gtk_range_set_range (current_widget, tb.Minimum, tb.Maximum);
1030                         gtk_range_set_value (current_widget, tb.Value);
1031                         
1032                         ShadowType shadow_type = ShadowType.In;
1033                         
1034                         if (!tb.Enabled)
1035                                 shadow_type = ShadowType.Out;
1036                         
1037                         StateType state_type = StateType.Normal;
1038                         
1039                         if (!tb.Enabled)
1040                                 state_type = StateType.Insensitive;
1041                         else
1042                         if (tb.is_entered)
1043                                 state_type = StateType.Prelight;
1044                         
1045                         switch (tb.TickStyle)   {
1046                         case TickStyle.BottomRight:
1047                         case TickStyle.None:
1048                                 channel_startpoint.Y = 8;
1049                                 channel_startpoint.X = 9;
1050                                 bottomtick_startpoint.Y = 13;
1051                                 bottomtick_startpoint.X = 24;                           
1052                                 break;
1053                         case TickStyle.TopLeft:
1054                                 channel_startpoint.Y = 8;
1055                                 channel_startpoint.X = 19;
1056                                 toptick_startpoint.Y = 13;
1057                                 toptick_startpoint.X = 8;
1058                                 break;
1059                         case TickStyle.Both:
1060                                 channel_startpoint.Y = 8;
1061                                 channel_startpoint.X = 18;      
1062                                 bottomtick_startpoint.Y = 13;
1063                                 bottomtick_startpoint.X = 32;                           
1064                                 toptick_startpoint.Y = 13;
1065                                 toptick_startpoint.X = 8;                               
1066                                 break;
1067                         default:
1068                                 break;
1069                         }
1070                         
1071                         thumb_area.X = area.X + channel_startpoint.X;
1072                         thumb_area.Y = area.Y + channel_startpoint.Y;
1073                         thumb_area.Height = area.Height - space_from_right - space_from_left;
1074                         thumb_area.Width = 4;
1075                         
1076                         pixel_len = thumb_area.Height - 11;
1077                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
1078                         
1079                         /* Convert thumb position from mouse position to value*/
1080                         if (mouse_value) {
1081                                 
1082                                 if (value_pos >= channel_startpoint.Y)
1083                                         value_pos = (int)(((float) (value_pos - channel_startpoint.Y)) / pixels_betweenticks);
1084                                 else
1085                                         value_pos = 0;                  
1086                                 
1087                                 if (value_pos + tb.Minimum > tb.Maximum)
1088                                         value_pos = tb.Maximum - tb.Minimum;
1089                                 
1090                                 tb.Value = value_pos + tb.Minimum;
1091                         }               
1092                         
1093                         thumb_pos.Width = 13;
1094                         thumb_pos.Height = 29;
1095                         
1096                         thumb_pos.Y = channel_startpoint.Y + (int) (pixels_betweenticks * (float) value_pos) - (thumb_pos.Height / 3);
1097                         
1098                         if (thumb_pos.Y < channel_startpoint.Y)
1099                                 thumb_pos.Y = channel_startpoint.Y;
1100                         
1101                         if (thumb_pos.Y > thumb_area.Bottom - 29)
1102                                 thumb_pos.Y = thumb_area.Bottom - 29;
1103                         
1104                         /* Draw channel */
1105                         gtk_paint_box (current_style,
1106                                        current_gdk_drawable,
1107                                        (int)state_type,
1108                                        (int)shadow_type,
1109                                        IntPtr.Zero,
1110                                        current_widget,
1111                                        "trough",
1112                                        thumb_area.X,
1113                                        thumb_area.Y,
1114                                        4,
1115                                        thumb_area.Height);
1116                         
1117                         /* Draw thumb */
1118                         thumb_pos.X = channel_startpoint.X + 2 - thumb_pos.Width / 2;
1119                         
1120                         shadow_type = ShadowType.Out;
1121                         
1122                         gtk_paint_slider (current_style,
1123                                           current_gdk_drawable,
1124                                           (int)state_type,
1125                                           (int)shadow_type,
1126                                           IntPtr.Zero,
1127                                           current_widget,
1128                                           "vscale",
1129                                           thumb_pos.X,
1130                                           thumb_pos.Y,
1131                                           thumb_pos.Width,
1132                                           thumb_pos.Height,
1133                                           0);
1134                         
1135                         pixel_len = thumb_area.Height - 11;
1136                         pixels_betweenticks = pixel_len / ticks;
1137                         
1138                         /* Draw ticks*/
1139                         thumb_area.X = thumb_pos.X;
1140                         thumb_area.Y = channel_startpoint.Y;
1141                         thumb_area.Width = thumb_pos.Width;
1142                         
1143                         Region outside = new Region (area);
1144                         outside.Exclude (thumb_area);                   
1145                         
1146                         if (outside.IsVisible (clip_rectangle)) {                               
1147                                 if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight ||
1148                                     ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {     
1149                                         
1150                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks)  {                                       
1151                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len + 1)
1152                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X , area.Y + bottomtick_startpoint.Y  + inc, 
1153                                                                      area.X + bottomtick_startpoint.X  + 3, area.Y + bottomtick_startpoint.Y + inc);
1154                                                 else
1155                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X, area.Y + bottomtick_startpoint.Y  + inc, 
1156                                                                      area.X + bottomtick_startpoint.X  + 2, area.Y + bottomtick_startpoint.Y + inc);
1157                                         }
1158                                 }
1159                                 
1160                                 if (pixels_betweenticks > 0 &&  ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft ||
1161                                     ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {
1162                                         
1163                                         pixel_len = thumb_area.Height - 11;
1164                                         pixels_betweenticks = pixel_len / ticks;
1165                                         
1166                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
1167                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len + 1)
1168                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X  - 3 , area.Y + toptick_startpoint.Y + inc, 
1169                                                                      area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y + inc);
1170                                                 else
1171                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X  - 2, area.Y + toptick_startpoint.Y + inc, 
1172                                                                      area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y  + inc);
1173                                         }                       
1174                                 }
1175                         }
1176                         
1177                         outside.Dispose ();
1178                 }
1179                 
1180                 private void DrawTrackBar_Horizontal (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
1181                                                       ref Rectangle thumb_pos, ref Rectangle thumb_area,
1182                                                       float ticks, int value_pos, bool mouse_value)
1183                 {                       
1184                         Point toptick_startpoint = new Point ();
1185                         Point bottomtick_startpoint = new Point ();
1186                         Point channel_startpoint = new Point ();
1187                         float pixel_len;
1188                         float pixels_betweenticks;
1189                         const int space_from_right = 8;
1190                         const int space_from_left = 8;
1191                         Rectangle area = tb.ClientRectangle;
1192                         
1193                         Rectangle allocation = new Rectangle (area.X, area.Y, area.Width, area.Height);
1194                         
1195                         gtk_widget_size_allocate (current_widget, ref allocation);
1196                         
1197                         gtk_range_set_range (current_widget, tb.Minimum, tb.Maximum);
1198                         gtk_range_set_value (current_widget, tb.Value);
1199                         
1200                         ShadowType shadow_type = ShadowType.In;
1201                         
1202                         if (!tb.Enabled)
1203                                 shadow_type = ShadowType.Out;
1204                         
1205                         StateType state_type = StateType.Normal;
1206                         
1207                         if (!tb.Enabled)
1208                                 state_type = StateType.Insensitive;
1209                         else
1210                         if (tb.is_entered)
1211                                 state_type = StateType.Prelight;
1212                         
1213                         switch (tb.TickStyle) {
1214                         case TickStyle.BottomRight:
1215                         case TickStyle.None:
1216                                 channel_startpoint.X = 8;
1217                                 channel_startpoint.Y = 9;
1218                                 bottomtick_startpoint.X = 13;
1219                                 bottomtick_startpoint.Y = 24;                           
1220                                 break;
1221                         case TickStyle.TopLeft:
1222                                 channel_startpoint.X = 8;
1223                                 channel_startpoint.Y = 19;
1224                                 toptick_startpoint.X = 13;
1225                                 toptick_startpoint.Y = 8;
1226                                 break;
1227                         case TickStyle.Both:
1228                                 channel_startpoint.X = 8;
1229                                 channel_startpoint.Y = 18;      
1230                                 bottomtick_startpoint.X = 13;
1231                                 bottomtick_startpoint.Y = 32;                           
1232                                 toptick_startpoint.X = 13;
1233                                 toptick_startpoint.Y = 8;                               
1234                                 break;
1235                         default:
1236                                 break;
1237                         }
1238                         
1239                         thumb_area.X = area.X + channel_startpoint.X;
1240                         thumb_area.Y = area.Y + channel_startpoint.Y;
1241                         thumb_area.Width = area.Width - space_from_right - space_from_left;
1242                         thumb_area.Height = 4;
1243                         
1244                         pixel_len = thumb_area.Width - 11;
1245                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
1246                         
1247                         /* Convert thumb position from mouse position to value*/
1248                         if (mouse_value) {                      
1249                                 if (value_pos >= channel_startpoint.X)
1250                                         value_pos = (int)(((float) (value_pos - channel_startpoint.X)) / pixels_betweenticks);
1251                                 else
1252                                         value_pos = 0;                          
1253                                 
1254                                 if (value_pos + tb.Minimum > tb.Maximum)
1255                                         value_pos = tb.Maximum - tb.Minimum;
1256                                 
1257                                 tb.Value = value_pos + tb.Minimum;
1258                         }                       
1259                         
1260                         thumb_pos.Width = 29;
1261                         thumb_pos.Height = 13;
1262                         
1263                         thumb_pos.X = channel_startpoint.X + (int) (pixels_betweenticks * (float) value_pos) - (thumb_pos.Width / 3);
1264                         
1265                         
1266                         if (thumb_pos.X < channel_startpoint.X)
1267                                 thumb_pos.X = channel_startpoint.X;
1268                         
1269                         if (thumb_pos.X > thumb_area.Right - 29)
1270                                 thumb_pos.X = thumb_area.Right - 29;
1271                         
1272                         /* Draw channel */
1273                         gtk_paint_box (current_style,
1274                                        current_gdk_drawable,
1275                                        (int)state_type,
1276                                        (int)shadow_type,
1277                                        IntPtr.Zero,
1278                                        current_widget,
1279                                        "trough",
1280                                        thumb_area.X,
1281                                        thumb_area.Y,
1282                                        thumb_area.Width,
1283                                        4);
1284                         
1285                         /* Draw thumb */
1286                         
1287                         thumb_pos.Y = channel_startpoint.Y + 2 - thumb_pos.Height / 2;
1288                         
1289                         shadow_type = ShadowType.Out;
1290                         
1291                         gtk_paint_slider (current_style,
1292                                           current_gdk_drawable,
1293                                           (int)state_type,
1294                                           (int)shadow_type,
1295                                           IntPtr.Zero,
1296                                           current_widget,
1297                                           "hscale",
1298                                           thumb_pos.X,
1299                                           thumb_pos.Y,
1300                                           thumb_pos.Width,
1301                                           thumb_pos.Height,
1302                                           0);
1303                         
1304                         pixel_len = thumb_area.Width - 11;
1305                         pixels_betweenticks = pixel_len / ticks;
1306                         
1307                         /* Draw ticks*/
1308                         thumb_area.Y = thumb_pos.Y;
1309                         thumb_area.X = channel_startpoint.X;
1310                         thumb_area.Height = thumb_pos.Height;
1311                         Region outside = new Region (area);
1312                         outside.Exclude (thumb_area);                   
1313                         
1314                         if (outside.IsVisible (clip_rectangle)) {                               
1315                                 if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight ||
1316                                     ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {                             
1317                                         
1318                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
1319                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len + 1)
1320                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y, 
1321                                                                      area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y + 3);
1322                                                 else
1323                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y, 
1324                                                                      area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y + 2);
1325                                         }
1326                                 }
1327                                 
1328                                 if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft ||
1329                                     ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {
1330                                         
1331                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
1332                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len + 1)
1333                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y - 3, 
1334                                                                      area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y);
1335                                                 else
1336                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y - 2, 
1337                                                                      area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y);
1338                                         }                       
1339                                 }
1340                         }
1341                         
1342                         outside.Dispose ();                     
1343                 }
1344                 
1345                 public override void DrawTrackBar (Graphics dc, Rectangle clip_rectangle, TrackBar tb)
1346                 {
1347                         int             value_pos;
1348                         bool            mouse_value;
1349                         float           ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/
1350                         Rectangle       area;
1351                         Rectangle       thumb_pos = tb.ThumbPos;
1352                         Rectangle       thumb_area = tb.ThumbArea;
1353                         
1354                         if (tb.thumb_pressed) {
1355                                 value_pos = tb.thumb_mouseclick;
1356                                 mouse_value = true;
1357                         } else {
1358                                 value_pos = tb.Value - tb.Minimum;
1359                                 mouse_value = false;
1360                         }
1361                         
1362                         area = tb.ClientRectangle;
1363                         
1364                         SetDrawableAndStyle (tb);
1365                         
1366                         /* Control Background */
1367                         if (tb.BackColor == DefaultControlBackColor) {
1368                                 dc.FillRectangle (ResPool.GetSolidBrush (ColorControl), clip_rectangle);
1369                         } else {
1370                                 dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle);
1371                         }
1372                         
1373                         if (tb.Orientation == Orientation.Vertical) {
1374                                 DrawTrackBar_Vertical (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
1375                                                        ticks, value_pos, mouse_value);
1376                                 
1377                         } else {
1378                                 DrawTrackBar_Horizontal (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
1379                                                          ticks, value_pos, mouse_value);
1380                         }
1381                         
1382                         if (tb.Enabled && tb.Focused)
1383                                 gtk_paint_focus (current_style,
1384                                                  current_gdk_drawable, 
1385                                                  (int)StateType.Normal,
1386                                                  IntPtr.Zero,
1387                                                  current_widget, 
1388                                                  "trough",
1389                                                  area.X,
1390                                                  area.Y,
1391                                                  area.Width,
1392                                                  area.Height);
1393                         
1394                         tb.ThumbPos = thumb_pos;
1395                         tb.ThumbArea = thumb_area;
1396                         
1397                         #if _EXPERIMENTAL_
1398                         DrawDrawableToDC (dc, tb);
1399                         #endif
1400                 }
1401                 #endregion      // TrackBar
1402                 
1403                 public override void CPDrawButton (Graphics dc, Rectangle rectangle, ButtonState state)
1404                 {
1405                         #if _EXPERIMENTAL_
1406                         SetDrawableAndStyle (rectangle, typeof(ButtonBase), Orientation.Horizontal);
1407                         #endif
1408                         
1409                         bool is_pushed = false;
1410 //                      bool is_checked = false;
1411 //                      bool is_flat = false;
1412                         bool is_inactive = false;
1413                         
1414                         if ((state & ButtonState.Pushed) != 0) {
1415                                 is_pushed = true;
1416                         }
1417                         
1418 //                      if ((state & ButtonState.Checked) != 0) {
1419 //                              is_checked = true;
1420 //                      }
1421 //                      
1422 //                      if ((state & ButtonState.Flat) != 0) {
1423 //                              is_flat = true;
1424 //                      }
1425                         
1426                         if ((state & ButtonState.Inactive) != 0) {
1427                                 is_inactive = true;
1428                         }
1429                         
1430                         IntPtr drawbutton_style = gtk_style_attach (global_gtk_button_style, current_gdk_drawable);  // need it
1431                         
1432                         StateType state_type = StateType.Normal;
1433                         ShadowType shadow_type = ShadowType.Out;
1434                         string detail = "buttondefault";
1435                         
1436                         if (is_inactive) {
1437                                 state_type = StateType.Insensitive;
1438                         } else
1439                         if (is_pushed) {
1440                                 state_type = StateType.Active;
1441                                 shadow_type = ShadowType.In;
1442                                 detail = "button";
1443                         }
1444                         
1445                         gtk_paint_box (drawbutton_style, current_gdk_drawable,
1446                                        (int) state_type,
1447                                        (int) shadow_type,
1448                                        IntPtr.Zero,
1449                                        IntPtr.Zero,
1450                                        detail,
1451                                        rectangle.X, rectangle.Y,
1452                                        rectangle.Width, rectangle.Height);
1453                         
1454                         #if _EXPERIMENTAL_
1455                         DrawDrawableToDC (dc, rectangle);
1456                         #endif
1457                 }
1458                 
1459                 /* Scroll button: regular button + direction arrow */
1460                 public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton scroll_button_type, ButtonState state)
1461                 {
1462                         #if _EXPERIMENTAL_
1463                         Orientation orientation = Orientation.Vertical;
1464                         if (scroll_button_type == ScrollButton.Left || scroll_button_type == ScrollButton.Right)
1465                                 orientation = Orientation.Horizontal;
1466                         SetDrawableAndStyle (area, typeof(ScrollBar), orientation);
1467                         #endif
1468                         
1469                         bool enabled = (state == ButtonState.Inactive) ? false: true;
1470                         
1471                         StateType state_type = enabled ? StateType.Normal : StateType.Insensitive;
1472                         
1473                         DrawScrollButtonPrimitive (dc, area, state, scroll_button_type);
1474                         
1475                         if (area.Width < 12 || area.Height < 12) /* Cannot see a thing at smaller sizes */
1476                                 return;
1477                         
1478                         ArrowType arrow_type = 0;
1479                         
1480                         switch (scroll_button_type) {
1481                         case ScrollButton.Up:
1482                                 arrow_type = ArrowType.Up;
1483                                 break;
1484                         case ScrollButton.Down:
1485                                 arrow_type = ArrowType.Down;
1486                                 break;
1487                         case ScrollButton.Right:
1488                                 arrow_type = ArrowType.Right;
1489                                 break;
1490                         case ScrollButton.Left:
1491                                 arrow_type = ArrowType.Left;
1492                                 break;
1493                         default:
1494                                 break;
1495                         }
1496                         
1497                         int centerX = area.Left + area.Width / 2;
1498                         int centerY = area.Top + area.Height / 2;
1499                         int arrow_x = 0, arrow_y = 0, arrow_height = 0, arrow_width = 0;
1500                         
1501                         switch (scroll_button_type) {
1502                         case ScrollButton.Down:
1503                         case ScrollButton.Up:
1504                                 arrow_x = centerX - 4;
1505                                 arrow_y = centerY - 2;
1506                                 arrow_width = 8;
1507                                 arrow_height = 4;
1508                                 break;
1509                         case ScrollButton.Left:
1510                         case ScrollButton.Right:
1511                                 arrow_x = centerX - 2;
1512                                 arrow_y = centerY - 4;
1513                                 arrow_width = 4;
1514                                 arrow_height = 8;
1515                                 break;
1516                         default:
1517                                 break;
1518                         }
1519                         
1520                         gtk_paint_arrow (current_style, 
1521                                          current_gdk_drawable, 
1522                                          (int) state_type,
1523                                          (int) ShadowType.Out,
1524                                          IntPtr.Zero,
1525                                          current_widget,
1526                                          "",            
1527                                          (int) arrow_type, true, 
1528                                          arrow_x, 
1529                                          arrow_y,
1530                                          arrow_width, arrow_height);
1531                         
1532                         current_widget = IntPtr.Zero;
1533                         
1534                         #if _EXPERIMENTAL_
1535                         DrawDrawableToDC (dc, area);
1536                         #endif
1537                 }
1538                 
1539                 public void DrawScrollButtonPrimitive (Graphics dc, Rectangle area, ButtonState state, ScrollButton scroll_button_type)
1540                 {
1541                         StateType state_type = StateType.Normal;
1542                         ShadowType shadow_type = ShadowType.Out;
1543                         
1544                         if ((state & ButtonState.Pushed) == ButtonState.Pushed) {
1545                                 state_type = StateType.Active;
1546                                 shadow_type = ShadowType.In;
1547                         }
1548                         
1549                         switch (scroll_button_type) {
1550                         case ScrollButton.Left:
1551                         case ScrollButton.Right:
1552                                 gtk_paint_box (current_style, 
1553                                                current_gdk_drawable, 
1554                                                (int) state_type,
1555                                                (int) shadow_type,
1556                                                IntPtr.Zero,
1557                                                global_gtk_hscrollbar,
1558                                                "stepper",
1559                                                area.X, area.Y,
1560                                                area.Width, area.Height);
1561                                 break;
1562                         case ScrollButton.Up:
1563                         case ScrollButton.Down:
1564                                 gtk_paint_box (current_style, 
1565                                                current_gdk_drawable, 
1566                                                (int) state_type,
1567                                                (int) shadow_type,
1568                                                IntPtr.Zero,
1569                                                global_gtk_vscrollbar,
1570                                                "stepper",
1571                                                area.X, area.Y,
1572                                                area.Width, area.Height);
1573                                 break;
1574                         }
1575                 }
1576                 
1577                 private static Color ColorFromGdkColor (GdkColorStruct gtkcolor)
1578                 {
1579                         return Color.FromArgb (255, 
1580                                 (gtkcolor.red >> 8)  & 0xff, 
1581                                 (gtkcolor.green  >> 8) & 0xff,
1582                                 (gtkcolor.blue >> 8) & 0xff );
1583                 }
1584
1585         } //class
1586 }