89a59a6bb846c9e21cc736f1bc9c8a220a7679cb
[pcsx_rearmed.git] / frontend / plat_omap.c
1 /*
2  * (C) GraÅžvydas "notaz" Ignotas, 2010-2012
3  *
4  * This work is licensed under the terms of the GNU GPLv2 or later.
5  * See the COPYING file in the top-level directory.
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <sys/ioctl.h>
14 #include <unistd.h>
15 #include <linux/omapfb.h>
16
17 #include "common/menu.h"
18 #include "common/input.h"
19 #include "linux/fbdev.h"
20 #include "linux/xenv.h"
21 #include "plugin_lib.h"
22 #include "pl_gun_ts.h"
23 #include "plat.h"
24 #include "plat_omap.h"
25 #include "menu.h"
26
27 static struct vout_fbdev *main_fb, *layer_fb;
28
29 static int omap_setup_layer_(int fd, int enabled, int x, int y, int w, int h)
30 {
31         struct omapfb_plane_info pi = { 0, };
32         struct omapfb_mem_info mi = { 0, };
33         int ret;
34
35         ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi);
36         if (ret != 0) {
37                 perror("QUERY_PLANE");
38                 return -1;
39         }
40
41         ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi);
42         if (ret != 0) {
43                 perror("QUERY_MEM");
44                 return -1;
45         }
46
47         /* must disable when changing stuff */
48         if (pi.enabled) {
49                 pi.enabled = 0;
50                 ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
51                 if (ret != 0)
52                         perror("SETUP_PLANE");
53         }
54
55         if (mi.size < 640*512*3*3) {
56                 mi.size = 640*512*3*3;
57                 ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi);
58                 if (ret != 0) {
59                         perror("SETUP_MEM");
60                         return -1;
61                 }
62         }
63
64         pi.pos_x = x;
65         pi.pos_y = y;
66         pi.out_width = w;
67         pi.out_height = h;
68         pi.enabled = enabled;
69
70         ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
71         if (ret != 0) {
72                 perror("SETUP_PLANE");
73                 return -1;
74         }
75
76         return 0;
77 }
78
79 static int omap_enable_layer(int enabled)
80 {
81         if (enabled)
82                 pl_set_gun_rect(g_layer_x, g_layer_y, g_layer_w, g_layer_h);
83
84         return omap_setup_layer_(vout_fbdev_get_fd(layer_fb), enabled,
85                 g_layer_x, g_layer_y, g_layer_w, g_layer_h);
86 }
87
88 void plat_omap_gvideo_open(void)
89 {
90         omap_enable_layer(1);
91
92         // try to align redraws to vsync
93         vout_fbdev_wait_vsync(layer_fb);
94 }
95
96 void *plat_gvideo_set_mode(int *w, int *h, int *bpp)
97 {
98         void *buf;
99
100         vout_fbdev_clear(layer_fb);
101         buf = vout_fbdev_resize(layer_fb, *w, *h, *bpp, 0, 0, 0, 0, 3);
102
103         omap_enable_layer(1);
104
105         return buf;
106 }
107
108 void *plat_gvideo_flip(void)
109 {
110         return vout_fbdev_flip(layer_fb);
111 }
112
113 void plat_gvideo_close(void)
114 {
115         omap_enable_layer(0);
116 }
117
118 void plat_video_menu_enter(int is_rom_loaded)
119 {
120         g_menuscreen_ptr = vout_fbdev_resize(main_fb,
121                 g_menuscreen_w, g_menuscreen_h, 16, 0, 0, 0, 0, 3);
122         if (g_menuscreen_ptr == NULL)
123                 fprintf(stderr, "warning: vout_fbdev_resize failed\n");
124
125         xenv_update(NULL, NULL, NULL, NULL);
126 }
127
128 void plat_video_menu_begin(void)
129 {
130 }
131
132 void plat_video_menu_end(void)
133 {
134         g_menuscreen_ptr = vout_fbdev_flip(main_fb);
135 }
136
137 void plat_video_menu_leave(void)
138 {
139         /* have to get rid of panning so that plugins that
140          * use fb0 and don't ever pan can work. */
141         vout_fbdev_clear(main_fb);
142         g_menuscreen_ptr = vout_fbdev_resize(main_fb,
143                 g_menuscreen_w, g_menuscreen_h, 16, 0, 0, 0, 0, 1);
144         if (g_menuscreen_ptr == NULL)
145                 fprintf(stderr, "warning: vout_fbdev_resize failed\n");
146 }
147
148 void plat_minimize(void)
149 {
150         omap_enable_layer(0);
151         xenv_minimize();
152         in_set_config_int(0, IN_CFG_BLOCKING, 0); /* flush event queue */
153         omap_enable_layer(1);
154 }
155
156 void *plat_prepare_screenshot(int *w, int *h, int *bpp)
157 {
158         return NULL;
159 }
160
161 void plat_omap_init(void)
162 {
163         const char *main_fb_name, *layer_fb_name;
164         int fd, ret, w, h;
165
166         main_fb_name = getenv("FBDEV_MAIN");
167         if (main_fb_name == NULL)
168                 main_fb_name = "/dev/fb0";
169
170         layer_fb_name = getenv("FBDEV_LAYER");
171         if (layer_fb_name == NULL)
172                 layer_fb_name = "/dev/fb1";
173
174         // must set the layer up first to be able to use it
175         fd = open(layer_fb_name, O_RDWR);
176         if (fd == -1) {
177                 fprintf(stderr, "%s: ", layer_fb_name);
178                 perror("open");
179                 exit(1);
180         }
181
182         g_layer_x = 80, g_layer_y = 0;
183         g_layer_w = 640, g_layer_h = 480;
184
185         ret = omap_setup_layer_(fd, 0, g_layer_x, g_layer_y, g_layer_w, g_layer_h);
186         close(fd);
187         if (ret != 0) {
188                 fprintf(stderr, "failed to set up layer, exiting.\n");
189                 exit(1);
190         }
191
192         xenv_init(NULL, "PCSX-ReARMed");
193
194         w = h = 0;
195         main_fb = vout_fbdev_init(main_fb_name, &w, &h, 16, 2);
196         if (main_fb == NULL) {
197                 fprintf(stderr, "couldn't init fb: %s\n", main_fb_name);
198                 exit(1);
199         }
200
201         g_menuscreen_w = w;
202         g_menuscreen_h = h;
203         g_menuscreen_ptr = vout_fbdev_flip(main_fb);
204         pl_rearmed_cbs.screen_w = w;
205         pl_rearmed_cbs.screen_h = h;
206
207         w = 640;
208         h = 512;
209         layer_fb = vout_fbdev_init(layer_fb_name, &w, &h, 16, 3);
210         if (layer_fb == NULL) {
211                 fprintf(stderr, "couldn't init fb: %s\n", layer_fb_name);
212                 goto fail0;
213         }
214
215         return;
216
217 fail0:
218         vout_fbdev_finish(main_fb);
219         exit(1);
220 }
221
222 void plat_omap_finish(void)
223 {
224         omap_enable_layer(0);
225         vout_fbdev_finish(layer_fb);
226         vout_fbdev_finish(main_fb);
227         xenv_finish();
228 }
229