1/* $Id$ */ 2 3/*** 4 This file is part of avahi. 5 6 avahi is free software; you can redistribute it and/or modify it 7 under the terms of the GNU Lesser General Public License as 8 published by the Free Software Foundation; either version 2.1 of the 9 License, or (at your option) any later version. 10 11 avahi is distributed in the hope that it will be useful, but WITHOUT 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 14 Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with avahi; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 USA. 20***/ 21 22using System; 23using System.Collections; 24using System.Runtime.InteropServices; 25using System.Text; 26 27namespace Avahi 28{ 29 internal delegate void DomainBrowserCallback (IntPtr browser, int iface, Protocol proto, BrowserEvent bevent, 30 IntPtr domain, LookupResultFlags flags, IntPtr userdata); 31 32 public enum DomainBrowserType { 33 Browse, 34 BrowseDefault, 35 Register, 36 RegisterDefault, 37 BrowseLegacy 38 } 39 40 public struct DomainInfo 41 { 42 public int NetworkInterface; 43 public Protocol Protocol; 44 public string Domain; 45 public LookupResultFlags Flags; 46 } 47 48 public class DomainInfoArgs : EventArgs 49 { 50 private DomainInfo domain; 51 52 public DomainInfo Domain 53 { 54 get { return domain; } 55 } 56 57 public DomainInfoArgs (DomainInfo domain) 58 { 59 this.domain = domain; 60 } 61 } 62 63 public delegate void DomainInfoHandler (object o, DomainInfoArgs args); 64 65 public class DomainBrowser : BrowserBase, IDisposable 66 { 67 private IntPtr handle; 68 private ArrayList infos = new ArrayList (); 69 private Client client; 70 private int iface; 71 private Protocol proto; 72 private string domain; 73 private DomainBrowserType btype; 74 private LookupFlags flags; 75 private DomainBrowserCallback cb; 76 77 private ArrayList addListeners = new ArrayList (); 78 private ArrayList removeListeners = new ArrayList (); 79 80 [DllImport ("avahi-client")] 81 private static extern IntPtr avahi_domain_browser_new (IntPtr client, int iface, int proto, 82 byte[] domain, int btype, LookupFlags flags, 83 DomainBrowserCallback cb, 84 IntPtr userdata); 85 86 [DllImport ("avahi-client")] 87 private static extern void avahi_domain_browser_free (IntPtr handle); 88 89 public event DomainInfoHandler DomainAdded 90 { 91 add { 92 addListeners.Add (value); 93 Start (); 94 } 95 remove { 96 addListeners.Remove (value); 97 Stop (false); 98 } 99 } 100 101 public event DomainInfoHandler DomainRemoved 102 { 103 add { 104 removeListeners.Add (value); 105 Start (); 106 } 107 remove { 108 removeListeners.Remove (value); 109 Stop (false); 110 } 111 } 112 113 public DomainInfo[] Domains 114 { 115 get { return (DomainInfo[]) infos.ToArray (typeof (DomainInfo)); } 116 } 117 118 public DomainBrowser (Client client) : this (client, -1, Protocol.Unspecified, client.DomainName, 119 DomainBrowserType.Browse, LookupFlags.None) { 120 } 121 122 public DomainBrowser (Client client, int iface, Protocol proto, string domain, 123 DomainBrowserType btype, LookupFlags flags) 124 { 125 this.client = client; 126 this.iface = iface; 127 this.proto = proto; 128 this.domain = domain; 129 this.btype = btype; 130 this.flags = flags; 131 cb = OnDomainBrowserCallback; 132 } 133 134 ~DomainBrowser () 135 { 136 Dispose (); 137 } 138 139 public void Dispose () 140 { 141 Stop (true); 142 } 143 144 private void Start () 145 { 146 if (client.Handle == IntPtr.Zero && handle != IntPtr.Zero || 147 (addListeners.Count == 0 && removeListeners.Count == 0)) 148 return; 149 150 lock (client) { 151 handle = avahi_domain_browser_new (client.Handle, iface, (int) proto, 152 Utility.StringToBytes (domain), (int) btype, flags, 153 cb, IntPtr.Zero); 154 155 if (handle == IntPtr.Zero) 156 client.ThrowError (); 157 } 158 } 159 160 private void Stop (bool force) 161 { 162 if (client.Handle != IntPtr.Zero && handle != IntPtr.Zero && 163 (force || (addListeners.Count == 0 && removeListeners.Count == 0))) { 164 lock (client) { 165 avahi_domain_browser_free (handle); 166 handle = IntPtr.Zero; 167 } 168 } 169 } 170 171 private void OnDomainBrowserCallback (IntPtr browser, int iface, Protocol proto, BrowserEvent bevent, 172 IntPtr domain, LookupResultFlags flags, IntPtr userdata) 173 { 174 175 DomainInfo info; 176 info.NetworkInterface = iface; 177 info.Protocol = proto; 178 info.Domain = Utility.PtrToString (domain); 179 info.Flags = flags; 180 181 switch (bevent) { 182 case BrowserEvent.Added: 183 infos.Add (info); 184 185 foreach (DomainInfoHandler handler in addListeners) 186 handler (this, new DomainInfoArgs (info)); 187 break; 188 case BrowserEvent.Removed: 189 infos.Remove (info); 190 191 foreach (DomainInfoHandler handler in removeListeners) 192 handler (this, new DomainInfoArgs (info)); 193 break; 194 default: 195 EmitBrowserEvent (bevent); 196 break; 197 } 198 } 199 } 200} 201