Ticket #7445: app_server-DecorManager-DecorInfo.patch

File app_server-DecorManager-DecorInfo.patch, 57.2 KB (added by looncraz, 13 years ago)

app_server-DecorManager-DecorInfo.patch

  • src/preferences/appearance/APRView.cpp

     
    2020#include <Path.h>
    2121#include <SpaceLayoutItem.h>
    2222
     23#include <private/interface/DecorInfo.h>
     24
    2325#include <stdio.h>
    2426
     27
    2528#include "APRWindow.h"
    2629#include "defs.h"
    2730#include "ColorWell.h"
     
    3538#define COLOR_DROPPED 'cldp'
    3639#define DECORATOR_CHANGED 'dcch'
    3740
    38 namespace BPrivate
    39 {
    40     int32 count_decorators(void);
    41     status_t set_decorator(const int32 &index);
    42     int32 get_decorator(void);
    43     status_t get_decorator_name(const int32 &index, BString &name);
    44     status_t get_decorator_preview(const int32 &index, BBitmap *bitmap);
    45 }
    4641
    4742APRView::APRView(const char *name, uint32 flags)
    48  :  BView(name, flags),
     43 :
     44    BView(name, flags),
    4945    fDefaultSet(ColorSet::DefaultColorSet()),
    50     fDecorMenu(NULL)
     46    fDecorMenu(NULL),
     47    fDecorUtil(new DecorInfoUtility(false))
    5148{
    5249    SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
    5350
    5451#if 0
    5552    fDecorMenu = new BMenu("Window Style");
    56     int32 decorCount = BPrivate::count_decorators();
     53    int32 decorCount = fDecorUtil->CountDecorators();
     54    DecorInfo* decor = NULL;
    5755    if (decorCount > 1) {
    5856        for (int32 i = 0; i < decorCount; i++) {
    59             BString name;
    60             BPrivate::get_decorator_name(i, name);
    61             if (name.CountChars() < 1)
     57            decor = fDecorUtil->GetDecorator(i);
     58            if (!decor)
    6259                continue;
    63             fDecorMenu->AddItem(new BMenuItem(name.String(),
     60            fDecorMenu->AddItem(new BMenuItem(decor->Name().String(),
    6461                new BMessage(DECORATOR_CHANGED)));
    6562        }
    6663
    67         BMenuField *field = new BMenuField("Window Style", fDecorMenu);
     64        BMenuField* field = new BMenuField("Window Style", fDecorMenu);
    6865        // TODO: use this menu field.
    6966    }
    70     BMenuItem *marked = fDecorMenu->ItemAt(BPrivate::get_decorator());
     67    BMenuItem *marked = fDecorMenu->ItemAt(fDecorUtil->IndexOfCurrentDecorator());
    7168    if (marked)
    7269        marked->SetMarked(true);
    7370    else {
     
    156153            int32 index = fDecorMenu->IndexOf(fDecorMenu->FindMarked());
    157154            #ifdef HAIKU_TARGET_PLATFORM_HAIKU
    158155            if (index >= 0)
    159                 BPrivate::set_decorator(index);
     156                fDecorUtil->SetDecorator(index);
    160157            #endif
    161158            break;
    162159        }
     
    207204                if (item) {
    208205                    item->SetMarked(true);
    209206                    #ifdef HAIKU_TARGET_PLATFORM_HAIKU
    210                     BPrivate::set_decorator(fDecorMenu->IndexOf(item));
     207                    fDecorUtil->SetDecorator(fDecorMenu->IndexOf(item));
    211208                    #endif
    212209                }
    213210            }
  • src/preferences/appearance/APRView.h

     
    2828#include "ColorSet.h"
    2929
    3030class ColorWell;
     31class DecorInfoUtility;
    3132class APRWindow;
    3233
    3334class APRView : public BView
     
    6263    ColorSet        fDefaultSet;
    6364
    6465    BMenu           *fDecorMenu;
     66    DecorInfoUtility*fDecorUtil;
    6567};
    6668
    6769#endif
  • src/add-ons/decorators/WinDecorator/WinDecorator.cpp

     
    3030
    3131
    3232WinDecorAddOn::WinDecorAddOn(image_id id, const char* name)
    33     :
     33    :
    3434    DecorAddOn(id, name)
    3535{
    3636
    3737}
    3838
    3939
    40 float
    41 WinDecorAddOn::Version()
    42 {
    43     return 1.00;
    44 }
    45 
    46 
    4740Decorator*
    4841WinDecorAddOn::_AllocateDecorator(DesktopSettings& settings, BRect rect,
    4942    window_look look, uint32 flags)
  • src/add-ons/decorators/WinDecorator/WinDecorator.h

     
    1414public:
    1515                                WinDecorAddOn(image_id id, const char* name);
    1616
    17             float               Version();
    1817
    1918protected:
    2019    virtual Decorator*          _AllocateDecorator(DesktopSettings& settings,
  • src/add-ons/decorators/WinDecorator/Jamfile

     
    77UsePrivateHeaders app shared interface graphics ;
    88UseLibraryHeaders agg ;
    99
     10AddResources WinDecorator : resources.rdef ;
     11
    1012Addon WinDecorator :
    1113    WinDecorator.cpp
    1214    : be <nogrist>app_server $(TARGET_LIBSTDC++)
  • src/add-ons/decorators/WinDecorator/resources.rdef

     
     1
     2resource("be:decor:info") message('deco')
     3
     4{
     5    "name"          = "Windows 95",
     6    "authors"       = "",
     7    "short_descr"   = "Windows 95",
     8    "long_descr"        = "",
     9    "lic_url"           = "",
     10    "lic_name"      = "MIT",
     11    "support_url"       = "http://www.haiku-os.org/",
     12    float   "version" = 1.0
     13};
     14
  • src/add-ons/decorators/MacDecorator/MacDecorator.cpp

     
    3838}
    3939
    4040
    41 float
    42 MacDecorAddOn::Version()
    43 {
    44     return 1.00;
    45 }
    46 
    47 
    4841Decorator*
    4942MacDecorAddOn::_AllocateDecorator(DesktopSettings& settings, BRect rect,
    5043    window_look look, uint32 flags)
  • src/add-ons/decorators/MacDecorator/Jamfile

     
    77UsePrivateHeaders app shared interface graphics ;
    88UseLibraryHeaders agg ;
    99
     10AddResources MacDecorator : resources.rdef ;
     11
    1012Addon MacDecorator :
    1113    MacDecorator.cpp
    1214    : be <nogrist>app_server $(TARGET_LIBSTDC++)
  • src/add-ons/decorators/MacDecorator/MacDecorator.h

     
    1414public:
    1515                                MacDecorAddOn(image_id id, const char* name);
    1616
    17             float               Version();
    18 
    1917protected:
    2018    virtual Decorator*          _AllocateDecorator(DesktopSettings& settings,
    2119                                    BRect rect, window_look look, uint32 flags);
  • src/add-ons/decorators/MacDecorator/resources.rdef

     
     1
     2resource("be:decor:info") message('deco')
     3
     4{
     5    "name"          = "MacOS 9",
     6    "authors"       = "",
     7    "short_descr"   = "MacOS 9",
     8    "long_descr"        = "",
     9    "lic_url"           = "",
     10    "lic_name"      = "MIT",
     11    "support_url"       = "http://www.haiku-os.org/",
     12    float   "version" = 1.0
     13};
     14
  • src/add-ons/decorators/BeDecorator/BeDecorator.h

     
    2424public:
    2525                                BeDecorAddOn(image_id id, const char* name);
    2626
    27             float               Version();
    28 
    2927protected:
    3028    virtual Decorator*          _AllocateDecorator(DesktopSettings& settings,
    3129                                    BRect rect, window_look look, uint32 flags);
  • src/add-ons/decorators/BeDecorator/Jamfile

     
    77UsePrivateHeaders app shared interface graphics ;
    88UseLibraryHeaders agg ;
    99
     10AddResources ClassicBe : resources.rdef ;
     11
    1012Addon ClassicBe :
    1113    BeDecorator.cpp
    1214    : be <nogrist>app_server $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++)
     15    : resources.rdef
    1316;
  • src/add-ons/decorators/BeDecorator/resources.rdef

     
     1
     2resource("be:decor:info") message('deco')
     3
     4{
     5    "name"          = "Classic BeOS",
     6    "authors"       = "DarkWyrm, Stephan Aßmus, Clemens Zeidler",
     7    "short_descr"   = "Basic appearance of the classic BeOS.",
     8    "long_descr"        = "",
     9    "lic_url"           = "",
     10    "lic_name"      = "MIT",
     11    "support_url"       = "http://www.haiku-os.org/",
     12    float   "version" = 1.0
     13};
     14
  • src/add-ons/decorators/BeDecorator/BeDecorator.cpp

     
    9393}
    9494
    9595
    96 float
    97 BeDecorAddOn::Version()
    98 {
    99     return 1.00;
    100 }
    101 
    102 
    10396Decorator*
    10497BeDecorAddOn::_AllocateDecorator(DesktopSettings& settings, BRect rect,
    10598    window_look look, uint32 flags)
  • src/add-ons/decorators/SATDecorator/SATDecorator.h

     
    1919                                SATDecorAddOn(image_id id, const char* name);
    2020
    2121    virtual status_t            InitCheck() const;
    22             float               Version();
    2322
    2423protected:
    2524    virtual Decorator*          _AllocateDecorator(DesktopSettings& settings,
  • src/add-ons/decorators/SATDecorator/Jamfile

     
    88UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter ] ;
    99UseFreeTypeHeaders ;
    1010
     11AddResources SATDecorator : resources.rdef ;
     12
    1113Addon SATDecorator :
    1214    SATDecorator.cpp
    1315    SATGroup.cpp
  • src/add-ons/decorators/SATDecorator/resources.rdef

     
     1
     2resource("be:decor:info") message('deco')
     3
     4{
     5    "name"          = "Stack and Tile",
     6    "authors"       = "Clemens Zeidler, Ingo Weinhold",
     7    "short_descr"   = "Default look with ability to stack & tile windows.",
     8    "long_descr"        = "Group windows together and take advantage of those"
     9                        " tabs!\n\nTODO: instructions",
     10    "lic_url"           = "",
     11    "lic_name"      = "MIT",
     12    "support_url"       = "http://www.haiku-os.org/",
     13    float   "version" = 1.0
     14};
     15
  • src/add-ons/decorators/SATDecorator/SATDecorator.cpp

     
    6666}
    6767
    6868
    69 float
    70 SATDecorAddOn::Version()
    71 {
    72     return 0.1;
    73 }
    74 
    75 
    7669Decorator*
    7770SATDecorAddOn::_AllocateDecorator(DesktopSettings& settings, BRect rect,
    7871    window_look look, uint32 flags)
  • src/bin/setdecor.cpp

     
    11/*
     2 * Copyright 2011, Joseph "looncraz" Groover, looncraz@satx.rr.com
    23 * Copyright 2007, François Revol, revol@free.fr.
    34 * Distributed under the terms of the MIT license.
     5 *
    46 */
    57
    68
    79#include <stdio.h>
    810
    911#include <Application.h>
     12#include <Bitmap.h>
    1013#include <InterfaceDefs.h>
    1114#include <String.h>
     15#include <Window.h>
     16#include <View.h>
    1217
    13 class BBitmap;
     18#include <private/interface/DecorInfo.h>
    1419
    15 namespace BPrivate {
    16 int32 count_decorators(void);
    17 int32 get_decorator(void);
    18 status_t get_decorator_name(const int32 &index, BString &name);
    19 status_t get_decorator_preview(const int32 &index, BBitmap *bitmap);
    20 status_t set_decorator(const int32 &index);
     20
     21void    print_decor_info_header()
     22{
     23    printf("    Name      License\t    Description\n");
     24    printf("----------------------------------------------------\n");
    2125}
    2226
    23 using namespace BPrivate;
    2427
     28void    print_decor_summary(DecorInfo* decor, bool is_current)
     29{
     30    if ( is_current )
     31        printf("*");
     32
     33    printf("%-12s\t%-8s  %-30s\n",  decor->Name().String(),
     34                            decor->LicenseName().String(),
     35                            decor->ShortDescription().String());
     36}
     37
     38
     39void    print_decor_shortcut(DecorInfo* decor, bool is_current)
     40{
     41    if ( is_current )
     42        printf("*");
     43
     44    printf("%-12s\t%-12s\n",    decor->ShortcutName().String(),
     45                            decor->Name().String());
     46}
     47
     48
     49void    print_decor_info_verbose(DecorInfo* decor, bool is_current)
     50{
     51    printf("Name:\t\t%s\n", decor->Name().String());
     52    printf("Version:\t%f\n", decor->Version());
     53    printf("Author(s):\t%s\n", decor->Authors().String());
     54    printf("Description:\t%s\n", decor->ShortDescription().String());
     55    printf("License:\t%s (%s)\n", decor->LicenseName().String(),
     56            decor->LicenseURL().String());
     57    printf("Support URL:\t%s\n", decor->SupportURL().String());
     58    printf("%s\n", is_current ? "Currently in use." : "Currently not in use.");
     59}
     60
     61
    2562int main(int argc, char **argv)
    2663{
    27     status_t err;
    2864    if (argc < 2) {
    2965        printf("usage: %s [-l|-c|decorname]\n", argv[0]);
    3066        printf("\t-l: list available decors\n");
     67        printf("\t-s: list shortcut names for available decors\n");
    3168        printf("\t-c: give current decor name\n");
     69        printf("\t-i: detailed information about decor\n");
     70        printf("\t-p: see preview window\n");
    3271        return 1;
    3372    }
     73
     74        // combine remaining args into one string:
     75    BString decoratorName;
     76    for (int i = 2; i < argc; ++i)
     77        decoratorName << argv[i] << " ";
     78    decoratorName.RemoveLast(" ");
     79
    3480    BApplication app("application/x-vnd.Haiku-setdecor");
     81
     82    DecorInfoUtility* util = new DecorInfoUtility();
     83    DecorInfo* decor = NULL;
     84
     85    if (util == NULL) {
     86        fprintf(stderr, "error instantiating DecoratorInfoUtility ( out of"
     87                " memory? )\n");
     88        return 1;
     89    }
     90
    3591    // we want the list
    3692    if (!strcmp(argv[1], "-l")) {
    37         int32 i, count;
    38         count = count_decorators();
    39         if (count < 0) {
    40             fprintf(stderr, "error counting decorators: %s\n", strerror(count));
    41             return 1;
     93        // Print default decorator:
     94
     95        print_decor_info_header();
     96        int32 count = util->CountDecorators();
     97        for (int32 i = 0; i < count; ++i) {
     98            decor = util->DecoratorAt(i);
     99            if (decor == NULL) {
     100                fprintf(stderr, "error NULL entry @ %li / %li - BUG BUG BUG\n",
     101                        i, count);
     102                return 2; // return 2 to track DecorInfoUtility errors
     103            }
     104            print_decor_summary(decor, util->IsCurrentDecorator(decor));
    42105        }
    43         for (i = 0; i < count; i++) {
    44             BString name;
    45             err = get_decorator_name(i, name);
    46             if (err < 0)
    47                 continue;
    48             printf("%s\n", name.String());
     106
     107        return 0;
     108    }
     109
     110    // we want the current decorator
     111    if (!strcmp(argv[1], "-c")) {
     112        decor = util->CurrentDecorator();
     113
     114        if (decor == NULL) {
     115            fprintf(stderr, "Unable to determine current decorator, sorry! - "
     116                    "BUG BUG BUG\n");
     117            return 2;
    49118        }
     119
     120        print_decor_info_header();
     121        print_decor_summary(decor, true);
    50122        return 0;
    51123    }
    52     // we want the current one
    53     if (!strcmp(argv[1], "-c")) {
    54         int32 i;
    55         BString name;
    56         i = get_decorator();
    57         if (i < 0) {
    58             fprintf(stderr, "error getting current decorator: %s\n", strerror(i));
     124
     125
     126    if (!strcmp(argv[1], "-s")) {
     127
     128        printf("  Shortcut        Name\n");
     129        printf("------------------------------------\n");
     130
     131        int32 count = util->CountDecorators();
     132        for (int32 i = 0; i < count; ++i) {
     133            decor = util->DecoratorAt(i);
     134            if (decor == NULL) {
     135                fprintf(stderr, "error NULL entry @ %li / %li - BUG BUG BUG\n",
     136                        i, count);
     137                return 2; // return 2 to track DecorInfoUtility errors
     138            }
     139            print_decor_shortcut(decor, util->IsCurrentDecorator(decor));
     140        }
     141
     142        return 0;
     143
     144    }
     145
     146    // we want detailed information for a specific decorator ( by name or path )
     147    if (!strcmp(argv[1], "-i")) {
     148        if (argc < 3) {
     149            fprintf(stderr, "not enough arguments\n");
    59150            return 1;
    60151        }
    61         err = get_decorator_name(i, name);
    62         if (err < 0) {
    63             fprintf(stderr, "error getting name of decorator: %s\n", strerror(err));
     152
     153        decor = util->FindDecorator(decoratorName.String());
     154
     155        if (decor == NULL) {
     156                fprintf(stderr, "Can't find decor named \"%s\", try again\n",
     157                        decoratorName.String());
     158                return 1;
     159            }
     160
     161        print_decor_info_verbose(decor, util->IsCurrentDecorator(decor));
     162        return 0;
     163    }
     164
     165
     166    if (!strcmp(argv[1], "-p")) {
     167        if (argc < 3) {
     168            fprintf(stderr, "not enough arguments\n");
    64169            return 1;
    65170        }
    66         printf("%s\n", name.String());
     171
     172
     173        decor = util->FindDecorator(decoratorName.String());
     174
     175        if (decor == NULL) {
     176                fprintf(stderr, "Can't find decor named \"%s\", try again\n",
     177                        decoratorName.String());
     178                return 1;
     179            }
     180
     181        printf("Preparing preview...\n");
     182
     183
     184        BWindow* win = new BWindow(BRect(50,50,290,390),
     185                                    decor->Name().String(),
     186                                    B_TITLED_WINDOW,
     187                                    B_NOT_ZOOMABLE
     188                                        | B_QUIT_ON_WINDOW_CLOSE
     189                                        | B_NOT_RESIZABLE );
     190
     191        win->MoveBy(100,100);
     192        BView* v = new BView(win->Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW);
     193        win->AddChild(v);
     194
     195        if (util->Preview(decor, win) != B_OK) {
     196                fprintf(stderr, "Unable to preview decorator, sorry!\n");
     197                return 1;   // todo more detailed error...
     198            }
     199
     200        win->Show();
     201
     202        be_app->Run();
    67203        return 0;
    68204    }
     205
     206
    69207    // we want to change it
    70     int32 i, count;
    71     count = count_decorators();
    72     if (count < 0) {
    73         fprintf(stderr, "error counting decorators: %s\n", strerror(count));
     208    decoratorName = "";
     209    for (int i = 1; i < argc; ++i)
     210        decoratorName << argv[i] << " ";
     211    decoratorName.RemoveLast(" ");
     212
     213    decor = util->FindDecorator(decoratorName.String());
     214
     215    if (decor == NULL) {
     216        fprintf(stderr, "no such decorator \"%s\"\n", decoratorName.String());
    74217        return 1;
    75218    }
    76     for (i = 0; i < count; i++) {
    77         BString name;
    78         err = get_decorator_name(i, name);
    79         if (err < 0)
    80             continue;
    81         if (name == argv[1]) {
    82             err = set_decorator(i);
    83             if (err < 0) {
    84                 fprintf(stderr, "error setting decorator: %s\n", strerror(err));
    85                 return 1;
    86             }
    87             return 0;
    88         }
     219
     220    if (util->IsCurrentDecorator(decor)) {
     221        printf("\"%s\" is already the current decorator\n",
     222                decor->Name().String());
     223        return 0;
    89224    }
    90     fprintf(stderr, "can't find decorator \"%s\"\n", argv[1]);
    91     return 1;
     225
     226    printf("Setting %s as the current decorator...\n", decor->Name().String());
     227    if (util->SetDecorator(decor) != B_OK ) {
     228        fprintf(stderr, "Unable to set decorator, sorry\n\n");
     229        return 1;   // todo more detailed error...
     230    }
     231
     232    return 0;
    92233}
    93234
  • src/servers/app/DecorManager.cpp

     
    55 * Author:
    66 *      DarkWyrm <bpmagic@columbus.rr.com>
    77 *      Clemens Zeidler <haiku@clemens-zeidler.de>
     8 *      Joseph Groover <looncraz@satx.rr.com>
    89 */
    910
    1011#include "DecorManager.h"
     
    4445
    4546DecorAddOn::~DecorAddOn()
    4647{
    47 
    4848}
    4949
    5050
     
    7070
    7171    if (!decorator)
    7272        return NULL;
     73
    7374    decorator->SetDrawingEngine(engine);
    7475    decorator->SetTitle(title);
    7576
     
    102103//  #pragma mark -
    103104
    104105
     106
    105107DecorManager::DecorManager()
    106108    :
    107     fDefaultDecorAddOn(-1, "Default"),
    108     fCurrentDecor(NULL)
     109    fDefaultDecor(-1, "Default"),
     110    fCurrentDecor(&fDefaultDecor),
     111    fPreviewDecor(NULL),
     112    fPreviewWindow(NULL),
     113    fCurrentDecorPath("Default")
    109114{
    110     // Start with the default decorator - index is always 0
    111     fDecorList.AddItem(&fDefaultDecorAddOn);
    112 
    113     // Add any on disk
    114     RescanDecorators();
    115 
    116115    _LoadSettingsFromDisk();
    117 
    118     if (!fCurrentDecor)
    119         fCurrentDecor = fDecorList.ItemAt(0L);
    120116}
    121117
    122118
    123119DecorManager::~DecorManager()
    124120{
    125     _EmptyList();
     121    syslog(LOG_INFO, "app_server::DecorManager::~DecorManager() destructor\n");
    126122}
    127123
    128 
    129 void
    130 DecorManager::RescanDecorators()
    131 {
    132     BDirectory dir(DECORATORS_DIR);
    133 
    134     if (dir.InitCheck() != B_OK)
    135         return;
    136 
    137     entry_ref ref;
    138     while (dir.GetNextRef(&ref) == B_OK) {
    139         BPath path;
    140         path.SetTo(DECORATORS_DIR);
    141         path.Append(ref.name);
    142 
    143         // Because this function is used for both initialization and for keeping
    144         // the list up to date, check for existence in the list. Note that we
    145         // do not check to see if a decorator has been removed. This is for
    146         // stability. If there is a decorator in memory already whose file has
    147         // been deleted, it is still available until the next boot, at which point
    148         // it will obviously not be loaded.
    149 
    150         if (_FindDecor(ref.name))
    151             continue;
    152 
    153         image_id image = load_add_on(path.Path());
    154         if (image < 0)
    155             continue;
    156 
    157         // As of now, we do nothing with decorator versions, but the possibility
    158         // exists that the API will change even though I cannot forsee any reason
    159         // to do so. If we *did* do anything with decorator versions, the
    160         // assignment would go here.
    161 
    162         create_decor_addon* createFunc;
    163 
    164         // Get the instantiation function
    165         status_t status = get_image_symbol(image, "instantiate_decor_addon",
    166                                 B_SYMBOL_TYPE_TEXT, (void**)&createFunc);
    167         if (status != B_OK) {
    168             unload_add_on(image);
    169             continue;
    170         }
    171 
    172         DecorAddOn* addon = createFunc(image, ref.name);
    173 
    174         // TODO: unload images until they are actually used!
    175         if (!addon || addon->InitCheck() != B_OK
    176             || !fDecorList.AddItem(addon)) {
    177             unload_add_on(image);
    178             delete addon;
    179             continue;
    180         }
    181     }
    182 }
    183 
    184 
    185124Decorator *
    186 DecorManager::AllocateDecorator(Desktop* desktop, DrawingEngine* engine,
    187     BRect rect, const char* title, window_look look, uint32 flags)
     125DecorManager::AllocateDecorator(Window *window)
    188126{
    189127    // Create a new instance of the current decorator.
    190128    // Ownership is that of the caller
    191 
    192129    if (!fCurrentDecor) {
    193130        // We should *never* be here. If we do, it's a bug.
    194131        debugger("DecorManager::AllocateDecorator has a NULL decorator");
    195132        return NULL;
    196133    }
    197134
    198     return fCurrentDecor->AllocateDecorator(desktop, engine, rect, title,
    199         look, flags);
     135    // Are we previewing a specific decorator?
     136    if ( window == fPreviewWindow ) {
     137        if (fPreviewDecor != NULL) {
     138            return fPreviewDecor->AllocateDecorator(window->Desktop(),
     139                        window->GetDrawingEngine(), window->Frame(),
     140                        window->Title(), window->Look(), window->Flags());
     141        } else {
     142            fPreviewWindow = NULL;
     143        }
     144    }
     145
     146    return fCurrentDecor->AllocateDecorator(window->Desktop(),
     147                window->GetDrawingEngine(), window->Frame(),
     148                window->Title(), window->Look(), window->Flags());
    200149}
    201150
    202151
     
    213162}
    214163
    215164
    216 const DesktopListenerList&
    217 DecorManager::GetDesktopListeners()
    218 {
    219     return fCurrentDecor->GetDesktopListeners();
     165void
     166DecorManager::CleanupForWindow(Window *window)
     167{   // given window is being deleted, do any cleanup needed
     168    if (fPreviewWindow == window && window != NULL){
     169        fPreviewWindow = NULL;
     170
     171        if (fPreviewDecor != NULL)
     172            unload_add_on(fPreviewDecor->ImageID());
     173
     174        fPreviewDecor = NULL;
     175    }
    220176}
    221177
    222178
    223 int32
    224 DecorManager::CountDecorators() const
    225 {
    226     return fDecorList.CountItems();
    227 }
     179status_t
     180DecorManager::PreviewDecorator(BString path, Window *window)
     181{
     182    if (fPreviewWindow != NULL && fPreviewWindow != window){
     183    // reset other window to current decorator - only one can preview
     184        Window * old_preview_window = fPreviewWindow;
     185        fPreviewWindow = NULL;
     186        old_preview_window->ReloadDecor();
     187    }
    228188
     189    if (window == NULL)
     190        return B_BAD_VALUE;
     191
     192    status_t error = B_OK;
     193    // We have to jump some hoops because the window must be able to
     194    // delete its decorator before we unload the add-on
     195    DecorAddOn* decorPtr = _LoadDecor(path, error),
     196            * oldDecor = fPreviewDecor;
    229197
    230 int32
    231 DecorManager::GetDecorator() const
    232 {
    233     return fDecorList.IndexOf(fCurrentDecor);
    234 }
     198    if (decorPtr == NULL)
     199        return error == B_OK ? B_ERROR : error;
    235200
     201    BRegion border, newBorder;
     202    window->GetBorderRegion(&border);
     203
    236204
    237 bool
    238 DecorManager::SetDecorator(int32 index, Desktop* desktop)
    239 {
    240     DecorAddOn* newDecor = fDecorList.ItemAt(index);
     205    fPreviewDecor = decorPtr;
     206    fPreviewWindow = window;
     207    fPreviewWindow->ReloadDecor(); // window deletes its decorator here
     208
     209    window->GetBorderRegion(&newBorder);
     210    border.Include(&newBorder);
     211    window->Desktop()->RebuildAndRedrawAfterWindowChange(window, border);
    241212
    242     if (newDecor) {
    243         fCurrentDecor = newDecor;
    244         desktop->ReloadDecor();
    245         _SaveSettingsToDisk();
    246         return true;
    247     }
     213    if (oldDecor != NULL)
     214        unload_add_on(oldDecor->ImageID());
    248215
    249     return false;
     216
     217    return B_OK;
    250218}
    251219
    252220
    253 bool
    254 DecorManager::SetR5Decorator(int32 value)
     221const DesktopListenerList&
     222DecorManager::GetDesktopListeners()
    255223{
    256     BString string;
     224    return fCurrentDecor->GetDesktopListeners();
     225}
    257226
    258     switch (value) {
    259         case 0: string = "BeOS"; break;
    260         case 1: string = "AmigaOS"; break;
    261         case 2: string = "Windows"; break;
    262         case 3: string = "MacOS"; break;
    263         default:
    264             return false;
    265     }
    266227
    267     DecorAddOn *newDecor = _FindDecor(string);
    268     if (newDecor) {
    269         fCurrentDecor = newDecor;
    270         return true;
    271     }
    272 
    273     return false;
     228BString
     229DecorManager::GetCurrentDecorator() const
     230{
     231    return fCurrentDecorPath.String();
    274232}
    275233
    276234
    277 BString
    278 DecorManager::GetDecoratorName(int32 index)
     235status_t
     236DecorManager::SetDecorator(BString path, Desktop* desktop)
    279237{
    280     DecorAddOn *decor = fDecorList.ItemAt(index);
    281     if (decor)
    282         return decor->Name();
     238    status_t error = B_OK;
    283239
    284     return BString("");
    285 }
     240    DecorAddOn *newDecor = _LoadDecor(path, error);
     241
     242    if (!newDecor)
     243        return B_ERROR;
     244
     245    DecorAddOn *oldDecor = fCurrentDecor;
     246    BString oldPath = fCurrentDecorPath;
     247    image_id oldImage = fCurrentDecor->ImageID();
     248
     249    fCurrentDecor = newDecor;
     250    fCurrentDecorPath = path.String();
    286251
    287 
    288 void
    289 DecorManager::_EmptyList()
    290 {
    291     for (int32 i = 1; i < fDecorList.CountItems(); i++) {
    292         unload_add_on(fDecorList.ItemAt(i)->ImageID());
    293         delete fDecorList.ItemAt(i);
     252    if (desktop->ReloadDecor()) {
     253        // now safe to unload all old decorator data
     254        unload_add_on(oldImage); // saves us from deleting oldDecor...
     255        _SaveSettingsToDisk();
     256        return B_OK;
    294257    }
     258    // TODO: unloading the newDecor and its image
     259    // problem is we don't know how many windows failed...
     260        // or why they failed...
     261    syslog(LOG_WARNING,
     262            "app_server:DecorManager:SetDecorator:\"%s\" *partly* failed\n",
     263            fCurrentDecorPath.String());
    295264
    296     fDecorList.MakeEmpty();
    297     fDecorList.AddItem(&fDefaultDecorAddOn);
    298 
    299     fCurrentDecor = &fDefaultDecorAddOn;
     265    fCurrentDecor = oldDecor;
     266    fCurrentDecorPath = oldPath;
     267    return B_ERROR;
    300268}
    301269
    302270
     271
    303272DecorAddOn*
    304 DecorManager::_FindDecor(BString name)
     273DecorManager::_LoadDecor(BString _path, status_t &error )
    305274{
    306     if (!name)
     275    if (_path == "Default") {
     276        error = B_OK;
     277        return &fDefaultDecor;
     278    }
     279
     280    image_id image = -1;
     281    DecorAddOn* newDecor = NULL;
     282    entry_ref ref;
     283
     284    BEntry entry(_path.String(), true);
     285
     286    if (!entry.Exists()) {
     287        entry.Unset();
     288        error = B_ENTRY_NOT_FOUND;
    307289        return NULL;
    308 
    309     for (int32 i = 0; i < fDecorList.CountItems(); i++) {
    310         DecorAddOn* decor = fDecorList.ItemAt(i);
    311 
    312         if (decor->Name() == name)
    313             return decor;
    314290    }
     291
     292    BPath path(&entry);
     293    entry.GetRef(&ref);
     294    entry.Unset();
     295
     296    image = load_add_on(path.Path());
     297
     298    path.Unset();
     299
     300    if (image < 0) {
     301        error = B_BAD_IMAGE_ID;
     302        return NULL;
     303    }
     304
     305    create_decor_addon* createFunc;
     306
     307    if (get_image_symbol(image,
     308                "instantiate_decor_addon",
     309                B_SYMBOL_TYPE_TEXT,
     310                (void**)&createFunc) != B_OK) {
     311        unload_add_on(image);
     312        error = B_MISSING_SYMBOL;
     313        return NULL;
     314    }
     315
     316    newDecor = createFunc(image, ref.name);
     317
     318    if (newDecor == NULL || newDecor->InitCheck() != B_OK) {
     319        unload_add_on(image);
     320        error = B_ERROR;
     321        return NULL;
     322    }
    315323
    316     return NULL;
     324    return newDecor;
    317325}
    318326
    319327
     328
     329
    320330static const char* kSettingsDir = "system/app_server";
    321331static const char* kSettingsFile = "decorator_settings";
    322332
     
    338348
    339349    BMessage settings;
    340350    if (settings.Unflatten(&file) == B_OK) {
    341         BString itemtext;
    342         if (settings.FindString("decorator", &itemtext) == B_OK) {
    343             DecorAddOn* decor = _FindDecor(itemtext);
     351        BString itemPath;
     352        if (settings.FindString("decorator", &itemPath) == B_OK) {
     353            status_t error = B_OK;
     354            DecorAddOn* decor = _LoadDecor(itemPath, error);
    344355            if (decor) {
    345356                fCurrentDecor = decor;
    346357                return true;
     358            } else {
     359                //TODO: do something with the reported error
    347360            }
    348361        }
    349362    }
     
    371384        return false;
    372385
    373386    BMessage settings;
    374     if (settings.AddString("decorator", fCurrentDecor->Name()) != B_OK)
     387    if (settings.AddString("decorator", fCurrentDecorPath.String()) != B_OK)
    375388        return false;
    376389    if (settings.Flatten(&file) != B_OK)
    377390        return false;
  • src/servers/app/ServerApp.cpp

     
    648648        case AS_SET_DECORATOR:
    649649        {
    650650            // Attached Data:
    651             // int32 the index of the decorator to use
     651            // entry_ref to decorator
    652652
    653             int32 index;
    654             link.Read<int32>(&index);
    655             if (gDecorManager.SetDecorator(index, fDesktop))
     653            BString path;
     654            link.ReadString(path);
     655
     656            status_t error = gDecorManager.SetDecorator(path, fDesktop);
     657
     658            fLink.Attach<status_t>(error);
     659            fLink.Flush();
     660
     661            if (error == B_OK)
    656662                fDesktop->BroadcastToAllApps(AS_UPDATE_DECORATOR);
    657663            break;
    658664        }
    659665
    660         case AS_COUNT_DECORATORS:
    661         {
    662             fLink.StartMessage(B_OK);
    663             fLink.Attach<int32>(gDecorManager.CountDecorators());
    664             fLink.Flush();
    665             break;
    666         }
    667 
    668666        case AS_GET_DECORATOR:
    669667        {
    670668            fLink.StartMessage(B_OK);
    671             fLink.Attach<int32>(gDecorManager.GetDecorator());
     669            fLink.AttachString(gDecorManager.GetCurrentDecorator().String());
    672670            fLink.Flush();
    673671            break;
    674672        }
    675673
    676         case AS_GET_DECORATOR_NAME:
    677         {
    678             int32 index;
    679             link.Read<int32>(&index);
    680 
    681             BString str(gDecorManager.GetDecoratorName(index));
    682             if (str.CountChars() > 0) {
    683                 fLink.StartMessage(B_OK);
    684                 fLink.AttachString(str.String());
    685             } else
    686                 fLink.StartMessage(B_ERROR);
    687 
    688             fLink.Flush();
    689             break;
    690         }
    691 
    692         case AS_R5_SET_DECORATOR:
    693         {
    694             // Sort of supports Tracker's nifty Easter Egg. It was easy to do
    695             // and it's kind of neat, so why not?
    696 
    697             // Attached Data:
    698             // int32 value of the decorator to use
    699             // 0: BeOS
    700             // 1: Amiga
    701             // 2: Windows
    702             // 3: MacOS
    703 
    704             int32 decindex = 0;
    705             link.Read<int32>(&decindex);
    706 
    707             if (gDecorManager.SetR5Decorator(decindex))
    708                 fDesktop->BroadcastToAllApps(AS_UPDATE_DECORATOR);
    709 
    710             break;
    711         }
    712 
    713674        case AS_CREATE_BITMAP:
    714675        {
    715676            STRACE(("ServerApp %s: Received BBitmap creation request\n",
  • src/servers/app/Window.h

     
    375375            int32               fMaxHeight;
    376376
    377377            int32               fWorkspacesViewCount;
     378
     379        friend class DecorManager;
    378380};
    379381
    380382#endif // WINDOW_H
  • src/servers/app/Desktop.h

     
    221221            void                Redraw();
    222222            void                RedrawBackground();
    223223
    224             void                ReloadDecor();
     224            bool                ReloadDecor();
    225225
    226226            BRegion&            BackgroundRegion()
    227227                                    { return fBackgroundRegion; }
  • src/servers/app/ProfileMessageSupport.cpp

     
    162162        CODE(AS_SET_UI_COLOR);
    163163        CODE(AS_SET_DECORATOR);
    164164        CODE(AS_GET_DECORATOR);
    165         case AS_R5_SET_DECORATOR:
    166             string = "AS_R5_SET_DECORATOR"; break;
    167         CODE(AS_COUNT_DECORATORS);
    168         CODE(AS_GET_DECORATOR_NAME);
    169165
    170166        CODE(AS_SET_WORKSPACE_LAYOUT);
    171167        CODE(AS_GET_WORKSPACE_LAYOUT);
  • src/servers/app/Window.cpp

     
    129129    SetFlags(flags, NULL);
    130130
    131131    if (fLook != B_NO_BORDER_WINDOW_LOOK) {
    132         fDecorator = gDecorManager.AllocateDecorator(fDesktop, fDrawingEngine,
    133             frame, name, fLook, fFlags);
     132        fDecorator = gDecorManager.AllocateDecorator(this);
    134133        if (fDecorator) {
    135134            fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight,
    136135                &fMaxWidth, &fMaxHeight);
     
    172171
    173172    delete fWindowBehaviour;
    174173    delete fDecorator;
    175 
    176174    delete fDrawingEngine;
     175
     176    gDecorManager.CleanupForWindow(this);
    177177}
    178178
    179179
     
    548548{
    549549    ::Decorator* decorator = NULL;
    550550    WindowBehaviour* windowBehaviour = NULL;
     551
    551552
    552553    if (fLook != B_NO_BORDER_WINDOW_LOOK) {
    553554        // we need a new decorator
    554         decorator = gDecorManager.AllocateDecorator(fDesktop, fDrawingEngine,
    555             Frame(), Title(), fLook, fFlags);
    556         if (!decorator)
     555        decorator = gDecorManager.AllocateDecorator(this);
     556        if (decorator == NULL)
    557557            return false;
    558558        if (IsFocus())
    559559            decorator->SetFocus(true);
    560560    }
    561561
    562562    windowBehaviour = gDecorManager.AllocateWindowBehaviour(this);
    563     if (!windowBehaviour) {
     563    if (windowBehaviour == NULL) {
    564564        delete decorator;
    565565        return false;
    566566    }
     
    11081108bool
    11091109Window::SetDecoratorSettings(const BMessage& settings, BRegion& dirty)
    11101110{
     1111    if (settings.what == 'prVu') { // 'prVu' == preview a decorator!
     1112        BString path;
     1113        if (settings.FindString("preview", &path) == B_OK){
     1114            return gDecorManager.PreviewDecorator(path, this) == B_OK;
     1115        }
     1116        return false;
     1117    }
     1118
    11111119    if (fDecorator)
    11121120        return fDecorator->SetSettings(settings, &dirty);
    11131121    return false;
     
    11421150{
    11431151    if (fDecorator == NULL && look != B_NO_BORDER_WINDOW_LOOK) {
    11441152        // we need a new decorator
    1145         fDecorator = gDecorManager.AllocateDecorator(fDesktop, fDrawingEngine,
    1146             Frame(), Title(), fLook, fFlags);
     1153        fDecorator = gDecorManager.AllocateDecorator(this);
    11471154        if (IsFocus())
    11481155            fDecorator->SetFocus(true);
    11491156    }
  • src/servers/app/Desktop.cpp

     
    1717
    1818
    1919#include "Desktop.h"
    20 
    2120#include <stdio.h>
    2221#include <string.h>
    2322#include <syslog.h>
     
    20442043}
    20452044
    20462045
    2047 void
     2046bool
    20482047Desktop::ReloadDecor()
    20492048{
    20502049    AutoWriteLocker _(fWindowLock);
    2051 
     2050
     2051    bool returnValue = true;
     2052
    20522053    // TODO it is assumed all listeners are registered by one decor
    20532054    // unregister old listeners
    20542055    const DesktopListenerDLList& currentListeners = GetDesktopListenerList();
     
    20612062            BRegion oldBorder;
    20622063            window->GetBorderRegion(&oldBorder);
    20632064
    2064             window->ReloadDecor();
     2065            if (!window->ReloadDecor())
     2066                returnValue = false; // prevent unloading previous add-on
    20652067
    20662068            BRegion border;
    20672069            window->GetBorderRegion(&border);
     
    20752077        = gDecorManager.GetDesktopListeners();
    20762078    for (int i = 0; i < newListeners.CountItems(); i++)
    20772079        RegisterListener(newListeners.ItemAt(i));
     2080
     2081    return returnValue;
    20782082}
    20792083
    20802084
  • src/servers/app/DecorManager.h

     
    1414#include <String.h>
    1515#include <Locker.h>
    1616#include <ObjectList.h>
     17#include <Entry.h>
     18#include <DecorInfo.h>
    1719
    1820#include "Decorator.h"
    1921
    20 class DecorInfo;
    2122class Desktop;
    2223class DesktopListener;
    2324class DrawingEngine;
     
    2829typedef BObjectList<DesktopListener> DesktopListenerList;
    2930
    3031
     32// special name to test for use of non-fs-tied default decorator
     33// this just keeps things clean and simple is all
     34
    3135class DecorAddOn {
    3236public:
    3337                                DecorAddOn(image_id id, const char* name);
     
    3640    virtual status_t            InitCheck() const;
    3741
    3842        image_id                ImageID() const { return fImageID; }
    39         BString                 Name() const { return fName; }
    4043
    4144        Decorator*              AllocateDecorator(Desktop* desktop,
    4245                                    DrawingEngine* engine, BRect rect,
    4346                                    const char* title, window_look look,
    4447                                    uint32 flags);
    4548
    46     virtual float               Version() { return 1.0; }
    4749    virtual WindowBehaviour*    AllocateWindowBehaviour(Window* window);
    4850
    4951    virtual const DesktopListenerList&  GetDesktopListeners();
     
    6365class DecorManager
    6466{
    6567public:
    66                     DecorManager();
    67                     ~DecorManager();
     68                            DecorManager();
     69                            ~DecorManager();
    6870
    69         void        RescanDecorators();
     71        Decorator*          AllocateDecorator(Window *window);
     72        WindowBehaviour*    AllocateWindowBehaviour(Window *window);
     73        void                CleanupForWindow(Window *window);
     74
     75        status_t            PreviewDecorator(BString path, Window *window);
    7076
    71         Decorator*  AllocateDecorator(Desktop* desktop,
    72                         DrawingEngine* engine,
    73                         BRect rect,
    74                         const char* title, window_look look,
    75                         uint32 flags);
    76         WindowBehaviour*            AllocateWindowBehaviour(Window* window);
    77         const DesktopListenerList&  GetDesktopListeners();
     77    const DesktopListenerList&  GetDesktopListeners();
    7878
    79         int32       CountDecorators() const;
    80 
    81         int32       GetDecorator() const;
    82         bool        SetDecorator(int32 index, Desktop* desktop);
    83         bool        SetR5Decorator(int32 value);
    84         BString     GetDecoratorName(int32 index);
    85 
    86         // TODO: Implement this method once the rest of the necessary infrastructure
    87         // is in place
    88         //status_t  GetPreview(int32 index, ServerBitmap *bitmap);
    89 
     79        BString             GetCurrentDecorator() const;
     80        status_t            SetDecorator(BString path, Desktop *desktop);
     81
    9082private:
    91         void        _EmptyList();
    92         DecorAddOn* _FindDecor(BString name);
     83        DecorAddOn*         _LoadDecor(BString path, status_t &error);
     84        bool                _LoadSettingsFromDisk();
     85        bool                _SaveSettingsToDisk();
    9386
    94         bool        _LoadSettingsFromDisk();
    95         bool        _SaveSettingsToDisk();
    96 
    97         BObjectList<DecorAddOn> fDecorList;
    98         DecorAddOn  fDefaultDecorAddOn;
    99         DecorAddOn* fCurrentDecor;
     87        DecorAddOn          fDefaultDecor,
     88                            *fCurrentDecor,
     89                            *fPreviewDecor;
     90
     91        Window              *fPreviewWindow;
     92        BString             fCurrentDecorPath;
    10093};
    10194
    10295extern DecorManager gDecorManager;
  • src/kits/interface/DecorInfo.cpp

     
     1/*
     2 * Public domain source code.
     3 *
     4 * Author:
     5 *      Joseph "looncraz" Groover <looncraz@satx.rr.com>
     6 */
     7
     8
     9#include <stdio.h>
     10#include <DecorInfo.h>
     11#include <Path.h>
     12#include <Resources.h>
     13
     14#include <Directory.h>
     15#include <FindDirectory.h>
     16
     17
     18DecorInfo::DecorInfo()
     19    :
     20    fVersion(0),
     21    fModificationTime(0),
     22    fInitStatus(B_NO_INIT)
     23{
     24}
     25
     26DecorInfo::DecorInfo(BString path)
     27    :
     28    fPath(path.String()),
     29    fVersion(0),
     30    fModificationTime(0),
     31    fInitStatus(B_NO_INIT)
     32{
     33    BEntry entry(path.String(), true);
     34    entry.GetRef(&fRef);
     35    entry.Unset();
     36
     37    _Init();
     38}
     39
     40DecorInfo::DecorInfo(const entry_ref& ref)
     41    :
     42    fRef(ref),
     43    fVersion(0),
     44    fModificationTime(0),
     45    fInitStatus(B_NO_INIT)
     46{
     47    BPath path(&ref);
     48    fPath = path.Path();
     49    path.Unset();
     50
     51    _Init();
     52}
     53
     54DecorInfo::~DecorInfo()
     55{
     56}
     57
     58status_t
     59DecorInfo::SetTo(const entry_ref& ref)
     60{
     61    Unset();
     62
     63    BPath path(&ref);
     64    fPath = path.Path();
     65    path.Unset();
     66
     67    fRef = ref;
     68    _Init();
     69
     70    return InitCheck();
     71}
     72
     73status_t
     74DecorInfo::SetTo(BString path)
     75{
     76    entry_ref ref;
     77    BEntry entry(path.String(), true);
     78    entry.GetRef(&ref);
     79    entry.Unset();
     80    return SetTo(ref);
     81}
     82
     83status_t
     84DecorInfo::InitCheck()  const
     85{
     86        return fInitStatus;
     87}
     88
     89void
     90DecorInfo::Unset()
     91{
     92    fRef = entry_ref();
     93    fPath = "";
     94    fName = "";
     95    fAuthors = "";
     96    fShortDescription = "";
     97    fLicenseURL = "";
     98    fLicenseName = "";
     99    fSupportURL = "";
     100    fVersion = 0;
     101    fModificationTime = 0;
     102    fInitStatus = B_NO_INIT;
     103}
     104
     105
     106bool
     107DecorInfo::IsDefault() const
     108{
     109    return (fInitStatus == B_OK && Path() == "default");
     110}
     111
     112
     113BString
     114DecorInfo::Path() const
     115{
     116    return fPath.String();
     117}
     118
     119const entry_ref*
     120DecorInfo::Ref() const
     121{
     122    if (InitCheck() != B_OK
     123        ||  IsDefault())
     124        return NULL;
     125    return &fRef;
     126}
     127
     128
     129BString
     130DecorInfo::Name() const
     131{
     132    return fName;
     133}
     134
     135
     136BString
     137DecorInfo::ShortcutName() const
     138{
     139    if (Ref())
     140        return fRef.name;
     141    return Name();
     142}
     143
     144
     145BString
     146DecorInfo::Authors() const
     147{
     148        return fAuthors;
     149}
     150
     151BString
     152DecorInfo::ShortDescription() const
     153{
     154        return fShortDescription;
     155}
     156
     157BString
     158DecorInfo::LongDescription() const
     159{
     160        return fLongDescription;
     161}
     162
     163BString
     164DecorInfo::LicenseURL() const
     165{
     166        return fLicenseURL;
     167}
     168
     169BString
     170DecorInfo::LicenseName() const
     171{
     172        return fLicenseName;
     173}
     174
     175BString
     176DecorInfo::SupportURL() const
     177{
     178        return fSupportURL;
     179}
     180
     181float
     182DecorInfo::Version() const
     183{
     184    return fVersion;
     185}
     186
     187time_t
     188DecorInfo::ModificationTime() const
     189{
     190    return fModificationTime;
     191}
     192
     193bool
     194DecorInfo::CheckForChanges(bool &deleted)
     195{
     196    if (InitCheck() != B_OK)
     197        return false;
     198
     199    BEntry entry(&fRef);
     200
     201    if (entry.InitCheck() != B_OK) {
     202        entry.Unset();
     203        return false;
     204    }
     205
     206    if (!entry.Exists()) {
     207        entry.Unset();
     208        deleted = true;
     209        return true;
     210    }
     211
     212    time_t modtime = 0;
     213
     214    if (entry.GetModificationTime(&modtime) != B_OK) {
     215        entry.Unset();
     216        fprintf(stderr, "DecorInfo::CheckForChanges()\tERROR: "
     217                "BEntry:GetModificationTime() failed\n");
     218        return false;
     219    }
     220
     221    if (fModificationTime != modtime) {
     222        _Init(true);
     223        return true;
     224    }
     225
     226    return false;
     227}
     228            // checks for changes (by modification time), and updates data
     229            // accordingly
     230
     231void
     232DecorInfo::_Init(bool is_update)
     233{
     234    if (!is_update && InitCheck() != B_NO_INIT)
     235        { // TODO: remove after validation
     236                fprintf(stderr, "DecorInfo::_Init()\tImproper init state\n");
     237                return;
     238        }
     239
     240    BEntry entry;
     241
     242    if (fPath == "Default")
     243    {
     244        if (is_update){
     245            fprintf(stderr, "DecorInfo::_Init(true)\tBUG BUG updating default"
     246                    "decorator!?!?!\n");
     247            return; // should never happen
     248        }
     249
     250        fName = "Default";
     251        fAuthors = "DarkWyrm, Stephan Aßmus, Clemens Zeidler, ";
     252            fAuthors << "Ingo Weinhold";
     253        fShortDescription = "Default Haiku window decorator.";
     254        fLongDescription = fShortDescription;
     255        fLicenseURL = "http://";
     256        fLicenseName = "MIT";
     257        fSupportURL = "http://www.haiku-os.org/";
     258        fVersion = 0.5;
     259        fInitStatus = B_OK;
     260
     261        // the following is to get the modification time of the app_server
     262            // and, thusly, the Default decorator...
     263            // if you can make it more simple, please do!
     264
     265        BPath path;
     266            find_directory(B_BEOS_SERVERS_DIRECTORY, &path );
     267            path.Append("app_server");
     268            entry.SetTo(path.Path(), true);
     269        path.Unset();
     270
     271        if (!entry.Exists()) {
     272            fprintf(stderr, "server MIA"
     273                            "the world has become its slave!"
     274                            "call the CIA\n");
     275
     276            entry.Unset();
     277            return;
     278        }
     279
     280        entry.GetModificationTime(&fModificationTime);
     281        entry.Unset();
     282        return;
     283    }
     284
     285    // Is a file system object...
     286
     287    entry.SetTo(&fRef, true);   // follow links
     288
     289    if (entry.InitCheck() != B_OK) {
     290        fInitStatus = entry.InitCheck();
     291        entry.Unset();
     292        return;
     293    }
     294
     295    if (!entry.Exists()) {
     296        entry.Unset();
     297        if (is_update) {
     298            fprintf(stderr, "DecorInfo::_Init()\tERROR: decorator deleted"
     299                    " after CheckForChanges() found it!\n");
     300            fprintf(stderr, "DecorInfo::_Init()\tERROR: DecorInfo will "
     301                    "Unset\n");
     302            Unset();
     303        }
     304        return;
     305    }
     306    // update fRef to match file system object
     307
     308    entry.GetRef(&fRef);
     309        entry.GetModificationTime(&fModificationTime);
     310    entry.Unset();
     311
     312    BResources  rsrc(&fRef);
     313
     314    if (rsrc.InitCheck() != B_OK) {
     315        fprintf(stderr, "DecorInfo::_Init()\t BResource InitCheck() "
     316                "failure\n");
     317        rsrc.Unset();
     318        return;
     319    }
     320
     321    size_t  sz = 0;
     322
     323    const void* ptr = rsrc.LoadResource(B_MESSAGE_TYPE, "be:decor:info", &sz);
     324    BMessage* msg = new BMessage();
     325
     326    if (!ptr || !msg || sz <= 0) {
     327        fprintf(stderr, "DecorInfo::_init()\tNo extended information found for"
     328                " \"%s\"\n", fRef.name);
     329    }else{
     330        msg->Unflatten((const char*)ptr);
     331        msg->FindString("name",         &fName);
     332        msg->FindString("authors",      &fAuthors);
     333        msg->FindString("short_descr",  &fShortDescription);
     334        msg->FindString("long_descr",   &fLongDescription);
     335        msg->FindString("lic_url",      &fLicenseURL);
     336        msg->FindString("lic_name",     &fLicenseName);
     337        msg->FindString("support_url",  &fSupportURL);
     338        msg->FindFloat ("version",      &fVersion);
     339    }
     340
     341    rsrc.Unset();
     342    fInitStatus = B_OK;
     343
     344    if (fName == "")
     345        fName = fRef.name;
     346}
     347
     348
     349/*
     350
     351    DecorInfoUtility below this point
     352
     353*/
     354
     355
     356namespace BPrivate{ // kits/interface/InterfaceDefs.cpp
     357    bool        get_decorator(BString*);
     358    status_t    set_decorator(BString);
     359    status_t    preview_decorator(BString, BWindow*);
     360
     361};
     362
     363using namespace BPrivate;
     364
     365
     366DecorInfoUtility::DecorInfoUtility(bool scan_now)
     367    :
     368    fHasScanned(false)
     369{
     370    // get default decorator from app_server
     371
     372    DecorInfo* info = new DecorInfo("Default");
     373
     374    if (info->InitCheck() != B_OK)  {
     375        fprintf(stderr, "DecorInfoUtility::constructor\tdefault decorator's "
     376                "DecorInfo failed InitCheck()\n");
     377        return;
     378    }
     379
     380    fList.AddItem(info);
     381
     382    if (scan_now)
     383        ScanDecorators();
     384}
     385
     386
     387DecorInfoUtility::~DecorInfoUtility()
     388{
     389    fLock.Lock();
     390
     391    DecorInfo* decor = NULL;
     392
     393    for (int i = fList.CountItems() - 1; i >= 0; --i) {
     394        decor = fList.ItemAt(i);
     395        if (!decor) {
     396            fprintf(stderr, "DecorInfoUtility::destructor\tNULL DecorInfo "
     397                    "in list!\n");
     398            continue;
     399        }
     400        delete decor;
     401        fList.RemoveItemAt(i);
     402    }
     403}
     404
     405
     406status_t
     407DecorInfoUtility::ScanDecorators()
     408{
     409    BPath decorPath;
     410
     411    find_directory(B_USER_ADDONS_DIRECTORY, &decorPath);
     412
     413    decorPath.Append("decorators");
     414
     415    BDirectory dir(decorPath.Path());
     416
     417    if (dir.InitCheck() != B_OK) {
     418            fprintf(stderr, "DecorInfoUtility::ScanDecorators:\tERROR: "
     419                    "DECORATORS_DIR not found!\n");
     420            dir.Unset();
     421            return B_ENTRY_NOT_FOUND;
     422        }
     423
     424
     425    BString* tstr = new BString();
     426
     427    if (!get_decorator(tstr)) {
     428        fprintf(stderr, "DecorInfoUtility::ScanDecorators()\tERROR: no can "
     429                "speak to app_server!\n");
     430        return B_ERROR;
     431    }
     432
     433    BString cur_decor = tstr->String();
     434
     435    DecorInfo* decor_ptr = NULL;
     436
     437    fLock.Lock();
     438    // First, run through our list and DecorInfos CheckForChanges()
     439
     440    if (fHasScanned) {
     441        for (int i = fList.CountItems() - 1; i >= 0; --i) {
     442            decor_ptr = fList.ItemAt(i);
     443
     444            if (decor_ptr) {
     445                if (decor_ptr->IsDefault())
     446                    continue;
     447
     448                bool deleted = false;
     449                decor_ptr->CheckForChanges(deleted);
     450
     451                if (deleted) {
     452                            fList.RemoveItem(decor_ptr);
     453                            delete decor_ptr;
     454                }
     455            }
     456            else
     457                fprintf(stderr, "DecorInfoUtility::ScanDecorators()\tFound "
     458                        "NULL entry in list @ %i _ BUG BUG BUG\n", i);
     459        }
     460    }
     461
     462    decor_ptr = NULL;
     463
     464    DecorInfo* decor = NULL;
     465    BPath path;
     466    entry_ref ref;
     467    // Now, look at file system:
     468    while (dir.GetNextRef(&ref) == B_OK) {
     469        path.Unset();
     470        path.SetTo(decorPath.Path());
     471        path.Append(ref.name);
     472
     473        decor_ptr = _find_decor(path.Path());
     474
     475        if (decor_ptr)
     476            continue;
     477
     478        decor = new DecorInfo(ref);
     479
     480        if (decor->InitCheck() != B_OK) {
     481            fprintf(stderr, "DecorInfoUtility::ScanDecorators()\tInitCheck() "
     482                    "failure on decorator, skipping\n");
     483            delete decor;
     484            decor = NULL;
     485            continue;
     486        }
     487
     488        fList.AddItem(decor);
     489    }
     490
     491    fHasScanned = true;
     492    fLock.Unlock();
     493    path.Unset();
     494    decorPath.Unset();
     495    return B_OK;
     496}
     497
     498
     499int32
     500DecorInfoUtility::CountDecorators()
     501{
     502    if (!fHasScanned)
     503        ScanDecorators();
     504
     505    return fList.CountItems();
     506}
     507
     508
     509DecorInfo*
     510DecorInfoUtility::DecoratorAt(int32 indx)
     511{
     512    return fList.ItemAt(indx);
     513}
     514
     515
     516DecorInfo*
     517DecorInfoUtility::FindDecorator(BString str)
     518{
     519    if (!fHasScanned)
     520        ScanDecorators();
     521
     522    BString tmp = str.String();
     523    if (tmp.ToLower() == "default")
     524        return DefaultDecorator();
     525
     526    if (str == "")
     527        return CurrentDecorator();
     528
     529    fLock.Lock();
     530
     531    // search by path
     532    DecorInfo* ptr = _find_decor(str);
     533
     534    if (ptr) {
     535        fLock.Unlock();
     536        return ptr;
     537    }
     538
     539    // scan through Name()
     540    str.ToLower();
     541
     542    BString lc_comp, lc_comp2;
     543
     544    for (int i = 1; i < fList.CountItems(); ++i) {
     545        ptr = fList.ItemAt(i);
     546
     547        if (ptr == NULL) {
     548            fprintf(stderr, "DecorInfoUtility::FindDecorator()\tFound NULL "
     549                    "entry @ %i BUG BUG\n", i);
     550            continue;
     551        }
     552        // last, but not least, we compare lower-case
     553
     554        lc_comp = ptr->Name();
     555        lc_comp.ToLower();
     556        lc_comp2 = "";
     557
     558        if (ptr->Ref())
     559            lc_comp2 = ptr->Ref()->name;
     560
     561        lc_comp2.ToLower();
     562
     563        // if "fancy" name or the file's name match, we are golden!
     564        if (lc_comp == str
     565            || str == lc_comp2) {
     566                fLock.Unlock();
     567                return ptr;
     568            }
     569    }
     570
     571    fLock.Unlock();
     572    return NULL;
     573}
     574
     575
     576DecorInfo*
     577DecorInfoUtility::CurrentDecorator()
     578{
     579    if (!fHasScanned)
     580        ScanDecorators();
     581
     582    BString str;
     583    get_decorator(&str);
     584    return FindDecorator(str);
     585}
     586
     587
     588DecorInfo*
     589DecorInfoUtility::DefaultDecorator()
     590{
     591    return fList.ItemAt(0);
     592}
     593
     594
     595bool
     596DecorInfoUtility::IsCurrentDecorator(DecorInfo* decor)
     597{
     598    if (decor == NULL)
     599         return false;
     600    return decor->Path() == CurrentDecorator()->Path().String();
     601}
     602
     603
     604status_t
     605DecorInfoUtility::SetDecorator(DecorInfo* decor)
     606{
     607    if (decor == NULL)
     608        return B_BAD_VALUE;
     609
     610    if (decor->IsDefault())
     611        return set_decorator("Default");
     612
     613    return set_decorator(decor->Path());
     614}
     615
     616
     617status_t
     618DecorInfoUtility::SetDecorator(int32 indx)
     619{
     620    if (!fHasScanned)
     621        return B_ERROR;
     622
     623    DecorInfo* decor = DecoratorAt(indx);;
     624
     625    if (!decor)
     626        return B_BAD_INDEX;
     627
     628    return SetDecorator(decor);
     629}
     630
     631
     632status_t
     633DecorInfoUtility::Preview(DecorInfo* decor, BWindow* window)
     634{
     635    if (decor == NULL)
     636        return B_BAD_VALUE;
     637
     638    return preview_decorator(decor->Path(), window);
     639}
     640
     641
     642// P R I V A T E
     643    // ENFORCE LOCKING!
     644
     645DecorInfo*
     646DecorInfoUtility::_find_decor(BString _path)
     647{       // find decor by path and path alone!
     648    if (!fLock.IsLocked()) {
     649        fprintf(stderr, "DecorInfoUtility::_find_decor()\tfailure to lock! - "
     650                "BUG BUG BUG\n");
     651        return NULL;
     652    }
     653
     654    BString tmp = _path;
     655    if (tmp.ToLower() == "default")
     656        return fList.ItemAt(0);
     657
     658    DecorInfo* decor = NULL;
     659
     660    BPath path;
     661
     662    for ( int i = 1; i < fList.CountItems(); ++i ) {
     663        decor = fList.ItemAt(i);
     664        if (decor == NULL) {
     665            fprintf(stderr, "DecorInfoUtility::_find_decor()\tfound NULL @ %i!"
     666                    " - BUG BUG BUG\n", i);
     667            continue;
     668        }
     669
     670        path.SetTo(decor->Ref());
     671
     672        if (path.Path() == _path
     673            ||decor->Path() == _path) {
     674                    path.Unset();
     675                    return decor;
     676            }
     677
     678        path.Unset();
     679    }
     680
     681    return NULL;
     682}
  • src/kits/interface/InterfaceDefs.cpp

     
    3232#include <ScrollBar.h>
    3333#include <String.h>
    3434#include <TextView.h>
     35#include <Window.h>
    3536
    3637#include <ApplicationPrivate.h>
    3738#include <AppServerLink.h>
    3839#include <ColorConversion.h>
     40#include <DecorInfo.h>
    3941#include <DefaultColors.h>
    4042#include <InputServerTypes.h>
    4143#include <input_globals.h>
     
    11851187}
    11861188
    11871189
    1188 //  #pragma mark -
    11891190
    1190 
    1191 /*! \brief private function used by Deskbar to set window decor
    1192     Note, we don't have to be compatible here, and could just change
    1193     the Deskbar not to use this anymore
    1194     \param theme The theme to choose
    1195 
    1196     - \c 0: BeOS
    1197     - \c 1: AmigaOS
    1198     - \c 2: Win95
    1199     - \c 3: MacOS
    1200 */
    1201 void
    1202 __set_window_decor(int32 theme)
    1203 {
    1204     BPrivate::AppServerLink link;
    1205     link.StartMessage(AS_R5_SET_DECORATOR);
    1206     link.Attach<int32>(theme);
    1207     link.Flush();
    1208 }
    1209 
    1210 
    12111191namespace BPrivate {
    12121192
    12131193
    1214 /*! \brief queries the server for the number of available decorators
    1215     \return the number of available decorators
     1194/*! \brief queries the server for the current decorator
     1195    \param ref entry_ref into which to store current decorator's location
     1196    \return boolean true/false
    12161197*/
    1217 int32
    1218 count_decorators(void)
     1198bool
     1199get_decorator(BString * path)
    12191200{
     1201    if ( ! path )
     1202        return false;
     1203
    12201204    BPrivate::AppServerLink link;
    1221     link.StartMessage(AS_COUNT_DECORATORS);
     1205    link.StartMessage(AS_GET_DECORATOR);
    12221206
    12231207    int32 code;
    1224     int32 count = -1;
    1225     if (link.FlushWithReply(code) == B_OK && code == B_OK)
    1226         link.Read<int32>(&count);
    1227 
    1228     return count;
     1208    if (link.FlushWithReply(code) != B_OK || code != B_OK)
     1209        return false;
     1210
     1211    return ( link.ReadString(*path) == B_OK );
    12291212}
    12301213
    12311214
    1232 /*! \brief queries the server for the index of the current decorators
    1233     \return the current decorator's index
     1215/*! \brief Private function which sets the window decorator for the system.
     1216    \param entry_ref to the decorator to set
    12341217
    1235     If for some bizarre reason this function fails, it returns -1
     1218    Will return detailed error status via status_t
    12361219*/
    1237 int32
    1238 get_decorator(void)
    1239 {
    1240     BPrivate::AppServerLink link;
    1241     link.StartMessage(AS_GET_DECORATOR);
    1242 
    1243     int32 code;
    1244     int32 index = -1;
    1245     if (link.FlushWithReply(code) == B_OK && code == B_OK)
    1246         link.Read<int32>(&index);
    1247 
    1248     return index;
    1249 }
    1250 
    1251 
    1252 /*! \brief queries the server for the name of the decorator with a certain index
    1253     \param index The index of the decorator to get the name for
    1254     \param name BString to receive the name of the decorator
    1255     \return B_OK if successful, B_ERROR if not
    1256 */
    12571220status_t
    1258 get_decorator_name(const int32 &index, BString &name)
     1221set_decorator(BString path)
    12591222{
    12601223    BPrivate::AppServerLink link;
    1261     link.StartMessage(AS_GET_DECORATOR_NAME);
    1262     link.Attach<int32>(index);
    12631224
    1264     int32 code;
    1265     if (link.FlushWithReply(code) == B_OK && code == B_OK) {
    1266         char *string;
    1267         if (link.ReadString(&string) == B_OK) {
    1268             name = string;
    1269             free(string);
    1270             return B_OK;
    1271         }
    1272     }
    1273 
    1274     return B_ERROR;
     1225    link.StartMessage(AS_SET_DECORATOR);
     1226
     1227    link.AttachString(path.String());
     1228    link.Flush();
     1229
     1230    status_t error = B_OK;
     1231    link.Read<status_t>(&error);
     1232
     1233    return error;
    12751234}
    12761235
    1277 
    1278 /*! \brief asks the server to draw a decorator preview into a BBitmap
    1279     \param index The index of the decorator to get the name for
    1280     \param bitmap BBitmap to receive the preview
    1281     \return B_OK if successful, B_ERROR if not.
    1282 
    1283     This is currently unimplemented.
     1236/*! \brief sets a window to preview a given decorator
     1237    \param path path to any given decorator add-on
     1238    \param window pointer to BWindow which will show decorator
     1239
     1240    Piggy-backs on BWindow::SetDecoratorSettings(...)
    12841241*/
    12851242status_t
    1286 get_decorator_preview(const int32 &index, BBitmap *bitmap)
     1243preview_decorator(BString path, BWindow * window)
    12871244{
    1288     // TODO: implement get_decorator_preview
    1289     return B_ERROR;
     1245    if (window == NULL)
     1246        return B_ERROR;
     1247
     1248    BMessage msg('prVu');
     1249    msg.AddString("preview", path.String());
     1250
     1251    return window->SetDecoratorSettings(msg);
    12901252}
    12911253
    12921254
    1293 /*! \brief Private function which sets the window decorator for the system.
    1294     \param index Index of the decorator to set
    1295 
    1296     If the index is invalid, this function and the server do nothing
    1297 */
    12981255status_t
    1299 set_decorator(const int32 &index)
    1300 {
    1301     if (index < 0)
    1302         return B_BAD_VALUE;
    1303 
    1304     BPrivate::AppServerLink link;
    1305 
    1306     link.StartMessage(AS_SET_DECORATOR);
    1307     link.Attach<int32>(index);
    1308     link.Flush();
    1309 
    1310     return B_OK;
    1311 }
    1312 
    1313 
    1314 status_t
    13151256get_application_order(int32 workspace, team_id** _applications,
    13161257    int32* _count)
    13171258{
  • src/kits/interface/Jamfile

     
    4949    ColorTools.cpp
    5050    Control.cpp
    5151    ControlLook.cpp
     52    DecorInfo.cpp
    5253    Deskbar.cpp
    5354    Dragger.cpp
    5455    Font.cpp
  • headers/private/interface/DecorInfo.h

     
     1/*
     2 * Public domain source code.
     3 *
     4 * Author:
     5 *      Joseph "looncraz" Groover <looncraz@satx.rr.com>
     6 */
     7
     8
     9#ifndef DECOR_INFO_H
     10#define DECOR_INFO_H
     11
     12
     13#include <Entry.h>
     14#include <Bitmap.h>
     15#include <String.h>
     16#include <Locker.h>
     17#include <ObjectList.h>
     18
     19
     20class DecorInfo {
     21    public: // DecorInfo is not thread-safe
     22                        DecorInfo();
     23                        DecorInfo(BString path);
     24                        DecorInfo(const entry_ref& ref);
     25                        ~DecorInfo();
     26
     27            status_t    SetTo(const entry_ref& ref);
     28            status_t    SetTo(BString path);
     29            status_t    InitCheck() const;
     30            void        Unset();
     31
     32            bool        IsDefault() const;
     33
     34            BString     Path()  const;
     35                    // "Default" is a possible result
     36
     37        const entry_ref*    Ref() const;
     38            // returns NULL if virtual ( default ) or InitCheck() != B_OK
     39            // the ref returned may NOT be the same as the one given to SetTo
     40            // or the constructor - we may have traversed a Symlink!
     41
     42            BString     Name() const;
     43            BString     ShortcutName() const;
     44
     45            BString     Authors() const;
     46            BString     ShortDescription() const;
     47            BString     LongDescription() const;
     48            BString     LicenseURL() const;
     49            BString     LicenseName() const;
     50            BString     SupportURL() const;
     51
     52            float       Version() const;
     53            time_t      ModificationTime() const;
     54
     55            bool        CheckForChanges(bool &deleted);
     56    private:
     57            void        _Init(bool is_update = false);
     58            entry_ref   fRef;
     59
     60            BString     fPath,
     61                        fName,
     62                        fAuthors,
     63                        fShortDescription,
     64                        fLongDescription,
     65                        fLicenseURL,
     66                        fLicenseName,
     67                        fSupportURL;
     68
     69            float       fVersion;
     70
     71            time_t      fModificationTime;
     72
     73            status_t    fInitStatus;
     74};
     75
     76
     77class DecorInfoUtility{
     78    public:
     79                        DecorInfoUtility(bool scan_now = true);
     80                                    // scan now or as neeeded?
     81
     82                        ~DecorInfoUtility();
     83
     84            status_t    ScanDecorators();
     85                // can also be used to rescan for changes.
     86                // warning: potentially destructive as we will remove
     87                // all DecorInfo objects which no longer have a file
     88                // system cousin.
     89                // TODO: would a call-back mechanism worthwhile here?
     90
     91            int32       CountDecorators();
     92
     93            DecorInfo*  DecoratorAt(int32);
     94
     95            DecorInfo*  FindDecorator(BString);
     96                // checks for ref.name, path, fName, and "Default,"
     97                // an empty-string returns the current decorator
     98                // NULL on match failure
     99
     100            DecorInfo*  CurrentDecorator();
     101            DecorInfo*  DefaultDecorator();
     102
     103            bool        IsCurrentDecorator(DecorInfo*);
     104
     105            status_t    SetDecorator(DecorInfo*);
     106            status_t    SetDecorator(int32);
     107
     108            status_t    Preview(DecorInfo* decor, BWindow* window);
     109
     110    private:
     111            DecorInfo*  _find_decor(BString path);
     112
     113            BObjectList<DecorInfo>  fList;
     114            BLocker                 fLock;
     115            bool                    fHasScanned;
     116
     117};
     118
     119
     120#endif