VirtualBox

Changeset 43364 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Sep 20, 2012 12:12:09 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
80828
Message:

Haiku Additions: cleanup.

Location:
trunk/src/VBox/Additions/haiku
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/haiku/SharedFolders/OpenHashTable.h

    r43363 r43364  
    3434
    3535#ifdef _KERNEL_MODE
    36 #       include <KernelExport.h>
    37 #       include "kernel_cpp.h"
     36#    include <KernelExport.h>
     37#    include "kernel_cpp.h"
    3838#endif
    3939
    4040/*!
    41         The Definition template must have four methods: `HashKey', `Hash',
    42         `Compare' and `GetLink;. It must also define several types as shown in the
    43         following example:
    44 
    45         struct Foo {
    46                 int bar;
    47 
    48                 Foo* fNext;
    49         };
    50 
    51         struct HashTableDefinition {
    52                 typedef int             KeyType;
    53                 typedef Foo             ValueType;
    54 
    55                 size_t HashKey(int key) const
     41    The Definition template must have four methods: `HashKey', `Hash',
     42    `Compare' and `GetLink;. It must also define several types as shown in the
     43    following example:
     44
     45    struct Foo {
     46        int bar;
     47
     48        Foo* fNext;
     49    };
     50
     51    struct HashTableDefinition {
     52        typedef int        KeyType;
     53        typedef    Foo        ValueType;
     54
     55        size_t HashKey(int key) const
     56        {
     57            return key >> 1;
     58        }
     59
     60        size_t Hash(Foo* value) const
     61        {
     62            return HashKey(value->bar);
     63        }
     64
     65        bool Compare(int key, Foo* value) const
     66        {
     67            return value->bar == key;
     68        }
     69
     70        Foo*& GetLink(Foo* value) const
     71        {
     72            return value->fNext;
     73        }
     74    };
     75*/
     76
     77
     78struct MallocAllocator
     79{
     80    void* Allocate(size_t size) const
     81    {
     82        return malloc(size);
     83    }
     84
     85    void Free(void* memory) const
     86    {
     87        free(memory);
     88    }
     89};
     90
     91
     92template<typename Definition, bool AutoExpand = true,
     93    bool CheckDuplicates = false, typename Allocator = MallocAllocator>
     94class BOpenHashTable
     95{
     96public:
     97    typedef BOpenHashTable<Definition, AutoExpand, CheckDuplicates> HashTable;
     98    typedef typename Definition::KeyType      KeyType;
     99    typedef typename Definition::ValueType    ValueType;
     100
     101    static const size_t kMinimumSize = 8;
     102
     103    // All allocations are of power of 2 lengths.
     104
     105    // regrowth factor: 200 / 256 = 78.125%
     106    //                   50 / 256 = 19.53125%
     107
     108    BOpenHashTable()
     109        :
     110        fTableSize(0),
     111        fItemCount(0),
     112        fTable(NULL)
     113    {
     114    }
     115
     116    BOpenHashTable(const Definition& definition)
     117        :
     118        fDefinition(definition),
     119        fTableSize(0),
     120        fItemCount(0),
     121        fTable(NULL)
     122    {
     123    }
     124
     125    BOpenHashTable(const Definition& definition, const Allocator& allocator)
     126        :
     127        fDefinition(definition),
     128        fAllocator(allocator),
     129        fTableSize(0),
     130        fItemCount(0),
     131        fTable(NULL)
     132    {
     133    }
     134
     135    ~BOpenHashTable()
     136    {
     137        fAllocator.Free(fTable);
     138    }
     139
     140    status_t Init(size_t initialSize = kMinimumSize)
     141    {
     142        if (initialSize > 0 && !_Resize(initialSize))
     143            return B_NO_MEMORY;
     144        return B_OK;
     145    }
     146
     147    size_t TableSize() const
     148    {
     149        return fTableSize;
     150    }
     151
     152    size_t CountElements() const
     153    {
     154        return fItemCount;
     155    }
     156
     157    ValueType* Lookup(const KeyType& key) const
     158    {
     159        if (fTableSize == 0)
     160            return NULL;
     161
     162        size_t index = fDefinition.HashKey(key) & (fTableSize - 1);
     163        ValueType* slot = fTable[index];
     164
     165        while (slot)
     166        {
     167            if (fDefinition.Compare(key, slot))
     168                break;
     169            slot = _Link(slot);
     170        }
     171
     172        return slot;
     173    }
     174
     175    status_t Insert(ValueType* value)
     176    {
     177        if (fTableSize == 0)
     178        {
     179            if (!_Resize(kMinimumSize))
     180                return B_NO_MEMORY;
     181        }
     182        else if (AutoExpand && fItemCount >= (fTableSize * 200 / 256))
     183            _Resize(fTableSize * 2);
     184
     185        InsertUnchecked(value);
     186        return B_OK;
     187    }
     188
     189    void InsertUnchecked(ValueType* value)
     190    {
     191        if (CheckDuplicates && _ExhaustiveSearch(value))
     192        {
     193#ifdef _KERNEL_MODE
     194            panic("Hash Table: value already in table.");
     195#else
     196            debugger("Hash Table: value already in table.");
     197#endif
     198        }
     199
     200        _Insert(fTable, fTableSize, value);
     201        fItemCount++;
     202    }
     203
     204    // TODO: a ValueType* Remove(const KeyType& key) method is missing
     205
     206    bool Remove(ValueType* value)
     207    {
     208        if (!RemoveUnchecked(value))
     209            return false;
     210
     211        if (AutoExpand && fTableSize > kMinimumSize
     212            && fItemCount < (fTableSize * 50 / 256))
     213            _Resize(fTableSize / 2);
     214
     215        return true;
     216    }
     217
     218    bool RemoveUnchecked(ValueType* value)
     219    {
     220        size_t index = fDefinition.Hash(value) & (fTableSize - 1);
     221        ValueType* previous = NULL;
     222        ValueType* slot = fTable[index];
     223
     224        while (slot)
     225        {
     226            ValueType* next = _Link(slot);
     227
     228            if (value == slot)
     229            {
     230                if (previous)
     231                    _Link(previous) = next;
     232                else
     233                    fTable[index] = next;
     234                break;
     235            }
     236
     237            previous = slot;
     238            slot = next;
     239        }
     240
     241        if (slot == NULL)
     242            return false;
     243
     244        if (CheckDuplicates && _ExhaustiveSearch(value))
     245        {
     246#ifdef _KERNEL_MODE
     247            panic("Hash Table: duplicate detected.");
     248#else
     249            debugger("Hash Table: duplicate detected.");
     250#endif
     251        }
     252
     253        fItemCount--;
     254        return true;
     255    }
     256
     257    /*!    Removes all elements from the hash table. No resizing happens. The
     258        elements are not deleted. If \a returnElements is \c true, the method
     259        returns all elements chained via their hash table link.
     260    */
     261    ValueType* Clear(bool returnElements = false)
     262    {
     263        if (this->fItemCount == 0)
     264            return NULL;
     265
     266        ValueType* result = NULL;
     267
     268        if (returnElements)
    56269                {
    57                         return key >> 1;
    58                 }
    59 
    60                 size_t Hash(Foo* value) const
    61                 {
    62                         return HashKey(value->bar);
    63                 }
    64 
    65                 bool Compare(int key, Foo* value) const
    66                 {
    67                         return value->bar == key;
    68                 }
    69 
    70                 Foo*& GetLink(Foo* value) const
    71                 {
    72                         return value->fNext;
    73                 }
    74         };
    75 */
    76 
    77 
    78 struct MallocAllocator {
    79         void* Allocate(size_t size) const
     270            ValueType** nextPointer = &result;
     271
     272            // iterate through all buckets
     273            for (size_t i = 0; i < fTableSize; i++)
     274            {
     275                ValueType* element = fTable[i];
     276                if (element != NULL)
     277                {
     278                    // add the bucket to the list
     279                    *nextPointer = element;
     280
     281                    // update nextPointer to point to the fNext of the last
     282                    // element in the bucket
     283                    while (element != NULL)
     284                    {
     285                        nextPointer = &_Link(element);
     286                        element = *nextPointer;
     287                    }
     288                }
     289            }
     290        }
     291
     292        memset(this->fTable, 0, sizeof(ValueType*) * this->fTableSize);
     293
     294        return result;
     295    }
     296
     297    /*!    If the table needs resizing, the number of bytes for the required
     298        allocation is returned. If no resizing is needed, 0 is returned.
     299    */
     300    size_t ResizeNeeded() const
     301    {
     302        size_t size = fTableSize;
     303        if (size == 0 || fItemCount >= (size * 200 / 256))
     304        {
     305            // grow table
     306            if (size == 0)
     307                size = kMinimumSize;
     308            while (fItemCount >= size * 200 / 256)
     309                size <<= 1;
     310        }
     311        else if (size > kMinimumSize && fItemCount < size * 50 / 256)
     312        {
     313            // shrink table
     314            while (fItemCount < size * 50 / 256)
     315                size >>= 1;
     316            if (size < kMinimumSize)
     317                size = kMinimumSize;
     318        }
     319
     320        if (size == fTableSize)
     321            return 0;
     322
     323        return size * sizeof(ValueType*);
     324    }
     325
     326    /*!    Resizes the table using the given allocation. The allocation must not
     327        be \c NULL. It must be of size \a size, which must a value returned
     328        earlier by ResizeNeeded(). If the size requirements have changed in the
     329        meantime, the method free()s the given allocation and returns \c false,
     330        unless \a force is \c true, in which case the supplied allocation is
     331        used in any event.
     332        Otherwise \c true is returned.
     333        If \a oldTable is non-null and resizing is successful, the old table
     334        will not be freed, but will be returned via this parameter instead.
     335    */
     336    bool Resize(void* allocation, size_t size, bool force = false,
     337        void** oldTable = NULL)
     338    {
     339        if (!force && size != ResizeNeeded())
     340        {
     341            fAllocator.Free(allocation);
     342            return false;
     343        }
     344
     345        _Resize((ValueType**)allocation, size / sizeof(ValueType*), oldTable);
     346        return true;
     347    }
     348
     349    class Iterator
    80350        {
    81                 return malloc(size);
    82         }
    83 
    84         void Free(void* memory) const
    85         {
    86                 free(memory);
    87         }
     351    public:
     352        Iterator(const HashTable* table)
     353            : fTable(table)
     354        {
     355            Rewind();
     356        }
     357
     358        Iterator(const HashTable* table, size_t index, ValueType* value)
     359            : fTable(table), fIndex(index), fNext(value) {}
     360
     361        bool HasNext() const { return fNext != NULL; }
     362
     363        ValueType* Next()
     364        {
     365            ValueType* current = fNext;
     366            _GetNext();
     367            return current;
     368        }
     369
     370        void Rewind()
     371        {
     372            // get the first one
     373            fIndex = 0;
     374            fNext = NULL;
     375            _GetNext();
     376        }
     377
     378    protected:
     379        Iterator() {}
     380
     381        void _GetNext()
     382        {
     383            if (fNext)
     384                fNext = fTable->_Link(fNext);
     385
     386            while (fNext == NULL && fIndex < fTable->fTableSize)
     387                fNext = fTable->fTable[fIndex++];
     388        }
     389
     390        const HashTable* fTable;
     391        size_t fIndex;
     392        ValueType* fNext;
     393    };
     394
     395    Iterator GetIterator() const
     396    {
     397        return Iterator(this);
     398    }
     399
     400    Iterator GetIterator(const KeyType& key) const
     401    {
     402        if (fTableSize == 0)
     403            return Iterator(this, fTableSize, NULL);
     404
     405        size_t index = fDefinition.HashKey(key) & (fTableSize - 1);
     406        ValueType* slot = fTable[index];
     407
     408        while (slot)
     409        {
     410            if (fDefinition.Compare(key, slot))
     411                break;
     412            slot = _Link(slot);
     413        }
     414
     415        if (slot == NULL)
     416            return Iterator(this, fTableSize, NULL);
     417
     418        return Iterator(this, index + 1, slot);
     419    }
     420
     421protected:
     422    // for g++ 2.95
     423    friend class Iterator;
     424
     425    void _Insert(ValueType** table, size_t tableSize, ValueType* value)
     426    {
     427        size_t index = fDefinition.Hash(value) & (tableSize - 1);
     428
     429        _Link(value) = table[index];
     430        table[index] = value;
     431    }
     432
     433    bool _Resize(size_t newSize)
     434    {
     435        ValueType** newTable
     436            = (ValueType**)fAllocator.Allocate(sizeof(ValueType*) * newSize);
     437        if (newTable == NULL)
     438            return false;
     439
     440        _Resize(newTable, newSize);
     441        return true;
     442    }
     443
     444    void _Resize(ValueType** newTable, size_t newSize, void** _oldTable = NULL)
     445    {
     446        for (size_t i = 0; i < newSize; i++)
     447            newTable[i] = NULL;
     448
     449        if (fTable)
     450        {
     451            for (size_t i = 0; i < fTableSize; i++)
     452            {
     453                ValueType* bucket = fTable[i];
     454                while (bucket)
     455                {
     456                    ValueType* next = _Link(bucket);
     457                    _Insert(newTable, newSize, bucket);
     458                    bucket = next;
     459                }
     460            }
     461
     462            if (_oldTable != NULL)
     463                *_oldTable = fTable;
     464            else
     465                fAllocator.Free(fTable);
     466        }
     467        else if (_oldTable != NULL)
     468            *_oldTable = NULL;
     469
     470        fTableSize = newSize;
     471        fTable = newTable;
     472    }
     473
     474    ValueType*& _Link(ValueType* bucket) const
     475    {
     476        return fDefinition.GetLink(bucket);
     477    }
     478
     479    bool _ExhaustiveSearch(ValueType* value) const
     480    {
     481        for (size_t i = 0; i < fTableSize; i++)
     482        {
     483            ValueType* bucket = fTable[i];
     484            while (bucket) {
     485                if (bucket == value)
     486                    return true;
     487                bucket = _Link(bucket);
     488            }
     489        }
     490
     491        return false;
     492    }
     493
     494    Definition        fDefinition;
     495    Allocator        fAllocator;
     496    size_t            fTableSize;
     497    size_t            fItemCount;
     498    ValueType**        fTable;
    88499};
    89500
    90 
    91 template<typename Definition, bool AutoExpand = true,
    92         bool CheckDuplicates = false, typename Allocator = MallocAllocator>
    93 class BOpenHashTable {
    94 public:
    95         typedef BOpenHashTable<Definition, AutoExpand, CheckDuplicates> HashTable;
    96         typedef typename Definition::KeyType    KeyType;
    97         typedef typename Definition::ValueType  ValueType;
    98 
    99         static const size_t kMinimumSize = 8;
    100 
    101         // All allocations are of power of 2 lengths.
    102 
    103         // regrowth factor: 200 / 256 = 78.125%
    104         //                   50 / 256 = 19.53125%
    105 
    106         BOpenHashTable()
    107                 :
    108                 fTableSize(0),
    109                 fItemCount(0),
    110                 fTable(NULL)
    111         {
    112         }
    113 
    114         BOpenHashTable(const Definition& definition)
    115                 :
    116                 fDefinition(definition),
    117                 fTableSize(0),
    118                 fItemCount(0),
    119                 fTable(NULL)
    120         {
    121         }
    122 
    123         BOpenHashTable(const Definition& definition, const Allocator& allocator)
    124                 :
    125                 fDefinition(definition),
    126                 fAllocator(allocator),
    127                 fTableSize(0),
    128                 fItemCount(0),
    129                 fTable(NULL)
    130         {
    131         }
    132 
    133         ~BOpenHashTable()
    134         {
    135                 fAllocator.Free(fTable);
    136         }
    137 
    138         status_t Init(size_t initialSize = kMinimumSize)
    139         {
    140                 if (initialSize > 0 && !_Resize(initialSize))
    141                         return B_NO_MEMORY;
    142                 return B_OK;
    143         }
    144 
    145         size_t TableSize() const
    146         {
    147                 return fTableSize;
    148         }
    149 
    150         size_t CountElements() const
    151         {
    152                 return fItemCount;
    153         }
    154 
    155         ValueType* Lookup(const KeyType& key) const
    156         {
    157                 if (fTableSize == 0)
    158                         return NULL;
    159 
    160                 size_t index = fDefinition.HashKey(key) & (fTableSize - 1);
    161                 ValueType* slot = fTable[index];
    162 
    163                 while (slot) {
    164                         if (fDefinition.Compare(key, slot))
    165                                 break;
    166                         slot = _Link(slot);
    167                 }
    168 
    169                 return slot;
    170         }
    171 
    172         status_t Insert(ValueType* value)
    173         {
    174                 if (fTableSize == 0) {
    175                         if (!_Resize(kMinimumSize))
    176                                 return B_NO_MEMORY;
    177                 } else if (AutoExpand && fItemCount >= (fTableSize * 200 / 256))
    178                         _Resize(fTableSize * 2);
    179 
    180                 InsertUnchecked(value);
    181                 return B_OK;
    182         }
    183 
    184         void InsertUnchecked(ValueType* value)
    185         {
    186                 if (CheckDuplicates && _ExhaustiveSearch(value)) {
    187 #ifdef _KERNEL_MODE
    188                         panic("Hash Table: value already in table.");
    189 #else
    190                         debugger("Hash Table: value already in table.");
    191 #endif
    192                 }
    193 
    194                 _Insert(fTable, fTableSize, value);
    195                 fItemCount++;
    196         }
    197 
    198         // TODO: a ValueType* Remove(const KeyType& key) method is missing
    199 
    200         bool Remove(ValueType* value)
    201         {
    202                 if (!RemoveUnchecked(value))
    203                         return false;
    204 
    205                 if (AutoExpand && fTableSize > kMinimumSize
    206                         && fItemCount < (fTableSize * 50 / 256))
    207                         _Resize(fTableSize / 2);
    208 
    209                 return true;
    210         }
    211 
    212         bool RemoveUnchecked(ValueType* value)
    213         {
    214                 size_t index = fDefinition.Hash(value) & (fTableSize - 1);
    215                 ValueType* previous = NULL;
    216                 ValueType* slot = fTable[index];
    217 
    218                 while (slot) {
    219                         ValueType* next = _Link(slot);
    220 
    221                         if (value == slot) {
    222                                 if (previous)
    223                                         _Link(previous) = next;
    224                                 else
    225                                         fTable[index] = next;
    226                                 break;
    227                         }
    228 
    229                         previous = slot;
    230                         slot = next;
    231                 }
    232 
    233                 if (slot == NULL)
    234                         return false;
    235 
    236                 if (CheckDuplicates && _ExhaustiveSearch(value)) {
    237 #ifdef _KERNEL_MODE
    238                         panic("Hash Table: duplicate detected.");
    239 #else
    240                         debugger("Hash Table: duplicate detected.");
    241 #endif
    242                 }
    243 
    244                 fItemCount--;
    245                 return true;
    246         }
    247 
    248         /*!     Removes all elements from the hash table. No resizing happens. The
    249                 elements are not deleted. If \a returnElements is \c true, the method
    250                 returns all elements chained via their hash table link.
    251         */
    252         ValueType* Clear(bool returnElements = false)
    253         {
    254                 if (this->fItemCount == 0)
    255                         return NULL;
    256 
    257                 ValueType* result = NULL;
    258 
    259                 if (returnElements) {
    260                         ValueType** nextPointer = &result;
    261 
    262                         // iterate through all buckets
    263                         for (size_t i = 0; i < fTableSize; i++) {
    264                                 ValueType* element = fTable[i];
    265                                 if (element != NULL) {
    266                                         // add the bucket to the list
    267                                         *nextPointer = element;
    268 
    269                                         // update nextPointer to point to the fNext of the last
    270                                         // element in the bucket
    271                                         while (element != NULL) {
    272                                                 nextPointer = &_Link(element);
    273                                                 element = *nextPointer;
    274                                         }
    275                                 }
    276                         }
    277                 }
    278 
    279                 memset(this->fTable, 0, sizeof(ValueType*) * this->fTableSize);
    280 
    281                 return result;
    282         }
    283 
    284         /*!     If the table needs resizing, the number of bytes for the required
    285                 allocation is returned. If no resizing is needed, 0 is returned.
    286         */
    287         size_t ResizeNeeded() const
    288         {
    289                 size_t size = fTableSize;
    290                 if (size == 0 || fItemCount >= (size * 200 / 256)) {
    291                         // grow table
    292                         if (size == 0)
    293                                 size = kMinimumSize;
    294                         while (fItemCount >= size * 200 / 256)
    295                                 size <<= 1;
    296                 } else if (size > kMinimumSize && fItemCount < size * 50 / 256) {
    297                         // shrink table
    298                         while (fItemCount < size * 50 / 256)
    299                                 size >>= 1;
    300                         if (size < kMinimumSize)
    301                                 size = kMinimumSize;
    302                 }
    303 
    304                 if (size == fTableSize)
    305                         return 0;
    306 
    307                 return size * sizeof(ValueType*);
    308         }
    309 
    310         /*!     Resizes the table using the given allocation. The allocation must not
    311                 be \c NULL. It must be of size \a size, which must a value returned
    312                 earlier by ResizeNeeded(). If the size requirements have changed in the
    313                 meantime, the method free()s the given allocation and returns \c false,
    314                 unless \a force is \c true, in which case the supplied allocation is
    315                 used in any event.
    316                 Otherwise \c true is returned.
    317                 If \a oldTable is non-null and resizing is successful, the old table
    318                 will not be freed, but will be returned via this parameter instead.
    319         */
    320         bool Resize(void* allocation, size_t size, bool force = false,
    321                 void** oldTable = NULL)
    322         {
    323                 if (!force && size != ResizeNeeded()) {
    324                         fAllocator.Free(allocation);
    325                         return false;
    326                 }
    327 
    328                 _Resize((ValueType**)allocation, size / sizeof(ValueType*), oldTable);
    329                 return true;
    330         }
    331 
    332         class Iterator {
    333         public:
    334                 Iterator(const HashTable* table)
    335                         : fTable(table)
    336                 {
    337                         Rewind();
    338                 }
    339 
    340                 Iterator(const HashTable* table, size_t index, ValueType* value)
    341                         : fTable(table), fIndex(index), fNext(value) {}
    342 
    343                 bool HasNext() const { return fNext != NULL; }
    344 
    345                 ValueType* Next()
    346                 {
    347                         ValueType* current = fNext;
    348                         _GetNext();
    349                         return current;
    350                 }
    351 
    352                 void Rewind()
    353                 {
    354                         // get the first one
    355                         fIndex = 0;
    356                         fNext = NULL;
    357                         _GetNext();
    358                 }
    359 
    360         protected:
    361                 Iterator() {}
    362 
    363                 void _GetNext()
    364                 {
    365                         if (fNext)
    366                                 fNext = fTable->_Link(fNext);
    367 
    368                         while (fNext == NULL && fIndex < fTable->fTableSize)
    369                                 fNext = fTable->fTable[fIndex++];
    370                 }
    371 
    372                 const HashTable* fTable;
    373                 size_t fIndex;
    374                 ValueType* fNext;
    375         };
    376 
    377         Iterator GetIterator() const
    378         {
    379                 return Iterator(this);
    380         }
    381 
    382         Iterator GetIterator(const KeyType& key) const
    383         {
    384                 if (fTableSize == 0)
    385                         return Iterator(this, fTableSize, NULL);
    386 
    387                 size_t index = fDefinition.HashKey(key) & (fTableSize - 1);
    388                 ValueType* slot = fTable[index];
    389 
    390                 while (slot) {
    391                         if (fDefinition.Compare(key, slot))
    392                                 break;
    393                         slot = _Link(slot);
    394                 }
    395 
    396                 if (slot == NULL)
    397                         return Iterator(this, fTableSize, NULL);
    398 
    399                 return Iterator(this, index + 1, slot);
    400         }
    401 
    402 protected:
    403         // for g++ 2.95
    404         friend class Iterator;
    405 
    406         void _Insert(ValueType** table, size_t tableSize, ValueType* value)
    407         {
    408                 size_t index = fDefinition.Hash(value) & (tableSize - 1);
    409 
    410                 _Link(value) = table[index];
    411                 table[index] = value;
    412         }
    413 
    414         bool _Resize(size_t newSize)
    415         {
    416                 ValueType** newTable
    417                         = (ValueType**)fAllocator.Allocate(sizeof(ValueType*) * newSize);
    418                 if (newTable == NULL)
    419                         return false;
    420 
    421                 _Resize(newTable, newSize);
    422                 return true;
    423         }
    424 
    425         void _Resize(ValueType** newTable, size_t newSize, void** _oldTable = NULL)
    426         {
    427                 for (size_t i = 0; i < newSize; i++)
    428                         newTable[i] = NULL;
    429 
    430                 if (fTable) {
    431                         for (size_t i = 0; i < fTableSize; i++) {
    432                                 ValueType* bucket = fTable[i];
    433                                 while (bucket) {
    434                                         ValueType* next = _Link(bucket);
    435                                         _Insert(newTable, newSize, bucket);
    436                                         bucket = next;
    437                                 }
    438                         }
    439 
    440                         if (_oldTable != NULL)
    441                                 *_oldTable = fTable;
    442                         else
    443                                 fAllocator.Free(fTable);
    444                 } else if (_oldTable != NULL)
    445                         *_oldTable = NULL;
    446 
    447                 fTableSize = newSize;
    448                 fTable = newTable;
    449         }
    450 
    451         ValueType*& _Link(ValueType* bucket) const
    452         {
    453                 return fDefinition.GetLink(bucket);
    454         }
    455 
    456         bool _ExhaustiveSearch(ValueType* value) const
    457         {
    458                 for (size_t i = 0; i < fTableSize; i++) {
    459                         ValueType* bucket = fTable[i];
    460                         while (bucket) {
    461                                 if (bucket == value)
    462                                         return true;
    463                                 bucket = _Link(bucket);
    464                         }
    465                 }
    466 
    467                 return false;
    468         }
    469 
    470         Definition              fDefinition;
    471         Allocator               fAllocator;
    472         size_t                  fTableSize;
    473         size_t                  fItemCount;
    474         ValueType**             fTable;
    475 };
    476 
    477 #endif  // _KERNEL_UTIL_OPEN_HASH_TABLE_H
     501#endif    // _KERNEL_UTIL_OPEN_HASH_TABLE_H
     502
  • trunk/src/VBox/Additions/haiku/SharedFolders/vboxsf.c

    r43363 r43364  
    5555status_t init_module(void)
    5656{
    57         if (get_module(VBOXGUEST_MODULE_NAME, (module_info **)&g_VBoxGuest) != B_OK) {
    58                 dprintf("get_module(%s) failed\n", VBOXGUEST_MODULE_NAME);
    59                 return B_ERROR;
    60         }
    61 
    62         if (RT_FAILURE(vboxInit())) {
    63                 dprintf("vboxInit failed\n");
    64                 return B_ERROR;
    65         }
    66 
    67         if (RT_FAILURE(vboxConnect(&g_clientHandle))) {
    68                 dprintf("vboxConnect failed\n");
    69                 return B_ERROR;
    70         }
    71 
    72         if (RT_FAILURE(vboxCallSetUtf8(&g_clientHandle))) {
    73                 dprintf("vboxCallSetUtf8 failed\n");
    74                 return B_ERROR;
    75         }
    76 
    77         if (RT_FAILURE(vboxCallSetSymlinks(&g_clientHandle))) {
    78                 dprintf("warning: vboxCallSetSymlinks failed (old vbox?) - symlinks will appear as copies\n");
    79         }
    80 
    81         mutex_init(&g_vnodeCacheLock, "vboxsf vnode cache lock");
    82 
    83         dprintf(FS_NAME ": inited successfully\n");
    84         return B_OK;
     57    if (get_module(VBOXGUEST_MODULE_NAME, (module_info **)&g_VBoxGuest) != B_OK)
     58    {
     59        dprintf("get_module(%s) failed\n", VBOXGUEST_MODULE_NAME);
     60        return B_ERROR;
     61    }
     62
     63    if (RT_FAILURE(vboxInit()))
     64    {
     65        dprintf("vboxInit failed\n");
     66        return B_ERROR;
     67    }
     68
     69    if (RT_FAILURE(vboxConnect(&g_clientHandle)))
     70    {
     71        dprintf("vboxConnect failed\n");
     72        return B_ERROR;
     73    }
     74
     75    if (RT_FAILURE(vboxCallSetUtf8(&g_clientHandle)))
     76    {
     77        dprintf("vboxCallSetUtf8 failed\n");
     78        return B_ERROR;
     79    }
     80
     81    if (RT_FAILURE(vboxCallSetSymlinks(&g_clientHandle)))
     82    {
     83        dprintf("warning: vboxCallSetSymlinks failed (old vbox?) - symlinks will appear as copies\n");
     84    }
     85
     86    mutex_init(&g_vnodeCacheLock, "vboxsf vnode cache lock");
     87
     88    dprintf(FS_NAME ": inited successfully\n");
     89    return B_OK;
    8590}
    8691
    8792void uninit_module(void)
    8893{
    89         mutex_destroy(&g_vnodeCacheLock);
    90         put_module(VBOXGUEST_MODULE_NAME);
    91 }
    92 
    93 PSHFLSTRING make_shflstring(const char* const s) {
    94         int len = strlen(s);
    95         if (len > 0xFFFE) {
    96                 dprintf(FS_NAME ": make_shflstring: string too long\n");
    97                 return NULL;
    98         }
    99 
    100         PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + len);
    101         if (!rv) {
    102                 return NULL;
    103         }
    104 
    105         rv->u16Length = len;
     94    mutex_destroy(&g_vnodeCacheLock);
     95    put_module(VBOXGUEST_MODULE_NAME);
     96}
     97
     98
     99PSHFLSTRING make_shflstring(const char* const s)
     100{
     101    int len = strlen(s);
     102    if (len > 0xFFFE)
     103    {
     104        dprintf(FS_NAME ": make_shflstring: string too long\n");
     105        return NULL;
     106    }
     107
     108    PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + len);
     109    if (!rv)
     110        return NULL;
     111
     112    rv->u16Length = len;
    106113    rv->u16Size = len + 1;
    107114    strcpy(rv->String.utf8, s);
    108         return rv;
    109 }
    110 
    111 PSHFLSTRING clone_shflstring(PSHFLSTRING s) {
    112         PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + s->u16Length);
    113         if (rv)
    114                 memcpy(rv, s, sizeof(SHFLSTRING) + s->u16Length);
    115         return rv;
    116 }
    117 
    118 PSHFLSTRING concat_shflstring_cstr(PSHFLSTRING s1, const char* const s2) {
    119         size_t s2len = strlen(s2);
    120         PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + s1->u16Length + s2len);
    121         if (rv) {
    122                 memcpy(rv, s1, sizeof(SHFLSTRING) + s1->u16Length);
    123                 strcat(rv->String.utf8, s2);
    124                 rv->u16Length += s2len;
    125                 rv->u16Size += s2len;
    126         }
    127         return rv;
    128 }
    129 
    130 PSHFLSTRING concat_cstr_shflstring(const char* const s1, PSHFLSTRING s2) {
    131         size_t s1len = strlen(s1);
    132         PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + s1len + s2->u16Length);
    133         if (rv) {
    134                 strcpy(rv->String.utf8, s1);
    135                 strcat(rv->String.utf8, s2->String.utf8);
    136                 rv->u16Length = s1len + s2->u16Length;
    137                 rv->u16Size = rv->u16Length + 1;
    138         }
    139         return rv;
    140 }
    141 
    142 PSHFLSTRING build_path(vboxsf_vnode* dir, const char* const name) {
    143 
    144         dprintf("*** build_path(%p, %p)\n", dir, name);
    145         if (!dir || !name)
    146                 return NULL;
    147 
    148         size_t len = dir->path->u16Length + strlen(name) + 1;
    149 
    150         PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + len);
    151         if (rv) {
    152                 strcpy(rv->String.utf8, dir->path->String.utf8);
    153                 strcat(rv->String.utf8, "/");
    154                 strcat(rv->String.utf8, name);
    155                 rv->u16Length = len;
    156                 rv->u16Size = rv->u16Length + 1;
    157         }
    158         return rv;
    159 }
    160 
    161 status_t mount(fs_volume *volume, const char *device, uint32 flags, const char *args, ino_t *_rootVnodeID) {
    162         if (device) {
    163                 dprintf(FS_NAME ": trying to mount a real device as a vbox share is silly\n");
    164                 return B_BAD_TYPE;
    165         }
    166 
    167         dprintf(FS_NAME ": mount(%s)\n", args);
    168 
    169         PSHFLSTRING sharename = make_shflstring(args);
    170 
    171         vboxsf_volume* vbsfvolume = malloc(sizeof(vboxsf_volume));
    172         volume->private_volume = vbsfvolume;
    173         int rv = vboxCallMapFolder(&g_clientHandle, sharename, &(vbsfvolume->map));
    174         free(sharename);
    175 
    176         if (rv == 0) {
    177                 vboxsf_vnode* root_vnode;
    178 
    179                 PSHFLSTRING name = make_shflstring("");
    180                 if (!name) {
    181                         dprintf(FS_NAME ": make_shflstring() failed\n");
    182                         return B_NO_MEMORY;
    183                 }
    184 
    185                 status_t rs = vboxsf_new_vnode(&vbsfvolume->map, name, name, &root_vnode);
    186                 dprintf(FS_NAME ": allocated %p (path=%p name=%p)\n", root_vnode, root_vnode->path, root_vnode->name);
    187 
    188                 if (rs != B_OK) {
    189                         dprintf(FS_NAME ": vboxsf_new_vnode() failed (%d)\n", (int)rs);
    190                         return rs;
    191                 }
    192 
    193                 rs = publish_vnode(volume, root_vnode->vnode, root_vnode, &vboxsf_vnode_ops, S_IFDIR, 0);
    194                 dprintf(FS_NAME ": publish_vnode(): %d\n", (int)rs);
    195                 *_rootVnodeID = root_vnode->vnode;
    196                 volume->ops = &vboxsf_volume_ops;
    197                 return B_OK;
    198         }
    199         else {
    200                 dprintf(FS_NAME ": vboxCallMapFolder failed (%d)\n", rv);
    201                 free(volume->private_volume);
    202                 return vbox_err_to_haiku_err(rv);
    203         }
    204 }
    205 
    206 status_t unmount(fs_volume *volume) {
    207         dprintf(FS_NAME ": unmount\n");
    208         vboxCallUnmapFolder(&g_clientHandle, volume->private_volume);
    209         return B_OK;
    210 }
    211 
    212 status_t vboxsf_read_stat(fs_volume* _volume, fs_vnode* _vnode, struct stat* st) {
    213         vboxsf_vnode* vnode = _vnode->private_node;
    214         vboxsf_volume* volume = _volume->private_volume;
    215         SHFLCREATEPARMS params;
    216         int rc;
    217 
    218         dprintf("vboxsf_read_stat (_vnode=%p, vnode=%p, path=%p (%s))\n", _vnode, vnode, vnode->path->String.utf8, vnode->path->String.utf8);
    219 
    220         params.Handle = SHFL_HANDLE_NIL;
    221         params.CreateFlags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;
    222         dprintf("sf_stat: calling vboxCallCreate, file %s, flags %x\n", vnode->path->String.utf8, params.CreateFlags);
    223         rc = vboxCallCreate(&g_clientHandle, &volume->map, vnode->path, &params);
    224         if (rc == VERR_INVALID_NAME)
    225         {
    226                 /* this can happen for names like 'foo*' on a Windows host */
    227                 return B_ENTRY_NOT_FOUND;
    228         }
    229         if (RT_FAILURE(rc))
    230         {
    231                 dprintf("vboxCallCreate: %d\n", params.Result);
    232                 return vbox_err_to_haiku_err(params.Result);
    233         }
    234         if (params.Result != SHFL_FILE_EXISTS)
    235         {
    236                 dprintf("vboxCallCreate: %d\n", params.Result);
    237                 return B_ENTRY_NOT_FOUND;
    238         }
    239 
    240         st->st_dev = 0;
    241         st->st_ino = vnode->vnode;
    242         st->st_mode = mode_from_fmode(params.Info.Attr.fMode);
    243         st->st_nlink = 1;
    244         st->st_uid = 0;
    245         st->st_gid = 0;
    246         st->st_rdev = 0;
    247         st->st_size = params.Info.cbObject;
    248         st->st_blksize = 1;
    249         st->st_blocks = params.Info.cbAllocated;
    250         st->st_atime = RTTimeSpecGetSeconds(&params.Info.AccessTime);
    251         st->st_mtime = RTTimeSpecGetSeconds(&params.Info.ModificationTime);
    252         st->st_ctime = RTTimeSpecGetSeconds(&params.Info.BirthTime);
    253         return B_OK;
    254 }
    255 
    256 status_t vboxsf_open_dir(fs_volume* _volume, fs_vnode* _vnode, void** _cookie) {
    257         vboxsf_volume* volume = _volume->private_volume;
    258         vboxsf_vnode* vnode = _vnode->private_node;
    259         SHFLCREATEPARMS params;
    260 
    261         RT_ZERO(params);
    262         params.Handle = SHFL_HANDLE_NIL;
    263         params.CreateFlags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_OPEN_IF_EXISTS
    264                 | SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_READ;
    265 
    266         int rc = vboxCallCreate(&g_clientHandle, &volume->map, vnode->path, &params);
    267         if (RT_SUCCESS(rc)) {
    268                 if (params.Result == SHFL_FILE_EXISTS && params.Handle != SHFL_HANDLE_NIL) {
    269                         vboxsf_dir_cookie* cookie = malloc(sizeof(vboxsf_dir_cookie));
    270                         *_cookie = cookie;
    271                         cookie->index = 0;
    272                         cookie->path = build_path(vnode, "*");
    273                         cookie->handle = params.Handle;
    274                         cookie->has_more_files = true;
    275                         cookie->buffer_start = cookie->buffer = NULL;
    276                         cookie->buffer_length = cookie->num_files = 0;
    277                         return B_OK;
    278                 }
    279                 else {
    280                         return B_ENTRY_NOT_FOUND;
    281                 }
    282         }
    283         else {
    284                 dprintf(FS_NAME ": vboxCallCreate: %d\n", rc);
    285                 return vbox_err_to_haiku_err(rc);
    286         }
    287 }
     115    return rv;
     116}
     117
     118
     119PSHFLSTRING clone_shflstring(PSHFLSTRING s)
     120{
     121    PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + s->u16Length);
     122    if (rv)
     123        memcpy(rv, s, sizeof(SHFLSTRING) + s->u16Length);
     124    return rv;
     125}
     126
     127PSHFLSTRING concat_shflstring_cstr(PSHFLSTRING s1, const char* const s2)
     128{
     129    size_t s2len = strlen(s2);
     130    PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + s1->u16Length + s2len);
     131    if (rv)
     132    {
     133        memcpy(rv, s1, sizeof(SHFLSTRING) + s1->u16Length);
     134        strcat(rv->String.utf8, s2);
     135        rv->u16Length += s2len;
     136        rv->u16Size += s2len;
     137    }
     138    return rv;
     139}
     140
     141
     142PSHFLSTRING concat_cstr_shflstring(const char* const s1, PSHFLSTRING s2)
     143{
     144    size_t s1len = strlen(s1);
     145    PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + s1len + s2->u16Length);
     146    if (rv)
     147    {
     148        strcpy(rv->String.utf8, s1);
     149        strcat(rv->String.utf8, s2->String.utf8);
     150        rv->u16Length = s1len + s2->u16Length;
     151        rv->u16Size = rv->u16Length + 1;
     152    }
     153    return rv;
     154}
     155
     156
     157PSHFLSTRING build_path(vboxsf_vnode* dir, const char* const name)
     158{
     159
     160    dprintf("*** build_path(%p, %p)\n", dir, name);
     161    if (!dir || !name)
     162        return NULL;
     163
     164    size_t len = dir->path->u16Length + strlen(name) + 1;
     165    PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + len);
     166    if (rv)
     167    {
     168        strcpy(rv->String.utf8, dir->path->String.utf8);
     169        strcat(rv->String.utf8, "/");
     170        strcat(rv->String.utf8, name);
     171        rv->u16Length = len;
     172        rv->u16Size = rv->u16Length + 1;
     173    }
     174    return rv;
     175}
     176
     177
     178status_t mount(fs_volume *volume, const char *device, uint32 flags, const char *args, ino_t *_rootVnodeID)
     179{
     180    if (device)
     181    {
     182        dprintf(FS_NAME ": trying to mount a real device as a vbox share is silly\n");
     183        return B_BAD_TYPE;
     184    }
     185
     186    dprintf(FS_NAME ": mount(%s)\n", args);
     187
     188    PSHFLSTRING sharename = make_shflstring(args);
     189
     190    vboxsf_volume* vbsfvolume = malloc(sizeof(vboxsf_volume));
     191    volume->private_volume = vbsfvolume;
     192    int rv = vboxCallMapFolder(&g_clientHandle, sharename, &(vbsfvolume->map));
     193    free(sharename);
     194
     195    if (rv == 0)
     196    {
     197        vboxsf_vnode* root_vnode;
     198
     199        PSHFLSTRING name = make_shflstring("");
     200        if (!name)
     201        {
     202            dprintf(FS_NAME ": make_shflstring() failed\n");
     203            return B_NO_MEMORY;
     204        }
     205
     206        status_t rs = vboxsf_new_vnode(&vbsfvolume->map, name, name, &root_vnode);
     207        dprintf(FS_NAME ": allocated %p (path=%p name=%p)\n", root_vnode, root_vnode->path, root_vnode->name);
     208
     209        if (rs != B_OK)
     210        {
     211            dprintf(FS_NAME ": vboxsf_new_vnode() failed (%d)\n", (int)rs);
     212            return rs;
     213        }
     214
     215        rs = publish_vnode(volume, root_vnode->vnode, root_vnode, &vboxsf_vnode_ops, S_IFDIR, 0);
     216        dprintf(FS_NAME ": publish_vnode(): %d\n", (int)rs);
     217        *_rootVnodeID = root_vnode->vnode;
     218        volume->ops = &vboxsf_volume_ops;
     219        return B_OK;
     220    }
     221    else
     222    {
     223        dprintf(FS_NAME ": vboxCallMapFolder failed (%d)\n", rv);
     224        free(volume->private_volume);
     225        return vbox_err_to_haiku_err(rv);
     226    }
     227}
     228
     229
     230status_t unmount(fs_volume *volume)
     231{
     232    dprintf(FS_NAME ": unmount\n");
     233    vboxCallUnmapFolder(&g_clientHandle, volume->private_volume);
     234    return B_OK;
     235}
     236
     237
     238status_t vboxsf_read_stat(fs_volume* _volume, fs_vnode* _vnode, struct stat* st)
     239{
     240    vboxsf_vnode* vnode = _vnode->private_node;
     241    vboxsf_volume* volume = _volume->private_volume;
     242    SHFLCREATEPARMS params;
     243    int rc;
     244
     245    dprintf("vboxsf_read_stat (_vnode=%p, vnode=%p, path=%p (%s))\n", _vnode, vnode, vnode->path->String.utf8, vnode->path->String.utf8);
     246
     247    params.Handle = SHFL_HANDLE_NIL;
     248    params.CreateFlags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;
     249    dprintf("sf_stat: calling vboxCallCreate, file %s, flags %x\n", vnode->path->String.utf8, params.CreateFlags);
     250    rc = vboxCallCreate(&g_clientHandle, &volume->map, vnode->path, &params);
     251    if (rc == VERR_INVALID_NAME)
     252    {
     253        /* this can happen for names like 'foo*' on a Windows host */
     254        return B_ENTRY_NOT_FOUND;
     255    }
     256    if (RT_FAILURE(rc))
     257    {
     258        dprintf("vboxCallCreate: %d\n", params.Result);
     259        return vbox_err_to_haiku_err(params.Result);
     260    }
     261    if (params.Result != SHFL_FILE_EXISTS)
     262    {
     263        dprintf("vboxCallCreate: %d\n", params.Result);
     264        return B_ENTRY_NOT_FOUND;
     265    }
     266
     267    st->st_dev = 0;
     268    st->st_ino = vnode->vnode;
     269    st->st_mode = mode_from_fmode(params.Info.Attr.fMode);
     270    st->st_nlink = 1;
     271    st->st_uid = 0;
     272    st->st_gid = 0;
     273    st->st_rdev = 0;
     274    st->st_size = params.Info.cbObject;
     275    st->st_blksize = 1;
     276    st->st_blocks = params.Info.cbAllocated;
     277    st->st_atime = RTTimeSpecGetSeconds(&params.Info.AccessTime);
     278    st->st_mtime = RTTimeSpecGetSeconds(&params.Info.ModificationTime);
     279    st->st_ctime = RTTimeSpecGetSeconds(&params.Info.BirthTime);
     280    return B_OK;
     281}
     282
     283
     284status_t vboxsf_open_dir(fs_volume* _volume, fs_vnode* _vnode, void** _cookie)
     285{
     286    vboxsf_volume* volume = _volume->private_volume;
     287    vboxsf_vnode* vnode = _vnode->private_node;
     288    SHFLCREATEPARMS params;
     289
     290    RT_ZERO(params);
     291    params.Handle = SHFL_HANDLE_NIL;
     292    params.CreateFlags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_OPEN_IF_EXISTS
     293        | SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_READ;
     294
     295    int rc = vboxCallCreate(&g_clientHandle, &volume->map, vnode->path, &params);
     296    if (RT_SUCCESS(rc))
     297    {
     298        if (params.Result == SHFL_FILE_EXISTS && params.Handle != SHFL_HANDLE_NIL)
     299        {
     300            vboxsf_dir_cookie* cookie = malloc(sizeof(vboxsf_dir_cookie));
     301            *_cookie = cookie;
     302            cookie->index = 0;
     303            cookie->path = build_path(vnode, "*");
     304            cookie->handle = params.Handle;
     305            cookie->has_more_files = true;
     306            cookie->buffer_start = cookie->buffer = NULL;
     307            cookie->buffer_length = cookie->num_files = 0;
     308            return B_OK;
     309        }
     310        else
     311            return B_ENTRY_NOT_FOUND;
     312    }
     313    else
     314    {
     315        dprintf(FS_NAME ": vboxCallCreate: %d\n", rc);
     316        return vbox_err_to_haiku_err(rc);
     317    }
     318}
     319
    288320
    289321/** read a single entry from a dir */
    290322status_t vboxsf_read_dir_1(vboxsf_volume* volume, vboxsf_vnode* vnode, vboxsf_dir_cookie* cookie,
    291         struct dirent* buffer, size_t bufferSize) {
    292         dprintf("%p, %d, %p\n", cookie, cookie->has_more_files, cookie->buffer);
    293         if (!cookie->has_more_files) {
    294                 return B_ENTRY_NOT_FOUND;
    295         }
    296         if (!cookie->buffer) {
    297                 cookie->buffer_length = 16384;
    298                 cookie->buffer_start = cookie->buffer = malloc(cookie->buffer_length);
    299 
    300                 int rc = vboxCallDirInfo(&g_clientHandle, &volume->map, cookie->handle, cookie->path,
    301                         0, cookie->index, &cookie->buffer_length, cookie->buffer, &cookie->num_files);
    302 
    303                 if (rc != 0 && rc != VERR_NO_MORE_FILES) {
    304                         dprintf(FS_NAME ": vboxCallDirInfo failed: %d\n", rc);
    305                         free(cookie->buffer_start);
    306                         cookie->buffer_start = NULL;
    307                         return vbox_err_to_haiku_err(rc);
    308                 }
    309 
    310                 if (rc == VERR_NO_MORE_FILES) {
    311                         free(cookie->buffer_start);
    312                         cookie->buffer_start = NULL;
    313                         cookie->has_more_files = false;
    314                         return B_ENTRY_NOT_FOUND;
    315                 }
    316         }
    317 
    318         if (bufferSize <= sizeof(struct dirent) + cookie->buffer->name.u16Length) {
    319                 dprintf("hit end of buffer\n");
    320                 return B_BUFFER_OVERFLOW;
    321         }
    322 
    323         PSHFLSTRING name1 = clone_shflstring(&cookie->buffer->name);
    324         if (!name1) {
    325                 dprintf(FS_NAME ": make_shflstring() failed\n");
    326                 return B_NO_MEMORY;
    327         }
    328 
    329         vboxsf_vnode* new_vnode;
    330         int rv = vboxsf_new_vnode(&volume->map, build_path(vnode, name1->String.utf8), name1, &new_vnode);
    331         if (rv != B_OK) {
    332                 dprintf(FS_NAME ": vboxsf_new_vnode() failed\n");
    333                 return rv;
    334         }
    335         buffer->d_dev = 0;
    336         buffer->d_pdev = 0;
    337         buffer->d_ino = new_vnode->vnode;
    338         buffer->d_pino = vnode->vnode;
    339         buffer->d_reclen = sizeof(struct dirent) + cookie->buffer->name.u16Length;
    340         strncpy(buffer->d_name, cookie->buffer->name.String.utf8, NAME_MAX);
    341 
    342         size_t size = offsetof(SHFLDIRINFO, name.String) + cookie->buffer->name.u16Size;
    343         cookie->buffer = ((void*)cookie->buffer + size);
    344         cookie->index++;
    345 
    346         if (cookie->index >= cookie->num_files) {
    347                 // hit end of this buffer, next call will reallocate a new one
    348                 free(cookie->buffer_start);
    349                 cookie->buffer_start = cookie->buffer = NULL;
    350         }
    351         return B_OK;
    352 }
     323    struct dirent* buffer, size_t bufferSize)
     324{
     325    dprintf("%p, %d, %p\n", cookie, cookie->has_more_files, cookie->buffer);
     326    if (!cookie->has_more_files)
     327        return B_ENTRY_NOT_FOUND;
     328
     329    if (!cookie->buffer)
     330    {
     331        cookie->buffer_length = 16384;
     332        cookie->buffer_start = cookie->buffer = malloc(cookie->buffer_length);
     333
     334        int rc = vboxCallDirInfo(&g_clientHandle, &volume->map, cookie->handle, cookie->path,
     335            0, cookie->index, &cookie->buffer_length, cookie->buffer, &cookie->num_files);
     336
     337        if (rc != 0 && rc != VERR_NO_MORE_FILES)
     338        {
     339            dprintf(FS_NAME ": vboxCallDirInfo failed: %d\n", rc);
     340            free(cookie->buffer_start);
     341            cookie->buffer_start = NULL;
     342            return vbox_err_to_haiku_err(rc);
     343        }
     344
     345        if (rc == VERR_NO_MORE_FILES)
     346        {
     347            free(cookie->buffer_start);
     348            cookie->buffer_start = NULL;
     349            cookie->has_more_files = false;
     350            return B_ENTRY_NOT_FOUND;
     351        }
     352    }
     353
     354    if (bufferSize <= sizeof(struct dirent) + cookie->buffer->name.u16Length)
     355    {
     356        dprintf("hit end of buffer\n");
     357        return B_BUFFER_OVERFLOW;
     358    }
     359
     360    PSHFLSTRING name1 = clone_shflstring(&cookie->buffer->name);
     361    if (!name1)
     362    {
     363        dprintf(FS_NAME ": make_shflstring() failed\n");
     364        return B_NO_MEMORY;
     365    }
     366
     367    vboxsf_vnode* new_vnode;
     368    int rv = vboxsf_new_vnode(&volume->map, build_path(vnode, name1->String.utf8), name1, &new_vnode);
     369    if (rv != B_OK)
     370    {
     371        dprintf(FS_NAME ": vboxsf_new_vnode() failed\n");
     372        return rv;
     373    }
     374    buffer->d_dev = 0;
     375    buffer->d_pdev = 0;
     376    buffer->d_ino = new_vnode->vnode;
     377    buffer->d_pino = vnode->vnode;
     378    buffer->d_reclen = sizeof(struct dirent) + cookie->buffer->name.u16Length;
     379    strncpy(buffer->d_name, cookie->buffer->name.String.utf8, NAME_MAX);
     380
     381    size_t size = offsetof(SHFLDIRINFO, name.String) + cookie->buffer->name.u16Size;
     382    cookie->buffer = ((void*)cookie->buffer + size);
     383    cookie->index++;
     384
     385    if (cookie->index >= cookie->num_files)
     386    {
     387        // hit end of this buffer, next call will reallocate a new one
     388        free(cookie->buffer_start);
     389        cookie->buffer_start = cookie->buffer = NULL;
     390    }
     391    return B_OK;
     392}
     393
    353394
    354395status_t vboxsf_read_dir(fs_volume* _volume, fs_vnode* _vnode, void* _cookie,
    355         struct dirent* buffer, size_t bufferSize, uint32* _num) {
    356         vboxsf_dir_cookie* cookie = _cookie;
    357         vboxsf_volume* volume = _volume->private_volume;
    358         vboxsf_vnode* vnode = _vnode->private_node;
    359         uint32 num_read = 0;
    360         status_t rv = B_OK;
    361 
    362         for (num_read = 0; num_read < *_num && cookie->has_more_files; num_read++) {
    363                 rv = vboxsf_read_dir_1(volume, vnode, cookie, buffer, bufferSize);
    364                 if (rv == B_BUFFER_OVERFLOW || rv == B_ENTRY_NOT_FOUND) {
    365                         // hit end of at least one of the buffers - not really an error
    366                         rv = B_OK;
    367                         break;
    368                 }
    369                 bufferSize -= buffer->d_reclen;
    370                 buffer = ((void*)(buffer)) + buffer->d_reclen;
    371         }
    372 
    373         *_num = num_read;
    374         return rv;
    375 }
    376 
    377 status_t vboxsf_free_dir_cookie(fs_volume* _volume, fs_vnode* vnode, void* _cookie) {
    378         vboxsf_volume* volume = _volume->private_volume;
    379         vboxsf_dir_cookie* cookie = _cookie;
    380 
    381         vboxCallClose(&g_clientHandle, &volume->map, cookie->handle);
    382         free(cookie->path);
    383         free(cookie);
    384 
    385         return B_OK;
    386 }
    387 
    388 status_t vboxsf_read_fs_info(fs_volume* _volume, struct fs_info* info) {
    389         vboxsf_volume* volume = _volume->private_volume;
    390 
    391         SHFLVOLINFO volume_info;
    392         uint32_t bytes = sizeof(SHFLVOLINFO);
    393 
    394         int rc = vboxCallFSInfo(&g_clientHandle, &volume->map, 0,
    395                 (SHFL_INFO_GET | SHFL_INFO_VOLUME), &bytes, (PSHFLDIRINFO)&volume_info);
    396 
    397         if (RT_FAILURE(rc)) {
    398                 dprintf(FS_NAME ": vboxCallFSInfo failed (%d)\n", rc);
    399                 return vbox_err_to_haiku_err(rc);
    400         }
    401 
    402         info->flags = B_FS_IS_PERSISTENT;
    403         if (volume_info.fsProperties.fReadOnly)
    404                 info->flags |= B_FS_IS_READONLY;
    405 
    406         info->dev = 0;
    407         info->root = 1;
    408         info->block_size = volume_info.ulBytesPerAllocationUnit;
    409         info->io_size = volume_info.ulBytesPerAllocationUnit;
    410         info->total_blocks = volume_info.ullTotalAllocationBytes / info->block_size;
    411         info->free_blocks = volume_info.ullAvailableAllocationBytes / info->block_size;
    412         info->total_nodes = LONGLONG_MAX;
    413         info->free_nodes = LONGLONG_MAX;
    414         strcpy(info->volume_name, "VBox share");
    415         return B_OK;
    416 }
    417 
    418 status_t vboxsf_lookup(fs_volume* _volume, fs_vnode* dir, const char* name, ino_t* _id) {
    419         dprintf(FS_NAME ": lookup %s\n", name);
    420         vboxsf_volume* volume = _volume->private_volume;
    421         SHFLCREATEPARMS params;
    422 
    423         RT_ZERO(params);
    424         params.Handle = SHFL_HANDLE_NIL;
    425         params.CreateFlags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;
    426 
    427         PSHFLSTRING path = build_path(dir->private_node, name);
    428         if (!path) {
    429                 dprintf(FS_NAME ": make_shflstring() failed\n");
    430                 return B_NO_MEMORY;
    431         }
    432 
    433         int rc = vboxCallCreate(&g_clientHandle, &volume->map, path, &params);
    434         if (RT_SUCCESS(rc)) {
    435                 if (params.Result == SHFL_FILE_EXISTS) {
    436                         vboxsf_vnode* vn;
    437                         status_t rv = vboxsf_new_vnode(&volume->map, path, path, &vn);
    438                         if (rv == B_OK) {
    439                                 *_id = vn->vnode;
    440                                 rv = publish_vnode(_volume, vn->vnode, vn, &vboxsf_vnode_ops, mode_from_fmode(params.Info.Attr.fMode), 0);
    441                         }
    442                         return rv;
    443                 }
    444                 else {
    445                         free(path);
    446                         return B_ENTRY_NOT_FOUND;
    447                 }
    448         }
    449         else {
    450                 free(path);
    451                 dprintf(FS_NAME ": vboxCallCreate: %d\n", rc);
    452                 return vbox_err_to_haiku_err(rc);
    453         }
    454 }
    455 
    456 mode_t mode_from_fmode(RTFMODE fMode) {
    457         mode_t m = 0;
    458 
    459         if (RTFS_IS_DIRECTORY(fMode))
    460                 m |= S_IFDIR;
    461         else if (RTFS_IS_FILE(fMode))
    462                 m |= S_IFREG;
    463         else if (RTFS_IS_FIFO(fMode))
    464                 m |= S_IFIFO;
    465         else if (RTFS_IS_DEV_CHAR(fMode))
    466                 m |= S_IFCHR;
    467         else if (RTFS_IS_DEV_BLOCK(fMode))
    468                 m |= S_IFBLK;
    469         else if (RTFS_IS_SYMLINK(fMode))
    470                 m |= S_IFLNK;
    471         else if (RTFS_IS_SOCKET(fMode))
    472                 m |= S_IFSOCK;
    473 
    474         if (fMode & RTFS_UNIX_IRUSR)
    475                 m |= S_IRUSR;
    476         if (fMode & RTFS_UNIX_IWUSR)
    477                 m |= S_IWUSR;
    478         if (fMode & RTFS_UNIX_IXUSR)
    479                 m |= S_IXUSR;
    480         if (fMode & RTFS_UNIX_IRGRP)
    481                 m |= S_IRGRP;
    482         if (fMode & RTFS_UNIX_IWGRP)
    483                 m |= S_IWGRP;
    484         if (fMode & RTFS_UNIX_IXGRP)
    485                 m |= S_IXGRP;
    486         if (fMode & RTFS_UNIX_IROTH)
    487                 m |= S_IROTH;
    488         if (fMode & RTFS_UNIX_IWOTH)
    489                 m |= S_IWOTH;
    490         if (fMode & RTFS_UNIX_IXOTH)
    491                 m |= S_IXOTH;
    492         if (fMode & RTFS_UNIX_ISUID)
    493                 m |= S_ISUID;
    494         if (fMode & RTFS_UNIX_ISGID)
    495                 m |= S_ISGID;
    496         if (fMode & RTFS_UNIX_ISTXT)
    497                 m |= S_ISVTX;
    498 
    499         return m;
    500 }
    501 
    502 status_t vboxsf_open(fs_volume* _volume, fs_vnode* _vnode, int openMode, void** _cookie) {
    503         vboxsf_volume* volume = _volume->private_volume;
    504         vboxsf_vnode* vnode = _vnode->private_node;
    505 
    506         dprintf(FS_NAME ": open %s (mode=%x)\n", vnode->path->String.utf8, openMode);
    507 
    508         SHFLCREATEPARMS params;
    509 
    510         RT_ZERO(params);
    511         params.Handle = SHFL_HANDLE_NIL;
    512 
    513         if (openMode & O_RDWR)
    514                 params.CreateFlags |= SHFL_CF_ACCESS_READWRITE;
    515         else if (openMode & O_RDONLY)
    516                 params.CreateFlags |= SHFL_CF_ACCESS_READ;
    517         else if (openMode & O_WRONLY)
    518                 params.CreateFlags |= SHFL_CF_ACCESS_WRITE;
    519 
    520         if (openMode & O_APPEND)
    521                 params.CreateFlags |= SHFL_CF_ACCESS_APPEND;
    522 
    523         if (openMode & O_CREAT) {
    524                 params.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW;
    525                 if (openMode & O_EXCL)
    526                         params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS;
    527                 else if (openMode & O_TRUNC)
    528                         params.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
    529                 else
    530                         params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
    531         }
    532         else {
    533                 params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW;
    534                 if (openMode & O_TRUNC)
    535                         params.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
    536                 else
    537                         params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
    538         }
    539 
    540         int rc = vboxCallCreate(&g_clientHandle, &volume->map, vnode->path, &params);
    541         if (!RT_SUCCESS(rc)) {
    542                 dprintf("vboxCallCreate returned %d\n", rc);
    543                 return vbox_err_to_haiku_err(rc);
    544         }
    545 
    546         vboxsf_file_cookie* cookie = malloc(sizeof(vboxsf_file_cookie));
    547         if (!cookie) {
    548                 dprintf("couldn't allocate file cookie\n");
    549                 return B_NO_MEMORY;
    550         }
    551 
    552         cookie->handle = params.Handle;
    553         cookie->path = vnode->path;
    554 
    555         *_cookie = cookie;
    556 
    557         return B_OK;
    558 }
    559 
    560 status_t vboxsf_create(fs_volume* _volume, fs_vnode* _dir, const char *name, int openMode, int perms, void **_cookie, ino_t *_newVnodeID) {
    561         vboxsf_volume* volume = _volume->private_volume;
    562 
    563         SHFLCREATEPARMS params;
    564 
    565         RT_ZERO(params);
    566         params.Handle = SHFL_HANDLE_NIL;
    567 
    568         if (openMode & O_RDWR)
    569                 params.CreateFlags |= SHFL_CF_ACCESS_READWRITE;
    570         else if (openMode & O_RDONLY)
    571                 params.CreateFlags |= SHFL_CF_ACCESS_READ;
    572         else if (openMode & O_WRONLY)
    573                 params.CreateFlags |= SHFL_CF_ACCESS_WRITE;
    574 
    575         if (openMode & O_APPEND)
    576                 params.CreateFlags |= SHFL_CF_ACCESS_APPEND;
    577 
    578         if (openMode & O_CREAT) {
    579                 params.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW;
    580                 if (openMode & O_EXCL)
    581                         params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS;
    582                 else if (openMode & O_TRUNC)
    583                         params.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
    584                 else
    585                         params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
    586         }
    587         else {
    588                 params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW;
    589                 if (openMode & O_TRUNC)
    590                         params.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
    591                 else
    592                         params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
    593         }
    594 
    595         PSHFLSTRING path = build_path(_dir->private_node, name);
    596         int rc = vboxCallCreate(&g_clientHandle, &volume->map, path, &params);
    597 
    598         if (!RT_SUCCESS(rc)) {
    599                 dprintf("vboxCallCreate returned %d\n", rc);
    600                 free(path);
    601                 return vbox_err_to_haiku_err(rc);
    602         }
    603 
    604         vboxsf_file_cookie* cookie = malloc(sizeof(vboxsf_file_cookie));
    605         if (!cookie) {
    606                 dprintf("couldn't allocate file cookie\n");
    607                 free(path);
    608                 return B_NO_MEMORY;
    609         }
    610 
    611         cookie->handle = params.Handle;
    612         cookie->path = path;
    613 
    614         *_cookie = cookie;
    615         return vboxsf_lookup(_volume, _dir, name, _newVnodeID);
    616 }
    617 
    618 status_t vboxsf_close(fs_volume* _volume, fs_vnode* _vnode, void* _cookie) {
    619         vboxsf_volume* volume = _volume->private_volume;
    620         vboxsf_file_cookie* cookie = _cookie;
    621 
    622         int rc = vboxCallClose(&g_clientHandle, &volume->map, cookie->handle);
    623         dprintf("vboxCallClose returned %d\n", rc);
    624         return vbox_err_to_haiku_err(rc);
    625 }
    626 
    627 status_t vboxsf_rewind_dir(fs_volume* _volume, fs_vnode* _vnode, void* _cookie) {
    628         vboxsf_dir_cookie* cookie = _cookie;
    629         cookie->index = 0;
    630         return B_OK;
    631 }
    632 
    633 status_t vboxsf_close_dir(fs_volume *volume, fs_vnode *vnode, void *cookie) {
    634         return B_OK;
    635 }
    636 
    637 status_t vboxsf_free_cookie(fs_volume *volume, fs_vnode *vnode, void *_cookie) {
    638         vboxsf_dir_cookie* cookie = _cookie;
    639         free(cookie);
    640         return B_OK;
    641 }
    642 
    643 status_t vboxsf_read(fs_volume* _volume, fs_vnode* _vnode, void* _cookie, off_t pos, void *buffer, size_t *length) {
    644         vboxsf_volume* volume = _volume->private_volume;
    645         vboxsf_vnode* vnode = _vnode->private_node;
    646         vboxsf_file_cookie* cookie = _cookie;
    647 
    648         if (*length > 0xFFFFFFFF) {
    649                 *length = 0xFFFFFFFF;
    650         }
    651 
    652         uint32_t l = *length;
    653         void* other_buffer = malloc(l); // TODO map the user memory into kernel space here for efficiency
    654         int rc = vboxCallRead(&g_clientHandle, &volume->map, cookie->handle, pos, &l, other_buffer, false);
    655         memcpy(buffer, other_buffer, l);
    656         free(other_buffer);
    657 
    658         dprintf("vboxCallRead returned %d\n", rc);
    659         *length = l;
    660         return vbox_err_to_haiku_err(rc);
    661 }
    662 
    663 status_t vboxsf_write(fs_volume* _volume, fs_vnode* _vnode, void* _cookie, off_t pos, const void *buffer, size_t *length) {
    664         vboxsf_volume* volume = _volume->private_volume;
    665         vboxsf_vnode* vnode = _vnode->private_node;
    666         vboxsf_file_cookie* cookie = _cookie;
    667 
    668         if (*length > 0xFFFFFFFF) {
    669                 *length = 0xFFFFFFFF;
    670         }
    671 
    672         uint32_t l = *length;
    673         void* other_buffer = malloc(l); // TODO map the user memory into kernel space here for efficiency
    674         memcpy(other_buffer, buffer, l);
    675         int rc = vboxCallWrite(&g_clientHandle, &volume->map, cookie->handle, pos, &l, other_buffer, false);
    676         free(other_buffer);
    677 
    678         *length = l;
    679         return vbox_err_to_haiku_err(rc);
    680 }
    681 
    682 status_t vboxsf_write_stat(fs_volume *volume, fs_vnode *vnode, const struct stat *stat, uint32 statMask) {
    683         // the host handles updating the stat info - in the guest, this is a no-op
    684         return B_OK;
    685 }
    686 
    687 status_t vboxsf_create_dir(fs_volume *_volume, fs_vnode *parent, const char *name, int perms) {
    688         vboxsf_volume* volume = _volume->private_volume;
    689 
    690         SHFLCREATEPARMS params;
    691         params.Handle = 0;
    692         params.Info.cbObject = 0;
    693         params.CreateFlags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_CREATE_IF_NEW |
    694             SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACCESS_READ;
    695 
    696         PSHFLSTRING path = build_path(parent->private_node, name);
    697         int rc = vboxCallCreate(&g_clientHandle, &volume->map, path, &params);
    698         free(path);
    699         if (params.Handle == SHFL_HANDLE_NIL) {
    700                 return vbox_err_to_haiku_err(rc);
    701         }
    702         else {
    703                 vboxCallClose(&g_clientHandle, &volume->map, params.Handle);
    704                 return B_OK;
    705         }
    706 }
    707 
    708 status_t vboxsf_remove_dir(fs_volume *_volume, fs_vnode *parent, const char *name) {
    709         vboxsf_volume* volume = _volume->private_volume;
    710 
    711         PSHFLSTRING path = build_path(parent->private_node, name);
    712         int rc = vboxCallRemove(&g_clientHandle, &volume->map, path, SHFL_REMOVE_DIR);
    713         free(path);
    714 
    715         return vbox_err_to_haiku_err(rc);
    716 }
    717 
    718 status_t vboxsf_unlink(fs_volume *_volume, fs_vnode *parent, const char *name) {
    719         vboxsf_volume* volume = _volume->private_volume;
    720 
    721         PSHFLSTRING path = build_path(parent->private_node, name);
    722         int rc = vboxCallRemove(&g_clientHandle, &volume->map, path, SHFL_REMOVE_FILE);
    723         free(path);
    724 
    725         return vbox_err_to_haiku_err(rc);
    726 }
    727 
    728 status_t vboxsf_link(fs_volume *volume, fs_vnode *dir, const char *name, fs_vnode *vnode) {
    729         return B_UNSUPPORTED;
    730 }
    731 
    732 status_t vboxsf_rename(fs_volume* _volume, fs_vnode* fromDir, const char* fromName, fs_vnode* toDir, const char* toName) {
    733         vboxsf_volume* volume = _volume->private_volume;
    734 
    735         PSHFLSTRING oldpath = build_path(fromDir->private_node, fromName);
    736         PSHFLSTRING newpath = build_path(toDir->private_node, toName);
    737         int rc = vboxCallRename(&g_clientHandle, &volume->map, oldpath, newpath, SHFL_RENAME_FILE | SHFL_RENAME_REPLACE_IF_EXISTS);
    738         free(oldpath);
    739         free(newpath);
    740 
    741         return vbox_err_to_haiku_err(rc);
    742 }
    743 
    744 status_t vboxsf_create_symlink(fs_volume* _volume, fs_vnode* dir, const char* name, const char* path, int mode) {
    745         vboxsf_volume* volume = _volume->private_volume;
    746 
    747         PSHFLSTRING target = make_shflstring(path);
    748         PSHFLSTRING linkpath = build_path(dir->private_node, name);
    749         SHFLFSOBJINFO stuff;
    750         RT_ZERO(stuff);
    751 
    752         int rc = vboxCallSymlink(&g_clientHandle, &volume->map, linkpath, target, &stuff);
    753 
    754         free(target);
    755         free(linkpath);
    756 
    757         return vbox_err_to_haiku_err(rc);
    758 }
    759 
    760 status_t vboxsf_read_symlink(fs_volume* _volume, fs_vnode* link, char* buffer, size_t* _bufferSize) {
    761         vboxsf_volume* volume = _volume->private_volume;
    762         vboxsf_vnode* vnode = link->private_node;
    763 
    764         int rc = vboxReadLink(&g_clientHandle, &volume->map, vnode->path, *_bufferSize, buffer);
    765         *_bufferSize = strlen(buffer);
    766 
    767         return vbox_err_to_haiku_err(rc);
    768 }
     396    struct dirent* buffer, size_t bufferSize, uint32* _num)
     397{
     398    vboxsf_dir_cookie* cookie = _cookie;
     399    vboxsf_volume* volume = _volume->private_volume;
     400    vboxsf_vnode* vnode = _vnode->private_node;
     401    uint32 num_read = 0;
     402    status_t rv = B_OK;
     403
     404    for (num_read = 0; num_read < *_num && cookie->has_more_files; num_read++)
     405    {
     406        rv = vboxsf_read_dir_1(volume, vnode, cookie, buffer, bufferSize);
     407        if (rv == B_BUFFER_OVERFLOW || rv == B_ENTRY_NOT_FOUND)
     408        {
     409            // hit end of at least one of the buffers - not really an error
     410            rv = B_OK;
     411            break;
     412        }
     413        bufferSize -= buffer->d_reclen;
     414        buffer = ((void*)(buffer)) + buffer->d_reclen;
     415    }
     416
     417    *_num = num_read;
     418    return rv;
     419}
     420
     421
     422status_t vboxsf_free_dir_cookie(fs_volume* _volume, fs_vnode* vnode, void* _cookie)
     423{
     424    vboxsf_volume* volume = _volume->private_volume;
     425    vboxsf_dir_cookie* cookie = _cookie;
     426
     427    vboxCallClose(&g_clientHandle, &volume->map, cookie->handle);
     428    free(cookie->path);
     429    free(cookie);
     430
     431    return B_OK;
     432}
     433
     434
     435status_t vboxsf_read_fs_info(fs_volume* _volume, struct fs_info* info)
     436{
     437    vboxsf_volume* volume = _volume->private_volume;
     438
     439    SHFLVOLINFO volume_info;
     440    uint32_t bytes = sizeof(SHFLVOLINFO);
     441
     442    int rc = vboxCallFSInfo(&g_clientHandle, &volume->map, 0,
     443        (SHFL_INFO_GET | SHFL_INFO_VOLUME), &bytes, (PSHFLDIRINFO)&volume_info);
     444
     445    if (RT_FAILURE(rc))
     446    {
     447        dprintf(FS_NAME ": vboxCallFSInfo failed (%d)\n", rc);
     448        return vbox_err_to_haiku_err(rc);
     449    }
     450
     451    info->flags = B_FS_IS_PERSISTENT;
     452    if (volume_info.fsProperties.fReadOnly)
     453        info->flags |= B_FS_IS_READONLY;
     454
     455    info->dev = 0;
     456    info->root = 1;
     457    info->block_size = volume_info.ulBytesPerAllocationUnit;
     458    info->io_size = volume_info.ulBytesPerAllocationUnit;
     459    info->total_blocks = volume_info.ullTotalAllocationBytes / info->block_size;
     460    info->free_blocks = volume_info.ullAvailableAllocationBytes / info->block_size;
     461    info->total_nodes = LONGLONG_MAX;
     462    info->free_nodes = LONGLONG_MAX;
     463    strcpy(info->volume_name, "VBox share");
     464    return B_OK;
     465}
     466
     467
     468status_t vboxsf_lookup(fs_volume* _volume, fs_vnode* dir, const char* name, ino_t* _id)
     469{
     470    dprintf(FS_NAME ": lookup %s\n", name);
     471    vboxsf_volume* volume = _volume->private_volume;
     472    SHFLCREATEPARMS params;
     473
     474    RT_ZERO(params);
     475    params.Handle = SHFL_HANDLE_NIL;
     476    params.CreateFlags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;
     477
     478    PSHFLSTRING path = build_path(dir->private_node, name);
     479    if (!path)
     480    {
     481        dprintf(FS_NAME ": make_shflstring() failed\n");
     482        return B_NO_MEMORY;
     483    }
     484
     485    int rc = vboxCallCreate(&g_clientHandle, &volume->map, path, &params);
     486    if (RT_SUCCESS(rc))
     487    {
     488        if (params.Result == SHFL_FILE_EXISTS)
     489        {
     490            vboxsf_vnode* vn;
     491            status_t rv = vboxsf_new_vnode(&volume->map, path, path, &vn);
     492            if (rv == B_OK)
     493            {
     494                *_id = vn->vnode;
     495                rv = publish_vnode(_volume, vn->vnode, vn, &vboxsf_vnode_ops, mode_from_fmode(params.Info.Attr.fMode), 0);
     496            }
     497            return rv;
     498        }
     499        else
     500        {
     501            free(path);
     502            return B_ENTRY_NOT_FOUND;
     503        }
     504    }
     505    else
     506    {
     507        free(path);
     508        dprintf(FS_NAME ": vboxCallCreate: %d\n", rc);
     509        return vbox_err_to_haiku_err(rc);
     510    }
     511}
     512
     513
     514mode_t mode_from_fmode(RTFMODE fMode)
     515{
     516    mode_t m = 0;
     517
     518    if (RTFS_IS_DIRECTORY(fMode))
     519        m |= S_IFDIR;
     520    else if (RTFS_IS_FILE(fMode))
     521        m |= S_IFREG;
     522    else if (RTFS_IS_FIFO(fMode))
     523        m |= S_IFIFO;
     524    else if (RTFS_IS_DEV_CHAR(fMode))
     525        m |= S_IFCHR;
     526    else if (RTFS_IS_DEV_BLOCK(fMode))
     527        m |= S_IFBLK;
     528    else if (RTFS_IS_SYMLINK(fMode))
     529        m |= S_IFLNK;
     530    else if (RTFS_IS_SOCKET(fMode))
     531        m |= S_IFSOCK;
     532
     533    if (fMode & RTFS_UNIX_IRUSR)
     534        m |= S_IRUSR;
     535    if (fMode & RTFS_UNIX_IWUSR)
     536        m |= S_IWUSR;
     537    if (fMode & RTFS_UNIX_IXUSR)
     538        m |= S_IXUSR;
     539    if (fMode & RTFS_UNIX_IRGRP)
     540        m |= S_IRGRP;
     541    if (fMode & RTFS_UNIX_IWGRP)
     542        m |= S_IWGRP;
     543    if (fMode & RTFS_UNIX_IXGRP)
     544        m |= S_IXGRP;
     545    if (fMode & RTFS_UNIX_IROTH)
     546        m |= S_IROTH;
     547    if (fMode & RTFS_UNIX_IWOTH)
     548        m |= S_IWOTH;
     549    if (fMode & RTFS_UNIX_IXOTH)
     550        m |= S_IXOTH;
     551    if (fMode & RTFS_UNIX_ISUID)
     552        m |= S_ISUID;
     553    if (fMode & RTFS_UNIX_ISGID)
     554        m |= S_ISGID;
     555    if (fMode & RTFS_UNIX_ISTXT)
     556        m |= S_ISVTX;
     557
     558    return m;
     559}
     560
     561
     562status_t vboxsf_open(fs_volume* _volume, fs_vnode* _vnode, int openMode, void** _cookie)
     563{
     564    vboxsf_volume* volume = _volume->private_volume;
     565    vboxsf_vnode* vnode = _vnode->private_node;
     566
     567    dprintf(FS_NAME ": open %s (mode=%x)\n", vnode->path->String.utf8, openMode);
     568
     569    SHFLCREATEPARMS params;
     570
     571    RT_ZERO(params);
     572    params.Handle = SHFL_HANDLE_NIL;
     573
     574    if (openMode & O_RDWR)
     575        params.CreateFlags |= SHFL_CF_ACCESS_READWRITE;
     576    else if (openMode & O_RDONLY)
     577        params.CreateFlags |= SHFL_CF_ACCESS_READ;
     578    else if (openMode & O_WRONLY)
     579        params.CreateFlags |= SHFL_CF_ACCESS_WRITE;
     580
     581    if (openMode & O_APPEND)
     582        params.CreateFlags |= SHFL_CF_ACCESS_APPEND;
     583
     584    if (openMode & O_CREAT)
     585    {
     586        params.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW;
     587        if (openMode & O_EXCL)
     588            params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS;
     589        else if (openMode & O_TRUNC)
     590            params.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
     591        else
     592            params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
     593    }
     594    else
     595    {
     596        params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW;
     597        if (openMode & O_TRUNC)
     598            params.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
     599        else
     600            params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
     601    }
     602
     603    int rc = vboxCallCreate(&g_clientHandle, &volume->map, vnode->path, &params);
     604    if (!RT_SUCCESS(rc))
     605    {
     606        dprintf("vboxCallCreate returned %d\n", rc);
     607        return vbox_err_to_haiku_err(rc);
     608    }
     609
     610    vboxsf_file_cookie* cookie = malloc(sizeof(vboxsf_file_cookie));
     611    if (!cookie)
     612    {
     613        dprintf("couldn't allocate file cookie\n");
     614        return B_NO_MEMORY;
     615    }
     616
     617    cookie->handle = params.Handle;
     618    cookie->path = vnode->path;
     619
     620    *_cookie = cookie;
     621
     622    return B_OK;
     623}
     624
     625
     626status_t vboxsf_create(fs_volume* _volume, fs_vnode* _dir, const char *name, int openMode, int perms, void **_cookie, ino_t *_newVnodeID)
     627{
     628    vboxsf_volume* volume = _volume->private_volume;
     629
     630    SHFLCREATEPARMS params;
     631
     632    RT_ZERO(params);
     633    params.Handle = SHFL_HANDLE_NIL;
     634
     635    if (openMode & O_RDWR)
     636        params.CreateFlags |= SHFL_CF_ACCESS_READWRITE;
     637    else if (openMode & O_RDONLY)
     638        params.CreateFlags |= SHFL_CF_ACCESS_READ;
     639    else if (openMode & O_WRONLY)
     640        params.CreateFlags |= SHFL_CF_ACCESS_WRITE;
     641
     642    if (openMode & O_APPEND)
     643        params.CreateFlags |= SHFL_CF_ACCESS_APPEND;
     644
     645    if (openMode & O_CREAT)
     646    {
     647        params.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW;
     648        if (openMode & O_EXCL)
     649            params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS;
     650        else if (openMode & O_TRUNC)
     651            params.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
     652        else
     653            params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
     654    }
     655    else
     656    {
     657        params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW;
     658        if (openMode & O_TRUNC)
     659            params.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
     660        else
     661            params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
     662    }
     663
     664    PSHFLSTRING path = build_path(_dir->private_node, name);
     665    int rc = vboxCallCreate(&g_clientHandle, &volume->map, path, &params);
     666
     667    if (!RT_SUCCESS(rc))
     668    {
     669        dprintf("vboxCallCreate returned %d\n", rc);
     670        free(path);
     671        return vbox_err_to_haiku_err(rc);
     672    }
     673
     674    vboxsf_file_cookie* cookie = malloc(sizeof(vboxsf_file_cookie));
     675    if (!cookie)
     676    {
     677        dprintf("couldn't allocate file cookie\n");
     678        free(path);
     679        return B_NO_MEMORY;
     680    }
     681
     682    cookie->handle = params.Handle;
     683    cookie->path = path;
     684
     685    *_cookie = cookie;
     686    return vboxsf_lookup(_volume, _dir, name, _newVnodeID);
     687}
     688
     689
     690status_t vboxsf_close(fs_volume* _volume, fs_vnode* _vnode, void* _cookie)
     691{
     692    vboxsf_volume* volume = _volume->private_volume;
     693    vboxsf_file_cookie* cookie = _cookie;
     694
     695    int rc = vboxCallClose(&g_clientHandle, &volume->map, cookie->handle);
     696    dprintf("vboxCallClose returned %d\n", rc);
     697    return vbox_err_to_haiku_err(rc);
     698}
     699
     700
     701status_t vboxsf_rewind_dir(fs_volume* _volume, fs_vnode* _vnode, void* _cookie)
     702{
     703    vboxsf_dir_cookie* cookie = _cookie;
     704    cookie->index = 0;
     705    return B_OK;
     706}
     707
     708
     709status_t vboxsf_close_dir(fs_volume *volume, fs_vnode *vnode, void *cookie)
     710{
     711    return B_OK;
     712}
     713
     714
     715status_t vboxsf_free_cookie(fs_volume *volume, fs_vnode *vnode, void *_cookie)
     716{
     717    vboxsf_dir_cookie* cookie = _cookie;
     718    free(cookie);
     719    return B_OK;
     720}
     721
     722status_t vboxsf_read(fs_volume* _volume, fs_vnode* _vnode, void* _cookie, off_t pos, void *buffer, size_t *length)
     723{
     724    vboxsf_volume* volume = _volume->private_volume;
     725    vboxsf_vnode* vnode = _vnode->private_node;
     726    vboxsf_file_cookie* cookie = _cookie;
     727
     728    if (*length > 0xFFFFFFFF)
     729        *length = 0xFFFFFFFF;
     730
     731    uint32_t l = *length;
     732    void* other_buffer = malloc(l); // TODO map the user memory into kernel space here for efficiency
     733    int rc = vboxCallRead(&g_clientHandle, &volume->map, cookie->handle, pos, &l, other_buffer, false);
     734    memcpy(buffer, other_buffer, l);
     735    free(other_buffer);
     736
     737    dprintf("vboxCallRead returned %d\n", rc);
     738    *length = l;
     739    return vbox_err_to_haiku_err(rc);
     740}
     741
     742
     743status_t vboxsf_write(fs_volume* _volume, fs_vnode* _vnode, void* _cookie, off_t pos, const void *buffer, size_t *length)
     744{
     745    vboxsf_volume* volume = _volume->private_volume;
     746    vboxsf_vnode* vnode = _vnode->private_node;
     747    vboxsf_file_cookie* cookie = _cookie;
     748
     749    if (*length > 0xFFFFFFFF)
     750        *length = 0xFFFFFFFF;
     751
     752    uint32_t l = *length;
     753    void* other_buffer = malloc(l); // TODO map the user memory into kernel space here for efficiency
     754    memcpy(other_buffer, buffer, l);
     755    int rc = vboxCallWrite(&g_clientHandle, &volume->map, cookie->handle, pos, &l, other_buffer, false);
     756    free(other_buffer);
     757
     758    *length = l;
     759    return vbox_err_to_haiku_err(rc);
     760}
     761
     762
     763status_t vboxsf_write_stat(fs_volume *volume, fs_vnode *vnode, const struct stat *stat, uint32 statMask)
     764{
     765    // the host handles updating the stat info - in the guest, this is a no-op
     766    return B_OK;
     767}
     768
     769
     770status_t vboxsf_create_dir(fs_volume *_volume, fs_vnode *parent, const char *name, int perms)
     771{
     772    vboxsf_volume* volume = _volume->private_volume;
     773
     774    SHFLCREATEPARMS params;
     775    params.Handle = 0;
     776    params.Info.cbObject = 0;
     777    params.CreateFlags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_CREATE_IF_NEW |
     778        SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACCESS_READ;
     779
     780    PSHFLSTRING path = build_path(parent->private_node, name);
     781    int rc = vboxCallCreate(&g_clientHandle, &volume->map, path, &params);
     782    free(path);
     783    if (params.Handle == SHFL_HANDLE_NIL)
     784        return vbox_err_to_haiku_err(rc);
     785    else
     786    {
     787        vboxCallClose(&g_clientHandle, &volume->map, params.Handle);
     788        return B_OK;
     789    }
     790}
     791
     792
     793status_t vboxsf_remove_dir(fs_volume *_volume, fs_vnode *parent, const char *name)
     794{
     795    vboxsf_volume* volume = _volume->private_volume;
     796
     797    PSHFLSTRING path = build_path(parent->private_node, name);
     798    int rc = vboxCallRemove(&g_clientHandle, &volume->map, path, SHFL_REMOVE_DIR);
     799    free(path);
     800
     801    return vbox_err_to_haiku_err(rc);
     802}
     803
     804
     805status_t vboxsf_unlink(fs_volume *_volume, fs_vnode *parent, const char *name)
     806{
     807    vboxsf_volume* volume = _volume->private_volume;
     808
     809    PSHFLSTRING path = build_path(parent->private_node, name);
     810    int rc = vboxCallRemove(&g_clientHandle, &volume->map, path, SHFL_REMOVE_FILE);
     811    free(path);
     812
     813    return vbox_err_to_haiku_err(rc);
     814}
     815
     816status_t vboxsf_link(fs_volume *volume, fs_vnode *dir, const char *name, fs_vnode *vnode)
     817{
     818    return B_UNSUPPORTED;
     819}
     820
     821
     822status_t vboxsf_rename(fs_volume* _volume, fs_vnode* fromDir, const char* fromName, fs_vnode* toDir, const char* toName)
     823{
     824    vboxsf_volume* volume = _volume->private_volume;
     825
     826    PSHFLSTRING oldpath = build_path(fromDir->private_node, fromName);
     827    PSHFLSTRING newpath = build_path(toDir->private_node, toName);
     828    int rc = vboxCallRename(&g_clientHandle, &volume->map, oldpath, newpath, SHFL_RENAME_FILE | SHFL_RENAME_REPLACE_IF_EXISTS);
     829    free(oldpath);
     830    free(newpath);
     831
     832    return vbox_err_to_haiku_err(rc);
     833}
     834
     835
     836status_t vboxsf_create_symlink(fs_volume* _volume, fs_vnode* dir, const char* name, const char* path, int mode)
     837{
     838    vboxsf_volume* volume = _volume->private_volume;
     839
     840    PSHFLSTRING target = make_shflstring(path);
     841    PSHFLSTRING linkpath = build_path(dir->private_node, name);
     842    SHFLFSOBJINFO stuff;
     843    RT_ZERO(stuff);
     844
     845    int rc = vboxCallSymlink(&g_clientHandle, &volume->map, linkpath, target, &stuff);
     846
     847    free(target);
     848    free(linkpath);
     849
     850    return vbox_err_to_haiku_err(rc);
     851}
     852
     853
     854status_t vboxsf_read_symlink(fs_volume* _volume, fs_vnode* link, char* buffer, size_t* _bufferSize)
     855{
     856    vboxsf_volume* volume = _volume->private_volume;
     857    vboxsf_vnode* vnode = link->private_node;
     858
     859    int rc = vboxReadLink(&g_clientHandle, &volume->map, vnode->path, *_bufferSize, buffer);
     860    *_bufferSize = strlen(buffer);
     861
     862    return vbox_err_to_haiku_err(rc);
     863}
     864
    769865
    770866// TODO move this into the runtime
    771 status_t vbox_err_to_haiku_err(int rc) {
    772         switch (rc) {
    773                 case VINF_SUCCESS: return B_OK;
    774                 case VERR_INVALID_POINTER: return B_BAD_ADDRESS;
    775                 case VERR_INVALID_PARAMETER: return B_BAD_VALUE;
    776                 case VERR_PERMISSION_DENIED: return B_PERMISSION_DENIED;
    777                 case VERR_NOT_IMPLEMENTED: return B_UNSUPPORTED;
    778                 case VERR_FILE_NOT_FOUND: return B_ENTRY_NOT_FOUND;
    779 
    780                 case SHFL_FILE_EXISTS: return B_FILE_EXISTS;
    781                 case SHFL_PATH_NOT_FOUND:
    782                 case SHFL_FILE_NOT_FOUND: return B_ENTRY_NOT_FOUND;
    783 
    784                 default: return B_ERROR;
    785         }
    786 }
    787 
    788 static status_t std_ops(int32 op, ...) {
    789         switch(op) {
    790         case B_MODULE_INIT:
    791                 dprintf(MODULE_NAME ": B_MODULE_INIT\n");
    792                 return init_module();
    793         case B_MODULE_UNINIT:
    794                 dprintf(MODULE_NAME ": B_MODULE_UNINIT\n");
    795                 uninit_module();
    796                 return B_OK;
    797         default:
    798                 return B_ERROR;
    799         }
    800 }
    801 
    802 static fs_volume_ops vboxsf_volume_ops = {
    803         unmount,
    804 
    805         vboxsf_read_fs_info, // read_fs_info
    806         NULL, // write_fs_info
    807         NULL, // sync
    808 
    809         vboxsf_get_vnode, // get_vnode
    810 
    811         NULL, // open_index_dir
    812         NULL, // close_index_dir
    813         NULL, // free_index_dir_cookie
    814         NULL, // read_index_dir
    815         NULL, // rewind_index_dir
    816 
    817         NULL, // create_index
    818         NULL, // remove_index
    819         NULL, // read_index_stat
    820 
    821         NULL, // open_query
    822         NULL, // close_query
    823         NULL, // free_query_cookie
    824         NULL, // read_query
    825         NULL, // rewind_query
    826 
    827         NULL, // all_layers_mounted
    828         NULL, // create_sub_vnode
    829         NULL, // delete_sub_vnode
     867status_t vbox_err_to_haiku_err(int rc)
     868{
     869    switch (rc) {
     870        case VINF_SUCCESS: return B_OK;
     871        case VERR_INVALID_POINTER: return B_BAD_ADDRESS;
     872        case VERR_INVALID_PARAMETER: return B_BAD_VALUE;
     873        case VERR_PERMISSION_DENIED: return B_PERMISSION_DENIED;
     874        case VERR_NOT_IMPLEMENTED: return B_UNSUPPORTED;
     875        case VERR_FILE_NOT_FOUND: return B_ENTRY_NOT_FOUND;
     876
     877        case SHFL_FILE_EXISTS: return B_FILE_EXISTS;
     878        case SHFL_PATH_NOT_FOUND:
     879        case SHFL_FILE_NOT_FOUND: return B_ENTRY_NOT_FOUND;
     880
     881        default: return B_ERROR;
     882    }
     883}
     884
     885
     886static status_t std_ops(int32 op, ...)
     887{
     888    switch(op)
     889    {
     890        case B_MODULE_INIT:
     891            dprintf(MODULE_NAME ": B_MODULE_INIT\n");
     892            return init_module();
     893        case B_MODULE_UNINIT:
     894            dprintf(MODULE_NAME ": B_MODULE_UNINIT\n");
     895            uninit_module();
     896            return B_OK;
     897        default:
     898            return B_ERROR;
     899    }
     900}
     901
     902
     903static fs_volume_ops vboxsf_volume_ops =
     904{
     905    unmount,
     906    vboxsf_read_fs_info, // read_fs_info
     907    NULL, // write_fs_info
     908    NULL, // sync
     909    vboxsf_get_vnode, // get_vnode
     910    NULL, // open_index_dir
     911    NULL, // close_index_dir
     912    NULL, // free_index_dir_cookie
     913    NULL, // read_index_dir
     914    NULL, // rewind_index_dir
     915    NULL, // create_index
     916    NULL, // remove_index
     917    NULL, // read_index_stat
     918    NULL, // open_query
     919    NULL, // close_query
     920    NULL, // free_query_cookie
     921    NULL, // read_query
     922    NULL, // rewind_query
     923    NULL, // all_layers_mounted
     924    NULL, // create_sub_vnode
     925    NULL, // delete_sub_vnode
    830926};
    831927
    832 static fs_vnode_ops vboxsf_vnode_ops = {
    833         vboxsf_lookup, // lookup
    834         NULL, // get_vnode_name
    835         vboxsf_put_vnode, // put_vnode
    836         NULL, // remove_vnode
    837         NULL, // can_page
    838         NULL, // read_pages
    839         NULL, // write_pages
    840         NULL, // io
    841         NULL, // cancel_io
    842         NULL, // get_file_map
    843         NULL, // ioctl
    844         NULL, // set_flags
    845         NULL, // select
    846         NULL, // deselect
    847         NULL, // fsync
    848         vboxsf_read_symlink, // read_symlink
    849         vboxsf_create_symlink, // create_symlink
    850         vboxsf_link, // link
    851         vboxsf_unlink, // unlink
    852         vboxsf_rename, // rename
    853         NULL, // access
    854         vboxsf_read_stat, // read_stat
    855         vboxsf_write_stat, // write_stat
    856         NULL, // preallocate
    857         vboxsf_create, // create
    858         vboxsf_open, // open
    859         vboxsf_close, // close
    860         vboxsf_free_cookie, // free_cookie
    861         vboxsf_read, // read
    862         vboxsf_write, // write
    863         vboxsf_create_dir, // create_dir
    864         vboxsf_remove_dir, // remove_dir
    865         vboxsf_open_dir, // open_dir
    866         vboxsf_close_dir, // close_dir
    867         vboxsf_free_dir_cookie, // free_dir_cookie
    868         vboxsf_read_dir, // read_dir
    869         vboxsf_rewind_dir, // rewind_dir
    870         NULL, // open_attr_dir
    871         NULL, // close_attr_dir
    872         NULL, // free_attr_dir_cookie
    873         NULL, // read_attr_dir
    874         NULL, // rewind_attr_dir
    875         NULL, // create_attr
    876         NULL, // open_attr
    877         NULL, // close_attr
    878         NULL, // free_attr_cookie
    879         NULL, // read_attr
    880         NULL, // write_attr
    881         NULL, // read_attr_stat
    882         NULL, // write_attr_stat
    883         NULL, // rename_attr
    884         NULL, // remove_attr
    885         NULL, // create_special_node
    886         NULL, // get_super_vnode
     928static fs_vnode_ops vboxsf_vnode_ops =
     929{
     930    vboxsf_lookup, // lookup
     931    NULL, // get_vnode_name
     932    vboxsf_put_vnode, // put_vnode
     933    NULL, // remove_vnode
     934    NULL, // can_page
     935    NULL, // read_pages
     936    NULL, // write_pages
     937    NULL, // io
     938    NULL, // cancel_io
     939    NULL, // get_file_map
     940    NULL, // ioctl
     941    NULL, // set_flags
     942    NULL, // select
     943    NULL, // deselect
     944    NULL, // fsync
     945    vboxsf_read_symlink, // read_symlink
     946    vboxsf_create_symlink, // create_symlink
     947    vboxsf_link, // link
     948    vboxsf_unlink, // unlink
     949    vboxsf_rename, // rename
     950    NULL, // access
     951    vboxsf_read_stat, // read_stat
     952    vboxsf_write_stat, // write_stat
     953    NULL, // preallocate
     954    vboxsf_create, // create
     955    vboxsf_open, // open
     956    vboxsf_close, // close
     957    vboxsf_free_cookie, // free_cookie
     958    vboxsf_read, // read
     959    vboxsf_write, // write
     960    vboxsf_create_dir, // create_dir
     961    vboxsf_remove_dir, // remove_dir
     962    vboxsf_open_dir, // open_dir
     963    vboxsf_close_dir, // close_dir
     964    vboxsf_free_dir_cookie, // free_dir_cookie
     965    vboxsf_read_dir, // read_dir
     966    vboxsf_rewind_dir, // rewind_dir
     967    NULL, // open_attr_dir
     968    NULL, // close_attr_dir
     969    NULL, // free_attr_dir_cookie
     970    NULL, // read_attr_dir
     971    NULL, // rewind_attr_dir
     972    NULL, // create_attr
     973    NULL, // open_attr
     974    NULL, // close_attr
     975    NULL, // free_attr_cookie
     976    NULL, // read_attr
     977    NULL, // write_attr
     978    NULL, // read_attr_stat
     979    NULL, // write_attr_stat
     980    NULL, // rename_attr
     981    NULL, // remove_attr
     982    NULL, // create_special_node
     983    NULL, // get_super_vnode
    887984};
    888985
    889 static file_system_module_info sVBoxSharedFileSystem = {
    890         {
    891                 MODULE_NAME B_CURRENT_FS_API_VERSION,
    892                 0,
    893                 std_ops,
    894         },
    895 
    896         FS_NAME,                                                // short_name
    897         "VirtualBox shared folders",    // pretty_name
    898         0, //B_DISK_SYSTEM_SUPPORTS_WRITING,    // DDM flags
    899 
    900         // scanning
    901         NULL, // identify_partition
    902         NULL, // scan_partition
    903         NULL, // free_identify_partition_cookie
    904         NULL,   // free_partition_content_cookie()
    905 
    906         mount,
     986static file_system_module_info sVBoxSharedFileSystem =
     987{
     988    {
     989        MODULE_NAME B_CURRENT_FS_API_VERSION,
     990        0,
     991        std_ops,
     992    },
     993    FS_NAME,                        // short_name
     994    "VirtualBox shared folders",    // pretty_name
     995    0, //B_DISK_SYSTEM_SUPPORTS_WRITING,    // DDM flags
     996    // scanning
     997    NULL, // identify_partition
     998    NULL, // scan_partition
     999    NULL, // free_identify_partition_cookie
     1000    NULL,    // free_partition_content_cookie()
     1001    mount,
    9071002};
    9081003
    909 module_info *modules[] = {
    910         (module_info *)&sVBoxSharedFileSystem,
    911         NULL,
     1004module_info *modules[] =
     1005{
     1006    (module_info *)&sVBoxSharedFileSystem,
     1007    NULL,
    9121008};
     1009
  • trunk/src/VBox/Additions/haiku/SharedFolders/vboxsf.h

    r43363 r43364  
    5757#include "lock.h"
    5858
    59 typedef struct vboxsf_volume {
    60         VBSFMAP map;
    61         ino_t rootid;
     59typedef struct vboxsf_volume
     60{
     61    VBSFMAP map;
     62    ino_t rootid;
    6263} vboxsf_volume;
    6364
    64 typedef struct vboxsf_vnode {
    65         PVBSFMAP map;
    66         PSHFLSTRING name;
    67         PSHFLSTRING path;
    68 
    69         ino_t vnode;
    70         struct vboxsf_vnode* next;
     65typedef struct vboxsf_vnode
     66{
     67    PVBSFMAP map;
     68    PSHFLSTRING name;
     69    PSHFLSTRING path;
     70    ino_t vnode;
     71    struct vboxsf_vnode* next;
    7172} vboxsf_vnode;
    7273
    73 typedef struct vboxsf_dir_cookie {
    74         SHFLHANDLE handle;
    75         PSHFLSTRING path;
    76         uint32_t index;
    77         bool has_more_files;
    78         PSHFLDIRINFO buffer_start, buffer;
    79         uint32_t buffer_length, num_files;
     74typedef struct vboxsf_dir_cookie
     75{
     76    SHFLHANDLE handle;
     77    PSHFLSTRING path;
     78    uint32_t index;
     79    bool has_more_files;
     80    PSHFLDIRINFO buffer_start, buffer;
     81    uint32_t buffer_length, num_files;
    8082} vboxsf_dir_cookie;
    8183
    82 typedef struct vboxsf_file_cookie {
    83         SHFLHANDLE handle;
    84         PSHFLSTRING path;
     84typedef struct vboxsf_file_cookie
     85{
     86    SHFLHANDLE handle;
     87    PSHFLSTRING path;
    8588} vboxsf_file_cookie;
    8689
     
    100103
    101104#endif
     105
  • trunk/src/VBox/Additions/haiku/SharedFolders/vnode_cache.cpp

    r43363 r43364  
    4747#include "OpenHashTable.h"
    4848
    49 struct HashTableDefinition {
    50         typedef uint32 KeyType;
    51         typedef vboxsf_vnode ValueType;
     49struct HashTableDefinition
     50{
     51    typedef uint32 KeyType;
     52    typedef    vboxsf_vnode ValueType;
    5253
    53         size_t HashKey(uint32 key) const
    54         {
    55                 return key;
    56         }
     54    size_t HashKey(uint32 key) const
     55    {
     56        return key;
     57    }
    5758
    58         size_t Hash(vboxsf_vnode* value) const
    59         {
    60                 return HashKey(value->vnode);
    61         }
     59    size_t Hash(vboxsf_vnode* value) const
     60    {
     61        return HashKey(value->vnode);
     62    }
    6263
    63         bool Compare(uint32 key, vboxsf_vnode* value) const
    64         {
    65                 return value->vnode == key;
    66         }
     64    bool Compare(uint32 key, vboxsf_vnode* value) const
     65    {
     66        return value->vnode == key;
     67    }
    6768
    68         vboxsf_vnode*& GetLink(vboxsf_vnode* value) const
    69         {
    70                 return value->next;
    71         }
     69    vboxsf_vnode*& GetLink(vboxsf_vnode* value) const
     70    {
     71        return value->next;
     72    }
    7273};
    7374
     
    7677mutex g_vnodeCacheLock;
    7778
    78 extern "C" status_t vboxsf_new_vnode(PVBSFMAP map, PSHFLSTRING path, PSHFLSTRING name, vboxsf_vnode** p) {
    79         vboxsf_vnode* vn = (vboxsf_vnode*)malloc(sizeof(vboxsf_vnode));
    80         if (vn == NULL) {
    81                 return B_NO_MEMORY;
    82         }
    83         dprintf("creating new vnode at %p with path=%p (%s)\n", vn, path->String.utf8, path->String.utf8);
    84         vn->map = map;
    85         vn->path = path;
    86         if (name) {
    87                 vn->name = name;
    88         }
    89         else {
    90                 const char* cname = strrchr((char*)path->String.utf8, '/');
    91                 if (!cname)
    92                         vn->name = path; // no slash, assume this *is* the filename
    93                 else
    94                         vn->name = make_shflstring(cname);
    95         }
    9679
    97         if (mutex_lock(&g_vnodeCacheLock) < B_OK) {
    98                 free(vn);
    99                 return B_ERROR;
    100         }
     80extern "C" status_t vboxsf_new_vnode(PVBSFMAP map, PSHFLSTRING path, PSHFLSTRING name, vboxsf_vnode** p)
     81{
     82    vboxsf_vnode* vn = (vboxsf_vnode*)malloc(sizeof(vboxsf_vnode));
     83    if (vn == NULL)
     84        return B_NO_MEMORY;
    10185
    102         vn->vnode = g_nextVnid++;
    103         *p = vn;
    104         dprintf("vboxsf: allocated %p (path=%p name=%p)\n", vn, vn->path, vn->name);
    105         status_t rv = g_cache.Insert(vn);
     86    dprintf("creating new vnode at %p with path=%p (%s)\n", vn, path->String.utf8, path->String.utf8);
     87    vn->map = map;
     88    vn->path = path;
     89    if (name)
     90        vn->name = name;
     91    else
     92    {
     93        const char* cname = strrchr((char*)path->String.utf8, '/');
     94        if (!cname)
     95            vn->name = path; // no slash, assume this *is* the filename
     96        else
     97            vn->name = make_shflstring(cname);
     98    }
    10699
    107         mutex_unlock(&g_vnodeCacheLock);
     100    if (mutex_lock(&g_vnodeCacheLock) < B_OK)
     101    {
     102        free(vn);
     103        return B_ERROR;
     104    }
    108105
    109         return rv;
     106    vn->vnode = g_nextVnid++;
     107    *p = vn;
     108    dprintf("vboxsf: allocated %p (path=%p name=%p)\n", vn, vn->path, vn->name);
     109    status_t rv = g_cache.Insert(vn);
     110
     111    mutex_unlock(&g_vnodeCacheLock);
     112
     113    return rv;
    110114}
    111115
     116
    112117extern "C" status_t vboxsf_get_vnode(fs_volume* volume, ino_t id, fs_vnode* vnode,
    113         int* _type, uint32* _flags, bool reenter) {
    114         vboxsf_vnode* vn = g_cache.Lookup(id);
    115         if (vn) {
    116                 vnode->private_node = vn;
    117                 return B_OK;
    118         }
    119         else {
    120                 return B_ERROR;
    121         }
     118    int* _type, uint32* _flags, bool reenter)
     119{
     120    vboxsf_vnode* vn = g_cache.Lookup(id);
     121    if (vn)
     122    {
     123        vnode->private_node = vn;
     124        return B_OK;
     125    }
     126    return B_ERROR;
    122127}
    123128
    124 extern "C" status_t vboxsf_put_vnode(fs_volume* volume, fs_vnode* vnode, bool reenter) {
    125         g_cache.Remove((vboxsf_vnode*)vnode->private_node);
     129
     130extern "C" status_t vboxsf_put_vnode(fs_volume* volume, fs_vnode* vnode, bool reenter)
     131{
     132    g_cache.Remove((vboxsf_vnode*)vnode->private_node);
    126133}
     134
  • trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouse.cpp

    r43363 r43364  
    6363
    6464/* Export as global symbol with C linkage, RTDECL is necessary. */
    65 RTDECL(BInputServerDevice*)
     65RTDECL(BInputServerDevice *)
    6666instantiate_input_device()
    6767{
     
    6969}
    7070
     71
    7172VBoxMouse::VBoxMouse()
    72         : BInputServerDevice(),
    73         fDriverFD(-1),
    74         fServiceThreadID(-1),
    75         fExiting(false)
    76 {
    77 }
     73     : BInputServerDevice(),
     74       fDriverFD(-1),
     75       fServiceThreadID(-1),
     76       fExiting(false)
     77{
     78}
     79
    7880
    7981VBoxMouse::~VBoxMouse()
    8082{
    8183}
     84
    8285
    8386status_t VBoxMouse::InitCheck()
     
    8588    int rc = VbglR3Init();
    8689    if (!RT_SUCCESS(rc))
    87                 return ENXIO;
    88 
    89         //// Start() will *not* Init() again
     90        return ENXIO;
     91
     92    //// Start() will *not* Init() again
    9093    //VbglR3Term();
    9194
    92 //              return B_DEVICE_NOT_FOUND;
    93 
    94         input_device_ref device = { (char *)"VBoxMouse",
    95                 B_POINTING_DEVICE, (void*)this };
    96         input_device_ref* deviceList[2] = { &device, NULL };
    97         RegisterDevices(deviceList);
    98 
    99         return B_OK;
    100 }
     95//        return B_DEVICE_NOT_FOUND;
     96
     97    input_device_ref device = { (char *)"VBoxMouse",
     98        B_POINTING_DEVICE, (void *)this };
     99    input_device_ref *deviceList[2] = { &device, NULL };
     100    RegisterDevices(deviceList);
     101
     102    return B_OK;
     103}
     104
    101105
    102106status_t VBoxMouse::SystemShuttingDown()
     
    104108    VbglR3Term();
    105109
    106         return B_OK;
    107 }
    108 
    109 status_t VBoxMouse::Start(const char* device, void* cookie)
    110 {
    111         status_t err;
    112         int rc;
     110    return B_OK;
     111}
     112
     113
     114status_t VBoxMouse::Start(const char *device, void *cookie)
     115{
     116    status_t err;
     117    int rc;
    113118    uint32_t fFeatures = 0;
    114119    Log(("VBoxMouse::%s()\n", __FUNCTION__));
     
    116121    rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
    117122    if (RT_SUCCESS(rc))
    118         rc = VbglR3SetMouseStatus(  fFeatures
     123        rc = VbglR3SetMouseStatus(fFeatures
    119124                                  | VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
    120125                                  | VMMDEV_MOUSE_NEW_PROTOCOL);
    121     if (!RT_SUCCESS(rc)) {
    122                 LogRel(("VBoxMouse: Error switching guest mouse into absolute mode: %d\n", rc));
     126    if (!RT_SUCCESS(rc))
     127    {
     128        LogRel(("VBoxMouse: Error switching guest mouse into absolute mode: %d\n", rc));
    123129        return B_DEVICE_NOT_FOUND;
    124130    }
    125131
    126         err = fServiceThreadID = spawn_thread(_ServiceThreadNub,
    127                         "VBoxMouse", B_NORMAL_PRIORITY, this);
    128         if (err >= B_OK) {
    129                 resume_thread(fServiceThreadID);
    130                 return B_OK;
    131         } else
     132    err = fServiceThreadID = spawn_thread(_ServiceThreadNub,
     133                                          "VBoxMouse", B_NORMAL_PRIORITY, this);
     134    if (err >= B_OK)
     135    {
     136        resume_thread(fServiceThreadID);
     137        return B_OK;
     138    }
     139    else
    132140        LogRel(("VBoxMouse: Error starting service thread: 0x%08lx\n",
    133                 err));
    134 
    135         // release the mouse
     141                err));
     142
     143    // release the mouse
    136144    rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
    137145    if (RT_SUCCESS(rc))
    138         rc = VbglR3SetMouseStatus(  fFeatures
     146        rc = VbglR3SetMouseStatus(fFeatures
    139147                                  & ~VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
    140148                                  & ~VMMDEV_MOUSE_NEW_PROTOCOL);
    141149
    142          return B_ERROR;
    143 }
    144 
    145 status_t VBoxMouse::Stop(const char* device, void* cookie)
    146 {
    147         status_t status;
    148         int rc;
     150    return B_ERROR;
     151}
     152
     153
     154status_t VBoxMouse::Stop(const char *device, void *cookie)
     155{
     156    status_t status;
     157    int rc;
    149158    uint32_t fFeatures = 0;
    150159    Log(("VBoxMouse::%s()\n", __FUNCTION__));
    151160
    152         fExiting = true;
     161    fExiting = true;
    153162
    154163
    155164    rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
    156165    if (RT_SUCCESS(rc))
    157         rc = VbglR3SetMouseStatus(  fFeatures
     166        rc = VbglR3SetMouseStatus(fFeatures
    158167                                  & ~VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
    159168                                  & ~VMMDEV_MOUSE_NEW_PROTOCOL);
    160169
    161170
    162         close(fDriverFD);
    163         fDriverFD = -1;
    164         //XXX WTF ?
    165         suspend_thread(fServiceThreadID);
    166         resume_thread(fServiceThreadID);
    167         wait_for_thread(fServiceThreadID, &status);
    168         fServiceThreadID = -1;
    169         fExiting = false;
    170     return B_OK;
    171 }
    172 
    173 status_t VBoxMouse::Control(const char  *device,
    174                                                 void            *cookie,
    175                                                 uint32          code,
    176                                                 BMessage        *message)
    177 {
    178         // respond to changes in the system
    179         switch (code) {
    180                 case B_MOUSE_SPEED_CHANGED:
    181                 case B_CLICK_SPEED_CHANGED:
    182                 case B_MOUSE_ACCELERATION_CHANGED:
    183                 default:
    184                         return BInputServerDevice::Control(device, cookie, code, message);
    185         }
    186         return B_OK;
    187 }
     171    close(fDriverFD);
     172    fDriverFD = -1;
     173    //XXX WTF ?
     174    suspend_thread(fServiceThreadID);
     175    resume_thread(fServiceThreadID);
     176    wait_for_thread(fServiceThreadID, &status);
     177    fServiceThreadID = -1;
     178    fExiting = false;
     179    return B_OK;
     180}
     181
     182
     183status_t VBoxMouse::Control(const char *device, void *cookie, uint32 code, BMessage *message)
     184{
     185    // respond to changes in the system
     186    switch (code)
     187    {
     188        case B_MOUSE_SPEED_CHANGED:
     189        case B_CLICK_SPEED_CHANGED:
     190        case B_MOUSE_ACCELERATION_CHANGED:
     191        default:
     192            return BInputServerDevice::Control(device, cookie, code, message);
     193    }
     194    return B_OK;
     195}
     196
    188197
    189198status_t VBoxMouse::_ServiceThreadNub(void *_this)
    190199{
    191         VBoxMouse *service = (VBoxMouse *)_this;
    192         return service->_ServiceThread();
    193 }
     200    VBoxMouse *service = (VBoxMouse *)_this;
     201    return service->_ServiceThread();
     202}
     203
    194204
    195205status_t VBoxMouse::_ServiceThread()
     
    197207    Log(("VBoxMouse::%s()\n", __FUNCTION__));
    198208
    199         fDriverFD = open(VBOXGUEST_DEVICE_NAME, O_RDWR);
    200         if (fDriverFD < 0)
    201                 return ENXIO;
     209    fDriverFD = open(VBOXGUEST_DEVICE_NAME, O_RDWR);
     210    if (fDriverFD < 0)
     211        return ENXIO;
    202212
    203213    /* The thread waits for incoming messages from the host. */
    204214    while (!fExiting)
    205215    {
    206             uint32_t cx, cy, fFeatures;
    207         int rc;
    208 
    209 
    210                 fd_set readSet, writeSet, errorSet;
    211                 FD_ZERO(&readSet);
    212                 FD_ZERO(&writeSet);
    213                 FD_ZERO(&errorSet);
    214                 FD_SET(fDriverFD, &readSet);
    215                 if (fDriverFD < 0)
    216                         break;
    217                 rc = select(fDriverFD + 1, &readSet, &writeSet, &errorSet, NULL);
    218                 if (rc < 0) {
    219                         if (errno == EINTR || errno == EAGAIN)
    220                                 continue;
    221                         break;
    222                 }
    223 
    224             if (RT_SUCCESS(VbglR3GetMouseStatus(&fFeatures, &cx, &cy))
    225             && (fFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE))
    226         {
    227                 float x = cx * 1.0 / 65535;
    228                 float y = cy * 1.0 / 65535;
    229 
    230                 _debugPrintf("VBoxMouse: at %d,%d %f,%f\n", cx, cy, x, y);
    231 
    232                 /* send absolute movement */
    233 
    234                         bigtime_t now = system_time();
    235                         BMessage* event = new BMessage(B_MOUSE_MOVED);
    236                         event->AddInt64("when", now);
    237                         event->AddFloat("x", x);
    238                         event->AddFloat("y", y);
    239                         event->AddFloat("be:tablet_x", x);
    240                         event->AddFloat("be:tablet_y", y);
    241                         //event->PrintToStream();
    242                         EnqueueMessage(event);
    243 
    244                 //LogRelFlow(("processed host event rc = %d\n", rc));
    245         }
    246     }
    247         return 0;
    248 }
    249 
    250 
     216        uint32_t cx, cy, fFeatures;
     217        int rc;
     218
     219
     220        fd_set readSet, writeSet, errorSet;
     221        FD_ZERO(&readSet);
     222        FD_ZERO(&writeSet);
     223        FD_ZERO(&errorSet);
     224        FD_SET(fDriverFD, &readSet);
     225        if (fDriverFD < 0)
     226            break;
     227        rc = select(fDriverFD + 1, &readSet, &writeSet, &errorSet, NULL);
     228        if (rc < 0)
     229        {
     230            if (errno == EINTR || errno == EAGAIN)
     231                continue;
     232            break;
     233        }
     234
     235        if (RT_SUCCESS(VbglR3GetMouseStatus(&fFeatures, &cx, &cy))
     236            && (fFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE))
     237        {
     238            float x = cx * 1.0 / 65535;
     239            float y = cy * 1.0 / 65535;
     240
     241            _debugPrintf("VBoxMouse: at %d,%d %f,%f\n", cx, cy, x, y);
     242
     243            /* send absolute movement */
     244
     245            bigtime_t now = system_time();
     246            BMessage *event = new BMessage(B_MOUSE_MOVED);
     247            event->AddInt64("when", now);
     248            event->AddFloat("x", x);
     249            event->AddFloat("y", y);
     250            event->AddFloat("be:tablet_x", x);
     251            event->AddFloat("be:tablet_y", y);
     252            //event->PrintToStream();
     253            EnqueueMessage(event);
     254
     255            //LogRelFlow(("processed host event rc = %d\n", rc));
     256        }
     257    }
     258    return 0;
     259}
     260
  • trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouse.h

    r43363 r43364  
    5050#include <InputServerDevice.h>
    5151
    52 extern "C" _EXPORT BInputServerDevice* instantiate_input_device();
     52extern "C"
     53_EXPORT BInputServerDevice* instantiate_input_device();
    5354
    54 class VBoxMouse : public BInputServerDevice {
    55 public:
    56         VBoxMouse();
    57         virtual ~VBoxMouse();
     55class VBoxMouse : public BInputServerDevice
     56{
     57    public:
     58        VBoxMouse();
     59        virtual ~VBoxMouse();
    5860
    59         virtual status_t                InitCheck();
    60         virtual status_t                SystemShuttingDown();
     61        virtual status_t                InitCheck();
     62        virtual status_t                SystemShuttingDown();
    6163
    62         virtual status_t                Start(const char* device, void* cookie);
    63         virtual status_t                Stop(const char* device, void* cookie);
    64         virtual status_t                Control(const char      *device,
    65                                                                         void            *cookie,
    66                                                                         uint32          code,
    67                                                                         BMessage        *message);
     64        virtual status_t                Start(const char *device, void *cookie);
     65        virtual status_t                Stop(const char *device, void *cookie);
     66        virtual status_t                Control(const char      *device,
     67                                  void          *cookie,
     68                                  uint32                code,
     69                                  BMessage      *message);
    6870
    69 private:
     71    private:
    7072
    71 static status_t _ServiceThreadNub(void *_this);
    72         status_t        _ServiceThread();
     73        static status_t _ServiceThreadNub(void *_this);
     74        status_t        _ServiceThread();
    7375
    74         int                     fDriverFD;
    75         thread_id       fServiceThreadID;
    76         bool            fExiting;
     76        int                     fDriverFD;
     77        thread_id       fServiceThreadID;
     78        bool            fExiting;
    7779
    7880};
     
    8082
    8183#endif /* __VBOXMOUSE__H */
     84
  • trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouseFilter.cpp

    r43363 r43364  
    6464// TODO can this be merged with VBoxMouse?
    6565
    66 RTDECL(BInputServerFilter*)
     66RTDECL(BInputServerFilter *)
    6767instantiate_input_filter()
    6868{
    69         return new VBoxMouseFilter();
     69    return new VBoxMouseFilter();
    7070}
    7171
    7272VBoxMouseFilter::VBoxMouseFilter()
    73         : BInputServerFilter(),
    74         fDriverFD(-1),
    75         fServiceThreadID(-1),
    76         fExiting(false),
    77         fCurrentButtons(0)
     73     : BInputServerFilter(),
     74       fDriverFD(-1),
     75       fServiceThreadID(-1),
     76       fExiting(false),
     77       fCurrentButtons(0)
    7878{
    7979}
     
    8383}
    8484
    85 filter_result VBoxMouseFilter::Filter(BMessage* message, BList* outList)
     85filter_result VBoxMouseFilter::Filter(BMessage *message, BList *outList)
    8686{
    87         switch(message->what) {
    88                 case B_MOUSE_UP:
    89                 case B_MOUSE_DOWN:
    90                 {
    91                         printf("click|release\n");
    92                         message->FindInt32("buttons", &fCurrentButtons);
    93                 }
    94                 case B_MOUSE_MOVED:
    95                 {
    96                         printf("mouse moved\n");
    97                         message->ReplaceInt32("buttons", fCurrentButtons);
    98                 }
    99         }
     87    switch (message->what)
     88    {
     89        case B_MOUSE_UP:
     90        case B_MOUSE_DOWN:
     91        {
     92            printf("click|release\n");
     93            message->FindInt32("buttons", &fCurrentButtons);
     94        }
     95        case B_MOUSE_MOVED:
     96        {
     97            printf("mouse moved\n");
     98            message->ReplaceInt32("buttons", fCurrentButtons);
     99        }
     100    }
    100101
    101         return B_DISPATCH_MESSAGE;
     102    return B_DISPATCH_MESSAGE;
    102103}
  • trunk/src/VBox/Additions/haiku/VBoxTray/VBoxClipboard.cpp

    r43363 r43364  
    7474#define LogRelFlowFunc(x) printf x
    7575
     76
    7677VBoxClipboardService::VBoxClipboardService()
    77         : BHandler("VBoxClipboardService"),
    78         fClientId(-1),
    79         fServiceThreadID(-1),
    80         fExiting(false)
    81 {
    82 }
     78     : BHandler("VBoxClipboardService"),
     79       fClientId(-1),
     80       fServiceThreadID(-1),
     81       fExiting(false)
     82{
     83}
     84
    8385
    8486VBoxClipboardService::~VBoxClipboardService()
     
    8688}
    8789
     90
    8891status_t VBoxClipboardService::Connect()
    8992{
    90         status_t err;
     93    status_t err;
    9194    printf("VBoxClipboardService::%s()\n", __FUNCTION__);
    9295
    9396    int rc = VbglR3ClipboardConnect(&fClientId);
    94     if (RT_SUCCESS (rc)) {
    95                 err = fServiceThreadID = spawn_thread(_ServiceThreadNub,
    96                         "VBoxClipboardService", B_NORMAL_PRIORITY, this);
    97 
    98                 if (err >= B_OK) {
    99                         resume_thread(fServiceThreadID);
    100 
    101                         err = be_clipboard->StartWatching(BMessenger(this));
    102                         printf("be_clipboard->StartWatching: %ld\n", err);
    103                         if (err == B_OK)
    104                                 return B_OK;
    105                         else
    106                         LogRel(("VBoxClipboardService: Error watching the system clipboard: %ld\n", err));
    107                 } else
    108                 LogRel(("VBoxClipboardService: Error starting service thread: %ld\n", err));
    109 
    110                 //rc = RTErrConvertFromErrno(err);
     97    if (RT_SUCCESS(rc))
     98    {
     99        err = fServiceThreadID = spawn_thread(_ServiceThreadNub,
     100                                              "VBoxClipboardService", B_NORMAL_PRIORITY, this);
     101
     102        if (err >= B_OK)
     103        {
     104            resume_thread(fServiceThreadID);
     105
     106            err = be_clipboard->StartWatching(BMessenger(this));
     107            printf("be_clipboard->StartWatching: %ld\n", err);
     108            if (err == B_OK)
     109                return B_OK;
     110            else
     111                LogRel(("VBoxClipboardService: Error watching the system clipboard: %ld\n", err));
     112        }
     113        else
     114            LogRel(("VBoxClipboardService: Error starting service thread: %ld\n", err));
     115
     116        //rc = RTErrConvertFromErrno(err);
    111117        VbglR3ClipboardDisconnect(fClientId);
    112         } else
     118    }
     119    else
    113120        LogRel(("VBoxClipboardService: Error starting service thread: %d\n", rc));
    114          return B_ERROR;
    115 }
     121    return B_ERROR;
     122}
     123
    116124
    117125status_t VBoxClipboardService::Disconnect()
    118126{
    119         status_t status;
    120 
    121         be_clipboard->StopWatching(BMessenger(this));
    122 
    123         fExiting = true;
     127    status_t status;
     128
     129    be_clipboard->StopWatching(BMessenger(this));
     130
     131    fExiting = true;
    124132
    125133    VbglR3ClipboardDisconnect(fClientId);
    126134
    127         wait_for_thread(fServiceThreadID, &status);
     135    wait_for_thread(fServiceThreadID, &status);
    128136    return B_OK;
    129137}
    130138
    131 void VBoxClipboardService::MessageReceived(BMessage* message)
    132 {
    133         uint32_t formats = 0;
    134         message->PrintToStream();
    135         switch (message->what) {
    136                 case VBOX_GUEST_CLIPBOARD_HOST_MSG_FORMATS:
    137                 {
    138                         int rc;
    139                         uint32_t cb;
    140                         void *pv;
    141                         bool commit = false;
    142 
    143                         if (message->FindInt32("Formats", (int32 *)&formats) != B_OK)
    144                                 break;
    145 
    146                         if (!formats)
    147                                 break;
    148                         if (!be_clipboard->Lock())
    149                                 break;
    150 
    151                         be_clipboard->Clear();
    152                         BMessage *clip = be_clipboard->Data();
    153                         if (!clip) {
    154                                 be_clipboard->Unlock();
    155                                 break;
    156                         }
    157 
    158                         if (formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) {
    159                                 pv = _VBoxReadHostClipboard(VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, &cb);
    160                                 if (pv) {
    161                                         char *text;
    162                                         rc = RTUtf16ToUtf8((PCRTUTF16)pv, &text);
     139
     140void VBoxClipboardService::MessageReceived(BMessage *message)
     141{
     142    uint32_t formats = 0;
     143    message->PrintToStream();
     144    switch (message->what)
     145    {
     146        case VBOX_GUEST_CLIPBOARD_HOST_MSG_FORMATS:
     147        {
     148            int rc;
     149            uint32_t cb;
     150            void *pv;
     151            bool commit = false;
     152
     153            if (message->FindInt32("Formats", (int32 *)&formats) != B_OK)
     154                break;
     155
     156            if (!formats)
     157                break;
     158            if (!be_clipboard->Lock())
     159                break;
     160
     161            be_clipboard->Clear();
     162            BMessage *clip = be_clipboard->Data();
     163            if (!clip)
     164            {
     165                be_clipboard->Unlock();
     166                break;
     167            }
     168
     169            if (formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
     170            {
     171                pv = _VBoxReadHostClipboard(VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, &cb);
     172                if (pv)
     173                {
     174                    char *text;
     175                    rc = RTUtf16ToUtf8((PCRTUTF16)pv, &text);
    163176                    if (RT_SUCCESS(rc))
    164177                    {
    165                         BString str(text);
    166                         // @todo use vboxClipboardUtf16WinToLin()
    167                         // convert Windows CRLF to LF
    168                         str.ReplaceAll("\r\n", "\n");
    169                         // don't include the \0
    170                                         clip->AddData("text/plain", B_MIME_TYPE, str.String(), str.Length());
    171                                         RTStrFree(text);
    172                                         commit = true;
     178                        BString str(text);
     179                        // @todo use vboxClipboardUtf16WinToLin()
     180                        // convert Windows CRLF to LF
     181                        str.ReplaceAll("\r\n", "\n");
     182                        // don't include the \0
     183                        clip->AddData("text/plain", B_MIME_TYPE, str.String(), str.Length());
     184                        RTStrFree(text);
     185                        commit = true;
    173186                    }
    174                                         free(pv);
    175                                 }
    176                         }
    177 
    178                         if (formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) {
    179                                 pv = _VBoxReadHostClipboard(VBOX_SHARED_CLIPBOARD_FMT_BITMAP, &cb);
    180                                 if (pv) {
    181                                         void *pBmp;
    182                                         size_t cbBmp;
    183                                         rc = vboxClipboardDibToBmp(pv, cb, &pBmp, &cbBmp);
     187                    free(pv);
     188                }
     189            }
     190
     191            if (formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
     192            {
     193                pv = _VBoxReadHostClipboard(VBOX_SHARED_CLIPBOARD_FMT_BITMAP, &cb);
     194                if (pv)
     195                {
     196                    void *pBmp;
     197                    size_t cbBmp;
     198                    rc = vboxClipboardDibToBmp(pv, cb, &pBmp, &cbBmp);
    184199                    if (RT_SUCCESS(rc))
    185200                    {
    186                         BMemoryIO mio(pBmp, cbBmp);
    187                         BBitmap *bitmap = BTranslationUtils::GetBitmap(&mio);
    188                         if (bitmap)
    189                         {
    190                                 BMessage bitmapArchive;
    191                                 if (bitmap->IsValid() &&
    192                                         bitmap->Archive(&bitmapArchive) == B_OK &&
    193                                         clip->AddMessage("image/bitmap", &bitmapArchive) == B_OK)
    194                                 {
    195                                                         commit = true;
    196                                 }
    197                                                 delete bitmap;
    198                         }
    199                         RTMemFree(pBmp);
     201                        BMemoryIO mio(pBmp, cbBmp);
     202                        BBitmap *bitmap = BTranslationUtils::GetBitmap(&mio);
     203                        if (bitmap)
     204                        {
     205                            BMessage bitmapArchive;
     206                            if (bitmap->IsValid() &&
     207                                bitmap->Archive(&bitmapArchive) == B_OK &&
     208                                clip->AddMessage("image/bitmap", &bitmapArchive) == B_OK)
     209                            {
     210                                commit = true;
     211                            }
     212                            delete bitmap;
     213                        }
     214                        RTMemFree(pBmp);
    200215                    }
    201                                         free(pv);
    202                                 }
    203                         }
    204 
    205                         /* make sure we don't bounce this data back to the host,
    206                          * it's impolite.
    207                          * It can also be used as a hint to applications probably. */
    208                         clip->AddBool("FromVirtualBoxHost", true);
    209 
    210                         if (commit)
    211                                 be_clipboard->Commit();
    212                         be_clipboard->Unlock();
    213                         break;
    214                 }
    215 
    216                 case VBOX_GUEST_CLIPBOARD_HOST_MSG_READ_DATA:
    217                 {
    218                         int rc;
    219 
    220                         if (message->FindInt32("Formats", (int32 *)&formats) != B_OK)
    221                                 break;
    222 
    223                         if (!formats)
    224                                 break;
    225                         if (!be_clipboard->Lock())
    226                                 break;
    227 
    228                         BMessage *clip = be_clipboard->Data();
    229                         if (!clip) {
    230                                 be_clipboard->Unlock();
    231                                 break;
    232                         }
    233                         clip->PrintToStream();
    234 
    235                         if (formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) {
    236                                 const char *text;
    237                                 int32 textLen;
    238                                 if (clip->FindData("text/plain", B_MIME_TYPE, (const void **)&text, &textLen) == B_OK) {
    239                         // usually doesn't include the \0 so be safe
    240                                         BString str(text, textLen);
    241                                         // convert from LF to Windows CRLF
    242                                         str.ReplaceAll("\n", "\r\n");
     216                    free(pv);
     217                }
     218            }
     219
     220            /* make sure we don't bounce this data back to the host,
     221             * it's impolite.
     222             * It can also be used as a hint to applications probably. */
     223            clip->AddBool("FromVirtualBoxHost", true);
     224
     225            if (commit)
     226                be_clipboard->Commit();
     227            be_clipboard->Unlock();
     228            break;
     229        }
     230
     231        case VBOX_GUEST_CLIPBOARD_HOST_MSG_READ_DATA:
     232        {
     233            int rc;
     234
     235            if (message->FindInt32("Formats", (int32 *)&formats) != B_OK)
     236                break;
     237
     238            if (!formats)
     239                break;
     240            if (!be_clipboard->Lock())
     241                break;
     242
     243            BMessage *clip = be_clipboard->Data();
     244            if (!clip)
     245            {
     246                be_clipboard->Unlock();
     247                break;
     248            }
     249            clip->PrintToStream();
     250
     251            if (formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
     252            {
     253                const char *text;
     254                int32 textLen;
     255                if (clip->FindData("text/plain", B_MIME_TYPE, (const void **)&text, &textLen) == B_OK)
     256                {
     257                    // usually doesn't include the \0 so be safe
     258                    BString str(text, textLen);
     259                    // convert from LF to Windows CRLF
     260                    str.ReplaceAll("\n", "\r\n");
    243261                    PRTUTF16 pwsz;
    244262                    rc = RTStrToUtf16(str.String(), &pwsz);
     
    247265                        uint32_t cb = (RTUtf16Len(pwsz) + 1) * sizeof(RTUTF16);
    248266
    249                                         rc = VbglR3ClipboardWriteData(fClientId,
    250                                                 VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, pwsz, cb);
    251                                                 //printf("VbglR3ClipboardWriteData: %d\n", rc);
    252 
    253                                         RTUtf16Free(pwsz);
     267                        rc = VbglR3ClipboardWriteData(fClientId,
     268                                                      VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, pwsz, cb);
     269                        //printf("VbglR3ClipboardWriteData: %d\n", rc);
     270
     271                        RTUtf16Free(pwsz);
    254272                    }
    255                                 }
    256                         }
    257                         else if (formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
    258                         {
    259                                 BMessage archivedBitmap;
    260                                 if (clip->FindMessage("image/bitmap", &archivedBitmap) == B_OK ||
    261                                         clip->FindMessage("image/x-be-bitmap", &archivedBitmap) == B_OK) {
    262                                         BBitmap *bitmap = new(std::nothrow) BBitmap(&archivedBitmap);
    263                                         if (bitmap)
    264                                         {
    265                                                 // Don't delete bitmap, BBitmapStream will.
    266                                                 BBitmapStream stream(bitmap);
    267                                                 BTranslatorRoster *roster = BTranslatorRoster::Default();
    268                                                 if (roster && bitmap->IsValid())
    269                                                 {
    270                                                         BMallocIO bmpStream;
    271                                                         if (roster->Translate(&stream, NULL, NULL, &bmpStream, B_BMP_FORMAT) == B_OK)
    272                                                         {
    273                                                                 const void *pDib;
    274                                                                 size_t cbDibSize;
    275                                                                 /* Strip out the BM header */
    276                                                                 rc = vboxClipboardBmpGetDib(bmpStream.Buffer(), bmpStream.BufferLength(), &pDib, &cbDibSize);
    277                                                                 if (RT_SUCCESS(rc))
    278                                                                 {
    279                                                             rc = VbglR3ClipboardWriteData(fClientId,
    280                                                                     VBOX_SHARED_CLIPBOARD_FMT_BITMAP, (void *)pDib, cbDibSize);
    281                                                                 }
    282                                                         }
    283                                                 }
    284                                         }
    285                                 }
    286                         }
    287 
    288                         be_clipboard->Unlock();
    289                         break;
    290                 }
    291 
    292                 case B_CLIPBOARD_CHANGED:
    293                 {
    294                         printf("B_CLIPBOARD_CHANGED\n");
    295                         const void *data;
    296                         int32 dataLen;
    297                         if (!be_clipboard->Lock())
    298                                 break;
    299 
    300                         BMessage *clip = be_clipboard->Data();
    301                         if (!clip) {
    302                                 be_clipboard->Unlock();
    303                                 break;
    304                         }
    305 
    306                         bool fromVBox;
    307                         if (clip->FindBool("FromVirtualBoxHost", &fromVBox) == B_OK && fromVBox) {
    308                                 // It already comes from the host, discard.
    309                                 be_clipboard->Unlock();
    310                                 break;
    311                         }
    312 
    313                         if (clip->FindData("text/plain", B_MIME_TYPE, &data, &dataLen) == B_OK)
    314                                 formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
    315                         if (clip->HasMessage("image/bitmap") || clip->HasMessage("image/x-be-bitmap"))
    316                                 formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
    317 
    318                         be_clipboard->Unlock();
    319 
    320                     VbglR3ClipboardReportFormats(fClientId, formats);
    321                         break;
    322                 }
    323 
    324                 case B_QUIT_REQUESTED:
    325                         fExiting = true;
    326                         break;
    327 
    328                 default:
    329                         BHandler::MessageReceived(message);
    330         }
    331 }
     273                }
     274            }
     275            else if (formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
     276            {
     277                BMessage archivedBitmap;
     278                if (clip->FindMessage("image/bitmap", &archivedBitmap) == B_OK ||
     279                    clip->FindMessage("image/x-be-bitmap", &archivedBitmap) == B_OK)
     280                {
     281                    BBitmap *bitmap = new(std::nothrow) BBitmap(&archivedBitmap);
     282                    if (bitmap)
     283                    {
     284                        // Don't delete bitmap, BBitmapStream will.
     285                        BBitmapStream stream(bitmap);
     286                        BTranslatorRoster *roster = BTranslatorRoster::Default();
     287                        if (roster && bitmap->IsValid())
     288                        {
     289                            BMallocIO bmpStream;
     290                            if (roster->Translate(&stream, NULL, NULL, &bmpStream, B_BMP_FORMAT) == B_OK)
     291                            {
     292                                const void *pDib;
     293                                size_t cbDibSize;
     294                                /* Strip out the BM header */
     295                                rc = vboxClipboardBmpGetDib(bmpStream.Buffer(), bmpStream.BufferLength(), &pDib, &cbDibSize);
     296                                if (RT_SUCCESS(rc))
     297                                {
     298                                    rc = VbglR3ClipboardWriteData(fClientId,
     299                                                                  VBOX_SHARED_CLIPBOARD_FMT_BITMAP, (void *)pDib, cbDibSize);
     300                                }
     301                            }
     302                        }
     303                    }
     304                }
     305            }
     306
     307            be_clipboard->Unlock();
     308            break;
     309        }
     310
     311        case B_CLIPBOARD_CHANGED:
     312        {
     313            printf("B_CLIPBOARD_CHANGED\n");
     314            const void *data;
     315            int32 dataLen;
     316            if (!be_clipboard->Lock())
     317                break;
     318
     319            BMessage *clip = be_clipboard->Data();
     320            if (!clip)
     321            {
     322                be_clipboard->Unlock();
     323                break;
     324            }
     325
     326            bool fromVBox;
     327            if (clip->FindBool("FromVirtualBoxHost", &fromVBox) == B_OK && fromVBox)
     328            {
     329                // It already comes from the host, discard.
     330                be_clipboard->Unlock();
     331                break;
     332            }
     333
     334            if (clip->FindData("text/plain", B_MIME_TYPE, &data, &dataLen) == B_OK)
     335                formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
     336            if (clip->HasMessage("image/bitmap") || clip->HasMessage("image/x-be-bitmap"))
     337                formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
     338
     339            be_clipboard->Unlock();
     340
     341            VbglR3ClipboardReportFormats(fClientId, formats);
     342            break;
     343        }
     344
     345        case B_QUIT_REQUESTED:
     346            fExiting = true;
     347            break;
     348
     349        default:
     350            BHandler::MessageReceived(message);
     351    }
     352}
     353
    332354
    333355status_t VBoxClipboardService::_ServiceThreadNub(void *_this)
    334356{
    335         VBoxClipboardService *service = (VBoxClipboardService *)_this;
    336         return service->_ServiceThread();
    337 }
     357    VBoxClipboardService *service = (VBoxClipboardService *)_this;
     358    return service->_ServiceThread();
     359}
     360
    338361
    339362status_t VBoxClipboardService::_ServiceThread()
     
    347370        uint32_t u32Formats;
    348371        int rc = VbglR3ClipboardGetHostMsg(fClientId, &u32Msg, &u32Formats);
    349         if (RT_SUCCESS(rc)) {
    350             switch (u32Msg) {
     372        if (RT_SUCCESS(rc))
     373        {
     374            switch (u32Msg)
     375            {
    351376                case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS:
    352377                {
     
    374399                    /* The host is terminating. */
    375400                    LogRelFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT\n"));
    376                                         fExiting = true;
     401                    fExiting = true;
    377402                    return VERR_INTERRUPTED;
    378403                }
     
    381406                    Log(("VBoxClipboardService::%s: Unsupported message from host! Message = %u\n", __FUNCTION__, u32Msg));
    382407            }
    383         } else
    384                 fExiting = true;
     408        }
     409        else
     410            fExiting = true;
    385411
    386412        LogRelFlow(("processed host event rc = %d\n", rc));
    387413
    388414        if (fExiting)
    389                 break;
     415            break;
    390416    }
    391         return 0;
    392 }
    393 
    394 
    395 void *VBoxClipboardService::_VBoxReadHostClipboard(uint32_t format, uint32_t *pcb)
    396 {
    397         uint32_t cb = 1024;
    398         void *pv;
    399         int rc;
    400 
    401         pv = malloc(cb);
    402         if (pv == NULL)
    403                 return NULL;
    404 
    405         rc = VbglR3ClipboardReadData(fClientId, format, pv, cb, pcb);
     417    return 0;
     418}
     419
     420
     421void* VBoxClipboardService::_VBoxReadHostClipboard(uint32_t format, uint32_t *pcb)
     422{
     423    uint32_t cb = 1024;
     424    void *pv;
     425    int rc;
     426
     427    pv = malloc(cb);
     428    if (pv == NULL)
     429        return NULL;
     430
     431    rc = VbglR3ClipboardReadData(fClientId, format, pv, cb, pcb);
    406432    if (RT_SUCCESS(rc) && (rc != VINF_BUFFER_OVERFLOW))
    407433        return pv;
    408434    if (rc == VINF_BUFFER_OVERFLOW)
    409435    {
    410             free(pv);
    411             cb = *pcb;
    412         pv = malloc(cb);
    413                 if (pv == NULL)
    414                         return NULL;
    415 
    416                 rc = VbglR3ClipboardReadData(fClientId, format, pv, cb, pcb);
    417         if (RT_SUCCESS(rc) && (rc != VINF_BUFFER_OVERFLOW))
    418                 return pv;
    419 
    420             free(pv);
     436        free(pv);
     437        cb = *pcb;
     438        pv = malloc(cb);
     439        if (pv == NULL)
     440            return NULL;
     441
     442        rc = VbglR3ClipboardReadData(fClientId, format, pv, cb, pcb);
     443        if (RT_SUCCESS(rc) && (rc != VINF_BUFFER_OVERFLOW))
     444            return pv;
     445
     446        free(pv);
    421447    }
    422448    return NULL;
  • trunk/src/VBox/Additions/haiku/VBoxTray/VBoxClipboard.h

    r43363 r43364  
    5050#include <Handler.h>
    5151
    52 class VBoxClipboardService : public BHandler {
    53 public:
    54         VBoxClipboardService();
    55         virtual ~VBoxClipboardService();
     52class VBoxClipboardService : public BHandler
     53{
     54    public:
     55        VBoxClipboardService();
     56        virtual ~VBoxClipboardService();
    5657
    57         virtual status_t        Connect();
    58         virtual status_t        Disconnect();
     58        virtual status_t        Connect();
     59        virtual status_t        Disconnect();
    5960
    60         virtual void            MessageReceived(BMessage* message);
     61        virtual void            MessageReceived(BMessage *message);
    6162
    62 private:
     63    private:
    6364
    64 static status_t _ServiceThreadNub(void *_this);
    65         status_t        _ServiceThread();
     65        static status_t _ServiceThreadNub(void *_this);
     66        status_t        _ServiceThread();
    6667
    67         void            *_VBoxReadHostClipboard(uint32_t format, uint32_t *pcb);
     68        void* _VBoxReadHostClipboard(uint32_t format, uint32_t *pcb);
    6869
    69         uint32_t        fClientId;
    70         thread_id       fServiceThreadID;
    71         bool            fExiting;
     70        uint32_t        fClientId;
     71        thread_id       fServiceThreadID;
     72        bool            fExiting;
    7273
    7374};
  • trunk/src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.cpp

    r43363 r43364  
    7171
    7272VBoxDisplayService::VBoxDisplayService()
    73         : BHandler("VBoxDisplayService"),
    74         fClientId(-1),
    75         fServiceThreadID(-1),
    76         fExiting(false),
    77         fScreen(B_MAIN_SCREEN_ID)
     73     : BHandler("VBoxDisplayService"),
     74       fClientId(-1),
     75       fServiceThreadID(-1),
     76       fExiting(false),
     77       fScreen(B_MAIN_SCREEN_ID)
    7878{
    7979}
     80
    8081
    8182VBoxDisplayService::~VBoxDisplayService()
     
    8384}
    8485
     86
    8587void VBoxDisplayService::Start()
    8688{
    87         status_t err;
    88         err = fServiceThreadID = spawn_thread(_ServiceThreadNub,
    89                 "VBoxDisplayService", B_NORMAL_PRIORITY, this);
     89    status_t err;
     90    err = fServiceThreadID = spawn_thread(_ServiceThreadNub,
     91                                          "VBoxDisplayService", B_NORMAL_PRIORITY, this);
    9092
    91         if (err >= B_OK) {
    92                 resume_thread(fServiceThreadID);
    93         } else
    94                 LogRel(("VBoxDisplayService: Error starting service thread: %s\n", strerror(err)));
     93    if (err >= B_OK)
     94        resume_thread(fServiceThreadID);
     95    else
     96        LogRel(("VBoxDisplayService: Error starting service thread: %s\n", strerror(err)));
    9597
    9698}
    9799
    98 void VBoxDisplayService::MessageReceived(BMessage* message)
     100
     101void VBoxDisplayService::MessageReceived(BMessage *message)
    99102{
    100         if (message->what == B_QUIT_REQUESTED)
    101                 fExiting = true;
    102         else
    103                 BHandler::MessageReceived(message);
     103    if (message->what == B_QUIT_REQUESTED)
     104        fExiting = true;
     105    else
     106        BHandler::MessageReceived(message);
    104107}
     108
    105109
    106110status_t VBoxDisplayService::_ServiceThreadNub(void *_this)
    107111{
    108         VBoxDisplayService *service = (VBoxDisplayService *)_this;
    109         return service->_ServiceThread();
     112    VBoxDisplayService *service = (VBoxDisplayService *)_this;
     113    return service->_ServiceThread();
    110114}
     115
    111116
    112117status_t VBoxDisplayService::_ServiceThread()
     
    115120
    116121    VbglR3CtlFilterMask(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 0);
    117         VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0);
     122    VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0);
    118123
    119     for (;;) {
    120                 uint32_t events;
     124    for (;;)
     125    {
     126        uint32_t events;
    121127
    122                 int rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 5000, &events);
    123                 if (rc == -6) // timed out?
    124                         continue;
     128        int rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 5000, &events);
     129        if (rc == -6) // timed out?
     130            continue;
    125131
    126                 if (RT_SUCCESS(rc)) {
    127                         uint32_t cx, cy, cBits, iDisplay;
     132        if (RT_SUCCESS(rc))
     133        {
     134            uint32_t cx, cy, cBits, iDisplay;
    128135            int rc2 = VbglR3GetDisplayChangeRequest(&cx, &cy, &cBits, &iDisplay, true);
    129                         printf("rc2=%d screen %d size changed (%d, %d, %d)\n", rc2, iDisplay, cx, cy, cBits);
     136            printf("rc2=%d screen %d size changed (%d, %d, %d)\n", rc2, iDisplay, cx, cy, cBits);
    130137
    131                         if (RT_SUCCESS(rc2)) {
    132                                 display_mode mode;
    133                                 fScreen.GetMode(&mode);
    134                                 if (cBits == 0) {
    135                                         cBits = get_depth_for_color_space(mode.space);
    136                                 }
    137                                 mode.timing.h_display = cx;
    138                                 mode.timing.v_display = cy;
    139                                 mode.space = get_color_space_for_depth(cBits);
    140                                 mode.virtual_width = cx;
    141                                 mode.virtual_height = cy;
     138            if (RT_SUCCESS(rc2))
     139            {
     140                display_mode mode;
     141                fScreen.GetMode(&mode);
     142                if (cBits == 0)
     143                {
     144                    cBits = get_depth_for_color_space(mode.space);
     145                }
     146                mode.timing.h_display = cx;
     147                mode.timing.v_display = cy;
     148                mode.space = get_color_space_for_depth(cBits);
     149                mode.virtual_width = cx;
     150                mode.virtual_height = cy;
    142151
    143                                 /*= {
    144                                         {0, cx, 0, 0, cBits * cx / 8, cy, 0, 0, cBits * cy / 8, 0},
    145                                         get_color_space_for_depth(cBits),
    146                                         cx, cy, 0, 0, 0
    147                                 };*/
     152                /*= {
     153                    {0, cx, 0, 0, cBits * cx / 8, cy, 0, 0, cBits * cy / 8, 0},
     154                    get_color_space_for_depth(cBits),
     155                    cx, cy, 0, 0, 0
     156                };*/
    148157
    149                                 fScreen.SetMode(&mode, false);
    150                         }
     158                fScreen.SetMode(&mode, false);
     159            }
    151160        }
    152161        else
    153                 fExiting = true;
     162            fExiting = true;
    154163
    155164        LogRelFlow(("processed host event rc = %d\n", rc));
    156165
    157166        if (fExiting)
    158                 break;
     167            break;
    159168    }
    160         return 0;
     169    return 0;
    161170}
     171
  • trunk/src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.h

    r43363 r43364  
    5151#include <Screen.h>
    5252
    53 class VBoxDisplayService : public BHandler {
    54 public:
    55         VBoxDisplayService();
    56         virtual ~VBoxDisplayService();
     53class VBoxDisplayService : public BHandler
     54{
     55    public:
     56        VBoxDisplayService();
     57        virtual ~VBoxDisplayService();
    5758
    58         void            Start();
     59        void                Start();
    5960
    60         virtual void            MessageReceived(BMessage* message);
     61        virtual    void     MessageReceived(BMessage *message);
    6162
    62 private:
     63    private:
    6364
    64 static status_t _ServiceThreadNub(void *_this);
    65         status_t        _ServiceThread();
     65        static status_t     _ServiceThreadNub(void *_this);
     66        status_t            _ServiceThread();
    6667
    67         uint32_t        fClientId;
    68         thread_id       fServiceThreadID;
    69 volatile bool   fExiting;
    70         BScreen         fScreen;
     68        uint32_t            fClientId;
     69        thread_id           fServiceThreadID;
     70        volatile bool       fExiting;
     71        BScreen             fScreen;
    7172};
    7273
     74#endif /* __VBOXSERVICESHAREDCLIPLBOARD__H */
    7375
    74 #endif /* __VBOXSERVICESHAREDCLIPLBOARD__H */
  • trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestApplication.cpp

    r43363 r43364  
    6060
    6161VBoxGuestApplication::VBoxGuestApplication()
    62         : BApplication(VBOX_GUEST_APP_SIG)
     62     : BApplication(VBOX_GUEST_APP_SIG)
    6363{
    64         PRINT(("%s()\n", __FUNCTION__));
     64    PRINT(("%s()\n", __FUNCTION__));
    6565}
     66
    6667
    6768VBoxGuestApplication::~VBoxGuestApplication()
    6869{
    69         PRINT(("%s()\n", __FUNCTION__));
     70    PRINT(("%s()\n", __FUNCTION__));
    7071}
     72
    7173
    7274void VBoxGuestApplication::ReadyToRun()
    7375{
    74         status_t err;
     76    status_t err;
    7577
    76         err = VBoxGuestDeskbarView::AddToDeskbar();
    77         PRINT(("%s: VBoxGuestDeskbarView::AddToDeskbar: 0x%08lx\n", __FUNCTION__, err));
     78    err = VBoxGuestDeskbarView::AddToDeskbar();
     79    PRINT(("%s: VBoxGuestDeskbarView::AddToDeskbar: 0x%08lx\n", __FUNCTION__, err));
    7880
    79         exit(0);
     81    exit(0);
    8082}
     83
    8184
    8285int main(int argc, const char **argv)
    8386{
    84         new VBoxGuestApplication();
    85         be_app->Run();
    86         delete be_app;
     87    new VBoxGuestApplication();
     88    be_app->Run();
     89    delete be_app;
    8790
    8891/*    int rc = RTR3Init();
     
    9699    if (RT_SUCCESS(rc))
    97100    {
    98             Log(("VBoxGuestApp: Init successful\n"));
     101        Log(("VBoxGuestApp: Init successful\n"));
    99102
    100                 new VBoxGuestApplication(gVBoxDriverFD);
    101                 be_app->Run();
    102                 delete be_app;
     103        new VBoxGuestApplication(gVBoxDriverFD);
     104        be_app->Run();
     105        delete be_app;
    103106
    104107    }
    105108
    106         if (RT_FAILURE(rc))
     109    if (RT_FAILURE(rc))
    107110    {
    108111        LogRel(("VBoxGuestApp: Error while starting, rc=%Rrc\n", rc));
     
    110113    LogRel(("VBoxGuestApp: Ended\n"));
    111114
    112         vboxCloseBaseDriver();
     115    vboxCloseBaseDriver();
    113116
    114117    VbglR3Term();*/
    115118
    116         return 0;
     119    return 0;
    117120}
     121
  • trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestDeskbarView.cpp

    r43363 r43364  
    6969our_image(image_info& image)
    7070{
    71         /** @todo r=ramshankar: find a way to do this without annoying the compiler, probably uintptr_t? */
    72         int32 cookie = 0;
    73         while (get_next_image_info(B_CURRENT_TEAM, &cookie, &image) == B_OK) {
    74                 if ((char *)our_image >= (char *)image.text
    75                         && (char *)our_image <= (char *)image.text + image.text_size)
    76                         return B_OK;
    77         }
    78 
    79         return B_ERROR;
     71    /** @todo r=ramshankar: find a way to do this without annoying the compiler, probably uintptr_t? */
     72    int32 cookie = 0;
     73    while (get_next_image_info(B_CURRENT_TEAM, &cookie, &image) == B_OK)
     74    {
     75        if ((char *)our_image >= (char *)image.text
     76            && (char *)our_image <= (char *)image.text + image.text_size)
     77            return B_OK;
     78    }
     79
     80    return B_ERROR;
    8081}
    8182
    8283
    8384VBoxGuestDeskbarView::VBoxGuestDeskbarView()
    84         : BView(BRect(0, 0, 15, 15), VIEWNAME, B_FOLLOW_NONE,
    85                 B_WILL_DRAW | B_NAVIGABLE),
    86         fIcon(NULL), fClipboardService(NULL), fDisplayService(NULL)
    87 {
    88         PRINT(("%s()\n", __FUNCTION__));
    89         _Init();
    90 }
     85     : BView(BRect(0, 0, 15, 15), VIEWNAME, B_FOLLOW_NONE,
     86             B_WILL_DRAW | B_NAVIGABLE),
     87       fIcon(NULL), fClipboardService(NULL), fDisplayService(NULL)
     88{
     89    PRINT(("%s()\n", __FUNCTION__));
     90    _Init();
     91}
     92
    9193
    9294VBoxGuestDeskbarView::VBoxGuestDeskbarView(BMessage *archive)
    93         : BView(archive),
    94         fIcon(NULL)
    95 {
    96         PRINT(("%s()\n", __FUNCTION__));
    97         archive->PrintToStream();
    98 
    99         _Init(archive);
    100 }
     95     : BView(archive),
     96       fIcon(NULL)
     97{
     98    PRINT(("%s()\n", __FUNCTION__));
     99    archive->PrintToStream();
     100
     101    _Init(archive);
     102}
     103
    101104
    102105VBoxGuestDeskbarView::~VBoxGuestDeskbarView()
    103106{
    104         PRINT(("%s()\n", __FUNCTION__));
    105         delete fIcon;
    106         if (fClipboardService) {
    107                 fClipboardService->Disconnect();
    108                 delete fClipboardService;
    109         }
    110         VbglR3Term();
    111 }
    112 
    113 BArchivable *VBoxGuestDeskbarView::Instantiate(BMessage *data)
    114 {
    115         PRINT(("%s()\n", __FUNCTION__));
    116         if (!validate_instantiation(data, VIEWNAME))
    117                 return NULL;
    118 
    119         return new VBoxGuestDeskbarView(data);
    120 }
     107    PRINT(("%s()\n", __FUNCTION__));
     108    delete fIcon;
     109    if (fClipboardService)
     110    {
     111        fClipboardService->Disconnect();
     112        delete fClipboardService;
     113    }
     114    VbglR3Term();
     115}
     116
     117
     118BArchivable* VBoxGuestDeskbarView::Instantiate(BMessage *data)
     119{
     120    PRINT(("%s()\n", __FUNCTION__));
     121    if (!validate_instantiation(data, VIEWNAME))
     122        return NULL;
     123
     124    return new VBoxGuestDeskbarView(data);
     125}
     126
    121127
    122128status_t VBoxGuestDeskbarView::Archive(BMessage *data, bool deep) const
    123129{
    124         status_t err;
    125         PRINT(("%s()\n", __FUNCTION__));
    126 
    127         err = BView::Archive(data, false);
    128         if (err < B_OK)
    129                 return err;
    130         data->AddString("add_on", VBOX_GUEST_APP_SIG);
    131         data->AddString("class", "VBoxGuestDeskbarView");
    132         return B_OK;
    133 }
     130    status_t err;
     131    PRINT(("%s()\n", __FUNCTION__));
     132
     133    err = BView::Archive(data, false);
     134    if (err < B_OK)
     135        return err;
     136    data->AddString("add_on", VBOX_GUEST_APP_SIG);
     137    data->AddString("class", "VBoxGuestDeskbarView");
     138    return B_OK;
     139}
     140
    134141
    135142void VBoxGuestDeskbarView::Draw(BRect rect)
    136143{
    137         SetDrawingMode(B_OP_ALPHA);
    138         DrawBitmap(fIcon);
    139 }
     144    SetDrawingMode(B_OP_ALPHA);
     145    DrawBitmap(fIcon);
     146}
     147
    140148
    141149void VBoxGuestDeskbarView::AttachedToWindow()
    142150{
    143         BView::AttachedToWindow();
    144         if (Parent()) {
    145                 SetViewColor(Parent()->ViewColor());
    146                 SetLowColor(Parent()->LowColor());
    147         }
    148 
    149         if (fClipboardService) { // don't repeatedly crash deskbar if vboxdev not loaded
    150                 Looper()->AddHandler(fClipboardService);
    151                 fClipboardService->Connect();
    152         }
    153 
    154         if (fDisplayService) {
    155                 fDisplayService->Start();
    156         }
    157 }
     151    BView::AttachedToWindow();
     152    if (Parent())
     153    {
     154        SetViewColor(Parent()->ViewColor());
     155        SetLowColor(Parent()->LowColor());
     156    }
     157
     158    if (fClipboardService) // don't repeatedly crash deskbar if vboxdev not loaded
     159    {
     160        Looper()->AddHandler(fClipboardService);
     161        fClipboardService->Connect();
     162    }
     163
     164    if (fDisplayService)
     165    {
     166        fDisplayService->Start();
     167    }
     168}
     169
    158170
    159171void VBoxGuestDeskbarView::DetachedFromWindow()
    160172{
    161         BMessage message(B_QUIT_REQUESTED);
    162         fClipboardService->MessageReceived(&message);
    163         fDisplayService->MessageReceived(&message);
    164 }
     173    BMessage message(B_QUIT_REQUESTED);
     174    fClipboardService->MessageReceived(&message);
     175    fDisplayService->MessageReceived(&message);
     176}
     177
    165178
    166179void VBoxGuestDeskbarView::MouseDown(BPoint point)
    167180{
    168         printf("MouseDown\n");
    169         int32 buttons = B_PRIMARY_MOUSE_BUTTON;
    170         if (Looper() != NULL && Looper()->CurrentMessage() != NULL)
    171                 Looper()->CurrentMessage()->FindInt32("buttons", &buttons);
    172 
    173         BPoint where = ConvertToScreen(point);
    174 
    175         if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0) {
    176                 BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
    177                 menu->SetAsyncAutoDestruct(true);
    178                 menu->SetFont(be_plain_font);
    179 
    180                 menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED)));
    181                 menu->SetTargetForItems(this);
    182 
    183                 menu->Go(where, true, true, true);
    184         }
    185 }
    186 
    187 void VBoxGuestDeskbarView::MessageReceived(BMessage* message)
    188 {
    189         if (message->what == B_QUIT_REQUESTED)
    190                 RemoveFromDeskbar();
    191         else
    192                 BHandler::MessageReceived(message);
    193 }
     181    printf("MouseDown\n");
     182    int32 buttons = B_PRIMARY_MOUSE_BUTTON;
     183    if (Looper() != NULL && Looper()->CurrentMessage() != NULL)
     184        Looper()->CurrentMessage()->FindInt32("buttons", &buttons);
     185
     186    BPoint where = ConvertToScreen(point);
     187
     188    if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0)
     189    {
     190        BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
     191        menu->SetAsyncAutoDestruct(true);
     192        menu->SetFont(be_plain_font);
     193
     194        menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED)));
     195        menu->SetTargetForItems(this);
     196
     197        menu->Go(where, true, true, true);
     198    }
     199}
     200
     201
     202void VBoxGuestDeskbarView::MessageReceived(BMessage *message)
     203{
     204    if (message->what == B_QUIT_REQUESTED)
     205        RemoveFromDeskbar();
     206    else
     207        BHandler::MessageReceived(message);
     208}
     209
    194210
    195211status_t VBoxGuestDeskbarView::AddToDeskbar(bool force)
    196212{
    197         BDeskbar deskbar;
    198         status_t err;
    199         PRINT(("%s()\n", __FUNCTION__));
    200 
    201         if (force)
    202                 RemoveFromDeskbar();
    203         else if (deskbar.HasItem(VIEWNAME))
    204                 return B_OK;
    205 
    206         app_info info;
    207         err = be_app->GetAppInfo(&info);
    208         PRINT(("%s: be_app->GetAppInfo: 0x%08lx\n", __FUNCTION__, err));
    209         if (err < B_OK)
    210                 return err;
    211 
    212         BPath p(&info.ref);
    213         PRINT(("%s: app path: '%s'\n", __FUNCTION__, p.Path()));
    214 
    215         return deskbar.AddItem(&info.ref);
    216 }
     213    BDeskbar deskbar;
     214    status_t err;
     215    PRINT(("%s()\n", __FUNCTION__));
     216
     217    if (force)
     218        RemoveFromDeskbar();
     219    else if (deskbar.HasItem(VIEWNAME))
     220        return B_OK;
     221
     222    app_info info;
     223    err = be_app->GetAppInfo(&info);
     224    PRINT(("%s: be_app->GetAppInfo: 0x%08lx\n", __FUNCTION__, err));
     225    if (err < B_OK)
     226        return err;
     227
     228    BPath p(&info.ref);
     229    PRINT(("%s: app path: '%s'\n", __FUNCTION__, p.Path()));
     230
     231    return deskbar.AddItem(&info.ref);
     232}
     233
    217234
    218235status_t VBoxGuestDeskbarView::RemoveFromDeskbar()
    219236{
    220         BDeskbar deskbar;
    221         PRINT(("%s()\n", __FUNCTION__));
    222 
    223         return deskbar.RemoveItem(VIEWNAME);
    224 }
     237    BDeskbar deskbar;
     238    PRINT(("%s()\n", __FUNCTION__));
     239
     240    return deskbar.RemoveItem(VIEWNAME);
     241}
     242
    225243
    226244status_t VBoxGuestDeskbarView::_Init(BMessage *archive)
    227245{
    228         BString toolTipText;
    229         toolTipText << VBOX_PRODUCT << " Guest Additions ";
    230         toolTipText << VBOX_VERSION_MAJOR << "." << VBOX_VERSION_MINOR << "." << VBOX_VERSION_BUILD;
    231         toolTipText << "r" << VBOX_SVN_REV;
    232 
    233         SetToolTip(toolTipText.String());
    234 
    235         image_info info;
    236         if (our_image(info) != B_OK)
    237                 return B_ERROR;
    238 
    239         BFile file(info.name, B_READ_ONLY);
    240         if (file.InitCheck() < B_OK)
    241                 return B_ERROR;
    242 
    243         BResources resources(&file);
    244         if (resources.InitCheck() < B_OK)
    245                 return B_ERROR;
    246 
    247         const void* data = NULL;
    248         size_t size;
    249         //data = resources.LoadResource(B_VECTOR_ICON_TYPE,
    250         //      kNetworkStatusNoDevice + i, &size);
    251         data = resources.LoadResource('data', 400, &size);
    252         if (data != NULL) {
    253                 BMemoryIO mem(data, size);
    254                 fIcon = BTranslationUtils::GetBitmap(&mem);
    255         }
     246    BString toolTipText;
     247    toolTipText << VBOX_PRODUCT << " Guest Additions ";
     248    toolTipText << VBOX_VERSION_MAJOR << "." << VBOX_VERSION_MINOR << "." << VBOX_VERSION_BUILD;
     249    toolTipText << "r" << VBOX_SVN_REV;
     250
     251    SetToolTip(toolTipText.String());
     252
     253    image_info info;
     254    if (our_image(info) != B_OK)
     255        return B_ERROR;
     256
     257    BFile file(info.name, B_READ_ONLY);
     258    if (file.InitCheck() < B_OK)
     259        return B_ERROR;
     260
     261    BResources resources(&file);
     262    if (resources.InitCheck() < B_OK)
     263        return B_ERROR;
     264
     265    const void *data = NULL;
     266    size_t size;
     267    //data = resources.LoadResource(B_VECTOR_ICON_TYPE,
     268    //    kNetworkStatusNoDevice + i, &size);
     269    data = resources.LoadResource('data', 400, &size);
     270    if (data != NULL)
     271    {
     272        BMemoryIO mem(data, size);
     273        fIcon = BTranslationUtils::GetBitmap(&mem);
     274    }
    256275
    257276    int rc = RTR3InitDll(0);
    258         printf("%d\n", rc);
    259     if (RT_SUCCESS(rc)) {
     277    printf("%d\n", rc);
     278    if (RT_SUCCESS(rc))
     279    {
    260280        rc = VbglR3Init();
    261281    }
    262         printf("%d\n", rc);
    263         if (RT_SUCCESS(rc)) {
    264                 fClipboardService = new VBoxClipboardService();
    265                 fDisplayService = new VBoxDisplayService();
    266         }
    267 
    268         return RTErrConvertToErrno(rc);
    269 }
    270 
    271 extern "C" BView*
    272 instantiate_deskbar_item(void)
    273 {
    274         PRINT(("%s()\n", __FUNCTION__));
    275         return new VBoxGuestDeskbarView();
    276 }
    277 
     282    printf("%d\n", rc);
     283    if (RT_SUCCESS(rc))
     284    {
     285        fClipboardService = new VBoxClipboardService();
     286        fDisplayService = new VBoxDisplayService();
     287    }
     288
     289    return RTErrConvertToErrno(rc);
     290}
     291
     292
     293RTDECL(BView*) instantiate_deskbar_item()
     294{
     295    PRINT(("%s()\n", __FUNCTION__));
     296    return new VBoxGuestDeskbarView();
     297}
     298
  • trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestDeskbarView.h

    r43363 r43364  
    6565#define REMOVE_FROM_DESKBAR_MSG 'vbqr'
    6666
    67 class VBoxGuestDeskbarView : public BView {
    68 public:
    69                         VBoxGuestDeskbarView();
    70                         VBoxGuestDeskbarView(BMessage *archive);
    71         virtual ~VBoxGuestDeskbarView();
    72         static  BArchivable     *Instantiate(BMessage *data);
    73         virtual status_t        Archive(BMessage *data, bool deep = true) const;
     67class VBoxGuestDeskbarView : public BView
     68{
     69    public:
     70        VBoxGuestDeskbarView();
     71        VBoxGuestDeskbarView(BMessage *archive);
     72        virtual ~VBoxGuestDeskbarView();
    7473
    75                         void            Draw(BRect rect);
    76                         void            AttachedToWindow();
    77                         void            DetachedFromWindow();
     74                static  BArchivable*   Instantiate(BMessage *data);
     75        virtual status_t       Archive(BMessage *data, bool deep = true) const;
    7876
    79         virtual void            MouseDown(BPoint point);
    80         virtual void            MessageReceived(BMessage* message);
     77        void                   Draw(BRect rect);
     78        void                   AttachedToWindow();
     79        void                   DetachedFromWindow();
    8180
    82         static status_t         AddToDeskbar(bool force=true);
    83         static status_t         RemoveFromDeskbar();
     81        virtual    void        MouseDown(BPoint point);
     82        virtual void           MessageReceived(BMessage *message);
    8483
    85 private:
    86         status_t                        _Init(BMessage *archive=NULL);
    87         BBitmap                         *fIcon;
     84        static status_t        AddToDeskbar(bool force = true);
     85        static status_t        RemoveFromDeskbar();
    8886
    89         VBoxClipboardService *fClipboardService;
    90         VBoxDisplayService *fDisplayService;
     87    private:
     88        status_t               _Init(BMessage *archive = NULL);
     89        BBitmap               *fIcon;
     90
     91        VBoxClipboardService *fClipboardService;
     92        VBoxDisplayService *fDisplayService;
    9193};
    9294
    9395#endif /* __VBOXGUESTTRAYVIEW__H */
     96
  • trunk/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.cpp

    r43363 r43364  
    5353#define TRACE(x...) do { FILE* logfile = fopen("/var/log/vboxvideo.accelerant.log", "a"); fprintf(logfile, x); fflush(logfile); fsync(fileno(logfile)); fclose(logfile); sync(); } while(0)
    5454
    55 class AreaCloner {
    56         public:
    57                 AreaCloner() : fArea(-1) {}
    58                 ~AreaCloner() {
    59                         if (fArea >= B_OK)
    60                                 delete_area(fArea);
    61                 }
    62 
    63                 area_id Clone(const char *name, void **_address, uint32 spec, uint32 protection, area_id sourceArea) {
    64                         fArea = clone_area(name, _address, spec, protection, sourceArea);
    65                         return fArea;
    66                 }
    67 
    68                 status_t InitCheck() { return fArea < B_OK ? (status_t)fArea : B_OK; }
    69                 void Keep() { fArea = -1; }
    70 
    71         private:
    72                 area_id fArea;
     55class AreaCloner
     56{
     57    public:
     58        AreaCloner() : fArea(-1) { }
     59        ~AreaCloner()
     60        {
     61            if (fArea >= B_OK)
     62                delete_area(fArea);
     63        }
     64
     65        area_id Clone(const char *name, void **_address, uint32 spec, uint32 protection, area_id sourceArea)
     66        {
     67            fArea = clone_area(name, _address, spec, protection, sourceArea);
     68            return fArea;
     69        }
     70
     71        status_t InitCheck() { return fArea < B_OK ? (status_t)fArea : B_OK; }
     72        void Keep() { fArea = -1; }
     73
     74    private:
     75        area_id    fArea;
    7376};
    7477
    7578AccelerantInfo gInfo;
    7679
    77 static engine_token sEngineToken = {1, 0 /*B_2D_ACCELERATION*/, NULL};
    78 
    79 extern "C" void* get_accelerant_hook(uint32 feature, void* data) {
    80         TRACE("%s\n", __FUNCTION__);
    81         switch (feature) {
    82                 /* general */
    83                 case B_INIT_ACCELERANT:
    84                         return (void*)vboxvideo_init_accelerant;
    85                 case B_UNINIT_ACCELERANT:
    86                         return (void*)vboxvideo_uninit_accelerant;
    87                 case B_CLONE_ACCELERANT:
    88                         return (void*)vboxvideo_clone_accelerant;
    89                 case B_ACCELERANT_CLONE_INFO_SIZE:
    90                         return (void*)vboxvideo_accelerant_clone_info_size;
    91                 case B_GET_ACCELERANT_CLONE_INFO:
    92                         return (void*)vboxvideo_get_accelerant_clone_info;
    93                 case B_GET_ACCELERANT_DEVICE_INFO:
    94                         return (void*)vboxvideo_get_accelerant_device_info;
    95                 case B_ACCELERANT_RETRACE_SEMAPHORE:
    96                         return (void*)vboxvideo_accelerant_retrace_semaphore;
    97 
    98                 /* mode configuration */
    99                 case B_ACCELERANT_MODE_COUNT:
    100                         return (void*)vboxvideo_accelerant_mode_count;
    101                 case B_GET_MODE_LIST:
    102                         return (void*)vboxvideo_get_mode_list;
    103                 case B_SET_DISPLAY_MODE:
    104                         return (void*)vboxvideo_set_display_mode;
    105                 case B_GET_DISPLAY_MODE:
    106                         return (void*)vboxvideo_get_display_mode;
    107                 case B_GET_EDID_INFO:
    108                         return (void*)vboxvideo_get_edid_info;
    109                 case B_GET_FRAME_BUFFER_CONFIG:
    110                         return (void*)vboxvideo_get_frame_buffer_config;
    111                 case B_GET_PIXEL_CLOCK_LIMITS:
    112                         return (void*)vboxvideo_get_pixel_clock_limits;
    113 
    114                 /* cursor managment */
    115                 /*case B_SET_CURSOR_SHAPE:
    116                         return (void*)vboxvideo_set_cursor_shape;
    117                 case B_MOVE_CURSOR:
    118                         return (void*)vboxvideo_move_cursor;
    119                 case B_SHOW_CURSOR:
    120                         return (void*)vboxvideo_show_cursor;*/
    121 
    122                 /* engine/synchronization */
    123                 case B_ACCELERANT_ENGINE_COUNT:
    124                         return (void*)vboxvideo_accelerant_engine_count;
    125                 case B_ACQUIRE_ENGINE:
    126                         return (void*)vboxvideo_acquire_engine;
    127                 case B_RELEASE_ENGINE:
    128                         return (void*)vboxvideo_release_engine;
    129                 case B_WAIT_ENGINE_IDLE:
    130                         return (void*)vboxvideo_wait_engine_idle;
    131                 case B_GET_SYNC_TOKEN:
    132                         return (void*)vboxvideo_get_sync_token;
    133                 case B_SYNC_TO_TOKEN:
    134                         return (void*)vboxvideo_sync_to_token;
    135         }
    136 
    137         return NULL;
    138 }
    139 
    140 status_t vboxvideo_init_common(int fd, bool cloned) {
    141         unlink("/var/log/vboxvideo.accelerant.log"); // clear old log - next TRACE() will recreate it
    142         TRACE("%s\n", __FUNCTION__);
    143 
    144         gInfo.deviceFD = fd;
    145         gInfo.isClone = cloned;
    146         gInfo.sharedInfo = NULL;
    147         gInfo.sharedInfoArea = -1;
    148 
    149         area_id sharedArea;
    150         if (ioctl(gInfo.deviceFD, VBOXVIDEO_GET_PRIVATE_DATA, &sharedArea, sizeof(area_id)) != 0) {
    151                 TRACE("ioctl failed\n");
    152                 return B_ERROR;
    153         }
    154 
    155         AreaCloner sharedCloner;
    156         gInfo.sharedInfoArea = sharedCloner.Clone("vboxvideo shared info",
    157                 (void **)&gInfo.sharedInfo, B_ANY_ADDRESS,
    158                 B_READ_AREA | B_WRITE_AREA, sharedArea);
    159         status_t status = sharedCloner.InitCheck();
    160         if (status < B_OK) {
    161                 TRACE("InitCheck failed (%s)\n", strerror(status));
    162                 return status;
    163         }
    164         sharedCloner.Keep();
    165 
    166         return B_OK;
    167 }
    168 
    169 status_t vboxvideo_init_accelerant(int fd) {
    170         return vboxvideo_init_common(fd, false);
    171 }
    172 
    173 ssize_t vboxvideo_accelerant_clone_info_size(void) {
    174         TRACE("%s\n", __FUNCTION__);
    175         return B_PATH_NAME_LENGTH;
    176 }
    177 
    178 void vboxvideo_get_accelerant_clone_info(void *data) {
    179         TRACE("%s\n", __FUNCTION__);
    180         ioctl(gInfo.deviceFD, VBOXVIDEO_GET_DEVICE_NAME, data, B_PATH_NAME_LENGTH);
    181 }
    182 
    183 status_t vboxvideo_clone_accelerant(void *data) {
    184         TRACE("%s\n", __FUNCTION__);
    185 
    186         // create full device name
    187         char path[MAXPATHLEN];
    188         strcpy(path, "/dev/");
    189         strcat(path, (const char *)data);
    190 
    191         int fd = open(path, B_READ_WRITE);
    192         if (fd < 0)
    193                 return errno;
    194 
    195         return vboxvideo_init_common(fd, true);
    196 }
    197 
    198 void vboxvideo_uninit_accelerant(void) {
    199         delete_area(gInfo.sharedInfoArea);
    200         gInfo.sharedInfo = NULL;
    201         gInfo.sharedInfoArea = -1;
    202 
    203         if (gInfo.isClone)
    204                 close(gInfo.deviceFD);
    205 
    206         TRACE("%s\n", __FUNCTION__);
    207 }
    208 
    209 status_t vboxvideo_get_accelerant_device_info(accelerant_device_info *adi) {
    210         TRACE("%s\n", __FUNCTION__);
    211         adi->version = B_ACCELERANT_VERSION;
    212         strcpy(adi->name, "Virtual display");
    213         strcpy(adi->chipset, "VirtualBox Graphics Adapter");
    214         strcpy(adi->serial_no, "9001");
    215         return B_OK;
    216 }
    217 
    218 sem_id vboxvideo_accelerant_retrace_semaphore(void) {
    219         TRACE("%s\n", __FUNCTION__);
    220         return -1;
     80static engine_token sEngineToken = { 1, 0 /*B_2D_ACCELERATION*/, NULL };
     81
     82extern "C"
     83void* get_accelerant_hook(uint32 feature, void *data)
     84{
     85    TRACE("%s\n", __FUNCTION__);
     86    switch (feature)
     87    {
     88        /* general */
     89        case B_INIT_ACCELERANT:
     90            return (void *)vboxvideo_init_accelerant;
     91        case B_UNINIT_ACCELERANT:
     92            return (void *)vboxvideo_uninit_accelerant;
     93        case B_CLONE_ACCELERANT:
     94            return (void *)vboxvideo_clone_accelerant;
     95        case B_ACCELERANT_CLONE_INFO_SIZE:
     96            return (void *)vboxvideo_accelerant_clone_info_size;
     97        case B_GET_ACCELERANT_CLONE_INFO:
     98            return (void *)vboxvideo_get_accelerant_clone_info;
     99        case B_GET_ACCELERANT_DEVICE_INFO:
     100            return (void *)vboxvideo_get_accelerant_device_info;
     101        case B_ACCELERANT_RETRACE_SEMAPHORE:
     102            return (void *)vboxvideo_accelerant_retrace_semaphore;
     103
     104            /* mode configuration */
     105        case B_ACCELERANT_MODE_COUNT:
     106            return (void *)vboxvideo_accelerant_mode_count;
     107        case B_GET_MODE_LIST:
     108            return (void *)vboxvideo_get_mode_list;
     109        case B_SET_DISPLAY_MODE:
     110            return (void *)vboxvideo_set_display_mode;
     111        case B_GET_DISPLAY_MODE:
     112            return (void *)vboxvideo_get_display_mode;
     113        case B_GET_EDID_INFO:
     114            return (void *)vboxvideo_get_edid_info;
     115        case B_GET_FRAME_BUFFER_CONFIG:
     116            return (void *)vboxvideo_get_frame_buffer_config;
     117        case B_GET_PIXEL_CLOCK_LIMITS:
     118            return (void *)vboxvideo_get_pixel_clock_limits;
     119
     120            /* cursor managment */
     121            /*case B_SET_CURSOR_SHAPE:
     122                return (void*)vboxvideo_set_cursor_shape;
     123            case B_MOVE_CURSOR:
     124                return (void*)vboxvideo_move_cursor;
     125            case B_SHOW_CURSOR:
     126                return (void*)vboxvideo_show_cursor;*/
     127
     128            /* engine/synchronization */
     129        case B_ACCELERANT_ENGINE_COUNT:
     130            return (void *)vboxvideo_accelerant_engine_count;
     131        case B_ACQUIRE_ENGINE:
     132            return (void *)vboxvideo_acquire_engine;
     133        case B_RELEASE_ENGINE:
     134            return (void *)vboxvideo_release_engine;
     135        case B_WAIT_ENGINE_IDLE:
     136            return (void *)vboxvideo_wait_engine_idle;
     137        case B_GET_SYNC_TOKEN:
     138            return (void *)vboxvideo_get_sync_token;
     139        case B_SYNC_TO_TOKEN:
     140            return (void *)vboxvideo_sync_to_token;
     141    }
     142
     143    return NULL;
     144}
     145
     146status_t vboxvideo_init_common(int fd, bool cloned)
     147{
     148    unlink("/var/log/vboxvideo.accelerant.log"); // clear old log - next TRACE() will recreate it
     149    TRACE("%s\n", __FUNCTION__);
     150
     151    gInfo.deviceFD = fd;
     152    gInfo.isClone = cloned;
     153    gInfo.sharedInfo = NULL;
     154    gInfo.sharedInfoArea = -1;
     155
     156    area_id sharedArea;
     157    if (ioctl(gInfo.deviceFD, VBOXVIDEO_GET_PRIVATE_DATA, &sharedArea, sizeof(area_id)) != 0)
     158    {
     159        TRACE("ioctl failed\n");
     160        return B_ERROR;
     161    }
     162
     163    AreaCloner sharedCloner;
     164    gInfo.sharedInfoArea = sharedCloner.Clone("vboxvideo shared info",
     165                                              (void **)&gInfo.sharedInfo, B_ANY_ADDRESS,
     166                                              B_READ_AREA | B_WRITE_AREA, sharedArea);
     167    status_t status = sharedCloner.InitCheck();
     168    if (status < B_OK)
     169    {
     170        TRACE("InitCheck failed (%s)\n", strerror(status));
     171        return status;
     172    }
     173    sharedCloner.Keep();
     174
     175    return B_OK;
     176}
     177
     178status_t vboxvideo_init_accelerant(int fd)
     179{
     180    return vboxvideo_init_common(fd, false);
     181}
     182
     183ssize_t vboxvideo_accelerant_clone_info_size(void)
     184{
     185    TRACE("%s\n", __FUNCTION__);
     186    return B_PATH_NAME_LENGTH;
     187}
     188
     189void vboxvideo_get_accelerant_clone_info(void *data)
     190{
     191    TRACE("%s\n", __FUNCTION__);
     192    ioctl(gInfo.deviceFD, VBOXVIDEO_GET_DEVICE_NAME, data, B_PATH_NAME_LENGTH);
     193}
     194
     195status_t vboxvideo_clone_accelerant(void *data)
     196{
     197    TRACE("%s\n", __FUNCTION__);
     198
     199    // create full device name
     200    char path[MAXPATHLEN];
     201    strcpy(path, "/dev/");
     202    strcat(path, (const char *)data);
     203
     204    int fd = open(path, B_READ_WRITE);
     205    if (fd < 0)
     206        return errno;
     207
     208    return vboxvideo_init_common(fd, true);
     209}
     210
     211void vboxvideo_uninit_accelerant(void)
     212{
     213    delete_area(gInfo.sharedInfoArea);
     214    gInfo.sharedInfo = NULL;
     215    gInfo.sharedInfoArea = -1;
     216
     217    if (gInfo.isClone)
     218        close(gInfo.deviceFD);
     219
     220    TRACE("%s\n", __FUNCTION__);
     221}
     222
     223status_t vboxvideo_get_accelerant_device_info(accelerant_device_info *adi)
     224{
     225    TRACE("%s\n", __FUNCTION__);
     226    adi->version = B_ACCELERANT_VERSION;
     227    strcpy(adi->name, "Virtual display");
     228    strcpy(adi->chipset, "VirtualBox Graphics Adapter");
     229    strcpy(adi->serial_no, "9001");
     230    return B_OK;
     231}
     232
     233sem_id vboxvideo_accelerant_retrace_semaphore(void)
     234{
     235    TRACE("%s\n", __FUNCTION__);
     236    return -1;
    221237}
    222238
    223239// modes & constraints
    224 uint32 vboxvideo_accelerant_mode_count(void) {
    225         TRACE("%s\n", __FUNCTION__);
    226         return 1;
    227 }
    228 
    229 status_t vboxvideo_get_mode_list(display_mode *dm) {
    230         // TODO return some standard modes here
    231         TRACE("%s\n", __FUNCTION__);
    232         return vboxvideo_get_display_mode(dm);
    233 }
    234 
    235 status_t vboxvideo_set_display_mode(display_mode *modeToSet) {
    236         TRACE("%s\n", __FUNCTION__);
    237         TRACE("trying to set mode %dx%d\n", modeToSet->timing.h_display, modeToSet->timing.v_display);
    238         return ioctl(gInfo.deviceFD, VBOXVIDEO_SET_DISPLAY_MODE, modeToSet, sizeof(display_mode));
    239 }
    240 
    241 status_t vboxvideo_get_display_mode(display_mode *currentMode) {
    242         TRACE("%s\n", __FUNCTION__);
    243         *currentMode = gInfo.sharedInfo->currentMode;
    244         TRACE("current mode is %dx%d\n", currentMode->timing.h_display, currentMode->timing.v_display);
    245         return B_OK;
    246 }
    247 
    248 status_t vboxvideo_get_edid_info(void *info, size_t size, uint32 *_version) {
    249         TRACE("%s\n", __FUNCTION__);
    250 
    251         // copied from the X11 implementation:
    252         static const uint8 edid_data[128] = {
    253                 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
    254                 0x58, 0x58, /* manufacturer (VBX) */
    255                 0x00, 0x00, /* product code */
    256                 0x00, 0x00, 0x00, 0x00, /* serial number goes here */
    257                 0x01, /* week of manufacture */
    258                 0x00, /* year of manufacture */
    259                 0x01, 0x03, /* EDID version */
    260                 0x80, /* capabilities - digital */
    261                 0x00, /* horiz. res in cm, zero for projectors */
    262                 0x00, /* vert. res in cm */
    263                 0x78, /* display gamma (120 == 2.2).  Should we ask the host for this? */
    264                 0xEE, /* features (standby, suspend, off, RGB, standard colour space,
    265                                 * preferred timing mode) */
    266                 0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
    267                         /* chromaticity for standard colour space - should we ask the host? */
    268                 0x00, 0x00, 0x00, /* no default timings */
    269                 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    270                 0x01, 0x01, 0x01, 0x01, /* no standard timings */
    271                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    272                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* descriptor block 1 goes here */
    273                 0x00, 0x00, 0x00, 0xFD, 0x00, /* descriptor block 2, monitor ranges */
    274                 0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
    275                 0x20, /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */
    276                 0x00, 0x00, 0x00, 0xFC, 0x00, /* descriptor block 3, monitor name */
    277                 'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r', '\n',
    278                 0x00, 0x00, 0x00, 0x10, 0x00, /* descriptor block 4: dummy data */
    279                 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    280                 0x20,
    281                 0x00, /* number of extensions */
    282                 0x00 /* checksum goes here */
    283         };
    284 
    285         if (size < 128)
    286                 return B_BUFFER_OVERFLOW;
    287 
    288         *_version = 1; /*EDID_VERSION_1*/
    289         memcpy(info, edid_data, 128);
    290         return B_OK;
    291 }
    292 
    293 status_t vboxvideo_get_frame_buffer_config(frame_buffer_config *config) {
    294         TRACE("%s\n", __FUNCTION__);
    295         config->frame_buffer = gInfo.sharedInfo->framebuffer;
    296         config->frame_buffer_dma = NULL;
    297         config->bytes_per_row = get_depth_for_color_space(gInfo.sharedInfo->currentMode.space)
    298                 * gInfo.sharedInfo->currentMode.timing.h_display / 8;
    299         return B_OK;
    300 }
    301 
    302 status_t vboxvideo_get_pixel_clock_limits(display_mode *dm, uint32 *low, uint32 *high) {
    303         TRACE("%s\n", __FUNCTION__);
    304         // irrelevant for virtual monitors
    305         *low = 0;
    306         *high = 9001;
    307         return B_OK;
     240uint32 vboxvideo_accelerant_mode_count(void)
     241{
     242    TRACE("%s\n", __FUNCTION__);
     243    return 1;
     244}
     245
     246status_t vboxvideo_get_mode_list(display_mode *dm)
     247{
     248    // TODO return some standard modes here
     249    TRACE("%s\n", __FUNCTION__);
     250    return vboxvideo_get_display_mode(dm);
     251}
     252
     253status_t vboxvideo_set_display_mode(display_mode *modeToSet)
     254{
     255    TRACE("%s\n", __FUNCTION__);
     256    TRACE("trying to set mode %dx%d\n", modeToSet->timing.h_display, modeToSet->timing.v_display);
     257    return ioctl(gInfo.deviceFD, VBOXVIDEO_SET_DISPLAY_MODE, modeToSet, sizeof(display_mode));
     258}
     259
     260status_t vboxvideo_get_display_mode(display_mode *currentMode)
     261{
     262    TRACE("%s\n", __FUNCTION__);
     263    *currentMode = gInfo.sharedInfo->currentMode;
     264    TRACE("current mode is %dx%d\n", currentMode->timing.h_display, currentMode->timing.v_display);
     265    return B_OK;
     266}
     267
     268status_t vboxvideo_get_edid_info(void *info, size_t size, uint32 *_version)
     269{
     270    TRACE("%s\n", __FUNCTION__);
     271
     272    // copied from the X11 implementation:
     273    static const uint8 edid_data[128] = {
     274        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
     275        0x58, 0x58, /* manufacturer (VBX) */
     276        0x00, 0x00, /* product code */
     277        0x00, 0x00, 0x00, 0x00, /* serial number goes here */
     278        0x01, /* week of manufacture */
     279        0x00, /* year of manufacture */
     280        0x01, 0x03, /* EDID version */
     281        0x80, /* capabilities - digital */
     282        0x00, /* horiz. res in cm, zero for projectors */
     283        0x00, /* vert. res in cm */
     284        0x78, /* display gamma (120 == 2.2).  Should we ask the host for this? */
     285        0xEE, /* features (standby, suspend, off, RGB, standard colour space,
     286                * preferred timing mode) */
     287        0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
     288        /* chromaticity for standard colour space - should we ask the host? */
     289        0x00, 0x00, 0x00, /* no default timings */
     290        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     291        0x01, 0x01, 0x01, 0x01, /* no standard timings */
     292        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     293        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* descriptor block 1 goes here */
     294        0x00, 0x00, 0x00, 0xFD, 0x00, /* descriptor block 2, monitor ranges */
     295        0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
     296        0x20, /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */
     297        0x00, 0x00, 0x00, 0xFC, 0x00, /* descriptor block 3, monitor name */
     298        'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r', '\n',
     299        0x00, 0x00, 0x00, 0x10, 0x00, /* descriptor block 4: dummy data */
     300        0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
     301        0x20,
     302        0x00, /* number of extensions */
     303        0x00 /* checksum goes here */
     304    };
     305
     306    if (size < 128)
     307        return B_BUFFER_OVERFLOW;
     308
     309    *_version = 1; /*EDID_VERSION_1*/
     310    memcpy(info, edid_data, 128);
     311    return B_OK;
     312}
     313
     314status_t vboxvideo_get_frame_buffer_config(frame_buffer_config *config)
     315{
     316    TRACE("%s\n", __FUNCTION__);
     317    config->frame_buffer = gInfo.sharedInfo->framebuffer;
     318    config->frame_buffer_dma = NULL;
     319    config->bytes_per_row = get_depth_for_color_space(gInfo.sharedInfo->currentMode.space)
     320                            * gInfo.sharedInfo->currentMode.timing.h_display / 8;
     321    return B_OK;
     322}
     323
     324status_t vboxvideo_get_pixel_clock_limits(display_mode *dm, uint32 *low, uint32 *high)
     325{
     326    TRACE("%s\n", __FUNCTION__);
     327    // irrelevant for virtual monitors
     328    *low = 0;
     329    *high = 9001;
     330    return B_OK;
    308331}
    309332
    310333// cursor
    311 status_t vboxvideo_set_cursor_shape(uint16 width, uint16 height, uint16 hotX, uint16 hotY, uint8 *andMask, uint8 *xorMask) {
    312         TRACE("%s\n", __FUNCTION__);
    313         // VBoxHGSMIUpdatePointerShape
    314         return B_UNSUPPORTED;
    315 }
    316 
    317 void vboxvideo_move_cursor(uint16 x, uint16 y) {
    318         TRACE("%s\n", __FUNCTION__);
    319 }
    320 
    321 void vboxvideo_show_cursor(bool is_visible) {
    322         TRACE("%s\n", __FUNCTION__);
     334status_t vboxvideo_set_cursor_shape(uint16 width, uint16 height, uint16 hotX, uint16 hotY, uint8 *andMask, uint8 *xorMask)
     335{
     336    TRACE("%s\n", __FUNCTION__);
     337    // VBoxHGSMIUpdatePointerShape
     338    return B_UNSUPPORTED;
     339}
     340
     341void vboxvideo_move_cursor(uint16 x, uint16 y)
     342{
     343    TRACE("%s\n", __FUNCTION__);
     344}
     345
     346void vboxvideo_show_cursor(bool is_visible)
     347{
     348    TRACE("%s\n", __FUNCTION__);
    323349}
    324350
    325351// accelerant engine
    326 uint32 vboxvideo_accelerant_engine_count(void) {
    327         TRACE("%s\n", __FUNCTION__);
    328         return 1;
    329 }
    330 
    331 status_t vboxvideo_acquire_engine(uint32 capabilities, uint32 maxWait, sync_token *st, engine_token **et) {
    332         TRACE("%s\n", __FUNCTION__);
    333         *et = &sEngineToken;
    334         return B_OK;
    335 }
    336 
    337 status_t vboxvideo_release_engine(engine_token *et, sync_token *st) {
    338         TRACE("%s\n", __FUNCTION__);
    339         if (st != NULL)
    340                 st->engine_id = et->engine_id;
    341 
    342         return B_OK;
    343 }
    344 
    345 void vboxvideo_wait_engine_idle(void) {
    346         TRACE("%s\n", __FUNCTION__);
    347 }
    348 
    349 status_t vboxvideo_get_sync_token(engine_token *et, sync_token *st) {
    350         TRACE("%s\n", __FUNCTION__);
    351         return B_OK;
    352 }
    353 
    354 status_t vboxvideo_sync_to_token(sync_token *st) {
    355         TRACE("%s\n", __FUNCTION__);
    356         return B_OK;
     352uint32 vboxvideo_accelerant_engine_count(void)
     353{
     354    TRACE("%s\n", __FUNCTION__);
     355    return 1;
     356}
     357
     358status_t vboxvideo_acquire_engine(uint32 capabilities, uint32 maxWait, sync_token *st, engine_token **et)
     359{
     360    TRACE("%s\n", __FUNCTION__);
     361    *et = &sEngineToken;
     362    return B_OK;
     363}
     364
     365status_t vboxvideo_release_engine(engine_token *et, sync_token *st)
     366{
     367    TRACE("%s\n", __FUNCTION__);
     368    if (st != NULL)
     369        st->engine_id = et->engine_id;
     370
     371    return B_OK;
     372}
     373
     374void vboxvideo_wait_engine_idle(void)
     375{
     376    TRACE("%s\n", __FUNCTION__);
     377}
     378
     379status_t vboxvideo_get_sync_token(engine_token *et, sync_token *st)
     380{
     381    TRACE("%s\n", __FUNCTION__);
     382    return B_OK;
     383}
     384
     385status_t vboxvideo_sync_to_token(sync_token *st)
     386{
     387    TRACE("%s\n", __FUNCTION__);
     388    return B_OK;
    357389}
    358390
    359391// 2D acceleration
    360 void vboxvideo_screen_to_screen_blit(engine_token *et, blit_params *list, uint32 count) {
    361         TRACE("%s\n", __FUNCTION__);
    362 }
    363 
    364 void vboxvideo_fill_rectangle(engine_token *et, uint32 color, fill_rect_params *list, uint32 count) {
    365         TRACE("%s\n", __FUNCTION__);
    366 }
    367 
    368 void vboxvideo_invert_rectangle(engine_token *et, fill_rect_params *list, uint32 count) {
    369         TRACE("%s\n", __FUNCTION__);
    370 }
    371 
    372 void vboxvideo_fill_span(engine_token *et, uint32 color, uint16 *list, uint32 count) {
    373         TRACE("%s\n", __FUNCTION__);
    374 }
     392void vboxvideo_screen_to_screen_blit(engine_token *et, blit_params *list, uint32 count)
     393{
     394    TRACE("%s\n", __FUNCTION__);
     395}
     396
     397void vboxvideo_fill_rectangle(engine_token *et, uint32 color, fill_rect_params *list, uint32 count)
     398{
     399    TRACE("%s\n", __FUNCTION__);
     400}
     401
     402void vboxvideo_invert_rectangle(engine_token *et, fill_rect_params *list, uint32 count)
     403{
     404    TRACE("%s\n", __FUNCTION__);
     405}
     406
     407void vboxvideo_fill_span(engine_token *et, uint32 color, uint16 *list, uint32 count)
     408{
     409    TRACE("%s\n", __FUNCTION__);
     410}
  • trunk/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.h

    r43363 r43364  
    5151#include "../common/VBoxVideo_common.h"
    5252
    53 struct AccelerantInfo {
    54         int deviceFD;
    55         bool isClone;
     53struct AccelerantInfo
     54{
     55        int deviceFD;
     56        bool isClone;
    5657
    57         SharedInfo* sharedInfo;
    58         area_id sharedInfoArea;
     58        SharedInfo *sharedInfo;
     59        area_id sharedInfoArea;
    5960};
    6061extern AccelerantInfo gInfo;
     
    9798void vboxvideo_fill_span(engine_token *et, uint32 color, uint16 *list, uint32 count);
    9899
    99 #endif  /* _ACCELERANT_PROTOS_H */
     100#endif    /* _ACCELERANT_PROTOS_H */
  • trunk/src/VBox/Additions/haiku/VBoxVideo/common/VBoxVideo_common.h

    r43363 r43364  
    5252#include <PCI.h>
    5353
    54 struct SharedInfo {
    55         display_mode currentMode;
    56 
    57         area_id framebufferArea;
    58         void* framebuffer;
     54struct SharedInfo
     55{
     56        display_mode currentMode;
     57        area_id framebufferArea;
     58        void *framebuffer;
    5959};
    6060
    61 enum {
    62         VBOXVIDEO_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
    63         VBOXVIDEO_GET_DEVICE_NAME,
    64         VBOXVIDEO_SET_DISPLAY_MODE
     61enum
     62{
     63    VBOXVIDEO_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
     64    VBOXVIDEO_GET_DEVICE_NAME,
     65    VBOXVIDEO_SET_DISPLAY_MODE
    6566};
    6667
    6768static inline uint32 get_color_space_for_depth(uint32 depth)
    6869{
    69         switch (depth) {
    70                 case 1:
    71                         return B_GRAY1;
    72                 case 4:
    73                         return B_GRAY8;
    74                                 // the app_server is smart enough to translate this to VGA mode
    75                 case 8:
    76                         return B_CMAP8;
    77                 case 15:
    78                         return B_RGB15;
    79                 case 16:
    80                         return B_RGB16;
    81                 case 24:
    82                         return B_RGB24;
    83                 case 32:
    84                         return B_RGB32;
    85         }
     70    switch (depth)
     71    {
     72        case 1:  return B_GRAY1;
     73        case 4:  return B_GRAY8;
     74                // the app_server is smart enough to translate this to VGA mode
     75        case 8:  return B_CMAP8;
     76        case 15: return B_RGB15;
     77        case 16: return B_RGB16;
     78        case 24: return B_RGB24;
     79        case 32: return B_RGB32;
     80    }
    8681
    87         return 0;
     82    return 0;
    8883}
    8984
    9085static inline uint32 get_depth_for_color_space(uint32 depth)
    9186{
    92         switch (depth) {
    93                 case B_GRAY1:
    94                         return 1;
    95                 case B_GRAY8:
    96                         return 4;
    97                 case B_CMAP8:
    98                         return 8;
    99                 case B_RGB15:
    100                         return 15;
    101                 case B_RGB16:
    102                         return 16;
    103                 case B_RGB24:
    104                         return 24;
    105                 case B_RGB32:
    106                         return 32;
    107         }
    108 
    109         return 0;
     87    switch (depth)
     88    {
     89        case B_GRAY1: return 1;
     90        case B_GRAY8: return 4;
     91        case B_CMAP8: return 8;
     92        case B_RGB15: return 15;
     93        case B_RGB16: return 16;
     94        case B_RGB24: return 24;
     95        case B_RGB32: return 32;
     96    }
     97    return 0;
    11098}
    11199
    112 #endif
     100#endif /* _VBOXVIDEO_COMMON_H */
     101
  • trunk/src/VBox/Additions/haiku/VBoxVideo/driver/driver.cpp

    r43363 r43364  
    6666#undef TRACE
    6767#ifdef ENABLE_DEBUG_TRACE
    68 #       define TRACE(x...) dprintf("VBoxVideo: " x)
     68#define TRACE(x...) dprintf("VBoxVideo: " x)
    6969#else
    70 #       define TRACE(x...) ;
     70#define TRACE(x...) ;
    7171#endif
    7272
     
    7575extern "C" status_t vm_set_area_memory_type(area_id id, phys_addr_t physicalBase, uint32 type);
    7676
    77 struct Benaphore {
    78         sem_id  sem;
    79         int32   count;
    80 
    81         status_t Init(const char* name)
    82         {
    83                 count = 0;
    84                 sem = create_sem(0, name);
    85                 return sem < 0 ? sem : B_OK;
    86         }
    87 
    88         status_t Acquire()
    89         {
    90                 if (atomic_add(&count, 1) > 0)
    91                         return acquire_sem(sem);
    92                 return B_OK;
    93         }
    94 
    95         status_t Release()
    96         {
    97                 if (atomic_add(&count, -1) > 1)
    98                         return release_sem(sem);
    99                 return B_OK;
    100         }
    101 
    102         void Delete() { delete_sem(sem); }
     77struct Benaphore
     78{
     79        sem_id    sem;
     80        int32    count;
     81
     82        status_t Init(const char *name)
     83        {
     84            count = 0;
     85            sem = create_sem(0, name);
     86            return sem < 0 ? sem : B_OK;
     87        }
     88
     89        status_t Acquire()
     90        {
     91            if (atomic_add(&count, 1) > 0)
     92                return acquire_sem(sem);
     93            return B_OK;
     94        }
     95
     96        status_t Release()
     97        {
     98            if (atomic_add(&count, -1) > 1)
     99                return release_sem(sem);
     100            return B_OK;
     101        }
     102
     103        void Delete()
     104                {
     105                        delete_sem(sem);
     106                }
    103107};
    104108
    105 struct DeviceInfo {
    106         uint32                  openCount;              // count of how many times device has been opened
    107         uint32                  flags;
    108         area_id                 sharedArea;             // area shared between driver and all accelerants
    109         SharedInfo*             sharedInfo;             // pointer to shared info area memory
    110         pci_info                pciInfo;                // copy of pci info for this device
    111         char                    name[B_OS_NAME_LENGTH]; // name of device
     109struct DeviceInfo
     110{
     111        uint32          openCount;                      // count of how many times device has been opened
     112        uint32          flags;                                  // device flags
     113        area_id         sharedArea;                     // area shared between driver and all accelerants
     114        SharedInfo     *sharedInfo;                     // pointer to shared info area memory
     115        pci_info        pciInfo;                        // copy of pci info for this device
     116        char            name[B_OS_NAME_LENGTH]; // name of device
    112117};
    113118
    114119// at most one virtual video card ever appears, no reason for this to be an array
    115120static DeviceInfo gDeviceInfo;
    116 static char* gDeviceNames[2] = {gDeviceInfo.name, NULL};
     121static char *gDeviceNames[2] = { gDeviceInfo.name, NULL };
    117122static bool gCanHasDevice = false; // is the device present?
    118123static Benaphore gLock;
    119 static pci_module_info* gPCI;
    120 
    121 status_t device_open(const char* name, uint32 flags, void** cookie);
    122 status_t device_close(void* dev);
    123 status_t device_free(void* dev);
    124 status_t device_read(void* dev, off_t pos, void* buf, size_t* len);
    125 status_t device_write(void* dev, off_t pos, const void* buf, size_t* len);
    126 status_t device_ioctl(void* dev, uint32 msg, void* buf, size_t len);
     124static pci_module_info *gPCI;
     125
     126status_t device_open(const char *name, uint32 flags, void **cookie);
     127status_t device_close(void *dev);
     128status_t device_free(void *dev);
     129status_t device_read(void *dev, off_t pos, void *buf, size_t *len);
     130status_t device_write(void *dev, off_t pos, const void *buf, size_t *len);
     131status_t device_ioctl(void *dev, uint32 msg, void *buf, size_t len);
    127132static uint32 get_color_space_for_depth(uint32 depth);
    128133
    129 static device_hooks gDeviceHooks = {
    130         device_open, // open
    131         device_close, // close
    132         device_free, // free
    133         device_ioctl, // control
    134         device_read, // read
    135         device_write, // write
    136         NULL, // select
    137         NULL, // deselect
    138         NULL, // read_pages
    139         NULL  // write_pages
     134static device_hooks gDeviceHooks =
     135{
     136    device_open, // open
     137    device_close, // close
     138    device_free, // free
     139    device_ioctl, // control
     140    device_read, // read
     141    device_write, // write
     142    NULL, // select
     143    NULL, // deselect
     144    NULL, // read_pages
     145    NULL  // write_pages
    140146};
    141147
    142148status_t init_hardware()
    143149{
    144         TRACE("init_hardware\n");
    145 
    146         if (get_module(VBOXGUEST_MODULE_NAME, (module_info **)&g_VBoxGuest) != B_OK) {
    147                 dprintf("get_module(%s) failed\n", VBOXGUEST_MODULE_NAME);
    148                 return B_ERROR;
    149         }
    150 
    151         if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI) != B_OK) {
    152                 dprintf("get_module(%s) failed\n", B_PCI_MODULE_NAME);
    153                 return B_ERROR;
    154         }
    155 
    156         return B_OK;
     150    TRACE("init_hardware\n");
     151
     152    if (get_module(VBOXGUEST_MODULE_NAME, (module_info **)&g_VBoxGuest) != B_OK)
     153    {
     154        dprintf("get_module(%s) failed\n", VBOXGUEST_MODULE_NAME);
     155        return B_ERROR;
     156    }
     157
     158    if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI) != B_OK)
     159    {
     160        dprintf("get_module(%s) failed\n", B_PCI_MODULE_NAME);
     161        return B_ERROR;
     162    }
     163
     164    return B_OK;
    157165}
    158166
    159167status_t init_driver()
    160168{
    161         TRACE("init_driver\n");
    162 
    163         gLock.Init("VBoxVideo driver lock");
    164 
    165         uint32 pciIndex = 0;
    166 
    167         while (gPCI->get_nth_pci_info(pciIndex, &gDeviceInfo.pciInfo) == B_OK) {
    168                 if (gDeviceInfo.pciInfo.vendor_id == VENDOR_ID && gDeviceInfo.pciInfo.device_id == DEVICE_ID) {
    169                         sprintf(gDeviceInfo.name, "graphics/" DEVICE_FORMAT,
    170                                 gDeviceInfo.pciInfo.vendor_id, gDeviceInfo.pciInfo.device_id,
    171                                 gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function);
    172                         TRACE("found device %s\n", gDeviceInfo.name);
    173 
    174                         gCanHasDevice = true;
    175                         gDeviceInfo.openCount = 0;
    176 
    177                         size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7;
    178                         gDeviceInfo.sharedArea = create_area("vboxvideo shared info",
    179                                 (void**)&gDeviceInfo.sharedInfo, B_ANY_KERNEL_ADDRESS,
    180                                 ROUND_TO_PAGE_SIZE(sharedSize), B_FULL_LOCK,
    181                                 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA);
    182 
    183                         uint16_t width, height, vwidth, bpp, flags;
    184                         VBoxVideoGetModeRegisters(&width, &height, &vwidth, &bpp, &flags);
    185 
    186                         gDeviceInfo.sharedInfo->currentMode.space = get_color_space_for_depth(bpp);
    187                         gDeviceInfo.sharedInfo->currentMode.virtual_width = width;
    188                         gDeviceInfo.sharedInfo->currentMode.virtual_height = height;
    189                         gDeviceInfo.sharedInfo->currentMode.h_display_start = 0;
    190                         gDeviceInfo.sharedInfo->currentMode.v_display_start = 0;
    191                         gDeviceInfo.sharedInfo->currentMode.flags = 0;
    192                         gDeviceInfo.sharedInfo->currentMode.timing.h_display = width;
    193                         gDeviceInfo.sharedInfo->currentMode.timing.v_display = height;
    194                         // not used, but this makes a reasonable-sounding refresh rate show in screen prefs:
    195                         gDeviceInfo.sharedInfo->currentMode.timing.h_total = 1000;
    196                         gDeviceInfo.sharedInfo->currentMode.timing.v_total = 1;
    197                         gDeviceInfo.sharedInfo->currentMode.timing.pixel_clock = 850;
    198 
    199                         // map the PCI memory space
    200                         uint32 command_reg = gPCI->read_pci_config(gDeviceInfo.pciInfo.bus,
    201                                 gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function,  PCI_command, 2);
    202                         command_reg |= PCI_command_io | PCI_command_memory | PCI_command_master;
    203                         gPCI->write_pci_config(gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device,
    204                                 gDeviceInfo.pciInfo.function, PCI_command, 2, command_reg);
    205 
    206                         gDeviceInfo.sharedInfo->framebufferArea =
    207                                 map_physical_memory("vboxvideo framebuffer", (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0],
    208                                         gDeviceInfo.pciInfo.u.h0.base_register_sizes[0], B_ANY_KERNEL_BLOCK_ADDRESS,
    209                                         B_READ_AREA | B_WRITE_AREA, &(gDeviceInfo.sharedInfo->framebuffer));
    210                         vm_set_area_memory_type(gDeviceInfo.sharedInfo->framebufferArea,
    211                                 (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0], B_MTR_WC);
    212 
    213                         break;
    214                 }
    215 
    216                 pciIndex++;
    217         }
    218 
    219         return B_OK;
    220 }
     169    TRACE("init_driver\n");
     170
     171    gLock.Init("VBoxVideo driver lock");
     172
     173    uint32 pciIndex = 0;
     174
     175    while (gPCI->get_nth_pci_info(pciIndex, &gDeviceInfo.pciInfo) == B_OK)
     176    {
     177        if (gDeviceInfo.pciInfo.vendor_id == VENDOR_ID && gDeviceInfo.pciInfo.device_id == DEVICE_ID)
     178        {
     179            sprintf(gDeviceInfo.name, "graphics/" DEVICE_FORMAT,
     180                    gDeviceInfo.pciInfo.vendor_id, gDeviceInfo.pciInfo.device_id,
     181                    gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function);
     182            TRACE("found device %s\n", gDeviceInfo.name);
     183
     184            gCanHasDevice = true;
     185            gDeviceInfo.openCount = 0;
     186
     187            size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7;
     188            gDeviceInfo.sharedArea = create_area("vboxvideo shared info",
     189                                                 (void **)&gDeviceInfo.sharedInfo, B_ANY_KERNEL_ADDRESS,
     190                                                 ROUND_TO_PAGE_SIZE(sharedSize), B_FULL_LOCK,
     191                                                 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA);
     192
     193            uint16_t width, height, vwidth, bpp, flags;
     194            VBoxVideoGetModeRegisters(&width, &height, &vwidth, &bpp, &flags);
     195
     196            gDeviceInfo.sharedInfo->currentMode.space = get_color_space_for_depth(bpp);
     197            gDeviceInfo.sharedInfo->currentMode.virtual_width = width;
     198            gDeviceInfo.sharedInfo->currentMode.virtual_height = height;
     199            gDeviceInfo.sharedInfo->currentMode.h_display_start = 0;
     200            gDeviceInfo.sharedInfo->currentMode.v_display_start = 0;
     201            gDeviceInfo.sharedInfo->currentMode.flags = 0;
     202            gDeviceInfo.sharedInfo->currentMode.timing.h_display = width;
     203            gDeviceInfo.sharedInfo->currentMode.timing.v_display = height;
     204            // not used, but this makes a reasonable-sounding refresh rate show in screen prefs:
     205            gDeviceInfo.sharedInfo->currentMode.timing.h_total = 1000;
     206            gDeviceInfo.sharedInfo->currentMode.timing.v_total = 1;
     207            gDeviceInfo.sharedInfo->currentMode.timing.pixel_clock = 850;
     208
     209            // map the PCI memory space
     210            uint32 command_reg = gPCI->read_pci_config(gDeviceInfo.pciInfo.bus,
     211                                                       gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function,  PCI_command, 2);
     212            command_reg |= PCI_command_io | PCI_command_memory | PCI_command_master;
     213            gPCI->write_pci_config(gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device,
     214                                   gDeviceInfo.pciInfo.function, PCI_command, 2, command_reg);
     215
     216            gDeviceInfo.sharedInfo->framebufferArea = map_physical_memory("vboxvideo framebuffer",
     217                                                      (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0],
     218                                                      gDeviceInfo.pciInfo.u.h0.base_register_sizes[0], B_ANY_KERNEL_BLOCK_ADDRESS,
     219                                                      B_READ_AREA | B_WRITE_AREA, &(gDeviceInfo.sharedInfo->framebuffer));
     220            vm_set_area_memory_type(gDeviceInfo.sharedInfo->framebufferArea,
     221                                    (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0], B_MTR_WC);
     222            break;
     223        }
     224
     225        pciIndex++;
     226    }
     227
     228    return B_OK;
     229}
     230
    221231
    222232const char** publish_devices()
    223233{
    224         TRACE("publish_devices\n");
    225         if (gCanHasDevice) {
    226                 return (const char**)gDeviceNames;
    227         }
    228         else {
    229                 return NULL;
    230         }
    231 }
    232 
    233 device_hooks* find_device(const char* name)
    234 {
    235         TRACE("find_device\n");
    236         if (gCanHasDevice && strcmp(name, gDeviceInfo.name) == 0) {
    237                 return &gDeviceHooks;
    238         }
    239         else {
    240                 return NULL;
    241         }
    242 }
     234    TRACE("publish_devices\n");
     235    if (gCanHasDevice)
     236        return (const char **)gDeviceNames;
     237    return NULL;
     238}
     239
     240
     241device_hooks* find_device(const char *name)
     242{
     243    TRACE("find_device\n");
     244    if (gCanHasDevice && strcmp(name, gDeviceInfo.name) == 0)
     245        return &gDeviceHooks;
     246
     247    return NULL;
     248}
     249
    243250
    244251void uninit_driver()
    245252{
    246         TRACE("uninit_driver\n");
    247         gLock.Delete();
    248         put_module(VBOXGUEST_MODULE_NAME);
    249 }
    250 
    251 status_t device_open(const char* name, uint32 flags, void** cookie)
    252 {
    253         TRACE("device_open\n");
    254 
    255         if (!gCanHasDevice || strcmp(name, gDeviceInfo.name) != 0)
    256                 return B_BAD_VALUE;
    257 
    258         // TODO init device!
    259 
    260         *cookie = (void*)&gDeviceInfo;
    261 
    262         return B_OK;
    263 }
    264 
    265 status_t device_close(void* dev)
    266 {
    267         TRACE("device_close\n");
    268         return B_ERROR;
    269 }
    270 
    271 status_t device_free(void* dev)
    272 {
    273         TRACE("device_free\n");
    274 
    275         DeviceInfo& di = *(DeviceInfo*)dev;
    276         gLock.Acquire();
    277 
    278         if (di.openCount <= 1) {
    279                 // TODO deinit device!
    280 
    281                 delete_area(di.sharedArea);
    282                 di.sharedArea = -1;
    283                 di.sharedInfo = NULL;
    284         }
    285 
    286         if (di.openCount > 0)
    287                 di.openCount--;
    288 
    289         gLock.Release();
    290 
    291         return B_OK;
    292 }
    293 
    294 status_t device_read(void* dev, off_t pos, void* buf, size_t* len)
    295 {
    296         TRACE("device_read\n");
    297         return B_NOT_ALLOWED;
    298 }
    299 
    300 status_t device_write(void* dev, off_t pos, const void* buf, size_t* len)
    301 {
    302         TRACE("device_write\n");
    303         return B_NOT_ALLOWED;
    304 }
    305 
    306 status_t device_ioctl(void* cookie, uint32 msg, void* buf, size_t len)
    307 {
    308         TRACE("device_ioctl\n");
    309 
    310         DeviceInfo* dev = (DeviceInfo*)cookie;
    311 
    312         switch (msg) {
    313         case B_GET_ACCELERANT_SIGNATURE:
    314                 strcpy((char*)buf, "vboxvideo.accelerant");
    315                 return B_OK;
    316 
    317         case VBOXVIDEO_GET_PRIVATE_DATA:
    318                 return user_memcpy(buf, &dev->sharedArea, sizeof(area_id));
    319 
    320         case VBOXVIDEO_GET_DEVICE_NAME:
    321                 if (user_strlcpy((char*)buf, gDeviceInfo.name, len) < B_OK)
    322                         return B_BAD_ADDRESS;
    323                 else
    324                         return B_OK;
    325 
    326         case VBOXVIDEO_SET_DISPLAY_MODE: {
    327                 display_mode* mode = (display_mode*)buf;
    328                 VBoxVideoSetModeRegisters(mode->timing.h_display, mode->timing.v_display,
    329                         mode->timing.h_display, get_depth_for_color_space(mode->space), 0, 0, 0);
    330                 gDeviceInfo.sharedInfo->currentMode = *mode;
    331                 return B_OK;
    332         }
    333         default:
    334                 return B_BAD_VALUE;
    335         }
    336 
    337 }
     253    TRACE("uninit_driver\n");
     254    gLock.Delete();
     255    put_module(VBOXGUEST_MODULE_NAME);
     256}
     257
     258status_t device_open(const char *name, uint32 flags, void **cookie)
     259{
     260    TRACE("device_open\n");
     261
     262    if (!gCanHasDevice || strcmp(name, gDeviceInfo.name) != 0)
     263        return B_BAD_VALUE;
     264
     265    // TODO init device!
     266
     267    *cookie = (void *)&gDeviceInfo;
     268    return B_OK;
     269}
     270
     271
     272status_t device_close(void *dev)
     273{
     274    TRACE("device_close\n");
     275    return B_ERROR;
     276}
     277
     278
     279status_t device_free(void *dev)
     280{
     281    TRACE("device_free\n");
     282
     283    DeviceInfo& di = *(DeviceInfo *)dev;
     284    gLock.Acquire();
     285
     286    if (di.openCount <= 1)
     287    {
     288        // TODO deinit device!
     289        delete_area(di.sharedArea);
     290        di.sharedArea = -1;
     291        di.sharedInfo = NULL;
     292    }
     293
     294    if (di.openCount > 0)
     295        di.openCount--;
     296
     297    gLock.Release();
     298
     299    return B_OK;
     300}
     301
     302
     303status_t device_read(void *dev, off_t pos, void *buf, size_t *len)
     304{
     305    TRACE("device_read\n");
     306    return B_NOT_ALLOWED;
     307}
     308
     309
     310status_t device_write(void *dev, off_t pos, const void *buf, size_t *len)
     311{
     312    TRACE("device_write\n");
     313    return B_NOT_ALLOWED;
     314}
     315
     316
     317status_t device_ioctl(void *cookie, uint32 msg, void *buf, size_t len)
     318{
     319    TRACE("device_ioctl\n");
     320
     321    DeviceInfo *dev = (DeviceInfo *)cookie;
     322
     323    switch (msg)
     324    {
     325        case B_GET_ACCELERANT_SIGNATURE:
     326            strcpy((char *)buf, "vboxvideo.accelerant");
     327            return B_OK;
     328
     329        case VBOXVIDEO_GET_PRIVATE_DATA:
     330            return user_memcpy(buf, &dev->sharedArea, sizeof(area_id));
     331
     332        case VBOXVIDEO_GET_DEVICE_NAME:
     333            if (user_strlcpy((char *)buf, gDeviceInfo.name, len) < B_OK)
     334                return B_BAD_ADDRESS;
     335            else
     336                return B_OK;
     337
     338        case VBOXVIDEO_SET_DISPLAY_MODE:
     339        {
     340            display_mode *mode = (display_mode *)buf;
     341            VBoxVideoSetModeRegisters(mode->timing.h_display, mode->timing.v_display,
     342                                      mode->timing.h_display, get_depth_for_color_space(mode->space), 0, 0, 0);
     343            gDeviceInfo.sharedInfo->currentMode = *mode;
     344            return B_OK;
     345        }
     346        default:
     347            return B_BAD_VALUE;
     348    }
     349
     350}
     351
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette