1 /*	Public domain	*/
2 
3 /*
4  * Single-window graphics driver framework. In this mode, the driver
5  * creates a single "native" display context and Agar emulates a window
6  * manager internally.
7  */
8 
9 typedef struct ag_driver_sw_class {
10 	struct ag_driver_class _inherit;
11 	Uint flags;
12 	/* Create or attach to a graphics display */
13 	int  (*openVideo)(void *drv, Uint w, Uint h, int depth, Uint flags);
14 	int  (*openVideoContext)(void *drv, void *ctx, Uint flags);
15 	int  (*setVideoContext)(void *drv, void *ctx);
16 	void (*closeVideo)(void *drv);
17 	/* Resize the display */
18 	int  (*videoResize)(void *drv, Uint w, Uint h);
19 	/* Capture display contents to surface */
20 	int  (*videoCapture)(void *drv, AG_Surface **);
21 	/* Clear background */
22 	void (*videoClear)(void *drv, AG_Color c);
23 } AG_DriverSwClass;
24 
25 struct ag_style;
26 
27 /* General window alignment in view */
28 enum ag_window_alignment {
29 	AG_WINDOW_ALIGNMENT_NONE,
30 	AG_WINDOW_TL,
31 	AG_WINDOW_TC,
32 	AG_WINDOW_TR,
33 	AG_WINDOW_ML,
34 	AG_WINDOW_MC,
35 	AG_WINDOW_MR,
36 	AG_WINDOW_BL,
37 	AG_WINDOW_BC,
38 	AG_WINDOW_BR,
39 	AG_WINDOW_ALIGNMENT_LAST
40 };
41 
42 /* Window manager operation */
43 enum ag_wm_operation {
44 	AG_WINOP_NONE,		/* No operation */
45 	AG_WINOP_MOVE,		/* Move window */
46 	AG_WINOP_LRESIZE,	/* Resize (via left control) */
47 	AG_WINOP_RRESIZE,	/* Resize (via right control) */
48 	AG_WINOP_HRESIZE	/* Resize (via horizontal control) */
49 };
50 
51 /* Single-window driver instance */
52 typedef struct ag_driver_sw {
53 	struct ag_driver _inherit;
54 	Uint w, h, depth;		/* Video resolution */
55 	Uint flags;
56 #define AG_DRIVER_SW_OVERLAY	0x01	/* "Overlay" mode */
57 #define AG_DRIVER_SW_BGPOPUP	0x02	/* Enable generic background popup */
58 #define AG_DRIVER_SW_FULLSCREEN	0x04	/* Currently in full-screen mode */
59 #define AG_DRIVER_SW_REDRAW	0x08	/* Global redraw request */
60 
61 	struct ag_window *winSelected;	/* Window being moved/resized/etc */
62 	struct ag_window *winLastKeydown; /* For keyboard processing */
63 	AG_List *Lmodal;		/* Modal window stack */
64 	enum ag_wm_operation winop;	/* WM operation in progress */
65 	struct ag_style *theme;		/* Default style for new windows */
66 	int windowXOutLimit;		/* Limit past left/right boundary */
67 	int windowBotOutLimit;		/* Limit past bottom boundary */
68 	int windowIconWidth;		/* Preferred window icon dimensions */
69 	int windowIconHeight;
70 	Uint rNom;			/* Nominal refresh rate (ms) */
71 	int rCur;			/* Effective refresh rate (ms) */
72 	AG_Color bgColor;		/* "bgColor" setting */
73 	Uint rLast;			/* Refresh rate timestamp */
74 } AG_DriverSw;
75 
76 #define AGDRIVER_SW(obj) ((AG_DriverSw *)(obj))
77 #define AGDRIVER_SW_CLASS(obj) ((struct ag_driver_sw_class *)(AGOBJECT(obj)->cls))
78 
79 __BEGIN_DECLS
80 extern AG_ObjectClass    agDriverSwClass;
81 extern AG_DriverSw      *agDriverSw;		/* Root driver instance */
82 
83 struct ag_size_alloc;
84 
85 void AG_WM_BackgroundPopupMenu(AG_DriverSw *);
86 void AG_WM_CommitWindowFocus(struct ag_window *);
87 
88 int  AG_ResizeDisplay(int, int);
89 void AG_PostResizeDisplay(AG_DriverSw *);
90 void AG_SetVideoResizeCallback(void (*)(Uint, Uint));
91 
92 void AG_WM_LimitWindowToView(struct ag_window *);
93 void AG_WM_LimitWindowToDisplaySize(AG_Driver *, struct ag_size_alloc *);
94 void AG_WM_GetPrefPosition(struct ag_window *, int *, int *, int, int);
95 
96 void AG_WM_MoveBegin(struct ag_window *);
97 void AG_WM_MoveEnd(struct ag_window *);
98 void AG_WM_MouseMotion(AG_DriverSw *, struct ag_window *, int, int);
99 
100 /* Blank the display background. */
101 static __inline__ void
AG_ClearBackground(void)102 AG_ClearBackground(void)
103 {
104 	if (agDriverSw != NULL) {
105 		AG_Color c = { 0,0,0,0 };
106 		AGDRIVER_SW_CLASS(agDriverSw)->videoClear(agDriverSw, c);
107 	}
108 }
109 
110 /* Configure the display refresh rate (driver-dependent). */
111 static __inline__ int
AG_SetRefreshRate(int fps)112 AG_SetRefreshRate(int fps)
113 {
114 	if (agDriverOps->setRefreshRate == NULL) {
115 		AG_SetError("Refresh rate not applicable to graphics driver");
116 		return (-1);
117 	}
118 	return agDriverOps->setRefreshRate(agDriverSw, fps);
119 }
120 
121 /* Evaluate whether there are pending events to be processed. */
122 static __inline__ int
AG_PendingEvents(AG_Driver * drv)123 AG_PendingEvents(AG_Driver *drv)
124 {
125 	if (drv != NULL) {
126 		return AGDRIVER_CLASS(drv)->pendingEvents(drv);
127 	} else {
128 		return agDriverOps->pendingEvents(agDriverSw);
129 	}
130 }
131 
132 /* Retrieve the next pending event, translated to generic AG_DriverEvent form. */
133 static __inline__ int
AG_GetNextEvent(AG_Driver * drv,AG_DriverEvent * dev)134 AG_GetNextEvent(AG_Driver *drv, AG_DriverEvent *dev)
135 {
136 	if (drv != NULL) {
137 		return AGDRIVER_CLASS(drv)->getNextEvent(drv, dev);
138 	} else {
139 		return agDriverOps->getNextEvent(agDriverSw, dev);
140 	}
141 }
142 
143 /* Process the next pending event in generic manner. */
144 static __inline__ int
AG_ProcessEvent(AG_Driver * drv,AG_DriverEvent * dev)145 AG_ProcessEvent(AG_Driver *drv, AG_DriverEvent *dev)
146 {
147 	if (drv != NULL) {
148 		return AGDRIVER_CLASS(drv)->processEvent(drv, dev);
149 	} else {
150 		return agDriverOps->processEvent(agDriverSw, dev);
151 	}
152 }
153 
154 #ifdef AG_LEGACY
155 /* Update a video region (FB drivers only). */
156 static __inline__ void
AG_ViewUpdateFB(const AG_Rect2 * r2)157 AG_ViewUpdateFB(const AG_Rect2 *r2)
158 {
159 	AG_Rect r;
160 	r.x = r2->x1;
161 	r.y = r2->y1;
162 	r.w = r2->w;
163 	r.h = r2->h;
164 	if (agDriverOps->updateRegion != NULL)
165 		agDriverOps->updateRegion(agDriverSw, r);
166 }
167 #endif /* AG_LEGACY */
168 __END_DECLS
169