File: Idle.cs

package info (click to toggle)
gtk-sharp3 2.99.3-4.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 25,488 kB
  • sloc: xml: 308,885; cs: 38,796; sh: 11,336; perl: 1,295; makefile: 1,099; ansic: 903
file content (149 lines) | stat: -rw-r--r-- 3,889 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// GLib.Idle.cs - Idle class implementation
//
// Author(s):
//	Mike Kestner <mkestner@speakeasy.net>
//	Rachel Hestilow <hestilow@ximian.com>
//	Stephane Delcroix <stephane@delcroix.org>
//
// Copyright (c) 2002 Mike Kestner
// Copyright (c) Rachel Hestilow
// Copyright (c) 2009 Novell, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the Lesser GNU General 
// Public License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.


namespace GLib {

	using System;
	using System.Collections.Generic;
	using System.Runtime.InteropServices;

	public delegate bool IdleHandler ();

	public class Idle {

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool IdleHandlerInternal ();


		internal class IdleProxy : SourceProxy {
			public IdleProxy (IdleHandler real)
			{
				real_handler = real;
				proxy_handler = new IdleHandlerInternal (Handler);
			}

			~IdleProxy ()
			{
				Dispose (false);
			}

			public void Dispose ()
			{
				Dispose (true);
				GC.SuppressFinalize (this);
			}

			protected virtual void Dispose (bool disposing)
			{
				// Both branches remove our delegate from the
				// managed list of handlers, but only
				// Source.Remove will remove it from the
				// unmanaged list also.

				if (disposing)
					Remove ();
				else
					Source.Remove (ID);
			}

			public bool Handler ()
			{
				try {
					IdleHandler idle_handler = (IdleHandler) real_handler;

					bool cont = idle_handler ();
					if (!cont)
						Remove ();
					return cont;
				} catch (Exception e) {
					ExceptionManager.RaiseUnhandledException (e, false);
				}
				return false;
			}
		}
		
		private Idle ()
		{
		}
		
		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
		static extern uint g_idle_add (IdleHandlerInternal d, IntPtr data);

		public static uint Add (IdleHandler hndlr)
		{
			IdleProxy p = new IdleProxy (hndlr);
			p.ID = g_idle_add ((IdleHandlerInternal) p.proxy_handler, IntPtr.Zero);
			lock (Source.source_handlers)
				Source.source_handlers [p.ID] = p;

			return p.ID;
		}

		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
		static extern uint g_idle_add_full (int priority, IdleHandlerInternal d, IntPtr data, DestroyNotify notify);

		public static uint Add (IdleHandler hndlr, Priority priority)
		{
			IdleProxy p = new IdleProxy (hndlr);
			p.ID = g_idle_add_full ((int)priority, (IdleHandlerInternal)p.proxy_handler, IntPtr.Zero, null);
			lock (Source.source_handlers)
				Source.source_handlers [p.ID] = p;

			return p.ID;
		}
		
		[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
		static extern bool g_source_remove (uint id);
                                                                                
		public static void Remove (uint id)
		{
			Source.Remove (id);
		}

		public static bool Remove (IdleHandler hndlr)
		{
			bool result = false;
			List<uint> keys = new List<uint> ();

			lock (Source.source_handlers) {
				foreach (uint code in Source.source_handlers.Keys) {
					IdleProxy p = Source.source_handlers [code] as IdleProxy;
				
					if (p != null && p.real_handler == hndlr) {
						keys.Add (code);
						result = g_source_remove (code);
					}
				}

				foreach (object key in keys)
					Source.source_handlers.Remove (key);
			}

			return result;
		}
	}
}