Mercurial > mplayer.hg
annotate gui/ui/actions.c @ 33671:a460339acfdf
Fix volume and balance bug.
Changing the volume changed the balance as well,
because the calculation for the balance was wrong.
Additionally, use macro FFMAX() and replace
identical code by a call to existing code.
author | ib |
---|---|
date | Tue, 28 Jun 2011 17:52:30 +0000 |
parents | cbb7cfeb8c71 |
children | 45553d0f65c6 |
rev | line source |
---|---|
26458 | 1 /* |
2 * This file is part of MPlayer. | |
3 * | |
4 * MPlayer is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; either version 2 of the License, or | |
7 * (at your option) any later version. | |
8 * | |
9 * MPlayer is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License along | |
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
17 */ | |
23077 | 18 |
19 #include <stdlib.h> | |
20 #include <string.h> | |
21 | |
33556 | 22 #include "actions.h" |
32881 | 23 #include "gmplayer.h" |
24 #include "gui/app.h" | |
25 #include "gui/interface.h" | |
26 #include "gui/skin/font.h" | |
27 #include "gui/skin/skin.h" | |
28 #include "gui/wm/wsxdnd.h" | |
29 #include "widgets.h" | |
23077 | 30 |
26382
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
26365
diff
changeset
|
31 #include "config.h" |
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
26365
diff
changeset
|
32 #include "help_mp.h" |
32881 | 33 #include "input/input.h" |
30653
3d23e24c5c60
Declare externally used variables from vd.c as extern in vd.h.
diego
parents:
29263
diff
changeset
|
34 #include "libmpcodecs/vd.h" |
26382
b2f4abcf20ed
Make include paths consistent; do not use ../ in them.
diego
parents:
26365
diff
changeset
|
35 #include "libvo/video_out.h" |
32881 | 36 #include "mp_core.h" |
23077 | 37 #include "stream/stream.h" |
38 | |
33555 | 39 int uiGotoTheNext = 1; |
23077 | 40 |
33555 | 41 void uiFullScreen(void) |
23077 | 42 { |
33655 | 43 if (!guiInfo.MovieWindow && guiInfo.Playing) |
32881 | 44 return; |
45 | |
33555 | 46 if (guiInfo.Playing && guiApp.subWindow.isFullScreen) { |
47 guiApp.subWindow.OldWidth = guiInfo.MovieWidth; | |
48 guiApp.subWindow.OldHeight = guiInfo.MovieHeight; | |
32881 | 49 |
33555 | 50 switch (guiApp.sub.x) { |
32881 | 51 case -1: |
33555 | 52 guiApp.subWindow.OldX = wsMaxX / 2 - guiApp.subWindow.OldWidth / 2 + wsOrgX; |
32881 | 53 break; |
54 | |
55 case -2: | |
33555 | 56 guiApp.subWindow.OldX = wsMaxX - guiApp.subWindow.OldWidth + wsOrgX; |
32881 | 57 break; |
58 | |
59 default: | |
33555 | 60 guiApp.subWindow.OldX = guiApp.sub.x; |
32881 | 61 break; |
62 } | |
23077 | 63 |
33555 | 64 switch (guiApp.sub.y) { |
32881 | 65 case -1: |
33555 | 66 guiApp.subWindow.OldY = wsMaxY / 2 - guiApp.subWindow.OldHeight / 2 + wsOrgY; |
32881 | 67 break; |
68 | |
69 case -2: | |
33555 | 70 guiApp.subWindow.OldY = wsMaxY - guiApp.subWindow.OldHeight + wsOrgY; |
32881 | 71 break; |
23077 | 72 |
32881 | 73 default: |
33555 | 74 guiApp.subWindow.OldY = guiApp.sub.y; |
32881 | 75 break; |
76 } | |
77 } | |
78 | |
33555 | 79 if (guiInfo.Playing || gtkShowVideoWindow) |
80 wsFullScreen(&guiApp.subWindow); | |
32881 | 81 |
33555 | 82 fullscreen = vo_fs = guiApp.subWindow.isFullScreen; |
83 wsSetLayer(wsDisplay, guiApp.mainWindow.WindowID, guiApp.subWindow.isFullScreen); | |
32881 | 84 |
33555 | 85 if (guiApp.menuIsPresent) |
86 wsSetLayer(wsDisplay, guiApp.menuWindow.WindowID, guiApp.subWindow.isFullScreen); | |
32881 | 87 |
33555 | 88 if (guiInfo.Playing) |
89 wsSetBackgroundRGB(&guiApp.subWindow, 0, 0, 0); | |
32881 | 90 else |
33555 | 91 wsSetBackgroundRGB(&guiApp.subWindow, guiApp.sub.R, guiApp.sub.G, guiApp.sub.B); |
23077 | 92 } |
93 | |
33555 | 94 void uiEnd(void) |
23077 | 95 { |
32881 | 96 plItem *next; |
23077 | 97 |
33555 | 98 if (!uiGotoTheNext && guiInfo.Playing) { |
99 uiGotoTheNext = 1; | |
32881 | 100 return; |
101 } | |
23077 | 102 |
33555 | 103 if (guiInfo.Playing && (next = gtkSet(gtkGetNextPlItem, 0, NULL)) && (plLastPlayed != next)) { |
32881 | 104 plLastPlayed = next; |
33555 | 105 guiSetDF(guiInfo.Filename, next->path, next->name); |
106 guiInfo.StreamType = STREAMTYPE_FILE; | |
107 guiInfo.FilenameChanged = guiInfo.NewPlay = 1; | |
108 gfree((void **)&guiInfo.AudioFile); | |
109 gfree((void **)&guiInfo.Subtitlename); | |
32881 | 110 } else { |
33555 | 111 if (guiInfo.FilenameChanged || guiInfo.NewPlay) |
32881 | 112 return; |
23077 | 113 |
33647 | 114 guiInfo.TimeSec = 0; |
115 guiInfo.Position = 0; | |
33646 | 116 guiInfo.AudioChannels = 0; |
33655 | 117 guiInfo.MovieWindow = True; |
23077 | 118 |
27341
e7c989f7a7c9
Start unifying names of internal preprocessor directives.
diego
parents:
26458
diff
changeset
|
119 #ifdef CONFIG_DVDREAD |
33555 | 120 guiInfo.DVD.current_title = 1; |
121 guiInfo.DVD.current_chapter = 1; | |
122 guiInfo.DVD.current_angle = 1; | |
23077 | 123 #endif |
124 | |
33555 | 125 if (!guiApp.subWindow.isFullScreen && gtkShowVideoWindow) { |
126 wsResizeWindow(&guiApp.subWindow, guiApp.sub.width, guiApp.sub.height); | |
127 wsMoveWindow(&guiApp.subWindow, True, guiApp.sub.x, guiApp.sub.y); | |
32881 | 128 } else |
33555 | 129 wsVisibleWindow(&guiApp.subWindow, wsHideWindow); |
32881 | 130 |
33614 | 131 guiGetEvent(guiSetState, (void *)GUI_STOP); |
33555 | 132 uiSubRender = 1; |
133 wsSetBackgroundRGB(&guiApp.subWindow, guiApp.sub.R, guiApp.sub.G, guiApp.sub.B); | |
134 wsClearWindow(guiApp.subWindow); | |
135 wsPostRedisplay(&guiApp.subWindow); | |
23077 | 136 } |
137 } | |
138 | |
33555 | 139 void uiPlay(void) |
23077 | 140 { |
33555 | 141 if (!guiInfo.Filename || |
142 (guiInfo.Filename[0] == 0) || | |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33614
diff
changeset
|
143 (guiInfo.Playing == GUI_PLAY)) |
32881 | 144 return; |
23077 | 145 |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33614
diff
changeset
|
146 if (guiInfo.Playing == GUI_PAUSE) { |
33555 | 147 uiPause(); |
32881 | 148 return; |
149 } | |
150 | |
33614 | 151 guiGetEvent(guiSetState, (void *)GUI_PLAY); |
33555 | 152 uiSubRender = 0; |
153 wsSetBackgroundRGB(&guiApp.subWindow, 0, 0, 0); | |
154 wsClearWindow(guiApp.subWindow); | |
23077 | 155 } |
156 | |
33555 | 157 void uiPause(void) |
23077 | 158 { |
33555 | 159 if (!guiInfo.Playing) |
32881 | 160 return; |
161 | |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33614
diff
changeset
|
162 if (guiInfo.Playing == GUI_PLAY) { |
32881 | 163 mp_cmd_t *cmd = calloc(1, sizeof(*cmd)); |
164 cmd->id = MP_CMD_PAUSE; | |
165 cmd->name = strdup("pause"); | |
166 mp_input_queue_cmd(cmd); | |
167 } else | |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33614
diff
changeset
|
168 guiInfo.Playing = GUI_PLAY; |
23077 | 169 } |
170 | |
33555 | 171 void uiState(void) |
32881 | 172 { |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33614
diff
changeset
|
173 if (guiInfo.Playing == GUI_STOP || guiInfo.Playing == GUI_PAUSE) { |
32881 | 174 btnModify(evPlaySwitchToPause, btnReleased); |
175 btnModify(evPauseSwitchToPlay, btnDisabled); | |
176 } else { | |
177 btnModify(evPlaySwitchToPause, btnDisabled); | |
178 btnModify(evPauseSwitchToPlay, btnReleased); | |
179 } | |
23077 | 180 } |
181 | |
33555 | 182 void uiRelSeek(float sec) |
32881 | 183 { |
32971 | 184 rel_seek_secs = sec; |
32881 | 185 abs_seek_pos = 0; |
186 } | |
187 | |
33555 | 188 void uiAbsSeek(float percent) |
32881 | 189 { |
33555 | 190 if (guiInfo.StreamType == STREAMTYPE_STREAM) |
32881 | 191 return; |
192 | |
32971 | 193 rel_seek_secs = percent / 100.0; |
32881 | 194 abs_seek_pos = 3; |
23077 | 195 } |
196 | |
33555 | 197 void uiChangeSkin(char *name) |
23077 | 198 { |
32893 | 199 int prev, bprev; |
32881 | 200 |
33555 | 201 prev = guiApp.menuIsPresent; |
202 bprev = guiApp.playbarIsPresent; | |
32881 | 203 |
204 mainVisible = 0; | |
205 | |
32893 | 206 if (skinRead(name) != 0) { |
207 if (skinRead(skinName) != 0) { | |
32894 | 208 mainVisible = 1; |
209 return; | |
32893 | 210 } |
32881 | 211 } |
212 | |
213 // reload menu window | |
23077 | 214 |
33555 | 215 if (prev && guiApp.menuIsPresent) { |
216 free(menuDrawBuffer); | |
217 menuDrawBuffer = calloc(1, guiApp.menu.Bitmap.ImageSize); | |
32881 | 218 |
33555 | 219 if (!menuDrawBuffer) { |
33530 | 220 gmp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_NEMDB); |
221 guiExit(EXIT_ERROR); | |
32881 | 222 } |
23077 | 223 |
33555 | 224 wsResizeWindow(&guiApp.menuWindow, guiApp.menu.width, guiApp.menu.height); |
225 wsResizeImage(&guiApp.menuWindow, guiApp.menu.width, guiApp.menu.height); | |
226 wsSetShape(&guiApp.menuWindow, guiApp.menu.Mask.Image); | |
227 wsVisibleWindow(&guiApp.menuWindow, wsHideWindow); | |
32881 | 228 } else |
33555 | 229 uiMenuInit(); |
32881 | 230 |
231 // reload sub window | |
23077 | 232 |
33555 | 233 if (guiApp.sub.Bitmap.Image) |
234 wsResizeImage(&guiApp.subWindow, guiApp.sub.Bitmap.Width, guiApp.sub.Bitmap.Height); | |
32881 | 235 |
33555 | 236 if (!guiApp.subWindow.isFullScreen && !guiInfo.Playing) { |
237 wsResizeWindow(&guiApp.subWindow, guiApp.sub.width, guiApp.sub.height); | |
238 wsMoveWindow(&guiApp.subWindow, True, guiApp.sub.x, guiApp.sub.y); | |
32881 | 239 } |
240 | |
33555 | 241 if (guiApp.sub.Bitmap.Image) |
242 wsConvert(&guiApp.subWindow, guiApp.sub.Bitmap.Image); | |
23077 | 243 |
33555 | 244 if (!guiInfo.Playing) { |
245 uiSubRender = 1; | |
246 wsSetBackgroundRGB(&guiApp.subWindow, guiApp.sub.R, guiApp.sub.G, guiApp.sub.B); | |
247 wsClearWindow(guiApp.subWindow); | |
248 wsPostRedisplay(&guiApp.subWindow); | |
32881 | 249 } |
250 | |
33555 | 251 // reload playbar |
32881 | 252 |
253 if (bprev) | |
33555 | 254 wsDestroyWindow(&guiApp.playbarWindow); |
32881 | 255 |
33555 | 256 uiPlaybarInit(); |
23077 | 257 |
32881 | 258 // reload main window |
259 | |
33555 | 260 free(mainDrawBuffer); |
261 mainDrawBuffer = calloc(1, guiApp.main.Bitmap.ImageSize); | |
23077 | 262 |
33555 | 263 if (!mainDrawBuffer) { |
33530 | 264 gmp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_NEMDB); |
265 guiExit(EXIT_ERROR); | |
32881 | 266 } |
23077 | 267 |
33555 | 268 wsDestroyWindow(&guiApp.mainWindow); |
32881 | 269 |
33555 | 270 wsCreateWindow(&guiApp.mainWindow, guiApp.main.x, guiApp.main.y, guiApp.main.width, guiApp.main.height, wsNoBorder, wsShowMouseCursor | wsHandleMouseButton | wsHandleMouseMove, wsShowFrame | wsMaxSize | wsHideWindow, "MPlayer"); |
271 wsCreateImage(&guiApp.mainWindow, guiApp.main.Bitmap.Width, guiApp.main.Bitmap.Height); | |
272 wsSetShape(&guiApp.mainWindow, guiApp.main.Mask.Image); | |
273 wsSetIcon(wsDisplay, guiApp.mainWindow.WindowID, &guiIcon); | |
23077 | 274 |
33555 | 275 guiApp.mainWindow.ReDraw = (void *)uiMainDraw; |
276 guiApp.mainWindow.MouseHandler = uiMainMouseHandle; | |
277 guiApp.mainWindow.KeyHandler = uiMainKeyHandle; | |
278 guiApp.mainWindow.DandDHandler = uiDandDHandler; | |
32881 | 279 |
33555 | 280 wsXDNDMakeAwareness(&guiApp.mainWindow); |
23077 | 281 |
33555 | 282 if (!guiApp.mainDecoration) |
283 wsWindowDecoration(&guiApp.mainWindow, 0); | |
32881 | 284 |
33555 | 285 wsVisibleWindow(&guiApp.mainWindow, wsShowWindow); |
32881 | 286 mainVisible = 1; |
287 | |
33555 | 288 btnModify(evSetVolume, guiInfo.Volume); |
289 btnModify(evSetBalance, guiInfo.Balance); | |
290 btnModify(evSetMoviePosition, guiInfo.Position); | |
291 btnModify(evFullScreen, !guiApp.subWindow.isFullScreen); | |
23077 | 292 |
33555 | 293 wsSetLayer(wsDisplay, guiApp.mainWindow.WindowID, guiApp.subWindow.isFullScreen); |
294 wsSetLayer(wsDisplay, guiApp.menuWindow.WindowID, guiApp.subWindow.isFullScreen); | |
32881 | 295 } |
296 | |
33555 | 297 void uiSetFileName(char *dir, char *name, int type) |
32881 | 298 { |
299 if (!name) | |
300 return; | |
23077 | 301 |
32881 | 302 if (!dir) |
33555 | 303 guiSetFilename(guiInfo.Filename, name) |
32881 | 304 else |
33555 | 305 guiSetDF(guiInfo.Filename, dir, name) |
23077 | 306 |
33555 | 307 guiInfo.StreamType = type; |
308 gfree((void **)&guiInfo.AudioFile); | |
309 gfree((void **)&guiInfo.Subtitlename); | |
23077 | 310 } |
311 | |
33555 | 312 void uiCurr(void) |
23077 | 313 { |
32881 | 314 plItem *curr; |
315 int stop = 0; | |
23077 | 316 |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33614
diff
changeset
|
317 if (guiInfo.Playing == GUI_PAUSE) |
32881 | 318 return; |
23077 | 319 |
33555 | 320 switch (guiInfo.StreamType) { |
32881 | 321 #ifdef CONFIG_DVDREAD |
322 case STREAMTYPE_DVD: | |
323 break; | |
32953 | 324 #endif |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27370
diff
changeset
|
325 |
27370
14c5017f40d2
Change a bunch of video/audio-output-specific preprocessor directives from
diego
parents:
27341
diff
changeset
|
326 #ifdef CONFIG_VCD |
32881 | 327 case STREAMTYPE_VCD: |
328 break; | |
32953 | 329 #endif |
32881 | 330 |
331 default: | |
332 | |
333 curr = gtkSet(gtkGetCurrPlItem, 0, NULL); | |
334 | |
335 if (curr) { | |
33555 | 336 uiSetFileName(curr->path, curr->name, STREAMTYPE_FILE); |
337 uiGotoTheNext = 0; | |
32881 | 338 break; |
339 } | |
340 | |
341 return; | |
342 } | |
343 | |
344 if (stop) | |
33555 | 345 uiEventHandling(evStop, 0); |
32881 | 346 |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33614
diff
changeset
|
347 if (guiInfo.Playing == GUI_PLAY) |
33555 | 348 uiEventHandling(evPlay, 0); |
23077 | 349 } |
350 | |
33555 | 351 void uiPrev(void) |
23077 | 352 { |
32881 | 353 plItem *prev; |
354 int stop = 0; | |
355 | |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33614
diff
changeset
|
356 if (guiInfo.Playing == GUI_PAUSE) |
32881 | 357 return; |
358 | |
33555 | 359 switch (guiInfo.StreamType) { |
32881 | 360 #ifdef CONFIG_DVDREAD |
361 case STREAMTYPE_DVD: | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
27370
diff
changeset
|
362 |
33555 | 363 if (--guiInfo.DVD.current_chapter == 0) { |
364 guiInfo.DVD.current_chapter = 1; | |
32881 | 365 |
33555 | 366 if (--guiInfo.DVD.current_title <= 0) { |
367 guiInfo.DVD.current_title = 1; | |
32881 | 368 stop = 1; |
369 } | |
370 } | |
371 | |
33555 | 372 guiInfo.Track = guiInfo.DVD.current_title; |
32881 | 373 break; |
32953 | 374 #endif |
32881 | 375 |
27370
14c5017f40d2
Change a bunch of video/audio-output-specific preprocessor directives from
diego
parents:
27341
diff
changeset
|
376 #ifdef CONFIG_VCD |
32881 | 377 case STREAMTYPE_VCD: |
33555 | 378 if (--guiInfo.Track == 0) { |
379 guiInfo.Track = 1; | |
32881 | 380 stop = 1; |
381 } | |
382 break; | |
32953 | 383 #endif |
32881 | 384 |
385 default: | |
386 | |
387 prev = gtkSet(gtkGetPrevPlItem, 0, NULL); | |
388 | |
389 if (prev) { | |
33555 | 390 uiSetFileName(prev->path, prev->name, STREAMTYPE_FILE); |
391 uiGotoTheNext = 0; | |
32881 | 392 break; |
393 } | |
394 | |
395 return; | |
396 } | |
397 | |
398 if (stop) | |
33555 | 399 uiEventHandling(evStop, 0); |
32881 | 400 |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33614
diff
changeset
|
401 if (guiInfo.Playing == GUI_PLAY) |
33555 | 402 uiEventHandling(evPlay, 0); |
23077 | 403 } |
404 | |
33555 | 405 void uiNext(void) |
23077 | 406 { |
32881 | 407 int stop = 0; |
408 plItem *next; | |
23077 | 409 |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33614
diff
changeset
|
410 if (guiInfo.Playing == GUI_PAUSE) |
32881 | 411 return; |
412 | |
33555 | 413 switch (guiInfo.StreamType) { |
27341
e7c989f7a7c9
Start unifying names of internal preprocessor directives.
diego
parents:
26458
diff
changeset
|
414 #ifdef CONFIG_DVDREAD |
32881 | 415 case STREAMTYPE_DVD: |
416 | |
33555 | 417 if (guiInfo.DVD.current_chapter++ == guiInfo.DVD.chapters) { |
418 guiInfo.DVD.current_chapter = 1; | |
32881 | 419 |
33555 | 420 if (++guiInfo.DVD.current_title > guiInfo.DVD.titles) { |
421 guiInfo.DVD.current_title = guiInfo.DVD.titles; | |
32881 | 422 stop = 1; |
423 } | |
424 } | |
425 | |
33555 | 426 guiInfo.Track = guiInfo.DVD.current_title; |
32881 | 427 break; |
32953 | 428 #endif |
32881 | 429 |
27370
14c5017f40d2
Change a bunch of video/audio-output-specific preprocessor directives from
diego
parents:
27341
diff
changeset
|
430 #ifdef CONFIG_VCD |
32881 | 431 case STREAMTYPE_VCD: |
33003 | 432 |
33555 | 433 if (++guiInfo.Track >= guiInfo.VCDTracks) { |
434 guiInfo.Track = guiInfo.VCDTracks; | |
33003 | 435 |
33555 | 436 if (guiInfo.VCDTracks > 1) |
437 guiInfo.Track--; | |
33003 | 438 |
32881 | 439 stop = 1; |
440 } | |
33003 | 441 |
32881 | 442 break; |
32953 | 443 #endif |
32881 | 444 |
445 default: | |
446 | |
447 next = gtkSet(gtkGetNextPlItem, 0, NULL); | |
448 | |
449 if (next) { | |
33555 | 450 uiSetFileName(next->path, next->name, STREAMTYPE_FILE); |
451 uiGotoTheNext = 0; | |
32881 | 452 break; |
453 } | |
454 | |
455 return; | |
456 } | |
457 | |
458 if (stop) | |
33555 | 459 uiEventHandling(evStop, 0); |
32881 | 460 |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33614
diff
changeset
|
461 if (guiInfo.Playing == GUI_PLAY) |
33555 | 462 uiEventHandling(evPlay, 0); |
23077 | 463 } |
33482
7e41f14e7778
Fix segmentation fault when pressing U (stop playing) in GUI.
ib
parents:
33084
diff
changeset
|
464 |
33555 | 465 void uiStop(void) |
33482
7e41f14e7778
Fix segmentation fault when pressing U (stop playing) in GUI.
ib
parents:
33084
diff
changeset
|
466 { |
33555 | 467 uiEventHandling(evStop, 0); |
33482
7e41f14e7778
Fix segmentation fault when pressing U (stop playing) in GUI.
ib
parents:
33084
diff
changeset
|
468 } |