filename | src/drivers/io_osx.m |
changeset | 1077:136fc24d17ef |
prev | 1071:182cfe43c09e |
next | 1298:d0eb2307b847 |
author | nkeynes |
date | Sat Mar 03 16:11:28 2012 +1000 (12 years ago) |
permissions | -rw-r--r-- |
last change | Support depth component 16 as well as 24 (add capability flag for the available bits) Put remaining TODOs inside HAVE_OPENGL_FIXEDFUNC blocks Add swap-buffer calls for EGL (does not appear to support rendering directly to front-buffer) |
file | annotate | diff | log | raw |
nkeynes@998 | 1 | /** |
nkeynes@1021 | 2 | * $Id$ |
nkeynes@998 | 3 | * |
nkeynes@998 | 4 | * OS X networking support functions. Currently this is just for activity callbacks. |
nkeynes@998 | 5 | * |
nkeynes@998 | 6 | * Copyright (c) 2009 Nathan Keynes. |
nkeynes@998 | 7 | * |
nkeynes@998 | 8 | * This program is free software; you can redistribute it and/or modify |
nkeynes@998 | 9 | * it under the terms of the GNU General Public License as published by |
nkeynes@998 | 10 | * the Free Software Foundation; either version 2 of the License, or |
nkeynes@998 | 11 | * (at your option) any later version. |
nkeynes@998 | 12 | * |
nkeynes@998 | 13 | * This program is distributed in the hope that it will be useful, |
nkeynes@998 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
nkeynes@998 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
nkeynes@998 | 16 | * GNU General Public License for more details. |
nkeynes@998 | 17 | */ |
nkeynes@998 | 18 | |
nkeynes@998 | 19 | #include <CoreFoundation/CoreFoundation.h> |
nkeynes@1077 | 20 | #include "ioutil.h" |
nkeynes@998 | 21 | |
nkeynes@1077 | 22 | struct io_osx_cbinfo { |
nkeynes@1077 | 23 | int fd; |
nkeynes@1077 | 24 | io_callback_t callback; |
nkeynes@998 | 25 | void * cbdata; |
nkeynes@998 | 26 | void (*cbdealloc)(void *); |
nkeynes@1077 | 27 | void *fdRef; |
nkeynes@998 | 28 | CFRunLoopSourceRef sourceRef; |
nkeynes@1077 | 29 | |
nkeynes@1077 | 30 | struct io_osx_cbinfo *next; |
nkeynes@998 | 31 | }; |
nkeynes@998 | 32 | |
nkeynes@1077 | 33 | static struct io_osx_cbinfo *cbinfo_list = NULL; |
nkeynes@1077 | 34 | |
nkeynes@1077 | 35 | void io_unregister_callback( struct io_osx_cbinfo *cbinfo ) |
nkeynes@998 | 36 | { |
nkeynes@1077 | 37 | CFRunLoopRemoveSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes ); |
nkeynes@1077 | 38 | CFRelease(cbinfo->sourceRef); |
nkeynes@1077 | 39 | cbinfo->sourceRef = NULL; |
nkeynes@1077 | 40 | CFRelease(cbinfo->fdRef); /* Note this implicitly releases the cbinfo itself as well */ |
nkeynes@1077 | 41 | } |
nkeynes@1077 | 42 | |
nkeynes@1077 | 43 | static void io_osx_net_callback( CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *unused, void *data ) |
nkeynes@1077 | 44 | { |
nkeynes@1077 | 45 | struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data; |
nkeynes@998 | 46 | if(!cbinfo->callback( CFSocketGetNative(s), cbinfo->cbdata) ) { |
nkeynes@1077 | 47 | io_unregister_callback(cbinfo); |
nkeynes@998 | 48 | } |
nkeynes@998 | 49 | } |
nkeynes@998 | 50 | |
nkeynes@1077 | 51 | static void io_osx_fd_callback( CFFileDescriptorRef f, CFOptionFlags type, void *data ) |
nkeynes@998 | 52 | { |
nkeynes@1077 | 53 | struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data; |
nkeynes@1077 | 54 | if(!cbinfo->callback( CFFileDescriptorGetNativeDescriptor(f), cbinfo->cbdata) ) { |
nkeynes@1077 | 55 | io_unregister_callback(cbinfo); |
nkeynes@1077 | 56 | } |
nkeynes@1077 | 57 | } |
nkeynes@1077 | 58 | |
nkeynes@1077 | 59 | static void io_osx_release( const void *data ) |
nkeynes@1077 | 60 | { |
nkeynes@1077 | 61 | struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data; |
nkeynes@998 | 62 | if( cbinfo->cbdealloc != NULL ) { |
nkeynes@998 | 63 | cbinfo->cbdealloc(cbinfo->cbdata); |
nkeynes@998 | 64 | } |
nkeynes@998 | 65 | free( cbinfo ); |
nkeynes@998 | 66 | } |
nkeynes@998 | 67 | |
nkeynes@998 | 68 | /** |
nkeynes@998 | 69 | * Register a TCP server socket listener on an already open (and listening) |
nkeynes@998 | 70 | * socket. The socket must not have been previously registered. |
nkeynes@998 | 71 | * @return TRUE on success, FALSE on failure. |
nkeynes@998 | 72 | * |
nkeynes@998 | 73 | * Defined in netutil.h |
nkeynes@998 | 74 | */ |
nkeynes@1077 | 75 | io_listener_t io_register_tcp_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void*) ) |
nkeynes@998 | 76 | { |
nkeynes@998 | 77 | CFSocketContext socketContext; |
nkeynes@1077 | 78 | struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) ); |
nkeynes@998 | 79 | assert(cbinfo != NULL); |
nkeynes@998 | 80 | |
nkeynes@998 | 81 | cbinfo->callback = callback; |
nkeynes@998 | 82 | cbinfo->cbdata = data; |
nkeynes@998 | 83 | cbinfo->cbdealloc = dealloc; |
nkeynes@998 | 84 | socketContext.version = 0; |
nkeynes@998 | 85 | socketContext.info = cbinfo; |
nkeynes@998 | 86 | socketContext.retain = NULL; |
nkeynes@1077 | 87 | socketContext.release = io_osx_release; |
nkeynes@998 | 88 | socketContext.copyDescription = NULL; |
nkeynes@998 | 89 | |
nkeynes@1077 | 90 | CFSocketRef ref = CFSocketCreateWithNative( kCFAllocatorDefault, fd, kCFSocketReadCallBack, |
nkeynes@1077 | 91 | io_osx_net_callback, &socketContext ); |
nkeynes@1077 | 92 | cbinfo->fdRef = ref; |
nkeynes@1077 | 93 | cbinfo->sourceRef = CFSocketCreateRunLoopSource( kCFAllocatorDefault, ref, 0 ); |
nkeynes@998 | 94 | CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes ); |
nkeynes@1071 | 95 | |
nkeynes@1077 | 96 | return cbinfo; |
nkeynes@998 | 97 | } |
nkeynes@1077 | 98 | |
nkeynes@1077 | 99 | /** |
nkeynes@1077 | 100 | * Register a file descriptor listener on an already open (and listening) |
nkeynes@1077 | 101 | * file descriptor. The file descriptor must not have been previously registered. |
nkeynes@1077 | 102 | * @return TRUE on success, FALSE on failure. |
nkeynes@1077 | 103 | * |
nkeynes@1077 | 104 | */ |
nkeynes@1077 | 105 | io_listener_t io_register_listener( int fd, io_callback_t callback, void *data, void (*dealloc)(void *) ) |
nkeynes@1077 | 106 | { |
nkeynes@1077 | 107 | CFFileDescriptorContext fdContext; |
nkeynes@1077 | 108 | struct io_osx_cbinfo *cbinfo = malloc( sizeof(struct io_osx_cbinfo) ); |
nkeynes@1077 | 109 | assert(cbinfo != NULL); |
nkeynes@1077 | 110 | |
nkeynes@1077 | 111 | cbinfo->callback = callback; |
nkeynes@1077 | 112 | cbinfo->cbdata = data; |
nkeynes@1077 | 113 | cbinfo->cbdealloc = dealloc; |
nkeynes@1077 | 114 | fdContext.version = 0; |
nkeynes@1077 | 115 | fdContext.retain = NULL; |
nkeynes@1077 | 116 | fdContext.info = cbinfo; |
nkeynes@1077 | 117 | fdContext.release = io_osx_release; |
nkeynes@1077 | 118 | fdContext.copyDescription = NULL; |
nkeynes@1077 | 119 | |
nkeynes@1077 | 120 | CFFileDescriptorRef ref = CFFileDescriptorCreate( kCFAllocatorDefault, fd, FALSE, |
nkeynes@1077 | 121 | io_osx_fd_callback, &fdContext); |
nkeynes@1077 | 122 | cbinfo->fdRef = ref; |
nkeynes@1077 | 123 | cbinfo->sourceRef = CFFileDescriptorCreateRunLoopSource( kCFAllocatorDefault, ref, 0 ); |
nkeynes@1077 | 124 | CFRunLoopAddSource( CFRunLoopGetCurrent(), cbinfo->sourceRef, kCFRunLoopCommonModes ); |
nkeynes@1077 | 125 | return cbinfo; |
nkeynes@1077 | 126 | } |
nkeynes@1077 | 127 | |
nkeynes@1077 | 128 | void io_unregister_listener( io_listener_t data ) |
nkeynes@1077 | 129 | { |
nkeynes@1077 | 130 | struct io_osx_cbinfo *cbinfo = (struct io_osx_cbinfo *)data; |
nkeynes@1077 | 131 | io_unregister_callback(cbinfo); |
nkeynes@1077 | 132 | } |
.