1 /*
2    (c) Copyright 2001-2009  The world wide DirectFB Open Source Community (directfb.org)
3    (c) Copyright 2000-2004  Convergence (integrated media) GmbH
4 
5    All rights reserved.
6 
7    Written by Denis Oliver Kropp <dok@directfb.org>,
8               Andreas Hundt <andi@fischlustig.de>,
9               Sven Neumann <neo@directfb.org>,
10               Ville Syrjälä <syrjala@sci.fi> and
11               Claudio Ciccani <klan@users.sf.net>.
12 
13    This library is free software; you can redistribute it and/or
14    modify it under the terms of the GNU Lesser General Public
15    License as published by the Free Software Foundation; either
16    version 2 of the License, or (at your option) any later version.
17 
18    This library is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    Lesser General Public License for more details.
22 
23    You should have received a copy of the GNU Lesser General Public
24    License along with this library; if not, write to the
25    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26    Boston, MA 02111-1307, USA.
27 */
28 
29 #include <config.h>
30 
31 #include <string.h>
32 #include <stdio.h>
33 
34 #include <directfb.h>
35 
36 #include <core/layers.h>
37 
38 #include <misc/conf.h>
39 
40 #include "unichrome.h"
41 #include "uc_overlay.h"
42 #include "vidregs.h"
43 #include "mmio.h"
44 
45 /* primary layer hooks */
46 
47 #define OSD_OPTIONS      (DLOP_ALPHACHANNEL | DLOP_SRC_COLORKEY | DLOP_OPACITY)
48 
49 DisplayLayerFuncs  ucOldPrimaryFuncs;
50 void              *ucOldPrimaryDriverData;
51 
52 static DFBResult
osdInitLayer(CoreLayer * layer,void * driver_data,void * layer_data,DFBDisplayLayerDescription * description,DFBDisplayLayerConfig * config,DFBColorAdjustment * adjustment)53 osdInitLayer( CoreLayer                  *layer,
54               void                       *driver_data,
55               void                       *layer_data,
56               DFBDisplayLayerDescription *description,
57               DFBDisplayLayerConfig      *config,
58               DFBColorAdjustment         *adjustment )
59 {
60      DFBResult ret;
61 
62      /* call the original initialization function first */
63      ret = ucOldPrimaryFuncs.InitLayer( layer,
64                                         ucOldPrimaryDriverData,
65                                         layer_data, description,
66                                         config, adjustment );
67      if (ret)
68           return ret;
69 
70      /* set name */
71      snprintf(description->name,
72               DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "VIA CLE266 Graphics");
73 
74      /* add support for options */
75      config->flags |= DLCONF_OPTIONS;
76 
77      config->pixelformat = dfb_config->mode.format ?
78                            dfb_config->mode.format : DSPF_ARGB;
79      config->options = DLOP_ALPHACHANNEL;
80 
81      /* add some capabilities */
82      description->caps |= DLCAPS_ALPHACHANNEL |
83                           DLCAPS_OPACITY | DLCAPS_SRC_COLORKEY;
84 
85      return DFB_OK;
86 }
87 
88 static DFBResult
osdTestRegion(CoreLayer * layer,void * driver_data,void * layer_data,CoreLayerRegionConfig * config,CoreLayerRegionConfigFlags * failed)89 osdTestRegion( CoreLayer                  *layer,
90                void                       *driver_data,
91                void                       *layer_data,
92                CoreLayerRegionConfig      *config,
93                CoreLayerRegionConfigFlags *failed )
94 {
95      DFBResult                  ret;
96      CoreLayerRegionConfigFlags fail = 0;
97      DFBDisplayLayerOptions     options = config->options;
98 
99      /* remove options before calling the original function */
100      config->options = DLOP_NONE;
101 
102      /* call the original function */
103      ret = ucOldPrimaryFuncs.TestRegion( layer, ucOldPrimaryDriverData,
104                                          layer_data, config, &fail );
105 
106      /* check options if specified */
107      if (options) {
108           /* any unsupported option wanted? */
109           if (options & ~OSD_OPTIONS)
110                fail |= CLRCF_OPTIONS;
111 
112           /* opacity and alpha channel cannot be used at once */
113           if ((options & (DLOP_OPACITY | DLOP_ALPHACHANNEL)) ==
114               (DLOP_OPACITY | DLOP_ALPHACHANNEL))
115           {
116                fail |= CLRCF_OPTIONS;
117           }
118      }
119 
120      /* restore options */
121      config->options = options;
122 
123      if (failed)
124           *failed = fail;
125 
126      if (fail)
127           return DFB_UNSUPPORTED;
128 
129      return ret;
130 }
131 
132 static DFBResult
osdSetRegion(CoreLayer * layer,void * driver_data,void * layer_data,void * region_data,CoreLayerRegionConfig * config,CoreLayerRegionConfigFlags updated,CoreSurface * surface,CorePalette * palette,CoreSurfaceBufferLock * lock)133 osdSetRegion( CoreLayer                  *layer,
134               void                       *driver_data,
135               void                       *layer_data,
136               void                       *region_data,
137               CoreLayerRegionConfig      *config,
138               CoreLayerRegionConfigFlags  updated,
139               CoreSurface                *surface,
140               CorePalette                *palette,
141               CoreSurfaceBufferLock      *lock )
142 {
143      DFBResult     ret;
144      UcDriverData *ucdrv = (UcDriverData*) driver_data;
145 
146      /* call the original function */
147      ret = ucOldPrimaryFuncs.SetRegion( layer, ucOldPrimaryDriverData,
148                                         layer_data, region_data,
149                                         config, updated, surface,
150                                         palette, lock );
151      if (ret)
152           return ret;
153 
154      uc_ovl_vcmd_wait(ucdrv->hwregs);
155 
156      /* select pixel based or global alpha */
157 
158      if (config->options & DLOP_ALPHACHANNEL)
159           VIDEO_OUT(ucdrv->hwregs, V_ALPHA_CONTROL, uc_ovl_map_alpha(-1));
160      else if (config->options & DLOP_OPACITY)
161           VIDEO_OUT(ucdrv->hwregs, V_ALPHA_CONTROL, uc_ovl_map_alpha(config->opacity));
162      else
163           VIDEO_OUT(ucdrv->hwregs, V_ALPHA_CONTROL, uc_ovl_map_alpha(0xff));
164 
165      VIDEO_OUT(ucdrv->hwregs, V_COMPOSE_MODE, V1_COMMAND_FIRE);
166 
167      return DFB_OK;
168 }
169 
170 DisplayLayerFuncs ucPrimaryFuncs = {
171      .InitLayer  = osdInitLayer,
172 
173      .TestRegion = osdTestRegion,
174      .SetRegion  = osdSetRegion,
175 };
176 
177