1 /* 2 * Copyright 2001-2006, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Frans van Nispen (xlr8@tref.nl) 7 * Gabe Yoder (gyoder@stny.rr.com) 8 * Axel Dörfler, axeld@pinc-software.de 9 */ 10 11 /** BCursor describes a view-wide or application-wide cursor. */ 12 13 /** 14 @note: As BeOS only supports 16x16 monochrome cursors, and I would like 15 to see a nice shadowes one, we will need to extend this one. 16 */ 17 18 #include <AppDefs.h> 19 #include <Cursor.h> 20 21 #include <AppServerLink.h> 22 #include <ServerProtocol.h> 23 24 25 const BCursor *B_CURSOR_SYSTEM_DEFAULT; 26 const BCursor *B_CURSOR_I_BEAM; 27 // these are initialized in BApplication::InitData() 28 29 BCursor::BCursor(const void *cursorData) 30 : 31 fServerToken(-1), 32 fNeedToFree(false) 33 { 34 const uint8 *data = (const uint8 *)cursorData; 35 36 if (data == B_HAND_CURSOR || data == B_I_BEAM_CURSOR) { 37 // just use the default cursors from the app_server 38 fServerToken = data == B_HAND_CURSOR ? 39 B_CURSOR_ID_SYSTEM_DEFAULT : B_CURSOR_ID_I_BEAM; 40 return; 41 } 42 43 // Create a new cursor in the app_server 44 45 if (data == NULL 46 || data[0] != 16 // size 47 || data[1] != 1 // depth 48 || data[2] >= 16 || data[3] >= 16) // hot-spot 49 return; 50 51 // Send data directly to server 52 BPrivate::AppServerLink link; 53 link.StartMessage(AS_CREATE_CURSOR); 54 link.Attach(cursorData, 68); 55 56 status_t status; 57 if (link.FlushWithReply(status) == B_OK && status == B_OK) { 58 link.Read<int32>(&fServerToken); 59 fNeedToFree = true; 60 } 61 } 62 63 64 BCursor::BCursor(BCursorID id) 65 : 66 fServerToken(id), 67 fNeedToFree(false) 68 { 69 } 70 71 72 BCursor::BCursor(const BCursor& other) 73 : 74 fServerToken(-1), 75 fNeedToFree(false) 76 { 77 *this = other; 78 } 79 80 81 BCursor::BCursor(BMessage *data) 82 { 83 // undefined on BeOS 84 fServerToken = -1; 85 fNeedToFree = false; 86 } 87 88 89 BCursor::~BCursor() 90 { 91 _FreeCursorData(); 92 } 93 94 95 status_t 96 BCursor::Archive(BMessage *into, bool deep) const 97 { 98 // not implemented on BeOS 99 return B_OK; 100 } 101 102 103 BArchivable * 104 BCursor::Instantiate(BMessage *data) 105 { 106 // not implemented on BeOS 107 return NULL; 108 } 109 110 111 BCursor& 112 BCursor::operator=(const BCursor& other) 113 { 114 if (&other != this && other != *this) { 115 _FreeCursorData(); 116 117 fServerToken = other.fServerToken; 118 fNeedToFree = other.fNeedToFree; 119 120 if (fNeedToFree) { 121 // Tell app_server that there is another reference for this 122 // cursor data! 123 BPrivate::AppServerLink link; 124 link.StartMessage(AS_REFERENCE_CURSOR); 125 link.Attach<int32>(fServerToken); 126 } 127 } 128 return *this; 129 } 130 131 132 bool 133 BCursor::operator==(const BCursor& other) const 134 { 135 return fServerToken == other.fServerToken; 136 } 137 138 139 bool 140 BCursor::operator!=(const BCursor& other) const 141 { 142 return fServerToken != other.fServerToken; 143 } 144 145 146 status_t 147 BCursor::Perform(perform_code d, void *arg) 148 { 149 return B_OK; 150 } 151 152 153 void BCursor::_ReservedCursor1() {} 154 void BCursor::_ReservedCursor2() {} 155 void BCursor::_ReservedCursor3() {} 156 void BCursor::_ReservedCursor4() {} 157 158 159 void 160 BCursor::_FreeCursorData() 161 { 162 // Notify server to deallocate server-side objects for this cursor 163 if (fNeedToFree) { 164 BPrivate::AppServerLink link; 165 link.StartMessage(AS_DELETE_CURSOR); 166 link.Attach<int32>(fServerToken); 167 link.Flush(); 168 } 169 } 170 171